diff options
author | Rui Matos <tiagomatos@gmail.com> | 2015-10-15 19:34:40 +0200 |
---|---|---|
committer | Rui Matos <tiagomatos@gmail.com> | 2015-10-16 13:57:26 +0200 |
commit | 43a1d43f2b6437173bfdc8db2e936791cffd4149 (patch) | |
tree | 55a73844ef32d84a6f09a457525a2be050ed67ec | |
parent | d6d377a44754520695f1fa558e21e8780c93b815 (diff) | |
download | mutter-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.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 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; |