[mutter] monitor-manager-xrandr: Be more robust when reading XRROutputInfos



commit 43a1d43f2b6437173bfdc8db2e936791cffd4149
Author: Rui Matos <tiagomatos gmail com>
Date:   Thu Oct 15 19:34:40 2015 +0200

    monitor-manager-xrandr: Be more robust when reading XRROutputInfos
    
    We might get modes in XRROutputInfos that aren't in the
    XRRScreenResources we get earlier. This always seems to be transient,
    i.e. when it happens, the X server will usually send us a follow up
    RRScreenChangeNotify where we then get a "stable" view of the world
    again.
    
    In any case, when these glitches happen, we end up with NULL pointers
    in the MetaOutput->modes array which makes us crash later on. This
    patch ensures that doesn't happen.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756660

 src/backends/x11/meta-monitor-manager-xrandr.c |   42 ++++++++++++++++-------
 1 files changed, 29 insertions(+), 13 deletions(-)
---
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 9008841..0acb217 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -637,6 +637,32 @@ output_get_connector_type (MetaMonitorManagerXrandr *manager_xrandr,
   return META_CONNECTOR_TYPE_Unknown;
 }
 
+static void
+output_get_modes (MetaMonitorManager *manager,
+                  MetaOutput         *meta_output,
+                  XRROutputInfo      *output)
+{
+  guint j, k;
+  guint n_actual_modes;
+
+  meta_output->modes = g_new0 (MetaMonitorMode *, output->nmode);
+
+  n_actual_modes = 0;
+  for (j = 0; j < (guint)output->nmode; j++)
+    {
+      for (k = 0; k < manager->n_modes; k++)
+        {
+          if (output->modes[j] == (XID)manager->modes[k].mode_id)
+            {
+              meta_output->modes[n_actual_modes] = &manager->modes[k];
+              n_actual_modes += 1;
+              break;
+            }
+        }
+    }
+  meta_output->n_modes = n_actual_modes;
+}
+
 static char *
 get_xmode_name (XRRModeInfo *xmode)
 {
@@ -773,6 +799,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
       MetaOutput *meta_output;
 
       output = XRRGetOutputInfo (manager_xrandr->xdisplay, resources, resources->outputs[i]);
+      if (!output)
+        continue;
 
       meta_output = &manager->outputs[n_actual_outputs];
 
@@ -796,19 +824,7 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
           meta_output->connector_type = output_get_connector_type (manager_xrandr, meta_output);
 
          output_get_tile_info (manager_xrandr, meta_output);
-         meta_output->n_modes = output->nmode;
-         meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
-         for (j = 0; j < meta_output->n_modes; j++)
-           {
-             for (k = 0; k < manager->n_modes; k++)
-               {
-                 if (output->modes[j] == (XID)manager->modes[k].mode_id)
-                   {
-                     meta_output->modes[j] = &manager->modes[k];
-                     break;
-                   }
-               }
-           }
+         output_get_modes (manager, meta_output, output);
          meta_output->preferred_mode = meta_output->modes[0];
 
          meta_output->n_possible_crtcs = output->ncrtc;


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