[gnome-desktop/wip/wayland-display: 1/2] API: GnomeRR: replace direct XRandR calls with DBus calls to mutter
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-desktop/wip/wayland-display: 1/2] API: GnomeRR: replace direct XRandR calls with DBus calls to mutter
- Date: Fri, 26 Jul 2013 15:18:36 +0000 (UTC)
commit 91e5b6ed6a8e023a0e80035f5a3fed7f16917287
Author: Giovanni Campagna <gcampagn redhat com>
Date: Fri Jul 26 13:40:41 2013 +0200
API: GnomeRR: replace direct XRandR calls with DBus calls to mutter
Mutter now provides a DBus API that wraps XRandR and abstracts
away the detail of running X or wayland.
A number of API changes are needed, as GnomeRR is no longer in
charge of maintaining the monitors.xml file updated.
libgnome-desktop/Makefile.am | 12 +
libgnome-desktop/gnome-rr-config.c | 1032 +++------------------
libgnome-desktop/gnome-rr-config.h | 33 +-
libgnome-desktop/gnome-rr-debug.c | 2 +-
libgnome-desktop/gnome-rr-output-info.c | 22 +-
libgnome-desktop/gnome-rr-private.h | 53 +-
libgnome-desktop/gnome-rr.c | 1534 ++++++-------------------------
libgnome-desktop/gnome-rr.h | 56 +-
libgnome-desktop/xrandr.xml | 241 +++++
9 files changed, 769 insertions(+), 2216 deletions(-)
---
diff --git a/libgnome-desktop/Makefile.am b/libgnome-desktop/Makefile.am
index 7041be5..c19a3d5 100644
--- a/libgnome-desktop/Makefile.am
+++ b/libgnome-desktop/Makefile.am
@@ -42,6 +42,7 @@ introspection_sources = \
libgnome_desktop_3_la_SOURCES = \
$(introspection_sources) \
+ $(dbus_xrandr_built_sources) \
gnome-datetime-source.h \
gnome-datetime-source.c \
gnome-rr-private.h \
@@ -49,6 +50,17 @@ libgnome_desktop_3_la_SOURCES = \
edid.h \
locarchive.h
+dbus_xrandr_built_sources = meta-dbus-xrandr.c meta-dbus-xrandr.h
+
+$(dbus_xrandr_built_sources) : Makefile.am xrandr.xml
+ $(AM_V_GEN)gdbus-codegen \
+ --interface-prefix org.gnome.Mutter \
+ --c-namespace MetaDBus \
+ --generate-c-code meta-dbus-xrandr \
+ xrandr.xml
+
+BUILT_SOURCES = $(dbus_xrandr_built_sources)
+
libgnome_desktop_3_la_LIBADD = \
$(XLIB_LIBS) \
$(LIBM) \
diff --git a/libgnome-desktop/gnome-rr-config.c b/libgnome-desktop/gnome-rr-config.c
index 06ff2e6..2fb1632 100644
--- a/libgnome-desktop/gnome-rr-config.c
+++ b/libgnome-desktop/gnome-rr-config.c
@@ -1,8 +1,8 @@
/* gnome-rr-config.c
* -*- c-basic-offset: 4 -*-
*
- * Copyright 2007, 2008, Red Hat, Inc.
- * Copyright 2010 Giovanni Campagna
+ * Copyright 2007, 2008, 2013 Red Hat, Inc.
+ * Copyright 2010 Giovanni Campagna <scampa giovanni gmail com>
*
* This file is part of the Gnome Library.
*
@@ -74,16 +74,10 @@
* </monitors>
*/
-/* A helper wrapper around the GMarkup parser stuff */
-static gboolean parse_file_gmarkup (const gchar *file,
- const GMarkupParser *parser,
- gpointer data,
- GError **err);
-
typedef struct CrtcAssignment CrtcAssignment;
static gboolean crtc_assignment_apply (CrtcAssignment *assign,
- guint32 timestamp,
+ gboolean persistent,
GError **error);
static CrtcAssignment *crtc_assignment_new (GnomeRRScreen *screen,
GnomeRROutputInfo **outputs,
@@ -98,357 +92,6 @@ enum {
G_DEFINE_TYPE (GnomeRRConfig, gnome_rr_config, G_TYPE_OBJECT)
-typedef struct Parser Parser;
-
-/* Parser for monitor configurations */
-struct Parser
-{
- int config_file_version;
- GnomeRROutputInfo * output;
- GnomeRRConfig * configuration;
- GPtrArray * outputs;
- GPtrArray * configurations;
- GQueue * stack;
-};
-
-static int
-parse_int (const char *text)
-{
- return strtol (text, NULL, 0);
-}
-
-static guint
-parse_uint (const char *text)
-{
- return strtoul (text, NULL, 0);
-}
-
-static gboolean
-stack_is (Parser *parser,
- const char *s1,
- ...)
-{
- GList *stack = NULL;
- const char *s;
- GList *l1, *l2;
- va_list args;
-
- stack = g_list_prepend (stack, (gpointer)s1);
-
- va_start (args, s1);
-
- s = va_arg (args, const char *);
- while (s)
- {
- stack = g_list_prepend (stack, (gpointer)s);
- s = va_arg (args, const char *);
- }
-
- l1 = stack;
- l2 = parser->stack->head;
-
- while (l1 && l2)
- {
- if (strcmp (l1->data, l2->data) != 0)
- {
- g_list_free (stack);
- return FALSE;
- }
-
- l1 = l1->next;
- l2 = l2->next;
- }
-
- g_list_free (stack);
-
- return (!l1 && !l2);
-}
-
-static void
-handle_start_element (GMarkupParseContext *context,
- const gchar *name,
- const gchar **attr_names,
- const gchar **attr_values,
- gpointer user_data,
- GError **err)
-{
- Parser *parser = user_data;
-
- if (strcmp (name, "output") == 0)
- {
- int i;
- g_assert (parser->output == NULL);
-
- parser->output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL);
- parser->output->priv->rotation = 0;
-
- for (i = 0; attr_names[i] != NULL; ++i)
- {
- if (strcmp (attr_names[i], "name") == 0)
- {
- parser->output->priv->name = g_strdup (attr_values[i]);
- break;
- }
- }
-
- if (!parser->output->priv->name)
- {
- /* This really shouldn't happen, but it's better to make
- * something up than to crash later.
- */
- g_warning ("Malformed monitor configuration file");
-
- parser->output->priv->name = g_strdup ("default");
- }
- parser->output->priv->connected = FALSE;
- parser->output->priv->on = FALSE;
- parser->output->priv->primary = FALSE;
- }
- else if (strcmp (name, "configuration") == 0)
- {
- g_assert (parser->configuration == NULL);
-
- parser->configuration = g_object_new (GNOME_TYPE_RR_CONFIG, NULL);
- parser->configuration->priv->clone = FALSE;
- parser->configuration->priv->outputs = NULL;
- }
- else if (strcmp (name, "monitors") == 0)
- {
- int i;
-
- for (i = 0; attr_names[i] != NULL; i++)
- {
- if (strcmp (attr_names[i], "version") == 0)
- {
- parser->config_file_version = parse_int (attr_values[i]);
- break;
- }
- }
- }
-
- g_queue_push_tail (parser->stack, g_strdup (name));
-}
-
-static void
-handle_end_element (GMarkupParseContext *context,
- const gchar *name,
- gpointer user_data,
- GError **err)
-{
- Parser *parser = user_data;
-
- if (strcmp (name, "output") == 0)
- {
- /* If no rotation properties were set, just use GNOME_RR_ROTATION_0 */
- if (parser->output->priv->rotation == 0)
- parser->output->priv->rotation = GNOME_RR_ROTATION_0;
-
- g_ptr_array_add (parser->outputs, parser->output);
-
- parser->output = NULL;
- }
- else if (strcmp (name, "configuration") == 0)
- {
- g_ptr_array_add (parser->outputs, NULL);
- parser->configuration->priv->outputs =
- (GnomeRROutputInfo **)g_ptr_array_free (parser->outputs, FALSE);
- parser->outputs = g_ptr_array_new ();
- g_ptr_array_add (parser->configurations, parser->configuration);
- parser->configuration = NULL;
- }
-
- g_free (g_queue_pop_tail (parser->stack));
-}
-
-#define TOPLEVEL_ELEMENT (parser->config_file_version > 0 ? "monitors" : NULL)
-
-static void
-handle_text (GMarkupParseContext *context,
- const gchar *text,
- gsize text_len,
- gpointer user_data,
- GError **err)
-{
- Parser *parser = user_data;
-
- if (stack_is (parser, "vendor", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->connected = TRUE;
-
- strncpy ((gchar*) parser->output->priv->vendor, text, 3);
- parser->output->priv->vendor[3] = 0;
- }
- else if (stack_is (parser, "clone", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- parser->configuration->priv->clone = TRUE;
- }
- else if (stack_is (parser, "product", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->connected = TRUE;
-
- parser->output->priv->product = parse_int (text);
- }
- else if (stack_is (parser, "serial", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->connected = TRUE;
-
- parser->output->priv->serial = parse_uint (text);
- }
- else if (stack_is (parser, "width", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->on = TRUE;
-
- parser->output->priv->width = parse_int (text);
- }
- else if (stack_is (parser, "x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->on = TRUE;
-
- parser->output->priv->x = parse_int (text);
- }
- else if (stack_is (parser, "y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->on = TRUE;
-
- parser->output->priv->y = parse_int (text);
- }
- else if (stack_is (parser, "height", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->on = TRUE;
-
- parser->output->priv->height = parse_int (text);
- }
- else if (stack_is (parser, "rate", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- parser->output->priv->on = TRUE;
-
- parser->output->priv->rate = parse_int (text);
- }
- else if (stack_is (parser, "rotation", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "normal") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_ROTATION_0;
- }
- else if (strcmp (text, "left") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_ROTATION_90;
- }
- else if (strcmp (text, "upside_down") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_ROTATION_180;
- }
- else if (strcmp (text, "right") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_ROTATION_270;
- }
- }
- else if (stack_is (parser, "reflect_x", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_REFLECT_X;
- }
- }
- else if (stack_is (parser, "reflect_y", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- {
- parser->output->priv->rotation |= GNOME_RR_REFLECT_Y;
- }
- }
- else if (stack_is (parser, "primary", "output", "configuration", TOPLEVEL_ELEMENT, NULL))
- {
- if (strcmp (text, "yes") == 0)
- {
- parser->output->priv->primary = TRUE;
- }
- }
- else
- {
- /* Ignore other properties so we can expand the format in the future */
- }
-}
-
-static void
-parser_free (Parser *parser)
-{
- int i;
- GList *list;
-
- g_assert (parser != NULL);
-
- if (parser->output)
- g_object_unref (parser->output);
-
- if (parser->configuration)
- g_object_unref (parser->configuration);
-
- for (i = 0; i < parser->outputs->len; ++i)
- {
- GnomeRROutputInfo *output = parser->outputs->pdata[i];
-
- g_object_unref (output);
- }
-
- g_ptr_array_free (parser->outputs, TRUE);
-
- for (i = 0; i < parser->configurations->len; ++i)
- {
- GnomeRRConfig *config = parser->configurations->pdata[i];
-
- g_object_unref (config);
- }
-
- g_ptr_array_free (parser->configurations, TRUE);
-
- for (list = parser->stack->head; list; list = list->next)
- g_free (list->data);
- g_queue_free (parser->stack);
-
- g_free (parser);
-}
-
-static GnomeRRConfig **
-configurations_read_from_file (const gchar *filename, GError **error)
-{
- Parser *parser = g_new0 (Parser, 1);
- GnomeRRConfig **result;
- GMarkupParser callbacks = {
- handle_start_element,
- handle_end_element,
- handle_text,
- NULL, /* passthrough */
- NULL, /* error */
- };
-
- parser->config_file_version = 0;
- parser->configurations = g_ptr_array_new ();
- parser->outputs = g_ptr_array_new ();
- parser->stack = g_queue_new ();
-
- if (!parse_file_gmarkup (filename, &callbacks, parser, error))
- {
- result = NULL;
-
- g_assert (parser->outputs);
- goto out;
- }
-
- g_assert (parser->outputs);
-
- g_ptr_array_add (parser->configurations, NULL);
- result = (GnomeRRConfig **)g_ptr_array_free (parser->configurations, FALSE);
- parser->configurations = g_ptr_array_new ();
-
- g_assert (parser->outputs);
-out:
- parser_free (parser);
-
- return result;
-}
-
static void
gnome_rr_config_init (GnomeRRConfig *self)
{
@@ -516,11 +159,10 @@ gnome_rr_config_load_current (GnomeRRConfig *config, GError **error)
GnomeRROutput *rr_output = rr_outputs[i];
GnomeRROutputInfo *output = g_object_new (GNOME_TYPE_RR_OUTPUT_INFO, NULL);
GnomeRRMode *mode = NULL;
- const guint8 *edid_data = gnome_rr_output_get_edid_data (rr_output, NULL);
GnomeRRCrtc *crtc;
output->priv->name = g_strdup (gnome_rr_output_get_name (rr_output));
- output->priv->connected = gnome_rr_output_is_connected (rr_output);
+ output->priv->connected = TRUE;
output->priv->display_name = g_strdup (gnome_rr_output_get_display_name (rr_output));
if (!output->priv->connected)
@@ -534,35 +176,18 @@ gnome_rr_config_load_current (GnomeRRConfig *config, GError **error)
}
else
{
- MonitorInfo *info = NULL;
-
- if (edid_data)
- info = decode_edid (edid_data);
-
- if (info)
- {
- memcpy (output->priv->vendor, info->manufacturer_code,
- sizeof (output->priv->vendor));
-
- output->priv->product = info->product_code;
- output->priv->serial = info->serial_number;
- output->priv->aspect = info->aspect_ratio;
- }
- else
- {
- strcpy (output->priv->vendor, "???");
- output->priv->product = 0;
- output->priv->serial = 0;
- }
- g_free (info);
+ gnome_rr_output_get_ids_from_edid (rr_output,
+ &output->priv->vendor,
+ &output->priv->product,
+ &output->priv->serial);
crtc = gnome_rr_output_get_crtc (rr_output);
- mode = crtc? gnome_rr_crtc_get_current_mode (crtc) : NULL;
-
+ mode = crtc ? gnome_rr_crtc_get_current_mode (crtc) : NULL;
+
if (crtc && mode)
{
output->priv->on = TRUE;
-
+
gnome_rr_crtc_get_position (crtc, &output->priv->x, &output->priv->y);
output->priv->width = gnome_rr_mode_get_width (mode);
output->priv->height = gnome_rr_mode_get_height (mode);
@@ -570,13 +195,13 @@ gnome_rr_config_load_current (GnomeRRConfig *config, GError **error)
output->priv->rotation = gnome_rr_crtc_get_current_rotation (crtc);
if (output->priv->x == 0 && output->priv->y == 0) {
- if (clone_width == -1) {
- clone_width = output->priv->width;
- clone_height = output->priv->height;
- } else if (clone_width == output->priv->width &&
- clone_height == output->priv->height) {
- config->priv->clone = TRUE;
- }
+ if (clone_width == -1) {
+ clone_width = output->priv->width;
+ clone_height = output->priv->height;
+ } else if (clone_width == output->priv->width &&
+ clone_height == output->priv->height) {
+ config->priv->clone = TRUE;
+ }
}
}
else
@@ -587,36 +212,8 @@ gnome_rr_config_load_current (GnomeRRConfig *config, GError **error)
/* Get preferred size for the monitor */
mode = gnome_rr_output_get_preferred_mode (rr_output);
-
- if (!mode)
- {
- GnomeRRMode **modes = gnome_rr_output_list_modes (rr_output);
-
- /* FIXME: we should pick the "best" mode here, where best is
- * sorted wrt
- *
- * - closest aspect ratio
- * - mode area
- * - refresh rate
- * - We may want to extend randrwrap so that get_preferred
- * returns that - although that could also depend on
- * the crtc.
- */
- if (modes[0])
- mode = modes[0];
- }
-
- if (mode)
- {
- output->priv->pref_width = gnome_rr_mode_get_width (mode);
- output->priv->pref_height = gnome_rr_mode_get_height (mode);
- }
- else
- {
- /* Pick some random numbers. This should basically never happen */
- output->priv->pref_width = 1024;
- output->priv->pref_height = 768;
- }
+ output->priv->pref_width = gnome_rr_mode_get_width (mode);
+ output->priv->pref_height = gnome_rr_mode_get_height (mode);
}
output->priv->primary = gnome_rr_output_get_is_primary (rr_output);
@@ -661,57 +258,6 @@ gnome_rr_config_load_current (GnomeRRConfig *config, GError **error)
return TRUE;
}
-gboolean
-gnome_rr_config_load_filename (GnomeRRConfig *result, const char *filename, GError **error)
-{
- GnomeRRConfig *current;
- GnomeRRConfig **configs;
- gboolean found = FALSE;
-
- g_return_val_if_fail (GNOME_IS_RR_CONFIG (result), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- current = gnome_rr_config_new_current (result->priv->screen, error);
-
- configs = configurations_read_from_file (filename, error);
-
- if (configs)
- {
- int i;
-
- for (i = 0; configs[i] != NULL; ++i)
- {
- if (gnome_rr_config_match (configs[i], current))
- {
- int j;
- GPtrArray *array;
- result->priv->clone = configs[i]->priv->clone;
-
- array = g_ptr_array_new ();
- for (j = 0; configs[i]->priv->outputs[j] != NULL; j++) {
- g_object_ref (configs[i]->priv->outputs[j]);
- g_ptr_array_add (array, configs[i]->priv->outputs[j]);
- }
- g_ptr_array_add (array, NULL);
- result->priv->outputs = (GnomeRROutputInfo **) g_ptr_array_free (array, FALSE);
-
- found = TRUE;
- break;
- }
- g_object_unref (configs[i]);
- }
- g_free (configs);
-
- if (!found)
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_MATCHING_CONFIG,
- _("none of the saved display configurations matched the active configuration"));
- }
-
- g_object_unref (current);
- return found;
-}
-
static void
gnome_rr_config_class_init (GnomeRRConfigClass *klass)
{
@@ -741,69 +287,6 @@ gnome_rr_config_new_current (GnomeRRScreen *screen, GError **error)
}
}
-GnomeRRConfig *
-gnome_rr_config_new_stored (GnomeRRScreen *screen, GError **error)
-{
- GnomeRRConfig *self = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, NULL);
- char *filename;
- gboolean success;
-
- filename = gnome_rr_config_get_intended_filename ();
-
- success = gnome_rr_config_load_filename (self, filename, error);
-
- g_free (filename);
-
- if (success)
- return self;
- else
- {
- g_object_unref (self);
- return NULL;
- }
-}
-
-static gboolean
-parse_file_gmarkup (const gchar *filename,
- const GMarkupParser *parser,
- gpointer data,
- GError **err)
-{
- GMarkupParseContext *context = NULL;
- gchar *contents = NULL;
- gboolean result = TRUE;
- gsize len;
-
- if (!g_file_get_contents (filename, &contents, &len, err))
- {
- result = FALSE;
- goto out;
- }
-
- context = g_markup_parse_context_new (parser, 0, data, NULL);
-
- if (!g_markup_parse_context_parse (context, contents, len, err))
- {
- result = FALSE;
- goto out;
- }
-
- if (!g_markup_parse_context_end_parse (context, err))
- {
- result = FALSE;
- goto out;
- }
-
-out:
- if (contents)
- g_free (contents);
-
- if (context)
- g_markup_parse_context_free (context);
-
- return result;
-}
-
static gboolean
output_match (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2)
{
@@ -816,13 +299,10 @@ output_match (GnomeRROutputInfo *output1, GnomeRROutputInfo *output2)
if (strcmp (output1->priv->vendor, output2->priv->vendor) != 0)
return FALSE;
- if (output1->priv->product != output2->priv->product)
- return FALSE;
-
- if (output1->priv->serial != output2->priv->serial)
+ if (strcmp (output1->priv->product, output2->priv->product) != 0)
return FALSE;
- if (output1->priv->connected != output2->priv->connected)
+ if (strcmp (output1->priv->serial, output2->priv->serial) != 0)
return FALSE;
return TRUE;
@@ -1006,115 +486,6 @@ gnome_rr_config_applicable (GnomeRRConfig *configuration,
/* Database management */
-static void
-ensure_config_directory (void)
-{
- g_mkdir_with_parents (g_get_user_config_dir (), 0700);
-}
-
-char *
-gnome_rr_config_get_backup_filename (void)
-{
- ensure_config_directory ();
- return g_build_filename (g_get_user_config_dir (), CONFIG_BACKUP_BASENAME, NULL);
-}
-
-char *
-gnome_rr_config_get_intended_filename (void)
-{
- ensure_config_directory ();
- return g_build_filename (g_get_user_config_dir (), CONFIG_INTENDED_BASENAME, NULL);
-}
-
-static const char *
-get_rotation_name (GnomeRRRotation r)
-{
- if (r & GNOME_RR_ROTATION_0)
- return "normal";
- if (r & GNOME_RR_ROTATION_90)
- return "left";
- if (r & GNOME_RR_ROTATION_180)
- return "upside_down";
- if (r & GNOME_RR_ROTATION_270)
- return "right";
-
- return "normal";
-}
-
-static const char *
-yes_no (int x)
-{
- return x? "yes" : "no";
-}
-
-static const char *
-get_reflect_x (GnomeRRRotation r)
-{
- return yes_no (r & GNOME_RR_REFLECT_X);
-}
-
-static const char *
-get_reflect_y (GnomeRRRotation r)
-{
- return yes_no (r & GNOME_RR_REFLECT_Y);
-}
-
-static void
-emit_configuration (GnomeRRConfig *config,
- GString *string)
-{
- int j;
-
- g_string_append_printf (string, " <configuration>\n");
-
- g_string_append_printf (string, " <clone>%s</clone>\n", yes_no (config->priv->clone));
-
- for (j = 0; config->priv->outputs[j] != NULL; ++j)
- {
- GnomeRROutputInfo *output = config->priv->outputs[j];
-
- g_string_append_printf (
- string, " <output name=\"%s\">\n", output->priv->name);
-
- if (output->priv->connected && *output->priv->vendor != '\0')
- {
- g_string_append_printf (
- string, " <vendor>%s</vendor>\n", output->priv->vendor);
- g_string_append_printf (
- string, " <product>0x%04x</product>\n", output->priv->product);
- g_string_append_printf (
- string, " <serial>0x%08x</serial>\n", output->priv->serial);
- }
-
- /* An unconnected output which is on does not make sense */
- if (output->priv->connected && output->priv->on)
- {
- g_string_append_printf (
- string, " <width>%d</width>\n", output->priv->width);
- g_string_append_printf (
- string, " <height>%d</height>\n", output->priv->height);
- g_string_append_printf (
- string, " <rate>%d</rate>\n", output->priv->rate);
- g_string_append_printf (
- string, " <x>%d</x>\n", output->priv->x);
- g_string_append_printf (
- string, " <y>%d</y>\n", output->priv->y);
- g_string_append_printf (
- string, " <rotation>%s</rotation>\n", get_rotation_name (output->priv->rotation));
- g_string_append_printf (
- string, " <reflect_x>%s</reflect_x>\n", get_reflect_x (output->priv->rotation));
- g_string_append_printf (
- string, " <reflect_y>%s</reflect_y>\n", get_reflect_y (output->priv->rotation));
- g_string_append_printf (
- string, " <primary>%s</primary>\n", yes_no (output->priv->primary));
- }
-
- g_string_append_printf (string, " </output>\n");
- }
-
- g_string_append_printf (string, " </configuration>\n");
-}
-
void
gnome_rr_config_sanitize (GnomeRRConfig *config)
{
@@ -1224,63 +595,11 @@ gnome_rr_config_ensure_primary (GnomeRRConfig *configuration)
return !found;
}
-gboolean
-gnome_rr_config_save (GnomeRRConfig *configuration, GError **error)
-{
- GnomeRRConfig **configurations;
- GString *output;
- int i;
- gchar *intended_filename;
- gchar *backup_filename;
- gboolean result;
-
- g_return_val_if_fail (GNOME_IS_RR_CONFIG (configuration), FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- output = g_string_new ("");
-
- backup_filename = gnome_rr_config_get_backup_filename ();
- intended_filename = gnome_rr_config_get_intended_filename ();
-
- configurations = configurations_read_from_file (intended_filename, NULL); /* NULL-GError */
-
- g_string_append_printf (output, "<monitors version=\"1\">\n");
-
- if (configurations)
- {
- for (i = 0; configurations[i] != NULL; ++i)
- {
- if (!gnome_rr_config_match (configurations[i], configuration))
- emit_configuration (configurations[i], output);
- g_object_unref (configurations[i]);
- }
-
- g_free (configurations);
- }
-
- emit_configuration (configuration, output);
-
- g_string_append_printf (output, "</monitors>\n");
-
- /* backup the file first */
- rename (intended_filename, backup_filename); /* no error checking because the intended file may not even
exist */
-
- result = g_file_set_contents (intended_filename, output->str, -1, error);
-
- if (!result)
- rename (backup_filename, intended_filename); /* no error checking because the backup may not even
exist */
-
- g_free (backup_filename);
- g_free (intended_filename);
-
- return result;
-}
-
-gboolean
-gnome_rr_config_apply_with_time (GnomeRRConfig *config,
- GnomeRRScreen *screen,
- guint32 timestamp,
- GError **error)
+static gboolean
+gnome_rr_config_apply_helper (GnomeRRConfig *config,
+ GnomeRRScreen *screen,
+ gboolean persistent,
+ GError **error)
{
CrtcAssignment *assignment;
GnomeRROutputInfo **outputs;
@@ -1294,76 +613,35 @@ gnome_rr_config_apply_with_time (GnomeRRConfig *config,
assignment = crtc_assignment_new (screen, outputs, error);
- for (i = 0; outputs[i] != NULL; i++)
- g_object_unref (outputs[i]);
- g_free (outputs);
-
if (assignment)
{
- if (crtc_assignment_apply (assignment, timestamp, error))
+ if (crtc_assignment_apply (assignment, persistent, error))
result = TRUE;
crtc_assignment_free (assignment);
-
- gdk_flush ();
}
+ for (i = 0; outputs[i] != NULL; i++)
+ g_object_unref (outputs[i]);
+ g_free (outputs);
+
return result;
}
-/* gnome_rr_config_apply_from_filename_with_time:
- * @screen: A #GnomeRRScreen
- * @filename: Path of the file to look in for stored RANDR configurations.
- * @timestamp: X server timestamp from the event that causes the screen configuration to change (a user's
button press, for example)
- * @error: Location to store error, or %NULL
- *
- * Loads the file in @filename and looks for suitable matching RANDR
- * configurations in the file; if one is found, that configuration will be
- * applied to the current set of RANDR outputs.
- *
- * Typically, @filename is the result of gnome_rr_config_get_intended_filename() or
- * gnome_rr_config_get_backup_filename().
- *
- * Returns: TRUE if the RANDR configuration was loaded and applied from
- * the specified file, or FALSE otherwise:
- *
- * If the file in question is loaded successfully but the configuration cannot
- * be applied, the @error will have a domain of #GNOME_RR_ERROR. Note that an
- * error code of #GNOME_RR_ERROR_NO_MATCHING_CONFIG is not a real error; it
- * simply means that there were no stored configurations that match the current
- * set of RANDR outputs.
- *
- * If the file in question cannot be loaded, the @error will have a domain of
- * #G_FILE_ERROR. Note that an error code of G_FILE_ERROR_NOENT is not really
- * an error, either; it means that there was no stored configuration file and so
- * nothing is changed.
- */
gboolean
-gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen, const char *filename, guint32
timestamp, GError **error)
+gnome_rr_config_apply (GnomeRRConfig *config,
+ GnomeRRScreen *screen,
+ GError **error)
{
- GnomeRRConfig *stored;
-
- g_return_val_if_fail (GNOME_IS_RR_SCREEN (screen), FALSE);
- g_return_val_if_fail (filename != NULL, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- stored = g_object_new (GNOME_TYPE_RR_CONFIG, "screen", screen, NULL);
-
- if (gnome_rr_config_load_filename (stored, filename, error))
- {
- gboolean result;
-
- gnome_rr_config_ensure_primary (stored);
- result = gnome_rr_config_apply_with_time (stored, screen, timestamp, error);
+ return gnome_rr_config_apply_helper (config, screen, FALSE, error);
+}
- g_object_unref (stored);
- return result;
- }
- else
- {
- g_object_unref (stored);
- return FALSE;
- }
+gboolean
+gnome_rr_config_apply_persistent (GnomeRRConfig *config,
+ GnomeRRScreen *screen,
+ GError **error)
+{
+ return gnome_rr_config_apply_helper (config, screen, TRUE, error);
}
/**
@@ -1418,6 +696,7 @@ struct CrtcInfo
struct CrtcAssignment
{
+ GnomeRROutputInfo **outputs;
GnomeRRScreen *screen;
GHashTable *info;
GnomeRROutput *primary;
@@ -1479,9 +758,8 @@ crtc_assignment_assign (CrtcAssignment *assign,
if (!gnome_rr_crtc_supports_rotation (crtc, rotation))
{
g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_CRTC_ASSIGNMENT,
- _("CRTC %d does not support rotation=%s"),
- crtc_id,
- get_rotation_name (rotation));
+ _("CRTC %d does not support rotation=%d"),
+ crtc_id, rotation);
return FALSE;
}
@@ -1496,12 +774,12 @@ crtc_assignment_assign (CrtcAssignment *assign,
_("output %s does not have the same parameters as another cloned output:\n"
"existing mode = %d, new mode = %d\n"
"existing coordinates = (%d, %d), new coordinates = (%d, %d)\n"
- "existing rotation = %s, new rotation = %s"),
+ "existing rotation = %d, new rotation = %d"),
output_name,
gnome_rr_mode_get_id (info->mode), gnome_rr_mode_get_id (mode),
info->x, info->y,
x, y,
- get_rotation_name (info->rotation), get_rotation_name (rotation));
+ info->rotation, rotation);
return FALSE;
}
@@ -1574,35 +852,6 @@ crtc_assignment_free (CrtcAssignment *assign)
g_free (assign);
}
-typedef struct {
- guint32 timestamp;
- gboolean has_error;
- GError **error;
-} ConfigureCrtcState;
-
-static void
-configure_crtc (gpointer key,
- gpointer value,
- gpointer data)
-{
- GnomeRRCrtc *crtc = key;
- CrtcInfo *info = value;
- ConfigureCrtcState *state = data;
-
- if (state->has_error)
- return;
-
- if (!gnome_rr_crtc_set_config_with_time (crtc,
- state->timestamp,
- info->x, info->y,
- info->mode,
- info->rotation,
- (GnomeRROutput **)info->outputs->pdata,
- info->outputs->len,
- state->error))
- state->has_error = TRUE;
-}
-
static gboolean
mode_is_rotated (CrtcInfo *info)
{
@@ -1614,20 +863,6 @@ mode_is_rotated (CrtcInfo *info)
return FALSE;
}
-static gboolean
-crtc_is_rotated (GnomeRRCrtc *crtc)
-{
- GnomeRRRotation r = gnome_rr_crtc_get_current_rotation (crtc);
-
- if ((r & GNOME_RR_ROTATION_270) ||
- (r & GNOME_RR_ROTATION_90))
- {
- return TRUE;
- }
-
- return FALSE;
-}
-
static void
accumulate_error (GString *accumulated_error, GError *error)
{
@@ -1806,10 +1041,13 @@ get_required_virtual_size (CrtcAssignment *assign, int *width, int *height)
}
static CrtcAssignment *
-crtc_assignment_new (GnomeRRScreen *screen, GnomeRROutputInfo **outputs, GError **error)
+crtc_assignment_new (GnomeRRScreen *screen,
+ GnomeRROutputInfo **outputs,
+ GError **error)
{
CrtcAssignment *assignment = g_new0 (CrtcAssignment, 1);
+ assignment->outputs = outputs;
assignment->info = g_hash_table_new_full (
g_direct_hash, g_direct_equal, NULL, (GFreeFunc)crtc_info_free);
@@ -1849,102 +1087,94 @@ fail:
return NULL;
}
-static gboolean
-crtc_assignment_apply (CrtcAssignment *assign, guint32 timestamp, GError **error)
+static enum wl_output_transform
+rotation_to_transform (GnomeRRRotation rotation)
{
- GnomeRRCrtc **all_crtcs = gnome_rr_screen_list_crtcs (assign->screen);
- int width, height;
- int i;
- int min_width, max_width, min_height, max_height;
- int width_mm, height_mm;
- gboolean success = TRUE;
-
- /* Compute size of the screen */
- get_required_virtual_size (assign, &width, &height);
-
- gnome_rr_screen_get_ranges (
- assign->screen, &min_width, &max_width, &min_height, &max_height);
-
- /* We should never get here if the dimensions don't fit in the virtual size,
- * but just in case we do, fix it up.
- */
- width = MAX (min_width, width);
- width = MIN (max_width, width);
- height = MAX (min_height, height);
- height = MIN (max_height, height);
-
- /* FMQ: do we need to check the sizes instead of clamping them? */
+ static const enum wl_output_transform y_reflected_map[4] = {
+ WL_OUTPUT_TRANSFORM_FLIPPED_180,
+ WL_OUTPUT_TRANSFORM_FLIPPED_90,
+ WL_OUTPUT_TRANSFORM_FLIPPED,
+ WL_OUTPUT_TRANSFORM_FLIPPED_270
+ };
+ enum wl_output_transform ret;
+
+ switch (rotation & 0x7F)
+ {
+ default:
+ case GNOME_RR_ROTATION_0:
+ ret = WL_OUTPUT_TRANSFORM_NORMAL;
+ break;
+ case GNOME_RR_ROTATION_90:
+ ret = WL_OUTPUT_TRANSFORM_90;
+ break;
+ case GNOME_RR_ROTATION_180:
+ ret = WL_OUTPUT_TRANSFORM_180;
+ break;
+ case GNOME_RR_ROTATION_270:
+ ret = WL_OUTPUT_TRANSFORM_270;
+ break;
+ }
+
+ if (rotation & GNOME_RR_REFLECT_X)
+ return ret + 4;
+ else if (rotation & GNOME_RR_REFLECT_Y)
+ return y_reflected_map[ret];
+ else
+ return ret;
+}
- /* Grab the server while we fiddle with the CRTCs and the screen, so that
- * apps that listen for RANDR notifications will only receive the final
- * status.
- */
+static gboolean
+crtc_assignment_apply (CrtcAssignment *assign, gboolean persistent, GError **error)
+{
+ GVariantBuilder crtc_builder, output_builder, nested_outputs;
+ GHashTableIter iter;
+ GnomeRRCrtc *crtc;
+ CrtcInfo *info;
+ unsigned i;
- gdk_x11_display_grab (gdk_screen_get_display (assign->screen->priv->gdk_screen));
+ g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uiiiuaua{sv})"));
+ g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(ua{sv})"));
- /* Turn off all crtcs that are currently displaying outside the new screen,
- * or are not used in the new setup
- */
- for (i = 0; all_crtcs[i] != NULL; ++i)
+ g_hash_table_iter_init (&iter, assign->info);
+ while (g_hash_table_iter_next (&iter, (void*) &crtc, (void*) &info))
{
- GnomeRRCrtc *crtc = all_crtcs[i];
- GnomeRRMode *mode = gnome_rr_crtc_get_current_mode (crtc);
- int x, y;
-
- if (mode)
+ g_variant_builder_init (&nested_outputs, G_VARIANT_TYPE ("au"));
+ for (i = 0; i < info->outputs->len; i++)
{
- int w, h;
- gnome_rr_crtc_get_position (crtc, &x, &y);
-
- w = gnome_rr_mode_get_width (mode);
- h = gnome_rr_mode_get_height (mode);
+ GnomeRROutput *output = g_ptr_array_index (info->outputs, i);
- if (crtc_is_rotated (crtc))
- {
- int tmp = h;
- h = w;
- w = tmp;
- }
-
- if (x + w > width || y + h > height || !g_hash_table_lookup (assign->info, crtc))
- {
- if (!gnome_rr_crtc_set_config_with_time (crtc, timestamp, 0, 0, NULL, GNOME_RR_ROTATION_0,
NULL, 0, error))
- {
- success = FALSE;
- break;
- }
-
- }
+ g_variant_builder_add (&nested_outputs, "u",
+ gnome_rr_output_get_id (output));
}
- }
- /* The 'physical size' of an X screen is meaningless if that screen
- * can consist of many monitors. So just pick a size that make the
- * dpi 96.
- *
- * Firefox and Evince apparently believe what X tells them.
- */
- width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5;
- height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5;
-
- if (success)
- {
- ConfigureCrtcState state;
-
- gnome_rr_screen_set_size (assign->screen, width, height, width_mm, height_mm);
-
- state.timestamp = timestamp;
- state.has_error = FALSE;
- state.error = error;
-
- g_hash_table_foreach (assign->info, configure_crtc, &state);
-
- success = !state.has_error;
+ g_variant_builder_add (&crtc_builder, "(uiiiuaua{sv})",
+ gnome_rr_crtc_get_id (crtc),
+ info->mode ?
+ gnome_rr_mode_get_id (info->mode) : -1,
+ info->x,
+ info->y,
+ rotation_to_transform (info->rotation),
+ &nested_outputs,
+ NULL);
}
- gnome_rr_screen_set_primary_output (assign->screen, assign->primary);
-
- gdk_x11_display_ungrab (gdk_screen_get_display (assign->screen->priv->gdk_screen));
-
- return success;
+ for (i = 0; assign->outputs[i]; i++)
+ {
+ GnomeRROutputInfo *output = assign->outputs[i];
+ GnomeRROutput *gnome_rr_output = gnome_rr_screen_get_output_by_name (assign->screen,
+ output->priv->name);
+
+ g_variant_builder_add (&output_builder, "(u a{sv})",
+ gnome_rr_output_get_id (gnome_rr_output),
+ g_variant_new_parsed ("{ 'primary': <%b>,"
+ " 'presentation': <%b> }",
+ output->priv->primary,
+ FALSE));
+ }
+
+ return _gnome_rr_screen_apply_configuration (assign->screen,
+ persistent,
+ g_variant_builder_end (&crtc_builder),
+ g_variant_builder_end (&output_builder),
+ error);
}
diff --git a/libgnome-desktop/gnome-rr-config.h b/libgnome-desktop/gnome-rr-config.h
index 0a406d1..e7069e0 100644
--- a/libgnome-desktop/gnome-rr-config.h
+++ b/libgnome-desktop/gnome-rr-config.h
@@ -75,9 +75,9 @@ GnomeRRRotation gnome_rr_output_info_get_rotation (GnomeRROutputInfo *self);
void gnome_rr_output_info_set_rotation (GnomeRROutputInfo *self, GnomeRRRotation rotation);
gboolean gnome_rr_output_info_is_connected (GnomeRROutputInfo *self);
-void gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self, gchar* vendor);
-guint gnome_rr_output_info_get_product (GnomeRROutputInfo *self);
-guint gnome_rr_output_info_get_serial (GnomeRROutputInfo *self);
+const char *gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self);
+const char *gnome_rr_output_info_get_product (GnomeRROutputInfo *self);
+const char *gnome_rr_output_info_get_serial (GnomeRROutputInfo *self);
double gnome_rr_output_info_get_aspect_ratio (GnomeRROutputInfo *self);
char *gnome_rr_output_info_get_display_name (GnomeRROutputInfo *self);
@@ -115,31 +115,21 @@ GType gnome_rr_config_get_type (void);
GnomeRRConfig *gnome_rr_config_new_current (GnomeRRScreen *screen,
GError **error);
-GnomeRRConfig *gnome_rr_config_new_stored (GnomeRRScreen *screen,
+gboolean gnome_rr_config_load_current (GnomeRRConfig *self,
GError **error);
-gboolean gnome_rr_config_load_current (GnomeRRConfig *self,
- GError **error);
-gboolean gnome_rr_config_load_filename (GnomeRRConfig *self,
- const gchar *filename,
- GError **error);
gboolean gnome_rr_config_match (GnomeRRConfig *config1,
GnomeRRConfig *config2);
gboolean gnome_rr_config_equal (GnomeRRConfig *config1,
GnomeRRConfig *config2);
-gboolean gnome_rr_config_save (GnomeRRConfig *configuration,
- GError **error);
void gnome_rr_config_sanitize (GnomeRRConfig *configuration);
gboolean gnome_rr_config_ensure_primary (GnomeRRConfig *configuration);
-gboolean gnome_rr_config_apply_with_time (GnomeRRConfig *configuration,
- GnomeRRScreen *screen,
- guint32 timestamp,
- GError **error);
-
-gboolean gnome_rr_config_apply_from_filename_with_time (GnomeRRScreen *screen,
- const char *filename,
- guint32 timestamp,
- GError **error);
+gboolean gnome_rr_config_apply (GnomeRRConfig *configuration,
+ GnomeRRScreen *screen,
+ GError **error);
+gboolean gnome_rr_config_apply_persistent (GnomeRRConfig *configuration,
+ GnomeRRScreen *screen,
+ GError **error);
gboolean gnome_rr_config_applicable (GnomeRRConfig *configuration,
GnomeRRScreen *screen,
@@ -149,7 +139,4 @@ gboolean gnome_rr_config_get_clone (GnomeRRConfig *configuration)
void gnome_rr_config_set_clone (GnomeRRConfig *configuration, gboolean clone);
GnomeRROutputInfo **gnome_rr_config_get_outputs (GnomeRRConfig *configuration);
-char *gnome_rr_config_get_backup_filename (void);
-char *gnome_rr_config_get_intended_filename (void);
-
#endif
diff --git a/libgnome-desktop/gnome-rr-debug.c b/libgnome-desktop/gnome-rr-debug.c
index 20fa090..0395ecc 100644
--- a/libgnome-desktop/gnome-rr-debug.c
+++ b/libgnome-desktop/gnome-rr-debug.c
@@ -83,7 +83,7 @@ main (int argc, char *argv[])
outputs = gnome_rr_screen_list_outputs (screen);
for (i = 0; outputs[i] != NULL; i++) {
g_print ("[%s]\n", gnome_rr_output_get_name (outputs[i]));
- g_print ("\tconnected: %i\n", gnome_rr_output_is_connected (outputs[i]));
+ g_print ("\tconnected: %i\n", 1);
g_print ("\tbuilt-in: %i\n", gnome_rr_output_is_builtin_display (outputs[i]));
g_print ("\tprimary: %i\n", gnome_rr_output_get_is_primary (outputs[i]));
g_print ("\tid: %i\n", gnome_rr_output_get_id (outputs[i]));
diff --git a/libgnome-desktop/gnome-rr-output-info.c b/libgnome-desktop/gnome-rr-output-info.c
index 43ab0e3..2177692 100644
--- a/libgnome-desktop/gnome-rr-output-info.c
+++ b/libgnome-desktop/gnome-rr-output-info.c
@@ -169,29 +169,27 @@ gboolean gnome_rr_output_info_is_connected (GnomeRROutputInfo *self)
/**
* gnome_rr_output_info_get_vendor:
* @self: a #GnomeRROutputInfo
- * @vendor: (out caller-allocates) (array fixed-size=4):
*/
-void gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self, gchar* vendor)
+const char *
+gnome_rr_output_info_get_vendor (GnomeRROutputInfo *self)
{
- g_return_if_fail (GNOME_IS_RR_OUTPUT_INFO (self));
- g_return_if_fail (vendor != NULL);
+ g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL);
- vendor[0] = self->priv->vendor[0];
- vendor[1] = self->priv->vendor[1];
- vendor[2] = self->priv->vendor[2];
- vendor[3] = self->priv->vendor[3];
+ return self->priv->vendor;
}
-guint gnome_rr_output_info_get_product (GnomeRROutputInfo *self)
+const char *
+gnome_rr_output_info_get_product (GnomeRROutputInfo *self)
{
- g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+ g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL);
return self->priv->product;
}
-guint gnome_rr_output_info_get_serial (GnomeRROutputInfo *self)
+const char *
+gnome_rr_output_info_get_serial (GnomeRROutputInfo *self)
{
- g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), 0);
+ g_return_val_if_fail (GNOME_IS_RR_OUTPUT_INFO (self), NULL);
return self->priv->serial;
}
diff --git a/libgnome-desktop/gnome-rr-private.h b/libgnome-desktop/gnome-rr-private.h
index edadbad..522398a 100644
--- a/libgnome-desktop/gnome-rr-private.h
+++ b/libgnome-desktop/gnome-rr-private.h
@@ -1,9 +1,22 @@
#ifndef GNOME_RR_PRIVATE_H
#define GNOME_RR_PRIVATE_H
-#include <X11/Xlib.h>
+#ifdef GDK_WINDOWING_WAYLAND
+#include <gdk/gdkwayland.h>
+#else
+enum wl_output_transform {
+ WL_OUTPUT_TRANSFORM_NORMAL,
+ WL_OUTPUT_TRANSFORM_90,
+ WL_OUTPUT_TRANSFORM_180,
+ WL_OUTPUT_TRANSFORM_270,
+ WL_OUTPUT_TRANSFORM_FLIPPED,
+ WL_OUTPUT_TRANSFORM_FLIPPED_90,
+ WL_OUTPUT_TRANSFORM_FLIPPED_180,
+ WL_OUTPUT_TRANSFORM_FLIPPED_270
+};
+#endif
-#include <X11/extensions/Xrandr.h>
+#include "meta-dbus-xrandr.h"
typedef struct ScreenInfo ScreenInfo;
@@ -14,7 +27,7 @@ struct ScreenInfo
int min_height;
int max_height;
- XRRScreenResources *resources;
+ guint serial;
GnomeRROutput ** outputs;
GnomeRRCrtc ** crtcs;
@@ -24,24 +37,16 @@ struct ScreenInfo
GnomeRRMode ** clone_modes;
- RROutput primary;
+ GnomeRROutput * primary;
};
struct GnomeRRScreenPrivate
{
GdkScreen * gdk_screen;
GdkWindow * gdk_root;
- Display * xdisplay;
- Screen * xscreen;
- Window xroot;
ScreenInfo * info;
-
- int randr_event_base;
- int rr_major_version;
- int rr_minor_version;
-
- Atom connector_type_atom;
- gboolean dpms_capable;
+
+ MetaDBusDisplayConfig *proxy;
};
struct _GnomeRROutputInfoPrivate
@@ -57,9 +62,9 @@ struct _GnomeRROutputInfoPrivate
GnomeRRRotation rotation;
gboolean connected;
- gchar vendor[4];
- guint product;
- guint serial;
+ char * vendor;
+ char * product;
+ char * serial;
double aspect;
int pref_width;
int pref_height;
@@ -76,4 +81,18 @@ struct _GnomeRRConfigPrivate
gboolean _gnome_rr_output_name_is_builtin_display (const char *name);
+typedef enum {
+ META_POWER_SAVE_UNKNOWN = -1,
+ META_POWER_SAVE_ON = 0,
+ META_POWER_SAVE_STANDBY,
+ META_POWER_SAVE_SUSPEND,
+ META_POWER_SAVE_OFF,
+} MetaPowerSave;
+
+gboolean _gnome_rr_screen_apply_configuration (GnomeRRScreen *screen,
+ gboolean persistent,
+ GVariant *crtcs,
+ GVariant *outputs,
+ GError **error);
+
#endif
diff --git a/libgnome-desktop/gnome-rr.c b/libgnome-desktop/gnome-rr.c
index c59d142..5249e17 100644
--- a/libgnome-desktop/gnome-rr.c
+++ b/libgnome-desktop/gnome-rr.c
@@ -1,6 +1,6 @@
/* gnome-rr.c
*
- * Copyright 2007, 2008, Red Hat, Inc.
+ * Copyright 2007, 2008, 2013 Red Hat, Inc.
*
* This file is part of the Gnome Library.
*
@@ -20,6 +20,7 @@
* Boston, MA 02110-1301, USA.
*
* Author: Soren Sandmann <sandmann redhat com>
+ * Giovanni Campagna <gcampagn redhat com>
*/
#define GNOME_DESKTOP_USE_UNSTABLE_API
@@ -27,14 +28,9 @@
#include <config.h>
#include <glib/gi18n-lib.h>
#include <string.h>
-#include <X11/Xlib.h>
-
-#include <X11/extensions/Xrandr.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/dpms.h>
#undef GNOME_DISABLE_DEPRECATED
#include "gnome-rr.h"
@@ -43,9 +39,6 @@
#include "edid.h"
#include "gnome-rr-private.h"
-#define DISPLAY(o) ((o)->info->screen->priv->xdisplay)
-
-#define SERVERS_RANDR_IS_AT_LEAST_1_3(priv) (priv->rr_major_version > 1 || (priv->rr_major_version == 1 &&
priv->rr_minor_version >= 3))
enum {
SCREEN_PROP_0,
@@ -65,34 +58,31 @@ gint screen_signals[SCREEN_SIGNAL_LAST];
struct GnomeRROutput
{
ScreenInfo * info;
- RROutput id;
+ guint id;
+ glong winsys_id;
char * name;
char * display_name;
GnomeRRCrtc * current_crtc;
- gboolean connected;
- gulong width_mm;
- gulong height_mm;
GnomeRRCrtc ** possible_crtcs;
GnomeRROutput ** clones;
GnomeRRMode ** modes;
- int n_preferred;
- guint8 * edid_data;
- gsize edid_size;
- char * connector_type;
- gint backlight_min;
- gint backlight_max;
-};
-struct GnomeRROutputWrap
-{
- RROutput id;
+ char * vendor;
+ char * product;
+ char * serial;
+
+ int backlight;
+
+ gboolean is_primary;
+ gboolean is_presentation;
};
struct GnomeRRCrtc
{
ScreenInfo * info;
- RRCrtc id;
+ guint id;
+ glong winsys_id;
GnomeRRMode * current_mode;
GnomeRROutput ** current_outputs;
@@ -100,16 +90,16 @@ struct GnomeRRCrtc
int x;
int y;
- GnomeRRRotation current_rotation;
- GnomeRRRotation rotations;
+ enum wl_output_transform transform;
+ int all_transforms;
int gamma_size;
};
struct GnomeRRMode
{
ScreenInfo * info;
- RRMode id;
- char * name;
+ guint id;
+ glong winsys_id;
int width;
int height;
int freq; /* in mHz */
@@ -117,31 +107,29 @@ struct GnomeRRMode
/* GnomeRRCrtc */
static GnomeRRCrtc * crtc_new (ScreenInfo *info,
- RRCrtc id);
+ guint id);
static GnomeRRCrtc * crtc_copy (const GnomeRRCrtc *from);
static void crtc_free (GnomeRRCrtc *crtc);
-static gboolean crtc_initialize (GnomeRRCrtc *crtc,
- XRRScreenResources *res,
- GError **error);
+static void crtc_initialize (GnomeRRCrtc *crtc,
+ GVariant *res);
/* GnomeRROutput */
static GnomeRROutput *output_new (ScreenInfo *info,
- RROutput id);
+ guint id);
-static gboolean output_initialize (GnomeRROutput *output,
- XRRScreenResources *res,
- GError **error);
+static void output_initialize (GnomeRROutput *output,
+ GVariant *res);
static GnomeRROutput *output_copy (const GnomeRROutput *from);
static void output_free (GnomeRROutput *output);
/* GnomeRRMode */
static GnomeRRMode * mode_new (ScreenInfo *info,
- RRMode id);
+ guint id);
static void mode_initialize (GnomeRRMode *mode,
- XRRModeInfo *info);
+ GVariant *info);
static GnomeRRMode * mode_copy (const GnomeRRMode *from);
static void mode_free (GnomeRRMode *mode);
@@ -176,7 +164,7 @@ gnome_rr_error_quark (void)
/* Screen */
static GnomeRROutput *
-gnome_rr_output_by_id (ScreenInfo *info, RROutput id)
+gnome_rr_output_by_id (ScreenInfo *info, guint id)
{
GnomeRROutput **output;
@@ -192,7 +180,7 @@ gnome_rr_output_by_id (ScreenInfo *info, RROutput id)
}
static GnomeRRCrtc *
-crtc_by_id (ScreenInfo *info, RRCrtc id)
+crtc_by_id (ScreenInfo *info, guint id)
{
GnomeRRCrtc **crtc;
@@ -209,7 +197,7 @@ crtc_by_id (ScreenInfo *info, RRCrtc id)
}
static GnomeRRMode *
-mode_by_id (ScreenInfo *info, RRMode id)
+mode_by_id (ScreenInfo *info, guint id)
{
GnomeRRMode **mode;
@@ -233,13 +221,6 @@ screen_info_free (ScreenInfo *info)
g_assert (info != NULL);
- if (info->resources)
- {
- XRRFreeScreenResources (info->resources);
-
- info->resources = NULL;
- }
-
if (info->outputs)
{
for (output = info->outputs; *output; ++output)
@@ -305,9 +286,6 @@ gather_clone_modes (ScreenInfo *info)
output1 = info->outputs[i];
- if (!output1->connected)
- continue;
-
for (j = 0; output1->modes[j] != NULL; ++j)
{
GnomeRRMode *mode = output1->modes[j];
@@ -319,9 +297,6 @@ gather_clone_modes (ScreenInfo *info)
{
output2 = info->outputs[k];
- if (!output2->connected)
- continue;
-
if (!has_similar_mode (output2, mode))
{
valid = FALSE;
@@ -339,25 +314,44 @@ gather_clone_modes (ScreenInfo *info)
info->clone_modes = (GnomeRRMode **)g_ptr_array_free (result, FALSE);
}
-static gboolean
+static void
fill_screen_info_from_resources (ScreenInfo *info,
- XRRScreenResources *resources,
- GError **error)
+ guint serial,
+ GVariant *crtcs,
+ GVariant *outputs,
+ GVariant *modes,
+ int max_width,
+ int max_height)
{
int i;
GPtrArray *a;
GnomeRRCrtc **crtc;
GnomeRROutput **output;
+ GnomeRRMode **mode;
+ guint ncrtc, noutput, nmode;
+ guint id;
- info->resources = resources;
+ info->min_width = 312;
+ info->min_height = 312;
+ info->max_width = max_width;
+ info->max_height = max_height;
+ info->serial = serial;
+
+ ncrtc = g_variant_n_children (crtcs);
+ noutput = g_variant_n_children (outputs);
+ nmode = g_variant_n_children (modes);
/* We create all the structures before initializing them, so
* that they can refer to each other.
*/
a = g_ptr_array_new ();
- for (i = 0; i < resources->ncrtc; ++i)
+ for (i = 0; i < ncrtc; ++i)
{
- GnomeRRCrtc *crtc = crtc_new (info, resources->crtcs[i]);
+ GnomeRRCrtc *crtc;
+
+ g_variant_get_child (crtcs, i, "(uxiiiiiuaua{sv})", &id,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ crtc = crtc_new (info, id);
g_ptr_array_add (a, crtc);
}
@@ -365,9 +359,13 @@ fill_screen_info_from_resources (ScreenInfo *info,
info->crtcs = (GnomeRRCrtc **)g_ptr_array_free (a, FALSE);
a = g_ptr_array_new ();
- for (i = 0; i < resources->noutput; ++i)
+ for (i = 0; i < noutput; ++i)
{
- GnomeRROutput *output = output_new (info, resources->outputs[i]);
+ GnomeRROutput *output;
+
+ g_variant_get_child (outputs, i, "(uxiaussssiauaua{sv})", &id,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ output = output_new (info, id);
g_ptr_array_add (a, output);
}
@@ -375,9 +373,13 @@ fill_screen_info_from_resources (ScreenInfo *info,
info->outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE);
a = g_ptr_array_new ();
- for (i = 0; i < resources->nmode; ++i)
+ for (i = 0; i < nmode; ++i)
{
- GnomeRRMode *mode = mode_new (info, resources->modes[i].id);
+ GnomeRRMode *mode;
+
+ g_variant_get_child (modes, i, "(uxuud)", &id,
+ NULL, NULL, NULL, NULL);
+ mode = mode_new (info, id);
g_ptr_array_add (a, mode);
}
@@ -385,140 +387,66 @@ fill_screen_info_from_resources (ScreenInfo *info,
info->modes = (GnomeRRMode **)g_ptr_array_free (a, FALSE);
/* Initialize */
- for (crtc = info->crtcs; *crtc; ++crtc)
+ for (i = 0, crtc = info->crtcs; *crtc; ++i, ++crtc)
{
- if (!crtc_initialize (*crtc, resources, error))
- return FALSE;
+ crtc_initialize (*crtc, g_variant_get_child_value (crtcs, i));
}
- for (output = info->outputs; *output; ++output)
+ for (i = 0, output = info->outputs; *output; ++i, ++output)
{
- if (!output_initialize (*output, resources, error))
- return FALSE;
+ output_initialize (*output, g_variant_get_child_value (outputs, i));
}
- for (i = 0; i < resources->nmode; ++i)
+ for (i = 0, mode = info->modes; *mode; ++i, ++mode)
{
- GnomeRRMode *mode = mode_by_id (info, resources->modes[i].id);
-
- mode_initialize (mode, &(resources->modes[i]));
+ mode_initialize (*mode, g_variant_get_child_value (modes, i));
}
gather_clone_modes (info);
-
- return TRUE;
}
static gboolean
-fill_out_screen_info (Display *xdisplay,
- Window xroot,
- ScreenInfo *info,
- gboolean needs_reprobe,
- GError **error)
+fill_out_screen_info (ScreenInfo *info,
+ GError **error)
{
- XRRScreenResources *resources;
GnomeRRScreenPrivate *priv;
-
- g_assert (xdisplay != NULL);
+ guint serial;
+ GVariant *crtcs, *outputs, *modes;
+ int max_width, max_height;
+
g_assert (info != NULL);
priv = info->screen->priv;
- /* First update the screen resources */
-
- if (needs_reprobe)
- resources = XRRGetScreenResources (xdisplay, xroot);
- else
- {
- /* XRRGetScreenResourcesCurrent is less expensive than
- * XRRGetScreenResources, however it is available only
- * in RandR 1.3 or higher
- */
- if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv))
- resources = XRRGetScreenResourcesCurrent (xdisplay, xroot);
- else
- resources = XRRGetScreenResources (xdisplay, xroot);
- }
-
- if (resources)
- {
- if (!fill_screen_info_from_resources (info, resources, error))
- return FALSE;
- }
- else
- {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR,
- /* Translators: a CRTC is a CRT Controller (this is X terminology). */
- _("could not get the screen resources (CRTCs, outputs, modes)"));
+ if (!meta_dbus_display_config_call_get_resources_sync (priv->proxy,
+ &serial,
+ &crtcs,
+ &outputs,
+ &modes,
+ &max_width,
+ &max_height,
+ NULL,
+ error))
return FALSE;
- }
-
- /* Then update the screen size range. We do this after XRRGetScreenResources() so that
- * the X server will already have an updated view of the outputs.
- */
-
- if (needs_reprobe) {
- gboolean success;
-
- gdk_error_trap_push ();
- success = XRRGetScreenSizeRange (xdisplay, xroot,
- &(info->min_width),
- &(info->min_height),
- &(info->max_width),
- &(info->max_height));
- gdk_flush ();
- if (gdk_error_trap_pop ()) {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_UNKNOWN,
- _("unhandled X error while getting the range of screen sizes"));
- return FALSE;
- }
-
- if (!success) {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR,
- _("could not get the range of screen sizes"));
- return FALSE;
- }
- }
- else
- {
- gnome_rr_screen_get_ranges (info->screen,
- &(info->min_width),
- &(info->max_width),
- &(info->min_height),
- &(info->max_height));
- }
-
- info->primary = None;
- if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv)) {
- gdk_error_trap_push ();
- info->primary = XRRGetOutputPrimary (xdisplay, xroot);
- gdk_error_trap_pop_ignored ();
- }
-
- /* can the screen do DPMS? */
- gdk_error_trap_push ();
- priv->dpms_capable = DPMSCapable (priv->xdisplay);
- gdk_error_trap_pop_ignored ();
+ fill_screen_info_from_resources (info, serial, crtcs, outputs,
+ modes, max_width, max_height);
return TRUE;
}
static ScreenInfo *
-screen_info_new (GnomeRRScreen *screen, gboolean needs_reprobe, GError **error)
+screen_info_new (GnomeRRScreen *screen, GError **error)
{
ScreenInfo *info = g_new0 (ScreenInfo, 1);
- GnomeRRScreenPrivate *priv;
g_assert (screen != NULL);
- priv = screen->priv;
-
info->outputs = NULL;
info->crtcs = NULL;
info->modes = NULL;
info->screen = screen;
- if (fill_out_screen_info (priv->xdisplay, priv->xroot, info, needs_reprobe, error))
+ if (fill_out_screen_info (info, error))
{
return info;
}
@@ -530,13 +458,13 @@ screen_info_new (GnomeRRScreen *screen, gboolean needs_reprobe, GError **error)
}
static GnomeRROutput *
-find_output_by_id (GnomeRROutput **haystack, guint32 id)
+find_output_by_winsys_id (GnomeRROutput **haystack, glong winsys_id)
{
guint i;
for (i = 0; haystack[i] != NULL; i++)
{
- if (gnome_rr_output_get_id (haystack[i]) == id)
+ if (haystack[i]->winsys_id == winsys_id)
return haystack[i];
}
return NULL;
@@ -546,76 +474,50 @@ static void
diff_outputs_and_emit_signals (ScreenInfo *old, ScreenInfo *new)
{
guint i;
- guint32 id_old, id_new;
+ gulong winsys_id_old, winsys_id_new;
GnomeRROutput *output_old;
GnomeRROutput *output_new;
- /* have any outputs been removed or disconnected */
+ /* have any outputs been removed/disconnected */
for (i = 0; old->outputs[i] != NULL; i++)
{
- id_old = gnome_rr_output_get_id (old->outputs[i]);
- output_new = find_output_by_id (new->outputs, id_old);
+ winsys_id_old = old->outputs[i]->winsys_id;
+ output_new = find_output_by_winsys_id (new->outputs, winsys_id_old);
if (output_new == NULL)
{
- /* output removed (and disconnected) */
- if (gnome_rr_output_is_connected (old->outputs[i]))
- {
- g_signal_emit (G_OBJECT (new->screen),
- screen_signals[SCREEN_OUTPUT_DISCONNECTED], 0,
- old->outputs[i]);
- }
- continue;
- }
- if (gnome_rr_output_is_connected (old->outputs[i]) &&
- !gnome_rr_output_is_connected (output_new))
- {
- /* output disconnected */
g_signal_emit (G_OBJECT (new->screen),
screen_signals[SCREEN_OUTPUT_DISCONNECTED], 0,
old->outputs[i]);
- }
+ }
}
- /* have any outputs been created or connected */
+ /* have any outputs been created/connected */
for (i = 0; new->outputs[i] != NULL; i++)
{
- id_new = gnome_rr_output_get_id (new->outputs[i]);
- output_old = find_output_by_id (old->outputs, id_new);
+ winsys_id_new = new->outputs[i]->winsys_id;
+ output_old = find_output_by_winsys_id (old->outputs, winsys_id_new);
if (output_old == NULL)
{
- /* output created */
- if (gnome_rr_output_is_connected (new->outputs[i]))
- {
- g_signal_emit (G_OBJECT (new->screen),
- screen_signals[SCREEN_OUTPUT_CONNECTED], 0,
- new->outputs[i]);
- }
- continue;
- }
- if (!gnome_rr_output_is_connected (output_old) &&
- gnome_rr_output_is_connected (new->outputs[i]))
- {
- /* output connected */
g_signal_emit (G_OBJECT (new->screen),
screen_signals[SCREEN_OUTPUT_CONNECTED], 0,
new->outputs[i]);
- }
+ }
}
}
static gboolean
-screen_update (GnomeRRScreen *screen, gboolean force_callback, gboolean needs_reprobe, GError **error)
+screen_update (GnomeRRScreen *screen, gboolean force_callback, GError **error)
{
ScreenInfo *info;
gboolean changed = FALSE;
g_assert (screen != NULL);
- info = screen_info_new (screen, needs_reprobe, error);
+ info = screen_info_new (screen, error);
if (!info)
return FALSE;
- if (info->resources->configTimestamp != screen->priv->info->resources->configTimestamp)
+ if (info->serial != screen->priv->info->serial)
changed = TRUE;
/* work out if any outputs have changed connected state */
@@ -631,98 +533,13 @@ screen_update (GnomeRRScreen *screen, gboolean force_callback, gboolean needs_re
return changed;
}
-static GdkFilterReturn
-screen_on_event (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
+static void
+screen_on_monitors_changed (GdkScreen *gdk_screen,
+ gpointer data)
{
GnomeRRScreen *screen = data;
- GnomeRRScreenPrivate *priv = screen->priv;
- XEvent *e = xevent;
- int event_num;
-
- if (!e)
- return GDK_FILTER_CONTINUE;
-
- event_num = e->type - priv->randr_event_base;
-
- if (event_num == RRScreenChangeNotify) {
- /* We don't reprobe the hardware; we just fetch the X server's latest
- * state. The server already knows the new state of the outputs; that's
- * why it sent us an event!
- */
- screen_update (screen, TRUE, FALSE, NULL); /* NULL-GError */
-#if 0
- /* Enable this code to get a dialog showing the RANDR timestamps, for debugging purposes */
- {
- GtkWidget *dialog;
- XRRScreenChangeNotifyEvent *rr_event;
- static int dialog_num;
-
- rr_event = (XRRScreenChangeNotifyEvent *) e;
-
- dialog = gtk_message_dialog_new (NULL,
- 0,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- "RRScreenChangeNotify timestamps (%d):\n"
- "event change: %u\n"
- "event config: %u\n"
- "event serial: %lu\n"
- "----------------------"
- "screen change: %u\n"
- "screen config: %u\n",
- dialog_num++,
- (guint32) rr_event->timestamp,
- (guint32) rr_event->config_timestamp,
- rr_event->serial,
- (guint32) priv->info->resources->timestamp,
- (guint32) priv->info->resources->configTimestamp);
- g_signal_connect (dialog, "response",
- G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_show (dialog);
- }
-#endif
- }
-#if 0
- /* WHY THIS CODE IS DISABLED:
- *
- * Note that in gnome_rr_screen_new(), we only select for
- * RRScreenChangeNotifyMask. We used to select for other values in
- * RR*NotifyMask, but we weren't really doing anything useful with those
- * events. We only care about "the screens changed in some way or another"
- * for now.
- *
- * If we ever run into a situtation that could benefit from processing more
- * detailed events, we can enable this code again.
- *
- * Note that the X server sends RRScreenChangeNotify in conjunction with the
- * more detailed events from RANDR 1.2 - see xserver/randr/randr.c:TellChanged().
- */
- else if (event_num == RRNotify)
- {
- /* Other RandR events */
-
- XRRNotifyEvent *event = (XRRNotifyEvent *)e;
-
- /* Here we can distinguish between RRNotify events supported
- * since RandR 1.2 such as RRNotify_OutputProperty. For now, we
- * don't have anything special to do for particular subevent types, so
- * we leave this as an empty switch().
- */
- switch (event->subtype)
- {
- default:
- break;
- }
-
- /* No need to reprobe hardware here */
- screen_update (screen, TRUE, FALSE, NULL); /* NULL-GError */
- }
-#endif
- /* Pass the event on to GTK+ */
- return GDK_FILTER_CONTINUE;
+ screen_update (screen, TRUE, NULL);
}
static gboolean
@@ -730,46 +547,25 @@ gnome_rr_screen_initable_init (GInitable *initable, GCancellable *canc, GError *
{
GnomeRRScreen *self = GNOME_RR_SCREEN (initable);
GnomeRRScreenPrivate *priv = self->priv;
- Display *dpy = GDK_SCREEN_XDISPLAY (self->priv->gdk_screen);
- int event_base;
- int ignore;
-
- priv->connector_type_atom = XInternAtom (dpy, "ConnectorType", FALSE);
-
- if (XRRQueryExtension (dpy, &event_base, &ignore))
- {
- priv->randr_event_base = event_base;
-
- XRRQueryVersion (dpy, &priv->rr_major_version, &priv->rr_minor_version);
- if (priv->rr_major_version < 1 || (priv->rr_major_version == 1 && priv->rr_minor_version < 2)) {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_RANDR_EXTENSION,
- "RANDR extension is too old (must be at least 1.2)");
- return FALSE;
- }
-
- priv->info = screen_info_new (self, TRUE, error);
-
- if (!priv->info) {
- return FALSE;
- }
+ MetaDBusDisplayConfig *proxy;
+
+ proxy = meta_dbus_display_config_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ "org.gnome.Mutter.DisplayConfig",
+ "/org/gnome/Mutter/DisplayConfig",
+ NULL, error);
+ if (!proxy)
+ return FALSE;
- XRRSelectInput (priv->xdisplay,
- priv->xroot,
- RRScreenChangeNotifyMask);
- gdk_x11_register_standard_event_type (gdk_screen_get_display (priv->gdk_screen),
- event_base,
- RRNotify + 1);
- gdk_window_add_filter (priv->gdk_root, screen_on_event, self);
+ priv->proxy = META_DBUS_DISPLAY_CONFIG (proxy);
- return TRUE;
- }
- else
- {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_NO_RANDR_EXTENSION,
- _("RANDR extension is not present"));
+ priv->info = screen_info_new (self, error);
+ if (!priv->info)
+ return FALSE;
- return FALSE;
- }
+ g_signal_connect_object (priv->gdk_screen, "monitors-changed",
+ G_CALLBACK (screen_on_monitors_changed), self, 0);
+ return TRUE;
}
void
@@ -783,11 +579,11 @@ gnome_rr_screen_finalize (GObject *gobject)
{
GnomeRRScreen *screen = GNOME_RR_SCREEN (gobject);
- gdk_window_remove_filter (screen->priv->gdk_root, screen_on_event, screen);
-
if (screen->priv->info)
screen_info_free (screen->priv->info);
+ g_clear_object (&screen->priv->proxy);
+
G_OBJECT_CLASS (gnome_rr_screen_parent_class)->finalize (gobject);
}
@@ -801,10 +597,6 @@ gnome_rr_screen_set_property (GObject *gobject, guint property_id, const GValue
{
case SCREEN_PROP_GDK_SCREEN:
priv->gdk_screen = g_value_get_object (value);
- priv->gdk_root = gdk_screen_get_root_window (priv->gdk_screen);
- priv->xroot = gdk_x11_window_get_xid (priv->gdk_root);
- priv->xdisplay = GDK_SCREEN_XDISPLAY (priv->gdk_screen);
- priv->xscreen = gdk_x11_screen_get_xscreen (priv->gdk_screen);
return;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, property);
@@ -928,15 +720,6 @@ gnome_rr_screen_init (GnomeRRScreen *self)
{
GnomeRRScreenPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GNOME_TYPE_RR_SCREEN,
GnomeRRScreenPrivate);
self->priv = priv;
-
- priv->gdk_screen = NULL;
- priv->gdk_root = NULL;
- priv->xdisplay = NULL;
- priv->xroot = None;
- priv->xscreen = NULL;
- priv->info = NULL;
- priv->rr_major_version = 0;
- priv->rr_minor_version = 0;
}
/* Weak reference callback set in gnome_rr_screen_new(); we remove the GObject data from the GdkScreen. */
@@ -982,21 +765,6 @@ gnome_rr_screen_new (GdkScreen *screen,
return rr_screen;
}
-void
-gnome_rr_screen_set_size (GnomeRRScreen *screen,
- int width,
- int height,
- int mm_width,
- int mm_height)
-{
- g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
-
- gdk_error_trap_push ();
- XRRSetScreenSize (screen->priv->xdisplay, screen->priv->xroot,
- width, height, mm_width, mm_height);
- gdk_error_trap_pop_ignored ();
-}
-
/**
* gnome_rr_screen_get_ranges:
* @screen: a #GnomeRRScreen
@@ -1034,83 +802,6 @@ gnome_rr_screen_get_ranges (GnomeRRScreen *screen,
}
/**
- * gnome_rr_screen_get_timestamps:
- * @screen: a #GnomeRRScreen
- * @change_timestamp_ret: (out): Location in which to store the timestamp at which the RANDR configuration
was last changed
- * @config_timestamp_ret: (out): Location in which to store the timestamp at which the RANDR configuration
was last obtained
- *
- * Queries the two timestamps that the X RANDR extension maintains. The X
- * server will prevent change requests for stale configurations, those whose
- * timestamp is not equal to that of the latest request for configuration. The
- * X server will also prevent change requests that have an older timestamp to
- * the latest change request.
- */
-void
-gnome_rr_screen_get_timestamps (GnomeRRScreen *screen,
- guint32 *change_timestamp_ret,
- guint32 *config_timestamp_ret)
-{
- GnomeRRScreenPrivate *priv;
-
- g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
-
- priv = screen->priv;
-
- if (change_timestamp_ret)
- *change_timestamp_ret = priv->info->resources->timestamp;
-
- if (config_timestamp_ret)
- *config_timestamp_ret = priv->info->resources->configTimestamp;
-}
-
-static gboolean
-force_timestamp_update (GnomeRRScreen *screen)
-{
- GnomeRRScreenPrivate *priv = screen->priv;
- GnomeRRCrtc *crtc;
- XRRCrtcInfo *current_info;
- Status status;
- gboolean timestamp_updated;
-
- timestamp_updated = FALSE;
-
- crtc = priv->info->crtcs[0];
-
- if (crtc == NULL)
- goto out;
-
- current_info = XRRGetCrtcInfo (priv->xdisplay,
- priv->info->resources,
- crtc->id);
-
- if (current_info == NULL)
- goto out;
-
- gdk_error_trap_push ();
- status = XRRSetCrtcConfig (priv->xdisplay,
- priv->info->resources,
- crtc->id,
- current_info->timestamp,
- current_info->x,
- current_info->y,
- current_info->mode,
- current_info->rotation,
- current_info->outputs,
- current_info->noutput);
-
- XRRFreeCrtcInfo (current_info);
-
- gdk_flush ();
- if (gdk_error_trap_pop ())
- goto out;
-
- if (status == RRSetConfigSuccess)
- timestamp_updated = TRUE;
-out:
- return timestamp_updated;
-}
-
-/**
* gnome_rr_screen_refresh:
* @screen: a #GnomeRRScreen
* @error: location to store error, or %NULL
@@ -1127,18 +818,9 @@ gboolean
gnome_rr_screen_refresh (GnomeRRScreen *screen,
GError **error)
{
- gboolean refreshed;
-
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- gdk_x11_display_grab (gdk_screen_get_display (screen->priv->gdk_screen));
-
- refreshed = screen_update (screen, FALSE, TRUE, error);
- force_timestamp_update (screen); /* this is to keep other clients from thinking that the X server
re-detected things by itself - bgo#621046 */
-
- gdk_x11_display_ungrab (gdk_screen_get_display (screen->priv->gdk_screen));
-
- return refreshed;
+ return screen_update (screen, FALSE, error);
}
/**
@@ -1146,81 +828,43 @@ gnome_rr_screen_refresh (GnomeRRScreen *screen,
* @mode: (out): The current #GnomeRRDpmsMode of this screen
**/
gboolean
-gnome_rr_screen_get_dpms_mode (GnomeRRScreen *screen,
- GnomeRRDpmsMode *mode,
- GError **error)
+gnome_rr_screen_get_dpms_mode (GnomeRRScreen *screen,
+ GnomeRRDpmsMode *mode,
+ GError **error)
{
- BOOL enabled = FALSE;
- CARD16 state;
- gboolean ret = FALSE;
+ MetaPowerSave power_save;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (mode != NULL, FALSE);
- if (!screen->priv->dpms_capable) {
+ power_save = meta_dbus_display_config_get_power_save_mode (screen->priv->proxy);
+
+ if (power_save == META_POWER_SAVE_UNKNOWN) {
g_set_error_literal (error,
GNOME_RR_ERROR,
GNOME_RR_ERROR_NO_DPMS_EXTENSION,
"Display is not DPMS capable");
- goto out;
- }
-
- if (!DPMSInfo (screen->priv->xdisplay,
- &state,
- &enabled)) {
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_UNKNOWN,
- "Unable to get DPMS state");
- goto out;
- }
-
- /* DPMS not enabled is a valid mode */
- if (!enabled) {
- *mode = GNOME_RR_DPMS_DISABLED;
- ret = TRUE;
- goto out;
+ return FALSE;
}
- switch (state) {
- case DPMSModeOn:
+ switch (power_save) {
+ case META_POWER_SAVE_ON:
*mode = GNOME_RR_DPMS_ON;
break;
- case DPMSModeStandby:
+ case META_POWER_SAVE_STANDBY:
*mode = GNOME_RR_DPMS_STANDBY;
break;
- case DPMSModeSuspend:
+ case META_POWER_SAVE_SUSPEND:
*mode = GNOME_RR_DPMS_SUSPEND;
break;
- case DPMSModeOff:
+ case META_POWER_SAVE_OFF:
*mode = GNOME_RR_DPMS_OFF;
break;
default:
g_assert_not_reached ();
break;
}
- ret = TRUE;
-out:
- return ret;
-}
-/**
- * gnome_rr_screen_clear_dpms_timeouts:
- **/
-static gboolean
-gnome_rr_screen_clear_dpms_timeouts (GnomeRRScreen *screen,
- GError **error)
-{
- gdk_error_trap_push ();
- /* DPMSSetTimeouts() return value is often a lie, so ignore it */
- DPMSSetTimeouts (screen->priv->xdisplay, 0, 0, 0);
- if (gdk_error_trap_pop ()) {
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_UNKNOWN,
- "Could not set DPMS timeouts");
- return FALSE;
- }
return TRUE;
}
@@ -1230,11 +874,11 @@ gnome_rr_screen_clear_dpms_timeouts (GnomeRRScreen *screen,
* This method also disables the DPMS timeouts.
**/
gboolean
-gnome_rr_screen_set_dpms_mode (GnomeRRScreen *screen,
- GnomeRRDpmsMode mode,
- GError **error)
+gnome_rr_screen_set_dpms_mode (GnomeRRScreen *screen,
+ GnomeRRDpmsMode mode,
+ GError **error)
{
- CARD16 state = 0;
+ MetaPowerSave power_save;
gboolean ret;
GnomeRRDpmsMode current_mode;
@@ -1243,48 +887,31 @@ gnome_rr_screen_set_dpms_mode (GnomeRRScreen *screen,
/* set, if the new mode is different */
ret = gnome_rr_screen_get_dpms_mode (screen, ¤t_mode, error);
if (!ret)
- goto out;
- if (current_mode == mode) {
- ret = gnome_rr_screen_clear_dpms_timeouts (screen, error);
- goto out;
- }
+ return FALSE;
+ if (current_mode == mode)
+ return TRUE;
switch (mode) {
case GNOME_RR_DPMS_ON:
- state = DPMSModeOn;
+ power_save = META_POWER_SAVE_ON;
break;
case GNOME_RR_DPMS_STANDBY:
- state = DPMSModeStandby;
+ power_save = META_POWER_SAVE_STANDBY;
break;
case GNOME_RR_DPMS_SUSPEND:
- state = DPMSModeSuspend;
+ power_save = META_POWER_SAVE_SUSPEND;
break;
case GNOME_RR_DPMS_OFF:
- state = DPMSModeOff;
+ power_save = META_POWER_SAVE_OFF;
break;
default:
g_assert_not_reached ();
break;
}
- gdk_error_trap_push ();
- /* DPMSForceLevel() return value is often a lie, so ignore it */
- DPMSForceLevel (screen->priv->xdisplay, state);
- XSync (screen->priv->xdisplay, False);
- if (gdk_error_trap_pop ()) {
- ret = FALSE;
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_UNKNOWN,
- "Could not change DPMS mode");
- goto out;
- }
+ meta_dbus_display_config_set_power_save_mode (screen->priv->proxy, power_save);
- ret = gnome_rr_screen_clear_dpms_timeouts (screen, error);
- if (!ret)
- goto out;
-out:
- return ret;
+ return TRUE;
}
/**
@@ -1405,7 +1032,7 @@ gnome_rr_screen_get_output_by_id (GnomeRRScreen *screen,
/* GnomeRROutput */
static GnomeRROutput *
-output_new (ScreenInfo *info, RROutput id)
+output_new (ScreenInfo *info, guint id)
{
GnomeRROutput *output = g_slice_new0 (GnomeRROutput);
@@ -1415,230 +1042,90 @@ output_new (ScreenInfo *info, RROutput id)
return output;
}
-static guint8 *
-get_property (Display *dpy,
- RROutput output,
- Atom atom,
- gsize *len)
-{
- unsigned char *prop;
- int actual_format;
- unsigned long nitems, bytes_after;
- Atom actual_type;
- guint8 *result;
-
- XRRGetOutputProperty (dpy, output, atom,
- 0, 100, False, False,
- AnyPropertyType,
- &actual_type, &actual_format,
- &nitems, &bytes_after, &prop);
-
- if (actual_type == XA_INTEGER && actual_format == 8)
- {
- result = g_memdup (prop, nitems);
- if (len)
- *len = nitems;
- }
- else
- {
- result = NULL;
- }
-
- XFree (prop);
-
- return result;
-}
-
-static guint8 *
-read_edid_data (GnomeRROutput *output, gsize *len)
+static void
+append_output_array (GnomeRROutput ***array, GnomeRROutput *output)
{
- Atom edid_atom;
- guint8 *result;
+ unsigned i;
- edid_atom = XInternAtom (DISPLAY (output), "EDID", FALSE);
- result = get_property (DISPLAY (output),
- output->id, edid_atom, len);
+ for (i = 0; (*array)[i]; i++);
- if (!result)
- {
- edid_atom = XInternAtom (DISPLAY (output), "EDID_DATA", FALSE);
- result = get_property (DISPLAY (output),
- output->id, edid_atom, len);
- }
-
- if (!result)
- {
- edid_atom = XInternAtom (DISPLAY (output), "XFree86_DDC_EDID1_RAWDATA", FALSE);
- result = get_property (DISPLAY (output),
- output->id, edid_atom, len);
- }
+ *array = g_renew (GnomeRROutput *, *array, i + 2);
- if (result)
- {
- if (*len % 128 == 0)
- return result;
- else
- g_free (result);
- }
-
- return NULL;
-}
-
-static char *
-get_connector_type_string (GnomeRROutput *output)
-{
- char *result;
- unsigned char *prop;
- int actual_format;
- unsigned long nitems, bytes_after;
- Atom actual_type;
- Atom connector_type;
- char *connector_type_str;
-
- result = NULL;
-
- if (XRRGetOutputProperty (DISPLAY (output), output->id, output->info->screen->priv->connector_type_atom,
- 0, 100, False, False,
- AnyPropertyType,
- &actual_type, &actual_format,
- &nitems, &bytes_after, &prop) != Success)
- return NULL;
-
- if (!(actual_type == XA_ATOM && actual_format == 32 && nitems == 1))
- goto out;
-
- connector_type = *((Atom *) prop);
-
- connector_type_str = XGetAtomName (DISPLAY (output), connector_type);
- if (connector_type_str) {
- result = g_strdup (connector_type_str); /* so the caller can g_free() it */
- XFree (connector_type_str);
- }
-
-out:
-
- XFree (prop);
-
- return result;
+ (*array)[i] = output;
+ (*array)[i + 1] = NULL;
}
static void
-update_brightness_limits (GnomeRROutput *output)
-{
- gint rc;
- Atom atom;
- XRRPropertyInfo *info;
-
- gdk_error_trap_push ();
- atom = XInternAtom (DISPLAY (output), "BACKLIGHT", FALSE);
- info = XRRQueryOutputProperty (DISPLAY (output), output->id, atom);
- rc = gdk_error_trap_pop ();
- if (rc != Success)
- {
- if (rc != BadName)
- g_warning ("could not get output property for %s, rc: %i",
- output->name, rc);
- goto out;
- }
- if (info == NULL)
- {
- g_warning ("could not get output property for %s",
- output->name);
- goto out;
- }
- if (!info->range || info->num_values != 2)
- {
- g_debug ("backlight %s was not range", output->name);
- goto out;
- }
- output->backlight_min = info->values[0];
- output->backlight_max = info->values[1];
-out:
- if (info != NULL)
- {
- XFree (info);
- }
-}
-
-static gboolean
-output_initialize (GnomeRROutput *output, XRRScreenResources *res, GError **error)
+output_initialize (GnomeRROutput *output, GVariant *info)
{
- XRROutputInfo *info = XRRGetOutputInfo (
- DISPLAY (output), res, output->id);
GPtrArray *a;
- int i;
-
-#if 0
- g_print ("Output %lx Timestamp: %u\n", output->id, (guint32)info->timestamp);
-#endif
-
- if (!info || !output->info)
- {
- /* FIXME: see the comment in crtc_initialize() */
- /* Translators: here, an "output" is a video output */
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR,
- _("could not get information about output %d"),
- (int) output->id);
- return FALSE;
- }
-
- output->name = g_strdup (info->name); /* FIXME: what is nameLen used for? */
- output->display_name = NULL; /* set first time the getter is used */
- output->current_crtc = crtc_by_id (output->info, info->crtc);
- output->width_mm = info->mm_width;
- output->height_mm = info->mm_height;
- output->connected = (info->connection == RR_Connected);
- output->connector_type = get_connector_type_string (output);
+ GVariantIter *crtcs, *clones, *modes;
+ GVariant *properties;
+ int current_crtc_id;
+ guint id;
+
+ g_variant_get (info, "(uxiaussssiauau a{sv})",
+ &output->id, &output->winsys_id,
+ ¤t_crtc_id, &crtcs,
+ &output->name, &output->vendor,
+ &output->product, &output->serial,
+ &output->backlight,
+ &modes, &clones, &properties);
/* Possible crtcs */
a = g_ptr_array_new ();
-
- for (i = 0; i < info->ncrtc; ++i)
+ while (g_variant_iter_loop (crtcs, "u", &id))
{
- GnomeRRCrtc *crtc = crtc_by_id (output->info, info->crtcs[i]);
+ GnomeRRCrtc *crtc = crtc_by_id (output->info, id);
- if (crtc)
- g_ptr_array_add (a, crtc);
+ if (!crtc)
+ continue;
+
+ g_ptr_array_add (a, crtc);
+
+ if (crtc->id == current_crtc_id)
+ {
+ output->current_crtc = crtc;
+ append_output_array (&crtc->current_outputs, output);
+ }
+
+ append_output_array (&crtc->possible_outputs, output);
}
g_ptr_array_add (a, NULL);
output->possible_crtcs = (GnomeRRCrtc **)g_ptr_array_free (a, FALSE);
-
+ g_variant_iter_free (crtcs);
+
/* Clones */
a = g_ptr_array_new ();
- for (i = 0; i < info->nclone; ++i)
+ while (g_variant_iter_loop (clones, "u", &id))
{
- GnomeRROutput *gnome_rr_output = gnome_rr_output_by_id (output->info, info->clones[i]);
+ GnomeRROutput *gnome_rr_output = gnome_rr_output_by_id (output->info, id);
if (gnome_rr_output)
g_ptr_array_add (a, gnome_rr_output);
}
g_ptr_array_add (a, NULL);
output->clones = (GnomeRROutput **)g_ptr_array_free (a, FALSE);
+ g_variant_iter_free (clones);
/* Modes */
a = g_ptr_array_new ();
- for (i = 0; i < info->nmode; ++i)
+ while (g_variant_iter_loop (modes, "u", &id))
{
- GnomeRRMode *mode = mode_by_id (output->info, info->modes[i]);
+ GnomeRRMode *mode = mode_by_id (output->info, id);
if (mode)
g_ptr_array_add (a, mode);
}
g_ptr_array_add (a, NULL);
output->modes = (GnomeRRMode **)g_ptr_array_free (a, FALSE);
+ g_variant_iter_free (modes);
- output->n_preferred = info->npreferred;
-
- /* Edid data */
- output->edid_data = read_edid_data (output, &output->edid_size);
+ g_variant_lookup (properties, "primary", "b", &output->is_primary);
+ g_variant_lookup (properties, "presentation", "b", &output->is_presentation);
- /* brightness data */
- if (output->connected)
- update_brightness_limits (output);
-
- XRRFreeOutputInfo (info);
-
- return TRUE;
+ if (output->is_primary)
+ output->info->primary = output;
}
static GnomeRROutput*
@@ -1653,14 +1140,14 @@ output_copy (const GnomeRROutput *from)
output->id = from->id;
output->info = from->info;
output->name = g_strdup (from->name);
+ output->vendor = g_strdup (from->vendor);
+ output->product = g_strdup (from->product);
+ output->serial = g_strdup (from->serial);
output->current_crtc = from->current_crtc;
- output->width_mm = from->width_mm;
- output->height_mm = from->height_mm;
- output->connected = from->connected;
- output->n_preferred = from->n_preferred;
- output->connector_type = g_strdup (from->connector_type);
- output->backlight_min = -1;
- output->backlight_max = -1;
+ output->backlight = from->backlight;
+
+ output->is_primary = from->is_primary;
+ output->is_presentation = from->is_presentation;
array = g_ptr_array_new ();
for (p_crtc = from->possible_crtcs; *p_crtc != NULL; p_crtc++)
@@ -1683,9 +1170,6 @@ output_copy (const GnomeRROutput *from)
}
output->modes = (GnomeRRMode**) g_ptr_array_free (array, FALSE);
- output->edid_size = from->edid_size;
- output->edid_data = g_memdup (from->edid_data, from->edid_size);
-
return output;
}
@@ -1695,10 +1179,11 @@ output_free (GnomeRROutput *output)
g_free (output->clones);
g_free (output->modes);
g_free (output->possible_crtcs);
- g_free (output->edid_data);
g_free (output->name);
+ g_free (output->vendor);
+ g_free (output->product);
+ g_free (output->serial);
g_free (output->display_name);
- g_free (output->connector_type);
g_slice_free (GnomeRROutput, output);
}
@@ -1710,15 +1195,6 @@ gnome_rr_output_get_id (GnomeRROutput *output)
return output->id;
}
-const guint8 *
-gnome_rr_output_get_edid_data (GnomeRROutput *output, gsize *size)
-{
- g_return_val_if_fail (output != NULL, NULL);
- if (size)
- *size = output->edid_size;
- return output->edid_data;
-}
-
/**
* gnome_rr_output_get_ids_from_edid:
* @output: a #GnomeRROutput
@@ -1726,32 +1202,17 @@ gnome_rr_output_get_edid_data (GnomeRROutput *output, gsize *size)
* @product: (out) (allow-none):
* @serial: (out) (allow-none):
*/
-gboolean
+void
gnome_rr_output_get_ids_from_edid (GnomeRROutput *output,
char **vendor,
- int *product,
- int *serial)
+ char **product,
+ char **serial)
{
- MonitorInfo *info;
-
- g_return_val_if_fail (output != NULL, FALSE);
-
- if (!output->edid_data)
- return FALSE;
- info = decode_edid (output->edid_data);
- if (!info)
- return FALSE;
- if (vendor)
- *vendor = g_memdup (info->manufacturer_code, 4);
- if (product)
- *product = info->product_code;
- if (serial)
- *serial = info->serial_number;
-
- g_free (info);
-
- return TRUE;
+ g_return_if_fail (output != NULL);
+ *vendor = g_strdup (output->vendor);
+ *product = g_strdup (output->product);
+ *serial = g_strdup (output->serial);
}
static void
@@ -1763,31 +1224,13 @@ ensure_display_name (GnomeRROutput *output)
if (gnome_rr_output_is_builtin_display (output))
output->display_name = g_strdup (_("Built-in Display"));
- if (output->display_name == NULL
- && output->edid_data != NULL) {
- MonitorInfo *info;
-
- info = decode_edid (output->edid_data);
- if (info != NULL)
- output->display_name = make_display_name (info);
-
- g_free (info);
- }
-
- if (output->display_name == NULL) {
- char *inches;
- inches = make_display_size_string (output->width_mm, output->height_mm);
- if (inches != NULL) {
- /* Translators: %s is the size of the monitor in inches */
- output->display_name = g_strdup_printf (_("%s Display"), inches);
- }
- g_free (inches);
- }
+#if 0
+ if (output->display_name == NULL)
+ output->display_name = make_display_name (output);
+#endif
- /* last chance on the stairway */
- if (output->display_name == NULL) {
+ if (output->display_name == NULL)
output->display_name = g_strdup (_("Unknown Display"));
- }
}
const char *
@@ -1801,136 +1244,33 @@ gnome_rr_output_get_display_name (GnomeRROutput *output)
}
/**
- * gnome_rr_output_get_backlight_min:
- *
- * Returns: The mimimum backlight value, or -1 if not supported
- */
-gint
-gnome_rr_output_get_backlight_min (GnomeRROutput *output)
-{
- g_return_val_if_fail (output != NULL, -1);
- return output->backlight_min;
-}
-
-/**
- * gnome_rr_output_get_backlight_max:
- *
- * Returns: The maximum backlight value, or -1 if not supported
- */
-gint
-gnome_rr_output_get_backlight_max (GnomeRROutput *output)
-{
- g_return_val_if_fail (output != NULL, -1);
- return output->backlight_max;
-}
-
-/**
* gnome_rr_output_get_backlight:
*
* Returns: The currently set backlight brightness
*/
-gint
-gnome_rr_output_get_backlight (GnomeRROutput *output, GError **error)
-{
- guint now = -1;
- unsigned long nitems;
- unsigned long bytes_after;
- guint *prop;
- Atom atom;
- Atom actual_type;
- int actual_format;
- gint retval;
-
+int
+gnome_rr_output_get_backlight (GnomeRROutput *output)
+{
g_return_val_if_fail (output != NULL, -1);
- gdk_error_trap_push ();
- atom = XInternAtom (DISPLAY (output), "BACKLIGHT", FALSE);
- retval = XRRGetOutputProperty (DISPLAY (output), output->id, atom,
- 0, 4, False, False, None,
- &actual_type, &actual_format,
- &nitems, &bytes_after, ((unsigned char **)&prop));
- gdk_flush ();
- if (gdk_error_trap_pop ())
- {
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_UNKNOWN,
- "unhandled X error while getting the range of backlight values");
- goto out;
- }
-
- if (retval != Success) {
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_RANDR_ERROR,
- "could not get the range of backlight values");
- goto out;
- }
- if (actual_type == XA_INTEGER &&
- nitems == 1 &&
- actual_format == 32)
- {
- memcpy (&now, prop, sizeof (guint));
- }
- else
- {
- g_set_error (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_RANDR_ERROR,
- "failed to get correct property type, got %lu,%i",
- nitems, actual_format);
- }
-out:
- XFree (prop);
- return now;
+ return output->backlight;
}
/**
* gnome_rr_output_set_backlight:
- * @value: the absolute value which is min >= this <= max
+ * @value: the absolute value which is 0 >= this <= 100
*
* Returns: %TRUE for success
*/
gboolean
gnome_rr_output_set_backlight (GnomeRROutput *output, gint value, GError **error)
{
- gboolean ret = FALSE;
- Atom atom;
-
g_return_val_if_fail (output != NULL, FALSE);
- /* check this is sane */
- if (value < output->backlight_min ||
- value > output->backlight_max)
- {
- g_set_error (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_BOUNDS_ERROR,
- "out of brightness range: %i, has to be %i -> %i",
- value,
- output->backlight_max, output->backlight_min);
- goto out;
- }
-
- /* don't abort on error */
- gdk_error_trap_push ();
- atom = XInternAtom (DISPLAY (output), "BACKLIGHT", FALSE);
- XRRChangeOutputProperty (DISPLAY (output), output->id, atom,
- XA_INTEGER, 32, PropModeReplace,
- (unsigned char *) &value, 1);
- if (gdk_error_trap_pop ())
- {
- g_set_error_literal (error,
- GNOME_RR_ERROR,
- GNOME_RR_ERROR_UNKNOWN,
- "unhandled X error while setting the backlight values");
- goto out;
- }
-
- /* we assume this succeeded as there's no return value */
- ret = TRUE;
-out:
- return ret;
+ return meta_dbus_display_config_call_change_backlight_sync (output->info->screen->priv->proxy,
+ output->info->serial,
+ output->id, value,
+ NULL, error);
}
/**
@@ -1966,15 +1306,6 @@ gnome_rr_output_get_crtc (GnomeRROutput *output)
return output->current_crtc;
}
-/* Returns NULL if the ConnectorType property is not available */
-const char *
-gnome_rr_output_get_connector_type (GnomeRROutput *output)
-{
- g_return_val_if_fail (output != NULL, NULL);
-
- return output->connector_type;
-}
-
gboolean
_gnome_rr_output_name_is_builtin_display (const char *name)
{
@@ -1997,20 +1328,7 @@ gnome_rr_output_is_builtin_display (GnomeRROutput *output)
{
g_return_val_if_fail (output != NULL, FALSE);
- if (!output->connected)
- return FALSE;
-
- /* The ConnectorType property is present in RANDR 1.3 and greater */
- if (g_strcmp0 (output->connector_type, GNOME_RR_CONNECTOR_TYPE_PANEL) == 0)
- return TRUE;
-
- /* Older versions of RANDR - this is a best guess, as @#$% RANDR doesn't have standard output names,
- * so drivers can use whatever they like.
- */
- if (_gnome_rr_output_name_is_builtin_display (output->name))
- return TRUE;
-
- return FALSE;
+ return _gnome_rr_output_name_is_builtin_display (output->name);
}
GnomeRRMode *
@@ -2052,28 +1370,11 @@ gnome_rr_output_get_name (GnomeRROutput *output)
return output->name;
}
-int
-gnome_rr_output_get_width_mm (GnomeRROutput *output)
-{
- g_assert (output != NULL);
- return output->width_mm;
-}
-
-int
-gnome_rr_output_get_height_mm (GnomeRROutput *output)
-{
- g_assert (output != NULL);
- return output->height_mm;
-}
-
GnomeRRMode *
gnome_rr_output_get_preferred_mode (GnomeRROutput *output)
{
g_return_val_if_fail (output != NULL, NULL);
- if (output->n_preferred)
- return output->modes[0];
-
- return NULL;
+ return output->modes[0];
}
GnomeRRMode **
@@ -2084,13 +1385,6 @@ gnome_rr_output_list_modes (GnomeRROutput *output)
}
gboolean
-gnome_rr_output_is_connected (GnomeRROutput *output)
-{
- g_return_val_if_fail (output != NULL, FALSE);
- return output->connected;
-}
-
-gboolean
gnome_rr_output_supports_mode (GnomeRROutput *output,
GnomeRRMode *mode)
{
@@ -2129,150 +1423,26 @@ gnome_rr_output_can_clone (GnomeRROutput *output,
gboolean
gnome_rr_output_get_is_primary (GnomeRROutput *output)
{
- return output->info->primary == output->id;
-}
-
-void
-gnome_rr_screen_set_primary_output (GnomeRRScreen *screen,
- GnomeRROutput *output)
-{
- GnomeRRScreenPrivate *priv;
- RROutput id;
-
- g_return_if_fail (GNOME_IS_RR_SCREEN (screen));
-
- priv = screen->priv;
-
- if (output)
- id = output->id;
- else
- id = None;
-
- if (SERVERS_RANDR_IS_AT_LEAST_1_3 (priv))
- XRRSetOutputPrimary (priv->xdisplay, priv->xroot, id);
+ return output->is_primary;
}
/* GnomeRRCrtc */
-typedef struct
-{
- Rotation xrot;
- GnomeRRRotation rot;
-} RotationMap;
-
-static const RotationMap rotation_map[] =
-{
- { RR_Rotate_0, GNOME_RR_ROTATION_0 },
- { RR_Rotate_90, GNOME_RR_ROTATION_90 },
- { RR_Rotate_180, GNOME_RR_ROTATION_180 },
- { RR_Rotate_270, GNOME_RR_ROTATION_270 },
- { RR_Reflect_X, GNOME_RR_REFLECT_X },
- { RR_Reflect_Y, GNOME_RR_REFLECT_Y },
+static const GnomeRRRotation rotation_map[] =
+{
+ GNOME_RR_ROTATION_0,
+ GNOME_RR_ROTATION_90,
+ GNOME_RR_ROTATION_180,
+ GNOME_RR_ROTATION_270,
+ GNOME_RR_REFLECT_X | GNOME_RR_ROTATION_0,
+ GNOME_RR_REFLECT_X | GNOME_RR_ROTATION_90,
+ GNOME_RR_REFLECT_X | GNOME_RR_ROTATION_180,
+ GNOME_RR_REFLECT_X | GNOME_RR_ROTATION_270,
};
static GnomeRRRotation
-gnome_rr_rotation_from_xrotation (Rotation r)
+gnome_rr_rotation_from_transform (enum wl_output_transform transform)
{
- int i;
- GnomeRRRotation result = 0;
-
- for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i)
- {
- if (r & rotation_map[i].xrot)
- result |= rotation_map[i].rot;
- }
-
- return result;
-}
-
-static Rotation
-xrotation_from_rotation (GnomeRRRotation r)
-{
- int i;
- Rotation result = 0;
-
- for (i = 0; i < G_N_ELEMENTS (rotation_map); ++i)
- {
- if (r & rotation_map[i].rot)
- result |= rotation_map[i].xrot;
- }
-
- return result;
-}
-
-gboolean
-gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc,
- guint32 timestamp,
- int x,
- int y,
- GnomeRRMode *mode,
- GnomeRRRotation rotation,
- GnomeRROutput **outputs,
- int n_outputs,
- GError **error)
-{
- ScreenInfo *info;
- GArray *output_ids;
- Status status;
- gboolean result;
- int i;
-
- g_return_val_if_fail (crtc != NULL, FALSE);
- g_return_val_if_fail (mode != NULL || outputs == NULL || n_outputs == 0, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
- info = crtc->info;
-
- if (mode)
- {
- if (x + mode->width > info->max_width
- || y + mode->height > info->max_height)
- {
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_BOUNDS_ERROR,
- /* Translators: the "position", "size", and "maximum"
- * words here are not keywords; please translate them
- * as usual. A CRTC is a CRT Controller (this is X terminology) */
- _("requested position/size for CRTC %d is outside the allowed limit: "
- "position=(%d, %d), size=(%d, %d), maximum=(%d, %d)"),
- (int) crtc->id,
- x, y,
- mode->width, mode->height,
- info->max_width, info->max_height);
- return FALSE;
- }
- }
-
- output_ids = g_array_new (FALSE, FALSE, sizeof (RROutput));
-
- if (outputs)
- {
- for (i = 0; i < n_outputs; ++i)
- g_array_append_val (output_ids, outputs[i]->id);
- }
-
- gdk_error_trap_push ();
- status = XRRSetCrtcConfig (DISPLAY (crtc), info->resources, crtc->id,
- timestamp,
- x, y,
- mode ? mode->id : None,
- xrotation_from_rotation (rotation),
- (RROutput *)output_ids->data,
- output_ids->len);
-
- g_array_free (output_ids, TRUE);
-
- if (gdk_error_trap_pop () || status != RRSetConfigSuccess) {
- /* Translators: CRTC is a CRT Controller (this is X terminology).
- * It is *very* unlikely that you'll ever get this error, so it is
- * only listed for completeness. */
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR,
- _("could not set the configuration for CRTC %d"),
- (int) crtc->id);
- return FALSE;
- } else {
- result = TRUE;
- }
-
- return result;
+ return rotation_map[transform];
}
GnomeRRMode *
@@ -2309,7 +1479,6 @@ gnome_rr_crtc_can_drive_output (GnomeRRCrtc *crtc,
return FALSE;
}
-/* FIXME: merge with get_mode()? */
/**
* gnome_rr_crtc_get_position:
* @crtc: a #GnomeRRCrtc
@@ -2330,19 +1499,32 @@ gnome_rr_crtc_get_position (GnomeRRCrtc *crtc,
*y = crtc->y;
}
-/* FIXME: merge with get_mode()? */
GnomeRRRotation
gnome_rr_crtc_get_current_rotation (GnomeRRCrtc *crtc)
{
g_assert(crtc != NULL);
- return crtc->current_rotation;
+ return gnome_rr_rotation_from_transform (crtc->transform);
+}
+
+static GnomeRRRotation
+gnome_rr_rotation_from_all_transforms (int all_transforms)
+{
+ GnomeRRRotation ret = all_transforms & 0x3;
+
+ if (all_transforms & (1 << WL_OUTPUT_TRANSFORM_FLIPPED))
+ ret |= GNOME_RR_REFLECT_X;
+
+ if (all_transforms & (1 << WL_OUTPUT_TRANSFORM_FLIPPED_180))
+ ret |= GNOME_RR_REFLECT_Y;
+
+ return ret;
}
GnomeRRRotation
gnome_rr_crtc_get_rotations (GnomeRRCrtc *crtc)
{
g_assert(crtc != NULL);
- return crtc->rotations;
+ return gnome_rr_rotation_from_all_transforms (crtc->all_transforms);
}
gboolean
@@ -2350,16 +1532,18 @@ gnome_rr_crtc_supports_rotation (GnomeRRCrtc * crtc,
GnomeRRRotation rotation)
{
g_return_val_if_fail (crtc != NULL, FALSE);
- return (crtc->rotations & rotation);
+ return (gnome_rr_rotation_from_all_transforms (crtc->all_transforms) & rotation);
}
static GnomeRRCrtc *
-crtc_new (ScreenInfo *info, RROutput id)
+crtc_new (ScreenInfo *info, guint id)
{
GnomeRRCrtc *crtc = g_slice_new0 (GnomeRRCrtc);
crtc->id = id;
crtc->info = info;
+ crtc->current_outputs = g_new0 (GnomeRROutput *, 1);
+ crtc->possible_outputs = g_new0 (GnomeRROutput *, 1);
return crtc;
}
@@ -2376,8 +1560,8 @@ crtc_copy (const GnomeRRCrtc *from)
to->current_mode = from->current_mode;
to->x = from->x;
to->y = from->y;
- to->current_rotation = from->current_rotation;
- to->rotations = from->rotations;
+ to->transform = from->transform;
+ to->all_transforms = from->all_transforms;
to->gamma_size = from->gamma_size;
array = g_ptr_array_new ();
@@ -2397,73 +1581,26 @@ crtc_copy (const GnomeRRCrtc *from)
return to;
}
-static gboolean
-crtc_initialize (GnomeRRCrtc *crtc,
- XRRScreenResources *res,
- GError **error)
+static void
+crtc_initialize (GnomeRRCrtc *crtc, GVariant *info)
{
- XRRCrtcInfo *info = XRRGetCrtcInfo (DISPLAY (crtc), res, crtc->id);
- GPtrArray *a;
- int i;
-
-#if 0
- g_print ("CRTC %lx Timestamp: %u\n", crtc->id, (guint32)info->timestamp);
-#endif
-
- if (!info)
- {
- /* FIXME: We need to reaquire the screen resources */
- /* FIXME: can we actually catch BadRRCrtc, and does it make sense to emit that? */
-
- /* Translators: CRTC is a CRT Controller (this is X terminology).
- * It is *very* unlikely that you'll ever get this error, so it is
- * only listed for completeness. */
- g_set_error (error, GNOME_RR_ERROR, GNOME_RR_ERROR_RANDR_ERROR,
- _("could not get information about CRTC %d"),
- (int) crtc->id);
- return FALSE;
- }
-
- /* GnomeRRMode */
- crtc->current_mode = mode_by_id (crtc->info, info->mode);
-
- crtc->x = info->x;
- crtc->y = info->y;
-
- /* Current outputs */
- a = g_ptr_array_new ();
- for (i = 0; i < info->noutput; ++i)
- {
- GnomeRROutput *output = gnome_rr_output_by_id (crtc->info, info->outputs[i]);
-
- if (output)
- g_ptr_array_add (a, output);
- }
- g_ptr_array_add (a, NULL);
- crtc->current_outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE);
-
- /* Possible outputs */
- a = g_ptr_array_new ();
- for (i = 0; i < info->npossible; ++i)
- {
- GnomeRROutput *output = gnome_rr_output_by_id (crtc->info, info->possible[i]);
-
- if (output)
- g_ptr_array_add (a, output);
- }
- g_ptr_array_add (a, NULL);
- crtc->possible_outputs = (GnomeRROutput **)g_ptr_array_free (a, FALSE);
-
- /* Rotations */
- crtc->current_rotation = gnome_rr_rotation_from_xrotation (info->rotation);
- crtc->rotations = gnome_rr_rotation_from_xrotation (info->rotations);
-
- XRRFreeCrtcInfo (info);
+ GVariantIter *all_transforms;
+ int current_mode_id;
+ guint transform;
- /* get an store gamma size */
- crtc->gamma_size = XRRGetCrtcGammaSize (DISPLAY (crtc), crtc->id);
+ g_variant_get (info, "(uxiiiiiuau a{sv})",
+ &crtc->id, &crtc->winsys_id,
+ &crtc->x, &crtc->y,
+ NULL, NULL,
+ ¤t_mode_id,
+ &crtc->transform, &all_transforms,
+ NULL);
- return TRUE;
+ /* GnomeRRMode */
+ crtc->current_mode = current_mode_id >= 0 ? mode_by_id (crtc->info, current_mode_id) : NULL;
+
+ while (g_variant_iter_loop (all_transforms, "u", &transform))
+ crtc->all_transforms |= 1 << transform;
}
static void
@@ -2476,7 +1613,7 @@ crtc_free (GnomeRRCrtc *crtc)
/* GnomeRRMode */
static GnomeRRMode *
-mode_new (ScreenInfo *info, RRMode id)
+mode_new (ScreenInfo *info, guint id)
{
GnomeRRMode *mode = g_slice_new0 (GnomeRRMode);
@@ -2515,15 +1652,16 @@ gnome_rr_mode_get_height (GnomeRRMode *mode)
}
static void
-mode_initialize (GnomeRRMode *mode, XRRModeInfo *info)
+mode_initialize (GnomeRRMode *mode, GVariant *info)
{
- g_assert (mode != NULL);
- g_assert (info != NULL);
+ gdouble frequency;
+
+ g_variant_get (info, "(uxuud)",
+ &mode->id, &mode->winsys_id,
+ &mode->width, &mode->height,
+ &frequency);
- mode->name = g_strdup (info->name);
- mode->width = info->width;
- mode->height = info->height;
- mode->freq = ((info->dotClock / (double)info->hTotal) / info->vTotal + 0.5) * 1000;
+ mode->freq = frequency * 1000;
}
static GnomeRRMode *
@@ -2533,7 +1671,6 @@ mode_copy (const GnomeRRMode *from)
to->id = from->id;
to->info = from->info;
- to->name = g_strdup (from->name);
to->width = from->width;
to->height = from->height;
to->freq = from->freq;
@@ -2544,78 +1681,19 @@ mode_copy (const GnomeRRMode *from)
static void
mode_free (GnomeRRMode *mode)
{
- g_free (mode->name);
g_slice_free (GnomeRRMode, mode);
}
-void
-gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc, int size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue)
-{
- int copy_size;
- XRRCrtcGamma *gamma;
-
- g_return_if_fail (crtc != NULL);
- g_return_if_fail (red != NULL);
- g_return_if_fail (green != NULL);
- g_return_if_fail (blue != NULL);
-
- if (size != crtc->gamma_size)
- return;
-
- gamma = XRRAllocGamma (crtc->gamma_size);
-
- copy_size = crtc->gamma_size * sizeof (unsigned short);
- memcpy (gamma->red, red, copy_size);
- memcpy (gamma->green, green, copy_size);
- memcpy (gamma->blue, blue, copy_size);
-
- XRRSetCrtcGamma (DISPLAY (crtc), crtc->id, gamma);
- XRRFreeGamma (gamma);
-}
-
gboolean
-gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc, int *size,
- unsigned short **red, unsigned short **green,
- unsigned short **blue)
-{
- int copy_size;
- unsigned short *r, *g, *b;
- XRRCrtcGamma *gamma;
-
- g_return_val_if_fail (crtc != NULL, FALSE);
-
- gamma = XRRGetCrtcGamma (DISPLAY (crtc), crtc->id);
- if (!gamma)
- return FALSE;
-
- copy_size = crtc->gamma_size * sizeof (unsigned short);
-
- if (red) {
- r = g_new0 (unsigned short, crtc->gamma_size);
- memcpy (r, gamma->red, copy_size);
- *red = r;
- }
-
- if (green) {
- g = g_new0 (unsigned short, crtc->gamma_size);
- memcpy (g, gamma->green, copy_size);
- *green = g;
- }
-
- if (blue) {
- b = g_new0 (unsigned short, crtc->gamma_size);
- memcpy (b, gamma->blue, copy_size);
- *blue = b;
- }
-
- XRRFreeGamma (gamma);
-
- if (size)
- *size = crtc->gamma_size;
-
- return TRUE;
+_gnome_rr_screen_apply_configuration (GnomeRRScreen *screen,
+ gboolean persistent,
+ GVariant *crtcs,
+ GVariant *outputs,
+ GError **error)
+{
+ return meta_dbus_display_config_call_apply_configuration_sync (screen->priv->proxy,
+ screen->priv->info->serial,
+ persistent,
+ crtcs, outputs,
+ NULL, error);
}
-
diff --git a/libgnome-desktop/gnome-rr.h b/libgnome-desktop/gnome-rr.h
index 08bceca..316e088 100644
--- a/libgnome-desktop/gnome-rr.h
+++ b/libgnome-desktop/gnome-rr.h
@@ -111,11 +111,6 @@ GnomeRROutput **gnome_rr_screen_list_outputs (GnomeRRScreen *scree
GnomeRRCrtc ** gnome_rr_screen_list_crtcs (GnomeRRScreen *screen);
GnomeRRMode ** gnome_rr_screen_list_modes (GnomeRRScreen *screen);
GnomeRRMode ** gnome_rr_screen_list_clone_modes (GnomeRRScreen *screen);
-void gnome_rr_screen_set_size (GnomeRRScreen *screen,
- int width,
- int height,
- int mm_width,
- int mm_height);
GnomeRRCrtc * gnome_rr_screen_get_crtc_by_id (GnomeRRScreen *screen,
guint32 id);
gboolean gnome_rr_screen_refresh (GnomeRRScreen *screen,
@@ -129,12 +124,6 @@ void gnome_rr_screen_get_ranges (GnomeRRScreen *scree
int *max_width,
int *min_height,
int *max_height);
-void gnome_rr_screen_get_timestamps (GnomeRRScreen *screen,
- guint32 *change_timestamp_ret,
- guint32 *config_timestamp_ret);
-
-void gnome_rr_screen_set_primary_output (GnomeRRScreen *screen,
- GnomeRROutput *output);
GnomeRRMode **gnome_rr_screen_create_clone_modes (GnomeRRScreen *screen);
@@ -149,21 +138,12 @@ gboolean gnome_rr_screen_set_dpms_mode (GnomeRRScreen *scree
guint32 gnome_rr_output_get_id (GnomeRROutput *output);
const char * gnome_rr_output_get_name (GnomeRROutput *output);
const char * gnome_rr_output_get_display_name (GnomeRROutput *output);
-gboolean gnome_rr_output_is_connected (GnomeRROutput *output);
-int gnome_rr_output_get_size_inches (GnomeRROutput *output);
-int gnome_rr_output_get_width_mm (GnomeRROutput *outout);
-int gnome_rr_output_get_height_mm (GnomeRROutput *output);
-const guint8 * gnome_rr_output_get_edid_data (GnomeRROutput *output,
- gsize *size);
-gboolean gnome_rr_output_get_ids_from_edid (GnomeRROutput *output,
+void gnome_rr_output_get_ids_from_edid (GnomeRROutput *output,
char **vendor,
- int *product,
- int *serial);
+ char **product,
+ char **serial);
-gint gnome_rr_output_get_backlight_min (GnomeRROutput *output);
-gint gnome_rr_output_get_backlight_max (GnomeRROutput *output);
-gint gnome_rr_output_get_backlight (GnomeRROutput *output,
- GError **error);
+gint gnome_rr_output_get_backlight (GnomeRROutput *output);
gboolean gnome_rr_output_set_backlight (GnomeRROutput *output,
gint value,
GError **error);
@@ -171,7 +151,6 @@ gboolean gnome_rr_output_set_backlight (GnomeRROutput *outpu
GnomeRRCrtc ** gnome_rr_output_get_possible_crtcs (GnomeRROutput *output);
GnomeRRMode * gnome_rr_output_get_current_mode (GnomeRROutput *output);
GnomeRRCrtc * gnome_rr_output_get_crtc (GnomeRROutput *output);
-const char * gnome_rr_output_get_connector_type (GnomeRROutput *output);
gboolean gnome_rr_output_is_builtin_display (GnomeRROutput *output);
void gnome_rr_output_get_position (GnomeRROutput *output,
int *x,
@@ -193,15 +172,6 @@ int gnome_rr_mode_get_freq (GnomeRRMode *mode)
/* GnomeRRCrtc */
guint32 gnome_rr_crtc_get_id (GnomeRRCrtc *crtc);
-gboolean gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc,
- guint32 timestamp,
- int x,
- int y,
- GnomeRRMode *mode,
- GnomeRRRotation rotation,
- GnomeRROutput **outputs,
- int n_outputs,
- GError **error);
gboolean gnome_rr_crtc_can_drive_output (GnomeRRCrtc *crtc,
GnomeRROutput *output);
GnomeRRMode * gnome_rr_crtc_get_current_mode (GnomeRRCrtc *crtc);
@@ -213,6 +183,7 @@ GnomeRRRotation gnome_rr_crtc_get_rotations (GnomeRRCrtc *crtc)
gboolean gnome_rr_crtc_supports_rotation (GnomeRRCrtc *crtc,
GnomeRRRotation rotation);
+#if 0 /* gamma support */
gboolean gnome_rr_crtc_get_gamma (GnomeRRCrtc *crtc,
int *size,
unsigned short **red,
@@ -223,4 +194,21 @@ void gnome_rr_crtc_set_gamma (GnomeRRCrtc *crtc,
unsigned short *red,
unsigned short *green,
unsigned short *blue);
+#endif
+
+#if 0 /* configuration writing */
+void gnome_rr_screen_set_primary_output (GnomeRRScreen *screen,
+ GnomeRROutput *output);
+
+gboolean gnome_rr_crtc_set_config_with_time (GnomeRRCrtc *crtc,
+ guint32 timestamp,
+ int x,
+ int y,
+ GnomeRRMode *mode,
+ GnomeRRRotation rotation,
+ GnomeRROutput **outputs,
+ int n_outputs,
+ GError **error);
+#endif
+
#endif /* GNOME_RR_H */
diff --git a/libgnome-desktop/xrandr.xml b/libgnome-desktop/xrandr.xml
new file mode 100644
index 0000000..f7abefd
--- /dev/null
+++ b/libgnome-desktop/xrandr.xml
@@ -0,0 +1,241 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+<node>
+ <!--
+ org.gnome.Mutter.DisplayConfig:
+ @short_description: display configuration interface
+
+ This interface is used by mutter and gnome-settings-daemon
+ to apply multiple monitor configuration.
+ -->
+
+ <interface name="org.gnome.Mutter.DisplayConfig">
+
+ <!--
+ GetResources:
+ @serial: configuration serial
+ @crtcs: available CRTCs
+ @outputs: available outputs
+ @modes: available modes
+ @max_screen_width:
+ @max_screen_height:
+
+ Retrieves the current layout of the hardware.
+
+ @serial is an unique identifier representing the current state
+ of the screen. It must be passed back to ApplyConfiguration()
+ and will be increased for every configuration change (so that
+ mutter can detect that the new configuration is based on old
+ state).
+
+ A CRTC (CRT controller) is a logical monitor, ie a portion
+ of the compositor coordinate space. It might correspond
+ to multiple monitors, when in clone mode, but not that
+ it is possible to implement clone mode also by setting different
+ CRTCs to the same coordinates.
+
+ The number of CRTCs represent the maximum number of monitors
+ that can be set to expand and it is a HW constraint; if more
+ monitors are connected, then necessarily some will clone. This
+ is complementary to the concept of the encoder (not exposed in
+ the API), which groups outputs that necessarily will show the
+ same image (again a HW constraint).
+
+ A CRTC is represented by a DBus structure with the following
+ layout:
+ * u ID: the ID in the API of this CRTC
+ * x winsys_id: the low-level ID of this CRTC (which might
+ be a XID, a KMS handle or something entirely
+ different)
+ * i x, y, width, height: the geometry of this CRTC
+ (might be invalid if the CRTC is not in
+ use)
+ * i current_mode: the current mode of the CRTC, or -1 if this
+ CRTC is not used
+ Note: the size of the mode will always correspond
+ to the width and height of the CRTC
+ * u current_transform: the current transform (espressed according
+ to the wayland protocol)
+ * au transforms: all possible transforms
+ * a{sv} properties: other high-level properties that affect this
+ CRTC; they are not necessarily reflected in
+ the hardware.
+ No property is specified in this version of the API.
+ FIXME: gamma?
+
+ Note: all geometry information refers to the untransformed
+ display.
+
+ An output represents a physical screen, connected somewhere to
+ the computer. Floating connectors are not exposed in the API.
+ An output is a DBus struct with the following fields:
+ * u ID: the ID in the API
+ * x winsys_id: the low-level ID of this output (XID or KMS handle)
+ * i current_crtc: the CRTC that is currently driving this output,
+ or -1 if the output is disabled
+ * au possible_crtcs: all CRTCs that can control this output
+ * s name: the name of the connector to which the output is attached
+ (like VGA1 or HDMI)
+ * s vendor: the human readable name of the manufacturer
+ * s product: the human readable name of the display model
+ * s serial: the serial number of this particular hardward part
+ * i backlight: the backlight value as a percentage (-1 if not supported)
+ * au modes: valid modes for this output
+ * au clones: valid clones for this output, ie other outputs that
+ can be assigned the same CRTC as this one; if you
+ want to mirror two outputs that don't have each other
+ in the clone list, you must configure two different
+ CRTCs for the same geometry
+ * a{sv} properties: other high-level properties that affect this
+ output; they are not necessarily reflected in
+ the hardware.
+ Known properties:
+ - "primary" (b): whether this output is primary
+ or not
+ - "presentation" (b): whether this output is
+ for presentation only
+ Note: properties might be ignored if not consistenly
+ applied to all outputs in the same clone group. In
+ general, it's expected that presentation or primary
+ outputs will not be cloned.
+
+ A mode represents a set of parameters that are applied to
+ each output, such as resolution and refresh rate. It is a separate
+ object so that it can be referenced by CRTCs and outputs.
+ Multiple outputs in the same CRTCs must all have the same mode.
+ A mode is exposed as:
+ * u ID: the ID in the API
+ * x winsys_id: the low-level ID of this mode
+ * u width, height: the resolution
+ * d frequency: refresh rate
+
+ Output and modes are read-only objects (except for output properties),
+ they can change only in accordance to HW changes (such as hotplugging
+ a monitor), while CRTCs can be changed with ApplyConfiguration().
+
+ XXX: actually, if you insist enough, you can add new modes
+ through xrandr command line or the KMS API, overriding what the
+ kernel driver and the EDID say.
+ Usually, it only matters with old cards with broken drivers, or
+ old monitors with broken EDIDs, but it happens more often with
+ projectors (if for example the kernel driver doesn't add the
+ 640x480 - 800x600 - 1024x768 default modes). Probably something
+ that we need to handle in mutter anyway.
+ -->
+ <method name="GetResources">
+ <arg name="serial" direction="out" type="u" />
+ <arg name="crtcs" direction="out" type="a(uxiiiiiuaua{sv})" />
+ <arg name="outputs" direction="out" type="a(uxiaussssiauaua{sv})" />
+ <arg name="modes" direction="out" type="a(uxuud)" />
+ <arg name="max_screen_width" direction="out" type="i" />
+ <arg name="max_screen_height" direction="out" type="i" />
+ </method>
+
+ <!--
+ ApplyConfiguration:
+ @serial: configuration serial
+ @persistent: whether this configuration should be saved on disk
+ @crtcs: new data for CRTCs
+ @outputs: new data for outputs
+
+ Applies the requested configuration changes.
+
+ @serial must match the serial from the last GetResources() call,
+ or org.freedesktop.DBus.AccessDenied will be generated.
+ (XXX: a better error maybe?)
+
+ If @persistent is true, mutter will attempt to replicate this
+ configuration the next time this HW layout appears.
+ (XXX: or is this gnome-settings-daemon role?)
+
+ @crtcs represents the new logical configuration, as a list
+ of structures containing:
+ - u ID: the API ID from the corresponding GetResources() call
+ - i new_mode: the API ID of the new mode to configure the CRTC
+ with, or -1 if the CRTC should be disabled
+ - i x, y: the new coordinates of the top left corner
+ the geometry will be completed with the size information
+ from @new_mode
+ - u transform: the desired transform
+ - au outputs: the API ID of outputs that should be assigned to
+ this CRTC
+ - a{sv} properties: properties whose value should be changed
+
+ Note: CRTCs not referenced in the array will be disabled.
+
+ @outputs represent the output property changes as:
+ - u ID: the API ID of the output to change
+ - a{sv} properties: properties whose value should be changed
+
+ Note: both for CRTCs and outputs, properties not included in
+ the dictionary will not be changed.
+
+ Note: unrecognized properties will have no effect, but if the
+ configuration change succeeds the property will be reported
+ by the next GetResources() call, and if @persistent is true,
+ it will also be saved to disk.
+
+ If the configuration is invalid according to the previous
+ GetResources() call, for example because a CRTC references
+ an output it cannot drive, or not all outputs support the
+ chosen mode, the error org.freedesktop.DBus.InvalidArgs will
+ be generated.
+
+ If the configuration cannot be applied for any other reason
+ (eg. the screen size would exceed texture limits), the error
+ org.freedesktop.DBus.Error.LimitsExceeded will be generated.
+ -->
+ <method name="ApplyConfiguration">
+ <arg name="serial" direction="in" type="u" />
+ <arg name="persistent" direction="in" type="b" />
+ <arg name="crtcs" direction="in" type="a(uiiiuaua{sv})" />
+ <arg name="outputs" direction="in" type="a(ua{sv})" />
+ </method>
+
+ <!--
+ ChangeBacklight:
+ @serial: configuration serial
+ @output: the API id of the output
+ @value: the new backlight value
+
+ Changes the backlight of @output to @value, which is
+ expressed as a percentage and rounded to the HW limits.
+ -->
+ <method name="ChangeBacklight">
+ <arg name="serial" direction="in" type="u" />
+ <arg name="output" direction="in" type="u" />
+ <arg name="value" direction="in" type="i" />
+ </method>
+
+ <!--
+ PowerSaveMode:
+
+ Contains the current power saving mode for the screen, and
+ allows changing it.
+
+ Possible values:
+ - 0: on
+ - 1: standby
+ - 2: suspend
+ - 3: off
+ - -1: unknown (unsupported)
+
+ A client should not attempt to change the powersave mode
+ from -1 (unknown) to any other value, and viceversa.
+ Note that the actual effects of the different values
+ depend on the hardware and the kernel driver in use, and
+ it's perfectly possible that all values different than on
+ have the same effect.
+ Also, setting the PowerSaveMode to 3 (off) may or may
+ not have the same effect as disabling all outputs by
+ setting no CRTC on them with ApplyConfiguration(), and
+ may or may not cause a configuration change.
+
+ Also note that this property might become out of date
+ if changed through different means (for example using the
+ XRandR interface directly).
+ -->
+ <property name="PowerSaveMode" type="i" access="readwrite" />
+ </interface>
+</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]