kov changed libgksu/branches/composited_fadeout/ChangeLog, libgksu/branches/composited_fadeout/libgksu/libgksu.c

Gustavo Noronha kov at alioth.debian.org
Tue Feb 20 14:21:49 CET 2007


Mensagem de log: 
patch by Paul Betts <betts.62 at osu.edu> modified by myself to enable
composite fadeout when composite is available


-----


Modified: libgksu/branches/composited_fadeout/ChangeLog
===================================================================
--- libgksu/branches/composited_fadeout/ChangeLog	2007-02-20 13:11:52 UTC (rev 778)
+++ libgksu/branches/composited_fadeout/ChangeLog	2007-02-20 13:21:49 UTC (rev 779)
@@ -1,3 +1,10 @@
+2007-02-20  Gustavo Noronha Silva  <kov at debian.org>
+
+	* libgksu/libgksu.c:
+	- accepted patch by Paul Betts <betts.62 at osu.edu>
+	  with some slight modifications by me to introduce
+	  composite fadeout if composite is available
+
 2007-02-04  Gustavo Noronha Silva  <kov at debian.org>
 
 	* Release 2.0.4

Modified: libgksu/branches/composited_fadeout/libgksu/libgksu.c
===================================================================
--- libgksu/branches/composited_fadeout/libgksu/libgksu.c	2007-02-20 13:11:52 UTC (rev 778)
+++ libgksu/branches/composited_fadeout/libgksu/libgksu.c	2007-02-20 13:21:49 UTC (rev 779)
@@ -52,6 +52,9 @@
 #include "libgksu.h"
 #include "../libgksuui/gksuui-dialog.h"
 
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
 GType
 gksu_error_get_type (void)
 {
@@ -151,11 +154,58 @@
    return FD;
 }
 
+/* code borrowed and slightly modified from GTK+
+ *
+ * Copyright 2001 Sun Microsystems Inc.
+ *
+ * Erwann Chenede <erwann.chenede at sun.com>
+ *
+ * GTK+ is licensed under the LGPL (see http://svn.gnome.org/viewcvs/gtk%2B/trunk/gdk/x11/gdkscreen-x11.c?revision=15560&view=markup)
+ */
+static GdkAtom
+make_cm_atom (GdkScreen *screen)
+{
+  gchar *name = g_strdup_printf ("_NET_WM_CM_S%d", gdk_screen_get_number(screen));
+  GdkAtom atom = gdk_atom_intern (name, FALSE);
+  g_free (name);
+  return atom;
+}
+
+static gboolean
+check_is_composited (GdkDisplay *display,
+		     GdkScreen *screen)
+{
+  Atom xselection = gdk_x11_atom_to_xatom_for_display (display, make_cm_atom(screen));
+  Window xwindow;
+
+  xwindow = XGetSelectionOwner (GDK_DISPLAY_XDISPLAY (display), xselection);
+
+  return xwindow != None;
+}
+/* end of borrowed code */
+
+static gboolean
+is_screen_composited (GdkScreen *screen)
+{
+  static gboolean response_cached = FALSE;
+  static gboolean is_composited = FALSE;
+
+  if (response_cached)
+    return is_composited;
+
+  is_composited = check_is_composited (gdk_screen_get_display(screen), screen);
+  response_cached = TRUE;
+
+  return is_composited;
+}
+
 /*
  * code 'stolen' from gnome-session's logout.c
  *
  * Written by Owen Taylor <otaylor at redhat.com>
  * Copyright (C) Red Hat
+ *
+ * Composite version by Paul Betts
  */
 typedef struct {
   GdkScreen    *screen;
@@ -168,58 +218,82 @@
   guchar       *start_p, *end_p, *frame_p;
   GTimeVal      start_time;
   GdkGC        *gc;
+  gboolean     use_composite;
 } FadeoutData;
 
 FadeoutData *fade_data = NULL;
 static GList *fadeout_windows = NULL;
 
-#define FADE_DURATION 500.0
+#define FADE_WAIT     350.0
+#define FADE_DURATION 600.0
 
 int
 gsm_screen_get_width (GdkScreen *screen,
-		      int        monitor)
+		      int monitor)
 {
-	GdkRectangle geometry;
+  GdkRectangle geometry;
 
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
-
-	return geometry.width;
+  gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+  return geometry.width;
 }
 
 int
 gsm_screen_get_height (GdkScreen *screen,
-		       int        monitor)
+		       int monitor)
 {
-	GdkRectangle geometry;
+  GdkRectangle geometry;
 
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+  gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
 
-	return geometry.height;
+  return geometry.height;
 }
 
 int
 gsm_screen_get_x (GdkScreen *screen,
 		  int        monitor)
 {
-	GdkRectangle geometry;
+  GdkRectangle geometry;
 
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+  gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
 
-	return geometry.x;
+  return geometry.x;
 }
 
 int
 gsm_screen_get_y (GdkScreen *screen,
 		  int        monitor)
 {
-	GdkRectangle geometry;
+  GdkRectangle geometry;
 
-	gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+  gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
 
-	return geometry.y;
+  return geometry.y;
 }
 
