[mutter] backends: Add a MetaOrientationManager class



commit aad228030945b37957a8bbd4d69edeba7690c6e2
Author: Rui Matos <tiagomatos gmail com>
Date:   Fri Apr 28 17:49:00 2017 +0200

    backends: Add a MetaOrientationManager class
    
    This basically moves g-s-d's orientation plugin into mutter so that
    eventually g-s-d doesn't need to build monitor configurations by
    itself anymore.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=781906

 src/Makefile.am                         |    2 +
 src/backends/meta-backend-private.h     |    2 +
 src/backends/meta-backend.c             |   15 ++
 src/backends/meta-orientation-manager.c |  280 +++++++++++++++++++++++++++++++
 src/backends/meta-orientation-manager.h |   40 +++++
 5 files changed, 339 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 34dd545..0d6afa2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -118,6 +118,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES =      \
        backends/meta-monitor-manager-private.h \
        backends/meta-monitor-manager-dummy.c   \
        backends/meta-monitor-manager-dummy.h   \
+       backends/meta-orientation-manager.c     \
+       backends/meta-orientation-manager.h     \
        backends/meta-pointer-constraint.c      \
        backends/meta-pointer-constraint.h      \
        backends/meta-settings.c                \
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index d2c3a91..382c939 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -34,6 +34,7 @@
 #include <meta/meta-idle-monitor.h>
 #include "meta-cursor-renderer.h"
 #include "meta-monitor-manager-private.h"
+#include "meta-orientation-manager.h"
 #include "meta-input-settings-private.h"
 #include "backends/meta-egl.h"
 #include "backends/meta-pointer-constraint.h"
@@ -112,6 +113,7 @@ void meta_backend_foreach_device_monitor (MetaBackend *backend,
                                           gpointer     user_data);
 
 MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);
+MetaOrientationManager * meta_backend_get_orientation_manager (MetaBackend *backend);
 MetaCursorTracker * meta_backend_get_cursor_tracker (MetaBackend *backend);
 MetaCursorRenderer * meta_backend_get_cursor_renderer (MetaBackend *backend);
 MetaRenderer * meta_backend_get_renderer (MetaBackend *backend);
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 171c611..573666d 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -79,6 +79,7 @@ meta_get_backend (void)
 struct _MetaBackendPrivate
 {
   MetaMonitorManager *monitor_manager;
+  MetaOrientationManager *orientation_manager;
   MetaCursorTracker *cursor_tracker;
   MetaCursorRenderer *cursor_renderer;
   MetaInputSettings *input_settings;
@@ -115,6 +116,7 @@ meta_backend_finalize (GObject *object)
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 
   g_clear_object (&priv->monitor_manager);
+  g_clear_object (&priv->orientation_manager);
   g_clear_object (&priv->input_settings);
 
   if (priv->device_update_idle_id)
@@ -534,6 +536,8 @@ meta_backend_initable_init (GInitable     *initable,
 
   priv->dnd = g_object_new (META_TYPE_DND, NULL);
 
+  priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL);
+
   return TRUE;
 }
 
@@ -582,6 +586,17 @@ meta_backend_get_monitor_manager (MetaBackend *backend)
   return priv->monitor_manager;
 }
 
