[gnome-flashback] monitor-manager: implement GetCurrentState
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] monitor-manager: implement GetCurrentState
- Date: Thu, 21 Sep 2017 00:08:59 +0000 (UTC)
commit 42239fdd2389982677e3195092c5c1120575e3e2
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Thu Sep 21 01:19:46 2017 +0300
monitor-manager: implement GetCurrentState
backends/gf-monitor-manager-private.h | 4 +
backends/gf-monitor-manager.c | 385 ++++++++++++++++++++++++++++++++-
po/POTFILES.in | 1 +
3 files changed, 387 insertions(+), 3 deletions(-)
---
diff --git a/backends/gf-monitor-manager-private.h b/backends/gf-monitor-manager-private.h
index 69a5b04..a53972c 100644
--- a/backends/gf-monitor-manager-private.h
+++ b/backends/gf-monitor-manager-private.h
@@ -210,6 +210,10 @@ gboolean gf_monitor_manager_is_scale_supported (GfM
GfMonitorManagerCapability gf_monitor_manager_get_capabilities (GfMonitorManager
*manager);
+gboolean gf_monitor_manager_get_max_screen_size (GfMonitorManager
*manager,
+ gint
*max_width,
+ gint
*max_height);
+
GfLogicalMonitorLayoutMode gf_monitor_manager_get_default_layout_mode (GfMonitorManager
*manager);
GfMonitorConfigManager *gf_monitor_manager_get_config_manager (GfMonitorManager
*manager);
diff --git a/backends/gf-monitor-manager.c b/backends/gf-monitor-manager.c
index 1f8e18e..9428184 100644
--- a/backends/gf-monitor-manager.c
+++ b/backends/gf-monitor-manager.c
@@ -27,6 +27,8 @@
#include "config.h"
+#include <glib/gi18n-lib.h>
+#include <math.h>
#include <string.h>
#include "gf-crtc-private.h"
@@ -405,6 +407,93 @@ gf_monitor_manager_apply_monitors_config (GfMonitorManager *manager,
return TRUE;
}
+static const gdouble known_diagonals[] =
+ {
+ 12.1,
+ 13.3,
+ 15.6
+ };
+
+static gchar *
+diagonal_to_str (gdouble d)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (known_diagonals); i++)
+ {
+ gdouble 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 gchar *
+make_display_name (GfMonitorManager *manager,
+ GfOutput *output)
+{
+ gchar *inches;
+ gchar *vendor_name;
+
+ if (gf_output_is_laptop (output))
+ return g_strdup (_("Built-in display"));
+
+ inches = NULL;
+ vendor_name = NULL;
+
+ if (output->width_mm > 0 && output->height_mm > 0)
+ {
+ gint width_mm;
+ gint height_mm;
+ gdouble d;
+
+ width_mm = output->width_mm;
+ height_mm = output->height_mm;
+ d = sqrt (width_mm * width_mm + height_mm * 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)
+ {
+ gchar *display_name;
+
+ /* TRANSLATORS: this is a monitor vendor name, followed by a
+ * size in inches, like 'Dell 15"'
+ */
+ display_name = g_strdup_printf (_("%s %s"), vendor_name, inches);
+
+ g_free (vendor_name);
+ g_free (inches);
+
+ return display_name;
+ }
+
+ return vendor_name;
+}
+
static gboolean
is_main_tiled_monitor_output (GfOutput *output)
{
@@ -536,17 +625,240 @@ gf_monitor_manager_handle_set_crtc_gamma (GfDBusDisplayConfig *skeleton,
return TRUE;
}
+#define MODE_FORMAT "(siiddada{sv})"
+#define MODES_FORMAT "a" MODE_FORMAT
+#define MONITOR_SPEC_FORMAT "(ssss)"
+#define MONITOR_FORMAT "(" MONITOR_SPEC_FORMAT MODES_FORMAT "a{sv})"
+#define MONITORS_FORMAT "a" MONITOR_FORMAT
+
+#define LOGICAL_MONITOR_MONITORS_FORMAT "a" MONITOR_SPEC_FORMAT
+#define LOGICAL_MONITOR_FORMAT "(iidub" LOGICAL_MONITOR_MONITORS_FORMAT "a{sv})"
+#define LOGICAL_MONITORS_FORMAT "a" LOGICAL_MONITOR_FORMAT
+
static gboolean
gf_monitor_manager_handle_get_current_state (GfDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation)
{
- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
- G_DBUS_ERROR_FAILED,
- "Not implemented");
+ GfMonitorManager *manager;
+ GVariantBuilder monitors_builder;
+ GVariantBuilder logical_monitors_builder;
+ GVariantBuilder properties_builder;
+ GList *l;
+ GfMonitorManagerCapability capabilities;
+ gint max_screen_width;
+ gint max_screen_height;
+
+ manager = GF_MONITOR_MANAGER (skeleton);
+
+ g_variant_builder_init (&monitors_builder, G_VARIANT_TYPE (MONITORS_FORMAT));
+ g_variant_builder_init (&logical_monitors_builder, G_VARIANT_TYPE (LOGICAL_MONITORS_FORMAT));
+ g_variant_builder_init (&properties_builder, G_VARIANT_TYPE ("a{sv}"));
+
+ for (l = manager->monitors; l; l = l->next)
+ {
+ GfMonitor *monitor = l->data;
+ GfMonitorSpec *monitor_spec = gf_monitor_get_spec (monitor);
+ GfMonitorMode *current_mode;
+ GfMonitorMode *preferred_mode;
+ GVariantBuilder modes_builder;
+ GVariantBuilder monitor_properties_builder;
+ GList *k;
+ gboolean is_builtin;
+ GfOutput *main_output;
+ gchar *display_name;
+ gint i;
+
+ current_mode = gf_monitor_get_current_mode (monitor);
+ preferred_mode = gf_monitor_get_preferred_mode (monitor);
+
+ g_variant_builder_init (&modes_builder, G_VARIANT_TYPE (MODES_FORMAT));
+ for (k = gf_monitor_get_modes (monitor); k; k = k->next)
+ {
+ GfMonitorMode *monitor_mode = k->data;
+ GVariantBuilder supported_scales_builder;
+ const gchar *mode_id;
+ gint mode_width, mode_height;
+ gfloat refresh_rate;
+ gfloat preferred_scale;
+ gfloat *supported_scales;
+ gint n_supported_scales;
+ GVariantBuilder mode_properties_builder;
+ GfCrtcModeFlag mode_flags;
+
+ mode_id = gf_monitor_mode_get_id (monitor_mode);
+ gf_monitor_mode_get_resolution (monitor_mode,
+ &mode_width, &mode_height);
+ refresh_rate = gf_monitor_mode_get_refresh_rate (monitor_mode);
+
+ preferred_scale =
+ gf_monitor_manager_calculate_monitor_mode_scale (manager,
+ monitor,
+ monitor_mode);
+
+ g_variant_builder_init (&supported_scales_builder,
+ G_VARIANT_TYPE ("ad"));
+ supported_scales =
+ gf_monitor_manager_calculate_supported_scales (manager,
+ manager->layout_mode,
+ monitor,
+ monitor_mode,
+ &n_supported_scales);
+ for (i = 0; i < n_supported_scales; i++)
+ g_variant_builder_add (&supported_scales_builder, "d",
+ (gdouble) supported_scales[i]);
+ g_free (supported_scales);
+
+ mode_flags = gf_monitor_mode_get_flags (monitor_mode);
+
+ g_variant_builder_init (&mode_properties_builder,
+ G_VARIANT_TYPE ("a{sv}"));
+ if (monitor_mode == current_mode)
+ g_variant_builder_add (&mode_properties_builder, "{sv}",
+ "is-current",
+ g_variant_new_boolean (TRUE));
+ if (monitor_mode == preferred_mode)
+ g_variant_builder_add (&mode_properties_builder, "{sv}",
+ "is-preferred",
+ g_variant_new_boolean (TRUE));
+ if (mode_flags & GF_CRTC_MODE_FLAG_INTERLACE)
+ g_variant_builder_add (&mode_properties_builder, "{sv}",
+ "is-interlaced",
+ g_variant_new_boolean (TRUE));
+
+ g_variant_builder_add (&modes_builder, MODE_FORMAT,
+ mode_id,
+ mode_width,
+ mode_height,
+ refresh_rate,
+ (gdouble) preferred_scale,
+ &supported_scales_builder,
+ &mode_properties_builder);
+ }
+
+ g_variant_builder_init (&monitor_properties_builder,
+ G_VARIANT_TYPE ("a{sv}"));
+ if (gf_monitor_supports_underscanning (monitor))
+ {
+ gboolean is_underscanning = gf_monitor_is_underscanning (monitor);
+
+ g_variant_builder_add (&monitor_properties_builder, "{sv}",
+ "is-underscanning",
+ g_variant_new_boolean (is_underscanning));
+ }
+
+ is_builtin = gf_monitor_is_laptop_panel (monitor);
+ g_variant_builder_add (&monitor_properties_builder, "{sv}",
+ "is-builtin",
+ g_variant_new_boolean (is_builtin));
+
+ main_output = gf_monitor_get_main_output (monitor);
+ display_name = make_display_name (manager, main_output);
+ g_variant_builder_add (&monitor_properties_builder, "{sv}",
+ "display-name",
+ g_variant_new_take_string (display_name));
+
+ g_variant_builder_add (&monitors_builder, MONITOR_FORMAT,
+ monitor_spec->connector,
+ monitor_spec->vendor,
+ monitor_spec->product,
+ monitor_spec->serial,
+ &modes_builder,
+ &monitor_properties_builder);
+ }
+
+ for (l = manager->logical_monitors; l; l = l->next)
+ {
+ GfLogicalMonitor *logical_monitor = l->data;
+ GVariantBuilder logical_monitor_monitors_builder;
+ GList *k;
+
+ g_variant_builder_init (&logical_monitor_monitors_builder,
+ G_VARIANT_TYPE (LOGICAL_MONITOR_MONITORS_FORMAT));
+
+ for (k = logical_monitor->monitors; k; k = k->next)
+ {
+ GfMonitor *monitor = k->data;
+ GfMonitorSpec *monitor_spec = gf_monitor_get_spec (monitor);
+
+ g_variant_builder_add (&logical_monitor_monitors_builder,
+ MONITOR_SPEC_FORMAT,
+ monitor_spec->connector,
+ monitor_spec->vendor,
+ monitor_spec->product,
+ monitor_spec->serial);
+ }
+
+ g_variant_builder_add (&logical_monitors_builder,
+ LOGICAL_MONITOR_FORMAT,
+ logical_monitor->rect.x,
+ logical_monitor->rect.y,
+ (gdouble) logical_monitor->scale,
+ logical_monitor->transform,
+ logical_monitor->is_primary,
+ &logical_monitor_monitors_builder,
+ NULL);
+ }
+
+ capabilities = gf_monitor_manager_get_capabilities (manager);
+ if ((capabilities & GF_MONITOR_MANAGER_CAPABILITY_MIRRORING) == 0)
+ {
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "supports-mirroring",
+ g_variant_new_boolean (FALSE));
+ }
+
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "layout-mode",
+ g_variant_new_uint32 (manager->layout_mode));
+ if (capabilities & GF_MONITOR_MANAGER_CAPABILITY_LAYOUT_MODE)
+ {
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "supports-changing-layout-mode",
+ g_variant_new_boolean (TRUE));
+ }
+
+ if (capabilities & GF_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED)
+ {
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "global-scale-required",
+ g_variant_new_boolean (TRUE));
+ }
+
+ if (gf_monitor_manager_get_max_screen_size (manager,
+ &max_screen_width,
+ &max_screen_height))
+ {
+ GVariantBuilder max_screen_size_builder;
+
+ g_variant_builder_init (&max_screen_size_builder,
+ G_VARIANT_TYPE ("(ii)"));
+ g_variant_builder_add (&max_screen_size_builder, "i",
+ max_screen_width);
+ g_variant_builder_add (&max_screen_size_builder, "i",
+ max_screen_height);
+
+ g_variant_builder_add (&properties_builder, "{sv}",
+ "max-screen-size",
+ g_variant_builder_end (&max_screen_size_builder));
+ }
+
+ gf_dbus_display_config_complete_get_current_state (skeleton, invocation, manager->serial,
+ g_variant_builder_end (&monitors_builder),
+ g_variant_builder_end (&logical_monitors_builder),
+ g_variant_builder_end (&properties_builder));
return TRUE;
}
+#undef MODE_FORMAT
+#undef MODES_FORMAT
+#undef MONITOR_SPEC_FORMAT
+#undef MONITOR_FORMAT
+#undef MONITORS_FORMAT
+#undef LOGICAL_MONITOR_MONITORS_FORMAT
+#undef LOGICAL_MONITOR_FORMAT
+#undef LOGICAL_MONITORS_FORMAT
+
static gboolean
gf_monitor_manager_handle_apply_monitors_config (GfDBusDisplayConfig *skeleton,
GDBusMethodInvocation *invocation,
@@ -603,17 +915,65 @@ name_lost_cb (GDBusConnection *connection,
{
}
+static GBytes *
+gf_monitor_manager_real_read_edid (GfMonitorManager *manager,
+ GfOutput *output)
+{
+ return NULL;
+}
+
+static gchar *
+gf_monitor_manager_real_get_edid_file (GfMonitorManager *manager,
+ GfOutput *output)
+{
+ return NULL;
+}
+
+static gboolean
+gf_monitor_manager_real_is_lid_closed (GfMonitorManager *manager)
+{
+ if (!manager->up_client)
+ return FALSE;
+
+ return up_client_get_lid_is_closed (manager->up_client);
+}
+
+static void
+lid_is_closed_changed (UpClient *client,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ GfMonitorManager *manager = user_data;
+
+ gf_monitor_manager_ensure_configured (manager);
+}
+
static void
gf_monitor_manager_constructed (GObject *object)
{
GfMonitorManager *manager;
+ GfMonitorManagerClass *manager_class;
GfMonitorManagerPrivate *priv;
manager = GF_MONITOR_MANAGER (object);
+ manager_class = GF_MONITOR_MANAGER_GET_CLASS (manager);
priv = gf_monitor_manager_get_instance_private (manager);
G_OBJECT_CLASS (gf_monitor_manager_parent_class)->constructed (object);
+ if (manager_class->is_lid_closed == gf_monitor_manager_real_is_lid_closed)
+ {
+ manager->up_client = up_client_new ();
+
+ g_signal_connect_object (manager->up_client, "notify::lid-is-closed",
+ G_CALLBACK (lid_is_closed_changed), manager, 0);
+ }
+
+ manager->config_manager = gf_monitor_config_manager_new (manager);
+
+ gf_monitor_manager_read_current_state (manager);
+ manager_class->ensure_initial_config (manager);
+
priv->bus_name_id = g_bus_own_name (G_BUS_TYPE_SESSION,
"org.gnome.Mutter.DisplayConfig",
G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
@@ -642,6 +1002,9 @@ gf_monitor_manager_dispose (GObject *object)
priv->bus_name_id = 0;
}
+ g_clear_object (&manager->config_manager);
+ g_clear_object (&manager->up_client);
+
priv->backend = NULL;
G_OBJECT_CLASS (gf_monitor_manager_parent_class)->dispose (object);
@@ -732,6 +1095,10 @@ gf_monitor_manager_class_init (GfMonitorManagerClass *manager_class)
object_class->get_property = gf_monitor_manager_get_property;
object_class->set_property = gf_monitor_manager_set_property;
+ manager_class->get_edid_file = gf_monitor_manager_real_get_edid_file;
+ manager_class->read_edid = gf_monitor_manager_real_read_edid;
+ manager_class->is_lid_closed = gf_monitor_manager_real_is_lid_closed;
+
gf_monitor_manager_install_properties (object_class);
gf_monitor_manager_install_signals (object_class);
}
@@ -1113,6 +1480,18 @@ gf_monitor_manager_get_capabilities (GfMonitorManager *manager)
return manager_class->get_capabilities (manager);
}
+gboolean
+gf_monitor_manager_get_max_screen_size (GfMonitorManager *manager,
+ gint *max_width,
+ gint *max_height)
+{
+ GfMonitorManagerClass *manager_class;
+
+ manager_class = GF_MONITOR_MANAGER_GET_CLASS (manager);
+
+ return manager_class->get_max_screen_size (manager, max_width, max_height);
+}
+
GfLogicalMonitorLayoutMode
gf_monitor_manager_get_default_layout_mode (GfMonitorManager *manager)
{
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 53920a6..296ce67 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,5 +1,6 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
+backends/gf-monitor-manager.c
data/applications/gnome-flashback.desktop.in
data/applications/gnome-flashback-init.desktop.in
data/autostart/gnome-flashback-nm-applet.desktop.in
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]