summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r--video/out/wayland_common.c231
1 files changed, 104 insertions, 127 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 480f29638b..e64c046327 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -3,6 +3,7 @@
* Copyright © 2008 Kristian Høgsberg
* Copyright © 2012-2013 Collabora, Ltd.
* Copyright © 2013 Alexander Preisinger <alexander.preisinger@gmail.com>
+ * Copyright © 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -46,6 +47,7 @@
#include "input/input.h"
#include "input/event.h"
#include "input/keycodes.h"
+#include "sub/osd.h"
static int lookupkey(int key);
@@ -54,11 +56,7 @@ static void show_cursor(struct vo_wayland_state * wl);
static void window_move(struct vo_wayland_state * wl, uint32_t serial);
static void window_set_title(struct vo_wayland_state * wl, const char *title);
static void schedule_resize(struct vo_wayland_state *wl,
- uint32_t edges,
- int32_t width,
- int32_t height);
-
-static void vo_wayland_fullscreen(struct vo *vo);
+ int32_t width, int32_t height);
static const struct wl_callback_listener frame_listener;
@@ -127,37 +125,77 @@ static const struct mp_keymap keymap[] = {
/** Wayland listeners **/
-static void ssurface_handle_ping(void *data,
- struct wl_shell_surface *shell_surface,
+static void xdg_handle_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
+{
+ zxdg_shell_v6_pong(shell, serial);
+}
+
+static const struct zxdg_shell_v6_listener xdg_shell_listener = {
+ xdg_handle_ping,
+};
+
+static void xdg_handle_configure(void *data, struct zxdg_surface_v6 *surface,
uint32_t serial)
{
- wl_shell_surface_pong(shell_surface, serial);
+ zxdg_surface_v6_ack_configure(surface, serial);
}
-static void ssurface_handle_configure(void *data,
- struct wl_shell_surface *shell_surface,
- uint32_t edges,
- int32_t width,
- int32_t height)
+const struct zxdg_surface_v6_listener xdg_surface_listener = {
+ xdg_handle_configure,
+};
+
+static void handle_toplevel_configure(void *data, struct zxdg_toplevel_v6 *toplevel,
+ int32_t width, int32_t height,
+ struct wl_array *states)
{
struct vo_wayland_state *wl = data;
- float win_aspect = wl->window.aspect;
- if (!width || !height)
- return;
- if (!wl->window.is_fullscreen)
- width = win_aspect * height;
- schedule_resize(wl, edges, width, height);
+ uint32_t *state;
+
+ if (!width) {
+ width = wl->window.p_width;
+ }
+
+ if (!height) {
+ height = wl->window.p_height;
+ }
+
+ if (wl->display.current_output) {
+ int scale = wl->display.current_output->scale;
+ width = MPMIN(width, wl->display.current_output->width/scale);
+ height = MPMIN(height, wl->display.current_output->height/scale);
+ }
+
+ wl->window.state.fullscreen = false;
+
+ wl_array_for_each(state, states) {
+ switch (*state) {
+ case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
+ wl->window.state.fullscreen = true;
+ break;
+ case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED:
+ break;
+ case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED: /* Window is focused */
+ break;
+ case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
+ break;
+ default:
+ /* Undefined state */
+ break;
+ }
+ }
+
+ schedule_resize(wl, width, height);
}
-static void ssurface_handle_popup_done(void *data,
- struct wl_shell_surface *shell_surface)
+static void handle_toplevel_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
{
+ struct vo_wayland_state *wl = data;
+ mp_input_put_key(wl->vo->input_ctx, MP_KEY_CLOSE_WIN);
}
-static const struct wl_shell_surface_listener shell_surface_listener = {
- ssurface_handle_ping,
- ssurface_handle_configure,
- ssurface_handle_popup_done
+static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
+ handle_toplevel_configure,
+ handle_toplevel_close,
};
static void output_handle_geometry(void *data,
@@ -540,9 +578,9 @@ static void registry_handle_global(void *data, struct wl_registry *reg,
MPMIN(3, version));
}
- else if (strcmp(interface, "wl_shell") == 0) {
-
- wl->display.shell = wl_registry_bind(reg, id, &wl_shell_interface, 1);
+ else if (strcmp(interface, "zxdg_shell_v6") == 0) {
+ wl->display.shell = wl_registry_bind(reg, id, &zxdg_shell_v6_interface, 1);
+ zxdg_shell_v6_add_listener(wl->display.shell, &xdg_shell_listener, wl);
}
else if (strcmp(interface, "wl_shm") == 0) {
@@ -638,77 +676,29 @@ static void show_cursor (struct vo_wayland_state *wl)
static void window_move(struct vo_wayland_state *wl, uint32_t serial)
{
- if (wl->display.shell)
- wl_shell_surface_move(wl->window.shell_surface, wl->input.seat, serial);
-}
-
-static void window_set_toplevel(struct vo_wayland_state *wl)
-{
- if (wl->display.shell)
- wl_shell_surface_set_toplevel(wl->window.shell_surface);
+ zxdg_toplevel_v6_move(wl->window.xdg_toplevel, wl->input.seat, serial);
}
static void window_set_title(struct vo_wayland_state *wl, const char *title)
{
if (wl->display.shell)
- wl_shell_surface_set_title(wl->window.shell_surface, title);
+ zxdg_toplevel_v6_set_title(wl->window.xdg_toplevel, title);
}
static void schedule_resize(struct vo_wayland_state *wl,
- uint32_t edges,
int32_t width,
int32_t height)
{
- int32_t minimum_size = 150;
- int32_t x, y;
- float win_aspect = wl->window.aspect;
- if (win_aspect <= 0)
- win_aspect = 1;
-
- MP_DBG(wl, "schedule resize: %dx%d\n", width, height);
-
- width = MPMAX(minimum_size, width);
- height = MPMAX(minimum_size, height);
- if (wl->display.current_output) {
- int scale = wl->display.current_output->scale;
- width = MPMIN(width, wl->display.current_output->width /scale);
- height = MPMIN(height, wl->display.current_output->height/scale);
- }
-
- // don't keep the aspect ration in fullscreen mode, because the compositor
- // shows the desktop in the border regions if the video has not the same
- // aspect ration as the screen
- /* if only the height is changed we have to calculate the width
- * in any other case we calculate the height */
- switch (edges) {
- case WL_SHELL_SURFACE_RESIZE_TOP:
- case WL_SHELL_SURFACE_RESIZE_BOTTOM:
- width = win_aspect * height;
- break;
- case WL_SHELL_SURFACE_RESIZE_LEFT:
- case WL_SHELL_SURFACE_RESIZE_RIGHT:
- case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
- case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
- case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
- case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
- height = (1 / win_aspect) * width;
- break;
- }
-
- if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
- x = wl->window.width - width;
- else
- x = 0;
+ MP_DBG(wl, "shedule resize: %dx%d\n", width, height);
+ wl->vo->dwidth = width;
+ wl->vo->dheight = height;
- if (edges & WL_SHELL_SURFACE_RESIZE_TOP)
- y = wl->window.height - height;
- else
- y = 0;
+ struct mp_rect src, dst;
+ struct mp_osd_res osd;
+ vo_get_src_dst_rects(wl->vo, &src, &dst, &osd);
- wl->window.sh_width = width;
- wl->window.sh_height = height;
- wl->window.sh_x = x;
- wl->window.sh_y = y;
+ wl->window.sh_width = dst.x1 - dst.x0;
+ wl->window.sh_height = dst.y1 - dst.y0;
wl->window.events |= VO_EVENT_RESIZE;
}
@@ -781,7 +771,7 @@ static void destroy_display(struct vo_wayland_state *wl)
wl_shm_destroy(wl->display.shm);
if (wl->display.shell)
- wl_shell_destroy(wl->display.shell);
+ zxdg_shell_v6_destroy(wl->display.shell);
if (wl->display.subcomp)
wl_subcompositor_destroy(wl->display.subcomp);
@@ -807,19 +797,22 @@ static bool create_window(struct vo_wayland_state *wl)
&surface_listener, wl);
if (wl->display.shell) {
- wl->window.shell_surface = wl_shell_get_shell_surface(wl->display.shell,
- wl->window.video_surface);
+ wl->window.xdg_surface = zxdg_shell_v6_get_xdg_surface(wl->display.shell,
+ wl->window.video_surface);
- if (!wl->window.shell_surface) {
- MP_ERR(wl, "creating shell surface failed\n");
+ if (!wl->window.xdg_surface) {
+ MP_ERR(wl, "creating xdg surface failed\n");
return false;
}
- wl_shell_surface_add_listener(wl->window.shell_surface,
- &shell_surface_listener, wl);
+ zxdg_surface_v6_add_listener(wl->window.xdg_surface,
+ &xdg_surface_listener, wl);
- wl_shell_surface_set_toplevel(wl->window.shell_surface);
- wl_shell_surface_set_class(wl->window.shell_surface, "mpv");
+ wl->window.xdg_toplevel = zxdg_surface_v6_get_toplevel(wl->window.xdg_surface);
+
+ zxdg_toplevel_v6_add_listener(wl->window.xdg_toplevel,
+ &xdg_toplevel_listener, wl);
+ zxdg_toplevel_v6_set_app_id(wl->window.xdg_toplevel, "mpv");
}
return true;
@@ -827,8 +820,8 @@ static bool create_window(struct vo_wayland_state *wl)
static void destroy_window(struct vo_wayland_state *wl)
{
- if (wl->window.shell_surface)
- wl_shell_surface_destroy(wl->window.shell_surface);
+ if (wl->window.xdg_surface)
+ zxdg_surface_v6_destroy(wl->window.xdg_surface);
if (wl->window.video_surface)
wl_surface_destroy(wl->window.video_surface);
@@ -954,42 +947,26 @@ void vo_wayland_uninit(struct vo *vo)
vo->wayland = NULL;
}
-static void vo_wayland_ontop(struct vo *vo)
-{
- struct vo_wayland_state *wl = vo->wayland;
- if (!vo->opts->ontop)
- return;
- MP_DBG(wl, "going ontop\n");
- window_set_toplevel(wl);
- schedule_resize(wl, 0, wl->window.width, wl->window.height);
-}
-
-static void vo_wayland_fullscreen(struct vo *vo)
+static void window_set_fullscreen(struct vo *vo)
{
struct vo_wayland_state *wl = vo->wayland;
if (!wl->display.shell)
return;
- struct wl_output *fs_output = wl->display.fs_output;
-
if (vo->opts->fullscreen) {
MP_DBG(wl, "going fullscreen\n");
- wl->window.is_fullscreen = true;
wl->window.p_width = wl->window.width;
wl->window.p_height = wl->window.height;
- if (wl->display.current_output)
- schedule_resize(wl, 0, wl->display.current_output->width,
- wl->display.current_output->height);
- wl_shell_surface_set_fullscreen(wl->window.shell_surface,
- WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
- 0, fs_output);
+ zxdg_toplevel_v6_set_fullscreen(wl->window.xdg_toplevel, NULL);
+ //if (wl->display.current_output)
+ //schedule_resize(wl, wl->display.current_output->width,
+ // wl->display.current_output->height);
}
else {
MP_DBG(wl, "leaving fullscreen\n");
- wl->window.is_fullscreen = false;
- window_set_toplevel(wl);
- schedule_resize(wl, 0, wl->window.p_width, wl->window.p_height);
+ zxdg_toplevel_v6_unset_fullscreen(wl->window.xdg_toplevel);
+ //schedule_resize(wl, wl->window.p_width, wl->window.p_height);
}
}
@@ -1047,10 +1024,7 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
wl->window.events = 0;
return VO_TRUE;
case VOCTRL_FULLSCREEN:
- vo_wayland_fullscreen(vo);
- return VO_TRUE;
- case VOCTRL_ONTOP:
- vo_wayland_ontop(vo);
+ window_set_fullscreen(vo);
return VO_TRUE;
case VOCTRL_GET_UNFS_WINDOW_SIZE: {
int *s = arg, scale = 1;
@@ -1062,8 +1036,8 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
}
case VOCTRL_SET_UNFS_WINDOW_SIZE: {
int *s = arg;
- if (!wl->window.is_fullscreen)
- schedule_resize(wl, 0, s[0], s[1]);
+ if (!wl->window.state.fullscreen)
+ schedule_resize(wl, s[0], s[1]);
return VO_TRUE;
}
case VOCTRL_SET_CURSOR_VISIBILITY:
@@ -1097,6 +1071,9 @@ bool vo_wayland_config(struct vo *vo)
{
struct vo_wayland_state *wl = vo->wayland;
+ // reset states
+ wl->window.state.fullscreen = false;
+
struct mp_rect screenrc;
vo_wayland_update_screeninfo(vo, &screenrc);
@@ -1110,7 +1087,7 @@ bool vo_wayland_config(struct vo *vo)
wl->window.width = vo->dwidth;
wl->window.height = vo->dheight;
- vo_wayland_fullscreen(vo);
+ window_set_fullscreen(vo);
return true;
}