glimagesink: add property to request full screen window

Only affects windows created internally, externally created windows
(i.e. windows created and owned by apps) are not affected.

BUG: 142900877
Change-Id: I8b3039f0b063f7b46e4040419e750c057f185ced
diff --git a/ext/gl/gstglimagesink.c b/ext/gl/gstglimagesink.c
index 43653bb..7fa3b71 100644
--- a/ext/gl/gstglimagesink.c
+++ b/ext/gl/gstglimagesink.c
@@ -100,6 +100,7 @@
 #define DEFAULT_HANDLE_EVENTS       TRUE
 #define DEFAULT_FORCE_ASPECT_RATIO  TRUE
 #define DEFAULT_IGNORE_ALPHA        TRUE
+#define DEFAULT_FULLSCREEN          FALSE
 
 #define DEFAULT_MULTIVIEW_MODE GST_VIDEO_MULTIVIEW_MODE_MONO
 #define DEFAULT_MULTIVIEW_FLAGS GST_VIDEO_MULTIVIEW_FLAGS_NONE
@@ -123,6 +124,7 @@
   PROP_BIN_OUTPUT_MULTIVIEW_LAYOUT,
   PROP_BIN_OUTPUT_MULTIVIEW_FLAGS,
   PROP_BIN_OUTPUT_MULTIVIEW_DOWNMIX_MODE,
+  PROP_BIN_FULLSCREEN,
   PROP_BIN_LAST
 };
 
@@ -285,6 +287,11 @@
           "Output anaglyph type to generate when downmixing to mono",
           GST_TYPE_GL_STEREO_DOWNMIX_MODE_TYPE, DEFAULT_MULTIVIEW_DOWNMIX,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (gobject_class, PROP_BIN_FULLSCREEN,
+      g_param_spec_boolean ("fullscreen", "Fullscreen",
+          "Requests that internally created windows are fullscreen"
+          " (does not affect external windows)",
+          DEFAULT_FULLSCREEN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
   gst_video_overlay_install_properties (gobject_class, PROP_BIN_LAST);
 
@@ -394,6 +401,7 @@
   PROP_OUTPUT_MULTIVIEW_LAYOUT,
   PROP_OUTPUT_MULTIVIEW_FLAGS,
   PROP_OUTPUT_MULTIVIEW_DOWNMIX_MODE,
+  PROP_FULLSCREEN,
   PROP_LAST
 };
 
@@ -697,6 +705,12 @@
           GST_TYPE_GL_STEREO_DOWNMIX_MODE_TYPE, DEFAULT_MULTIVIEW_DOWNMIX,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  g_object_class_install_property (gobject_class, PROP_FULLSCREEN,
+      g_param_spec_boolean ("fullscreen", "Fullscreen",
+          "Requests that internally created windows are fullscreen"
+          " (does not affect external windows)",
+          DEFAULT_FULLSCREEN, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gst_video_overlay_install_properties (gobject_class, PROP_LAST);
 
   gst_element_class_set_metadata (element_class, "OpenGL video sink",
@@ -779,6 +793,8 @@
   glimage_sink->current_rotate_method = DEFAULT_ROTATE_METHOD;
   glimage_sink->transform_matrix = NULL;
 
+  glimage_sink->fullscreen = DEFAULT_FULLSCREEN;
+
   g_mutex_init (&glimage_sink->drawing_lock);
 }
 
@@ -833,6 +849,9 @@
       glimage_sink->output_mode_changed = TRUE;
       GST_GLIMAGE_SINK_UNLOCK (glimage_sink);
       break;
+    case PROP_FULLSCREEN:
+      glimage_sink->fullscreen = g_value_get_boolean (value);
+      break;
     default:
       if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value))
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -892,6 +911,9 @@
     case PROP_OUTPUT_MULTIVIEW_DOWNMIX_MODE:
       g_value_set_enum (value, glimage_sink->mview_downmix_mode);
       break;
+    case PROP_FULLSCREEN:
+      g_value_set_boolean (value, glimage_sink->fullscreen);
+      break;
     default:
       if (!gst_video_overlay_set_property (object, PROP_LAST, prop_id, value))
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -2341,6 +2363,7 @@
 
     gst_gl_window_set_preferred_size (window, GST_VIDEO_SINK_WIDTH (gl_sink),
         GST_VIDEO_SINK_HEIGHT (gl_sink));
+    gst_gl_window_prefer_fullscreen (window, gl_sink->fullscreen);
     gst_gl_window_show (window);
   }
 
