[gnome-flashback] backends: add GfOrientationManager
- From: Alberts Muktupāvels <muktupavels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-flashback] backends: add GfOrientationManager
- Date: Sat, 9 Sep 2017 22:18:26 +0000 (UTC)
commit 86540c027c01b8339a8e1130879f2ed79dcd8d4c
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date: Sat Sep 9 22:27:08 2017 +0300
backends: add GfOrientationManager
backends/Makefile.am | 2 +
backends/gf-backend.c | 6 +-
backends/gf-orientation-manager-private.h | 49 +++++
backends/gf-orientation-manager.c | 327 +++++++++++++++++++++++++++++
4 files changed, 383 insertions(+), 1 deletions(-)
---
diff --git a/backends/Makefile.am b/backends/Makefile.am
index e53f01d..9019178 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -29,6 +29,8 @@ libbackends_la_SOURCES = \
gf-backend-x11.c \
gf-backend.c \
gf-backend.h \
+ gf-orientation-manager-private.h \
+ gf-orientation-manager.c \
gf-settings-private.h \
gf-settings.c \
$(BUILT_SOURCES) \
diff --git a/backends/gf-backend.c b/backends/gf-backend.c
index a4ba4eb..28f6d71 100644
--- a/backends/gf-backend.c
+++ b/backends/gf-backend.c
@@ -30,11 +30,13 @@
#include "gf-backend-native-private.h"
#include "gf-backend-x11-cm-private.h"
#include "gf-backend-x11-nested-private.h"
+#include "gf-orientation-manager-private.h"
#include "gf-settings-private.h"
typedef struct
{
- GfSettings *settings;
+ GfSettings *settings;
+ GfOrientationManager *orientation_manager;
} GfBackendPrivate;
static void
@@ -57,6 +59,7 @@ gf_backend_initable_init (GInitable *initable,
priv = gf_backend_get_instance_private (backend);
priv->settings = gf_settings_new (backend);
+ priv->orientation_manager = gf_orientation_manager_new ();
return TRUE;
}
@@ -76,6 +79,7 @@ gf_backend_dispose (GObject *object)
backend = GF_BACKEND (object);
priv = gf_backend_get_instance_private (backend);
+ g_clear_object (&priv->orientation_manager);
g_clear_object (&priv->settings);
G_OBJECT_CLASS (gf_backend_parent_class)->dispose (object);
diff --git a/backends/gf-orientation-manager-private.h b/backends/gf-orientation-manager-private.h
new file mode 100644
index 0000000..e0e5cb5
--- /dev/null
+++ b/backends/gf-orientation-manager-private.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 Alberts Muktupāvels
+ * 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 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:
+ * - src/backends/meta-orientation-manager.h
+ */
+
+#ifndef GF_ORIENTATION_MANAGER_PRIVATE_H
+#define GF_ORIENTATION_MANAGER_PRIVATE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ GF_ORIENTATION_UNDEFINED,
+
+ GF_ORIENTATION_NORMAL,
+ GF_ORIENTATION_BOTTOM_UP,
+ GF_ORIENTATION_LEFT_UP,
+ GF_ORIENTATION_RIGHT_UP
+} GfOrientation;
+
+#define GF_TYPE_ORIENTATION_MANAGER (gf_orientation_manager_get_type ())
+G_DECLARE_FINAL_TYPE (GfOrientationManager, gf_orientation_manager,
+ GF, ORIENTATION_MANAGER, GObject)
+
+GfOrientationManager *gf_orientation_manager_new (void);
+
+GfOrientation gf_orientation_manager_get_orientation (GfOrientationManager *manager);
+
+G_END_DECLS
+
+#endif
diff --git a/backends/gf-orientation-manager.c b/backends/gf-orientation-manager.c
new file mode 100644
index 0000000..b2f411c
--- /dev/null
+++ b/backends/gf-orientation-manager.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2017 Alberts Muktupāvels
+ * 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 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:
+ * - src/backends/meta-orientation-manager.c
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include "gf-orientation-manager-private.h"
+
+#define TOUCHSCREEN_SCHEMA "org.gnome.settings-daemon.peripherals.touchscreen"
+#define ORIENTATION_LOCK_KEY "orientation-lock"
+
+struct _GfOrientationManager
+{
+ GObject parent;
+
+ GCancellable *cancellable;
+
+ guint iio_watch_id;
+ GDBusProxy *iio_proxy;
+ GfOrientation prev_orientation;
+ GfOrientation curr_orientation;
+
+ GSettings *settings;
+};
+
+enum
+{
+ ORIENTATION_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint manager_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GfOrientationManager, gf_orientation_manager, G_TYPE_OBJECT)
+
+static GfOrientation
+orientation_from_string (const gchar *orientation)
+{
+ if (g_strcmp0 (orientation, "normal") == 0)
+ return GF_ORIENTATION_NORMAL;
+ if (g_strcmp0 (orientation, "bottom-up") == 0)
+ return GF_ORIENTATION_BOTTOM_UP;
+ if (g_strcmp0 (orientation, "left-up") == 0)
+ return GF_ORIENTATION_LEFT_UP;
+ if (g_strcmp0 (orientation, "right-up") == 0)
+ return GF_ORIENTATION_RIGHT_UP;
+
+ return GF_ORIENTATION_UNDEFINED;
+}
+
+static void
+read_iio_proxy (GfOrientationManager *manager)
+{
+ gboolean has_accel;
+ GVariant *variant;
+
+ manager->curr_orientation = GF_ORIENTATION_UNDEFINED;
+
+ if (!manager->iio_proxy)
+ return;
+
+ has_accel = FALSE;
+ variant = g_dbus_proxy_get_cached_property (manager->iio_proxy, "HasAccelerometer");
+
+ if (variant)
+ {
+ has_accel = g_variant_get_boolean (variant);
+ g_variant_unref (variant);
+ }
+
+ if (!has_accel)
+ return;
+
+ variant = g_dbus_proxy_get_cached_property (manager->iio_proxy, "AccelerometerOrientation");
+
+ if (variant)
+ {
+ const gchar *str;
+
+ str = g_variant_get_string (variant, NULL);
+ manager->curr_orientation = orientation_from_string (str);
+ g_variant_unref (variant);
+ }
+}
+
+static void
+sync_state (GfOrientationManager *manager)
+{
+ read_iio_proxy (manager);
+
+ if (manager->prev_orientation == manager->curr_orientation)
+ return;
+
+ manager->prev_orientation = manager->curr_orientation;
+ if (manager->curr_orientation == GF_ORIENTATION_UNDEFINED)
+ return;
+
+ if (g_settings_get_boolean (manager->settings, ORIENTATION_LOCK_KEY))
+ return;
+
+ g_signal_emit (manager, manager_signals[ORIENTATION_CHANGED], 0);
+}
+
+static void
+orientation_lock_changed_cb (GSettings *settings,
+ const gchar *key,
+ gpointer user_data)
+{
+ GfOrientationManager *manager;
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+
+ sync_state (manager);
+}
+
+static void
+iio_properties_changed_cb (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ GStrv invalidated_properties,
+ gpointer user_data)
+{
+ GfOrientationManager *manager;
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+
+ sync_state (manager);
+}
+
+static void
+accelerometer_claimed_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GVariant *variant;
+ GError *error;
+ GfOrientationManager *manager;
+
+ error = NULL;
+ variant = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error);
+
+ if (!variant)
+ {
+ 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;
+ }
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+
+ g_variant_unref (variant);
+ sync_state (manager);
+}
+
+static void
+iio_proxy_ready_cb (GObject *source,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GDBusProxy *proxy;
+ GError *error;
+ GfOrientationManager *manager;
+
+ 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;
+ }
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+ manager->iio_proxy = proxy;
+
+ g_signal_connect (manager->iio_proxy, "g-properties-changed",
+ G_CALLBACK (iio_properties_changed_cb), manager);
+
+ g_dbus_proxy_call (manager->iio_proxy,
+ "ClaimAccelerometer",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ manager->cancellable,
+ accelerometer_claimed_cb,
+ manager);
+}
+
+static void
+iio_sensor_appeared_cb (GDBusConnection *connection,
+ const gchar *name,
+ const gchar *name_owner,
+ gpointer user_data)
+{
+ GfOrientationManager *manager;
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+
+ manager->cancellable = g_cancellable_new ();
+ g_dbus_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "net.hadess.SensorProxy",
+ "/net/hadess/SensorProxy",
+ "net.hadess.SensorProxy",
+ manager->cancellable,
+ iio_proxy_ready_cb,
+ manager);
+}
+
+static void
+iio_sensor_vanished_cb (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ GfOrientationManager *manager;
+
+ manager = GF_ORIENTATION_MANAGER (user_data);
+
+ g_cancellable_cancel (manager->cancellable);
+ g_clear_object (&manager->cancellable);
+
+ g_clear_object (&manager->iio_proxy);
+
+ sync_state (manager);
+}
+
+static void
+gf_orientation_manager_dispose (GObject *object)
+{
+ GfOrientationManager *manager;
+
+ manager = GF_ORIENTATION_MANAGER (object);
+
+ if (manager->cancellable != NULL)
+ {
+ g_cancellable_cancel (manager->cancellable);
+ g_clear_object (&manager->cancellable);
+ }
+
+ if (manager->iio_watch_id != 0)
+ {
+ g_bus_unwatch_name (manager->iio_watch_id);
+ manager->iio_watch_id = 0;
+ }
+
+ g_clear_object (&manager->iio_proxy);
+ g_clear_object (&manager->settings);
+
+ G_OBJECT_CLASS (gf_orientation_manager_parent_class)->dispose (object);
+}
+
+static void
+gf_orientation_manager_install_signals (GObjectClass *object_class)
+{
+ manager_signals[ORIENTATION_CHANGED] =
+ g_signal_new ("orientation-changed",
+ G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
+}
+
+static void
+gf_orientation_manager_class_init (GfOrientationManagerClass *manager_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (manager_class);
+
+ object_class->dispose = gf_orientation_manager_dispose;
+
+ gf_orientation_manager_install_signals (object_class);
+}
+
+static void
+gf_orientation_manager_init (GfOrientationManager *manager)
+{
+ manager->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,
+ manager,
+ NULL);
+
+ manager->settings = g_settings_new (TOUCHSCREEN_SCHEMA);
+
+ g_signal_connect (manager->settings, "changed::" ORIENTATION_LOCK_KEY,
+ G_CALLBACK (orientation_lock_changed_cb), manager);
+
+ sync_state (manager);
+}
+
+GfOrientationManager *
+gf_orientation_manager_new (void)
+{
+ return g_object_new (GF_TYPE_ORIENTATION_MANAGER, NULL);
+}
+
+GfOrientation
+gf_orientation_manager_get_orientation (GfOrientationManager *manager)
+{
+ return manager->curr_orientation;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]