[gtk+/wip/frame-synchronization: 6/33] Switch to an extended form of _NET_WM_SYNC_REQUEST_COUNTER



commit 323da4cb5ffe27adc3b0f67598f46c40743d304c
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Sep 18 09:31:17 2012 -0400

    Switch to an extended form of _NET_WM_SYNC_REQUEST_COUNTER
    
    By exporting two XSync counters on a toplevel window, we subscribe
    to an extended form of the _NET_WM_SYNC_REQUEST_COUNTER protocol,
    where the window manager can initiate an atomic frame, as previously,
    but the application can also do so by incrementing the new counter to
    an odd value, and then to an even value to finish the frame.
    
    See:
    https://mail.gnome.org/archives/wm-spec-list/2011-October/msg00006.html
    
    The support for 64-bit integers that GLib requires is used to
    simplify the logic.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=685460

 gdk/x11/gdkdisplay-x11.c |   10 ++++------
 gdk/x11/gdkwindow-x11.c  |   45 +++++++++++++++++++++++++++++++++++----------
 gdk/x11/gdkwindow-x11.h  |   12 +++++++-----
 3 files changed, 46 insertions(+), 21 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 1957798..e420e80 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -747,10 +747,10 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
         }
 
 #ifdef HAVE_XSYNC
-      if (!is_substructure && toplevel && display_x11->use_sync && !XSyncValueIsZero (toplevel->pending_counter_value))
+      if (!is_substructure && toplevel && display_x11->use_sync && toplevel->pending_counter_value != 0)
 	{
-	  toplevel->current_counter_value = toplevel->pending_counter_value;
-	  XSyncIntToValue (&toplevel->pending_counter_value, 0);
+	  toplevel->configure_counter_value = toplevel->pending_counter_value;
+	  toplevel->pending_counter_value = 0;
 	}
 #endif
 
@@ -1126,9 +1126,7 @@ _gdk_wm_protocols_filter (GdkXEvent *xev,
       if (toplevel)
 	{
 #ifdef HAVE_XSYNC
-	  XSyncIntsToValue (&toplevel->pending_counter_value,
-			    xevent->xclient.data.l[2],
-			    xevent->xclient.data.l[3]);
+	  toplevel->pending_counter_value = xevent->xclient.data.l[2] + ((gint64)xevent->xclient.data.l[3] << 32);
 #endif
 	}
       return GDK_FILTER_REMOVE;
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c
index 9c11ecd..e4b4d98 100644
--- a/gdk/x11/gdkwindow-x11.c
+++ b/gdk/x11/gdkwindow-x11.c
@@ -199,6 +199,19 @@ _gdk_x11_window_update_size (GdkWindowImplX11 *impl)
     }
 }
 
+static void
+set_sync_counter(Display     *display,
+		 XSyncCounter counter,
+                 gint64       value)
+{
+    XSyncValue sync_value;
+
+    XSyncIntsToValue(&sync_value,
+                     value & G_GINT64_CONSTANT(0xFFFFFFFF),
+                     value >> 32);
+    XSyncSetCounter(display, counter, sync_value);
+}
+
 /*****************************************************
  * X11 specific implementations of generic functions *
  *****************************************************/
@@ -611,20 +624,24 @@ ensure_sync_counter (GdkWindow *window)
 	  Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
 	  XSyncValue value;
 	  Atom atom;
+	  XID counters[2];
 
 	  XSyncIntToValue (&value, 0);
 	  
 	  toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
+	  toplevel->extended_update_counter = XSyncCreateCounter (xdisplay, value);
 	  
 	  atom = gdk_x11_get_xatom_by_name_for_display (display,
 							"_NET_WM_SYNC_REQUEST_COUNTER");
-	  
+
+	  counters[0] = toplevel->update_counter;
+	  counters[1] = toplevel->extended_update_counter;
 	  XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
 			   atom, XA_CARDINAL,
 			   32, PropModeReplace,
-			   (guchar *)&toplevel->update_counter, 1);
+			   (guchar *)counters, 2);
 	  
-	  XSyncIntToValue (&toplevel->current_counter_value, 0);
+	  toplevel->current_counter_value = 0;
 	}
     }
 #endif
@@ -1005,7 +1022,7 @@ gdk_toplevel_x11_free_contents (GdkDisplay *display,
 			   toplevel->update_counter);
       toplevel->update_counter = None;
 
-      XSyncIntToValue (&toplevel->current_counter_value, 0);
+      toplevel->current_counter_value = 0;
     }
 #endif
 }
@@ -4750,13 +4767,21 @@ gdk_x11_window_configure_finished (GdkWindow *window)
 
       if (toplevel && toplevel->update_counter != None &&
 	  GDK_X11_DISPLAY (display)->use_sync &&
-	  !XSyncValueIsZero (toplevel->current_counter_value))
+	  toplevel->configure_counter_value != 0)
 	{
-	  XSyncSetCounter (GDK_WINDOW_XDISPLAY (window), 
-			   toplevel->update_counter,
-			   toplevel->current_counter_value);
-	  
-	  XSyncIntToValue (&toplevel->current_counter_value, 0);
+	  set_sync_counter (GDK_WINDOW_XDISPLAY (window),
+			    toplevel->update_counter,
+			    toplevel->configure_counter_value);
+
+	  toplevel->current_counter_value = toplevel->configure_counter_value;
+	  if ((toplevel->current_counter_value % 2) == 1)
+	    toplevel->current_counter_value += 1;
+
+	  toplevel->configure_counter_value = 0;
+
+	  set_sync_counter (GDK_WINDOW_XDISPLAY (window),
+			    toplevel->extended_update_counter,
+			    toplevel->current_counter_value);
 	}
     }
 #endif
diff --git a/gdk/x11/gdkwindow-x11.h b/gdk/x11/gdkwindow-x11.h
index 3dde777..b4b7376 100644
--- a/gdk/x11/gdkwindow-x11.h
+++ b/gdk/x11/gdkwindow-x11.h
@@ -144,11 +144,13 @@ struct _GdkToplevelX11
  
 #ifdef HAVE_XSYNC
   XID update_counter;
-  XSyncValue pending_counter_value; /* latest _NET_WM_SYNC_REQUEST value received */
-  XSyncValue current_counter_value; /* Latest _NET_WM_SYNC_REQUEST value received
-				     * where we have also seen the corresponding
-				     * ConfigureNotify
-				     */
+  XID extended_update_counter;
+  gint64 pending_counter_value; /* latest _NET_WM_SYNC_REQUEST value received */
+  gint64 configure_counter_value; /* Latest _NET_WM_SYNC_REQUEST value received
+				 * where we have also seen the corresponding
+				 * ConfigureNotify
+				 */
+  gint64 current_counter_value;
 #endif
 };
 



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