1*4882a593SmuzhiyunFrom 26f367d760afdf598f62d205da5c825ee48a727d 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/33] 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/wayland/gstwaylandsink.c | 32 ++++++++++++++++++++------------
12*4882a593Smuzhiyun ext/wayland/gstwaylandsink.h |  1 +
13*4882a593Smuzhiyun ext/wayland/wlwindow.c       | 29 ++++++++++++++++++++++-------
14*4882a593Smuzhiyun ext/wayland/wlwindow.h       |  5 +++--
15*4882a593Smuzhiyun 4 files changed, 46 insertions(+), 21 deletions(-)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
18*4882a593Smuzhiyunindex 9e55e4f..6647123 100644
19*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.c
20*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.c
21*4882a593Smuzhiyun@@ -63,7 +63,8 @@ enum
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun   PROP_0,
24*4882a593Smuzhiyun   PROP_DISPLAY,
25*4882a593Smuzhiyun-  PROP_FULLSCREEN
26*4882a593Smuzhiyun+  PROP_FULLSCREEN,
27*4882a593Smuzhiyun+  PROP_LAST
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun GST_DEBUG_CATEGORY (gstwayland_debug);
31*4882a593Smuzhiyun@@ -212,6 +213,8 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
32*4882a593Smuzhiyun           "Whether the surface should be made fullscreen ", FALSE,
33*4882a593Smuzhiyun           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun+  gst_video_overlay_install_properties (gobject_class, PROP_LAST);
36*4882a593Smuzhiyun+
37*4882a593Smuzhiyun   gst_type_mark_as_plugin_api (GST_TYPE_WAYLAND_VIDEO, 0);
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun@@ -275,7 +278,8 @@ gst_wayland_sink_set_property (GObject * object,
41*4882a593Smuzhiyun       GST_OBJECT_UNLOCK (sink);
42*4882a593Smuzhiyun       break;
43*4882a593Smuzhiyun     default:
44*4882a593Smuzhiyun-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
45*4882a593Smuzhiyun+      if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value))
46*4882a593Smuzhiyun+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
47*4882a593Smuzhiyun       break;
48*4882a593Smuzhiyun   }
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun@@ -721,7 +725,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
51*4882a593Smuzhiyun     if (!sink->window) {
52*4882a593Smuzhiyun       /* if we were not provided a window, create one ourselves */
53*4882a593Smuzhiyun       sink->window = gst_wl_window_new_toplevel (sink->display,
54*4882a593Smuzhiyun-          &sink->video_info, sink->fullscreen, &sink->render_lock);
55*4882a593Smuzhiyun+          &sink->video_info, sink->fullscreen, &sink->render_lock,
56*4882a593Smuzhiyun+          &sink->render_rectangle);
57*4882a593Smuzhiyun       g_signal_connect_object (sink->window, "closed",
58*4882a593Smuzhiyun           G_CALLBACK (on_window_closed), sink, 0);
59*4882a593Smuzhiyun     }
60*4882a593Smuzhiyun@@ -994,16 +999,19 @@ gst_wayland_sink_set_render_rectangle (GstVideoOverlay * overlay,
61*4882a593Smuzhiyun   g_return_if_fail (sink != NULL);
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun   g_mutex_lock (&sink->render_lock);
64*4882a593Smuzhiyun-  if (!sink->window) {
65*4882a593Smuzhiyun-    g_mutex_unlock (&sink->render_lock);
66*4882a593Smuzhiyun-    GST_WARNING_OBJECT (sink,
67*4882a593Smuzhiyun-        "set_render_rectangle called without window, ignoring");
68*4882a593Smuzhiyun-    return;
69*4882a593Smuzhiyun-  }
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun-  GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d",
72*4882a593Smuzhiyun-      x, y, w, h);
73*4882a593Smuzhiyun-  gst_wl_window_set_render_rectangle (sink->window, x, y, w, h);
74*4882a593Smuzhiyun+  if (sink->window) {
75*4882a593Smuzhiyun+    GST_DEBUG_OBJECT (sink, "window geometry changed to (%d, %d) %d x %d",
76*4882a593Smuzhiyun+        x, y, w, h);
77*4882a593Smuzhiyun+    gst_wl_window_set_render_rectangle (sink->window, x, y, w, h, TRUE);
78*4882a593Smuzhiyun+  } else {
79*4882a593Smuzhiyun+    GST_DEBUG_OBJECT (sink, "caching window geometry (%d, %d) %d x %d",
80*4882a593Smuzhiyun+        x, y, w, h);
81*4882a593Smuzhiyun+    sink->render_rectangle.x = x;
82*4882a593Smuzhiyun+    sink->render_rectangle.y = y;
83*4882a593Smuzhiyun+    sink->render_rectangle.w = w;
84*4882a593Smuzhiyun+    sink->render_rectangle.h = h;
85*4882a593Smuzhiyun+  }
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun   g_mutex_unlock (&sink->render_lock);
88*4882a593Smuzhiyun }
89*4882a593Smuzhiyundiff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
90*4882a593Smuzhiyunindex 1c5fb07..9872c29 100644
91*4882a593Smuzhiyun--- a/ext/wayland/gstwaylandsink.h
92*4882a593Smuzhiyun+++ b/ext/wayland/gstwaylandsink.h
93*4882a593Smuzhiyun@@ -69,6 +69,7 @@ struct _GstWaylandSink
94*4882a593Smuzhiyun   gboolean redraw_pending;
95*4882a593Smuzhiyun   GMutex render_lock;
96*4882a593Smuzhiyun   GstBuffer *last_buffer;
97*4882a593Smuzhiyun+  GstVideoRectangle render_rectangle;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun   struct wl_callback *callback;
100*4882a593Smuzhiyun };
101*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c
102*4882a593Smuzhiyunindex 57b5491..7814cb8 100644
103*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.c
104*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.c
105*4882a593Smuzhiyun@@ -79,7 +79,7 @@ handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel,
106*4882a593Smuzhiyun   if (width <= 0 || height <= 0)
107*4882a593Smuzhiyun     return;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun-  gst_wl_window_set_render_rectangle (window, 0, 0, width, height);
110*4882a593Smuzhiyun+  gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun static const struct xdg_toplevel_listener xdg_toplevel_listener = {
114*4882a593Smuzhiyun@@ -123,7 +123,7 @@ handle_configure (void *data, struct wl_shell_surface *wl_shell_surface,
115*4882a593Smuzhiyun   if (width == 0 || height == 0)
116*4882a593Smuzhiyun     return;
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun-  gst_wl_window_set_render_rectangle (window, 0, 0, width, height);
119*4882a593Smuzhiyun+  gst_wl_window_set_render_rectangle (window, 0, 0, width, height, FALSE);
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun static void
123*4882a593Smuzhiyun@@ -256,7 +256,8 @@ gst_wl_window_ensure_fullscreen (GstWlWindow * window, gboolean fullscreen)
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun GstWlWindow *
126*4882a593Smuzhiyun gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info,
127*4882a593Smuzhiyun-    gboolean fullscreen, GMutex * render_lock)
128*4882a593Smuzhiyun+    gboolean fullscreen, GMutex * render_lock,
129*4882a593Smuzhiyun+    GstVideoRectangle * render_rectangle)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun   GstWlWindow *window;
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun@@ -325,12 +326,22 @@ gst_wl_window_new_toplevel (GstWlDisplay * display, const GstVideoInfo * info,
134*4882a593Smuzhiyun   }
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun   /* render_rectangle is already set via toplevel_configure in
137*4882a593Smuzhiyun-   * xdg_shell fullscreen mode */
138*4882a593Smuzhiyun-  if (!(display->xdg_wm_base && fullscreen)) {
139*4882a593Smuzhiyun+   * fullscreen mode */
140*4882a593Smuzhiyun+  if (fullscreen)
141*4882a593Smuzhiyun+    return window;
142*4882a593Smuzhiyun+
143*4882a593Smuzhiyun+  if (render_rectangle->w || render_rectangle->h) {
144*4882a593Smuzhiyun+    /* apply cached position and size */
145*4882a593Smuzhiyun+    GST_DEBUG ("Applying window position (%d, %d)",
146*4882a593Smuzhiyun+        render_rectangle->x, render_rectangle->y);
147*4882a593Smuzhiyun+    gst_wl_window_set_render_rectangle (window, render_rectangle->x,
148*4882a593Smuzhiyun+        render_rectangle->y, render_rectangle->w, render_rectangle->h, TRUE);
149*4882a593Smuzhiyun+  } else {
150*4882a593Smuzhiyun     /* set the initial size to be the same as the reported video size */
151*4882a593Smuzhiyun     gint width =
152*4882a593Smuzhiyun         gst_util_uint64_scale_int_round (info->width, info->par_n, info->par_d);
153*4882a593Smuzhiyun-    gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
154*4882a593Smuzhiyun+    gst_wl_window_set_render_rectangle (window, 0, 0,
155*4882a593Smuzhiyun+        width, info->height, FALSE);
156*4882a593Smuzhiyun   }
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun   return window;
159*4882a593Smuzhiyun@@ -546,7 +557,7 @@ gst_wl_window_update_borders (GstWlWindow * window)
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun void
162*4882a593Smuzhiyun gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
163*4882a593Smuzhiyun-    gint w, gint h)
164*4882a593Smuzhiyun+    gint w, gint h, gboolean with_position)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun   g_return_if_fail (window != NULL);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun@@ -559,6 +570,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
169*4882a593Smuzhiyun   window->render_rectangle.w = w;
170*4882a593Smuzhiyun   window->render_rectangle.h = h;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun+  /* try to position the xdg surface with hacked wayland server API */
173*4882a593Smuzhiyun+  if (with_position && window->xdg_surface)
174*4882a593Smuzhiyun+    xdg_surface_set_window_geometry (window->xdg_surface, x, y, 0, 0);
175*4882a593Smuzhiyun+
176*4882a593Smuzhiyun   /* position the area inside the parent - needs a parent commit to apply */
177*4882a593Smuzhiyun   if (window->area_subsurface)
178*4882a593Smuzhiyun     wl_subsurface_set_position (window->area_subsurface, x, y);
179*4882a593Smuzhiyundiff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h
180*4882a593Smuzhiyunindex 303c336..ba61d7a 100644
181*4882a593Smuzhiyun--- a/ext/wayland/wlwindow.h
182*4882a593Smuzhiyun+++ b/ext/wayland/wlwindow.h
183*4882a593Smuzhiyun@@ -83,7 +83,8 @@ GType gst_wl_window_get_type (void);
184*4882a593Smuzhiyun void gst_wl_window_ensure_fullscreen (GstWlWindow * window,
185*4882a593Smuzhiyun         gboolean fullscreen);
186*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display,
187*4882a593Smuzhiyun-        const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock);
188*4882a593Smuzhiyun+        const GstVideoInfo * info, gboolean fullscreen, GMutex * render_lock,
189*4882a593Smuzhiyun+        GstVideoRectangle * render_rectangle);
190*4882a593Smuzhiyun GstWlWindow *gst_wl_window_new_in_surface (GstWlDisplay * display,
191*4882a593Smuzhiyun         struct wl_surface * parent, GMutex * render_lock);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun@@ -94,7 +95,7 @@ gboolean gst_wl_window_is_toplevel (GstWlWindow *window);
194*4882a593Smuzhiyun void gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer,
195*4882a593Smuzhiyun         const GstVideoInfo * info);
196*4882a593Smuzhiyun void gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y,
197*4882a593Smuzhiyun-        gint w, gint h);
198*4882a593Smuzhiyun+        gint w, gint h, gboolean with_position);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun G_END_DECLS
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun--
203*4882a593Smuzhiyun2.20.1
204*4882a593Smuzhiyun
205