[clutter] input-device: add APIs to grab sequences of touch events



commit 927624d92c3cd66e5a4e3c07e9d2d9c62c974908
Author: Lionel Landwerlin <llandwerlin gmail com>
Date:   Sun Jun 17 00:44:44 2012 +0100

    input-device: add APIs to grab sequences of touch events
    
    https://bugzilla.gnome.org/show_bug.cgi?id=678279

 clutter/clutter-device-manager-private.h   |    2 +
 clutter/clutter-event.h                    |   10 --
 clutter/clutter-input-device.c             |  136 ++++++++++++++++++++++++++++
 clutter/clutter-input-device.h             |   12 +++-
 clutter/clutter-main.c                     |   22 +++++-
 clutter/clutter-types.h                    |   12 +++
 clutter/clutter.symbols                    |   17 ++--
 doc/reference/clutter/clutter-sections.txt |    3 +
 8 files changed, 195 insertions(+), 19 deletions(-)
---
diff --git a/clutter/clutter-device-manager-private.h b/clutter/clutter-device-manager-private.h
index de89ecd..c79c6df 100644
--- a/clutter/clutter-device-manager-private.h
+++ b/clutter/clutter-device-manager-private.h
@@ -86,6 +86,8 @@ struct _ClutterInputDevice
   /* the actor that has a grab in place for the device */
   ClutterActor *pointer_grab_actor;
   ClutterActor *keyboard_grab_actor;
+  GHashTable   *sequence_grab_actors;
+  GHashTable   *inv_sequence_grab_actors;
 
   /* the current click count */
   gint click_count;
diff --git a/clutter/clutter-event.h b/clutter/clutter-event.h
index 1fe60c0..0569b13 100644
--- a/clutter/clutter-event.h
+++ b/clutter/clutter-event.h
@@ -116,16 +116,6 @@ typedef struct _ClutterCrossingEvent    ClutterCrossingEvent;
 typedef struct _ClutterTouchEvent       ClutterTouchEvent;
 
 /**
- * ClutterEventSequence:
- *
- * The <structname>ClutterEventSequence</structname> structure is an opaque
- * type used to denote the event sequence of a touch event.
- *
- * Since: 1.12
- */
-typedef struct _ClutterEventSequence    ClutterEventSequence;
-
-/**
  * ClutterAnyEvent:
  * @type: event type
  * @time: event time
diff --git a/clutter/clutter-input-device.c b/clutter/clutter-input-device.c
index 4e3554b..a0ba262 100644
--- a/clutter/clutter-input-device.c
+++ b/clutter/clutter-input-device.c
@@ -1540,3 +1540,139 @@ _clutter_input_device_reset_scroll_info (ClutterInputDevice *device)
       info->last_value_valid = FALSE;
     }
 }
+
+static void
+on_grab_sequence_actor_destroy (ClutterActor       *actor,
+                                ClutterInputDevice *device)
+{
+  ClutterEventSequence *sequence =
+    g_hash_table_lookup (device->inv_sequence_grab_actors, actor);
+
+  if (sequence != NULL)
+    {
+      g_hash_table_remove (device->sequence_grab_actors, sequence);
+      g_hash_table_remove (device->inv_sequence_grab_actors, actor);
+    }
+}
+
+/**
+ * clutter_input_device_sequence_grab:
+ * @device: a #ClutterInputDevice
+ * @sequence: a #ClutterEventSequence
+ * @actor: a #ClutterActor
+ *
+ * Acquires a grab on @actor for the given @device and the given touch
+ * @sequence.
+ *
+ * Any touch event coming from @device and from @sequence will be
+ * delivered to @actor, bypassing the usual event delivery mechanism,
+ * until the grab is released by calling
+ * clutter_input_device_sequence_ungrab().
+ *
+ * The grab is client-side: even if the windowing system used by the Clutter
+ * backend has the concept of "device grabs", Clutter will not use them.
+ *
+ * Since: 1.12
+ */
+void
+clutter_input_device_sequence_grab (ClutterInputDevice   *device,
+                                    ClutterEventSequence *sequence,
+                                    ClutterActor         *actor)
+{
+  ClutterActor *grab_actor;
+
+  g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
+  g_return_if_fail (CLUTTER_IS_ACTOR (actor));
+
+  if (device->sequence_grab_actors == NULL)
+    {
+      grab_actor = NULL;
+      device->sequence_grab_actors = g_hash_table_new (NULL, NULL);
+      device->inv_sequence_grab_actors = g_hash_table_new (NULL, NULL);
+    }
+  else
+    {
+      grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
+    }
+
+  if (grab_actor != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (grab_actor,
+                                            G_CALLBACK (on_grab_sequence_actor_destroy),
+                                            device);
+      g_hash_table_remove (device->sequence_grab_actors, sequence);
+      g_hash_table_remove (device->inv_sequence_grab_actors, grab_actor);
+    }
+
+  g_hash_table_insert (device->sequence_grab_actors, sequence, actor);
+  g_hash_table_insert (device->inv_sequence_grab_actors, actor, sequence);
+  g_signal_connect (grab_actor,
+                    "destroy",
+                    G_CALLBACK (on_grab_sequence_actor_destroy),
+                    device);
+}
+
+/**
+ * clutter_input_device_sequence_ungrab:
+ * @device: a #ClutterInputDevice
+ * @sequence: a #ClutterEventSequence
+ *
+ * Releases the grab on the @device for the given @sequence, if one is
+ * in place.
+ *
+ * Since: 1.12
+ */
+void
+clutter_input_device_sequence_ungrab (ClutterInputDevice   *device,
+                                      ClutterEventSequence *sequence)
+{
+  ClutterActor *grab_actor;
+
+  g_return_if_fail (CLUTTER_IS_INPUT_DEVICE (device));
+
+  if (device->sequence_grab_actors == NULL)
+    return;
+
+  grab_actor = g_hash_table_lookup (device->sequence_grab_actors, sequence);
+
+  if (grab_actor == NULL)
+    return;
+
+  g_signal_handlers_disconnect_by_func (grab_actor,
+                                        G_CALLBACK (on_grab_sequence_actor_destroy),
+                                        device);
+  g_hash_table_remove (device->sequence_grab_actors, sequence);
+  g_hash_table_remove (device->inv_sequence_grab_actors, grab_actor);
+
+  if (g_hash_table_size (device->sequence_grab_actors) == 0)
+    {
+      g_hash_table_destroy (device->sequence_grab_actors);
+      device->sequence_grab_actors = NULL;
+      g_hash_table_destroy (device->inv_sequence_grab_actors);
+      device->inv_sequence_grab_actors = NULL;
+    }
+}
+
+/**
+ * clutter_input_device_sequence_get_grabbed_actor:
+ * @device: a #ClutterInputDevice
+ * @sequence: a #ClutterEventSequence
+ *
+ * Retrieves a pointer to the #ClutterActor currently grabbing the
+ * touch events coming from @device given the @sequence.
+ *
+ * Return value: (transfer none): a #ClutterActor, or %NULL
+ *
+ * Since: 1.12
+ */
+ClutterActor *
+clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice   *device,
+                                                 ClutterEventSequence *sequence)
+{
+  g_return_val_if_fail (CLUTTER_IS_INPUT_DEVICE (device), NULL);
+
+  if (device->sequence_grab_actors == NULL)
+    return NULL;
+
+  return g_hash_table_lookup (device->sequence_grab_actors, sequence);
+}
diff --git a/clutter/clutter-input-device.h b/clutter/clutter-input-device.h
index 1458741..7b60e43 100644
--- a/clutter/clutter-input-device.h
+++ b/clutter/clutter-input-device.h
@@ -45,7 +45,6 @@ G_BEGIN_DECLS
  * Generic representation of an input device. The actual contents of this
  * structure depend on the backend used.
  */