+#define OPAQUE 0xFFFFFFFF
+#define OPACITY_PROP "_NET_WM_WINDOW_OPACITY"
+
 static void
+set_window_opacity (GdkWindow* window,
+		    double level)		/* 0.0 = transparent, 1.0 = opaque */
+{
+  /* FIXME: This is pretty hacky and only works on X; but then again, we
+   * don't have composite in Windows anyways
+   * Code from transset by Matthew Hawn */
+
+  Window win = GDK_DRAWABLE_XID(window);
+  Display* dpy = GDK_DRAWABLE_XDISPLAY(window);
+  unsigned int opacity = (unsigned int)(level * (double)OPAQUE);
+
+  if(opacity == OPAQUE)
+    XDeleteProperty(dpy, win, XInternAtom(dpy, OPACITY_PROP, False));
+  else
+    XChangeProperty(dpy, win, XInternAtom(dpy, OPACITY_PROP, False),
+		    XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&opacity, 1L);
+  XSync(dpy, False);
+}
+
+static void
 get_current_frame (FadeoutData *fadeout,
 		   double    sat)
 {
@@ -266,7 +340,7 @@
     {
       p = pixels + (i * rowstride);
       for (j = 0; j < width; j++)
-	p [j] >>= 1;
+	p [j] >>= 1;			/* Implies 50% darkened */
     }
 }
 
@@ -286,34 +360,48 @@
       elapsed = G_MAXDOUBLE;
     }
 
-  if (elapsed > FADE_DURATION)
+  if (elapsed > FADE_DURATION + FADE_WAIT)
     {
-      gdk_draw_pixbuf (fadeout->draw_window,
-		       fadeout->gc,
-		       fadeout->end_pb,
-		       0, 0,
-		       0, 0,
-		       fadeout->area.width,
-		       fadeout->area.height,
-		       GDK_RGB_DITHER_NONE,
-		       0, 0);
+      if(fadeout->use_composite)
+	set_window_opacity(fadeout->draw_window, 0.75);
+      else {
+	gdk_draw_pixbuf (fadeout->draw_window,
+			 fadeout->gc,
+			 fadeout->end_pb,
+			 0, 0,
+			 0, 0,
+			 fadeout->area.width,
+			 fadeout->area.height,
+			 GDK_RGB_DITHER_NONE,
+			 0, 0);
+      }
 
       return FALSE;
     }
 
-  percent = elapsed / FADE_DURATION;
+  /* We wait some extra time for the window to be created and visible
+   * before we start the fade; otherwise by the time we get a valid
+   * window, it's already done */
+  percent = (elapsed-FADE_WAIT) / FADE_DURATION;
+  percent = (percent < 0.0 ? 0.0 : percent);
 
-  get_current_frame (fadeout, 1.0 - percent);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
 
+  if(fadeout->use_composite) {
+    set_window_opacity(fadeout->draw_window, percent / 1.5);
+  }
+  else {
+    get_current_frame (fadeout, 1.0 - percent);
+    gdk_draw_pixbuf (fadeout->draw_window,
+		     fadeout->gc,
+		     fadeout->frame,
+		     0, 0,
+		     0, 0,
+		     fadeout->area.width,
+		     fadeout->area.height,
+		     GDK_RGB_DITHER_NONE,
+		     0, 0);
+  }
+
   gdk_flush ();
 
   return TRUE;
@@ -350,23 +438,33 @@
       elapsed = G_MAXDOUBLE;
     }
 
