[mutter] monitor-manager: Add support for suggested position for outputs
- From: Jonathon Jongsma <jjongsma src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor-manager: Add support for suggested position for outputs
- Date: Thu, 20 Nov 2014 18:35:00 +0000 (UTC)
commit f6f5f624d4e1bf13a8368110f695a393bc47c739
Author: Jonathon Jongsma <jjongsma redhat com>
Date: Mon Nov 10 15:36:47 2014 -0600
monitor-manager: Add support for suggested position for outputs
In recent versions of the QXL driver, it may set "suggested X|Y" connector
properties. These properties are used to indicate the position at which
multiple displays should be aligned. If all outputs have a suggested position,
the displays are arranged according to these positions, otherwise we fall back
to the default configuration.
At the moment, we trust that the driver has chosen sane values for the
suggested position.
src/backends/meta-monitor-config.c | 53 ++++++++++++++++++++++++
src/backends/meta-monitor-manager.h | 2 +
src/backends/native/meta-monitor-manager-kms.c | 2 +
src/backends/x11/meta-monitor-manager-xrandr.c | 52 +++++++++++++++++++++++
4 files changed, 109 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-monitor-config.c b/src/backends/meta-monitor-config.c
index 74239a3..81f0a5e 100644
--- a/src/backends/meta-monitor-config.c
+++ b/src/backends/meta-monitor-config.c
@@ -34,6 +34,7 @@
#include "config.h"
+#include "boxes-private.h"
#include "meta-monitor-config.h"
#include <string.h>
@@ -1096,6 +1097,55 @@ init_config_from_preferred_mode (MetaOutputConfig *config,
config->is_presentation = FALSE;
}
+/* This function handles configuring the outputs when the driver provides a
+ * suggested layout position for each output. This is done in recent versions
+ * of qxl and allows displays to be aligned on the guest in the same order as
+ * they are aligned on the client.
+ */
+static gboolean
+make_suggested_config (MetaMonitorConfig *self,
+ MetaOutput *outputs,
+ unsigned n_outputs,
+ int max_width,
+ int max_height,
+ MetaConfiguration *config)
+{
+ unsigned int i;
+ MetaOutput *primary;
+ GList *region = NULL;
+
+ g_return_if_fail (config != NULL);
+ primary = find_primary_output (outputs, n_outputs);
+
+ for (i = 0; i < n_outputs; i++)
+ {
+ gboolean is_primary = (&outputs[i] == primary);
+
+ if (outputs[i].suggested_x < 0 || outputs[i].suggested_y < 0)
+ return FALSE;
+
+ init_config_from_preferred_mode (&config->outputs[i], &outputs[i]);
+ config->outputs[i].is_primary = is_primary;
+
+ config->outputs[i].rect.x = outputs[i].suggested_x;
+ config->outputs[i].rect.y = outputs[i].suggested_y;
+
+ /* Reject the configuration if the suggested positions result in
+ * overlapping displays */
+ if (meta_rectangle_overlaps_with_region (region, &config->outputs[i].rect))
+ {
+ g_warning ("Overlapping outputs, rejecting suggested configuration");
+ g_list_free (region);
+ return FALSE;
+ }
+
+ region = g_list_prepend (region, &config->outputs[i].rect);
+ }
+
+ g_list_free (region);
+ return TRUE;
+}
+
static void
make_linear_config (MetaMonitorConfig *self,
MetaOutput *outputs,
@@ -1228,6 +1278,9 @@ make_default_config (MetaMonitorConfig *self,
return ret;
}
+ if (make_suggested_config (self, outputs, n_outputs, max_width, max_height, ret))
+ return ret;
+
if (use_stored_config &&
extend_stored_config (self, outputs, n_outputs, max_width, max_height, ret))
return ret;
diff --git a/src/backends/meta-monitor-manager.h b/src/backends/meta-monitor-manager.h
index 4d1b3b7..102759f 100644
--- a/src/backends/meta-monitor-manager.h
+++ b/src/backends/meta-monitor-manager.h
@@ -116,6 +116,8 @@ struct _MetaOutput
/* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
gboolean hotplug_mode_update;
+ gint suggested_x;
+ gint suggested_y;
};
struct _MetaCRTC
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 6334487..c528516 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -415,6 +415,8 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
meta_output->name = make_output_name (connector);
meta_output->width_mm = connector->mmWidth;
meta_output->height_mm = connector->mmHeight;
+ meta_output->suggested_x = -1;
+ meta_output->suggested_y = -1;
switch (connector->subpixel)
{
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 3fdfca2..dd32bd4 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -140,6 +140,34 @@ meta_monitor_transform_from_xrandr_all (Rotation rotation)
}
static gboolean
+output_get_integer_property (MetaMonitorManagerXrandr *manager_xrandr,
+ MetaOutput *output, const char *propname,
+ gint *value)
+{
+ gboolean exists = FALSE;
+ Atom atom, actual_type;
+ int actual_format;
+ unsigned long nitems, bytes_after;
+ unsigned char *buffer;
+
+ atom = XInternAtom (manager_xrandr->xdisplay, propname, False);
+ XRRGetOutputProperty (manager_xrandr->xdisplay,
+ (XID)output->winsys_id,
+ atom,
+ 0, G_MAXLONG, False, False, XA_INTEGER,
+ &actual_type, &actual_format,
+ &nitems, &bytes_after, &buffer);
+
+ exists = (actual_type == XA_INTEGER && actual_format == 32 && nitems == 1);
+
+ if (exists && value != NULL)
+ *value = ((int*)buffer)[0];
+
+ XFree (buffer);
+ return exists;
+}
+
+static gboolean
output_get_property_exists (MetaMonitorManagerXrandr *manager_xrandr,
MetaOutput *output, const char *propname)
{
@@ -356,6 +384,28 @@ output_get_hotplug_mode_update (MetaMonitorManagerXrandr *manager_xrandr,
return output_get_property_exists (manager_xrandr, output, "hotplug_mode_update");
}
+static gint
+output_get_suggested_x (MetaMonitorManagerXrandr *manager_xrandr,
+ MetaOutput *output)
+{
+ gint val;
+ if (output_get_integer_property (manager_xrandr, output, "suggested X", &val))
+ return val;
+
+ return -1;
+}
+
+static gint
+output_get_suggested_y (MetaMonitorManagerXrandr *manager_xrandr,
+ MetaOutput *output)
+{
+ gint val;
+ if (output_get_integer_property (manager_xrandr, output, "suggested Y", &val))
+ return val;
+
+ return -1;
+}
+
static char *
get_xmode_name (XRRModeInfo *xmode)
{
@@ -543,6 +593,8 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
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);
+ meta_output->suggested_x = output_get_suggested_x (manager_xrandr, meta_output);
+ meta_output->suggested_y = output_get_suggested_y (manager_xrandr, meta_output);
meta_output->n_modes = output->nmode;
meta_output->modes = g_new0 (MetaMonitorMode *, meta_output->n_modes);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]