[mutter/wip/carlosg/tablet-calibration-ui-mapping: 7/7] backends: Expose InputMapping D-Bus path to determine tablet mapping




commit 1a4296677e23d7814a31b3c5af0e0637657465d6
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Sep 1 13:51:40 2022 +0200

    backends: Expose InputMapping D-Bus path to determine tablet mapping
    
    Currently, the peripheral "output" setting will be unset if Mutter is
    deciding automatically the mapped output of a tablet device. In that
    case, gnome-control-center will have a hard time figuring out itself
    the better output to show the tablet calibration UI, unless it's hand
    held by Mutter.
    
    Add this private D-Bus interface so that gnome-control-center can look
    up the output as determined by Mutter to bring the missing harmony
    between both. This interface consists of a simple method to get the
    mapped output for a input device node.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2605>

 .../org.gnome.Mutter.InputMapping.xml              |  19 ++++
 src/backends/meta-input-mapper-private.h           |   5 +-
 src/backends/meta-input-mapper.c                   | 125 ++++++++++++++++++++-
 src/meson.build                                    |   7 ++
 4 files changed, 153 insertions(+), 3 deletions(-)
---
diff --git a/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml 
b/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml
new file mode 100644
index 0000000000..c7a8aad43c
--- /dev/null
+++ b/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml
@@ -0,0 +1,19 @@
+<!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.InputMapper:
+      @short_description: input mapper interface
+
+      This interface is used by gnome-control-center to implement
+      tablet calibration.
+  -->
+
+  <interface name="org.gnome.Mutter.InputMapping">
+    <method name="GetDeviceMapping">
+      <arg name="device_node" direction="in" type="o" />
+      <arg name="rect" direction="out" type="(iiii)" />
+    </method>
+  </interface>
+</node>
diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h
index 63d480dba7..894ea19fa5 100644
--- a/src/backends/meta-input-mapper-private.h
+++ b/src/backends/meta-input-mapper-private.h
@@ -26,10 +26,13 @@
 
 #include "backends/meta-backend-types.h"
 
+#include "meta-dbus-input-mapping.h"
+
 #define META_TYPE_INPUT_MAPPER (meta_input_mapper_get_type ())
 
 G_DECLARE_FINAL_TYPE (MetaInputMapper, meta_input_mapper,
-                     META, INPUT_MAPPER, GObject)
+                      META, INPUT_MAPPER,
+                      MetaDBusInputMappingSkeleton)
 
 MetaInputMapper * meta_input_mapper_new      (void);
 
diff --git a/src/backends/meta-input-mapper.c b/src/backends/meta-input-mapper.c
index ab0e848b4f..2d57351852 100644
--- a/src/backends/meta-input-mapper.c
+++ b/src/backends/meta-input-mapper.c
@@ -30,6 +30,11 @@
 #include "meta-logical-monitor.h"
 #include "meta-backend-private.h"
 
+#include "meta-dbus-input-mapping.h"
+
+#define META_INPUT_MAPPING_DBUS_SERVICE "org.gnome.Mutter.InputMapping"
+#define META_INPUT_MAPPING_DBUS_PATH "/org/gnome/Mutter/InputMapping"
+
 #define MAX_SIZE_MATCH_DIFF 0.05
 
 typedef struct _MetaMapperInputInfo MetaMapperInputInfo;
@@ -40,7 +45,7 @@ typedef struct _DeviceMatch DeviceMatch;
 
 struct _MetaInputMapper
 {
-  GObject parent_instance;
+  MetaDBusInputMappingSkeleton parent_instance;
   MetaMonitorManager *monitor_manager;
   ClutterSeat *seat;
   GHashTable *input_devices; /* ClutterInputDevice -> MetaMapperInputInfo */
@@ -48,6 +53,7 @@ struct _MetaInputMapper
 #ifdef HAVE_LIBGUDEV
   GUdevClient *udev_client;
 #endif
+  guint dbus_name_id;
 };
 
 typedef enum
@@ -112,7 +118,12 @@ static void mapper_output_info_remove_input (MetaMapperOutputInfo *output,
 static void mapper_recalculate_input (MetaInputMapper     *mapper,
                                       MetaMapperInputInfo *input);
 
-G_DEFINE_TYPE (MetaInputMapper, meta_input_mapper, G_TYPE_OBJECT)
+static void meta_input_mapping_init_iface (MetaDBusInputMappingIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaInputMapper, meta_input_mapper,
+                         META_DBUS_TYPE_INPUT_MAPPING_SKELETON,
+                         G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_INPUT_MAPPING,
+                                                meta_input_mapping_init_iface))
 
 static GSettings *
 get_device_settings (ClutterInputDevice *device)
