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 000000000..c7a8aad43 --- /dev/null +++ b/data/dbus-interfaces/org.gnome.Mutter.InputMapping.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/src/backends/meta-input-mapper-private.h b/src/backends/meta-input-mapper-private.h index 63d480dba..894ea19fa 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 ab0e848b4..56da701b8 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_info ("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 1dce13e13..f4d5c78df 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',