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