diff options
author | Benjamin Otte <otte@redhat.com> | 2012-03-05 13:58:00 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2012-03-14 19:32:54 +0100 |
commit | 4da18923c5d01cbc8cd5c0e0ebb7c5f6b5585fe3 (patch) | |
tree | 0012d1bcf3027ec365887521507374eff560ad2e | |
parent | d3cdf494d9f601c921354ad37516bd54079aad1a (diff) | |
download | gtk+-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.am | 2 | ||||
-rw-r--r-- | gdk/gdkdevice.c | 14 | ||||
-rw-r--r-- | gdk/gdkdeviceprivate.h | 1 | ||||
-rw-r--r-- | gdk/gdkevents.c | 3 | ||||
-rw-r--r-- | gdk/gdkeventsequence.c | 85 | ||||
-rw-r--r-- | gdk/gdkeventsequenceprivate.h | 44 | ||||
-rw-r--r-- | gdk/gdkwindow.c | 5 | ||||
-rw-r--r-- | gdk/x11/gdkdevicemanager-xi2.c | 26 |
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; |