gl/x11: use xcb instead of libX11
authorMatthew Waters <matthew@centricular.com>
Thu, 30 Jun 2016 14:07:23 +0000 (00:07 +1000)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:32:24 +0000 (19:32 +0000)
- xcb is supposedly thread-safe!

videotestsrc ! glimagesink now doesn't spuriously result in a
'call XInitThreads()' error however if anybody else is using X11,
then XInitThreads() still needs to be called and multiple glimagesink's
still need XInitThreads().

Everything still takes libX11 handles as they are compatible with the xcb
variants.  Unfortunately we cannot move fully over to xcb due to GLX being
entirely based on Xlib.  It's also impossible to transform a xcb_connection
to a Display which means we require X11 handles.

gst-libs/gst/gl/x11/Makefile.am
gst-libs/gst/gl/x11/gstgldisplay_x11.c
gst-libs/gst/gl/x11/gstgldisplay_x11.h
gst-libs/gst/gl/x11/gstglwindow_x11.c
gst-libs/gst/gl/x11/x11_event_source.c [deleted file]
gst-libs/gst/gl/x11/x11_event_source.h [deleted file]
gst-libs/gst/gl/x11/xcb_event_source.c [new file with mode: 0644]
gst-libs/gst/gl/x11/xcb_event_source.h [new file with mode: 0644]

index e575caee3963f1b585a70d83d82114d89eb241ad..d47d16f6d2cf958ca3d3e42afacea2d396b3b4be 100644 (file)
@@ -5,11 +5,11 @@ noinst_LTLIBRARIES = libgstgl-x11.la
 libgstgl_x11_la_SOURCES = \
        gstgldisplay_x11.c \
        gstglwindow_x11.c \
-       x11_event_source.c
+       xcb_event_source.c
 
 noinst_HEADERS = \
        gstglwindow_x11.h \
-       x11_event_source.h
+       xcb_event_source.h
 
 libgstgl_x11includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/x11
 libgstgl_x11include_HEADERS = \
index 696929eb8ec9b13692e5ce74fde215c0d87e7d33..92101d45e0a9f020f5755108ff25be77da99ca16 100644 (file)
@@ -23,6 +23,8 @@
 #endif
 
 #include <gst/gl/x11/gstgldisplay_x11.h>
+#include <gst/gl/x11/gstglwindow_x11.h>
+#include "xcb_event_source.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_gl_display_debug);
 #define GST_CAT_DEFAULT gst_gl_display_debug
@@ -32,6 +34,10 @@ G_DEFINE_TYPE (GstGLDisplayX11, gst_gl_display_x11, GST_TYPE_GL_DISPLAY);
 static void gst_gl_display_x11_finalize (GObject * object);
 static guintptr gst_gl_display_x11_get_handle (GstGLDisplay * display);
 
+gboolean gst_gl_display_x11_handle_event (GstGLDisplayX11 * display_x11);
+extern gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11,
+    xcb_generic_event_t * event);
+
 static void
 gst_gl_display_x11_class_init (GstGLDisplayX11Class * klass)
 {
@@ -58,6 +64,7 @@ gst_gl_display_x11_finalize (GObject * object)
   g_free (display_x11->name);
 
   if (!display_x11->foreign_display && display_x11->display) {
+    XSync (display_x11->display, FALSE);
     XCloseDisplay (display_x11->display);
   }
 
@@ -86,8 +93,23 @@ gst_gl_display_x11_new (const gchar * name)
 
   if (!ret->display) {
     GST_ERROR ("Failed to open X11 display connection with name, \'%s\'", name);
+    gst_object_unref (ret);
+    return NULL;
+  }
+
+  ret->xcb_connection = XGetXCBConnection (ret->display);
+  if (!ret->xcb_connection) {
+    GST_ERROR ("Failed to open retieve XCB connection from X11 Display");
+    gst_object_unref (ret);
+    return NULL;
   }
 
+  XSetEventQueueOwner (ret->display, XCBOwnsEventQueue);
+
+  GST_GL_DISPLAY (ret)->event_source = xcb_event_source_new (ret);
+  g_source_attach (GST_GL_DISPLAY (ret)->event_source,
+      GST_GL_DISPLAY (ret)->main_context);
+
   return ret;
 }
 
