summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2012-03-05 13:58:00 +0100
committerBenjamin Otte <otte@redhat.com>2012-03-14 19:32:54 +0100
commit4da18923c5d01cbc8cd5c0e0ebb7c5f6b5585fe3 (patch)
tree0012d1bcf3027ec365887521507374eff560ad2e
parentd3cdf494d9f601c921354ad37516bd54079aad1a (diff)
downloadgtk+-4da18923c5d01cbc8cd5c0e0ebb7c5f6b5585fe3.tar.gz
gdk: Make event sequences real objects
So far this fact is hidden from the implementation. The usefulness of this change will soon become apparent.
-rw-r--r--gdk/Makefile.am2
-rw-r--r--gdk/gdkdevice.c14
-rw-r--r--gdk/gdkdeviceprivate.h1
-rw-r--r--gdk/gdkevents.c3
-rw-r--r--gdk/gdkeventsequence.c85
-rw-r--r--gdk/gdkeventsequenceprivate.h44
-rw-r--r--gdk/gdkwindow.c5
-rw-r--r--gdk/x11/gdkdevicemanager-xi2.c26
8 files changed, 170 insertions, 10 deletions
diff --git a/gdk/Makefile.am b/gdk/Makefile.am
index 6b647e5302..f3dd659aa5 100644
--- a/gdk/Makefile.am
+++ b/gdk/Makefile.am
@@ -101,6 +101,7 @@ gdk_private_headers = \
gdkdisplaymanagerprivate.h \
gdkdisplayprivate.h \
gdkdndprivate.h \
+ gdkeventsequenceprivate.h \
gdkscreenprivate.h \
gdkinternals.h \
gdkintl.h \
@@ -121,6 +122,7 @@ gdk_c_sources = \
gdkdisplaymanager.c \
gdkdnd.c \
gdkevents.c \
+ gdkeventsequence.c \
gdkglobals.c \
gdkkeys.c \
gdkkeyuni.c \
diff --git a/gdk/gdkdevice.c b/gdk/gdkdevice.c
index 88e6f29f0f..090236f48a 100644
--- a/gdk/gdkdevice.c
+++ b/gdk/gdkdevice.c
@@ -21,6 +21,7 @@
#include "gdkdeviceprivate.h"
#include "gdkdisplayprivate.h"
+#include "gdkeventsequenceprivate.h"
#include "gdkinternals.h"
#include "gdkintl.h"
@@ -275,6 +276,7 @@ static void
gdk_device_dispose (GObject *object)
{
GdkDevice *device = GDK_DEVICE (object);
+ GSList *list;
if (device->type == GDK_DEVICE_TYPE_SLAVE)
_gdk_device_remove_slave (device->associated, device);
@@ -288,6 +290,18 @@ gdk_device_dispose (GObject *object)
device->associated = NULL;
}
+ for (list = device->sequences; list; list = list->next)
+ {
+ GdkEventSequence *sequence = list->data;
+
+ /* Set device to NULL in advance so that the unreffing doesn't
+ * modify the list we iterate over */
+ sequence->device = NULL;
+ gdk_event_sequence_unref (sequence);
+ }
+ g_slist_free (device->sequences);
+ device->sequences = NULL;
+
if (device->axes)
{
g_array_free (device->axes, TRUE);
diff --git a/gdk/gdkdeviceprivate.h b/gdk/gdkdeviceprivate.h
index 53e31cd20f..6a36e2971b 100644
--- a/gdk/gdkdeviceprivate.h
+++ b/gdk/gdkdeviceprivate.h
@@ -56,6 +56,7 @@ struct _GdkDevice
GList *slaves;
GdkDeviceType type;
GArray *axes;
+ GSList *sequences;
};
struct _GdkDeviceClass
diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c
index db37512bc6..f93a246733 100644
--- a/gdk/gdkevents.c
+++ b/gdk/gdkevents.c
@@ -26,6 +26,7 @@
#include "gdkinternals.h"
#include "gdkdisplayprivate.h"
+#include "gdkeventsequenceprivate.h"
#include <string.h>
#include <math.h>
@@ -600,6 +601,7 @@ gdk_event_copy (const GdkEvent *event)
case GDK_TOUCH_UPDATE:
case GDK_TOUCH_END:
case GDK_TOUCH_CANCEL:
+ new_event->touch.sequence = gdk_event_sequence_ref (event->touch.sequence);
if (event->touch.axes)
new_event->touch.axes = g_memdup (event->touch.axes,
sizeof (gdouble) * gdk_device_get_n_axes (event->touch.device));
@@ -689,6 +691,7 @@ gdk_event_free (GdkEvent *event)
case GDK_TOUCH_END:
case GDK_TOUCH_CANCEL:
g_free (event->touch.axes);
+ gdk_event_sequence_unref (event->touch.sequence);
break;
case GDK_EXPOSE:
diff --git a/gdk/gdkeventsequence.c b/gdk/gdkeventsequence.c
new file mode 100644
index 0000000000..34c815ea48
--- /dev/null
+++ b/gdk/gdkeventsequence.c
@@ -0,0 +1,85 @@
+/* gdkeventsequence.h - tracking sequences of events
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * 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 "gdkeventsequenceprivate.h"
+
+#include "gdkdeviceprivate.h"
+
+/* XXX: Does not return a reference - should we change that? */
+GdkEventSequence *
+gdk_event_sequence_new (GdkDevice *device,
+ guint sequence_id)
+{
+ GdkEventSequence *sequence = g_slice_new0 (GdkEventSequence);
+
+ /* device owns sequence, so cannot ref device here */
+ sequence->ref_count = 1;
+ sequence->device = device;
+ sequence->sequence_id = sequence_id;
+ sequence->axes = g_new0 (gdouble, gdk_device_get_n_axes (device));
+
+ device->sequences = g_slist_prepend (device->sequences, sequence);
+
+ return sequence;
+}
+
+GdkEventSequence *
+gdk_event_sequence_lookup (GdkDevice *device,
+ guint sequence_id)
+{
+ GSList *list;
+
+ for (list = device->sequences; list; list = list->next)
+ {
+ GdkEventSequence *sequence = list->data;
+
+ if (sequence->sequence_id == sequence_id)
+ return sequence;
+ }
+
+ return NULL;
+}
+
+GdkEventSequence *
+gdk_event_sequence_ref (GdkEventSequence *sequence)
+{
+ sequence->ref_count++;
+
+ return sequence;
+}
+
+void
+gdk_event_sequence_unref (GdkEventSequence *sequence)
+{
+ sequence->ref_count--;
+ if (sequence->ref_count > 0)
+ return;
+
+ if (sequence->device)
+ {
+ GdkDevice *device = sequence->device;
+
+ device->sequences = g_slist_remove (device->sequences, sequence);
+ }
+
+ g_free (sequence->axes);
+ g_slice_free (GdkEventSequence, sequence);
+}
diff --git a/gdk/gdkeventsequenceprivate.h b/gdk/gdkeventsequenceprivate.h
new file mode 100644
index 0000000000..7352042c74
--- /dev/null
+++ b/gdk/gdkeventsequenceprivate.h
@@ -0,0 +1,44 @@
+/* gdkeventsequence.h - tracking sequences of events
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * 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.
+ */
+
+#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
+#error "Only <gdk/gdk.h> can be included directly."
+#endif
+
+#ifndef __GDK_EVENT_SEQUENCE_H__
+#define __GDK_EVENT_SEQUENCE_H__
+
+#include <gdk/gdktypes.h>
+
+struct _GdkEventSequence {
+ GdkDevice *device;
+ guint sequence_id;
+ guint ref_count;
+ double *axes;
+};
+
+GdkEventSequence * gdk_event_sequence_new (GdkDevice *device,
+ guint sequence_id);
+GdkEventSequence * gdk_event_sequence_lookup (GdkDevice *device,
+ guint sequence_id);
+
+GdkEventSequence * gdk_event_sequence_ref (GdkEventSequence *sequence);
+void gdk_event_sequence_unref (GdkEventSequence *sequence);
+
+#endif /* __GDK_EVENT_SEQUENCE_H__ */
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 72f0a18ee3..b54065d8b4 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -29,6 +29,7 @@
#include "gdkwindow.h"
+#include "gdkeventsequenceprivate.h"
#include "gdkrectangle.h"
#include "gdkinternals.h"
#include "gdkintl.h"
@@ -9483,7 +9484,7 @@ proxy_pointer_event (GdkDisplay *display,
{
event->touch.time = time_;
event->touch.state = state | GDK_BUTTON1_MASK;
- event->touch.sequence = source_event->touch.sequence;
+ event->touch.sequence = gdk_event_sequence_ref (source_event->touch.sequence);
event->touch.emulating_pointer = source_event->touch.emulating_pointer;
convert_toplevel_coords_to_window (event_win,
toplevel_x, toplevel_y,
@@ -9772,7 +9773,7 @@ proxy_button_event (GdkEvent *source_event,
event->touch.device = source_event->touch.device;
event->touch.axes = g_memdup (source_event->touch.axes,
sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
- event->touch.sequence = source_event->touch.sequence;
+ event->touch.sequence = gdk_event_sequence_ref (source_event->touch.sequence);
event->touch.emulating_pointer = source_event->touch.emulating_pointer;
gdk_event_set_source_device (event, source_device);
diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c
index eba600e504..758152d3b5 100644
--- a/gdk/x11/gdkdevicemanager-xi2.c
+++ b/gdk/x11/gdkdevicemanager-xi2.c
@@ -23,6 +23,7 @@
#include "gdkdevicemanagerprivate-core.h"
#include "gdkdeviceprivate.h"
#include "gdkdisplayprivate.h"
+#include "gdkeventsequenceprivate.h"
#include "gdkeventtranslator.h"
#include "gdkprivate-x11.h"
#include "gdkintl.h"
@@ -1424,6 +1425,20 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GUINT_TO_POINTER (xev->sourceid));
gdk_event_set_source_device (event, source_device);
+ event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
+
+ if (ev->evtype == XI_TouchBegin)
+ {
+ event->touch.state |= GDK_BUTTON1_MASK;
+ event->touch.sequence = gdk_event_sequence_new (event->touch.device, xev->detail);
+ gdk_event_sequence_ref (event->touch.sequence);
+ }
+ else
+ {
+ /* no ref here, we want the sequence to go away with the event */
+ event->touch.sequence = gdk_event_sequence_lookup (event->touch.device, xev->detail);
+ }
+
event->touch.axes = translate_axes (event->touch.device,
event->touch.x,
event->touch.y,
@@ -1439,13 +1454,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
gdk_device_get_axis (device, event->touch.axes, GDK_AXIS_Y, &event->touch.y);
}
- event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
-
- if (ev->evtype == XI_TouchBegin)
- event->touch.state |= GDK_BUTTON1_MASK;
-
- event->touch.sequence = GUINT_TO_POINTER (xev->detail);
-
if (xev->flags & XITouchEmulatingPointer)
{
event->touch.emulating_pointer = TRUE;
@@ -1478,7 +1486,6 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
xev->flags & XITouchEmulatingPointer));
event->touch.window = window;
- event->touch.sequence = GUINT_TO_POINTER (xev->detail);
event->touch.type = GDK_TOUCH_UPDATE;
event->touch.time = xev->time;
event->touch.x = (gdouble) xev->event_x;
@@ -1493,6 +1500,9 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator,
GUINT_TO_POINTER (xev->sourceid));
gdk_event_set_source_device (event, source_device);
+ event->touch.sequence = gdk_event_sequence_lookup (event->touch.device, xev->detail);
+ gdk_event_sequence_ref (event->touch.sequence);
+
event->touch.state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
event->touch.state |= GDK_BUTTON1_MASK;