-typedef struct _ClutterInputDevice      ClutterInputDevice;
 typedef struct _ClutterInputDeviceClass ClutterInputDeviceClass;
 
 GType clutter_input_device_get_type (void) G_GNUC_CONST;
@@ -97,6 +96,17 @@ void                    clutter_input_device_ungrab             (ClutterInputDev
 CLUTTER_AVAILABLE_IN_1_10
 ClutterActor *          clutter_input_device_get_grabbed_actor  (ClutterInputDevice  *device);
 
+CLUTTER_AVAILABLE_IN_1_12
+void                    clutter_input_device_sequence_grab      (ClutterInputDevice   *device,
+                                                                 ClutterEventSequence *sequence,
+                                                                 ClutterActor         *actor);
+CLUTTER_AVAILABLE_IN_1_12
+void                    clutter_input_device_sequence_ungrab    (ClutterInputDevice   *device,
+                                                                 ClutterEventSequence *sequence);
+CLUTTER_AVAILABLE_IN_1_12
+ClutterActor *          clutter_input_device_sequence_get_grabbed_actor (ClutterInputDevice   *device,
+                                                                         ClutterEventSequence *sequence);
+
 gboolean                clutter_input_device_keycode_to_evdev   (ClutterInputDevice *device,
                                                                  guint               hardware_keycode,
                                                                  guint              *evdev_keycode);
diff --git a/clutter/clutter-main.c b/clutter/clutter-main.c
index fb1b56e..64df9f5 100644
--- a/clutter/clutter-main.c
+++ b/clutter/clutter-main.c
@@ -2315,6 +2315,26 @@ emit_pointer_event (ClutterEvent       *event,
 }
 
 static inline void
+emit_touch_event (ClutterEvent       *event,
+                  ClutterInputDevice *device)
+{
+  ClutterActor *grab_actor;
+
+  if ((device->sequence_grab_actors != NULL) &&
+       ((grab_actor = g_hash_table_lookup (device->sequence_grab_actors,
+                                           event->touch.sequence)) != NULL))
+    {
+      /* sequence grab */
+      clutter_actor_event (grab_actor, event, FALSE);
+    }
+  else
+    {
+      /* no grab, time to capture and bubble */
+      emit_event (event, FALSE);
+    }
+}
+
+static inline void
 emit_keyboard_event (ClutterEvent       *event,
                      ClutterInputDevice *device)
 {
@@ -2644,7 +2664,7 @@ _clutter_process_event_details (ClutterActor        *stage,
                         x, y,
                         actor);
 
-          emit_pointer_event (event, device);
+          emit_touch_event (event, device);
           break;
         }
 
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index 89f201f..3dc73bb 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -90,8 +90,20 @@ typedef struct _ClutterAnimation                ClutterAnimation;
 typedef struct _ClutterAnimator         	ClutterAnimator;
 typedef struct _ClutterState            	ClutterState;
 
+typedef struct _ClutterInputDevice              ClutterInputDevice;
+
 typedef union _ClutterEvent                     ClutterEvent;
 
+/**
+ * ClutterEventSequence:
+ *
+ * The <structname>ClutterEventSequence</structname> structure is an opaque
+ * type used to denote the event sequence of a touch event.
+ *
+ * Since: 1.12
+ */
+typedef struct _ClutterEventSequence            ClutterEventSequence;
+
 typedef struct _ClutterFog                      ClutterFog; /* deprecated */
 typedef struct _ClutterBehaviour                ClutterBehaviour; /* deprecated */
 typedef struct _ClutterShader                   ClutterShader; /* deprecated */
diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols
index cb53456..fd32e82 100644
--- a/clutter/clutter.symbols
+++ b/clutter/clutter.symbols
@@ -358,7 +358,7 @@ clutter_backend_get_cogl_context
 clutter_backend_get_double_click_distance
 clutter_backend_get_double_click_time
 clutter_backend_get_font_name
-clutter_backend_get_font_options 
+clutter_backend_get_font_options
 clutter_backend_get_resolution
 clutter_backend_get_type
 clutter_backend_set_double_click_distance
@@ -432,7 +432,7 @@ clutter_binding_pool_get_for_class
 clutter_binding_pool_get_type
 clutter_binding_pool_install_action
 clutter_binding_pool_install_closure
-clutter_binding_pool_new 
+clutter_binding_pool_new
 clutter_binding_pool_override_action
 clutter_binding_pool_override_closure
 clutter_binding_pool_remove_action
@@ -509,7 +509,7 @@ clutter_cairo_set_source_color
 clutter_cairo_texture_clear
 clutter_cairo_texture_create
 clutter_cairo_texture_create_region
-clutter_cairo_texture_get_auto_resize 
+clutter_cairo_texture_get_auto_resize
 clutter_cairo_texture_get_surface_size
 clutter_cairo_texture_get_type
 clutter_cairo_texture_invalidate
@@ -827,6 +827,9 @@ clutter_input_device_get_slave_devices
 clutter_input_device_get_type
 clutter_input_device_grab
 clutter_input_device_keycode_to_evdev
+clutter_input_device_sequence_get_grabbed_actor
+clutter_input_device_sequence_grab
+clutter_input_device_sequence_ungrab
 clutter_input_device_set_enabled
 clutter_input_device_set_key
 clutter_input_device_type_get_type
@@ -1246,7 +1249,7 @@ clutter_stage_show_cursor
 clutter_state_get_animator
 clutter_state_get_duration
 clutter_state_get_keys
-clutter_stage_get_redraw_clip_bounds 
+clutter_stage_get_redraw_clip_bounds
 clutter_state_get_state
 clutter_state_get_states
 clutter_state_get_timeline
@@ -1254,7 +1257,7 @@ clutter_state_get_type
 clutter_state_key_get_mode
 clutter_state_key_get_object
 clutter_state_key_get_post_delay
-clutter_state_key_get_pre_delay 
+clutter_state_key_get_pre_delay
 clutter_state_key_get_property_name
 clutter_state_key_get_property_type
 clutter_state_key_get_source_state_name
@@ -1538,7 +1541,7 @@ clutter_win32_disable_event_retrieval
 clutter_win32_get_stage_from_window
 clutter_win32_get_stage_window
 clutter_win32_set_stage_foreign
-clutter_win32_handle_event 
+clutter_win32_handle_event
 #endif
 #ifdef CLUTTER_WINDOWING_X11
 clutter_x11_add_filter
@@ -1572,7 +1575,7 @@ clutter_x11_texture_pixmap_set_automatic
 clutter_x11_texture_pixmap_set_pixmap
 clutter_x11_texture_pixmap_set_window
 clutter_x11_texture_pixmap_sync_window
-clutter_x11_texture_pixmap_update_area 
+clutter_x11_texture_pixmap_update_area
 clutter_x11_trap_x_errors
 clutter_x11_untrap_x_errors
 clutter_x11_xinput_event_types_get_type
diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt
index 705f853..7ae984a 100644
--- a/doc/reference/clutter/clutter-sections.txt
+++ b/doc/reference/clutter/clutter-sections.txt
@@ -1184,6 +1184,9 @@ clutter_input_device_get_pointer_stage
 clutter_input_device_grab
 clutter_input_device_ungrab
 clutter_input_device_get_grabbed_actor
+clutter_input_device_sequence_grab
+clutter_input_device_sequence_ungrab
+clutter_input_device_sequence_get_grabbed_actor
 
 <SUBSECTION>
 clutter_input_device_update_from_event



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