+/**
+ * meta_backend_get_orientation_manager: (skip)
+ */
+MetaOrientationManager *
+meta_backend_get_orientation_manager (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  return priv->orientation_manager;
+}
+
 MetaCursorTracker *
 meta_backend_get_cursor_tracker (MetaBackend *backend)
 {
diff --git a/src/backends/meta-orientation-manager.c b/src/backends/meta-orientation-manager.c
new file mode 100644
index 0000000..4dbdb62
--- /dev/null
+++ b/src/backends/meta-orientation-manager.c
@@ -0,0 +1,280 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "backends/meta-orientation-manager.h"
+
+enum
+{
+  ORIENTATION_CHANGED,
+
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS];
+
+struct _MetaOrientationManager
+{
+  GObject parent_instance;
+
+  GCancellable *cancellable;
+
+  guint iio_watch_id;
+  GDBusProxy *iio_proxy;
+  MetaOrientation prev_orientation;
+  MetaOrientation curr_orientation;
+
+  GSettings *settings;
+};
+
+G_DEFINE_TYPE (MetaOrientationManager, meta_orientation_manager, G_TYPE_OBJECT)
+
+#define CONF_SCHEMA "org.gnome.settings-daemon.peripherals.touchscreen"
+#define ORIENTATION_LOCK_KEY "orientation-lock"
+
+static MetaOrientation
+orientation_from_string (const char *orientation)
+{
+  if (g_strcmp0 (orientation, "normal") == 0)
+    return META_ORIENTATION_NORMAL;
+  if (g_strcmp0 (orientation, "bottom-up") == 0)
+    return META_ORIENTATION_BOTTOM_UP;
+  if (g_strcmp0 (orientation, "left-up") == 0)
+    return META_ORIENTATION_LEFT_UP;
+  if (g_strcmp0 (orientation, "right-up") == 0)
+    return META_ORIENTATION_RIGHT_UP;
+
+  return META_ORIENTATION_UNDEFINED;
+}
+
+static void
+read_iio_proxy (MetaOrientationManager *self)
+{
+  gboolean has_accel = FALSE;
+  GVariant *v;
+
+  self->curr_orientation = META_ORIENTATION_UNDEFINED;
+
+  if (!self->iio_proxy)
+    return;
+
+  v = g_dbus_proxy_get_cached_property (self->iio_proxy, "HasAccelerometer");
+  if (v)
+    {
+      has_accel = g_variant_get_boolean (v);
+      g_variant_unref (v);
+    }
+
+  if (has_accel)
+    {
+      v = g_dbus_proxy_get_cached_property (self->iio_proxy, "AccelerometerOrientation");
+      if (v)
+        {
+          self->curr_orientation = orientation_from_string (g_variant_get_string (v, NULL));
+          g_variant_unref (v);
+        }
+    }
+}
+
+static void
+sync_state (MetaOrientationManager *self)
+{
+  read_iio_proxy (self);
+
+  if (self->prev_orientation == self->curr_orientation)
+    return;
+
+  self->prev_orientation = self->curr_orientation;
+
+  if (self->curr_orientation == META_ORIENTATION_UNDEFINED)
+    return;
+
+  if (g_settings_get_boolean (self->settings, ORIENTATION_LOCK_KEY))
+    return;
+
+  g_signal_emit (self, signals[ORIENTATION_CHANGED], 0);
+}
+
+static void
+orientation_lock_changed (GSettings *settings,
+                          gchar     *key,
+                          gpointer   user_data)
+{
+  MetaOrientationManager *self = user_data;
+  sync_state (self);
+}
+
+static void
+iio_properties_changed (GDBusProxy *proxy,
+                        GVariant   *changed_properties,
+                        GStrv       invalidated_properties,
+                        gpointer    user_data)
+{
+  MetaOrientationManager *self = user_data;
+  sync_state (self);
+}
+
+static void
+accelerometer_claimed (GObject      *source,
+                       GAsyncResult *res,
+                       gpointer      user_data)
+{
+  MetaOrientationManager *self = user_data;
+  GVariant *v;
+  GError *error = NULL;
+
+  v = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
+  if (!v)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to claim accelerometer: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  g_variant_unref (v);
+
+  sync_state (self);
+}
+
+static void
+iio_proxy_ready (GObject      *source,
+                 GAsyncResult *res,
+                 gpointer      user_data)
+{
+  MetaOrientationManager *self = user_data;
+  GDBusProxy *proxy;
+  GError *error = NULL;
+
+  proxy = g_dbus_proxy_new_finish (res, &error);
+  if (!proxy)
+    {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to obtain IIO DBus proxy: %s", error->message);
+      g_error_free (error);
+      return;
+    }
+
+  self->iio_proxy = proxy;
+  g_signal_connect_object (self->iio_proxy, "g-properties-changed",
+                           G_CALLBACK (iio_properties_changed), self, 0);
+  g_dbus_proxy_call (self->iio_proxy,
+                     "ClaimAccelerometer",
+                     NULL,
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1,
+                     self->cancellable,
+                     accelerometer_claimed,
+                     self);
+}
+
+static void
+iio_sensor_appeared_cb (GDBusConnection *connection,
+                        const gchar     *name,
+                        const gchar     *name_owner,
+                        gpointer         user_data)
+{
+  MetaOrientationManager *self = user_data;
+
+  self->cancellable = g_cancellable_new ();
+  g_dbus_proxy_new (connection,
+                    G_DBUS_PROXY_FLAGS_NONE,
+                    NULL,
+                    "net.hadess.SensorProxy",
+                    "/net/hadess/SensorProxy",
+                    "net.hadess.SensorProxy",
+                    self->cancellable,
+                    iio_proxy_ready,
+                    self);
+}
+
+static void
+iio_sensor_vanished_cb (GDBusConnection *connection,
+                        const gchar     *name,
+                        gpointer         user_data)
+{
+  MetaOrientationManager *self = user_data;
+
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
+
+  g_clear_object (&self->iio_proxy);
+
+  sync_state (self);
+}
+
+static void
+meta_orientation_manager_init (MetaOrientationManager *self)
+{
+  self->iio_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
+                                         "net.hadess.SensorProxy",
+                                         G_BUS_NAME_WATCHER_FLAGS_NONE,
+                                         iio_sensor_appeared_cb,
+                                         iio_sensor_vanished_cb,
+                                         self,
+                                         NULL);
+
+  self->settings = g_settings_new (CONF_SCHEMA);
+  g_signal_connect_object (self->settings, "changed::"ORIENTATION_LOCK_KEY,
+                           G_CALLBACK (orientation_lock_changed), self, 0);
+  sync_state (self);
+}
+
+static void
+meta_orientation_manager_finalize (GObject *object)
+{
+  MetaOrientationManager *self = META_ORIENTATION_MANAGER (object);
+
+  g_cancellable_cancel (self->cancellable);
+  g_clear_object (&self->cancellable);
+
+  g_bus_unwatch_name (self->iio_watch_id);
+  g_clear_object (&self->iio_proxy);
+
+  g_clear_object (&self->settings);
+
+  G_OBJECT_CLASS (meta_orientation_manager_parent_class)->finalize (object);
+}
+
+static void
+meta_orientation_manager_class_init (MetaOrientationManagerClass *klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+  gobject_class->finalize = meta_orientation_manager_finalize;
+
+  signals[ORIENTATION_CHANGED] =
+    g_signal_new ("orientation-changed",
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 0);
+}
+
+MetaOrientation
+meta_orientation_manager_get_orientation (MetaOrientationManager *self)
+{
+  return self->curr_orientation;
+}
diff --git a/src/backends/meta-orientation-manager.h b/src/backends/meta-orientation-manager.h
new file mode 100644
index 0000000..b393d10
--- /dev/null
+++ b/src/backends/meta-orientation-manager.h
@@ -0,0 +1,40 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2017 Red Hat
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_ORIENTATION_MANAGER_H
+#define META_ORIENTATION_MANAGER_H
+
+typedef enum
+{
+  META_ORIENTATION_UNDEFINED,
+  META_ORIENTATION_NORMAL,
+  META_ORIENTATION_BOTTOM_UP,
+  META_ORIENTATION_LEFT_UP,
+  META_ORIENTATION_RIGHT_UP
+} MetaOrientation;
+
+#define META_TYPE_ORIENTATION_MANAGER (meta_orientation_manager_get_type ())
+G_DECLARE_FINAL_TYPE (MetaOrientationManager, meta_orientation_manager,
+                      META, ORIENTATION_MANAGER, GObject)
+
+MetaOrientation meta_orientation_manager_get_orientation (MetaOrientationManager *self);
+
+#endif  /* META_ORIENTATION_MANAGER_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]