gtk2-24: add randr 1.5 monitor support [v3]

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.

This patch was cherry-picked and fixed from the gtk3 branch and
squashes the two following additional fixupes:

v2: Fix primary monitor determination with XRANDR 1.5
	Matthias Clasen <mclasen@redhat.com>
v3: Fix a typo in the previous patch
	Matthias Clasen <mclasen@redhat.com>

https://bugzilla.gnome.org/show_bug.cgi?id=759912
This commit is contained in:
Dave Airlie
2015-02-02 16:02:04 +10:00
committed by Matthias Clasen
parent 6de93df9a4
commit 8bbd765930
4 changed files with 79 additions and 0 deletions

View File

@@ -1192,6 +1192,9 @@ if test "x$gdktarget" = "xx11"; 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"
fi

View File

@@ -182,6 +182,7 @@ gdk_display_open (const gchar *display_name)
/* RandR must be initialized before we initialize the screens */
display_x11->have_randr13 = FALSE;
display_x11->have_randr15 = FALSE;
#ifdef HAVE_RANDR
if (XRRQueryExtension (display_x11->xdisplay,
&display_x11->xrandr_event_base, &ignore))
@@ -193,6 +194,11 @@ gdk_display_open (const gchar *display_name)
if ((major == 1 && 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);
}
#endif

View File

@@ -87,6 +87,7 @@ struct _GdkDisplayX11
gint xdamage_event_base;
gboolean have_randr13;
gboolean have_randr15;
gint xrandr_event_base;
/* If the SECURITY extension is in place, whether this client holds

View File

@@ -740,6 +740,70 @@ monitor_compare_function (GdkX11Monitor *monitor1,
}
#endif
#ifdef HAVE_RANDR15
static gboolean
init_randr15 (GdkScreen *screen)
{
GdkDisplay *display = gdk_screen_get_display (screen);
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
GdkScreenX11 *x11_screen = GDK_SCREEN_X11 (screen);
XRRMonitorInfo *rr_monitors;
int num_rr_monitors;
int i;
GArray *monitors;
XID primary_output = None;
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_output = monitor.output;
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 = 0;
for (i = 0; i < x11_screen->n_monitors; i++)
{
if (x11_screen->monitors[i].output == primary_output)
{
x11_screen->primary_monitor = i;
break;
}
}
return x11_screen->n_monitors > 0;
}
#endif
static gboolean
init_randr13 (GdkScreen *screen)
{
@@ -1020,6 +1084,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;