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; GMainContext *main_context;
GMainLoop *loop; GMainLoop *loop;
GThread *navigation_thread;
guint surface_width; guint surface_width;
guint surface_height; guint surface_height;
gboolean alive; gboolean alive;
GThread *navigation_thread;
GMainContext *navigation_context;
GMainLoop *navigation_loop;
GMutex nav_lock; GMutex nav_lock;
GCond nav_create_cond; GCond nav_create_cond;
gboolean nav_alive; gboolean nav_alive;
@ -327,7 +329,7 @@ gst_gl_window_finalize (GObject * object)
GstGLWindowPrivate *priv = window->priv; GstGLWindowPrivate *priv = window->priv;
GST_INFO ("quit navigation loop"); 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 */ /* wait until navigation thread finished */
g_thread_join (window->priv->navigation_thread); g_thread_join (window->priv->navigation_thread);
window->priv->navigation_thread = NULL; 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); g_return_val_if_fail (GST_IS_GL_WINDOW (window), NULL);
window->navigation_context = g_main_context_new (); window->priv->navigation_context = g_main_context_new ();
window->navigation_loop = g_main_loop_new (window->navigation_context, FALSE); window->priv->navigation_loop =
g_main_context_push_thread_default (window->navigation_context); g_main_loop_new (window->priv->navigation_context, FALSE);
g_main_context_push_thread_default (window->priv->navigation_context);
source = g_idle_source_new (); source = g_idle_source_new ();
g_source_set_callback (source, (GSourceFunc) gst_gl_window_navigation_started, g_source_set_callback (source, (GSourceFunc) gst_gl_window_navigation_started,
window, NULL); window, NULL);
g_source_attach (source, window->navigation_context); g_source_attach (source, window->priv->navigation_context);
g_source_unref (source); 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_loop_unref (window->priv->navigation_loop);
g_main_context_unref (window->navigation_context); g_main_context_unref (window->priv->navigation_context);
window->navigation_loop = NULL; window->priv->navigation_loop = NULL;
window->navigation_context = NULL; window->priv->navigation_context = NULL;
GST_INFO ("navigation loop exited\n"); 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); 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 void
gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type, gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
const char *key_str) const char *key_str)
@ -1013,20 +1002,44 @@ gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
event_type, key_str); event_type, key_str);
} }
gboolean typedef struct
gst_gl_window_mouse_event_cb (gpointer data)
{ {
struct mouse_event *mouse_data = (struct mouse_event *) data; GstGLWindow *window;
GST_DEBUG ("%s called data struct %p mouse event %s button %d at %g, %g", const char *event_type;
__func__, mouse_data, mouse_data->event_type, mouse_data->button, const char *key_str;
mouse_data->posx, mouse_data->posy); } KeyEventData;
gst_gl_window_send_mouse_event (GST_GL_WINDOW (mouse_data->window),
mouse_data->event_type, mouse_data->button, mouse_data->posx, static gboolean
mouse_data->posy); gst_gl_window_key_event_cb (gpointer data)
g_slice_free (struct mouse_event, mouse_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; 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 void
gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type, gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
int button, double posx, double posy) 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); 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: * gst_gl_window_handle_events:
* @window: a #GstGLWindow * @window: a #GstGLWindow

View file

@ -88,9 +88,6 @@ struct _GstGLWindow {
gboolean queue_resize; gboolean queue_resize;
/*< private >*/ /*< private >*/
GMainContext *navigation_context;
GMainLoop *navigation_loop;
GstGLWindowPrivate *priv; GstGLWindowPrivate *priv;
gpointer _reserved[GST_PADDING]; gpointer _reserved[GST_PADDING];
@ -143,22 +140,6 @@ struct _GstGLWindowClass {
gpointer _reserved[GST_PADDING]; 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); GQuark gst_gl_window_error_quark (void);
GType gst_gl_window_get_type (void); GType gst_gl_window_get_type (void);
@ -196,16 +177,23 @@ void gst_gl_window_send_message_async (GstGLWindow *window,
/* navigation */ /* navigation */
void gst_gl_window_handle_events (GstGLWindow * window, void gst_gl_window_handle_events (GstGLWindow * window,
gboolean handle_events); 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, void gst_gl_window_send_key_event (GstGLWindow * window,
const char * event_type, const char * event_type,
const char * key_str); 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, void gst_gl_window_send_mouse_event (GstGLWindow * window,
const char * event_type, const char * event_type,
int button, int button,
double posx, double posx,
double posy); double posy);
void gst_gl_window_send_mouse_event_async (GstGLWindow * window,
const char * event_type,
int button,
double posx,
double posy);
/* surfaces/rendering */ /* surfaces/rendering */
void gst_gl_window_queue_resize (GstGLWindow *window); 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; GstGLContextClass *context_class;
GstGLWindow *window; GstGLWindow *window;
gboolean ret = TRUE; 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); window = GST_GL_WINDOW (window_x11);
@ -591,47 +587,39 @@ gst_gl_window_x11_handle_event (GstGLWindowX11 * window_x11)
break; break;
case KeyPress: case KeyPress:
case KeyRelease: case KeyRelease:
{
const char *key_str = NULL, *key_type = NULL;
KeySym keysym;
keysym = XkbKeycodeToKeysym (window_x11->device, keysym = XkbKeycodeToKeysym (window_x11->device,
event.xkey.keycode, 0, 0); event.xkey.keycode, 0, 0);
key_str = XKeysymToString (keysym); key_str = XKeysymToString (keysym);
key_data = g_slice_new (struct key_event); key_type = event.type == KeyPress ? "key-press" : "key-release";
key_data->window = window; GST_DEBUG ("input event key %d %s over window at %d,%d (%s)",
key_data->key_str = XKeysymToString (keysym); event.xkey.keycode, key_type, event.xkey.x, event.xkey.y, key_str);
key_data->event_type = gst_gl_window_send_key_event_async (window, key_type, key_str);
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);
break; break;
}
case ButtonPress: case ButtonPress:
case ButtonRelease: case ButtonRelease:{
GST_DEBUG ("input event mouse button %d pressed over window at %d,%d", const char *mouse_type = NULL;
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;
g_main_context_invoke (window->navigation_context, mouse_type = event.type ==
(GSourceFunc) gst_gl_window_mouse_event_cb, mouse_data); 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; break;
}
case MotionNotify: case MotionNotify:
GST_DEBUG ("input event pointer moved over window at %d,%d", GST_DEBUG ("input event pointer moved over window at %d,%d",
event.xmotion.x, event.xmotion.y); 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_send_mouse_event_async (window, "mouse-move", 0,
gst_gl_window_mouse_event_cb, mouse_data); event.xbutton.x, event.xbutton.y);
break; break;
default: default:
GST_DEBUG ("unknown XEvent type: %u", event.type); GST_DEBUG ("unknown XEvent type: %u", event.type);