@@ -112,6 +134,14 @@ gst_gl_display_x11_new_with_display (Display * display)
 
   ret->name = g_strdup (DisplayString (display));
   ret->display = display;
+
+  ret->xcb_connection = XGetXCBConnection (ret->display);
+  if (!ret->xcb_connection) {
+    GST_ERROR ("Failed to open retieve XCB connection from X11 Display");
+    gst_object_unref (ret);
+    return NULL;
+  }
+
   ret->foreign_display = TRUE;
 
   return ret;
@@ -122,3 +152,85 @@ gst_gl_display_x11_get_handle (GstGLDisplay * display)
 {
   return (guintptr) GST_GL_DISPLAY_X11 (display)->display;
 }
+
+static int
+_compare_xcb_window (GstGLWindowX11 * window_x11, xcb_window_t * window_id)
+{
+  return window_x11->internal_win_id - *window_id;
+}
+
+static GstGLWindowX11 *
+_find_window_from_xcb_window (GstGLDisplayX11 * display_x11,
+    xcb_window_t window_id)
+{
+  GstGLDisplay *display = GST_GL_DISPLAY (display_x11);
+  GstGLWindowX11 *ret = NULL;
+  GList *l;
+
+  if (!window_id)
+    return NULL;
+
+  GST_OBJECT_LOCK (display);
+  l = g_list_find_custom (display->windows, &window_id,
+      (GCompareFunc) _compare_xcb_window);
+  if (l)
+    ret = gst_object_ref (l->data);
+  GST_OBJECT_UNLOCK (display);
+
+  return ret;
+}
+
+static GstGLWindowX11 *
+_window_from_event (GstGLDisplayX11 * display_x11, xcb_generic_event_t * event)
+{
+  uint8_t event_code = event->response_type & 0x7f;
+
+  switch (event_code) {
+/* *INDENT-OFF* */
+#define WIN_FROM_EVENT(case_val,event_type,window_field) \
+    case case_val:{ \
+      event_type * real_event = (event_type *) event; \
+      return _find_window_from_xcb_window (display_x11, real_event->window_field); \
+    }
+    WIN_FROM_EVENT (XCB_CLIENT_MESSAGE, xcb_client_message_event_t, window)
+    WIN_FROM_EVENT (XCB_CONFIGURE_NOTIFY, xcb_configure_notify_event_t, window)
+    WIN_FROM_EVENT (XCB_EXPOSE, xcb_expose_event_t, window)
+    WIN_FROM_EVENT (XCB_KEY_PRESS, xcb_key_press_event_t, event)
+    WIN_FROM_EVENT (XCB_KEY_RELEASE, xcb_key_release_event_t, event)
+    WIN_FROM_EVENT (XCB_BUTTON_PRESS, xcb_button_press_event_t, event)
+    WIN_FROM_EVENT (XCB_BUTTON_RELEASE, xcb_button_release_event_t, event)
+    WIN_FROM_EVENT (XCB_MOTION_NOTIFY, xcb_motion_notify_event_t, event)
+#undef WIN_FROM_EVENT
+/* *INDENT-ON* */
+    default:
+      return NULL;
+  }
+}
+
+gboolean
+gst_gl_display_x11_handle_event (GstGLDisplayX11 * display_x11)
+{
+  xcb_connection_t *connection = display_x11->xcb_connection;
+  xcb_generic_event_t *event;
+  gboolean ret = TRUE;
+
+  while ((event = xcb_poll_for_event (connection))) {
+    GstGLWindowX11 *window_x11 = _window_from_event (display_x11, event);
+
+    GST_TRACE_OBJECT (display_x11, "got event %p to window %" GST_PTR_FORMAT,
+        event, window_x11);
+
+    if (window_x11) {
+      ret = gst_gl_window_x11_handle_event (window_x11, event);
+    } else {
+      /* unknown window, ignore */
+      ret = TRUE;
+    }
+
+    if (window_x11)
+      gst_object_unref (window_x11);
+    g_free (event);
+  }
+
+  return ret;
+}
index 29624745611b780d4618346c7df53e203a7e5fd8..b6bac8b42db970bb03224ef210d51c605849a28a 100644 (file)
@@ -23,8 +23,7 @@
 
 #include <gst/gst.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include <X11/Xlib-xcb.h>
 
 #include <gst/gl/gstgl_fwd.h>
 #include <gst/gl/gstgldisplay.h>
