From 075a4ed86c468b9f1bcb7d864ea678df25e7438b Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 14 Jul 2011 21:58:25 +0200 Subject: [PATCH] x11: Improve XGenericEventCookie data allocation https://bugzilla.gnome.org/show_bug.cgi?id=654656 Clutter may be used together with GTK+, which indirectly may use XInput2 too, so the cookie data must persist when both are handling events. What happens now in a nutshell is, Clutter is only guaranteed to allocate the cookie itself after XNextEvent(), and only frees the cookie if its XGetEventData() call allocated the cookie data. The X[Get|Free]EventData() calls happen now in clutter-event-x11.c as hypothetically different event translators could also handle other set of X Generic Events, or other libraries handling events for that matter. --- clutter/x11/clutter-device-manager-xi2.c | 18 +++++------------- clutter/x11/clutter-event-x11.c | 23 +++++++++++++++++++++++ configure.ac | 18 ++++++++++++++++++ 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/clutter/x11/clutter-device-manager-xi2.c b/clutter/x11/clutter-device-manager-xi2.c index 5cd53bb67..28e0ba200 100644 --- a/clutter/x11/clutter-device-manager-xi2.c +++ b/clutter/x11/clutter-device-manager-xi2.c @@ -562,27 +562,21 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, cookie = &xevent->xcookie; - if (!XGetEventData (backend_x11->xdpy, cookie)) - return CLUTTER_TRANSLATE_CONTINUE; - if (cookie->type != GenericEvent || cookie->extension != manager_xi2->opcode) - { - XFreeEventData (backend_x11->xdpy, cookie); - return CLUTTER_TRANSLATE_CONTINUE; - } + return CLUTTER_TRANSLATE_CONTINUE; xi_event = (XIEvent *) cookie->data; + if (!xi_event) + return CLUTTER_TRANSLATE_REMOVE; + if (!(xi_event->evtype == XI_HierarchyChanged || xi_event->evtype == XI_DeviceChanged)) { stage = get_event_stage (translator, xi_event); if (stage == NULL || CLUTTER_ACTOR_IN_DESTRUCTION (stage)) - { - XFreeEventData (backend_x11->xdpy, cookie); - return CLUTTER_TRANSLATE_CONTINUE; - } + return CLUTTER_TRANSLATE_CONTINUE; else stage_x11 = CLUTTER_STAGE_X11 (_clutter_stage_get_window (stage)); } @@ -902,8 +896,6 @@ clutter_device_manager_xi2_translate_event (ClutterEventTranslator *translator, break; } - XFreeEventData (backend_x11->xdpy, cookie); - return retval; } diff --git a/clutter/x11/clutter-event-x11.c b/clutter/x11/clutter-event-x11.c index ac3c502f3..432ae9f7c 100644 --- a/clutter/x11/clutter-event-x11.c +++ b/clutter/x11/clutter-event-x11.c @@ -240,10 +240,17 @@ events_queue (ClutterBackend *backend) event = clutter_event_new (CLUTTER_NOTHING); +#ifdef HAVE_XGE + XGetEventData (xdisplay, &xevent.xcookie); +#endif if (_clutter_backend_translate_event (backend, &xevent, event)) _clutter_event_push (event, FALSE); else clutter_event_free (event); + +#ifdef HAVE_XGE + XFreeEventData (xdisplay, &xevent.xcookie); +#endif } } @@ -273,8 +280,13 @@ clutter_x11_handle_event (XEvent *xevent) { ClutterX11FilterReturn result; ClutterBackend *backend; + ClutterBackendX11 *backend_x11; + Display *xdisplay; ClutterEvent *event; gint spin = 1; +#ifdef HAVE_XGE + gboolean allocated_event; +#endif /* The return values here are someone approximate; we return * CLUTTER_X11_FILTER_REMOVE if a clutter event is @@ -290,9 +302,15 @@ clutter_x11_handle_event (XEvent *xevent) clutter_threads_enter (); backend = clutter_get_default_backend (); + backend_x11 = CLUTTER_BACKEND_X11 (backend); + xdisplay = backend_x11->xdpy; event = clutter_event_new (CLUTTER_NOTHING); +#ifdef HAVE_XGE + allocated_event = XGetEventData (xdisplay, &xevent->xcookie); +#endif + if (_clutter_backend_translate_event (backend, xevent, event)) { _clutter_event_push (event, FALSE); @@ -323,6 +341,11 @@ clutter_x11_handle_event (XEvent *xevent) } out: +#ifdef HAVE_XGE + if (allocated_event) + XFreeEventData (xdisplay, &xevent->xcookie); +#endif + clutter_threads_leave (); return result; diff --git a/configure.ac b/configure.ac index 227401a0a..8fc034ca9 100644 --- a/configure.ac +++ b/configure.ac @@ -592,6 +592,23 @@ AS_IF([test "x$SUPPORT_XLIB" = "x1"], [AC_MSG_ERROR([not found])] ) + # X Generic Extensions (optional) + clutter_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $X11_CFLAGS" + + clutter_save_LIBS="$LIBS" + LIBS="$LIBS $X11_LIBS" + + have_xge=no + AC_CHECK_FUNC([XGetEventData], + [ + AC_DEFINE(HAVE_XGE, 1, [Define to 1 if X Generic Extensions is available]) + have_xge=yes + ]) + + CPPFLAGS="$clutter_save_CPPFLAGS" + LIBS="$clutter_save_LIBS" + # XI (optional) AC_ARG_ENABLE([xinput], [AS_HELP_STRING([--enable-xinput], [Use the XI X extension])], @@ -1020,6 +1037,7 @@ fi if test "x$SUPPORT_XLIB" = "x1"; then echo " Enable XComposite: ${have_xcomposite}" echo " Enable XInput: ${have_xinput}" +echo " Enable Xge: ${have_xge}" echo " Enable XI2: ${have_xinput2}" echo " Enable XKB: ${have_xkb}" echo " Enable X11 tests: ${x11_tests}"