diff -Naur ../emacs.orig/src/frame.c ../emacs/src/frame.c
--- ../emacs.orig/src/frame.c	2008-05-14 03:49:31.000000000 -0400
+++ ../emacs/src/frame.c	2008-05-14 23:14:44.000000000 -0400
@@ -62,6 +62,10 @@
 
 Lisp_Object Vx_resource_class;
 
+/* Lower limit value of the frame opacity (alpha transparency).  */
+
+Lisp_Object Vframe_alpha_lower_limit;
+
 #endif
 
 Lisp_Object Qframep, Qframe_live_p;
@@ -113,6 +117,7 @@
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
 Lisp_Object Qfont_backend;
+Lisp_Object Qalpha;
 
 Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
@@ -2824,7 +2829,8 @@
   {"right-fringe",		&Qright_fringe},
   {"wait-for-wm",		&Qwait_for_wm},
   {"fullscreen",                &Qfullscreen},
-  {"font-backend",		&Qfont_backend}
+  {"font-backend",		&Qfont_backend},
+  {"alpha",			&Qalpha}
 };
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -3634,6 +3640,61 @@
     return Qnil;
 }
 
+void
+x_set_alpha (f, arg, oldval)
+     struct frame *f;
+     Lisp_Object arg, oldval;
+{
+  double alpha = 1.0;
+  double newval[2];
+  int i, ialpha;
+  Lisp_Object item;
+
+  for (i=0;i<2;i++)
+    {
+      newval[i] = 1.0;
+      if (CONSP (arg))
+        {
+          item = CAR (arg);
+          arg  = CDR (arg);
+        }
+      else
+        item=arg;
+
+      if (!NILP (item))
+        {
+          if (FLOATP (item))
+            {
+              alpha = XFLOAT_DATA (item);
+              if (alpha < 0.0 || 1.0 < alpha)
+                args_out_of_range (make_float (0.0), make_float (1.0));
+            }
+          else if (INTEGERP (item))
+            {
+              ialpha = XINT (item);
+              if (ialpha < 0 || 100 < ialpha)
+                args_out_of_range (make_number (0), make_number (100));
+              else
+                alpha = ialpha / 100.0;
+            }
+          else
+            wrong_type_argument (Qnumberp, item);
+        }
+      newval[i] = alpha;
+    }
+
+  for (i=0;i<2;i++)
+    f->alpha[i] = newval[i];
+
+#ifdef HAVE_X_WINDOWS
+  BLOCK_INPUT;
+  x_set_frame_alpha (f);
+  UNBLOCK_INPUT;
+#endif
+
+  return;
+}
+
 
 /* Subroutines of creating an X frame.  */
 
@@ -4403,6 +4464,13 @@
 but binding this variable locally around a call to `x-get-resource'
 is a reasonable practice.  See also the variable `x-resource-name'.  */);
   Vx_resource_class = build_string (EMACS_CLASS);
+
+  DEFVAR_LISP ("frame-alpha-lower-limit", &Vframe_alpha_lower_limit,
+    doc: /* The lower limit of the frame opacity (alpha transparency).
+The value should range from 0 (invisible) to 100 (completely opaque).
+The user can also use a floating number between 0.0 and 1.0.
+The default is 20.  */);
+  Vframe_alpha_lower_limit = make_number (20);
 #endif
 
   DEFVAR_LISP ("default-frame-alist", &Vdefault_frame_alist,
diff -Naur ../emacs.orig/src/frame.h ../emacs/src/frame.h
--- ../emacs.orig/src/frame.h	2008-05-13 21:27:45.000000000 -0400
+++ ../emacs/src/frame.h	2008-05-14 23:19:16.000000000 -0400
@@ -215,6 +215,11 @@
      be used for output.  */
   unsigned glyphs_initialized_p : 1;
 
+  /* frame opacity
+     alpha[0]: alpha transparency of the active frame
+     alpha[1]: alpha transparency of inactive frames   */
+  double alpha[2];
+
   /* Set to non-zero in change_frame_size when size of frame changed
      Clear the frame in clear_garbaged_frames if set.  */
   unsigned resized_p : 1;
@@ -1035,6 +1040,7 @@
 extern Lisp_Object Qwait_for_wm;
 extern Lisp_Object Qfullscreen;
 extern Lisp_Object Qfont_backend;
+extern Lisp_Object Qalpha;
 
 extern Lisp_Object Qleft_fringe, Qright_fringe;
 extern Lisp_Object Qheight, Qwidth;
@@ -1099,6 +1105,8 @@
 
 extern int x_figure_window_size P_ ((struct frame *, Lisp_Object, int));
 
+extern Lisp_Object Vframe_alpha_lower_limit;
+extern void x_set_alpha P_ ((struct frame *, Lisp_Object, Lisp_Object));
 
 extern void validate_x_resource_name P_ ((void));
 
diff -Naur ../emacs.orig/src/macfns.c ../emacs/src/macfns.c
--- ../emacs.orig/src/macfns.c	2008-05-14 03:49:40.000000000 -0400
+++ ../emacs/src/macfns.c	2008-05-14 23:12:20.000000000 -0400
@@ -4321,6 +4321,8 @@
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
+  0, /* x_set_font_backend, */
+  0 /* x_set_alpha, */
 };
 
 void
