glwindow: Hide navigation specific internal API and add API to asynchronously send navigation events

Exposing the navigation thread's main context, GSourceFuncs and structs called
key_event and mouse_event is exposing a bit too much of the internals. Let's
just go with two functions to asynchronously send navigation events on the
window with the same API as the synchronous ones.
This commit is contained in:
Sebastian Dröge 2015-12-21 11:27:09 +01:00 committed by Tim-Philipp Müller
parent 8b00b1347e
commit 1403a6871f
3 changed files with 122 additions and 91 deletions

View file

@ -90,13 +90,15 @@ struct _GstGLWindowPrivate
{
GMainContext *main_context;
GMainLoop *loop;
GThread *navigation_thread;
guint surface_width;
guint surface_height;
gboolean alive;
GThread *navigation_thread;
GMainContext *navigation_context;
GMainLoop *navigation_loop;
GMutex nav_lock;
GCond nav_create_cond;
gboolean nav_alive;
@ -327,7 +329,7 @@ gst_gl_window_finalize (GObject * object)
GstGLWindowPrivate *priv = window->priv;
GST_INFO ("quit navigation loop");
g_main_loop_quit (window->navigation_loop);
g_main_loop_quit (window->priv->navigation_loop);
/* wait until navigation thread finished */
g_thread_join (window->priv->navigation_thread);
window->priv->navigation_thread = NULL;
@ -920,24 +922,25 @@ gst_gl_window_navigation_thread (GstGLWindow * window)
g_return_val_if_fail (GST_IS_GL_WINDOW (window), NULL);
window->navigation_context = g_main_context_new ();
window->navigation_loop = g_main_loop_new (window->navigation_context, FALSE);
g_main_context_push_thread_default (window->navigation_context);
window->priv->navigation_context = g_main_context_new ();
window->priv->navigation_loop =
g_main_loop_new (window->priv->navigation_context, FALSE);
g_main_context_push_thread_default (window->priv->navigation_context);
source = g_idle_source_new ();
g_source_set_callback (source, (GSourceFunc) gst_gl_window_navigation_started,
window, NULL);
g_source_attach (source, window->navigation_context);
g_source_attach (source, window->priv->navigation_context);
g_source_unref (source);
g_main_loop_run (window->navigation_loop);
g_main_loop_run (window->priv->navigation_loop);
g_main_context_pop_thread_default (window->navigation_context);
g_main_context_pop_thread_default (window->priv->navigation_context);
g_main_loop_unref (window->navigation_loop);
g_main_context_unref (window->navigation_context);
window->navigation_loop = NULL;
window->navigation_context = NULL;
g_main_loop_unref (window->priv->navigation_loop);
g_main_context_unref (window->priv->navigation_context);
window->priv->navigation_loop = NULL;
window->priv->navigation_context = NULL;
GST_INFO ("navigation loop exited\n");
@ -991,20 +994,6 @@ gst_gl_dummy_window_new (void)
return g_object_new (gst_gl_dummy_window_get_type (), NULL);
}
gboolean
gst_gl_window_key_event_cb (gpointer data)
{
struct key_event *key_data = (struct key_event *) data;
GST_DEBUG
("%s called data struct %p window %p key %s event %s ",
__func__, key_data, key_data->window, key_data->key_str,
key_data->event_type);
gst_gl_window_send_key_event (GST_GL_WINDOW (key_data->window),
key_data->event_type, key_data->key_str);
g_slice_free (struct key_event, key_data);
return G_SOURCE_REMOVE;
}
void
gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
const char *key_str)
@ -1013,20 +1002,44 @@ gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
event_type, key_str);
}
gboolean
gst_gl_window_mouse_event_cb (gpointer data)
typedef struct
{
struct mouse_event *mouse_data = (struct mouse_event *) data;
GST_DEBUG ("%s called data struct %p mouse event %s button %d at %g, %g",
__func__, mouse_data, mouse_data->event_type, mouse_data->button,
mouse_data->posx, mouse_data->posy);
gst_gl_window_send_mouse_event (GST_GL_WINDOW (mouse_data->window),
mouse_data->event_type, mouse_data->button, mouse_data->posx,
mouse_data->posy);
g_slice_free (struct mouse_event, mouse_data);
GstGLWindow *window;
const char *event_type;
const char *key_str;
} KeyEventData;
static gboolean
gst_gl_window_key_event_cb (gpointer data)
{
KeyEventData *key_data = data;
GST_DEBUG
("%s called data struct %p window %p key %s event %s ",
__func__, key_data, key_data->window, key_data->key_str,
key_data->event_type);
gst_gl_window_send_key_event (GST_GL_WINDOW (key_data->window),
key_data->event_type, key_data->key_str);
return G_SOURCE_REMOVE;
}
void
gst_gl_window_send_key_event_async (GstGLWindow * window,
const char *event_type, const char *key_str)
{
KeyEventData *key_data = g_new0 (KeyEventData, 1);
key_data->window = window;
key_data->key_str = key_str;
key_data->event_type = event_type;
g_main_context_invoke_full (window->priv->navigation_context,
G_PRIORITY_DEFAULT, (GSourceFunc) gst_gl_window_key_event_cb, key_data,
(GDestroyNotify) g_free);
}
void
gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
int button, double posx, double posy)
@ -1035,6 +1048,48 @@ gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
event_type, button, posx, posy);
}
typedef struct
{
GstGLWindow *window;
const char *event_type;
int button;
double posx;
double posy;
} MouseEventData;
static gboolean
gst_gl_window_mouse_event_cb (gpointer data)
{
MouseEventData *mouse_data = data;
GST_DEBUG ("%s called data struct %p mouse event %s button %d at %g, %g",
__func__, mouse_data, mouse_data->event_type, mouse_data->button,
mouse_data->posx, mouse_data->posy);
gst_gl_window_send_mouse_event (GST_GL_WINDOW (mouse_data->window),
mouse_data->event_type, mouse_data->button, mouse_data->posx,
mouse_data->posy);
return G_SOURCE_REMOVE;
}
void
gst_gl_window_send_mouse_event_async (GstGLWindow * window,
const char *event_type, int button, double posx, double posy)
{
MouseEventData *mouse_data = g_new0 (MouseEventData, 1);
mouse_data->window = window;
mouse_data->event_type = event_type;
mouse_data->button = button;
mouse_data->posx = posx;
mouse_data->posy = posy;
g_main_context_invoke_full (window->priv->navigation_context,
G_PRIORITY_DEFAULT, (GSourceFunc) gst_gl_window_mouse_event_cb,
mouse_data, (GDestroyNotify) g_free);
}
/**
* gst_gl_window_handle_events:
* @window: a #GstGLWindow

View file

@ -88,9 +88,6 @@ struct _GstGLWindow {
gboolean queue_resize;
/*< private >*/
GMainContext *navigation_context;
GMainLoop *navigation_loop;
GstGLWindowPrivate *priv;
gpointer _reserved[GST_PADDING];
@ -143,22 +140,6 @@ struct _GstGLWindowClass {
gpointer _reserved[GST_PADDING];
};
struct key_event
{
GstGLWindow *window;
const char *event_type;
const char *key_str;
};
struct mouse_event
{
GstGLWindow *window;
const char *event_type;
int button;
double posx;
double posy;
};
GQuark gst_gl_window_error_quark (void);
GType gst_gl_window_get_type (void);
@ -196,16 +177,23 @@ void gst_gl_window_send_message_async (GstGLWindow *window,
/* navigation */
void gst_gl_window_handle_events (GstGLWindow * window,
gboolean handle_events);
gboolean gst_gl_window_key_event_cb (gpointer data);
gboolean gst_gl_window_mouse_event_cb (gpointer data);
void gst_gl_window_send_key_event (GstGLWindow * window,
const char * event_type,
const char * key_str);
void gst_gl_window_send_key_event_async (GstGLWindow * window,
const char * event_type,
const char * key_str);
void gst_gl_window_send_mouse_event (GstGLWindow * window,
const char * event_type,
int button,
double posx,
double posy);
void gst_gl_window_send_mouse_event_async (GstGLWindow * window,
const char * event_type,
int button,
double posx,
double posy);
/* surfaces/rendering */
void gst_gl_window_queue_resize (GstGLWindow *window);

View file

@ -515,10 +515,6 @@ gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
GstGLContextClass *context_class;
GstGLWindow *window;
gboolean ret = TRUE;
const char *key_str = NULL;
KeySym keysym;
struct mouse_event *mouse_data;
struct key_event *key_data;
window = GST_GL_WINDOW (window_x11);
@ -591,47 +587,39 @@ gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
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_data = g_slice_new (struct key_event);
key_data->window = window;
key_data->key_str = XKeysymToString (keysym);
key_data->event_type =
event.type == KeyPress ? "key-press" : "key-release";
GST_DEBUG ("input event key %d pressed over window at %d,%d (%s)",
event.xkey.keycode, event.xkey.x, event.xkey.y, key_str);
g_main_context_invoke (window->navigation_context,
(GSourceFunc) gst_gl_window_key_event_cb, key_data);
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);
break;
}
case ButtonPress:
case ButtonRelease:
GST_DEBUG ("input event mouse button %d pressed over window at %d,%d",
event.xbutton.button, event.xbutton.x, event.xbutton.y);
mouse_data = g_slice_new (struct mouse_event);
mouse_data->window = window;
mouse_data->event_type =
event.type ==
ButtonPress ? "mouse-button-press" : "mouse-button-release";
mouse_data->button = event.xbutton.button;
mouse_data->posx = (double) event.xbutton.x;
mouse_data->posy = (double) event.xbutton.y;
case ButtonRelease:{
const char *mouse_type = NULL;
g_main_context_invoke (window->navigation_context,
(GSourceFunc) gst_gl_window_mouse_event_cb, mouse_data);
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);
mouse_data = g_slice_new (struct mouse_event);
mouse_data->window = window;
mouse_data->event_type = "mouse-move";
mouse_data->button = 0;
mouse_data->posx = (double) event.xbutton.x;
mouse_data->posy = (double) event.xbutton.y;
g_main_context_invoke (window->navigation_context, (GSourceFunc)
gst_gl_window_mouse_event_cb, mouse_data);
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);