+  /* We don't wait here because the window is already created */
   if (elapsed > FADE_DURATION)
     {
-      gdk_draw_pixbuf (fadeout->draw_window,
-		       fadeout->gc,
-		       fadeout->end_pb,
-		       0, 0,
-		       0, 0,
-		       fadeout->area.width,
-		       fadeout->area.height,
-		       GDK_RGB_DITHER_NONE,
-		       0, 0);
+      if(fadeout->use_composite) {
+	set_window_opacity(fadeout->draw_window, 0.0);
 
-      g_object_unref (fadeout->gc);
-      g_object_unref (fadeout->start_pb);
-      g_object_unref (fadeout->end_pb);
-      g_object_unref (fadeout->frame);
+	/* HACK: To avoid the flicker associated with the composite manager
+	 * doing fancy effects on a closing window, we resize to very small */
+	gdk_window_resize(fadeout->draw_window, 4, 4);
+      }
+      else {
+	gdk_draw_pixbuf (fadeout->draw_window,
+			 fadeout->gc,
+			 fadeout->end_pb,
+			 0, 0,
+			 0, 0,
+			 fadeout->area.width,
+			 fadeout->area.height,
+			 GDK_RGB_DITHER_NONE,
+			 0, 0);
 
+	g_object_unref (fadeout->gc);
+	g_object_unref (fadeout->start_pb);
+	g_object_unref (fadeout->end_pb);
+	g_object_unref (fadeout->frame);
+      }
+
       g_free (fadeout);
 
       hide_fadeout_windows ();
@@ -376,16 +474,20 @@
 
   percent = elapsed / FADE_DURATION;
 
-  get_current_frame (fadeout, percent);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
+  if(fadeout->use_composite)
+    set_window_opacity(fadeout->draw_window, (0.75 - percent/1.5) );
+  else {
+    get_current_frame (fadeout, percent);
+    gdk_draw_pixbuf (fadeout->draw_window,
+		     fadeout->gc,
+		     fadeout->frame,
+		     0, 0,
+		     0, 0,
+		     fadeout->area.width,
+		     fadeout->area.height,
+		     GDK_RGB_DITHER_NONE,
+		     0, 0);
+  }
 
   gdk_flush ();
 
@@ -393,30 +495,48 @@
 }
 
 static void
-fadeout_screen (GdkScreen *screen,
-		int        monitor)
+fadeout_screen (GdkScreen *screen, int _)
 {
   GdkWindowAttr attr;
   int attr_mask;
   GdkGCValues values;
   FadeoutData *fadeout;
+  GdkColor black = {0, 0, 0, 0};
+  GdkColormap* alpha_colormap;
 
   fadeout = g_new (FadeoutData, 1);
 
   fadeout->screen = screen;
-  fadeout->monitor = monitor;
 
-  fadeout->area.x = gsm_screen_get_x (screen, monitor);
-  fadeout->area.y = gsm_screen_get_y (screen, monitor);
-  fadeout->area.width = gsm_screen_get_width (screen, monitor);
-  fadeout->area.height = gsm_screen_get_height (screen, monitor);
+  /* This code only dimms out the primary monitor, which doesn't make sense
+   * for gksu on Xinerama setups; I think it works by accident on non-composite
+   fadeout->monitor = monitor;
+   fadeout->area.x = gsm_screen_get_x (screen, monitor);
+   fadeout->area.y = gsm_screen_get_y (screen, monitor);
+   fadeout->area.width = gsm_screen_get_width (screen, monitor);
+   fadeout->area.height = gsm_screen_get_height (screen, monitor);
+  */
 
+  fadeout->area.x = 0;	fadeout->area.y = 0;
+  fadeout->area.width = gdk_screen_get_width (screen);
+  fadeout->area.height = gdk_screen_get_height (screen);
+
+  /* Detect if we can use composite or not */
+  /* FIXME: This doesn't correctly tell if we actually have a composite manager
+   * running or not; this code is pretty hacky too */
+  alpha_colormap = gdk_screen_get_rgba_colormap(screen);
+  fadeout->use_composite = (alpha_colormap != NULL && is_screen_composited (screen));
+  if(fadeout->use_composite) {
+    g_warning("Using composite path...\n");
+    g_object_unref(alpha_colormap);
+  }
+
   fadeout->root_window = gdk_screen_get_root_window (screen);
   attr.window_type = GDK_WINDOW_CHILD;
   attr.x = fadeout->area.x;
   attr.y = fadeout->area.y;
-  attr.width = fadeout->area.width;
-  attr.height = fadeout->area.height;
+  attr.width = 4;			/* We initially set these very small */
+  attr.height = 4;			/* so that we don't get weird window effects on create */
   attr.wclass = GDK_INPUT_OUTPUT;
   attr.visual = gdk_screen_get_system_visual (fadeout->screen);
   attr.colormap = gdk_screen_get_default_colormap (fadeout->screen);
@@ -426,41 +546,52 @@
   fadeout->draw_window = gdk_window_new (fadeout->root_window, &attr, attr_mask);
   fadeout_windows = g_list_prepend (fadeout_windows, fadeout->draw_window);
 
-  fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
-						    fadeout->root_window,
-						    NULL,
-						    fadeout->area.x,
-						    fadeout->area.y,
-						    0, 0,
-						    fadeout->area.width,
-						    fadeout->area.height);
+  /* No need for this nonsense if we've got native alpha */
+  if(!fadeout->use_composite)	{
+    g_warning("Using non-composite path...\n");
+    fadeout->start_pb = gdk_pixbuf_get_from_drawable (NULL,
+						      fadeout->root_window,
+						      NULL,
+						      fadeout->area.x,
+						      fadeout->area.y,
+						      0, 0,
+						      fadeout->area.width,
+						      fadeout->area.height);
 
-  fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
-  darken_pixbuf (fadeout->end_pb);
+    fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
+    darken_pixbuf (fadeout->end_pb);
 
-  fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
-  fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
+    fadeout->frame = gdk_pixbuf_copy (fadeout->start_pb);
+    fadeout->rowstride = gdk_pixbuf_get_rowstride (fadeout->start_pb);
 
-  fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
-  fadeout->end_p   = gdk_pixbuf_get_pixels (fadeout->end_pb);
-  fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
+    fadeout->start_p = gdk_pixbuf_get_pixels (fadeout->start_pb);
+    fadeout->end_p   = gdk_pixbuf_get_pixels (fadeout->end_pb);
+    fadeout->frame_p = gdk_pixbuf_get_pixels (fadeout->frame);
 
-  values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+    values.subwindow_mode = GDK_INCLUDE_INFERIORS;
+    fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+    gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
+  }
 
