1*4882a593SmuzhiyunFrom c31eb56a5a9ee52efacf0589c3fcfcde92375422 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Fri, 5 Mar 2021 10:15:51 +0800 4*4882a593SmuzhiyunSubject: [PATCH 18/33] waylandsink: Support window layer property 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunSupport setting top|normal|bottom window layer. 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunTested with: 9*4882a593Smuzhiyungst-launch-1.0 videotestsrc ! waylandsink layer=top 10*4882a593Smuzhiyun 11*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 12*4882a593Smuzhiyun--- 13*4882a593Smuzhiyun ext/wayland/gstwaylandsink.c | 52 ++++++++++++++++++++++++++++++++++-- 14*4882a593Smuzhiyun ext/wayland/gstwaylandsink.h | 1 + 15*4882a593Smuzhiyun ext/wayland/wlwindow.c | 39 ++++++++++++++++++++++++++- 16*4882a593Smuzhiyun ext/wayland/wlwindow.h | 13 +++++++-- 17*4882a593Smuzhiyun 4 files changed, 100 insertions(+), 5 deletions(-) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 20*4882a593Smuzhiyunindex 4577e6c..1bf4511 100644 21*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.c 22*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.c 23*4882a593Smuzhiyun@@ -64,6 +64,7 @@ enum 24*4882a593Smuzhiyun PROP_0, 25*4882a593Smuzhiyun PROP_DISPLAY, 26*4882a593Smuzhiyun PROP_FULLSCREEN, 27*4882a593Smuzhiyun+ PROP_LAYER, 28*4882a593Smuzhiyun PROP_LAST 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun@@ -165,6 +166,24 @@ gst_wayland_pool_init (GstWaylandPool * pool) 32*4882a593Smuzhiyun { 33*4882a593Smuzhiyun } 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun+#define GST_TYPE_WL_WINDOW_LAYER (gst_wl_window_layer_get_type ()) 36*4882a593Smuzhiyun+static GType 37*4882a593Smuzhiyun+gst_wl_window_layer_get_type (void) 38*4882a593Smuzhiyun+{ 39*4882a593Smuzhiyun+ static GType layer = 0; 40*4882a593Smuzhiyun+ 41*4882a593Smuzhiyun+ if (!layer) { 42*4882a593Smuzhiyun+ static const GEnumValue layers[] = { 43*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_TOP, "Top", "top"}, 44*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_NORMAL, "Normal", "normal"}, 45*4882a593Smuzhiyun+ {GST_WL_WINDOW_LAYER_BOTTOM, "Bottom", "bottom"}, 46*4882a593Smuzhiyun+ {0, NULL, NULL} 47*4882a593Smuzhiyun+ }; 48*4882a593Smuzhiyun+ layer = g_enum_register_static ("GstWlWindowLayer", layers); 49*4882a593Smuzhiyun+ } 50*4882a593Smuzhiyun+ return layer; 51*4882a593Smuzhiyun+} 52*4882a593Smuzhiyun+ 53*4882a593Smuzhiyun static void 54*4882a593Smuzhiyun gst_wayland_sink_class_init (GstWaylandSinkClass * klass) 55*4882a593Smuzhiyun { 56*4882a593Smuzhiyun@@ -213,6 +232,12 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass) 57*4882a593Smuzhiyun "Whether the surface should be made fullscreen ", FALSE, 58*4882a593Smuzhiyun G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun+ g_object_class_install_property (gobject_class, PROP_LAYER, 61*4882a593Smuzhiyun+ g_param_spec_enum ("layer", "Window layer", 62*4882a593Smuzhiyun+ "Wayland window layer", 63*4882a593Smuzhiyun+ GST_TYPE_WL_WINDOW_LAYER, GST_WL_WINDOW_LAYER_NORMAL, 64*4882a593Smuzhiyun+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); 65*4882a593Smuzhiyun+ 66*4882a593Smuzhiyun gst_video_overlay_install_properties (gobject_class, PROP_LAST); 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun gst_type_mark_as_plugin_api (GST_TYPE_WAYLAND_VIDEO, 0); 69*4882a593Smuzhiyun@@ -225,6 +250,7 @@ gst_wayland_sink_init (GstWaylandSink * sink) 70*4882a593Smuzhiyun g_mutex_init (&sink->render_lock); 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun sink->window_handle = 1; 73*4882a593Smuzhiyun+ sink->layer = GST_WL_WINDOW_LAYER_NORMAL; 74*4882a593Smuzhiyun } 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun static void 77*4882a593Smuzhiyun@@ -239,6 +265,18 @@ gst_wayland_sink_set_fullscreen (GstWaylandSink * sink, gboolean fullscreen) 78*4882a593Smuzhiyun g_mutex_unlock (&sink->render_lock); 79*4882a593Smuzhiyun } 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun+static void 82*4882a593Smuzhiyun+gst_wayland_sink_set_layer (GstWaylandSink * sink, GstWlWindowLayer layer) 83*4882a593Smuzhiyun+{ 84*4882a593Smuzhiyun+ if (layer == sink->layer) 85*4882a593Smuzhiyun+ return; 86*4882a593Smuzhiyun+ 87*4882a593Smuzhiyun+ g_mutex_lock (&sink->render_lock); 88*4882a593Smuzhiyun+ sink->layer = layer; 89*4882a593Smuzhiyun+ gst_wl_window_ensure_layer (sink->window, layer); 90*4882a593Smuzhiyun+ g_mutex_unlock (&sink->render_lock); 91*4882a593Smuzhiyun+} 92*4882a593Smuzhiyun+ 93*4882a593Smuzhiyun static void 94*4882a593Smuzhiyun gst_wayland_sink_get_property (GObject * object, 95*4882a593Smuzhiyun guint prop_id, GValue * value, GParamSpec * pspec) 96*4882a593Smuzhiyun@@ -256,6 +294,11 @@ gst_wayland_sink_get_property (GObject * object, 97*4882a593Smuzhiyun g_value_set_boolean (value, sink->fullscreen); 98*4882a593Smuzhiyun GST_OBJECT_UNLOCK (sink); 99*4882a593Smuzhiyun break; 100*4882a593Smuzhiyun+ case PROP_LAYER: 101*4882a593Smuzhiyun+ GST_OBJECT_LOCK (sink); 102*4882a593Smuzhiyun+ g_value_set_enum (value, sink->layer); 103*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (sink); 104*4882a593Smuzhiyun+ break; 105*4882a593Smuzhiyun default: 106*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 107*4882a593Smuzhiyun break; 108*4882a593Smuzhiyun@@ -279,6 +322,11 @@ gst_wayland_sink_set_property (GObject * object, 109*4882a593Smuzhiyun gst_wayland_sink_set_fullscreen (sink, g_value_get_boolean (value)); 110*4882a593Smuzhiyun GST_OBJECT_UNLOCK (sink); 111*4882a593Smuzhiyun break; 112*4882a593Smuzhiyun+ case PROP_LAYER: 113*4882a593Smuzhiyun+ GST_OBJECT_LOCK (sink); 114*4882a593Smuzhiyun+ gst_wayland_sink_set_layer (sink, g_value_get_enum (value)); 115*4882a593Smuzhiyun+ GST_OBJECT_UNLOCK (sink); 116*4882a593Smuzhiyun+ break; 117*4882a593Smuzhiyun default: 118*4882a593Smuzhiyun if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) 119*4882a593Smuzhiyun G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 120*4882a593Smuzhiyun@@ -733,8 +781,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 121*4882a593Smuzhiyun if (!sink->window) { 122*4882a593Smuzhiyun /* if we were not provided a window, create one ourselves */ 123*4882a593Smuzhiyun sink->window = gst_wl_window_new_toplevel (sink->display, 124*4882a593Smuzhiyun- &sink->video_info, sink->fullscreen, &sink->render_lock, 125*4882a593Smuzhiyun- &sink->render_rectangle); 126*4882a593Smuzhiyun+ &sink->video_info, sink->fullscreen, sink->layer, 127*4882a593Smuzhiyun+ &sink->render_lock, &sink->render_rectangle); 128*4882a593Smuzhiyun g_signal_connect_object (sink->window, "closed", 129*4882a593Smuzhiyun G_CALLBACK (on_window_closed), sink, 0); 130*4882a593Smuzhiyun } 131*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h 132*4882a593Smuzhiyunindex 9872c29..3adddf2 100644 133*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.h 134*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.h 135*4882a593Smuzhiyun@@ -62,6 +62,7 @@ struct _GstWaylandSink 136*4882a593Smuzhiyun gboolean video_info_changed; 137*4882a593Smuzhiyun GstVideoInfo video_info; 138*4882a593Smuzhiyun gboolean fullscreen; 139*4882a593Smuzhiyun+ GstWlWindowLayer layer; 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun gchar *display_name; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c 144*4882a593Smuzhiyunindex 7814cb8..7f7f3b6 100644 145*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.c 146*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.c 147*4882a593Smuzhiyun@@ -234,6 +234,42 @@ gst_wl_window_new_internal (GstWlDisplay * display, GMutex * render_lock) 148*4882a593Smuzhiyun return window; 149*4882a593Smuzhiyun } 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun+static void 152*4882a593Smuzhiyun+gst_wl_window_set_flags (GstWlWindow * window, const char *flags) 153*4882a593Smuzhiyun+{ 154*4882a593Smuzhiyun+ /* HACK: set window flags through title */ 155*4882a593Smuzhiyun+ char s[128] = "flags="; 156*4882a593Smuzhiyun+ strcat (s, flags); 157*4882a593Smuzhiyun+ 158*4882a593Smuzhiyun+ if (!window) 159*4882a593Smuzhiyun+ return; 160*4882a593Smuzhiyun+ 161*4882a593Smuzhiyun+ if (window->xdg_toplevel) 162*4882a593Smuzhiyun+ xdg_toplevel_set_title (window->xdg_toplevel, s); 163*4882a593Smuzhiyun+ else if (window->wl_shell_surface) 164*4882a593Smuzhiyun+ wl_shell_surface_set_title (window->wl_shell_surface, s); 165*4882a593Smuzhiyun+} 166*4882a593Smuzhiyun+ 167*4882a593Smuzhiyun+void 168*4882a593Smuzhiyun+gst_wl_window_ensure_layer (GstWlWindow * window, GstWlWindowLayer layer) 169*4882a593Smuzhiyun+{ 170*4882a593Smuzhiyun+ char s[128] = "flags="; 171*4882a593Smuzhiyun+ 172*4882a593Smuzhiyun+ switch (layer) { 173*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_TOP: 174*4882a593Smuzhiyun+ strcat (s, "stay-on-top|-stay-on-bottom"); 175*4882a593Smuzhiyun+ break; 176*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_NORMAL: 177*4882a593Smuzhiyun+ strcat (s, "-stay-on-top|-stay-on-bottom"); 178*4882a593Smuzhiyun+ break; 179*4882a593Smuzhiyun+ case GST_WL_WINDOW_LAYER_BOTTOM: 180*4882a593Smuzhiyun+ strcat (s, "-stay-on-top|stay-on-bottom"); 181*4882a593Smuzhiyun+ break; 182*4882a593Smuzhiyun+ default: 183*4882a593Smuzhiyun+ return; 184*4882a593Smuzhiyun+ } 185*4882a593Smuzhiyun+} 186*4882a593Smuzhiyun+ 187*4882a593Smuzhiyun void 188*4882a593Smuzhiyun gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen) 189*4882a593Smuzhiyun { 190*4882a593Smuzhiyun@@ -256,7 +292,7 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen) 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun GstWlWindow * 193*4882a593Smuzhiyun gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 194*4882a593Smuzhiyun- gboolean fullscreen, GMutex * render_lock, 195*4882a593Smuzhiyun+ gboolean fullscreen, GstWlWindowLayer layer, GMutex * render_lock, 196*4882a593Smuzhiyun GstVideoRectangle * render_rectangle) 197*4882a593Smuzhiyun { 198*4882a593Smuzhiyun GstWlWindow *window; 199*4882a593Smuzhiyun@@ -287,6 +323,7 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 200*4882a593Smuzhiyun &xdg_toplevel_listener, window); 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun gst_wl_window_ensure_fullscreen (window, fullscreen); 203*4882a593Smuzhiyun+ gst_wl_window_ensure_layer (window, layer); 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /* Finally, commit the xdg_surface state as toplevel */ 206*4882a593Smuzhiyun window->configured = FALSE; 207*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h 208*4882a593Smuzhiyunindex ba61d7a..97ea79e 100644 209*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.h 210*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.h 211*4882a593Smuzhiyun@@ -80,11 +80,20 @@ struct _GstWlWindowClass 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun GType gst_wl_window_get_type (void); 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun+typedef enum 216*4882a593Smuzhiyun+{ 217*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_TOP = 0, 218*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_NORMAL = 1, 219*4882a593Smuzhiyun+ GST_WL_WINDOW_LAYER_BOTTOM = 2, 220*4882a593Smuzhiyun+} GstWlWindowLayer; 221*4882a593Smuzhiyun+ 222*4882a593Smuzhiyun+void gst_wl_window_ensure_layer (GstWlWindow * window, 223*4882a593Smuzhiyun+ GstWlWindowLayer layer); 224*4882a593Smuzhiyun void gst_wl_window_ensure_fullscreen (GstWlWindow * window, 225*4882a593Smuzhiyun gboolean fullscreen); 226*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, 227*4882a593Smuzhiyun- const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, 228*4882a593Smuzhiyun- GstVideoRectangle * render_rectangle); 229*4882a593Smuzhiyun+ const GstVideoInfo * info, gboolean fullscreen, GstWlWindowLayer layer, 230*4882a593Smuzhiyun+ GMutex * render_lock, GstVideoRectangle * render_rectangle); 231*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, 232*4882a593Smuzhiyun struct wl_surface * parent, GMutex * render_lock); 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun-- 235*4882a593Smuzhiyun2.20.1 236*4882a593Smuzhiyun 237