diff -Naur ../emacs.orig/src/w32fns.c ../emacs/src/w32fns.c
--- ../emacs.orig/src/w32fns.c	2008-05-14 03:50:03.000000000 -0400
+++ ../emacs/src/w32fns.c	2008-05-14 23:14:22.000000000 -0400
@@ -8922,7 +8922,8 @@
   x_set_fringe_width,
   0, /* x_set_wait_for_wm, */
   x_set_fullscreen,
-  x_set_font_backend
+  x_set_font_backend,
+  0 /* x_set_alpha, */
 };
 
 void
diff -Naur ../emacs.orig/src/xfns.c ../emacs/src/xfns.c
--- ../emacs.orig/src/xfns.c	2008-05-14 03:50:22.000000000 -0400
+++ ../emacs/src/xfns.c	2008-05-14 23:15:26.000000000 -0400
@@ -3405,6 +3405,8 @@
   x_default_parameter (f, parms, Qscroll_bar_width, Qnil,
 		       "scrollBarWidth", "ScrollBarWidth",
 		       RES_TYPE_NUMBER);
+  x_default_parameter (f, parms, Qalpha, Qnil,
+		       "alpha", "Alpha", RES_TYPE_NUMBER);
 
   /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size.
      Change will not be effected unless different from the current
@@ -5771,7 +5773,8 @@
   x_set_fringe_width,
   x_set_wait_for_wm,
   x_set_fullscreen,
-  x_set_font_backend
+  x_set_font_backend,
+  x_set_alpha
 };
 
 void
diff -Naur ../emacs.orig/src/xterm.c ../emacs/src/xterm.c
--- ../emacs.orig/src/xterm.c	2008-05-14 03:50:26.000000000 -0400
+++ ../emacs/src/xterm.c	2008-05-14 23:12:20.000000000 -0400
@@ -457,6 +457,67 @@
   return 0;
 }
 
+#define OPAQUE  0xffffffff
+#define OPACITY "_NET_WM_WINDOW_OPACITY"
+
+void
+x_set_frame_alpha (f)
+     struct frame *f;
+{
+  struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display *dpy = FRAME_X_DISPLAY (f);
+  Window win = FRAME_OUTER_WINDOW (f);
+  if (FRAME_X_DISPLAY_INFO (f)->root_window != FRAME_X_OUTPUT (f)->parent_desc)
+    /* Since the WM decoration lies under the FRAME_OUTER_WINDOW,
+       we must treat the former instead of the latter. */
+    win = FRAME_X_OUTPUT(f)->parent_desc;
+
+  double alpha = 1.0, alpha_min = 1.0;
+
+  if (dpyinfo->x_highlight_frame == f)
+    alpha = f->alpha[0];
+  else
+    alpha = f->alpha[1];
+
+  if (FLOATP (Vframe_alpha_lower_limit))
+    alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit);
+  else if (INTEGERP (Vframe_alpha_lower_limit))
+    alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
+
+  if (alpha < 0.0 || 1.0 < alpha)
+    alpha = 1.0;
+  else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
+    alpha = alpha_min;
+
+  unsigned int opac = (unsigned int)(alpha * OPAQUE);
+
+  /* return unless necessary */
+  {
+    unsigned char *data;
+    Atom actual;
+    int format;
+    unsigned long n, left;
+
+    XGetWindowProperty(dpy, win, XInternAtom(dpy, OPACITY, False),
+		       0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left,
+		       (unsigned char **) &data);
+    if (data != None)
+      if (*(unsigned int *)data == opac)
+	{
+	  XFree ((void *) data);
+	  return;
+	}
+      else
+       {
+	  XFree ((void *) data);
+       }
+  }
+
+  XChangeProperty (dpy, win, XInternAtom (dpy, OPACITY, False),
+		   XA_CARDINAL, 32, PropModeReplace,
+		   (unsigned char *) &opac, 1L);
+  XSync (dpy, False);
+}
 
 
 /***********************************************************************
@@ -3171,6 +3232,7 @@
 		    f->output_data.x->border_pixel);
   UNBLOCK_INPUT;
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 static void
@@ -3186,6 +3248,7 @@
 			  f->output_data.x->border_tile);
   UNBLOCK_INPUT;
   x_update_cursor (f, 1);
+  x_set_frame_alpha (f);
 }
 
 /* The focus has changed.  Update the frames as necessary to reflect