@@ -56,6 +55,7 @@ struct _GstGLDisplayX11
   /* <private> */
   gchar *name;
   Display *display;
+  xcb_connection_t *xcb_connection;
   gboolean foreign_display;
 
   gpointer _padding[GST_PADDING];
index b17a918530974856284d3dfc305ecb0a732e239a..800315a33b2731a68ef041ca3411da9e7ef2860d 100644 (file)
@@ -28,7 +28,6 @@
 #include <gst/gst.h>
 #include <locale.h>
 
-#include "x11_event_source.h"
 #include "gstglwindow_x11.h"
 #include "gstgldisplay_x11.h"
 /* for XkbKeycodeToKeysym */
 #define gst_gl_window_x11_parent_class parent_class
 G_DEFINE_TYPE (GstGLWindowX11, gst_gl_window_x11, GST_TYPE_GL_WINDOW);
 
+gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11,
+    xcb_generic_event_t * event);
+
 /* X error trap */
 static int TrappedErrorCode = 0;
 static int (*old_error_handler) (Display *, XErrorEvent *);
 
-gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11);
-
 enum
 {
   ARG_0,
@@ -139,8 +139,8 @@ gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
   GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
   GstGLDisplayX11 *display_x11 = (GstGLDisplayX11 *) window->display;
 
-  window_x11->device = XOpenDisplay (display_x11->name);
-//  window_x11->device = display_x11->display;
+  window_x11->device = display_x11->display;
+//  window_x11->device = XOpenDisplay (display_x11->name);
   if (window_x11->device == NULL) {
     g_set_error (error, GST_GL_WINDOW_ERROR,
         GST_GL_WINDOW_ERROR_RESOURCE_UNAVAILABLE,
@@ -148,8 +148,6 @@ gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
     goto failure;
   }
 
-  XSynchronize (window_x11->device, FALSE);
-
   GST_LOG ("gl device id: %ld", (gulong) window_x11->device);
 
   window_x11->screen = DefaultScreenOfDisplay (window_x11->device);
@@ -168,18 +166,9 @@ gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
   window_x11->device_height =
       DisplayHeight (window_x11->device, window_x11->screen_num);
 
-  if (!GST_GL_WINDOW_CLASS (parent_class)->open (window, error))
-    return FALSE;
-
-  if (!display_x11->foreign_display) {
-    window_x11->x11_source = x11_event_source_new (window_x11);
-    g_source_attach (window_x11->x11_source,
-        g_main_context_get_thread_default ());
-  }
-
   window_x11->allow_extra_expose_events = TRUE;
 
-  return TRUE;
+  return GST_GL_WINDOW_CLASS (parent_class)->open (window, error);
 
 failure:
   return FALSE;
@@ -265,39 +254,18 @@ void
 gst_gl_window_x11_close (GstGLWindow * window)
 {
   GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
-  GstGLDisplay *display = window->display;
-  XEvent event;
 
   if (window_x11->device) {
-    /* Avoid BadDrawable Errors... */
-    if (gst_gl_display_get_handle_type (display) & GST_GL_DISPLAY_TYPE_X11)
-      XSync (GST_GL_DISPLAY_X11 (display)->display, FALSE);
-
-    if (window_x11->internal_win_id)
+    if (window_x11->internal_win_id) {
       XUnmapWindow (window_x11->device, window_x11->internal_win_id);
 
-    XFree (window_x11->visual_info);
-
-    if (window_x11->internal_win_id) {
-      XReparentWindow (window_x11->device, window_x11->internal_win_id,
-          window_x11->root, 0, 0);
       XDestroyWindow (window_x11->device, window_x11->internal_win_id);
     }
-    XSync (window_x11->device, FALSE);
-
-    while (XPending (window_x11->device))
-      XNextEvent (window_x11->device, &event);
+    XFree (window_x11->visual_info);
 
-    XCloseDisplay (window_x11->device);
     GST_DEBUG ("display receiver closed");
   }
 
-  if (window_x11->x11_source) {
-    g_source_destroy (window_x11->x11_source);
-    g_source_unref (window_x11->x11_source);
-    window_x11->x11_source = NULL;
-  }
-
   window_x11->running = FALSE;
 
   GST_GL_WINDOW_CLASS (parent_class)->close (window);
@@ -308,24 +276,25 @@ void
 gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
 {
   GstGLWindowX11 *window_x11;
-  XWindowAttributes attr;
+  gint width, height;
 
   window_x11 = GST_GL_WINDOW_X11 (window);
 
   window_x11->parent_win = (Window) id;
 
-  /* XXX: seems to be needed for the difference between gtk videooverlay and
-   * the embedding gl into gtk directly */
-  if (id && !window_x11->x11_source) {
-    window_x11->x11_source = x11_event_source_new (window_x11);
-    g_source_attach (window_x11->x11_source,
-        g_main_context_get_thread_default ());
-  }
+  if (window_x11->parent_win) {
+    XWindowAttributes attr;
 
-  XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr);
+    XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr);
+    width = attr.width;
+    height = attr.height;
+  } else {
+    width = window_x11->priv->preferred_width;
+    height = window_x11->priv->preferred_height;
+  }
 
   XResizeWindow (window_x11->device, window_x11->internal_win_id,
-      attr.width, attr.height);
+      width, height);
 
   XReparentWindow (window_x11->device, window_x11->internal_win_id,
       window_x11->parent_win, 0, 0);
@@ -359,21 +328,15 @@ _show_window (GstGLWindow * window)
   GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (window);
   guint width = window_x11->priv->preferred_width;
   guint height = window_x11->priv->preferred_height;
-  XWindowAttributes attr;
-
-  XGetWindowAttributes (window_x11->device, window_x11->internal_win_id, &attr);
 
   if (!window_x11->visible) {
-
     if (!window_x11->parent_win) {
-      attr.width = width;
-      attr.height = height;
       XResizeWindow (window_x11->device, window_x11->internal_win_id,
-          attr.width, attr.height);
-      XSync (window_x11->device, FALSE);
+          width, height);
     }
 
     XMapWindow (window_x11->device, window_x11->internal_win_id);
+    XSync (window_x11->device, FALSE);
     window_x11->visible = TRUE;
   }
 }
