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