[mutter/wayland] xrandr: use "hotplug_mode_update" property
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wayland] xrandr: use "hotplug_mode_update" property
- Date: Tue, 19 Nov 2013 18:56:17 +0000 (UTC)
commit 957513242c26be458be7a101b83180e3f59f6a44
Author: Marc-André Lureau <marcandre lureau gmail com>
Date: Thu Oct 31 14:37:44 2013 +0100
xrandr: use "hotplug_mode_update" property
Use the "hotplug_mode_update" connector property indicating that the
screen settings should be updated: get a new preferred mode on hotplug
events to handle dynamic guest resizing (where you resize the host
window and the guest resizes with it).
https://bugzilla.gnome.org/show_bug.cgi?id=711216
src/core/monitor-config.c | 16 ++++++++
src/core/monitor-private.h | 4 ++
src/core/monitor-xrandr.c | 83 ++++++++++++++++++++++++++++++++-----------
src/meta/atomnames.h | 1 +
4 files changed, 83 insertions(+), 21 deletions(-)
---
diff --git a/src/core/monitor-config.c b/src/core/monitor-config.c
index ddda53a..e5aee4d 100644
--- a/src/core/monitor-config.c
+++ b/src/core/monitor-config.c
@@ -817,6 +817,22 @@ meta_monitor_config_match_current (MetaMonitorConfig *self,
return ok;
}
+gboolean
+meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
+{
+ MetaOutput *outputs;
+ unsigned n_outputs;
+ unsigned int i;
+
+ outputs = meta_monitor_manager_get_outputs (manager, &n_outputs);
+
+ for (i = 0; i < n_outputs; i++)
+ if (outputs[i].hotplug_mode_update)
+ return TRUE;
+
+ return FALSE;
+}
+
static MetaConfiguration *
meta_monitor_config_get_stored (MetaMonitorConfig *self,
MetaOutput *outputs,
diff --git a/src/core/monitor-private.h b/src/core/monitor-private.h
index a8eeb67..fdb11a7 100644
--- a/src/core/monitor-private.h
+++ b/src/core/monitor-private.h
@@ -119,6 +119,9 @@ struct _MetaOutput
gpointer driver_private;
GDestroyNotify driver_notify;
+
+ /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
+ gboolean hotplug_mode_update;
};
struct _MetaCRTC
@@ -407,6 +410,7 @@ void meta_monitor_manager_free_output_array (MetaOutput *old_outpu
int n_old_outputs);
void meta_monitor_manager_free_mode_array (MetaMonitorMode *old_modes,
int n_old_modes);
+gboolean meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager);
/* Returns true if transform causes width and height to be inverted
This is true for the odd transforms in the enum */
diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c
index ab1cf11..e723c1c 100644
--- a/src/core/monitor-xrandr.c
+++ b/src/core/monitor-xrandr.c
@@ -311,6 +311,29 @@ read_output_edid (MetaMonitorManagerXrandr *manager_xrandr,
return NULL;
}
+static gboolean
+output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
+ XID output_id)
+{
+ MetaDisplay *display = meta_get_display ();
+ XRRPropertyInfo *info;
+ gboolean result = FALSE;
+
+ meta_error_trap_push (display);
+ info = XRRQueryOutputProperty (manager_xrandr->xdisplay, output_id,
+ display->atom_hotplug_mode_update);
+ meta_error_trap_pop (display);
+
+ if (info)
+ {
+ result = TRUE;
+ XFree (info);
+ }
+
+ return result;
+}
+
+
static void
meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
{
@@ -484,6 +507,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
meta_output->width_mm = output->mm_width;
meta_output->height_mm = output->mm_height;
meta_output->subpixel_order = COGL_SUBPIXEL_ORDER_UNKNOWN;
+ meta_output->hotplug_mode_update =
+ output_get_hotplug_mode_update (manager_xrandr, meta_output->output_id);
meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
@@ -969,6 +994,16 @@ meta_monitor_manager_xrandr_set_crtc_gamma (MetaMonitorManager *manager,
XRRFreeGamma (gamma);
}
+static void
+meta_monitor_manager_xrandr_rebuild_derived (MetaMonitorManager *manager)
+{
+ /* This will be a no-op if the change was from our side, as
+ we already called it in the DBus method handler */
+ meta_monitor_config_update_current (manager->config, manager);
+
+ meta_monitor_manager_rebuild_derived (manager);
+}
+
static gboolean
meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
XEvent *event)
@@ -978,6 +1013,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
MetaCRTC *old_crtcs;
MetaMonitorMode *old_modes;
unsigned int n_old_outputs, n_old_modes;
+ gboolean new_config;
if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
return FALSE;
@@ -994,31 +1030,36 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManager *manager,
manager->serial++;
meta_monitor_manager_xrandr_read_current (manager);
- /* Check if the current intended configuration has the same outputs
- as the new real one, or if the event is a result of an XRandR call.
- If so, we can go straight to rebuild the logical config and tell
- the outside world.
- Otherwise, this event was caused by hotplug, so give a chance to
- MetaMonitorConfig.
-
- Note that we need to check both the timestamps and the list of
- outputs, because the X server might emit spurious events with
- new configTimestamps (bug 702804), and the driver may have
- changed the EDID for some other reason (old broken qxl and vbox
- drivers...).
- */
- if (manager_xrandr->resources->timestamp >= manager_xrandr->resources->configTimestamp ||
- meta_monitor_config_match_current (manager->config, manager))
- {
- /* This will be a no-op if the change was from our side, as
- we already called it in the DBus method handler */
- meta_monitor_config_update_current (manager->config, manager);
+ new_config = manager_xrandr->resources->timestamp >=
+ manager_xrandr->resources->configTimestamp;
+ if (meta_monitor_manager_has_hotplug_mode_update (manager))
- meta_monitor_manager_rebuild_derived (manager);
+ {
+ /* Check if the current intended configuration is a result of an
+ XRandR call. Otherwise, hotplug_mode_update tells us to get
+ a new preferred mode on hotplug events to handle dynamic
+ guest resizing. */
+ if (new_config)
+ meta_monitor_manager_xrandr_rebuild_derived (manager);
+ else
+ meta_monitor_config_make_default (manager->config, manager);
}
else
{
- if (!meta_monitor_config_apply_stored (manager->config, manager))
+ /* Check if the current intended configuration has the same outputs
+ as the new real one, or if the event is a result of an XRandR call.
+ If so, we can go straight to rebuild the logical config and tell
+ the outside world.
+ Otherwise, this event was caused by hotplug, so give a chance to
+ MetaMonitorConfig.
+
+ Note that we need to check both the timestamps and the list of
+ outputs, because the X server might emit spurious events with new
+ configTimestamps (bug 702804), and the driver may have changed
+ the EDID for some other reason (old qxl and vbox drivers). */
+ if (new_config || meta_monitor_config_match_current (manager->config, manager))
+ meta_monitor_manager_xrandr_rebuild_derived (manager);
+ else if (!meta_monitor_config_apply_stored (manager->config, manager))
meta_monitor_config_make_default (manager->config, manager);
}
diff --git a/src/meta/atomnames.h b/src/meta/atomnames.h
index 43a18a9..e90b0ab 100644
--- a/src/meta/atomnames.h
+++ b/src/meta/atomnames.h
@@ -82,6 +82,7 @@ item(VERSION)
item(ATOM_PAIR)
item(BACKLIGHT)
item(_XKB_RULES_NAMES)
+item(hotplug_mode_update)
/* Oddities: These are used, and we need atoms for them,
* but when we need all _NET_WM hints (i.e. when we're making
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]