if (self->wl_shell)
wl_shell_destroy (self->wl_shell);
+ if (self->xdg_wm_base)
+ xdg_wm_base_destroy (self->xdg_wm_base);
+
if (self->fullscreen_shell)
zwp_fullscreen_shell_v1_release (self->fullscreen_shell);
}
static void
+handle_xdg_wm_base_ping (void *user_data, struct xdg_wm_base *xdg_wm_base,
+ uint32_t serial)
+{
+ xdg_wm_base_pong (xdg_wm_base, serial);
+}
+
+static const struct xdg_wm_base_listener xdg_wm_base_listener = {
+ handle_xdg_wm_base_ping
+};
+
+static void
registry_handle_global (void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
{
wl_registry_bind (registry, id, &wl_subcompositor_interface, 1);
} else if (g_strcmp0 (interface, "wl_shell") == 0) {
self->wl_shell = wl_registry_bind (registry, id, &wl_shell_interface, 1);
+ } else if (g_strcmp0 (interface, "xdg_wm_base") == 0) {
+ self->xdg_wm_base =
+ wl_registry_bind (registry, id, &xdg_wm_base_interface, 1);
+ xdg_wm_base_add_listener (self->xdg_wm_base, &xdg_wm_base_listener, self);
} else if (g_strcmp0 (interface, "zwp_fullscreen_shell_v1") == 0) {
self->fullscreen_shell = wl_registry_bind (registry, id,
&zwp_fullscreen_shell_v1_interface, 1);
g_warning ("Could not bind to zwp_linux_dmabuf_v1");
}
- if (!self->wl_shell && !self->fullscreen_shell) {
+ if (!self->wl_shell && !self->xdg_wm_base && !self->fullscreen_shell) {
/* If wl_surface and wl_display are passed via GstContext
- * wl_shell, zwp_fullscreen_shell are not used.
+ * wl_shell, xdg_shell and zwp_fullscreen_shell are not used.
* In this case is correct to continue.
*/
- g_warning ("Could not bind to wl_shell or zwp_fullscreen_shell, video "
- "display may not work properly.");
+ g_warning ("Could not bind to either wl_shell, xdg_wm_base or "
+ "zwp_fullscreen_shell, video display may not work properly.");
}
self->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run,
GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
+enum
+{
+ CLOSED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT);
static void gst_wl_window_finalize (GObject * gobject);
static void
+handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel)
+{
+ GstWlWindow *window = data;
+
+ GST_DEBUG ("XDG toplevel got a \"close\" event.");
+ g_signal_emit (window, signals[CLOSED], 0);
+}
+
+static void
+handle_xdg_toplevel_configure (void *data, struct xdg_toplevel *xdg_toplevel,
+ int32_t width, int32_t height, struct wl_array *states)
+{
+ GstWlWindow *window = data;
+ const uint32_t *state;
+
+ GST_DEBUG ("XDG toplevel got a \"configure\" event, [ %d, %d ].",
+ width, height);
+
+ wl_array_for_each (state, states) {
+ switch (*state) {
+ case XDG_TOPLEVEL_STATE_FULLSCREEN:
+ case XDG_TOPLEVEL_STATE_MAXIMIZED:
+ case XDG_TOPLEVEL_STATE_RESIZING:
+ case XDG_TOPLEVEL_STATE_ACTIVATED:
+ break;
+ }
+ }
+
+ if (width <= 0 || height <= 0)
+ return;
+
+ gst_wl_window_set_render_rectangle (window, 0, 0, width, height);
+}
+
+static const struct xdg_toplevel_listener xdg_toplevel_listener = {
+ handle_xdg_toplevel_configure,
+ handle_xdg_toplevel_close,
+};
+
+static void
+handle_xdg_surface_configure (void *data, struct xdg_surface *xdg_surface,
+ uint32_t serial)
+{
+ xdg_surface_ack_configure (xdg_surface, serial);
+}
+
+static const struct xdg_surface_listener xdg_surface_listener = {
+ handle_xdg_surface_configure,
+};
+
+static void
handle_ping (void *data, struct wl_shell_surface *wl_shell_surface,
uint32_t serial)
{
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gst_wl_window_finalize;
+
+ signals[CLOSED] = g_signal_new ("closed", G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
}
static void
if (self->wl_shell_surface)
wl_shell_surface_destroy (self->wl_shell_surface);
+ if (self->xdg_toplevel)
+ xdg_toplevel_destroy (self->xdg_toplevel);
+ if (self->xdg_surface)
+ xdg_surface_destroy (self->xdg_surface);
+
if (self->video_viewport)
wp_viewport_destroy (self->video_viewport);
if (!window)
return;
- if (fullscreen)
- wl_shell_surface_set_fullscreen (window->wl_shell_surface,
- WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
- else
- wl_shell_surface_set_toplevel (window->wl_shell_surface);
+ if (window->display->xdg_wm_base) {
+ if (fullscreen)
+ xdg_toplevel_set_fullscreen (window->xdg_toplevel, NULL);
+ else
+ xdg_toplevel_unset_fullscreen (window->xdg_toplevel);
+ } else {
+ if (fullscreen)
+ wl_shell_surface_set_fullscreen (window->wl_shell_surface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_SCALE, 0, NULL);
+ else
+ wl_shell_surface_set_toplevel (window->wl_shell_surface);
+ }
}
GstWlWindow *
window = gst_wl_window_new_internal (display, render_lock);
- if (display->wl_shell) {
+ /* Check which protocol we will use (in order of preference) */
+ if (display->xdg_wm_base) {
+ /* First create the XDG surface */
+ window->xdg_surface = xdg_wm_base_get_xdg_surface (display->xdg_wm_base,
+ window->area_surface);
+ if (!window->xdg_surface) {
+ GST_ERROR ("Unable to get xdg_surface");
+ goto error;
+ }
+ xdg_surface_add_listener (window->xdg_surface, &xdg_surface_listener,
+ window);
+
+ /* Then the toplevel */
+ window->xdg_toplevel = xdg_surface_get_toplevel (window->xdg_surface);
+ if (!window->xdg_toplevel) {
+ GST_ERROR ("Unable to get xdg_toplevel");
+ goto error;
+ }
+ xdg_toplevel_add_listener (window->xdg_toplevel,
+ &xdg_toplevel_listener, window);
+
+ /* Finally, commit the xdg_surface state as toplevel */
+ wl_surface_commit (window->area_surface);
+
+ gst_wl_window_ensure_fullscreen (window, fullscreen);
+ } else if (display->wl_shell) {
/* go toplevel */
window->wl_shell_surface = wl_shell_get_shell_surface (display->wl_shell,
window->area_surface);
-
- if (window->wl_shell_surface) {
- wl_shell_surface_add_listener (window->wl_shell_surface,
- &wl_shell_surface_listener, window);
- gst_wl_window_ensure_fullscreen (window, fullscreen);
- } else {
+ if (!window->wl_shell_surface) {
GST_ERROR ("Unable to get wl_shell_surface");
- g_object_unref (window);
- return NULL;
+ goto error;
}
+
+ wl_shell_surface_add_listener (window->wl_shell_surface,
+ &wl_shell_surface_listener, window);
+ gst_wl_window_ensure_fullscreen (window, fullscreen);
} else if (display->fullscreen_shell) {
zwp_fullscreen_shell_v1_present_surface (display->fullscreen_shell,
window->area_surface, ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_ZOOM,
NULL);
} else {
- GST_ERROR ("Unable to use wl_shell or zwp_fullscreen_shell.");
- g_object_unref (window);
- return NULL;
+ GST_ERROR ("Unable to use either wl_shell, xdg_wm_base or "
+ "zwp_fullscreen_shell.");
+ goto error;
}
/* set the initial size to be the same as the reported video size */
gst_wl_window_set_render_rectangle (window, 0, 0, width, info->height);
return window;
+
+error:
+ g_object_unref (window);
+ return NULL;
}
GstWlWindow *