-  fadeout->gc = gdk_gc_new_with_values (fadeout->root_window, &values, GDK_GC_SUBWINDOW);
+  gdk_rgb_find_color(gdk_screen_get_default_colormap (fadeout->screen), &black);
+  gdk_window_set_background(fadeout->draw_window, &black);
 
-  gdk_window_set_back_pixmap (fadeout->draw_window, NULL, FALSE);
   gdk_window_show (fadeout->draw_window);
-  gdk_draw_pixbuf (fadeout->draw_window,
-		   fadeout->gc,
-		   fadeout->frame,
-		   0, 0,
-		   0, 0,
-		   fadeout->area.width,
-		   fadeout->area.height,
-		   GDK_RGB_DITHER_NONE,
-		   0, 0);
+  gdk_window_clear(fadeout->draw_window);
+  gdk_window_resize(fadeout->draw_window, fadeout->area.width, fadeout->area.height);
 
+  if(!alpha_colormap) {
+    gdk_draw_pixbuf (fadeout->draw_window,
+		     fadeout->gc,
+		     fadeout->frame,
+		     0, 0,
+		     0, 0,
+		     fadeout->area.width,
+		     fadeout->area.height,
+		     GDK_RGB_DITHER_NONE,
+		     0, 0);
+  }
+
   g_get_current_time (&fadeout->start_time);
   g_idle_add ((GSourceFunc) fadeout_callback, fadeout);
 
@@ -866,19 +997,19 @@
 	}
       else
 	{
-        if (strcmp(gksu_context_get_user (context), "root") == 0)
-          msg = g_strdup_printf (_("<b><big>Enter the administrative password"
-                                   "</big></b>\n\n"
-                                   "The application '%s' lets you "
-                                   "modify essential parts of your "
-                                   "system."),
+	  if (strcmp(gksu_context_get_user (context), "root") == 0)
+	    msg = g_strdup_printf (_("<b><big>Enter the administrative password"
+				     "</big></b>\n\n"
+				     "The application '%s' lets you "
+				     "modify essential parts of your "
+				     "system."),
 				   command);
-        else
-          msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
-                                   "the application '%s'"
-                                   "</big></b>"),
+	  else
+	    msg = g_strdup_printf (_("<b><big>Enter the password of %s to run "
+				     "the application '%s'"
+				     "</big></b>"),
 				   command, context->user);
-      }
+	}
 
       gksuui_dialog_set_message (GKSUUI_DIALOG(dialog), msg);
       g_free (msg);
@@ -1339,7 +1470,7 @@
 
   context->sn_context = NULL;
   context->sn_id = NULL;
-  
+
   context->ref_count = 1;
 
   get_configuration_options (context);
@@ -1780,7 +1911,7 @@
 {
   if (--context->ref_count == 0)
     {
-        gksu_context_free (context);
+      gksu_context_free (context);
     }
 }
 
@@ -1791,7 +1922,7 @@
 
   if (!type_gksu_context)
     type_gksu_context = g_boxed_type_register_static
-      ("GksuContext", 
+      ("GksuContext",
        (GBoxedCopyFunc) gksu_context_ref,
        (GBoxedFreeFunc) gksu_context_unref);
 
@@ -2371,7 +2502,7 @@
     }
 
   /*
-     FIXME: need to set GError in a more detailed way
+    FIXME: need to set GError in a more detailed way
   */
   if (!sudo_prepare_xauth (context))
     {
@@ -2607,7 +2738,7 @@
 	    fprintf (stderr, "Yeah, we're in...\n");
 
 	  prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
-						   NULL);
+					       NULL);
 	  if (prompt_grab)
 	    gksu_prompt_grab (context);
 




More information about the gksu-commits mailing list