File gnome-desktop-bnc490805-randr-grab-server.diff of Package gnome-desktop

bnc#490805 - Grab the X server while doing RANDR changes, to avoid race conditions
when client applications get the new RANDR configuration.

diff --git a/libgnome-desktop/Makefile.am b/libgnome-desktop/Makefile.am
index 772a918..297c3bd 100644
--- a/libgnome-desktop/Makefile.am
+++ b/libgnome-desktop/Makefile.am
@@ -25,6 +25,7 @@ libgnome_desktop_2_la_SOURCES = \
 	gnome-rr.c		\
 	gnome-rr-config.c	\
 	gnome-rr-labeler.c	\
+	gnome-rr-private.h	\
 	edid-parse.c		\
 	edid.h
 
diff --git a/libgnome-desktop/edid-parse.c b/libgnome-desktop/edid-parse.c
index ca494cc..980885a 100644
--- a/libgnome-desktop/edid-parse.c
+++ b/libgnome-desktop/edid-parse.c
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <glib.h>
 
 #define TRUE 1
 #define FALSE 0
@@ -519,33 +520,24 @@ decode_check_sum (const uchar *edid,
 MonitorInfo *
 decode_edid (const uchar *edid)
 {
-    MonitorInfo *info = calloc (1, sizeof (MonitorInfo));
+    MonitorInfo *info = g_new0 (MonitorInfo, 1);
 
     decode_check_sum (edid, info);
     
-    if (!decode_header (edid))
-	return NULL;
-
-    if (!decode_vendor_and_product_identification (edid, info))
-	return NULL;
-
-    if (!decode_edid_version (edid, info))
-	return NULL;
-
-    if (!decode_display_parameters (edid, info))
-	return NULL;
-
-    if (!decode_color_characteristics (edid, info))
-	return NULL;
-
-    if (!decode_established_timings (edid, info))
-	return NULL;
-
-    if (!decode_standard_timings (edid, info))
-	return NULL;
-    
-    if (!decode_descriptors (edid, info))
+    if (decode_header (edid)
+	&& decode_vendor_and_product_identification (edid, info)
+	&& decode_edid_version (edid, info)
+	&& decode_display_parameters (edid, info)
+	&& decode_color_characteristics (edid, info)
+	&& decode_established_timings (edid, info)
+	&& decode_standard_timings (edid, info)
+	&& decode_descriptors (edid, info))
+    {
+	return info;
+    }
+    else
+    {
+	g_free (info);
 	return NULL;
-    
-    return info;
+    }
 }
diff --git a/libgnome-desktop/gnome-rr-config.c b/libgnome-desktop/gnome-rr-config.c
index 8b393b9..9a91ceb 100644
--- a/libgnome-desktop/gnome-rr-config.c
+++ b/libgnome-desktop/gnome-rr-config.c
@@ -32,6 +32,10 @@
 #include <glib/gstdio.h>
 #include "libgnomeui/gnome-rr-config.h"
 #include "edid.h"
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#include <gdk/gdkx.h>
+#include "gnome-rr-private.h"
 
 #define CONFIG_INTENDED_BASENAME "monitors.xml"
 #define CONFIG_BACKUP_BASENAME "monitors.xml.backup"
@@ -1612,6 +1616,13 @@ crtc_assignment_apply (CrtcAssignment *assign, GError **error)
     height = MIN (max_height, height);
 
     /* FMQ: do we need to check the sizes instead of clamping them? */
+
+    /* Grab the server while we fiddle with the CRTCs and the screen, so that
+     * apps that listen for RANDR notifications will only receive the final
+     * status.
+     */
+
+    gdk_x11_display_grab (gdk_screen_get_display (assign->screen->gdk_screen));
     
     /* Turn off all crtcs that are currently displaying outside the new screen,
      * or are not used in the new setup
@@ -1672,5 +1683,7 @@ crtc_assignment_apply (CrtcAssignment *assign, GError **error)
 	success = !state.has_error;
     }
 
+    gdk_x11_display_ungrab (gdk_screen_get_display (assign->screen->gdk_screen));
+
     return success;
 }
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
new file mode 100644
index 0000000..3de7d24
--- /dev/null
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -0,0 +1,39 @@
+#ifndef GNOME_RR_PRIVATE_H
+#define GNOME_RR_PRIVATE_H
+
+typedef struct ScreenInfo ScreenInfo;
+
+struct ScreenInfo
+{
+    int			min_width;
+    int			max_width;
+    int			min_height;
+    int			max_height;
+
+    XRRScreenResources *resources;
+    
+    GnomeRROutput **	outputs;
+    GnomeRRCrtc **	crtcs;
+    GnomeRRMode **	modes;
+    
+    GnomeRRScreen *	screen;
+
+    GnomeRRMode **	clone_modes;
+};
+
+struct GnomeRRScreen
+{
+    GdkScreen *			gdk_screen;
+    GdkWindow *			gdk_root;
+    Display *			xdisplay;
+    Screen *			xscreen;
+    Window			xroot;
+    ScreenInfo *		info;
+    
+    int				randr_event_base;
+    
+    GnomeRRScreenChanged	callback;
+    gpointer			data;
+};
+
+#endif
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index 109b89e..7d883bd 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -34,42 +34,9 @@
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
 
-#define DISPLAY(o) ((o)->info->screen->xdisplay)
-
-typedef struct ScreenInfo ScreenInfo;
-
-struct ScreenInfo
-{
-    int			min_width;
-    int			max_width;
-    int			min_height;
-    int			max_height;
-
-    XRRScreenResources *resources;
-    
-    GnomeRROutput **	outputs;
-    GnomeRRCrtc **	crtcs;
-    GnomeRRMode **	modes;
-    
-    GnomeRRScreen *	screen;
-
-    GnomeRRMode **	clone_modes;
-};
+#include "gnome-rr-private.h"
 
-struct GnomeRRScreen
-{
-    GdkScreen *			gdk_screen;
-    GdkWindow *			gdk_root;
-    Display *			xdisplay;
-    Screen *			xscreen;
-    Window			xroot;
-    ScreenInfo *		info;
-    
-    int				randr_event_base;
-    
-    GnomeRRScreenChanged	callback;
-    gpointer			data;
-};
+#define DISPLAY(o) ((o)->info->screen->xdisplay)
 
 struct GnomeRROutput
 {
openSUSE Build Service is sponsored by