[gnome-flashback] display-config: implement dbus method handling
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] display-config: implement dbus method handling
- Date: Fri, 27 Mar 2015 00:36:13 +0000 (UTC)
commit 6326bb3c476d85ca4b56f89a922e6c433b47fecd
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Mar 26 23:30:21 2015 +0200
display-config: implement dbus method handling
This implements all dbus methods that are needed to comunicate with
gnome-control-center. Code are based on mutter 3.16.0 release.
Right now FlashbackMonitorManager and FlashbackMonitorConfig does
nothing...
configure.ac | 4 +-
data/org.gnome.gnome-flashback.gschema.xml.in.in | 2 +-
gnome-flashback/libdisplay-config/Makefile.am | 22 +-
.../libdisplay-config/flashback-display-config.c | 882 ++++++++++++++++++--
.../libdisplay-config/flashback-display-config.h | 22 +-
.../libdisplay-config/flashback-monitor-config.c | 86 ++
.../libdisplay-config/flashback-monitor-config.h | 47 +
.../libdisplay-config/flashback-monitor-manager.c | 113 +++
.../libdisplay-config/flashback-monitor-manager.h | 282 +++++++
9 files changed, 1362 insertions(+), 98 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 78f5d32..481417f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,7 +30,7 @@ GLIB_GSETTINGS
GTK_REQUIRED=3.15.2
LIBGNOME_DESKTOP_REQUIRED=3.12.0
CANBERRA_REQUIRED=0.13
-GLIB_REQUIRED=2.39.91
+GLIB_REQUIRED=2.44.0
GSETTINGS_DESKTOP_SCHEMAS_REQUIRED=3.12.0
PKG_CHECK_MODULES(GNOME_FLASHBACK, gtk+-3.0 >= $GTK_REQUIRED dbus-glib-1)
@@ -49,7 +49,7 @@ PKG_CHECK_MODULES(DESKTOP_BACKGROUND, gtk+-3.0 >= $GTK_REQUIRED gnome-desktop-3.
AC_SUBST(DESKTOP_BACKGROUND_CFLAGS)
AC_SUBST(DESKTOP_BACKGROUND_LIBS)
-PKG_CHECK_MODULES(DISPLAY_CONFIG, gtk+-3.0 >= $GTK_REQUIRED)
+PKG_CHECK_MODULES(DISPLAY_CONFIG, gtk+-3.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gnome-desktop-3.0 >=
$LIBGNOME_DESKTOP_REQUIRED)
AC_SUBST(DISPLAY_CONFIG_CFLAGS)
AC_SUBST(DISPLAY_CONFIG_LIBS)
diff --git a/data/org.gnome.gnome-flashback.gschema.xml.in.in
b/data/org.gnome.gnome-flashback.gschema.xml.in.in
index a546760..d8b9318 100644
--- a/data/org.gnome.gnome-flashback.gschema.xml.in.in
+++ b/data/org.gnome.gnome-flashback.gschema.xml.in.in
@@ -11,7 +11,7 @@
<_description>If set to true, then GNOME Flashback application will be used to draw
desktop background.</_description>
</key>
<key name="display-config" type="b">
- <default>false</default>
+ <default>true</default>
<_summary>Display config</_summary>
<_description>If set to true, then GNOME Flashback application will be used to
provide display configuration.</_description>
</key>
diff --git a/gnome-flashback/libdisplay-config/Makefile.am b/gnome-flashback/libdisplay-config/Makefile.am
index 5c6b2ee..52b3f1a 100644
--- a/gnome-flashback/libdisplay-config/Makefile.am
+++ b/gnome-flashback/libdisplay-config/Makefile.am
@@ -7,25 +7,29 @@ AM_CPPFLAGS = \
-DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\"
libdisplay_config_la_SOURCES = \
- dbus-display-config.c \
- dbus-display-config.h \
+ meta-dbus-display-config.c \
+ meta-dbus-display-config.h \
flashback-display-config.c \
- flashback-display-config.h
+ flashback-display-config.h \
+ flashback-monitor-config.c \
+ flashback-monitor-config.h \
+ flashback-monitor-manager.c \
+ flashback-monitor-manager.h
libdisplay_config_la_LIBADD = \
$(DISPLAY_CONFIG_LIBS)
-dbus-display-config.h:
-dbus-display-config.c: org.gnome.Mutter.DisplayConfig.xml
+meta-dbus-display-config.h:
+meta-dbus-display-config.c: org.gnome.Mutter.DisplayConfig.xml
$(AM_V_GEN) gdbus-codegen \
--interface-prefix org.gnome.Mutter \
- --c-namespace DBus \
- --generate-c-code dbus-display-config \
+ --c-namespace MetaDBus \
+ --generate-c-code meta-dbus-display-config \
$(srcdir)/org.gnome.Mutter.DisplayConfig.xml
BUILT_SOURCES = \
- dbus-display-config.h \
- dbus-display-config.c
+ meta-dbus-display-config.h \
+ meta-dbus-display-config.c
EXTRA_DIST = \
org.gnome.Mutter.DisplayConfig.xml
diff --git a/gnome-flashback/libdisplay-config/flashback-display-config.c
b/gnome-flashback/libdisplay-config/flashback-display-config.c
index 3268eb7..2db195e 100644
--- a/gnome-flashback/libdisplay-config/flashback-display-config.c
+++ b/gnome-flashback/libdisplay-config/flashback-display-config.c
@@ -1,4 +1,11 @@
/*
+ * Copyright (C) 2001, 2002 Havoc Pennington
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Some ICCCM manager selection code derived from fvwm2,
+ * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ * Copyright (C) 2013 Red Hat Inc.
* Copyright (C) 2014 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
@@ -13,30 +20,361 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter 3.16.0:
+ * - /src/backends/meta-monitor-manager.c
*/
+#include <config.h>
+#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include "config.h"
-#include "dbus-display-config.h"
+#include <math.h>
+#include "meta-dbus-display-config.h"
#include "flashback-display-config.h"
+#include "flashback-monitor-config.h"
+#include "flashback-monitor-manager.h"
-struct _FlashbackDisplayConfigPrivate {
- gint bus_name;
- GDBusInterfaceSkeleton *iface;
+struct _FlashbackDisplayConfig
+{
+ GObject parent;
+ gint bus_name;
+ GDBusInterfaceSkeleton *iface;
+ FlashbackMonitorManager *manager;
};
-G_DEFINE_TYPE (FlashbackDisplayConfig, flashback_display_config, G_TYPE_OBJECT);
+G_DEFINE_TYPE (FlashbackDisplayConfig, flashback_display_config, G_TYPE_OBJECT)
-static void
-handle_get_resources (DBusDisplayConfig *object,
+static const double known_diagonals[] = { 12.1, 13.3, 15.6 };
+
+static gboolean
+save_config_timeout (gpointer user_data)
+{
+ FlashbackMonitorManager *manager;
+
+ manager = FLASHBACK_MONITOR_MANAGER (user_data);
+
+ flashback_monitor_config_restore_previous (manager->config, manager);
+
+ manager->persistent_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+output_can_config (MetaOutput *output,
+ MetaCRTC *crtc,
+ MetaMonitorMode *mode)
+{
+ unsigned int i;
+ gboolean ok = FALSE;
+
+ for (i = 0; i < output->n_possible_crtcs && !ok; i++)
+ ok = output->possible_crtcs[i] == crtc;
+
+ if (!ok)
+ return FALSE;
+
+ if (mode == NULL)
+ return TRUE;
+
+ ok = FALSE;
+ for (i = 0; i < output->n_modes && !ok; i++)
+ ok = output->modes[i] == mode;
+
+ return ok;
+}
+
+static gboolean
+output_can_clone (MetaOutput *output,
+ MetaOutput *clone)
+{
+ unsigned int i;
+ gboolean ok = FALSE;
+
+ for (i = 0; i < output->n_possible_clones && !ok; i++)
+ ok = output->possible_clones[i] == clone;
+
+ return ok;
+}
+
+static char *
+diagonal_to_str (double d)
+{
+ unsigned int i;
+
+ for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++)
+ {
+ double delta;
+
+ delta = fabs(known_diagonals[i] - d);
+ if (delta < 0.1)
+ return g_strdup_printf ("%0.1lf\"", known_diagonals[i]);
+ }
+
+ return g_strdup_printf ("%d\"", (int) (d + 0.5));
+}
+
+static char *
+make_display_name (FlashbackMonitorManager *manager,
+ MetaOutput *output)
+{
+ char *inches = NULL;
+ char *vendor_name = NULL;
+ char *ret;
+
+ switch (output->connector_type)
+ {
+ case META_CONNECTOR_TYPE_LVDS:
+ case META_CONNECTOR_TYPE_eDP:
+ ret = g_strdup (_("Built-in display"));
+ goto out;
+ default:
+ break;
+ }
+
+ if (output->width_mm > 0 && output->height_mm > 0)
+ {
+ double d = sqrt (output->width_mm * output->width_mm +
+ output->height_mm * output->height_mm);
+ inches = diagonal_to_str (d / 25.4);
+ }
+
+ if (g_strcmp0 (output->vendor, "unknown") != 0)
+ {
+ if (!manager->pnp_ids)
+ manager->pnp_ids = gnome_pnp_ids_new ();
+
+ vendor_name = gnome_pnp_ids_get_pnp_id (manager->pnp_ids,
+ output->vendor);
+
+ if (!vendor_name)
+ vendor_name = g_strdup (output->vendor);
+ }
+ else
+ {
+ if (inches != NULL)
+ vendor_name = g_strdup (_("Unknown"));
+ else
+ vendor_name = g_strdup (_("Unknown Display"));
+ }
+
+ if (inches != NULL)
+ {
+ /* TRANSLATORS: this is a monitor vendor name, followed by a
+ * size in inches, like 'Dell 15"'
+ */
+ ret = g_strdup_printf (_("%s %s"), vendor_name, inches);
+ }
+ else
+ {
+ ret = g_strdup (vendor_name);
+ }
+
+ out:
+ g_free (inches);
+ g_free (vendor_name);
+
+ return ret;
+}
+
+static const char *
+get_connector_type_name (MetaConnectorType connector_type)
+{
+ switch (connector_type)
+ {
+ case META_CONNECTOR_TYPE_Unknown:
+ return "Unknown";
+ case META_CONNECTOR_TYPE_VGA:
+ return "VGA";
+ case META_CONNECTOR_TYPE_DVII:
+ return "DVII";
+ case META_CONNECTOR_TYPE_DVID:
+ return "DVID";
+ case META_CONNECTOR_TYPE_DVIA:
+ return "DVIA";
+ case META_CONNECTOR_TYPE_Composite:
+ return "Composite";
+ case META_CONNECTOR_TYPE_SVIDEO:
+ return "SVIDEO";
+ case META_CONNECTOR_TYPE_LVDS:
+ return "LVDS";
+ case META_CONNECTOR_TYPE_Component:
+ return "Component";
+ case META_CONNECTOR_TYPE_9PinDIN:
+ return "9PinDIN";
+ case META_CONNECTOR_TYPE_DisplayPort:
+ return "DisplayPort";
+ case META_CONNECTOR_TYPE_HDMIA:
+ return "HDMIA";
+ case META_CONNECTOR_TYPE_HDMIB:
+ return "HDMIB";
+ case META_CONNECTOR_TYPE_TV:
+ return "TV";
+ case META_CONNECTOR_TYPE_eDP:
+ return "eDP";
+ case META_CONNECTOR_TYPE_VIRTUAL:
+ return "VIRTUAL";
+ case META_CONNECTOR_TYPE_DSI:
+ return "DSI";
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
+handle_get_resources (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
- g_warning ("GetResources is not implemented!");
+ FlashbackDisplayConfig *config;
+ FlashbackMonitorManager *manager;
+ GVariantBuilder crtc_builder;
+ GVariantBuilder output_builder;
+ GVariantBuilder mode_builder;
+ unsigned int i;
+ unsigned int j;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ manager = config->manager;
+
+ g_variant_builder_init (&crtc_builder, G_VARIANT_TYPE ("a(uxiiiiiuaua{sv})"));
+ g_variant_builder_init (&output_builder, G_VARIANT_TYPE ("a(uxiausauaua{sv})"));
+ g_variant_builder_init (&mode_builder, G_VARIANT_TYPE ("a(uxuud)"));
+
+ for (i = 0; i < manager->n_crtcs; i++)
+ {
+ MetaCRTC *crtc;
+ GVariantBuilder transforms;
+
+ crtc = &manager->crtcs[i];
+
+ g_variant_builder_init (&transforms, G_VARIANT_TYPE ("au"));
+ for (j = 0; j <= META_MONITOR_TRANSFORM_FLIPPED_270; j++)
+ if (crtc->all_transforms & (1 << j))
+ g_variant_builder_add (&transforms, "u", j);
+
+ g_variant_builder_add (&crtc_builder, "(uxiiiiiuaua{sv})",
+ i, /* ID */
+ (gint64) crtc->crtc_id,
+ (int) crtc->rect.x,
+ (int) crtc->rect.y,
+ (int) crtc->rect.width,
+ (int) crtc->rect.height,
+ (int) (crtc->current_mode ? crtc->current_mode - manager->modes : -1),
+ (guint32) crtc->transform,
+ &transforms,
+ NULL /* properties */);
+ }
+
+ for (i = 0; i < manager->n_outputs; i++)
+ {
+ MetaOutput *output;
+ GVariantBuilder crtcs;
+ GVariantBuilder modes;
+ GVariantBuilder clones;
+ GVariantBuilder properties;
+ GBytes *edid;
+ char *edid_file;
+
+ output = &manager->outputs[i];
+
+ g_variant_builder_init (&crtcs, G_VARIANT_TYPE ("au"));
+ for (j = 0; j < output->n_possible_crtcs; j++)
+ g_variant_builder_add (&crtcs, "u",
+ (unsigned)(output->possible_crtcs[j] - manager->crtcs));
+
+ g_variant_builder_init (&modes, G_VARIANT_TYPE ("au"));
+ for (j = 0; j < output->n_modes; j++)
+ g_variant_builder_add (&modes, "u",
+ (unsigned)(output->modes[j] - manager->modes));
+
+ g_variant_builder_init (&clones, G_VARIANT_TYPE ("au"));
+ for (j = 0; j < output->n_possible_clones; j++)
+ g_variant_builder_add (&clones, "u",
+ (unsigned)(output->possible_clones[j] - manager->outputs));
+
+ g_variant_builder_init (&properties, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&properties, "{sv}", "vendor",
+ g_variant_new_string (output->vendor));
+ g_variant_builder_add (&properties, "{sv}", "product",
+ g_variant_new_string (output->product));
+ g_variant_builder_add (&properties, "{sv}", "serial",
+ g_variant_new_string (output->serial));
+ g_variant_builder_add (&properties, "{sv}", "width-mm",
+ g_variant_new_int32 (output->width_mm));
+ g_variant_builder_add (&properties, "{sv}", "height-mm",
+ g_variant_new_int32 (output->height_mm));
+ g_variant_builder_add (&properties, "{sv}", "display-name",
+ g_variant_new_take_string (make_display_name (manager, output)));
+ g_variant_builder_add (&properties, "{sv}", "backlight",
+ g_variant_new_int32 (output->backlight));
+ g_variant_builder_add (&properties, "{sv}", "min-backlight-step",
+ g_variant_new_int32 ((output->backlight_max - output->backlight_min) ?
+ 100 / (output->backlight_max - output->backlight_min) :
-1));
+ g_variant_builder_add (&properties, "{sv}", "primary",
+ g_variant_new_boolean (output->is_primary));
+ g_variant_builder_add (&properties, "{sv}", "presentation",
+ g_variant_new_boolean (output->is_presentation));
+ g_variant_builder_add (&properties, "{sv}", "connector-type",
+ g_variant_new_string (get_connector_type_name (output->connector_type)));
+
+ edid_file = flashback_monitor_manager_get_edid_file (manager, output);
+ if (edid_file)
+ {
+ g_variant_builder_add (&properties, "{sv}", "edid-file",
+ g_variant_new_take_string (edid_file));
+ }
+ else
+ {
+ edid = flashback_monitor_manager_read_edid (manager, output);
+
+ if (edid)
+ {
+ g_variant_builder_add (&properties, "{sv}", "edid",
+ g_variant_new_from_bytes (G_VARIANT_TYPE ("ay"),
+ edid, TRUE));
+ g_bytes_unref (edid);
+ }
+ }
+
+ g_variant_builder_add (&output_builder, "(uxiausauaua{sv})",
+ i, /* ID */
+ (gint64) output->winsys_id,
+ (int) (output->crtc ? output->crtc - manager->crtcs : -1),
+ &crtcs,
+ output->name,
+ &modes,
+ &clones,
+ &properties);
+ }
+
+ for (i = 0; i < manager->n_modes; i++)
+ {
+ MetaMonitorMode *mode;
+
+ mode = &manager->modes[i];
+
+ g_variant_builder_add (&mode_builder, "(uxuud)",
+ i, /* ID */
+ (gint64) mode->mode_id,
+ (guint32) mode->width,
+ (guint32) mode->height,
+ (double) mode->refresh_rate);
+ }
+
+ meta_dbus_display_config_complete_get_resources (skeleton,
+ invocation,
+ manager->serial,
+ g_variant_builder_end (&crtc_builder),
+ g_variant_builder_end (&output_builder),
+ g_variant_builder_end (&mode_builder),
+ manager->max_screen_width,
+ manager->max_screen_height);
+
+ return TRUE;
}
-static void
-handle_apply_configuration (DBusDisplayConfig *object,
+static gboolean
+handle_apply_configuration (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
guint serial,
gboolean persistent,
@@ -44,32 +382,376 @@ handle_apply_configuration (DBusDisplayConfig *object,
GVariant *outputs,
gpointer user_data)
{
- g_warning ("ApplyConfiguration is not implemented!");
+ FlashbackDisplayConfig *config;
+ FlashbackMonitorManager *manager;
+ GVariantIter crtc_iter;
+ GVariantIter output_iter;
+ GVariantIter *nested_outputs;
+ GVariant *properties;
+ guint crtc_id;
+ int new_mode;
+ int x;
+ int y;
+ int new_screen_width;
+ int new_screen_height;
+ guint transform;
+ guint output_index;
+ GPtrArray *crtc_infos;
+ GPtrArray *output_infos;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ manager = config->manager;
+
+ if (serial != manager->serial)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "The requested configuration is based on stale information");
+ return TRUE;
+ }
+
+ crtc_infos = g_ptr_array_new_full (g_variant_n_children (crtcs),
+ (GDestroyNotify) meta_crtc_info_free);
+ output_infos = g_ptr_array_new_full (g_variant_n_children (outputs),
+ (GDestroyNotify) meta_output_info_free);
+
+ /* Validate all arguments */
+ new_screen_width = 0; new_screen_height = 0;
+ g_variant_iter_init (&crtc_iter, crtcs);
+ while (g_variant_iter_loop (&crtc_iter, "(uiiiuaua{sv})",
+ &crtc_id, &new_mode, &x, &y, &transform,
+ &nested_outputs, NULL))
+ {
+ MetaCRTCInfo *crtc_info;
+ MetaOutput *first_output;
+ MetaCRTC *crtc;
+ MetaMonitorMode *mode;
+
+ crtc_info = g_slice_new (MetaCRTCInfo);
+ crtc_info->outputs = g_ptr_array_new ();
+
+ if (crtc_id >= manager->n_crtcs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid CRTC id");
+ return TRUE;
+ }
+
+ crtc = &manager->crtcs[crtc_id];
+ crtc_info->crtc = crtc;
+
+ if (new_mode != -1 && (new_mode < 0 || (unsigned) new_mode >= manager->n_modes))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid mode id");
+ return TRUE;
+ }
+
+ mode = new_mode != -1 ? &manager->modes[new_mode] : NULL;
+ crtc_info->mode = mode;
+
+ if (mode)
+ {
+ int width;
+ int height;
+
+ if (transform % 2)
+ {
+ width = mode->height;
+ height = mode->width;
+ }
+ else
+ {
+ width = mode->width;
+ height = mode->height;
+ }
+
+ if (x < 0 ||
+ x + width > manager->max_screen_width ||
+ y < 0 ||
+ y + height > manager->max_screen_height)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid CRTC geometry");
+ return TRUE;
+ }
+
+ new_screen_width = MAX (new_screen_width, x + width);
+ new_screen_height = MAX (new_screen_height, y + height);
+ crtc_info->x = x;
+ crtc_info->y = y;
+ }
+ else
+ {
+ crtc_info->x = 0;
+ crtc_info->y = 0;
+ }
+
+ if (transform < META_MONITOR_TRANSFORM_NORMAL ||
+ transform > META_MONITOR_TRANSFORM_FLIPPED_270 ||
+ ((crtc->all_transforms & (1 << transform)) == 0))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid transform");
+ return TRUE;
+ }
+
+ crtc_info->transform = transform;
+
+ first_output = NULL;
+ while (g_variant_iter_loop (nested_outputs, "u", &output_index))
+ {
+ MetaOutput *output;
+
+ if (output_index >= manager->n_outputs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid output id");
+ return TRUE;
+ }
+
+ output = &manager->outputs[output_index];
+
+ if (!output_can_config (output, crtc, mode))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Output cannot be assigned to this CRTC or mode");
+ return TRUE;
+ }
+
+ g_ptr_array_add (crtc_info->outputs, output);
+
+ if (first_output)
+ {
+ if (!output_can_clone (output, first_output))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Outputs cannot be cloned");
+ return TRUE;
+ }
+ }
+ else
+ first_output = output;
+ }
+
+ if (!first_output && mode)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Mode specified without outputs?");
+ return TRUE;
+ }
+
+ g_ptr_array_add (crtc_infos, crtc_info);
+ }
+
+ if (new_screen_width == 0 || new_screen_height == 0)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Refusing to disable all outputs");
+ return TRUE;
+ }
+
+ g_variant_iter_init (&output_iter, outputs);
+ while (g_variant_iter_loop (&output_iter, "(u a{sv})", &output_index, &properties))
+ {
+ MetaOutputInfo *output_info;
+ gboolean primary;
+ gboolean presentation;
+
+ if (output_index >= manager->n_outputs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid output id");
+ return TRUE;
+ }
+
+ output_info = g_slice_new0 (MetaOutputInfo);
+ output_info->output = &manager->outputs[output_index];
+
+ if (g_variant_lookup (properties, "primary", "b", &primary))
+ output_info->is_primary = primary;
+
+ if (g_variant_lookup (properties, "presentation", "b", &presentation))
+ output_info->is_presentation = presentation;
+
+ g_ptr_array_add (output_infos, output_info);
+ }
+
+ /* If we were in progress of making a persistent change and we see a
+ new request, it's likely that the old one failed in some way, so
+ don't save it, but also don't queue for restoring it.
+ */
+ if (manager->persistent_timeout_id && persistent)
+ {
+ g_source_remove (manager->persistent_timeout_id);
+ manager->persistent_timeout_id = 0;
+ }
+
+ flashback_monitor_manager_apply_configuration (manager,
+ (MetaCRTCInfo **) crtc_infos->pdata,
+ crtc_infos->len,
+ (MetaOutputInfo **) output_infos->pdata,
+ output_infos->len);
+
+ g_ptr_array_unref (crtc_infos);
+ g_ptr_array_unref (output_infos);
+
+ /* Update MetaMonitorConfig data structures immediately so that we
+ don't revert the change at the next XRandR event, then ask the plugin
+ manager (through MetaScreen) to confirm the display change with the
+ appropriate UI. Then wait 20 seconds and if not confirmed, revert the
+ configuration.
+ */
+ flashback_monitor_config_update_current (manager->config, manager);
+
+ if (persistent)
+ {
+ manager->persistent_timeout_id = g_timeout_add_seconds (20, save_config_timeout, manager);
+ g_source_set_name_by_id (manager->persistent_timeout_id, "[gnome-flashback] save_config_timeout");
+ }
+
+ meta_dbus_display_config_complete_apply_configuration (skeleton,
+ invocation);
+
+ return TRUE;
}
-static void
-handle_change_backlight (DBusDisplayConfig *object,
+static gboolean
+handle_change_backlight (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
guint serial,
guint output_index,
gint value,
gpointer user_data)
{
- g_warning ("ChangeBacklight is not implemented!");
+ FlashbackDisplayConfig *config;
+ FlashbackMonitorManager *manager;
+ MetaOutput *output;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ manager = config->manager;
+
+ if (serial != manager->serial)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "The requested configuration is based on stale information");
+ return TRUE;
+ }
+
+ if (output_index >= manager->n_outputs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid output id");
+ return TRUE;
+ }
+
+ output = &manager->outputs[output_index];
+
+ if (value < 0 || value > 100)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid backlight value");
+ return TRUE;
+ }
+
+ if (output->backlight == -1 ||
+ (output->backlight_min == 0 && output->backlight_max == 0))
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Output does not support changing backlight");
+ return TRUE;
+ }
+
+ flashback_monitor_manager_change_backlight (manager, output, value);
+
+ meta_dbus_display_config_complete_change_backlight (skeleton,
+ invocation,
+ output->backlight);
+
+ return TRUE;
}
-static void
-handle_get_crtc_gamma (DBusDisplayConfig *object,
+static gboolean
+handle_get_crtc_gamma (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
guint serial,
guint crtc_id,
gpointer user_data)
{
- g_warning ("GetCrtcGamma is not implemented!");
+ FlashbackDisplayConfig *config;
+ FlashbackMonitorManager *manager;
+ MetaCRTC *crtc;
+ gsize size;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+ GBytes *red_bytes;
+ GBytes *green_bytes;
+ GBytes *blue_bytes;
+ GVariant *red_v;
+ GVariant *green_v;
+ GVariant *blue_v;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ manager = config->manager;
+
+ if (serial != manager->serial)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "The requested configuration is based on stale information");
+ return TRUE;
+ }
+
+ if (crtc_id >= manager->n_crtcs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid crtc id");
+ return TRUE;
+ }
+
+ crtc = &manager->crtcs[crtc_id];
+
+ flashback_monitor_manager_get_crtc_gamma (manager, crtc, &size, &red, &green, &blue);
+
+ red_bytes = g_bytes_new_take (red, size * sizeof (unsigned short));
+ green_bytes = g_bytes_new_take (green, size * sizeof (unsigned short));
+ blue_bytes = g_bytes_new_take (blue, size * sizeof (unsigned short));
+
+ red_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), red_bytes, TRUE);
+ green_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), green_bytes, TRUE);
+ blue_v = g_variant_new_from_bytes (G_VARIANT_TYPE ("aq"), blue_bytes, TRUE);
+
+ g_bytes_unref (red_bytes);
+ g_bytes_unref (green_bytes);
+ g_bytes_unref (blue_bytes);
+
+ meta_dbus_display_config_complete_get_crtc_gamma (skeleton,
+ invocation,
+ red_v,
+ green_v,
+ blue_v);
+
+ return TRUE;
}
-static void
-handle_set_crtc_gamma (DBusDisplayConfig *object,
+static gboolean
+handle_set_crtc_gamma (MetaDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
guint serial,
guint crtc_id,
@@ -78,7 +760,58 @@ handle_set_crtc_gamma (DBusDisplayConfig *object,
GVariant *blue_v,
gpointer user_data)
{
- g_warning ("SetCrtcGamma is not implemented!");
+ FlashbackDisplayConfig *config;
+ FlashbackMonitorManager *manager;
+ MetaCRTC *crtc;
+ gsize size;
+ gsize dummy;
+ unsigned short *red;
+ unsigned short *green;
+ unsigned short *blue;
+ GBytes *red_bytes;
+ GBytes *green_bytes;
+ GBytes *blue_bytes;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ manager = config->manager;
+
+ if (serial != manager->serial)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_ACCESS_DENIED,
+ "The requested configuration is based on stale information");
+ return TRUE;
+ }
+
+ if (crtc_id >= manager->n_crtcs)
+ {
+ g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+ G_DBUS_ERROR_INVALID_ARGS,
+ "Invalid crtc id");
+ return TRUE;
+ }
+
+ crtc = &manager->crtcs[crtc_id];
+
+ red_bytes = g_variant_get_data_as_bytes (red_v);
+ green_bytes = g_variant_get_data_as_bytes (green_v);
+ blue_bytes = g_variant_get_data_as_bytes (blue_v);
+
+ size = g_bytes_get_size (red_bytes) / sizeof (unsigned short);
+ red = (unsigned short*) g_bytes_get_data (red_bytes, &dummy);
+ green = (unsigned short*) g_bytes_get_data (green_bytes, &dummy);
+ blue = (unsigned short*) g_bytes_get_data (blue_bytes, &dummy);
+
+ flashback_monitor_manager_set_crtc_gamma (manager, crtc, size, red, green, blue);
+
+ g_bytes_unref (red_bytes);
+ g_bytes_unref (green_bytes);
+ g_bytes_unref (blue_bytes);
+
+ meta_dbus_display_config_complete_set_crtc_gamma (skeleton,
+ invocation);
+
+ return TRUE;
}
static void
@@ -86,25 +819,35 @@ on_bus_acquired (GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
- FlashbackDisplayConfig *config = FLASHBACK_DISPLAY_CONFIG (user_data);
- GError *error = NULL;
+ FlashbackDisplayConfig *config;
+ MetaDBusDisplayConfig *skeleton;
+ GError *error;
+
+ config = FLASHBACK_DISPLAY_CONFIG (user_data);
+ skeleton = meta_dbus_display_config_skeleton_new ();
- config->priv->iface = G_DBUS_INTERFACE_SKELETON (dbus_display_config_skeleton_new ());
+ g_signal_connect (skeleton, "handle-get-resources",
+ G_CALLBACK (handle_get_resources), config);
+ g_signal_connect (skeleton, "handle-apply-configuration",
+ G_CALLBACK (handle_apply_configuration), config);
+ g_signal_connect (skeleton, "handle-change-backlight",
+ G_CALLBACK (handle_change_backlight), config);
+ g_signal_connect (skeleton, "handle-get-crtc-gamma",
+ G_CALLBACK (handle_get_crtc_gamma), config);
+ g_signal_connect (skeleton, "handle-set-crtc-gamma",
+ G_CALLBACK (handle_set_crtc_gamma), config);
- g_signal_connect (config->priv->iface, "handle-get-resources", G_CALLBACK (handle_get_resources),
config);
- g_signal_connect (config->priv->iface, "handle-apply-configuration", G_CALLBACK
(handle_apply_configuration), config);
- g_signal_connect (config->priv->iface, "handle-change-backlight", G_CALLBACK
(handle_change_backlight), config);
- g_signal_connect (config->priv->iface, "handle-get-crtc-gamma", G_CALLBACK (handle_get_crtc_gamma),
config);
- g_signal_connect (config->priv->iface, "handle-set-crtc-gamma", G_CALLBACK (handle_set_crtc_gamma),
config);
+ config->iface = G_DBUS_INTERFACE_SKELETON (skeleton);
+ error = NULL;
- if (!g_dbus_interface_skeleton_export (config->priv->iface,
- connection,
- "/org/gnome/Mutter/DisplayConfig",
- &error)) {
- g_warning ("Failed to export interface: %s", error->message);
- g_error_free (error);
- return;
- }
+ if (!g_dbus_interface_skeleton_export (config->iface, connection,
+ "/org/gnome/Mutter/DisplayConfig",
+ &error))
+ {
+ g_warning ("Failed to export interface: %s", error->message);
+ g_error_free (error);
+ return;
+ }
}
static void
@@ -124,54 +867,55 @@ on_name_lost (GDBusConnection *connection,
static void
flashback_display_config_finalize (GObject *object)
{
- FlashbackDisplayConfig *config = FLASHBACK_DISPLAY_CONFIG (object);
+ FlashbackDisplayConfig *config;
- if (config->priv->iface) {
- g_dbus_interface_skeleton_unexport (config->priv->iface);
+ config = FLASHBACK_DISPLAY_CONFIG (object);
- g_object_unref (config->priv->iface);
- config->priv->iface = NULL;
- }
+ if (config->iface)
+ {
+ g_dbus_interface_skeleton_unexport (config->iface);
+ g_clear_object (&config->iface);
+ }
- if (config->priv->bus_name) {
- g_bus_unown_name (config->priv->bus_name);
- config->priv->bus_name = 0;
- }
+ if (config->bus_name)
+ {
+ g_bus_unown_name (config->bus_name);
+ config->bus_name = 0;
+ }
- G_OBJECT_CLASS (flashback_display_config_parent_class)->finalize (object);
+ g_clear_object (&config->manager);
+
+ G_OBJECT_CLASS (flashback_display_config_parent_class)->finalize (object);
}
static void
-flashback_display_config_init (FlashbackDisplayConfig *config)
+flashback_display_config_class_init (FlashbackDisplayConfigClass *config_class)
{
- config->priv = G_TYPE_INSTANCE_GET_PRIVATE (config,
- FLASHBACK_TYPE_DISPLAY_CONFIG,
- FlashbackDisplayConfigPrivate);
+ GObjectClass *object_class;
- config->priv->bus_name = g_bus_own_name (G_BUS_TYPE_SESSION,
- "org.gnome.Mutter.DisplayConfig",
- G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
- G_BUS_NAME_OWNER_FLAGS_REPLACE,
- on_bus_acquired,
- on_name_acquired,
- on_name_lost,
- config,
- NULL);
+ object_class = G_OBJECT_CLASS (config_class);
+
+ object_class->finalize = flashback_display_config_finalize;
}
static void
-flashback_display_config_class_init (FlashbackDisplayConfigClass *class)
+flashback_display_config_init (FlashbackDisplayConfig *config)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- object_class->finalize = flashback_display_config_finalize;
-
- g_type_class_add_private (class, sizeof (FlashbackDisplayConfigPrivate));
+ config->manager = flashback_monitor_manager_new ();
+ config->bus_name = g_bus_own_name (G_BUS_TYPE_SESSION,
+ "org.gnome.Mutter.DisplayConfig",
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ config,
+ NULL);
}
FlashbackDisplayConfig *
flashback_display_config_new (void)
{
- return g_object_new (FLASHBACK_TYPE_DISPLAY_CONFIG,
- NULL);
+ return g_object_new (FLASHBACK_TYPE_DISPLAY_CONFIG,
+ NULL);
}
diff --git a/gnome-flashback/libdisplay-config/flashback-display-config.h
b/gnome-flashback/libdisplay-config/flashback-display-config.h
index 2fa261d..28f25a1 100644
--- a/gnome-flashback/libdisplay-config/flashback-display-config.h
+++ b/gnome-flashback/libdisplay-config/flashback-display-config.h
@@ -22,24 +22,12 @@
G_BEGIN_DECLS
-#define FLASHBACK_TYPE_DISPLAY_CONFIG (flashback_display_config_get_type ())
-#define FLASHBACK_DISPLAY_CONFIG(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), FLASHBACK_TYPE_DISPLAY_CONFIG,
FlashbackDisplayConfig))
+#define FLASHBACK_TYPE_DISPLAY_CONFIG flashback_display_config_get_type ()
+G_DECLARE_FINAL_TYPE (FlashbackDisplayConfig, flashback_display_config,
+ FLASHBACK, DISPLAY_CONFIG,
+ GObject)
-typedef struct _FlashbackDisplayConfig FlashbackDisplayConfig;
-typedef struct _FlashbackDisplayConfigClass FlashbackDisplayConfigClass;
-typedef struct _FlashbackDisplayConfigPrivate FlashbackDisplayConfigPrivate;
-
-struct _FlashbackDisplayConfig {
- GObject parent;
- FlashbackDisplayConfigPrivate *priv;
-};
-
-struct _FlashbackDisplayConfigClass {
- GObjectClass parent_class;
-};
-
-GType flashback_display_config_get_type (void);
-FlashbackDisplayConfig *flashback_display_config_new (void);
+FlashbackDisplayConfig *flashback_display_config_new (void);
G_END_DECLS
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-config.c
b/gnome-flashback/libdisplay-config/flashback-monitor-config.c
new file mode 100644
index 0000000..dde6f0d
--- /dev/null
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-config.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter 3.16.0:
+ * - /src/backends/meta-monitor-config.c
+ */
+
+#include <config.h>
+#include "flashback-monitor-config.h"
+
+struct _FlashbackMonitorConfig
+{
+ GObject parent;
+};
+
+G_DEFINE_TYPE (FlashbackMonitorConfig, flashback_monitor_config, G_TYPE_OBJECT)
+
+static void
+flashback_monitor_config_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (flashback_monitor_config_parent_class)->finalize (object);
+}
+
+static void
+flashback_monitor_config_class_init (FlashbackMonitorConfigClass *config_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (config_class);
+
+ object_class->finalize = flashback_monitor_config_finalize;
+}
+
+static void
+flashback_monitor_config_init (FlashbackMonitorConfig *config)
+{
+}
+
+FlashbackMonitorConfig *
+flashback_monitor_config_new (void)
+{
+ return g_object_new (FLASHBACK_TYPE_MONITOR_CONFIG,
+ NULL);
+}
+
+void
+flashback_monitor_config_update_current (FlashbackMonitorConfig *config,
+ FlashbackMonitorManager *manager)
+{
+}
+
+void
+flashback_monitor_config_restore_previous (FlashbackMonitorConfig *config,
+ FlashbackMonitorManager *manager)
+{
+}
+
+void
+meta_crtc_info_free (MetaCRTCInfo *info)
+{
+ g_ptr_array_free (info->outputs, TRUE);
+ g_slice_free (MetaCRTCInfo, info);
+}
+
+void
+meta_output_info_free (MetaOutputInfo *info)
+{
+ g_slice_free (MetaOutputInfo, info);
+}
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-config.h
b/gnome-flashback/libdisplay-config/flashback-monitor-config.h
new file mode 100644
index 0000000..cf4d109
--- /dev/null
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-config.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter 3.16.0:
+ * - /src/backends/meta-monitor-config.h
+ */
+
+#ifndef FLASHBACK_MONITOR_CONFIG_H
+#define FLASHBACK_MONITOR_CONFIG_H
+
+#include "flashback-monitor-manager.h"
+
+G_BEGIN_DECLS
+
+#define FLASHBACK_TYPE_MONITOR_CONFIG flashback_monitor_config_get_type ()
+G_DECLARE_FINAL_TYPE (FlashbackMonitorConfig, flashback_monitor_config,
+ FLASHBACK, MONITOR_CONFIG,
+ GObject)
+
+FlashbackMonitorConfig *flashback_monitor_config_new (void);
+
+void flashback_monitor_config_update_current (FlashbackMonitorConfig *config,
+ FlashbackMonitorManager *manager);
+
+void flashback_monitor_config_restore_previous (FlashbackMonitorConfig *config,
+ FlashbackMonitorManager *manager);
+
+G_END_DECLS
+
+#endif
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
new file mode 100644
index 0000000..6e35307
--- /dev/null
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2001, 2002 Havoc Pennington
+ * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Some ICCCM manager selection code derived from fvwm2,
+ * Copyright (C) 2001 Dominik Vogt, Matthias Clasen, and fvwm2 team
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter 3.16.0:
+ * - /src/backends/meta-monitor-manager.c
+ */
+
+#include <config.h>
+#include "flashback-monitor-manager.h"
+
+G_DEFINE_TYPE (FlashbackMonitorManager, flashback_monitor_manager, G_TYPE_OBJECT)
+
+static void
+flashback_monitor_manager_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (flashback_monitor_manager_parent_class)->finalize (object);
+}
+
+static void
+flashback_monitor_manager_class_init (FlashbackMonitorManagerClass *manager_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (manager_class);
+
+ object_class->finalize = flashback_monitor_manager_finalize;
+}
+
+static void
+flashback_monitor_manager_init (FlashbackMonitorManager *manager)
+{
+}
+
+FlashbackMonitorManager *
+flashback_monitor_manager_new (void)
+{
+ return g_object_new (FLASHBACK_TYPE_MONITOR_MANAGER,
+ NULL);
+}
+
+void
+flashback_monitor_manager_apply_configuration (FlashbackMonitorManager *manager,
+ MetaCRTCInfo **crtcs,
+ unsigned int n_crtcs,
+ MetaOutputInfo **outputs,
+ unsigned int n_outputs)
+{
+}
+
+void
+flashback_monitor_manager_change_backlight (FlashbackMonitorManager *manager,
+ MetaOutput *output,
+ gint value)
+{
+}
+
+void
+flashback_monitor_manager_get_crtc_gamma (FlashbackMonitorManager *manager,
+ MetaCRTC *crtc,
+ gsize *size,
+ unsigned short **red,
+ unsigned short **green,
+ unsigned short **blue)
+{
+ *size = 0;
+ *red = NULL;
+ *green = NULL;
+ *blue = NULL;
+}
+
+void
+flashback_monitor_manager_set_crtc_gamma (FlashbackMonitorManager *manager,
+ MetaCRTC *crtc,
+ gsize size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue)
+{
+}
+
+char *
+flashback_monitor_manager_get_edid_file (FlashbackMonitorManager *manager,
+ MetaOutput *output)
+{
+ return NULL;
+}
+
+GBytes *
+flashback_monitor_manager_read_edid (FlashbackMonitorManager *manager,
+ MetaOutput *output)
+{
+ return NULL;
+}
diff --git a/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
new file mode 100644
index 0000000..30f12c0
--- /dev/null
+++ b/gnome-flashback/libdisplay-config/flashback-monitor-manager.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2003 Rob Adams
+ * Copyright (C) 2004-2006 Elijah Newren
+ * Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2015 Alberts Muktupāvels
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Adapted from mutter 3.16.0:
+ * - /src/backends/meta-monitor-manager-private.h
+ */
+
+#ifndef FLASHBACK_MONITOR_MANAGER_H
+#define FLASHBACK_MONITOR_MANAGER_H
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+#include <libgnome-desktop/gnome-pnp-ids.h>
+
+G_BEGIN_DECLS
+
+typedef struct _FlashbackMonitorConfig FlashbackMonitorConfig;
+
+typedef struct _MetaCRTC MetaCRTC;
+typedef struct _MetaOutput MetaOutput;
+typedef struct _MetaMonitorMode MetaMonitorMode;
+typedef struct _MetaMonitorInfo MetaMonitorInfo;
+typedef struct _MetaCRTCInfo MetaCRTCInfo;
+typedef struct _MetaOutputInfo MetaOutputInfo;
+
+typedef enum {
+ META_MONITOR_TRANSFORM_NORMAL,
+ META_MONITOR_TRANSFORM_90,
+ META_MONITOR_TRANSFORM_180,
+ META_MONITOR_TRANSFORM_270,
+ META_MONITOR_TRANSFORM_FLIPPED,
+ META_MONITOR_TRANSFORM_FLIPPED_90,
+ META_MONITOR_TRANSFORM_FLIPPED_180,
+ META_MONITOR_TRANSFORM_FLIPPED_270,
+} MetaMonitorTransform;
+
+/* This matches the values in drm_mode.h */
+typedef enum {
+ META_CONNECTOR_TYPE_Unknown = 0,
+ META_CONNECTOR_TYPE_VGA = 1,
+ META_CONNECTOR_TYPE_DVII = 2,
+ META_CONNECTOR_TYPE_DVID = 3,
+ META_CONNECTOR_TYPE_DVIA = 4,
+ META_CONNECTOR_TYPE_Composite = 5,
+ META_CONNECTOR_TYPE_SVIDEO = 6,
+ META_CONNECTOR_TYPE_LVDS = 7,
+ META_CONNECTOR_TYPE_Component = 8,
+ META_CONNECTOR_TYPE_9PinDIN = 9,
+ META_CONNECTOR_TYPE_DisplayPort = 10,
+ META_CONNECTOR_TYPE_HDMIA = 11,
+ META_CONNECTOR_TYPE_HDMIB = 12,
+ META_CONNECTOR_TYPE_TV = 13,
+ META_CONNECTOR_TYPE_eDP = 14,
+ META_CONNECTOR_TYPE_VIRTUAL = 15,
+ META_CONNECTOR_TYPE_DSI = 16,
+} MetaConnectorType;
+
+struct _MetaOutput
+{
+ /* The CRTC driving this output, NULL if the output is not enabled */
+ MetaCRTC *crtc;
+ /* The low-level ID of this output, used to apply back configuration */
+ glong winsys_id;
+ char *name;
+ char *vendor;
+ char *product;
+ char *serial;
+ int width_mm;
+ int height_mm;
+ int scale;
+
+ MetaConnectorType connector_type;
+
+ MetaMonitorMode *preferred_mode;
+ MetaMonitorMode **modes;
+ unsigned int n_modes;
+
+ MetaCRTC **possible_crtcs;
+ unsigned int n_possible_crtcs;
+
+ MetaOutput **possible_clones;
+ unsigned int n_possible_clones;
+
+ int backlight;
+ int backlight_min;
+ int backlight_max;
+
+ /* Used when changing configuration */
+ gboolean is_dirty;
+
+ /* The low-level bits used to build the high-level info
+ in MetaMonitorInfo
+ */
+ gboolean is_primary;
+ gboolean is_presentation;
+
+ gpointer driver_private;
+ GDestroyNotify driver_notify;
+
+ /* get a new preferred mode on hotplug events, to handle dynamic guest resizing */
+ gboolean hotplug_mode_update;
+ gint suggested_x;
+ gint suggested_y;
+};
+
+struct _MetaCRTC
+{
+ glong crtc_id;
+ GdkRectangle rect;
+ MetaMonitorMode *current_mode;
+ MetaMonitorTransform transform;
+ unsigned int all_transforms;
+
+ /* Only used to build the logical configuration
+ from the HW one
+ */
+ MetaMonitorInfo *logical_monitor;
+
+ /* Used when changing configuration */
+ gboolean is_dirty;
+};
+
+struct _MetaMonitorMode
+{
+ /* The low-level ID of this mode, used to apply back configuration */
+ glong mode_id;
+ char *name;
+
+ int width;
+ int height;
+ float refresh_rate;
+
+ gpointer driver_private;
+ GDestroyNotify driver_notify;
+};
+
+/**
+ * MetaMonitorInfo:
+ *
+ * A structure with high-level information about monitors.
+ * This corresponds to a subset of the compositor coordinate space.
+ * Clones are only reported once, irrespective of the way
+ * they're implemented (two CRTCs configured for the same
+ * coordinates or one CRTCs driving two outputs). Inactive CRTCs
+ * are ignored, and so are disabled outputs.
+ */
+struct _MetaMonitorInfo
+{
+ int number;
+ int xinerama_index;
+ GdkRectangle rect;
+ gboolean is_primary;
+ gboolean is_presentation; /* XXX: not yet used */
+ gboolean in_fullscreen;
+
+ /* The primary or first output for this monitor, 0 if we can't figure out.
+ It can be matched to a winsys_id of a MetaOutput.
+
+ This is used as an opaque token on reconfiguration when switching from
+ clone to extened, to decide on what output the windows should go next
+ (it's an attempt to keep windows on the same monitor, and preferably on
+ the primary one).
+ */
+ glong winsys_id;
+};
+
+/*
+ * MetaCRTCInfo:
+ * This represents the writable part of a CRTC, as deserialized from DBus
+ * or built by MetaMonitorConfig
+ *
+ * Note: differently from the other structures in this file, MetaCRTCInfo
+ * is handled by pointer. This is to accomodate the usage in MetaMonitorConfig
+ */
+struct _MetaCRTCInfo
+{
+ MetaCRTC *crtc;
+ MetaMonitorMode *mode;
+ int x;
+ int y;
+ MetaMonitorTransform transform;
+ GPtrArray *outputs;
+};
+
+/*
+ * MetaOutputInfo:
+ * this is the same as MetaCRTCInfo, but for outputs
+ */
+struct _MetaOutputInfo
+{
+ MetaOutput *output;
+ gboolean is_primary;
+ gboolean is_presentation;
+};
+
+#define FLASHBACK_TYPE_MONITOR_MANAGER flashback_monitor_manager_get_type ()
+G_DECLARE_FINAL_TYPE (FlashbackMonitorManager, flashback_monitor_manager,
+ FLASHBACK, MONITOR_MANAGER,
+ GObject)
+
+struct _FlashbackMonitorManager
+{
+ GObject parnet;
+
+ unsigned int serial;
+
+ int max_screen_width;
+ int max_screen_height;
+
+ /* Outputs refer to physical screens,
+ CRTCs refer to stuff that can drive outputs
+ (like encoders, but less tied to the HW),
+ while monitor_infos refer to logical ones.
+ */
+ MetaOutput *outputs;
+ unsigned int n_outputs;
+
+ MetaMonitorMode *modes;
+ unsigned int n_modes;
+
+ MetaCRTC *crtcs;
+ unsigned int n_crtcs;
+
+ GnomePnpIds *pnp_ids;
+
+ int persistent_timeout_id;
+ FlashbackMonitorConfig *config;
+};
+
+FlashbackMonitorManager *flashback_monitor_manager_new (void);
+
+void flashback_monitor_manager_apply_configuration (FlashbackMonitorManager *manager,
+ MetaCRTCInfo **crtcs,
+ unsigned int n_crtcs,
+ MetaOutputInfo **outputs,
+ unsigned int n_outputs);
+
+void flashback_monitor_manager_change_backlight (FlashbackMonitorManager *manager,
+ MetaOutput *output,
+ gint value);
+
+void flashback_monitor_manager_get_crtc_gamma (FlashbackMonitorManager *manager,
+ MetaCRTC *crtc,
+ gsize *size,
+ unsigned short **red,
+ unsigned short **green,
+ unsigned short **blue);
+void flashback_monitor_manager_set_crtc_gamma (FlashbackMonitorManager *manager,
+ MetaCRTC *crtc,
+ gsize size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue);
+
+char *flashback_monitor_manager_get_edid_file (FlashbackMonitorManager *manager,
+ MetaOutput *output);
+GBytes *flashback_monitor_manager_read_edid (FlashbackMonitorManager *manager,
+ MetaOutput *output);
+
+void meta_crtc_info_free (MetaCRTCInfo *info);
+void meta_output_info_free (MetaOutputInfo *info);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]