[clutter] x11: Improve XGenericEventCookie data allocation



commit 075a4ed86c468b9f1bcb7d864ea678df25e7438b
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jul 14 21:58:25 2011 +0200

    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 5cd53bb..28e0ba2 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 ac3c502..432ae9f 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 227401a..8fc034c 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}"



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]