@@ -384,6 +347,17 @@ gst_gl_window_x11_show (GstGLWindow * window)
   gst_gl_window_send_message (window, (GstGLWindowCB) _show_window, window);
 }
 
+static void
+_context_draw (GstGLContext * context, GstGLWindow * window)
+{
+  GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
+
+  window->draw (window->draw_data);
+  context_class->swap_buffers (context);
+
+  gst_object_unref (context);
+}
+
 static void
 draw_cb (gpointer data)
 {
@@ -396,11 +370,14 @@ draw_cb (gpointer data)
 
     XGetWindowAttributes (window_x11->device, window_x11->internal_win_id,
         &attr);
+    GST_TRACE_OBJECT (window, "window size %ux%u", attr.width, attr.height);
 
     if (window_x11->parent_win) {
       XWindowAttributes attr_parent;
       XGetWindowAttributes (window_x11->device, window_x11->parent_win,
           &attr_parent);
+      GST_TRACE_OBJECT (window, "parent window size %ux%u", attr_parent.width,
+          attr_parent.height);
 
       if (attr.width != attr_parent.width || attr.height != attr_parent.height) {
         XMoveResizeWindow (window_x11->device, window_x11->internal_win_id,
@@ -428,12 +405,8 @@ draw_cb (gpointer data)
 
       if (window->draw) {
         GstGLContext *context = gst_gl_window_get_context (window);
-        GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context);
 
-        window->draw (window->draw_data);
-        context_class->swap_buffers (context);
-
-        gst_object_unref (context);
+        _context_draw (context, window);
       }
     }
   }
@@ -514,125 +487,105 @@ gst_gl_window_x11_handle_events (GstGLWindow * window, gboolean handle_events)
 }
 
 gboolean
-gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
+gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11,
+    xcb_generic_event_t * event)
 {
-  GstGLContext *context;
-  GstGLContextClass *context_class;
-  GstGLWindow *window;
-  gboolean ret = TRUE;
-
-  window = GST_GL_WINDOW (window_x11);
-
-  if (gst_gl_window_is_running (window)
-      && XPending (window_x11->device)) {
-    XEvent event;
-
-    /* XSendEvent (which are called in other threads) are done from another display structure */
-    XNextEvent (window_x11->device, &event);
-
-    window_x11->allow_extra_expose_events = XPending (window_x11->device) <= 2;
-
-    GST_LOG ("got event %s", event_type_to_string (event.type));
+  GstGLWindow *window = GST_GL_WINDOW (window_x11);
+  GstGLDisplayX11 *display_x11 = GST_GL_DISPLAY_X11 (window->display);
+  xcb_connection_t *connection = display_x11->xcb_connection;
+  uint8_t event_code = event->response_type & 0x7f;
 
-    switch (event.type) {
-      case ClientMessage:
-      {
-        Atom wm_delete =
-            XInternAtom (window_x11->device, "WM_DELETE_WINDOW", True);
+  switch (event_code) {
+    case XCB_CLIENT_MESSAGE:{
+      xcb_client_message_event_t *client_event;
+      xcb_intern_atom_cookie_t cookie;
+      xcb_intern_atom_reply_t *reply;
 
-        if (wm_delete == None)
-          GST_DEBUG ("Cannot create WM_DELETE_WINDOW");
+      client_event = (xcb_client_message_event_t *) event;
+      cookie = xcb_intern_atom (connection, 0, 16, "WM_DELETE_WINDOW");
+      reply = xcb_intern_atom_reply (connection, cookie, 0);
 
-        /* User clicked on the cross */
-        if (wm_delete != None && (Atom) event.xclient.data.l[0] == wm_delete) {
-          GST_DEBUG ("Close %lud", (gulong) window_x11->internal_win_id);
+      if (client_event->data.data32[0] == reply->atom) {
+        GST_INFO_OBJECT (window_x11, "Close requested");
 
-          if (window->close)
-            window->close (window->close_data);
+        if (window->close)
+          window->close (window->close_data);
 
-          ret = FALSE;
-        }
-        break;
+        gst_gl_display_remove_window (GST_GL_DISPLAY (display_x11),
+            GST_GL_WINDOW (window_x11));
       }
 
-      case CreateNotify:
-      case ConfigureNotify:
-      {
-        gst_gl_window_resize (window, event.xconfigure.width,
-            event.xconfigure.height);
-        break;
-      }
+      g_free (reply);
+      break;
+    }
+    case XCB_CONFIGURE_NOTIFY:{
+      xcb_configure_notify_event_t *configure_event;
 
-      case DestroyNotify:
-        break;
+      configure_event = (xcb_configure_notify_event_t *) event;
 
-      case Expose:
-        /* non-zero means that other Expose follows
-         * so just wait for the last one
-         * in theory we should not receive non-zero because
-         * we have no sub areas here but just in case */
-        if (event.xexpose.count != 0) {
-          break;
-        }
-
-        /* We need to redraw on expose */
-        if (window->draw) {
-          context = gst_gl_window_get_context (window);
-          context_class = GST_GL_CONTEXT_GET_CLASS (context);
-
-          window->draw (window->draw_data);
-          context_class->swap_buffers (context);
-
-          gst_object_unref (context);
-        }
-        break;
+      gst_gl_window_resize (window, configure_event->width,
+          configure_event->height);
 
-      case VisibilityNotify:
-        /* actually nothing to do here */
-        break;
-      case KeyPress:
-      case KeyRelease:
-      {
-        const char *key_str = NULL, *key_type = NULL;
-        KeySym keysym;
-
-        keysym = XkbKeycodeToKeysym (window_x11->device,
-            event.xkey.keycode, 0, 0);
-        key_str = XKeysymToString (keysym);
-        key_type = event.type == KeyPress ? "key-press" : "key-release";
-        GST_DEBUG ("input event key %d %s over window at %d,%d (%s)",
-            event.xkey.keycode, key_type, event.xkey.x, event.xkey.y, key_str);
-        gst_gl_window_send_key_event_async (window, key_type, key_str);
+      gst_gl_window_draw (window);
+      break;
+    }
+    case XCB_EXPOSE:{
+      xcb_expose_event_t *expose_event = (xcb_expose_event_t *) event;
+      /* non-zero means that other Expose follows
+       * so just wait for the last one
+       * in theory we should not receive non-zero because
+       * we have no sub areas here but just in case */
+      if (expose_event->count != 0)
         break;
-      }
-      case ButtonPress:
-      case ButtonRelease:{
-        const char *mouse_type = NULL;
-
-        mouse_type = event.type ==
-            ButtonPress ? "mouse-button-press" : "mouse-button-release";
 
-        GST_DEBUG ("input event mouse button %d %s over window at %d,%d",
-            event.xbutton.button, mouse_type, event.xbutton.x, event.xbutton.y);
-
-        gst_gl_window_send_mouse_event_async (window, mouse_type,
-            event.xbutton.button, event.xbutton.x, event.xbutton.y);
-        break;
-      }
-      case MotionNotify:
-        GST_DEBUG ("input event pointer moved over window at %d,%d",
-            event.xmotion.x, event.xmotion.y);
+      gst_gl_window_draw (window);
+      break;
+    }
+    case XCB_KEY_PRESS:
+    case XCB_KEY_RELEASE:{
+      xcb_key_press_event_t *kp = (xcb_key_press_event_t *) event;
+      const gchar *event_type_str;
+      gchar *key_str;
+      KeySym keysym;
+
+      keysym = XkbKeycodeToKeysym (window_x11->device, kp->detail, 0, 0);
+      key_str = XKeysymToString (keysym);
+
+      if (event_code == XCB_KEY_PRESS)
+        event_type_str = "key-press";
+      else
+        event_type_str = "key-release";
+
+      gst_gl_window_send_key_event (window, event_type_str, key_str);
+      break;
+    }
+    case XCB_BUTTON_PRESS:
+    case XCB_BUTTON_RELEASE:{
+      xcb_button_press_event_t *bp = (xcb_button_press_event_t *) event;
+      const gchar *event_type_str;
+
+      if (event_code == XCB_BUTTON_PRESS)
+        event_type_str = "mouse-button-press";
+      else
+        event_type_str = "mouse-button-release";
+
+      gst_gl_window_send_mouse_event (window, event_type_str, bp->detail,
+          (double) bp->event_x, (double) bp->event_y);
+      break;
+    }
+    case XCB_MOTION_NOTIFY:{
+      xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *) event;
 
-        gst_gl_window_send_mouse_event_async (window, "mouse-move", 0,
-            event.xbutton.x, event.xbutton.y);
-        break;
-      default:
-        GST_DEBUG ("unknown XEvent type: %u", event.type);
-        break;
-    }                           // switch
-  }                             // while running
+      gst_gl_window_send_mouse_event (window, "mouse-move", 0,
+          (double) motion->event_x, (double) motion->event_y);
+      break;
+    }
+    default:
+      GST_TRACE ("unhandled XCB event: %u", event_code);
+      break;
+  }
 
-  return ret;
+  return TRUE;
 }
 
 static int
