summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAttilio Fiandrotti <attilio@src.gnome.org>2007-12-06 17:45:05 +0000
committerAttilio Fiandrotti <attilio@src.gnome.org>2007-12-06 17:45:05 +0000
commit01f8212ad34161eac3949f59a0ca62472177565f (patch)
treee8a40ea8a4d69ebb8cd0e0d113d3a41c47da4493
parentfcf39799c7b3c8a74bb56723b2a230bef49fe46f (diff)
downloadgdk-pixbuf-01f8212ad34161eac3949f59a0ca62472177565f.tar.gz
Committed a patch by DOK to fix GDK events generations in the DirectFB backend
svn path=/trunk/; revision=19122
-rw-r--r--ChangeLog5
-rw-r--r--gdk/directfb/gdkevents-directfb.c108
2 files changed, 110 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 4569cc32d..a8acdc238 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-12-06 18:45:06 Attilio Fiandrotti <attilio.fiandrotti@gmail.com>
+
+ * gdk/directfb/gdkevents-directfb.c: Committed a patch by DOK to fix
+ GDK events generations in the DirectFB backend.
+
2007-12-06 13:55:06 Tim Janik <timj@imendio.com>
* Makefile.decl: replaced seq(1) invokation for X11 ids with a hardcoded
diff --git a/gdk/directfb/gdkevents-directfb.c b/gdk/directfb/gdkevents-directfb.c
index 2f55b26ca..490d17f1d 100644
--- a/gdk/directfb/gdkevents-directfb.c
+++ b/gdk/directfb/gdkevents-directfb.c
@@ -69,13 +69,93 @@ static GdkEvent * gdk_event_translate (DFBWindowEvent *dfbevent,
*/
static GList *client_filters; /* Filters for client messages */
+
+static void
+fixup_event (GdkEvent *event)
+{
+ if (event->any.window)
+ g_object_ref (event->any.window);
+ if (((event->any.type == GDK_ENTER_NOTIFY) ||
+ (event->any.type == GDK_LEAVE_NOTIFY)) &&
+ (event->crossing.subwindow != NULL))
+ g_object_ref (event->crossing.subwindow);
+ event->any.send_event = FALSE;
+}
+
+static GdkFilterReturn
+apply_filters (GdkWindow *window,
+ DFBWindowEvent *dfbevent,
+ GList *filters)
+{
+ GdkFilterReturn result = GDK_FILTER_CONTINUE;
+ GdkEvent *event;
+ GList *node;
+ GList *tmp_list;
+
+ event = gdk_event_new (GDK_NOTHING);
+ if (window != NULL)
+ event->any.window = g_object_ref (window);
+ ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING;
+
+ /* I think GdkFilterFunc semantics require the passed-in event
+ * to already be in the queue. The filter func can generate
+ * more events and append them after it if it likes.
+ */
+ node = _gdk_event_queue_append ((GdkDisplay*)_gdk_display, event);
+
+ tmp_list = filters;
+ while (tmp_list)
+ {
+ GdkEventFilter *filter = (GdkEventFilter *) tmp_list->data;
+
+ tmp_list = tmp_list->next;
+ result = filter->function (dfbevent, event, filter->data);
+ if (result != GDK_FILTER_CONTINUE)
+ break;
+ }
+
+ if (result == GDK_FILTER_CONTINUE || result == GDK_FILTER_REMOVE)
+ {
+ _gdk_event_queue_remove_link ((GdkDisplay*)_gdk_display, node);
+ g_list_free_1 (node);
+ gdk_event_free (event);
+ }
+ else /* GDK_FILTER_TRANSLATE */
+ {
+ ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+ fixup_event (event);
+ }
+ return result;
+}
+
static void
dfb_events_process_window_event (DFBWindowEvent *event)
{
- GdkWindow *window = gdk_directfb_window_id_table_lookup (event->window_id);
+ GdkWindow *window;
+
+ /*
+ * Apply global filters
+ *
+ * If result is GDK_FILTER_CONTINUE, we continue as if nothing
+ * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
+ * we return TRUE and won't dispatch the event.
+ */
+ if (_gdk_default_filters)
+ {
+ switch (apply_filters (NULL, event, _gdk_default_filters))
+ {
+ case GDK_FILTER_REMOVE:
+ case GDK_FILTER_TRANSLATE:
+ return;
- if (! window)
- return;
+ default:
+ break;
+ }
+ }
+
+ window = gdk_directfb_window_id_table_lookup (event->window_id);
+ if (!window)
+ return;
gdk_event_translate (event, window);
}
@@ -379,6 +459,28 @@ gdk_event_translate (DFBWindowEvent *dfbevent,
private = GDK_WINDOW_OBJECT (window);
g_object_ref (G_OBJECT (window));
+
+ /*
+ * Apply per-window filters
+ *
+ * If result is GDK_FILTER_CONTINUE, we continue as if nothing
+ * happened. If it is GDK_FILTER_REMOVE or GDK_FILTER_TRANSLATE,
+ * we return TRUE and won't dispatch the event.
+ */
+ if (private->filters)
+ {
+ switch (apply_filters (window, dfbevent, private->filters))
+ {
+ case GDK_FILTER_REMOVE:
+ case GDK_FILTER_TRANSLATE:
+ g_object_unref (G_OBJECT (window));
+ return NULL;
+
+ default:
+ break;
+ }
+ }
+
display = gdk_drawable_get_display (GDK_DRAWABLE (window));
switch (dfbevent->type)