[gtk+/multitouch: 7/57] Introduce GdkTouchCluster
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/multitouch: 7/57] Introduce GdkTouchCluster
- Date: Sun, 13 Nov 2011 17:50:23 +0000 (UTC)
commit 6e56fee44ee73047115e01fd16471f938e16dec8
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Mar 1 09:09:59 2011 +0100
Introduce GdkTouchCluster
This is a per-window/device object to gather a group of touch IDs
as a single entity.
docs/reference/gdk/gdk-docs.sgml | 1 +
docs/reference/gdk/gdk3-sections.txt | 19 ++
docs/reference/gdk/gdk3.types | 1 +
gdk/Makefile.am | 2 +
gdk/gdk.h | 1 +
gdk/gdk.symbols | 5 +
gdk/gdktouchcluster.c | 346 ++++++++++++++++++++++++++++++++++
gdk/gdktouchcluster.h | 69 +++++++
8 files changed, 444 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gdk/gdk-docs.sgml b/docs/reference/gdk/gdk-docs.sgml
index 8674acd..ec25447 100644
--- a/docs/reference/gdk/gdk-docs.sgml
+++ b/docs/reference/gdk/gdk-docs.sgml
@@ -33,6 +33,7 @@
<xi:include href="xml/windows.xml" />
<xi:include href="xml/events.xml" />
<xi:include href="xml/event_structs.xml" />
+ <xi:include href="xml/touchcluster.xml" />
<xi:include href="xml/keys.xml" />
<xi:include href="xml/selections.xml" />
<xi:include href="xml/dnd.xml" />
diff --git a/docs/reference/gdk/gdk3-sections.txt b/docs/reference/gdk/gdk3-sections.txt
index d51d0f1..85b77dd 100644
--- a/docs/reference/gdk/gdk3-sections.txt
+++ b/docs/reference/gdk/gdk3-sections.txt
@@ -855,6 +855,25 @@ gdk_owner_change_get_type
</SECTION>
<SECTION>
+<TITLE>Multitouch</TITLE>
+<FILE>touchcluster</FILE>
+GdkTouchCluster
+gdk_touch_cluster_add_touch
+gdk_touch_cluster_remove_touch
+gdk_touch_cluster_remove_all
+gdk_touch_cluster_set_device
+gdk_touch_cluster_get_device
+gdk_touch_cluster_get_touches
+
+<SUBSECTION Standard>
+GDK_TYPE_TOUCH_CLUSTER
+
+<SUBSECTION Private>
+gdk_touch_cluster_get_type
+</SECTION>
+
+
+<SECTION>
<TITLE>Cursors</TITLE>
<FILE>cursors</FILE>
GdkCursor
diff --git a/docs/reference/gdk/gdk3.types b/docs/reference/gdk/gdk3.types
index abf4374..e33ee38 100644
--- a/docs/reference/gdk/gdk3.types
+++ b/docs/reference/gdk/gdk3.types
@@ -9,5 +9,6 @@ gdk_display_manager_get_type
gdk_drag_context_get_type
gdk_keymap_get_type
gdk_screen_get_type
+gdk_touch_cluster_get_type
gdk_visual_get_type
gdk_window_get_type
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 0c38d9a..8aaee29 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -88,6 +88,7 @@ gdk_public_h_sources = \
gdkselection.h \
gdktestutils.h \
gdkthreads.h \
+ gdktouchcluster.h \
gdktypes.h \
gdkvisual.h \
gdkwindow.h
@@ -130,6 +131,7 @@ gdk_c_sources = \
gdkrgba.c \
gdkscreen.c \
gdkselection.c \
+ gdktouchcluster.c \
gdkvisual.c \
gdkwindow.c \
gdkwindowimpl.c
diff --git a/gdk/gdk.h b/gdk/gdk.h
index 2b84969..5bbf62e 100644
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -53,6 +53,7 @@
#include <gdk/gdkselection.h>
#include <gdk/gdktestutils.h>
#include <gdk/gdkthreads.h>
+#include <gdk/gdktouchcluster.h>
#include <gdk/gdktypes.h>
#include <gdk/gdkvisual.h>
#include <gdk/gdkwindow.h>
diff --git a/gdk/gdk.symbols b/gdk/gdk.symbols
index 0cd9d35..00c6e13 100644
--- a/gdk/gdk.symbols
+++ b/gdk/gdk.symbols
@@ -327,6 +327,11 @@ gdk_threads_enter
gdk_threads_init
gdk_threads_leave
gdk_threads_set_lock_functions
+gdk_touch_cluster_add_touch
+gdk_touch_cluster_get_device
+gdk_touch_cluster_get_type G_GNUC_CONST
+gdk_touch_cluster_list_touches
+gdk_touch_cluster_remove_touch
gdk_unicode_to_keyval
gdk_utf8_to_string_target
gdk_visibility_state_get_type
diff --git a/gdk/gdktouchcluster.c b/gdk/gdktouchcluster.c
new file mode 100644
index 0000000..9bc0474
--- /dev/null
+++ b/gdk/gdktouchcluster.c
@@ -0,0 +1,346 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2011 Carlos Garnacho <carlosg gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gdktouchcluster.h"
+#include "gdkintl.h"
+
+/**
+ * SECTION:touchcluster
+ * @Short_description: Multitouch handling
+ * @Title: Multitouch
+ * @See_also: #GdkEventMultiTouch
+ *
+ * #GdkTouchCluster is an object that gathers touch IDs from a
+ * touch-enabled slave #GdkDevice, in order to send
+ * #GdkEventMultiTouch<!-- --> events whenever a contained touch ID
+ * is updated.
+ *
+ * #GdkTouchCluster<!-- -->s are always associated to a window,
+ * you need to create them through gdk_window_create_touch_cluster(),
+ * and free them through gdk_window_remove_touch_cluster().
+ *
+ * Touch IDs from devices can be obtained from %GDK_TOUCH_PRESS,
+ * %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events through
+ * gdk_event_get_touch_id(), and then be added via
+ * gdk_touch_cluster_add_touch(). Note that touch IDs are
+ * highly transitive, even be an incrementable number only
+ * identifying the current touch event stream, so touch IDs
+ * should always be gotten from these events.
+ *
+ * Anytime a touch ID is within a cluster, no %GDK_TOUCH_PRESS,
+ * %GDK_TOUCH_MOTION or %GDK_TOUCH_RELEASE events will happen
+ * for the individual touch. The event will be available instead
+ * as part of the #GdkMultitouchEvent that will be emitted. This
+ * will hold true until gdk_touch_cluster_remove_touch() is
+ * called for it. Note that GTK+ will automatically take a
+ * touch ID out of any cluster if %GDK_TOUCH_RELEASE is gotten
+ * internally.
+ */
+
+typedef struct GdkTouchClusterPrivate GdkTouchClusterPrivate;
+
+struct GdkTouchClusterPrivate
+{
+ GdkDevice *device;
+ GList *touches;
+};
+
+enum {
+ PROP_0,
+ PROP_DEVICE
+};
+
+enum {
+ TOUCH_ADDED,
+ TOUCH_REMOVED,
+ LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
+static void gdk_touch_cluster_finalize (GObject *object);
+static void gdk_touch_cluster_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gdk_touch_cluster_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+
+G_DEFINE_TYPE (GdkTouchCluster, gdk_touch_cluster, G_TYPE_OBJECT)
+
+static void
+gdk_touch_cluster_class_init (GdkTouchClusterClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = gdk_touch_cluster_finalize;
+ object_class->get_property = gdk_touch_cluster_get_property;
+ object_class->set_property = gdk_touch_cluster_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_DEVICE,
+ g_param_spec_object ("device",
+ P_("Device"),
+ P_("Device attached to the cluster"),
+ GDK_TYPE_DEVICE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[TOUCH_ADDED] =
+ g_signal_new (g_intern_static_string ("touch-added"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdkTouchClusterClass, touch_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+ signals[TOUCH_REMOVED] =
+ g_signal_new (g_intern_static_string ("touch-removed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdkTouchClusterClass, touch_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1, G_TYPE_UINT);
+
+ g_type_class_add_private (object_class, sizeof (GdkTouchClusterPrivate));
+}
+
+static void
+gdk_touch_cluster_init (GdkTouchCluster *cluster)
+{
+ cluster->priv = G_TYPE_INSTANCE_GET_PRIVATE (cluster,
+ GDK_TYPE_TOUCH_CLUSTER,
+ GdkTouchClusterPrivate);
+}
+
+static void
+gdk_touch_cluster_finalize (GObject *object)
+{
+ GdkTouchClusterPrivate *priv;
+
+ priv = GDK_TOUCH_CLUSTER (object)->priv;
+ g_list_free (priv->touches);
+
+ G_OBJECT_CLASS (gdk_touch_cluster_parent_class)->finalize (object);
+}
+
+static void
+gdk_touch_cluster_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_DEVICE:
+ gdk_touch_cluster_set_device (GDK_TOUCH_CLUSTER (object),
+ g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gdk_touch_cluster_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GdkTouchClusterPrivate *priv;
+
+ priv = GDK_TOUCH_CLUSTER (object)->priv;
+
+ switch (prop_id)
+ {
+ case PROP_DEVICE:
+ g_value_set_object (value, priv->device);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gdk_touch_cluster_add_touch:
+ * @cluster: a #GdkTouchCluster
+ * @touch_id: a touch ID from a touch event
+ *
+ * Adds a touch ID to @cluster, so it will generate a
+ * %GDK_MULTITOUCH_ADDED event, followed by %GDK_MULTITOUCH_UPDATED
+ * events whenever this touch ID is updated.
+ *
+ * If @touch_id already pertained to another #GdkTouchCluster, it
+ * will be removed from it, generating a %GDK_MULTITOUCH_REMOVED
+ * for that another cluster.
+ **/
+void
+gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
+ guint touch_id)
+{
+ GdkTouchClusterPrivate *priv;
+
+ g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
+
+ priv = cluster->priv;
+
+ if (!g_list_find (priv->touches, GUINT_TO_POINTER (touch_id)))
+ {
+ priv->touches = g_list_prepend (priv->touches, GUINT_TO_POINTER (touch_id));
+ g_signal_emit (cluster, signals [TOUCH_ADDED], 0, touch_id);
+ }
+}
+
+/**
+ * gdk_touch_cluster_remove_touch:
+ * @cluster: a #GdkTouchCluster
+ * @touch_id: a touch ID from a touch event
+ *
+ * Removes a touch ID from @cluster, generating a %GDK_MULTITOUCH_REMOVED
+ * event for @cluster, and causing any further input from @touch_id
+ * to be reported trough %GDK_TOUCH_MOTION events.
+ *
+ * <note><para>
+ * Note that GTK+ automatically removes a touch ID from any cluster
+ * if a %GDK_TOUCH_RELEASE event is gotten internally.
+ * </para></note>
+ **/
+void
+gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
+ guint touch_id)
+{
+ GdkTouchClusterPrivate *priv;
+ GList *link;
+
+ g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
+
+ priv = cluster->priv;
+
+ link = g_list_find (priv->touches, GUINT_TO_POINTER (touch_id));
+
+ if (link)
+ {
+ priv->touches = g_list_remove_link (priv->touches, link);
+ g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, touch_id);
+ g_list_free1 (link);
+ }
+}
+
+/**
+ * gdk_touch_cluster_remove_all:
+ * @cluster: a #GdkTouchCluster
+ *
+ * Removes all touch IDs from @cluster.
+ **/
+void
+gdk_touch_cluster_remove_all (GdkTouchCluster *cluster)
+{
+ GdkTouchClusterPrivate *priv;
+ GList *link;
+
+ g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
+
+ priv = cluster->priv;
+ link = priv->touches;
+
+ while (link)
+ {
+ priv->touches = g_list_remove_link (priv->touches, link);
+ g_signal_emit (cluster, signals [TOUCH_REMOVED], 0, link->data);
+ }
+
+ g_list_free (priv->touches);
+ priv->touches = NULL;
+}
+
+
+/**
+ * gdk_touch_cluster_get_touches:
+ * @cluster: a #GdkTouchCluster
+ *
+ * Returns a const list of touch IDs as #guint.
+ *
+ * Returns: (transfer none): A list of touch IDs.
+ **/
+GList *
+gdk_touch_cluster_get_touches (GdkTouchCluster *cluster)
+{
+ GdkTouchClusterPrivate *priv;
+
+ g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
+
+ priv = cluster->priv;
+ return priv->touches;
+}
+
+/**
+ * gdk_touch_cluster_set_device:
+ * @cluster: a #GdkTouchCluster
+ * @device: a #GdkDevice
+ *
+ * Sets the current device associated to @cluster, all contained
+ * touch IDs must pertain to this device. As a consequence,
+ * gdk_touch_cluster_remove_all() will be called on @cluster
+ * if the current device changes.
+ **/
+void
+gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
+ GdkDevice *device)
+{
+ GdkTouchClusterPrivate *priv;
+
+ g_return_if_fail (GDK_IS_TOUCH_CLUSTER (cluster));
+ g_return_if_fail (!device || GDK_IS_DEVICE (device));
+
+ priv = cluster->priv;
+
+ if (priv->device != device)
+ gdk_touch_cluster_remove_all (cluster);
+
+ priv->device = device;
+}
+
+/**
+ * gdk_touch_cluster_get_device:
+ * @cluster: a #GdkTouchCluster
+ *
+ * Returns the slave/floating device this touch cluster pertains to,
+ * only touch IDs from this device can be included in @cluster.
+ * the #GdkDevice will typically have the %GDK_SOURCE_TOUCH input source.
+ *
+ * Returns: (transfer none): The #GdkDevice generating the contained touch IDs
+ **/
+GdkDevice *
+gdk_touch_cluster_get_device (GdkTouchCluster *cluster)
+{
+ GdkTouchClusterPrivate *priv;
+
+ g_return_val_if_fail (GDK_IS_TOUCH_CLUSTER (cluster), NULL);
+
+ priv = cluster->priv;
+ return priv->device;
+}
diff --git a/gdk/gdktouchcluster.h b/gdk/gdktouchcluster.h
new file mode 100644
index 0000000..0904df5
--- /dev/null
+++ b/gdk/gdktouchcluster.h
@@ -0,0 +1,69 @@
+/* GDK - The GIMP Drawing Kit
+ * Copyright (C) 2011 Carlos Garnacho <carlosg gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDK_TOUCH_CLUSTER_H__
+#define __GDK_TOUCH_CLUSTER_H__
+
+#include <glib-object.h>
+#include <gdk/gdkdevice.h>
+
+G_BEGIN_DECLS
+
+#define GDK_TYPE_TOUCH_CLUSTER (gdk_touch_cluster_get_type ())
+#define GDK_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_TOUCH_CLUSTER, GdkTouchCluster))
+#define GDK_IS_TOUCH_CLUSTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDK_TYPE_TOUCH_CLUSTER))
+
+typedef struct _GdkTouchCluster GdkTouchCluster;
+typedef struct _GdkTouchClusterClass GdkTouchClusterClass;
+
+struct _GdkTouchCluster
+{
+ GObject parent_instance;
+ gpointer priv;
+};
+
+struct _GdkTouchClusterClass
+{
+ GObjectClass parent_class;
+
+ void (* touch_added) (GdkTouchCluster *cluster,
+ guint touch_id);
+ void (* touch_removed) (GdkTouchCluster *cluster,
+ guint touch_id);
+
+ gpointer padding[16];
+};
+
+GType gdk_touch_cluster_get_type (void) G_GNUC_CONST;
+
+void gdk_touch_cluster_add_touch (GdkTouchCluster *cluster,
+ guint touch_id);
+void gdk_touch_cluster_remove_touch (GdkTouchCluster *cluster,
+ guint touch_id);
+void gdk_touch_cluster_remove_all (GdkTouchCluster *cluster);
+
+GList * gdk_touch_cluster_get_touches (GdkTouchCluster *cluster);
+
+void gdk_touch_cluster_set_device (GdkTouchCluster *cluster,
+ GdkDevice *device);
+GdkDevice * gdk_touch_cluster_get_device (GdkTouchCluster *cluster);
+
+G_END_DECLS
+
+#endif /* __GDK_TOUCH_CLUSTER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]