diff --git a/gst-libs/gst/gl/x11/x11_event_source.c b/gst-libs/gst/gl/x11/x11_event_source.c
deleted file mode 100644 (file)
index df6413a..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "x11_event_source.h"
-#include "gstgldisplay_x11.h"
-
-extern gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11);
-
-typedef struct _X11EventSource
-{
-  GSource source;
-  GPollFD pfd;
-  uint32_t mask;
-  GstGLWindowX11 *window;
-} X11EventSource;
-
-static gboolean
-x11_event_source_prepare (GSource * base, gint * timeout)
-{
-  X11EventSource *source = (X11EventSource *) base;
-  gboolean retval;
-
-  *timeout = -1;
-
-  retval = XPending (source->window->device);
-
-  return retval;
-}
-
-static gboolean
-x11_event_source_check (GSource * base)
-{
-  X11EventSource *source = (X11EventSource *) base;
-  gboolean retval;
-
-  retval = source->pfd.revents;
-
-  return retval;
-}
-
-static gboolean
-x11_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
-{
-  X11EventSource *source = (X11EventSource *) base;
-
-  gboolean ret = gst_gl_window_x11_handle_event (source->window);
-
-  if (callback)
-    callback (data);
-
-  return ret;
-}
-
-static GSourceFuncs x11_event_source_funcs = {
-  x11_event_source_prepare,
-  x11_event_source_check,
-  x11_event_source_dispatch,
-  NULL
-};
-
-GSource *
-x11_event_source_new (GstGLWindowX11 * window_x11)
-{
-  X11EventSource *source;
-
-  source = (X11EventSource *)
-      g_source_new (&x11_event_source_funcs, sizeof (X11EventSource));
-  source->window = window_x11;
-  source->pfd.fd = ConnectionNumber (source->window->device);
-  source->pfd.events = G_IO_IN | G_IO_ERR;
-  g_source_add_poll (&source->source, &source->pfd);
-
-  return &source->source;
-}
diff --git a/gst-libs/gst/gl/x11/x11_event_source.h b/gst-libs/gst/gl/x11/x11_event_source.h
deleted file mode 100644 (file)
index 39f79f0..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * GStreamer
- * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef __X11_EVENT_SOURCE_H__
-#define __X11_EVENT_SOURCE_H__
-
-#include <glib-object.h>
-#include "gstglwindow_x11.h"
-
-GSource *
-x11_event_source_new (GstGLWindowX11 *window_x11);
-
-#endif /* __WAYLAND_EVENT_SOURCE_H__ */
diff --git a/gst-libs/gst/gl/x11/xcb_event_source.c b/gst-libs/gst/gl/x11/xcb_event_source.c
new file mode 100644 (file)
index 0000000..4077223
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * GStreamer
+ * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "xcb_event_source.h"
+#include "gstgldisplay_x11.h"
+#include "gstglwindow_x11.h"
+
+extern gboolean gst_gl_display_x11_handle_event (GstGLDisplayX11 * display_x11);
+
+typedef struct _XCBEventSource
+{
+  GSource source;
+  GPollFD pfd;
+  uint32_t mask;
+  GstGLDisplayX11 *display_x11;
+} XCBEventSource;
+
+static gboolean
+xcb_event_source_prepare (GSource * base, gint * timeout)
+{
+  XCBEventSource *source = (XCBEventSource *) base;
+
+  xcb_flush (source->display_x11->xcb_connection);
+
+  *timeout = -1;
+  return FALSE;
+}
+
+static gboolean
+xcb_event_source_check (GSource * base)
+{
+  XCBEventSource *source = (XCBEventSource *) base;
+  gboolean retval;
+
+  retval = source->pfd.revents;
+
+  return retval;
+}
+
+static gboolean
+xcb_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
+{
+  XCBEventSource *source = (XCBEventSource *) base;
+
+  gboolean ret = gst_gl_display_x11_handle_event (source->display_x11);
+
+  source->pfd.revents = 0;
+
+  if (callback)
+    callback (data);
+
+  return ret;
+}
+
+static GSourceFuncs xcb_event_source_funcs = {
+  xcb_event_source_prepare,
+  xcb_event_source_check,
+  xcb_event_source_dispatch,
+  NULL
+};
+
+GSource *
+xcb_event_source_new (GstGLDisplayX11 * display_x11)
+{
+  xcb_connection_t *connection;
+  XCBEventSource *source;
+
+  connection = display_x11->xcb_connection;
+  g_return_val_if_fail (connection != NULL, NULL);
+
+  source = (XCBEventSource *)
+      g_source_new (&xcb_event_source_funcs, sizeof (XCBEventSource));
+  source->display_x11 = display_x11;
+  source->pfd.fd = xcb_get_file_descriptor (connection);
+  source->pfd.events = G_IO_IN | G_IO_ERR;
+  g_source_add_poll (&source->source, &source->pfd);
+
+  return &source->source;
+}
diff --git a/gst-libs/gst/gl/x11/xcb_event_source.h b/gst-libs/gst/gl/x11/xcb_event_source.h
new file mode 100644 (file)
index 0000000..ba47635
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * GStreamer
+ * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __XCB_EVENT_SOURCE_H__
+#define __XCB_EVENT_SOURCE_H__
+
+#include <glib-object.h>
+#include "gstgldisplay_x11.h"
+
+GSource * xcb_event_source_new (GstGLDisplayX11 *display_x11);
+
+#endif /* __XCB_EVENT_SOURCE_H__ */