diff options
author | Attilio Fiandrotti <attilio@src.gnome.org> | 2007-12-06 17:45:05 +0000 |
---|---|---|
committer | Attilio Fiandrotti <attilio@src.gnome.org> | 2007-12-06 17:45:05 +0000 |
commit | 01f8212ad34161eac3949f59a0ca62472177565f (patch) | |
tree | e8a40ea8a4d69ebb8cd0e0d113d3a41c47da4493 | |
parent | fcf39799c7b3c8a74bb56723b2a230bef49fe46f (diff) | |
download | gdk-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-- | ChangeLog | 5 | ||||
-rw-r--r-- | gdk/directfb/gdkevents-directfb.c | 108 |
2 files changed, 110 insertions, 3 deletions
@@ -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) |