[gtk+/gtk-3-18] X11, GdkScreen: properly implement init_randr15 including output name



commit 8419f894d60f2569f33e173a0c78ce2ef721ac6a
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Sat Feb 20 01:31:59 2016 +0100

    X11, GdkScreen: properly implement init_randr15 including output name
    
    https://bugzilla.gnome.org/show_bug.cgi?id=762319

 gdk/x11/gdkscreen-x11.c |   56 ++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 53 insertions(+), 3 deletions(-)
---
diff --git a/gdk/x11/gdkscreen-x11.c b/gdk/x11/gdkscreen-x11.c
index 44bb69f..7374336 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;


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