summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRui Matos <tiagomatos@gmail.com>2015-10-15 19:34:40 +0200
committerRui Matos <tiagomatos@gmail.com>2015-10-16 13:57:26 +0200
commit43a1d43f2b6437173bfdc8db2e936791cffd4149 (patch)
tree55a73844ef32d84a6f09a457525a2be050ed67ec
parentd6d377a44754520695f1fa558e21e8780c93b815 (diff)
downloadmutter-43a1d43f2b6437173bfdc8db2e936791cffd4149.tar.gz
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
-rw-r--r--src/backends/x11/meta-monitor-manager-xrandr.c42
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 900884170..0acb217a8 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;