@@ -709,6 +720,8 @@ meta_input_mapper_finalize (GObject *object)
 {
   MetaInputMapper *mapper = META_INPUT_MAPPER (object);
 
+  g_clear_handle_id (&mapper->dbus_name_id, g_bus_unown_name);
+
   g_signal_handlers_disconnect_by_func (mapper->monitor_manager,
                                         input_mapper_monitors_changed_cb,
                                         mapper);
@@ -792,6 +805,39 @@ meta_input_mapper_class_init (MetaInputMapperClass *klass)
                   G_TYPE_DOUBLE);
 }
 
+static void
+on_bus_acquired (GDBusConnection *connection,
+                 const char      *name,
+                 gpointer         user_data)
+{
+  MetaRemoteDesktop *remote_desktop = user_data;
+  GDBusInterfaceSkeleton *interface_skeleton =
+    G_DBUS_INTERFACE_SKELETON (remote_desktop);
+  g_autoptr (GError) error = NULL;
+
+  if (!g_dbus_interface_skeleton_export (interface_skeleton,
+                                         connection,
+                                         META_INPUT_MAPPING_DBUS_PATH,
+                                         &error))
+    g_warning ("Failed to export input mapping object: %s", error->message);
+}
+
+static void
+on_name_acquired (GDBusConnection *connection,
+                  const char      *name,
+                  gpointer         user_data)
+{
+  g_info ("Acquired name %s", name);
+}
+
+static void
+on_name_lost (GDBusConnection *connection,
+              const char      *name,
+              gpointer         user_data)
+{
+  g_warning ("Lost or failed to acquire name %s", name);
+}
+
 static void
 meta_input_mapper_init (MetaInputMapper *mapper)
 {
@@ -801,8 +847,83 @@ meta_input_mapper_init (MetaInputMapper *mapper)
   mapper->output_devices =
     g_hash_table_new_full (NULL, NULL, NULL,
                            (GDestroyNotify) mapper_output_info_free);
+
+  mapper->dbus_name_id =
+    g_bus_own_name (G_BUS_TYPE_SESSION,
+                    META_INPUT_MAPPING_DBUS_SERVICE,
+                    G_BUS_NAME_OWNER_FLAGS_NONE,
+                    on_bus_acquired,
+                    on_name_acquired,
+                    on_name_lost,
+                    mapper,
+                    NULL);
 }
 
+static gboolean
+handle_get_device_mapping (MetaDBusInputMapping  *skeleton,
+                           GDBusMethodInvocation *invocation,
+                           const char            *device_node)
+{
+  MetaInputMapper *input_mapper = META_INPUT_MAPPER (skeleton);
+  ClutterInputDevice *device = NULL;
+  g_autoptr (GList) devices = NULL;
+  MetaLogicalMonitor *logical_monitor;
+  GList *l;
+
+  devices = clutter_seat_list_devices (input_mapper->seat);
+
+  for (l = devices; l; l = l->next)
+    {
+      if (g_strcmp0 (clutter_input_device_get_device_node (l->data),
+                     device_node) == 0)
+        {
+          device = l->data;
+          break;
+        }
+    }
+
+  if (!device)
+    {
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_INVALID_DATA,
+                                             "Device does not exist");
+      return G_DBUS_METHOD_INVOCATION_HANDLED;
+    }
+
+  logical_monitor =
+    meta_input_mapper_get_device_logical_monitor (input_mapper, device);
+
+  if (logical_monitor)
+    {
+      MetaRectangle rect;
+
+      rect = meta_logical_monitor_get_layout (logical_monitor);
+      g_dbus_method_invocation_return_value (invocation,
+                                             g_variant_new ("((iiii))",
+                                                            rect.x,
+                                                            rect.y,
+                                                            rect.width,
+                                                            rect.height));
+      return G_DBUS_METHOD_INVOCATION_HANDLED;
+    }
+  else
+    {
+      g_dbus_method_invocation_return_error (invocation,
+                                             G_IO_ERROR,
+                                             G_IO_ERROR_NOT_FOUND,
+                                             "Device is not mapped to any output");
+      return G_DBUS_METHOD_INVOCATION_HANDLED;
+    }
+}
+
+static void
+meta_input_mapping_init_iface (MetaDBusInputMappingIface *iface)
+{
+  iface->handle_get_device_mapping = handle_get_device_mapping;
+}
+
+
 MetaInputMapper *
 meta_input_mapper_new (void)
 {
diff --git a/src/meson.build b/src/meson.build
index 1dce13e131..f4d5c78dfd 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -868,6 +868,13 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
   )
 mutter_built_sources += dbus_idle_monitor_built_sources
 
+dbus_input_mapping_built_sources = gnome.gdbus_codegen('meta-dbus-input-mapping',
+    join_paths(dbus_interfaces_dir, 'org.gnome.Mutter.InputMapping.xml'),
+    interface_prefix: 'org.gnome.Mutter.',
+    namespace: 'MetaDBus',
+  )
+mutter_built_sources += dbus_input_mapping_built_sources
+
 if have_profiler
   mutter_sources += [
     'backends/meta-profiler.c',


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