1From 0485939ec161e2f0069a8c356736569e887d8eab Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Mon, 15 Jun 2020 10:11:42 +0800 4Subject: [PATCH 09/41] waylandsink: Support setting toplevel window position 5 6Needs hacked wayland server, tested with: 7 waylandsink render-rectangle="<100,200,300,400>" 8 9Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 10--- 11 ext/gtk/gstgtkwaylandsink.c | 6 +++--- 12 ext/wayland/gstwaylandsink.c | 25 +++++++++++++++---------- 13 ext/wayland/gstwaylandsink.h | 2 ++ 14 gst-libs/gst/wayland/gstwlwindow.c | 26 ++++++++++++++++++++------ 15 gst-libs/gst/wayland/gstwlwindow.h | 5 +++-- 16 5 files changed, 43 insertions(+), 21 deletions(-) 17 18diff --git a/ext/gtk/gstgtkwaylandsink.c b/ext/gtk/gstgtkwaylandsink.c 19index e4dd06e..9030982 100644 20--- a/ext/gtk/gstgtkwaylandsink.c 21+++ b/ext/gtk/gstgtkwaylandsink.c 22@@ -254,7 +254,7 @@ widget_size_allocate_cb (GtkWidget * widget, GtkAllocation * allocation, 23 GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 24 allocation->x, allocation->y, allocation->width, allocation->height); 25 gst_wl_window_set_render_rectangle (priv->wl_window, allocation->x, 26- allocation->y, allocation->width, allocation->height); 27+ allocation->y, allocation->width, allocation->height, FALSE); 28 29 g_mutex_unlock (&priv->render_lock); 30 31@@ -425,7 +425,7 @@ scrollable_window_adjustment_changed_cb (GtkAdjustment * adjustment, 32 gtk_widget_get_allocation (priv->gtk_widget, &allocation); 33 calculate_adjustment (priv->gtk_widget, &allocation); 34 gst_wl_window_set_render_rectangle (priv->wl_window, allocation.x, 35- allocation.y, allocation.width, allocation.height); 36+ allocation.y, allocation.width, allocation.height, FALSE); 37 38 return FALSE; 39 } 40@@ -481,7 +481,7 @@ setup_wl_window (GstGtkWaylandSink * self) 41 gtk_widget_get_allocation (priv->gtk_widget, &allocation); 42 calculate_adjustment (priv->gtk_widget, &allocation); 43 gst_wl_window_set_render_rectangle (priv->wl_window, allocation.x, 44- allocation.y, allocation.width, allocation.height); 45+ allocation.y, allocation.width, allocation.height, FALSE); 46 47 /* Make subsurfaces syncronous during resizes. 48 * Unfortunately GTK/GDK does not provide easier to use signals. 49diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c 50index 5d2721c..1870ba3 100644 51--- a/ext/wayland/gstwaylandsink.c 52+++ b/ext/wayland/gstwaylandsink.c 53@@ -294,7 +294,8 @@ gst_wayland_sink_set_property (GObject * object, 54 FALSE); 55 break; 56 default: 57- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 58+ if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value)) 59+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); 60 break; 61 } 62 } 63@@ -764,7 +765,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer) 64 if (!self->window) { 65 /* if we were not provided a window, create one ourselves */ 66 self->window = gst_wl_window_new_toplevel (self->display, 67- &self->video_info, self->fullscreen, &self->render_lock); 68+ &self->video_info, self->fullscreen, &self->render_lock, 69+ &self->render_rectangle); 70 g_signal_connect_object (self->window, "closed", 71 G_CALLBACK (on_window_closed), self, 0); 72 gst_wl_window_set_rotate_method (self->window, 73@@ -1047,16 +1049,19 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay, 74 g_return_if_fail (self != NULL); 75 76 g_mutex_lock (&self->render_lock); 77- if (!self->window) { 78- g_mutex_unlock (&self->render_lock); 79- GST_WARNING_OBJECT (self, 80- "set_render_rectangle called without window, ignoring"); 81- return; 82- } 83 84- GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 85+ if (self->window) { 86+ GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 87+ x, y, w, h); 88+ gst_wl_window_set_render_rectangle (self->window, x, y, w, h, TRUE); 89+ } else { 90+ GST_DEBUG_OBJECT (self, "window geometry changed to (%d, %d) %d x %d", 91 x, y, w, h); 92- gst_wl_window_set_render_rectangle (self->window, x, y, w, h); 93+ self->render_rectangle.x = x; 94+ self->render_rectangle.y = y; 95+ self->render_rectangle.w = w; 96+ self->render_rectangle.h = h; 97+ } 98 99 g_mutex_unlock (&self->render_lock); 100 } 101diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h 102index 46b5faa..d4c3764 100644 103--- a/ext/wayland/gstwaylandsink.h 104+++ b/ext/wayland/gstwaylandsink.h 105@@ -70,6 +70,8 @@ struct _GstWaylandSink 106 GstVideoOrientationMethod current_rotate_method; 107 108 struct wl_callback *callback; 109+ 110+ GstVideoRectangle render_rectangle; 111 }; 112 113 struct _GstWaylandSinkClass 114diff --git a/gst-libs/gst/wayland/gstwlwindow.c b/gst-libs/gst/wayland/gstwlwindow.c 115index e7c429c..7080c8c 100644 116--- a/gst-libs/gst/wayland/gstwlwindow.c 117+++ b/gst-libs/gst/wayland/gstwlwindow.c 118@@ -122,7 +122,7 @@ handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel, 119 if (width <= 0 || height <= 0) 120 return; 121 122- gst_wl_window_set_render_rectangle (self, 0, 0, width, height); 123+ gst_wl_window_set_render_rectangle (self, 0, 0, width, height, FALSE); 124 } 125 126 static const struct xdg_toplevel_listener xdg_toplevel_listener = { 127@@ -268,7 +268,8 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * self, gboolean fullscreen) 128 129 GstWlWindow * 130 gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 131- gboolean fullscreen, GMutex * render_lock) 132+ gboolean fullscreen, GMutex * render_lock, 133+ GstVideoRectangle * render_rectangle) 134 { 135 GstWlWindow *self; 136 GstWlWindowPrivate *priv; 137@@ -329,12 +330,21 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info, 138 } 139 140 /* render_rectangle is already set via toplevel_configure in 141- * xdg_shell fullscreen mode */ 142- if (!(xdg_wm_base && fullscreen)) { 143+ * fullscreen mode */ 144+ if (fullscreen) 145+ return self; 146+ 147+ if (render_rectangle->w || render_rectangle->h) { 148+ /* apply cached position and size */ 149+ GST_DEBUG ("Applying window position (%d, %d)", 150+ render_rectangle->x, render_rectangle->y); 151+ gst_wl_window_set_render_rectangle (self, render_rectangle->x, 152+ render_rectangle->y, render_rectangle->w, render_rectangle->h, TRUE); 153+ } else { 154 /* set the initial size to be the same as the reported video size */ 155 gint width = 156 gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d); 157- gst_wl_window_set_render_rectangle (self, 0, 0, width, info->height); 158+ gst_wl_window_set_render_rectangle (self, 0, 0, width, info->height, FALSE); 159 } 160 161 return self; 162@@ -623,7 +633,7 @@ gst_wl_window_update_geometry (GstWlWindow * self) 163 164 void 165 gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 166- gint w, gint h) 167+ gint w, gint h, gboolean with_position) 168 { 169 GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self); 170 171@@ -637,6 +647,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 172 priv->render_rectangle.h = h; 173 174 gst_wl_window_update_geometry (self); 175+ 176+ /* try to position the xdg surface with hacked wayland server API */ 177+ if (with_position && priv->xdg_surface) 178+ xdg_surface_set_window_geometry (priv->xdg_surface, x, y, 0, 0); 179 } 180 181 const GstVideoRectangle * 182diff --git a/gst-libs/gst/wayland/gstwlwindow.h b/gst-libs/gst/wayland/gstwlwindow.h 183index 06c4001..2bbd643 100644 184--- a/gst-libs/gst/wayland/gstwlwindow.h 185+++ b/gst-libs/gst/wayland/gstwlwindow.h 186@@ -39,7 +39,8 @@ void gst_wl_window_ensure_fullscreen (GstWlWindow * self, 187 188 GST_WL_API 189 GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display, 190- const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock); 191+ const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock, 192+ GstVideoRectangle * render_rectangle); 193 194 GST_WL_API 195 GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display, 196@@ -63,7 +64,7 @@ void gst_wl_window_render (GstWlWindow * self, GstWlBuffer * buffer, 197 198 GST_WL_API 199 void gst_wl_window_set_render_rectangle (GstWlWindow * self, gint x, gint y, 200- gint w, gint h); 201+ gint w, gint h, gboolean with_position); 202 203 GST_WL_API 204 const GstVideoRectangle *gst_wl_window_get_render_rectangle (GstWlWindow * self); 205-- 2062.20.1 207 208