Commit 1403a687 authored by Sebastian Dröge's avatar Sebastian Dröge 🍵 Committed by Tim-Philipp Müller

glwindow: Hide navigation specific internal API and add API to asynchronously...

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.
parent 8b00b134
......@@ -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,48 +994,100 @@ gst_gl_dummy_window_new (void)
return g_object_new (gst_gl_dummy_window_get_type (), NULL);
}
gboolean
void
gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
const char *key_str)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_KEY_SIGNAL], 0,
event_type, key_str);
}
typedef struct
{
GstGLWindow *window;
const char *event_type;
const char *key_str;
} KeyEventData;
static gboolean
gst_gl_window_key_event_cb (gpointer data)
{
struct key_event *key_data = (struct key_event *) 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);
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)
gst_gl_window_send_key_event_async (GstGLWindow * window,
const char *event_type, const char *key_str)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_KEY_SIGNAL], 0,
event_type, 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);
}
gboolean
void
gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
int button, double posx, double posy)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_MOUSE_SIGNAL], 0,
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)
{
struct mouse_event *mouse_data = (struct mouse_event *) 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);
g_slice_free (struct mouse_event, mouse_data);
return G_SOURCE_REMOVE;
}
void
gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
int button, double posx, double posy)
gst_gl_window_send_mouse_event_async (GstGLWindow * window,
const char *event_type, int button, double posx, double posy)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_MOUSE_SIGNAL], 0,
event_type, button, posx, 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);
}
/**
......
......@@ -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);
......
......@@ -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 ==
case ButtonRelease:{
const char *mouse_type = NULL;
mouse_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,
(GSourceFunc) gst_gl_window_mouse_event_cb, mouse_data);
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment