summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac18
-rw-r--r--gst-libs/gst/gl/x11/Makefile.am4
-rw-r--r--gst-libs/gst/gl/x11/gstgldisplay_x11.c112
-rw-r--r--gst-libs/gst/gl/x11/gstgldisplay_x11.h4
-rw-r--r--gst-libs/gst/gl/x11/gstglwindow_x11.c287
-rw-r--r--gst-libs/gst/gl/x11/xcb_event_source.c (renamed from gst-libs/gst/gl/x11/x11_event_source.c)59
-rw-r--r--gst-libs/gst/gl/x11/xcb_event_source.h (renamed from gst-libs/gst/gl/x11/x11_event_source.h)11
7 files changed, 282 insertions, 213 deletions
diff --git a/configure.ac b/configure.ac
index e5df43cc0..7cdb1e28f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -692,7 +692,7 @@ AC_ARG_ENABLE([dispmanx],
*) AC_MSG_ERROR([bad value ${enableval} for --enable-dispmanx]) ;;
esac],[NEED_DISPMANX=auto])
-AG_GST_PKG_CHECK_MODULES(X, x11)
+AG_GST_PKG_CHECK_MODULES(X11_XCB, x11-xcb)
save_CPPFLAGS="$CPPFLAGS"
save_LIBS="$LIBS"
@@ -847,7 +847,7 @@ if test "x$HAVE_GLES2" = "xno"; then
fi
dnl X, GLX and OpenGL
-if test "x$HAVE_X" = "xno"; then
+if test "x$HAVE_X11_XCB" = "xno"; then
if test "x$NEED_GLX" = "xyes"; then
AC_MSG_ERROR([Building the GLX backend without X11 is unsupported])
fi
@@ -1002,7 +1002,7 @@ case $host in
AC_MSG_ERROR([WGL is not available on unix])
fi
- if test "x$HAVE_X" = "xno"; then
+ if test "x$HAVE_X11_XCB" = "xno"; then
if test "x$HAVE_WAYLAND_EGL" = "xno"; then
AC_MSG_WARN([X or Wayland is required for OpenGL support])
fi
@@ -1023,10 +1023,10 @@ case $host in
fi
fi
- if test "x$HAVE_X" = "xyes" -a "x$HAVE_EGL_RPI" = "xno"; then
+ if test "x$HAVE_X11_XCB" = "xyes" -a "x$HAVE_EGL_RPI" = "xno"; then
if test "x$NEED_X11" != "xno"; then
- GL_LIBS="$GL_LIBS $X_LIBS"
- GL_CFLAGS="$GL_CFLAGS $X_CFLAGS"
+ GL_LIBS="$GL_LIBS $X11_XCB_LIBS"
+ GL_CFLAGS="$GL_CFLAGS $X11_XCB_CFLAGS"
HAVE_WINDOW_X11=yes
fi
fi
@@ -1110,10 +1110,10 @@ case $host in
fi
if test "x$USE_GLX" = "xyes"; then
- if test "x$HAVE_X" = "xyes"; then
+ if test "x$HAVE_X11_XCB" = "xyes"; then
if test "x$NEED_X11" != "xno"; then
- GL_LIBS="$GL_LIBS $X_LIBS"
- GL_CFLAGS="$GL_CFLAGS $X_CFLAGS"
+ GL_LIBS="$GL_LIBS $X11_XCB_LIBS"
+ GL_CFLAGS="$GL_CFLAGS $X11_XCB_CFLAGS"
HAVE_WINDOW_X11=yes
fi
fi
diff --git a/gst-libs/gst/gl/x11/Makefile.am b/gst-libs/gst/gl/x11/Makefile.am
index e575caee3..d47d16f6d 100644
--- a/gst-libs/gst/gl/x11/Makefile.am
+++ b/gst-libs/gst/gl/x11/Makefile.am
@@ -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 = \
diff --git a/gst-libs/gst/gl/x11/gstgldisplay_x11.c b/gst-libs/gst/gl/x11/gstgldisplay_x11.c
index 696929eb8..92101d45e 100644
--- a/gst-libs/gst/gl/x11/gstgldisplay_x11.c
+++ b/gst-libs/gst/gl/x11/gstgldisplay_x11.c
@@ -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;
+}
diff --git a/gst-libs/gst/gl/x11/gstgldisplay_x11.h b/gst-libs/gst/gl/x11/gstgldisplay_x11.h
index 296247456..b6bac8b42 100644
--- a/gst-libs/gst/gl/x11/gstgldisplay_x11.h
+++ b/gst-libs/gst/gl/x11/gstgldisplay_x11.h
@@ -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];
diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c
index b17a91853..800315a33 100644
--- a/gst-libs/gst/gl/x11/gstglwindow_x11.c
+++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c
@@ -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 */
@@ -42,12 +41,13 @@
#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;
}
}
@@ -385,6 +348,17 @@ gst_gl_window_x11_show (GstGLWindow * 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)
{
GstGLWindowX11 *window_x11 = 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/xcb_event_source.c
index df6413a4f..407722394 100644
--- a/gst-libs/gst/gl/x11/x11_event_source.c
+++ b/gst-libs/gst/gl/x11/xcb_event_source.c
@@ -25,36 +25,35 @@
#include <stdint.h>
#include <stdlib.h>
-#include "x11_event_source.h"
+#include "xcb_event_source.h"
#include "gstgldisplay_x11.h"
+#include "gstglwindow_x11.h"
-extern gboolean gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11);
+extern gboolean gst_gl_display_x11_handle_event (GstGLDisplayX11 * display_x11);
-typedef struct _X11EventSource
+typedef struct _XCBEventSource
{
GSource source;
GPollFD pfd;
uint32_t mask;
- GstGLWindowX11 *window;
-} X11EventSource;
+ GstGLDisplayX11 *display_x11;
+} XCBEventSource;
static gboolean
-x11_event_source_prepare (GSource * base, gint * timeout)
+xcb_event_source_prepare (GSource * base, gint * timeout)
{
- X11EventSource *source = (X11EventSource *) base;
- gboolean retval;
-
- *timeout = -1;
+ XCBEventSource *source = (XCBEventSource *) base;
- retval = XPending (source->window->device);
+ xcb_flush (source->display_x11->xcb_connection);
- return retval;
+ *timeout = -1;
+ return FALSE;
}
static gboolean
-x11_event_source_check (GSource * base)
+xcb_event_source_check (GSource * base)
{
- X11EventSource *source = (X11EventSource *) base;
+ XCBEventSource *source = (XCBEventSource *) base;
gboolean retval;
retval = source->pfd.revents;
@@ -63,11 +62,13 @@ x11_event_source_check (GSource * base)
}
static gboolean
-x11_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
+xcb_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
{
- X11EventSource *source = (X11EventSource *) base;
+ XCBEventSource *source = (XCBEventSource *) base;
+
+ gboolean ret = gst_gl_display_x11_handle_event (source->display_x11);
- gboolean ret = gst_gl_window_x11_handle_event (source->window);
+ source->pfd.revents = 0;
if (callback)
callback (data);
@@ -75,22 +76,26 @@ x11_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
return ret;
}
-static GSourceFuncs x11_event_source_funcs = {
- x11_event_source_prepare,
- x11_event_source_check,
- x11_event_source_dispatch,
+static GSourceFuncs xcb_event_source_funcs = {
+ xcb_event_source_prepare,
+ xcb_event_source_check,
+ xcb_event_source_dispatch,
NULL
};
GSource *
-x11_event_source_new (GstGLWindowX11 * window_x11)
+xcb_event_source_new (GstGLDisplayX11 * display_x11)
{
- X11EventSource *source;
+ xcb_connection_t *connection;
+ XCBEventSource *source;
+
+ connection = display_x11->xcb_connection;
+ g_return_val_if_fail (connection != NULL, NULL);
- source = (X11EventSource *)
- g_source_new (&x11_event_source_funcs, sizeof (X11EventSource));
- source->window = window_x11;
- source->pfd.fd = ConnectionNumber (source->window->device);
+ 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);
diff --git a/gst-libs/gst/gl/x11/x11_event_source.h b/gst-libs/gst/gl/x11/xcb_event_source.h
index 39f79f0f0..ba476352a 100644
--- a/gst-libs/gst/gl/x11/x11_event_source.h
+++ b/gst-libs/gst/gl/x11/xcb_event_source.h
@@ -18,13 +18,12 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef __X11_EVENT_SOURCE_H__
-#define __X11_EVENT_SOURCE_H__
+#ifndef __XCB_EVENT_SOURCE_H__
+#define __XCB_EVENT_SOURCE_H__
#include <glib-object.h>
-#include "gstglwindow_x11.h"
+#include "gstgldisplay_x11.h"
-GSource *
-x11_event_source_new (GstGLWindowX11 *window_x11);
+GSource * xcb_event_source_new (GstGLDisplayX11 *display_x11);
-#endif /* __WAYLAND_EVENT_SOURCE_H__ */
+#endif /* __XCB_EVENT_SOURCE_H__ */