From d34f1aa775e8a66bd0e599b32c761869b319c639 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 20 Nov 2009 15:35:40 +0000 Subject: [PATCH] Add ClutterDeviceManager The ClutterDeviceManager is a singleton object that behaves like the StageManager: it holds all input devices and notifies on addition and removal. --- clutter/Makefile.am | 6 +- clutter/clutter-device-manager.c | 146 +++++++++++++++++++++++++++++++ clutter/clutter-device-manager.h | 30 +++++++ clutter/clutter-main.c | 30 +++---- clutter/clutter-marshal.list | 1 + clutter/clutter-private.h | 43 +++++---- clutter/clutter.h | 1 + 7 files changed, 224 insertions(+), 33 deletions(-) create mode 100644 clutter/clutter-device-manager.c create mode 100644 clutter/clutter-device-manager.h diff --git a/clutter/Makefile.am b/clutter/Makefile.am index 44791ee85..c61aea192 100644 --- a/clutter/Makefile.am +++ b/clutter/Makefile.am @@ -82,8 +82,9 @@ source_h = \ $(srcdir)/clutter-child-meta.h \ $(srcdir)/clutter-clone.h \ $(srcdir)/clutter-color.h \ - $(srcdir)/clutter-container.h \ - $(srcdir)/clutter-deprecated.h \ + $(srcdir)/clutter-container.h \ + $(srcdir)/clutter-deprecated.h \ + $(srcdir)/clutter-device-manager.h \ $(srcdir)/clutter-event.h \ $(srcdir)/clutter-feature.h \ $(srcdir)/clutter-fixed.h \ @@ -154,6 +155,7 @@ source_c = \ $(srcdir)/clutter-clone.c \ $(srcdir)/clutter-color.c \ $(srcdir)/clutter-container.c \ + $(srcdir)/clutter-device-manager.c \ clutter-enum-types.c \ $(srcdir)/clutter-event.c \ $(srcdir)/clutter-feature.c \ diff --git a/clutter/clutter-device-manager.c b/clutter/clutter-device-manager.c new file mode 100644 index 000000000..bfed42fb8 --- /dev/null +++ b/clutter/clutter-device-manager.c @@ -0,0 +1,146 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "clutter-debug.h" +#include "clutter-device-manager.h" +#include "clutter-enum-types.h" +#include "clutter-marshal.h" +#include "clutter-private.h" + +#define CLUTTER_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass)) +#define CLUTTER_IS_DEVICE_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_DEVICE_MANAGER)) +#define CLUTTER_DEVICE_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManagerClass)) + +typedef struct _ClutterDeviceManagerClass ClutterDeviceManagerClass; + +struct _ClutterDeviceManagerClass +{ + GObjectClass parent_instance; +}; + +enum +{ + DEVICE_ADDED, + DEVICE_REMOVED, + + LAST_SIGNAL +}; + +static ClutterDeviceManager *default_manager = NULL; + +static guint manager_signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE (ClutterDeviceManager, clutter_device_manager, G_TYPE_OBJECT); + +static void +clutter_device_manager_class_init (ClutterDeviceManagerClass *klass) +{ + manager_signals[DEVICE_ADDED] = + g_signal_new (I_("device-added"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + clutter_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + manager_signals[DEVICE_REMOVED] = + g_signal_new (I_("device-removed"), + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + clutter_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); +} + +static void +clutter_device_manager_init (ClutterDeviceManager *self) +{ +} + +ClutterDeviceManager * +clutter_device_manager_get_default (void) +{ + if (G_UNLIKELY (default_manager == NULL)) + default_manager = g_object_new (CLUTTER_TYPE_DEVICE_MANAGER, NULL); + + return default_manager; +} + +GSList * +clutter_device_manager_list_devices (ClutterDeviceManager *device_manager) +{ + g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); + + return g_slist_copy (device_manager->devices); +} + +const GSList * +clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager) +{ + g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); + + return device_manager->devices; +} + +ClutterInputDevice * +clutter_device_manager_get_device (ClutterDeviceManager *device_manager, + gint device_id) +{ + GSList *l; + + g_return_val_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager), NULL); + + for (l = device_manager->devices; l != NULL; l = l->next) + { + ClutterInputDevice *device = l->data; + + if (device->id == device_id) + return device; + } + + return NULL; +} + +static gint +input_device_cmp (gconstpointer a, + gconstpointer b) +{ + const ClutterInputDevice *device_a = a; + const ClutterInputDevice *device_b = b; + + if (device_a->id < device_b->id) + return -1; + + if (device_a->id > device_b->id) + return 1; + + return 0; +} + +void +_clutter_device_manager_add_device (ClutterDeviceManager *device_manager, + ClutterInputDevice *device) +{ + g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); + + device_manager->devices = g_slist_insert_sorted (device_manager->devices, + device, + input_device_cmp); +} + +void +_clutter_device_manager_remove_device (ClutterDeviceManager *device_manager, + ClutterInputDevice *device) +{ + g_return_if_fail (CLUTTER_IS_DEVICE_MANAGER (device_manager)); + + if (g_slist_find (device_manager->devices, device) == NULL) + return; + + device_manager->devices = g_slist_remove (device_manager->devices, device); +} diff --git a/clutter/clutter-device-manager.h b/clutter/clutter-device-manager.h new file mode 100644 index 000000000..6d4893d73 --- /dev/null +++ b/clutter/clutter-device-manager.h @@ -0,0 +1,30 @@ +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __CLUTTER_DEVICE_MANAGER_H__ +#define __CLUTTER_DEVICE_MANAGER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define CLUTTER_TYPE_DEVICE_MANAGER (clutter_device_manager_get_type ()) +#define CLUTTER_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_DEVICE_MANAGER, ClutterDeviceManager)) +#define CLUTTER_IS_DEVICE_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_DEVICE_MANAGER)) + +typedef struct _ClutterDeviceManager ClutterDeviceManager; + +GType clutter_stage_manager_get_type (void) G_GNUC_CONST; + +ClutterDeviceManager *clutter_device_manager_get_default (void); +GSList * clutter_device_manager_list_devices (ClutterDeviceManager *device_manager); +const GSList * clutter_device_manager_peek_devices (ClutterDeviceManager *device_manager); + +ClutterInputDevice * clutter_device_manager_get_device (ClutterDeviceManager *device_manager, + gint device_id); + +G_END_DECLS + +#endif /* __CLUTTER_DEVICE_MANAGER_H__ */ diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c index ea5e19d14..7d69fb8a0 100644 --- a/clutter/clutter-main.c +++ b/clutter/clutter-main.c @@ -3025,7 +3025,17 @@ clutter_get_font_flags (void) * clutter_get_input_device_for_id: * @id: a device id * - * Retrieves the #ClutterInputDevice from its id. + * Retrieves the #ClutterInputDevice from its id. This is a convenience + * wrapper for clutter_device_manager_get_device() and it is functionally + * equivalent to: + * + * |[ + * ClutterDeviceManager *manager; + * ClutterInputDevice *device; + * + * manager = clutter_device_manager_get_default (); + * device = clutter_device_manager_get_device (manager, id); + * ]| * * Return value: (transfer none): a #ClutterInputDevice, or %NULL * @@ -3034,23 +3044,11 @@ clutter_get_font_flags (void) ClutterInputDevice * clutter_get_input_device_for_id (gint id) { - GSList *item; - ClutterInputDevice *device = NULL; - ClutterMainContext *context; + ClutterDeviceManager *manager; - context = _clutter_context_get_default (); + manager = clutter_device_manager_get_default (); - for (item = context->input_devices; - item != NULL; - item = item->next) - { - device = item->data; - - if (device->id == id) - return device; - } - - return NULL; + return clutter_device_manager_get_device (manager, id); } /** diff --git a/clutter/clutter-marshal.list b/clutter/clutter-marshal.list index 7f354b11a..8296f9add 100644 --- a/clutter/clutter-marshal.list +++ b/clutter/clutter-marshal.list @@ -12,6 +12,7 @@ VOID:INT,INT,INT,INT VOID:OBJECT VOID:OBJECT,OBJECT,PARAM VOID:OBJECT,POINTER +VOID:POINTER VOID:STRING,BOOLEAN,BOOLEAN VOID:STRING,INT VOID:UINT diff --git a/clutter/clutter-private.h b/clutter/clutter-private.h index dd687d010..2567eaae9 100644 --- a/clutter/clutter-private.h +++ b/clutter/clutter-private.h @@ -41,6 +41,7 @@ #include "pango/cogl-pango.h" #include "clutter-backend.h" +#include "clutter-device-manager.h" #include "clutter-event.h" #include "clutter-feature.h" #include "clutter-id-pool.h" @@ -52,6 +53,8 @@ G_BEGIN_DECLS +typedef struct _ClutterMainContext ClutterMainContext; + typedef enum { CLUTTER_ACTOR_UNUSED_FLAG = 0, @@ -82,21 +85,33 @@ typedef enum { struct _ClutterInputDevice { - gint id; + gint id; ClutterInputDeviceType device_type; ClutterActor *pointer_grab_actor; ClutterActor *motion_last_actor; - gint click_count; - gint previous_x; - gint previous_y; - guint32 previous_time; - gint previous_button_number; + gint click_count; + gint previous_x; + gint previous_y; + guint32 previous_time; + gint previous_button_number; }; -typedef struct _ClutterMainContext ClutterMainContext; +struct _ClutterStageManager +{ + GObject parent_instance; + + GSList *stages; +}; + +struct _ClutterDeviceManager +{ + GObject parent_instance; + + GSList *devices; +}; struct _ClutterMainContext { @@ -170,21 +185,19 @@ PangoContext *_clutter_context_get_pango_context (ClutterMainContext *self); #define I_(str) (g_intern_static_string ((str))) +/* device manager */ +void _clutter_device_manager_add_device (ClutterDeviceManager *device_manager, + ClutterInputDevice *device); +void _clutter_device_manager_remove_device (ClutterDeviceManager *device_manager, + ClutterInputDevice *device); + /* stage manager */ -struct _ClutterStageManager -{ - GObject parent_instance; - - GSList *stages; -}; - void _clutter_stage_manager_add_stage (ClutterStageManager *stage_manager, ClutterStage *stage); void _clutter_stage_manager_remove_stage (ClutterStageManager *stage_manager, ClutterStage *stage); /* stage */ - void _clutter_stage_set_window (ClutterStage *stage, ClutterStageWindow *stage_window); ClutterStageWindow *_clutter_stage_get_window (ClutterStage *stage); diff --git a/clutter/clutter.h b/clutter/clutter.h index 087d93d40..971910976 100644 --- a/clutter/clutter.h +++ b/clutter/clutter.h @@ -51,6 +51,7 @@ #include "clutter-clone.h" #include "clutter-color.h" #include "clutter-container.h" +#include "clutter-device-manager.h" #include "clutter-event.h" #include "clutter-feature.h" #include "clutter-fixed-layout.h"