patch to gnome-session: smooth fade on logout



Hello,

For a while I've been annoyed by the choppy fade when logging out. This
is especially a problem on a high resolution laptop displays when
throttling CPU performance. Below is a patch to provide a smooth
fadeout. I've tested it on a 1400x1050 display with the CPU throttling
between 600MHz and 1.6GHz -- fading was nice and smooth. This is also
the first patch that I'm submitting to the gnome community over a
mailing list and directly to maintainers, so if I'm breaking and
etticate please let me know. I hope to become a gnome developer in the
future.

Cheers,
Ross

And the patch against cvs:

Index: logout.c
===================================================================
RCS file: /cvs/gnome/gnome-session/gnome-session/logout.c,v
retrieving revision 1.57
diff -u -r1.57 logout.c
--- logout.c	19 Apr 2004 12:48:11 -0000	1.57
+++ logout.c	21 Apr 2004 02:39:39 -0000
@@ -61,42 +61,36 @@
   int           rowstride;
   GdkWindow    *root_window;
   GdkWindow    *draw_window;
-  GdkPixbuf    *start_pb, *end_pb, *frame;
-  guchar       *start_p, *end_p, *frame_p;
+  GdkPixbuf    *start_pb, *frame, *diff;
+  guchar       *start_p, *frame_p, *diff_p;
   GTimeVal      start_time;
   GdkGC        *gc;
 } FadeoutData;
 
 static GList *fadeout_windows = NULL;
 
-/* Go for five seconds */
-#define FADE_DURATION 1500.0
+#define FADE_SHIFT 4
+#define FADE_STEPS 16
 
 static void
-get_current_frame (FadeoutData *fadeout,
-		   double    sat)
+get_current_frame (FadeoutData *fadeout)
 {
-  guchar *sp, *ep, *fp;
+  guchar *fp, *dp;
   int i, j, width, offset;
 
   width = fadeout->area.width * 3;
   offset = 0;
-  
+
   for (i = 0; i < fadeout->area.height; i++)
     {
-      sp = fadeout->start_p + offset;
-      ep = fadeout->end_p   + offset;
       fp = fadeout->frame_p + offset;
+      dp = fadeout->diff_p + offset;
 
       for (j = 0; j < width; j += 3)
 	{
-	  guchar r = abs (*(sp++) - ep[0]);
-	  guchar g = abs (*(sp++) - ep[1]);
-	  guchar b = abs (*(sp++) - ep[2]);
-
-	  *(fp++) = *(ep++) + r * sat;
-	  *(fp++) = *(ep++) + g * sat;
-	  *(fp++) = *(ep++) + b * sat;
+	  *(fp++) -= *(dp++);
+	  *(fp++) -= *(dp++);
+	  *(fp++) -= *(dp++);
 	}
 
       offset += fadeout->rowstride;
@@ -104,7 +98,7 @@
 }
 
 static void
-darken_pixbuf (GdkPixbuf *pb)
+diff_pixbuf (GdkPixbuf *pb)
 {
   int width, height, rowstride;
   int i, j;
@@ -119,7 +113,7 @@
     {
       p = pixels + (i * rowstride);
       for (j = 0; j < width; j++)
-	p [j] >>= 1;
+        p[j] >>= FADE_SHIFT+1;
     }
 }
 
@@ -127,44 +121,33 @@
 fadeout_callback (FadeoutData *fadeout)
 {
   GTimeVal current_time;
-  double elapsed, percent;
+  double elapsed, sleep;
+  static int times_called = 0;
 
   g_get_current_time (&current_time);
-  elapsed = ((((double)current_time.tv_sec -
fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
-	      (current_time.tv_usec - fadeout->start_time.tv_usec))) / 1000.0;
-
-  if (elapsed < 0)
-    {
-      g_warning ("System clock seemed to go backwards?");
-      elapsed = G_MAXDOUBLE;
-    }
-
-  if (elapsed > FADE_DURATION)
-    {
-      gdk_draw_pixbuf (fadeout->draw_window,
-		       fadeout->gc,
-		       fadeout->end_pb,
-		       0, 0,
-		       fadeout->area.x,
-		       fadeout->area.y,
-		       fadeout->area.width,
-		       fadeout->area.height,
-		       GDK_RGB_DITHER_NONE,
-		       0, 0);
 
+  if (times_called > FADE_STEPS)
+   {
       g_object_unref (fadeout->gc);
       g_object_unref (fadeout->start_pb);
-      g_object_unref (fadeout->end_pb);
-      g_object_unref (fadeout->frame);
+      g_object_unref (fadeout->diff);
 
       g_free (fadeout);
     
       return FALSE;
     }
 
-  percent = elapsed / FADE_DURATION;
+  times_called++;
+
+  get_current_frame (fadeout);
+  
+  elapsed = ((((double)current_time.tv_sec -
fadeout->start_time.tv_sec) * G_USEC_PER_SEC +
+	      (current_time.tv_usec - fadeout->start_time.tv_usec)));
+
+  /* Don't let the fade go too quickly on fast machines / lowres
displays. */
+  if ((sleep = 312500.0 - elapsed) > 0)
+    usleep (sleep);
 
-  get_current_frame (fadeout, 1.0 - percent);
   gdk_draw_pixbuf (fadeout->draw_window,
 		   fadeout->gc,
 		   fadeout->frame,
@@ -224,15 +207,15 @@
 						    fadeout->area.width,
 						    fadeout->area.height);
   
-  fadeout->end_pb = gdk_pixbuf_copy (fadeout->start_pb);
-  darken_pixbuf (fadeout->end_pb);
+  fadeout->diff = gdk_pixbuf_copy (fadeout->start_pb);
+  diff_pixbuf (fadeout->diff);
   
   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->diff_p = gdk_pixbuf_get_pixels (fadeout->diff);
   
   values.subwindow_mode = GDK_INCLUDE_INFERIORS;




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]