diff --git a/ext/gl/gstglimagesink.h b/ext/gl/gstglimagesink.h
index 12166ec..f5ac43d 100644
--- a/ext/gl/gstglimagesink.h
+++ b/ext/gl/gstglimagesink.h
@@ -141,6 +141,8 @@
     GstGLRotateMethod current_rotate_method;
     GstGLRotateMethod rotate_method;
     const gfloat *transform_matrix;
+
+    gboolean fullscreen;
 };
 
 struct _GstGLImageSinkClass
diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c
index f7237a4..daee213 100644
--- a/gst-libs/gst/gl/gstglwindow.c
+++ b/gst-libs/gst/gl/gstglwindow.c
@@ -931,6 +931,18 @@
 }
 
 void
+gst_gl_window_prefer_fullscreen (GstGLWindow * window, gboolean fullscreen)
+{
+  GstGLWindowClass *window_class;
+
+  g_return_val_if_fail (GST_IS_GL_WINDOW (window), FALSE);
+  window_class = GST_GL_WINDOW_GET_CLASS (window);
+
+  if (window_class->prefer_fullscreen)
+    window_class->prefer_fullscreen (window, fullscreen);
+}
+
+void
 gst_gl_window_queue_resize (GstGLWindow * window)
 {
   GstGLWindowClass *window_class;
diff --git a/gst-libs/gst/gl/gstglwindow.h b/gst-libs/gst/gl/gstglwindow.h
index ece8d31..b857e4d 100644
--- a/gst-libs/gst/gl/gstglwindow.h
+++ b/gst-libs/gst/gl/gstglwindow.h
@@ -168,6 +168,7 @@
   void     (*show)               (GstGLWindow *window);
   gboolean (*set_render_rectangle)(GstGLWindow *window, gint x, gint y, gint width, gint height);
   void     (*queue_resize)       (GstGLWindow *window);
+  void     (*prefer_fullscreen)  (GstGLWindow *window, gboolean fullscreen);
 
   /*< private >*/
   gpointer _reserved[GST_PADDING];
@@ -251,6 +252,10 @@
                                                gint width,
                                                gint height);
 
+GST_GL_API
+void gst_gl_window_prefer_fullscreen (GstGLWindow * window,
+                                      gboolean fullscreen);
+
 /* subclass usage only */
 GST_GL_API
 void     gst_gl_window_resize               (GstGLWindow *window, guint width, guint height);
diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
index 3852818..06809fa 100644
--- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
+++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
@@ -328,6 +328,25 @@
 }
 
 static void
+gst_gl_window_wayland_egl_prefer_fullscreen (GstGLWindow * window,
+    gboolean fullscreen)
+{
+  GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
+
+  window_egl->window.preferred_fullscreen = fullscreen;
+}
+
+static void
+gst_gl_window_wayland_egl_set_preferred_size (GstGLWindow * window, gint width,
+    gint height)
+{
+  GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (window);
+
+  window_egl->window.preferred_width = width;
+  window_egl->window.preferred_height = height;
+}
+
+static void
 gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
 {
   GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
@@ -344,6 +363,10 @@
       GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_display);
   window_class->set_render_rectangle =
       GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_set_render_rectangle);
+  window_class->set_preferred_size =
+      GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_set_preferred_size);
+  window_class->prefer_fullscreen =
+      GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_prefer_fullscreen);
 }
 
 static void
@@ -470,6 +493,17 @@
 
   create_surfaces (window_egl);
 
+  if (!window_egl->window.foreign_surface &&
+      window_egl->window.preferred_width &&
+      window_egl->window.preferred_height &&
+      window_egl->window.preferred_fullscreen) {
+    window_resize(window_egl, window_egl->window.preferred_width,
+        window_egl->window.preferred_height);
+    wl_shell_surface_set_fullscreen (window_egl->window.shell_surface,
+        WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+        0, NULL);
+  }
+
   gst_gl_window_send_message (window, (GstGLWindowCB) _roundtrip_async, window);
 }
 
diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h
index 07c7ad1..a643617 100644
--- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h
+++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h
@@ -73,6 +73,8 @@
   int fullscreen, configured;
   int window_width, window_height;
   int window_x, window_y;
+  int preferred_width, preferred_height;
+  gboolean preferred_fullscreen;
 };
 
 struct _GstGLWindowWaylandEGL {