mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:46:13 +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;
|
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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue