mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 16:50:47 +00:00
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:
parent
8b00b1347e
commit
1403a6871f
3 changed files with 122 additions and 91 deletions
|
@ -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
|
||||
|
|
|
@ -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 ==
|
||||
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);
|
||||
|
|
Loading…
Reference in a new issue