summaryrefslogtreecommitdiff
path: root/gdk/x11
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2016-02-20 01:31:59 +0100
committerMatthias Clasen <mclasen@redhat.com>2016-02-20 10:45:44 -0500
commit1dda932109f10d7582a8da9fd22626da835e9124 (patch)
tree223325b22633096cfd1884b1f1defad1ce4408a1 /gdk/x11
parent079e90b78076192c6e0e7e95b1dc91b1ea608962 (diff)
downloadgtk+-1dda932109f10d7582a8da9fd22626da835e9124.tar.gz
X11, GdkScreen: properly implement init_randr15 including output name
https://bugzilla.gnome.org/show_bug.cgi?id=762319
Diffstat (limited to 'gdk/x11')
-rw-r--r--gdk/x11/gdkscreen-x11.c56
1 files changed, 53 insertions, 3 deletions
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index abd3cae36e..2bbac70b04 100644
--- a/gdk/x11/gdkscreen-x11.c
+++ b/gdk/x11/gdkscreen-x11.c
@@ -621,6 +621,10 @@ init_randr15 (GdkScreen *screen)
GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
GdkX11Screen *x11_screen = GDK_X11_SCREEN (screen);
XRRMonitorInfo *rr_monitors;
+ XRRScreenResources *resources;
+ RROutput output;
+ RROutput first_output = None;
+ gboolean randr12_compat = FALSE;
int num_rr_monitors;
int i;
GArray *monitors;
@@ -629,6 +633,11 @@ init_randr15 (GdkScreen *screen)
if (!display_x11->have_randr15)
return FALSE;
+ resources = XRRGetScreenResourcesCurrent (x11_screen->xdisplay,
+ x11_screen->xroot_window);
+ if (!resources)
+ return FALSE;
+
rr_monitors = XRRGetMonitors (x11_screen->xdisplay,
x11_screen->xroot_window,
True,
@@ -638,8 +647,25 @@ init_randr15 (GdkScreen *screen)
monitors = g_array_sized_new (FALSE, TRUE, sizeof (GdkX11Monitor),
num_rr_monitors);
+
for (i = 0; i < num_rr_monitors; i++)
{
+ output = rr_monitors[i].outputs[0];
+ XRROutputInfo *output_info =
+ XRRGetOutputInfo (x11_screen->xdisplay, resources, output);
+
+ /* Non RandR1.2+ X driver have output name "default" */
+ randr12_compat |= !g_strcmp0 (output_info->name, "default");
+
+ if (output_info->connection == RR_Disconnected)
+ {
+ XRRFreeOutputInfo (output_info);
+ continue;
+ }
+
+ if (first_output == None)
+ first_output = output;
+
GdkX11Monitor monitor;
init_monitor_geometry (&monitor,
rr_monitors[i].x,
@@ -649,28 +675,52 @@ init_randr15 (GdkScreen *screen)
monitor.width_mm = rr_monitors[i].mwidth;
monitor.height_mm = rr_monitors[i].mheight;
- monitor.output = rr_monitors[i].outputs[0];
+ monitor.output = output;
+ monitor.output_name = g_strndup (output_info->name, output_info->nameLen);
+
if (rr_monitors[i].primary)
primary_output = monitor.output;
g_array_append_val (monitors, monitor);
+ XRRFreeOutputInfo (output_info);
}
XRRFreeMonitors (rr_monitors);
+ /* non RandR 1.2+ X driver doesn't return any usable multihead data */
+ if (randr12_compat)
+ {
+ guint n_monitors = monitors->len;
+
+ free_monitors ((GdkX11Monitor *)g_array_free (monitors, FALSE),
+ n_monitors);
+ return FALSE;
+ }
+
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++)
+ for (i = 0; i < x11_screen->n_monitors; ++i)
{
if (x11_screen->monitors[i].output == primary_output)
{
x11_screen->primary_monitor = i;
break;
}
+
+ /* No RandR1.3+ available or no primary set, fall back to prefer LVDS as primary if present */
+ if (primary_output == None &&
+ g_ascii_strncasecmp (x11_screen->monitors[i].output_name, "LVDS", 4) == 0)
+ {
+ x11_screen->primary_monitor = i;
+ break;
+ }
+
+ /* No primary specified and no LVDS found */
+ if (x11_screen->monitors[i].output == first_output)
+ x11_screen->primary_monitor = i;
}
return x11_screen->n_monitors > 0;