Commit 08efcd75 authored by Philippe Normand's avatar Philippe Normand 🦀

gl/wayland: Navigation events dispatch support

parent 7a4b400f
Pipeline #55593 passed with stages
in 61 minutes and 32 seconds
......@@ -899,12 +899,13 @@ gst_glimage_sink_get_property (GObject * object, guint prop_id,
}
static void
gst_glimage_sink_key_event_cb (GstGLWindow * window, char *event_name, char
*key_string, GstGLImageSink * gl_sink)
gst_glimage_sink_key_event_cb (GstGLWindow * window, char *event_name,
guint32 keycode, guint32 modifiers, GstGLImageSink * gl_sink)
{
GST_DEBUG_OBJECT (gl_sink, "event %s key %s pressed", event_name, key_string);
gst_navigation_send_key_event (GST_NAVIGATION (gl_sink),
event_name, key_string);
GST_DEBUG_OBJECT (gl_sink, "event %s key %" G_GUINT32_FORMAT " pressed",
event_name, keycode);
gst_navigation_send_keycode_event (GST_NAVIGATION (gl_sink), event_name,
keycode, modifiers);
}
static void
......@@ -916,6 +917,17 @@ gst_glimage_sink_mouse_event_cb (GstGLWindow * window, char *event_name,
event_name, button, posx, posy);
}
static void
gst_glimage_sink_mouse_scroll_event_cb (GstGLWindow * window,
double posx, double posy, double delta_x, double delta_y,
GstGLImageSink * gl_sink)
{
GST_DEBUG_OBJECT (gl_sink, "event scroll at %g, %g", posx, posy);
gst_navigation_send_mouse_scroll_event (GST_NAVIGATION (gl_sink),
posx, posy, delta_x, delta_y);
}
static gboolean
_ensure_gl_setup (GstGLImageSink * gl_sink)
{
......@@ -986,11 +998,15 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
gst_gl_window_set_close_callback (window,
GST_GL_WINDOW_CB (gst_glimage_sink_on_close),
gst_object_ref (gl_sink), (GDestroyNotify) gst_object_unref);
gl_sink->key_sig_id = g_signal_connect (window, "key-event", G_CALLBACK
(gst_glimage_sink_key_event_cb), gl_sink);
gl_sink->key_sig_id =
g_signal_connect (window, "keycode-event",
G_CALLBACK (gst_glimage_sink_key_event_cb), gl_sink);
gl_sink->mouse_sig_id =
g_signal_connect (window, "mouse-event",
G_CALLBACK (gst_glimage_sink_mouse_event_cb), gl_sink);
gl_sink->mouse_scroll_sig_id =
g_signal_connect (window, "scroll-event",
G_CALLBACK (gst_glimage_sink_mouse_scroll_event_cb), gl_sink);
gst_gl_window_set_render_rectangle (window, gl_sink->x, gl_sink->y,
gl_sink->width, gl_sink->height);
......@@ -1241,6 +1257,10 @@ gst_glimage_sink_change_state (GstElement * element, GstStateChange transition)
if (glimage_sink->mouse_sig_id)
g_signal_handler_disconnect (window, glimage_sink->mouse_sig_id);
glimage_sink->mouse_sig_id = 0;
if (glimage_sink->mouse_scroll_sig_id)
g_signal_handler_disconnect (window,
glimage_sink->mouse_scroll_sig_id);
glimage_sink->mouse_scroll_sig_id = 0;
gst_object_unref (window);
gst_object_unref (glimage_sink->context);
......@@ -2349,6 +2369,9 @@ gst_glimage_sink_on_close (GstGLImageSink * gl_sink)
if (gl_sink->mouse_sig_id)
g_signal_handler_disconnect (window, gl_sink->mouse_sig_id);
gl_sink->mouse_sig_id = 0;
if (gl_sink->mouse_scroll_sig_id)
g_signal_handler_disconnect (window, gl_sink->mouse_scroll_sig_id);
gl_sink->mouse_scroll_sig_id = 0;
g_atomic_int_set (&gl_sink->to_quit, 1);
......
......@@ -69,6 +69,7 @@ struct _GstGLImageSink
guintptr new_window_id;
gulong mouse_sig_id;
gulong key_sig_id;
gulong mouse_scroll_sig_id;
/* GstVideoOverlay::set_render_rectangle() cache */
gint x;
......
......@@ -124,6 +124,8 @@ enum
SIGNAL_0,
EVENT_MOUSE_SIGNAL,
EVENT_KEY_SIGNAL,
EVENT_KEYCODE_SIGNAL,
EVENT_SCROLL_SIGNAL,
LAST_SIGNAL
};
......@@ -227,6 +229,42 @@ gst_gl_window_class_init (GstGLWindowClass * klass)
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING);
/**
* GstGLWindow::keycode-event:
* @object: the #GstGLWindow
* @id: the name of the event
* @keycode: the hardware keycode of the key pressed
* @modifiers: FIXME
*
* Will be emitted when a key event is received by the GstGLwindow.
*
* Since: 1.18
*/
gst_gl_window_signals[EVENT_KEYCODE_SIGNAL] =
g_signal_new ("keycode-event", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_UINT);
/**
* GstGLWindow::scroll-event:
* @object: the #GstGLWindow
* @x: the x coordinate of the mouse event
* @y: the y coordinate of the mouse event
* @delta_x: the x offset of the scroll event
* @delta_y: the y offset of the scroll event
*
* Will be emitted when a mouse scroll event is received by the GstGLwindow.
*
* Since: 1.18
*/
gst_gl_window_signals[EVENT_SCROLL_SIGNAL] =
g_signal_new ("scroll-event", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
G_TYPE_NONE, 4, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
G_TYPE_DOUBLE);
_init_debug ();
}
......@@ -853,6 +891,14 @@ gst_gl_window_get_surface_dimensions (GstGLWindow * window, guint * width,
*height = window->priv->surface_height;
}
void
gst_gl_window_send_keycode_event (GstGLWindow * window, const char *event_type,
guint32 keycode, guint32 modifiers)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_KEYCODE_SIGNAL], 0,
event_type, keycode, modifiers);
}
void
gst_gl_window_send_key_event (GstGLWindow * window, const char *event_type,
const char *key_str)
......@@ -869,6 +915,15 @@ gst_gl_window_send_mouse_event (GstGLWindow * window, const char *event_type,
event_type, button, posx, posy);
}
void
gst_gl_window_send_scroll_event (GstGLWindow * window,
double posx, double posy, double delta_x, double delta_y)
{
g_signal_emit (window, gst_gl_window_signals[EVENT_SCROLL_SIGNAL], 0,
posx, posy, delta_x, delta_y);
}
/**
* gst_gl_window_handle_events:
* @window: a #GstGLWindow
......
......@@ -222,6 +222,12 @@ void gst_gl_window_handle_events (GstGLWindow * window,
gboolean handle_events);
GST_GL_API
void gst_gl_window_send_keycode_event (GstGLWindow * window,
const char * event_type,
guint32 keycode,
guint32 modifiers);
GST_GL_DEPRECATED_FOR(gst_gl_window_send_keycode_event)
void gst_gl_window_send_key_event (GstGLWindow * window,
const char * event_type,
const char * key_str);
......@@ -232,6 +238,13 @@ void gst_gl_window_send_mouse_event (GstGLWindow * window,
double posx,
double posy);
GST_GL_API
void gst_gl_window_send_scroll_event (GstGLWindow * window,
double posx,
double posy,
double delta_x,
double delta_y);
/* surfaces/rendering */
GST_GL_API
void gst_gl_window_queue_resize (GstGLWindow *window);
......
......@@ -515,6 +515,7 @@ endif
wayland_client_dep = unneeded_dep
wayland_cursor_dep = unneeded_dep
wayland_egl_dep = unneeded_dep
xkbcommon_dep = unneeded_dep
if need_win_wayland != 'no'
if need_win_wayland == 'yes'
if need_platform_egl == 'no'
......@@ -533,8 +534,9 @@ if need_win_wayland != 'no'
wayland_egl_dep = dependency('wayland-egl', version : '>= 1.0', required : false)
wayland_protocols_dep = dependency('wayland-protocols', version : '>= 1.15', required : false)
wayland_scanner = find_program('wayland-scanner', required: false)
xkbcommon_dep = dependency('xkbcommon', version : '>= 0.8', required : false)
if wayland_client_dep.found() and wayland_cursor_dep.found() and wayland_egl_dep.found() and wayland_protocols_dep.found() and wayland_scanner.found()
if wayland_client_dep.found() and wayland_cursor_dep.found() and wayland_egl_dep.found() and wayland_protocols_dep.found() and wayland_scanner.found() and xkbcommon_dep.found()
# Generate the XDG shell interface
wayland_protocols_basedir = wayland_protocols_dep.get_pkgconfig_variable('pkgdatadir')
xdg_shell_xml_spec = join_paths(wayland_protocols_basedir, 'stable', 'xdg-shell', 'xdg-shell.xml')
......@@ -562,7 +564,7 @@ if need_win_wayland != 'no'
'wayland/gstgldisplay_wayland.h'
]
glconf.set('GST_GL_HAVE_WINDOW_WAYLAND', 1)
gl_winsys_deps += [wayland_client_dep, wayland_cursor_dep, wayland_egl_dep]
gl_winsys_deps += [wayland_client_dep, wayland_cursor_dep, wayland_egl_dep, xkbcommon_dep]
enabled_gl_winsys += 'wayland'
else
if need_win_wayland == 'yes'
......@@ -572,6 +574,7 @@ if need_win_wayland != 'no'
wayland_cursor_dep = unneeded_dep
wayland_egl_dep = unneeded_dep
wayland_protocols_dep = unneeded_dep
xkbcommon_dep = unneeded_dep
endif
endif
endif
......
......@@ -74,8 +74,8 @@ registry_handle_global (void *data, struct wl_registry *registry,
GST_DEBUG_CATEGORY_GET (gst_gl_display_debug, "gldisplay");
GST_TRACE_OBJECT (display, "registry_handle_global with registry %p, "
"interface %s, version %u", registry, interface, version);
GST_TRACE_OBJECT (display, "registry %p, interface %s, version %u", registry,
interface, version);
if (g_strcmp0 (interface, "wl_compositor") == 0) {
display->compositor =
......@@ -90,6 +90,8 @@ registry_handle_global (void *data, struct wl_registry *registry,
display);
} else if (g_strcmp0 (interface, "wl_shell") == 0) {
display->shell = wl_registry_bind (registry, name, &wl_shell_interface, 1);
} else if (g_strcmp0 (interface, "wl_seat") == 0) {
display->seat = wl_registry_bind (registry, name, &wl_seat_interface, 4);
}
}
......@@ -140,6 +142,10 @@ gst_gl_display_wayland_finalize (GObject * object)
* https://bugzilla.gnome.org/show_bug.cgi?id=787293 */
g_object_set_data (object, "gst.gl.display.egl", NULL);
if (display_wayland->seat) {
wl_seat_destroy (display_wayland->seat);
}
if (!display_wayland->foreign_display && display_wayland->display) {
wl_display_flush (display_wayland->display);
wl_display_disconnect (display_wayland->display);
......
......@@ -56,6 +56,7 @@ struct _GstGLDisplayWayland
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_subcompositor *subcompositor;
struct wl_seat *seat;
/* Basic shell, see private struct for others (e.g. XDG-shell) */
struct wl_shell *shell;
......
......@@ -25,6 +25,8 @@
#include "xdg-shell-client-protocol.h"
#include <wayland-egl.h>
#include <wayland-cursor.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <gst/gl/gl.h>
......@@ -77,6 +79,18 @@ struct window {
struct wl_surface *foreign_surface;
struct wl_subsurface *subsurface;
struct wl_callback *callback;
struct xkb_context *keyboard_context;
struct xkb_state *keyboard_state;
struct xkb_compose_table *compose_table;
struct xkb_compose_state *compose_state;
struct {
xkb_mod_index_t control;
xkb_mod_index_t alt;
xkb_mod_index_t shift;
} indexes;
guint8 modifiers;
int fullscreen, configured;
int window_width, window_height;
int preferred_width, preferred_height;
......
......@@ -166,12 +166,18 @@ wayland_event_source_dispatch (GSource * base,
GSourceFunc callback, gpointer data)
{
WaylandEventSource *source = (WaylandEventSource *) base;
struct wl_display *display = source->display;
if (source->queue) {
wl_display_dispatch_queue_pending (source->display, source->queue);
} else {
wl_display_dispatch_pending (source->display);
if (source->pfd.revents & G_IO_IN) {
if (source->queue) {
wl_display_dispatch_queue_pending (source->display, source->queue);
}
wl_display_dispatch_pending (display);
}
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
return FALSE;
source->pfd.revents = 0;
if (callback)
......
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