summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-02-02 16:02:04 +1000
committerMatthias Clasen <mclasen@redhat.com>2015-05-21 23:09:04 -0400
commite670720d196bac1cef6f88313f6514cdd8c4a0c5 (patch)
treed25709dbe300560439e2285eea7103ed5d922f9f
parent61cc10760d84f8600b6faf11046bb7b9a276e942 (diff)
downloadgtk+-e670720d196bac1cef6f88313f6514cdd8c4a0c5.tar.gz
gtk3: add randr 1.5 monitor support
This patch introduces support for using the newly introduced monitor objects in the XRandR protocol. These objects are meant to be used to denote a set of rectangles representing a logical monitor, and are used to hide details like monitor tiling and virtual gpu outputs. This uses the new objects instead of crtc/outputs objects when they are available to create the monitor lists. X server 1.18 is required on the server side for randr 1.5. https://bugzilla.gnome.org/show_bug.cgi?id=749561
-rw-r--r--configure.ac3
-rw-r--r--gdk/x11/gdkdisplay-x11.c5
-rw-r--r--gdk/x11/gdkdisplay-x11.h1
-rw-r--r--gdk/x11/gdkscreen-x11.c58
4 files changed, 67 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 1f3185044f..106ff8ff34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1184,6 +1184,9 @@ if test "x$enable_x11_backend" = xyes; then
if $PKG_CONFIG --exists "xrandr >= 1.2.99" ; then
AC_DEFINE(HAVE_RANDR, 1, [Have the Xrandr extension library])
+ if $PKG_CONFIG --exists "xrandr >= 1.5.0" ; then
+ AC_DEFINE(HAVE_RANDR15, 1, [Have the Xrandr 1.5 extension library])
+ fi
X_PACKAGES="$X_PACKAGES xrandr"
X_EXTENSIONS="$X_EXTENSIONS XRANDR"
elif test x"$enable_xrandr" = xyes; then
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 1477a75d8b..d4be951bb0 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -1397,6 +1397,7 @@ _gdk_x11_display_open (const gchar *display_name)
/* RandR must be initialized before we initialize the screens */
display_x11->have_randr12 = FALSE;
display_x11->have_randr13 = FALSE;
+ display_x11->have_randr15 = FALSE;
#ifdef HAVE_RANDR
if (XRRQueryExtension (display_x11->xdisplay,
&display_x11->xrandr_event_base, &ignore))
@@ -1409,6 +1410,10 @@ _gdk_x11_display_open (const gchar *display_name)
display_x11->have_randr12 = TRUE;
if (minor >= 3 || major > 1)
display_x11->have_randr13 = TRUE;
+#ifdef HAVE_RANDR15
+ if (minor >= 5 || major > 1)
+ display_x11->have_randr15 = TRUE;
+#endif
}
gdk_x11_register_standard_event_type (display, display_x11->xrandr_event_base, RRNumberEvents);
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
index f601ed3763..b0c49a0858 100644
--- a/gdk/x11/gdkdisplay-x11.h
+++ b/gdk/x11/gdkdisplay-x11.h
@@ -66,6 +66,7 @@ struct _GdkX11Display
gboolean have_randr12;
gboolean have_randr13;
+ gboolean have_randr15;
gint xrandr_event_base;
/* If the SECURITY extension is in place, whether this client holds
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index 5c71c538a7..a1d0a7c954 100644
--- a/gdk/x11/gdkscreen-x11.c
+++ b/gdk/x11/gdkscreen-x11.c
@@ -613,6 +613,59 @@ monitor_compare_function (GdkX11Monitor *monitor1,
}
#endif
+#ifdef HAVE_RANDR15
+static gboolean
+init_randr15 (GdkScreen *screen)
+{
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
+ GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
+ XRRMonitorInfo *rr_monitors;
+ int num_rr_monitors;
+ int i;
+ GArray *monitors;
+ int primary_idx = 0;
+
+ if (!display_x11->have_randr15)
+ return FALSE;
+
+ rr_monitors = XRRGetMonitors (x11_screen->xdisplay,
+ x11_screen->xroot_window,
+ True,
+ &num_rr_monitors);
+ if (!rr_monitors)
+ return FALSE;
+
+ monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor),
+ num_rr_monitors);
+ for (i = 0; i < num_rr_monitors; i++)
+ {
+ GdkX11Monitor monitor;
+ init_monitor_geometry (&monitor,
+ rr_monitors[i].x,
+ rr_monitors[i].y,
+ rr_monitors[i].width,
+ rr_monitors[i].height);
+
+ monitor.width_mm = rr_monitors[i].mwidth;
+ monitor.height_mm = rr_monitors[i].mheight;
+ monitor.output = rr_monitors[i].outputs[0];
+ if (rr_monitors[i].primary)
+ primary_idx = i;
+ g_array_append_val (monitors, monitor);
+ }
+ XRRFreeMonitors (rr_monitors);
+
+ g_array_sort (monitors,
+ (GCompareFunc) monitor_compare_function);
+ x11_screen->n_monitors = monitors->len;
+ x11_screen->monitors = (GdkX11Monitor *) g_array_free (monitors, FALSE);
+
+ x11_screen->primary_monitor = primary_idx;
+ return x11_screen->n_monitors > 0;
+}
+#endif
+
static gboolean
init_randr13 (GdkScreen *screen)
{
@@ -1060,6 +1113,11 @@ init_multihead (GdkScreen *screen)
if (init_fake_xinerama (screen))
return;
+#ifdef HAVE_RANDR15
+ if (init_randr15 (screen))
+ return;
+#endif
+
if (init_randr13 (screen))
return;