[725/906] x11: use GMainContext/GMainLoop
allows us to be reentrant https://bugzilla.gnome.org/show_bug.cgi?id=703445
This commit is contained in:
parent
96deb2fba3
commit
f9d46c29ca
@ -6,10 +6,12 @@ libgstgl_@GST_API_VERSION@includedir = $(includedir)/gstreamer-@GST_API_VERSION@
|
|||||||
libgstglx11includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/x11
|
libgstglx11includedir = $(includedir)/gstreamer-@GST_API_VERSION@/gst/gl/x11
|
||||||
|
|
||||||
libgstgl_x11_la_SOURCES = \
|
libgstgl_x11_la_SOURCES = \
|
||||||
gstglwindow_x11.c
|
gstglwindow_x11.c \
|
||||||
|
x11_event_source.c
|
||||||
|
|
||||||
libgstglx11include_HEADERS = \
|
libgstglx11include_HEADERS = \
|
||||||
gstglwindow_x11.h
|
gstglwindow_x11.h \
|
||||||
|
x11_event_source.h
|
||||||
|
|
||||||
if USE_GLX
|
if USE_GLX
|
||||||
libgstgl_x11_la_SOURCES += gstglwindow_x11_glx.c
|
libgstgl_x11_la_SOURCES += gstglwindow_x11_glx.c
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
|
#include "x11_event_source.h"
|
||||||
#include "gstglwindow_x11.h"
|
#include "gstglwindow_x11.h"
|
||||||
|
|
||||||
#if GST_GL_HAVE_PLATFORM_GLX
|
#if GST_GL_HAVE_PLATFORM_GLX
|
||||||
@ -157,8 +158,6 @@ static void
|
|||||||
gst_gl_window_x11_init (GstGLWindowX11 * window)
|
gst_gl_window_x11_init (GstGLWindowX11 * window)
|
||||||
{
|
{
|
||||||
window->priv = GST_GL_WINDOW_X11_GET_PRIVATE (window);
|
window->priv = GST_GL_WINDOW_X11_GET_PRIVATE (window);
|
||||||
|
|
||||||
g_cond_init (&window->cond_send_message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must be called in the gl thread */
|
/* Must be called in the gl thread */
|
||||||
@ -228,7 +227,7 @@ gst_gl_window_x11_create_context (GstGLWindow * window,
|
|||||||
|
|
||||||
setlocale (LC_NUMERIC, "C");
|
setlocale (LC_NUMERIC, "C");
|
||||||
|
|
||||||
gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), TRUE);
|
gst_gl_window_set_need_lock (GST_GL_WINDOW (window_x11), FALSE);
|
||||||
|
|
||||||
window_x11->running = TRUE;
|
window_x11->running = TRUE;
|
||||||
window_x11->visible = FALSE;
|
window_x11->visible = FALSE;
|
||||||
@ -253,7 +252,11 @@ gst_gl_window_x11_create_context (GstGLWindow * window,
|
|||||||
window_x11->device_height =
|
window_x11->device_height =
|
||||||
DisplayHeight (window_x11->device, window_x11->screen_num);
|
DisplayHeight (window_x11->device, window_x11->screen_num);
|
||||||
|
|
||||||
window_x11->connection = ConnectionNumber (window_x11->device);
|
window_x11->x11_source = x11_event_source_new (window_x11);
|
||||||
|
window_x11->main_context = g_main_context_new ();
|
||||||
|
window_x11->loop = g_main_loop_new (window_x11->main_context, FALSE);
|
||||||
|
|
||||||
|
g_source_attach (window_x11->x11_source, window_x11->main_context);
|
||||||
|
|
||||||
if (!window_class->choose_format (window_x11, error)) {
|
if (!window_class->choose_format (window_x11, error)) {
|
||||||
goto failure;
|
goto failure;
|
||||||
@ -286,7 +289,7 @@ gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11)
|
|||||||
XWMHints wm_hints;
|
XWMHints wm_hints;
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
const gchar *title = "OpenGL renderer";
|
const gchar *title = "OpenGL renderer";
|
||||||
Atom wm_atoms[3];
|
Atom wm_atoms[1];
|
||||||
|
|
||||||
static gint x = 0;
|
static gint x = 0;
|
||||||
static gint y = 0;
|
static gint y = 0;
|
||||||
@ -337,16 +340,8 @@ gst_gl_window_x11_create_window (GstGLWindowX11 * window_x11)
|
|||||||
if (wm_atoms[0] == None)
|
if (wm_atoms[0] == None)
|
||||||
GST_DEBUG ("Cannot create WM_DELETE_WINDOW");
|
GST_DEBUG ("Cannot create WM_DELETE_WINDOW");
|
||||||
|
|
||||||
wm_atoms[1] = XInternAtom (window_x11->device, "WM_GL_WINDOW", False);
|
|
||||||
if (wm_atoms[1] == None)
|
|
||||||
GST_DEBUG ("Cannot create WM_GL_WINDOW");
|
|
||||||
|
|
||||||
wm_atoms[2] = XInternAtom (window_x11->device, "WM_QUIT_LOOP", False);
|
|
||||||
if (wm_atoms[2] == None)
|
|
||||||
GST_DEBUG ("Cannot create WM_QUIT_LOOP");
|
|
||||||
|
|
||||||
XSetWMProtocols (window_x11->device, window_x11->internal_win_id, wm_atoms,
|
XSetWMProtocols (window_x11->device, window_x11->internal_win_id, wm_atoms,
|
||||||
2);
|
1);
|
||||||
|
|
||||||
wm_hints.flags = StateHint;
|
wm_hints.flags = StateHint;
|
||||||
wm_hints.initial_state = NormalState;
|
wm_hints.initial_state = NormalState;
|
||||||
@ -413,8 +408,6 @@ gst_gl_window_x11_close (GstGLWindow * window)
|
|||||||
GST_DEBUG ("display sender closed");
|
GST_DEBUG ("display sender closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
g_cond_clear (&window_x11->cond_send_message);
|
|
||||||
|
|
||||||
GST_GL_WINDOW_UNLOCK (window_x11);
|
GST_GL_WINDOW_UNLOCK (window_x11);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -577,143 +570,76 @@ gst_gl_window_x11_draw (GstGLWindow * window, guint width, guint height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called in the gl thread */
|
typedef struct _GstGLMessage
|
||||||
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
GMutex lock;
|
||||||
|
GCond cond;
|
||||||
|
gboolean fired;
|
||||||
|
|
||||||
|
GstGLWindowCB callback;
|
||||||
|
gpointer data;
|
||||||
|
} GstGLMessage;
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_run_message (GstGLMessage * message)
|
||||||
|
{
|
||||||
|
g_mutex_lock (&message->lock);
|
||||||
|
|
||||||
|
if (message->callback)
|
||||||
|
message->callback (message->data);
|
||||||
|
|
||||||
|
message->fired = TRUE;
|
||||||
|
g_cond_signal (&message->cond);
|
||||||
|
g_mutex_unlock (&message->lock);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_gl_window_x11_run (GstGLWindow * window)
|
gst_gl_window_x11_run (GstGLWindow * window)
|
||||||
{
|
{
|
||||||
GstGLWindowX11 *window_x11;
|
GstGLWindowX11 *window_x11;
|
||||||
GstGLWindowX11Class *window_class;
|
|
||||||
|
|
||||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||||
|
|
||||||
|
g_main_loop_run (window_x11->loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
|
||||||
|
{
|
||||||
|
GstGLWindow *window;
|
||||||
|
GstGLWindowX11Class *window_class;
|
||||||
|
|
||||||
|
window = GST_GL_WINDOW (window_x11);
|
||||||
window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
window_class = GST_GL_WINDOW_X11_GET_CLASS (window_x11);
|
||||||
|
|
||||||
GST_DEBUG ("begin loop");
|
if (window_x11->running && XPending (window_x11->device)) {
|
||||||
|
|
||||||
while (window_x11->running) {
|
|
||||||
XEvent event;
|
XEvent event;
|
||||||
XEvent pending_event;
|
|
||||||
|
|
||||||
GST_GL_WINDOW_UNLOCK (window);
|
|
||||||
|
|
||||||
/* XSendEvent (which are called in other threads) are done from another display structure */
|
/* XSendEvent (which are called in other threads) are done from another display structure */
|
||||||
XNextEvent (window_x11->device, &event);
|
XNextEvent (window_x11->device, &event);
|
||||||
|
|
||||||
GST_GL_WINDOW_LOCK (window);
|
|
||||||
|
|
||||||
// use in generic/cube and other related uses
|
// use in generic/cube and other related uses
|
||||||
window_x11->allow_extra_expose_events = XPending (window_x11->device) <= 2;
|
window_x11->allow_extra_expose_events = XPending (window_x11->device) <= 2;
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
{
|
{
|
||||||
|
|
||||||
Atom wm_delete =
|
Atom wm_delete =
|
||||||
XInternAtom (window_x11->device, "WM_DELETE_WINDOW", True);
|
XInternAtom (window_x11->device, "WM_DELETE_WINDOW", True);
|
||||||
Atom wm_gl = XInternAtom (window_x11->device, "WM_GL_WINDOW", True);
|
|
||||||
Atom wm_quit_loop =
|
|
||||||
XInternAtom (window_x11->device, "WM_QUIT_LOOP", True);
|
|
||||||
|
|
||||||
if (wm_delete == None)
|
if (wm_delete == None)
|
||||||
GST_DEBUG ("Cannot create WM_DELETE_WINDOW");
|
GST_DEBUG ("Cannot create WM_DELETE_WINDOW");
|
||||||
if (wm_gl == None)
|
|
||||||
GST_DEBUG ("Cannot create WM_GL_WINDOW");
|
|
||||||
if (wm_quit_loop == None)
|
|
||||||
GST_DEBUG ("Cannot create WM_QUIT_LOOP");
|
|
||||||
|
|
||||||
/* Message sent with gst_gl_window_send_message */
|
|
||||||
if (wm_gl != None && event.xclient.message_type == wm_gl) {
|
|
||||||
if (window_x11->running) {
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
GstGLWindowCB custom_cb =
|
|
||||||
(GstGLWindowCB) (((event.xclient.data.
|
|
||||||
l[0] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[1] & 0xffffffff));
|
|
||||||
gpointer custom_data =
|
|
||||||
(gpointer) (((event.xclient.data.
|
|
||||||
l[2] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[3] & 0xffffffff));
|
|
||||||
#else
|
|
||||||
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
|
|
||||||
gpointer custom_data = (gpointer) event.xclient.data.l[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!custom_cb || !custom_data)
|
|
||||||
GST_DEBUG ("custom cb not initialized");
|
|
||||||
|
|
||||||
custom_cb (custom_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cond_signal (&window_x11->cond_send_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User clicked on the cross */
|
/* User clicked on the cross */
|
||||||
else if (wm_delete != None
|
if (wm_delete != None && (Atom) event.xclient.data.l[0] == wm_delete) {
|
||||||
&& (Atom) event.xclient.data.l[0] == wm_delete) {
|
|
||||||
GST_DEBUG ("Close %lud", (gulong) window_x11->internal_win_id);
|
GST_DEBUG ("Close %lud", (gulong) window_x11->internal_win_id);
|
||||||
|
|
||||||
if (window->close)
|
if (window->close)
|
||||||
window->close (window->close_data);
|
window->close (window->close_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* message sent with gst_gl_window_quit_loop */
|
|
||||||
else if (wm_quit_loop != None
|
|
||||||
&& event.xclient.message_type == wm_quit_loop) {
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
GstGLWindowCB destroy_cb =
|
|
||||||
(GstGLWindowCB) (((event.xclient.data.
|
|
||||||
l[0] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[1] & 0xffffffff));
|
|
||||||
gpointer destroy_data =
|
|
||||||
(gpointer) (((event.xclient.data.
|
|
||||||
l[2] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[3] & 0xffffffff));
|
|
||||||
#else
|
|
||||||
GstGLWindowCB destroy_cb = (GstGLWindowCB) event.xclient.data.l[0];
|
|
||||||
gpointer destroy_data = (gpointer) event.xclient.data.l[1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GST_DEBUG ("Quit loop message %lud",
|
|
||||||
(gulong) window_x11->internal_win_id);
|
|
||||||
|
|
||||||
/* exit loop */
|
|
||||||
window_x11->running = FALSE;
|
|
||||||
|
|
||||||
/* make sure last pendings send message calls are executed */
|
|
||||||
XFlush (window_x11->device);
|
|
||||||
while (XCheckTypedEvent (window_x11->device, ClientMessage,
|
|
||||||
&pending_event)) {
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
GstGLWindowCB custom_cb =
|
|
||||||
(GstGLWindowCB) (((event.xclient.data.
|
|
||||||
l[0] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[1] & 0xffffffff));
|
|
||||||
gpointer custom_data =
|
|
||||||
(gpointer) (((event.xclient.data.
|
|
||||||
l[2] & 0xffffffff) << 32) | (event.xclient.data.
|
|
||||||
l[3] & 0xffffffff));
|
|
||||||
#else
|
|
||||||
GstGLWindowCB custom_cb = (GstGLWindowCB) event.xclient.data.l[0];
|
|
||||||
gpointer custom_data = (gpointer) event.xclient.data.l[1];
|
|
||||||
#endif
|
|
||||||
GST_DEBUG ("execute last pending custom x events");
|
|
||||||
|
|
||||||
if (!custom_cb || !custom_data)
|
|
||||||
GST_DEBUG ("custom cb not initialized");
|
|
||||||
|
|
||||||
custom_cb (custom_data);
|
|
||||||
|
|
||||||
g_cond_signal (&window_x11->cond_send_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally we can destroy opengl ressources (texture/shaders/fbo) */
|
|
||||||
if (!destroy_cb || !destroy_data)
|
|
||||||
GST_FIXME ("destroy cb not correctly set");
|
|
||||||
|
|
||||||
if (destroy_cb)
|
|
||||||
destroy_cb (destroy_data);
|
|
||||||
|
|
||||||
} else
|
|
||||||
GST_DEBUG ("client message not recognized");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,7 +693,6 @@ gst_gl_window_x11_run (GstGLWindow * window)
|
|||||||
} // switch
|
} // switch
|
||||||
} // while running
|
} // while running
|
||||||
|
|
||||||
GST_DEBUG ("end loop");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not called by the gl thread */
|
/* Not called by the gl thread */
|
||||||
@ -779,32 +704,14 @@ gst_gl_window_x11_quit (GstGLWindow * window, GstGLWindowCB callback,
|
|||||||
|
|
||||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||||
|
|
||||||
GST_DEBUG ("sending quit, running:%i", window_x11->running);
|
if (callback)
|
||||||
|
gst_gl_window_x11_send_message (window, callback, data);
|
||||||
|
|
||||||
if (window_x11->running) {
|
GST_LOG ("sending quit");
|
||||||
XEvent event;
|
|
||||||
|
|
||||||
event.xclient.type = ClientMessage;
|
g_main_loop_quit (window_x11->loop);
|
||||||
event.xclient.send_event = TRUE;
|
|
||||||
event.xclient.display = window_x11->disp_send;
|
|
||||||
event.xclient.window = window_x11->internal_win_id;
|
|
||||||
event.xclient.message_type =
|
|
||||||
XInternAtom (window_x11->disp_send, "WM_QUIT_LOOP", True);
|
|
||||||
event.xclient.format = 32;
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
|
|
||||||
event.xclient.data.l[1] = (((long) callback)) & 0xffffffff;
|
|
||||||
event.xclient.data.l[2] = (((long) data) >> 32) & 0xffffffff;
|
|
||||||
event.xclient.data.l[3] = (((long) data)) & 0xffffffff;
|
|
||||||
#else
|
|
||||||
event.xclient.data.l[0] = (long) callback;
|
|
||||||
event.xclient.data.l[1] = (long) data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
XSendEvent (window_x11->disp_send, window_x11->internal_win_id, FALSE,
|
GST_LOG ("quit sent");
|
||||||
NoEventMask, &event);
|
|
||||||
XSync (window_x11->disp_send, FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not called by the gl thread */
|
/* Not called by the gl thread */
|
||||||
@ -817,32 +724,24 @@ gst_gl_window_x11_send_message (GstGLWindow * window, GstGLWindowCB callback,
|
|||||||
window_x11 = GST_GL_WINDOW_X11 (window);
|
window_x11 = GST_GL_WINDOW_X11 (window);
|
||||||
|
|
||||||
if (window_x11->running) {
|
if (window_x11->running) {
|
||||||
XEvent event;
|
GstGLMessage message;
|
||||||
|
|
||||||
event.xclient.type = ClientMessage;
|
message.window = window;
|
||||||
event.xclient.send_event = TRUE;
|
message.callback = callback;
|
||||||
event.xclient.display = window_x11->disp_send;
|
message.data = data;
|
||||||
event.xclient.window = window_x11->internal_win_id;
|
message.fired = FALSE;
|
||||||
event.xclient.message_type =
|
g_mutex_init (&message.lock);
|
||||||
XInternAtom (window_x11->disp_send, "WM_GL_WINDOW", True);
|
g_cond_init (&message.cond);
|
||||||
event.xclient.format = 32;
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
event.xclient.data.l[0] = (((long) callback) >> 32) & 0xffffffff;
|
|
||||||
event.xclient.data.l[1] = (((long) callback)) & 0xffffffff;
|
|
||||||
event.xclient.data.l[2] = (((long) data) >> 32) & 0xffffffff;
|
|
||||||
event.xclient.data.l[3] = (((long) data)) & 0xffffffff;
|
|
||||||
#else
|
|
||||||
event.xclient.data.l[0] = (long) callback;
|
|
||||||
event.xclient.data.l[1] = (long) data;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
XSendEvent (window_x11->disp_send, window_x11->internal_win_id, FALSE,
|
g_main_context_invoke (window_x11->main_context, (GSourceFunc) _run_message,
|
||||||
NoEventMask, &event);
|
&message);
|
||||||
XSync (window_x11->disp_send, FALSE);
|
|
||||||
|
g_mutex_lock (&message.lock);
|
||||||
|
|
||||||
/* block until opengl calls have been executed in the gl thread */
|
/* block until opengl calls have been executed in the gl thread */
|
||||||
g_cond_wait (&window_x11->cond_send_message,
|
while (!message.fired)
|
||||||
GST_GL_WINDOW_GET_LOCK (window));
|
g_cond_wait (&message.cond, &message.lock);
|
||||||
|
g_mutex_unlock (&message.lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +43,7 @@ typedef struct _GstGLWindowX11Class GstGLWindowX11Class;
|
|||||||
struct _GstGLWindowX11 {
|
struct _GstGLWindowX11 {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstGLWindow parent;
|
GstGLWindow parent;
|
||||||
|
|
||||||
GCond cond_send_message;
|
|
||||||
gboolean running;
|
gboolean running;
|
||||||
gboolean visible;
|
gboolean visible;
|
||||||
gboolean allow_extra_expose_events;
|
gboolean allow_extra_expose_events;
|
||||||
@ -71,6 +70,10 @@ struct _GstGLWindowX11 {
|
|||||||
/* X window */
|
/* X window */
|
||||||
Window internal_win_id;
|
Window internal_win_id;
|
||||||
|
|
||||||
|
GSource *x11_source;
|
||||||
|
GMainContext *main_context;
|
||||||
|
GMainLoop *loop;
|
||||||
|
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
GstGLWindowX11Private *priv;
|
GstGLWindowX11Private *priv;
|
||||||
|
|
||||||
|
98
gst-libs/gst/gl/x11/x11_event_source.c
Normal file
98
gst-libs/gst/gl/x11/x11_event_source.c
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* 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 <wayland-client.h>
|
||||||
|
|
||||||
|
#include "x11_event_source.h"
|
||||||
|
|
||||||
|
extern void 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); //clutter_events_pending ();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
x11_event_source_check (GSource * base)
|
||||||
|
{
|
||||||
|
X11EventSource *source = (X11EventSource *) base;
|
||||||
|
gboolean retval;
|
||||||
|
|
||||||
|
retval = source->pfd.revents; // || clutter_events_pending();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
x11_event_source_dispatch (GSource * base, GSourceFunc callback, gpointer data)
|
||||||
|
{
|
||||||
|
X11EventSource *source = (X11EventSource *) base;
|
||||||
|
|
||||||
|
gst_gl_window_x11_handle_event (source->window);
|
||||||
|
|
||||||
|
if (callback)
|
||||||
|
callback (data);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (window_x11->device);
|
||||||
|
source->pfd.events = G_IO_IN | G_IO_ERR;
|
||||||
|
g_source_add_poll (&source->source, &source->pfd);
|
||||||
|
|
||||||
|
return &source->source;
|
||||||
|
}
|
30
gst-libs/gst/gl/x11/x11_event_source.h
Normal file
30
gst-libs/gst/gl/x11/x11_event_source.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* 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__ */
|
Loading…
x
Reference in New Issue
Block a user