summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/wayland_common.c154
1 files changed, 89 insertions, 65 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 14bb63b279..6435cd7c77 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -792,6 +792,56 @@ static const struct wl_data_device_listener data_device_listener = {
data_device_handle_selection,
};
+static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b) {
+ // euclidean algorithm
+ int larger;
+ int smaller;
+ if (a > b) {
+ larger = a;
+ smaller = b;
+ } else {
+ larger = b;
+ smaller = a;
+ }
+ int remainder = larger - smaller * floor(larger/smaller);
+ if (remainder == 0) {
+ wl->gcd = smaller;
+ } else {
+ greatest_common_divisor(wl, smaller, remainder);
+ }
+}
+
+static void set_geometry(struct vo_wayland_state *wl)
+{
+ struct vo *vo = wl->vo;
+
+ struct vo_win_geometry geo;
+ struct mp_rect screenrc = wl->current_output->geometry;
+ vo_calc_window_geometry(vo, &screenrc, &geo);
+ vo_apply_window_geometry(vo, &geo);
+
+ greatest_common_divisor(wl, vo->dwidth, vo->dheight);
+ wl->reduced_width = vo->dwidth / wl->gcd;
+ wl->reduced_height = vo->dheight / wl->gcd;
+
+ wl->vdparams.x0 = 0;
+ wl->vdparams.y0 = 0;
+ wl->vdparams.x1 = vo->dwidth / wl->scaling;
+ wl->vdparams.y1 = vo->dheight / wl->scaling;
+}
+
+static void rescale_geometry_dimensions(struct vo_wayland_state *wl, double factor)
+{
+ wl->vdparams.x1 *= factor;
+ wl->vdparams.y1 *= factor;
+ wl->window_size.x1 *= factor;
+ wl->window_size.y1 *= factor;
+ if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized) {
+ wl->geometry.x1 *= factor;
+ wl->geometry.y1 *= factor;
+ }
+}
+
static void surface_handle_enter(void *data, struct wl_surface *wl_surface,
struct wl_output *output)
{
@@ -807,9 +857,19 @@ static void surface_handle_enter(void *data, struct wl_surface *wl_surface,
}
wl->current_output->has_surface = true;
- if (wl->scaling != wl->current_output->scale)
+ set_geometry(wl);
+ wl->window_size = wl->vdparams;
+
+ if (wl->scaling != wl->current_output->scale && wl->vo_opts->hidpi_window_scale) {
+ double factor = (double)wl->scaling / wl->current_output->scale;
+ wl->scaling = wl->current_output->scale;
+ rescale_geometry_dimensions(wl, factor);
+ }
+
+ if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized) {
+ wl->geometry = wl->window_size;
wl->pending_vo_events |= VO_EVENT_RESIZE;
- wl->scaling = wl->current_output->scale;
+ }
MP_VERBOSE(wl, "Surface entered output %s %s (0x%x), scale = %i\n", o->make,
o->model, o->id, wl->scaling);
@@ -1320,7 +1380,7 @@ void vo_wayland_uninit(struct vo *vo)
vo->wl = NULL;
}
-static bool find_output(struct vo_wayland_state *wl)
+static struct vo_wayland_output *find_output(struct vo_wayland_state *wl)
{
int index = 0;
int screen_id = wl->vo_opts->fsscreen_id;
@@ -1330,27 +1390,22 @@ static bool find_output(struct vo_wayland_state *wl)
wl_list_for_each(output, &wl->output_list, link) {
if (index == 0)
fallback_output = output;
- if (screen_id == -1 && screen_name && !strcmp(screen_name, output->model)) {
- wl->current_output = output;
- break;
- }
- if (screen_id == index++) {
- wl->current_output = output;
- break;
- }
+ if (screen_id == -1 && !screen_name)
+ return output;
+ if (screen_id == -1 && screen_name && !strcmp(screen_name, output->model))
+ return output;
+ if (screen_id == index++)
+ return output;
}
- if (!wl->current_output) {
- if (!fallback_output) {
- MP_ERR(wl, "No screens could be found!\n");
- return false;
- } else if (wl->vo_opts->fsscreen_id >= 0) {
- MP_WARN(wl, "Screen index %i not found/unavailable! Falling back to screen 0!\n", screen_id);
- } else if (wl->vo_opts->fsscreen_name) {
- MP_WARN(wl, "Screen name %s not found/unavailable! Falling back to screen 0!\n", screen_name);
- }
- wl->current_output = fallback_output;
+ if (!fallback_output) {
+ MP_ERR(wl, "No screens could be found!\n");
+ return NULL;
+ } else if (wl->vo_opts->fsscreen_id >= 0) {
+ MP_WARN(wl, "Screen index %i not found/unavailable! Falling back to screen 0!\n", screen_id);
+ } else if (wl->vo_opts->fsscreen_name) {
+ MP_WARN(wl, "Screen name %s not found/unavailable! Falling back to screen 0!\n", screen_name);
}
- return true;
+ return fallback_output;
}
static void toggle_fullscreen(struct vo_wayland_state *wl)
@@ -1362,8 +1417,8 @@ static void toggle_fullscreen(struct vo_wayland_state *wl)
if (wl->vo_opts->fullscreen && !specific_screen) {
xdg_toplevel_set_fullscreen(wl->xdg_toplevel, NULL);
} else if (wl->vo_opts->fullscreen && specific_screen) {
- find_output(wl);
- xdg_toplevel_set_fullscreen(wl->xdg_toplevel, wl->current_output->output);
+ struct vo_wayland_output *output = find_output(wl);
+ xdg_toplevel_set_fullscreen(wl->xdg_toplevel, output->output);
} else {
xdg_toplevel_unset_fullscreen(wl->xdg_toplevel);
}
@@ -1389,25 +1444,6 @@ static void do_minimize(struct vo_wayland_state *wl)
xdg_toplevel_set_minimized(wl->xdg_toplevel);
}
-static void greatest_common_divisor(struct vo_wayland_state *wl, int a, int b) {
- // euclidean algorithm
- int larger;
- int smaller;
- if (a > b) {
- larger = a;
- smaller = b;
- } else {
- larger = b;
- smaller = a;
- }
- int remainder = larger - smaller * floor(larger/smaller);
- if (remainder == 0) {
- wl->gcd = smaller;
- } else {
- greatest_common_divisor(wl, smaller, remainder);
- }
-}
-
int vo_wayland_reconfig(struct vo *vo)
{
struct vo_wayland_state *wl = vo->wl;
@@ -1416,30 +1452,24 @@ int vo_wayland_reconfig(struct vo *vo)
MP_VERBOSE(wl, "Reconfiguring!\n");
if (!wl->current_output) {
- if (!find_output(wl))
+ wl->current_output = find_output(wl);
+ if (!wl->current_output)
return false;
if (!wl->vo_opts->hidpi_window_scale)
wl->current_output->scale = 1;
wl->scaling = wl->current_output->scale;
+ wl_surface_set_buffer_scale(wl->surface, wl->scaling);
+ wl_surface_commit(wl->surface);
configure = true;
}
- struct vo_win_geometry geo;
- struct mp_rect screenrc = wl->current_output->geometry;
- vo_calc_window_geometry(vo, &screenrc, &geo);
- vo_apply_window_geometry(vo, &geo);
-
- greatest_common_divisor(wl, vo->dwidth, vo->dheight);
- wl->reduced_width = vo->dwidth / wl->gcd;
- wl->reduced_height = vo->dheight / wl->gcd;
+ set_geometry(wl);
- wl->vdparams.x0 = 0;
- wl->vdparams.y0 = 0;
- wl->vdparams.x1 = vo->dwidth / wl->scaling;
- wl->vdparams.y1 = vo->dheight / wl->scaling;
- if (wl->vo_opts->keepaspect && wl->vo_opts->keepaspect_window) {
+ if (wl->vo_opts->keepaspect && wl->vo_opts->keepaspect_window)
wl->window_size = wl->vdparams;
- }
+
+ if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized)
+ wl->geometry = wl->window_size;
if (wl->vo_opts->fullscreen)
toggle_fullscreen(wl);
@@ -1450,18 +1480,12 @@ int vo_wayland_reconfig(struct vo *vo)
if (wl->vo_opts->window_minimized)
do_minimize(wl);
- wl_surface_set_buffer_scale(wl->surface, wl->scaling);
- wl_surface_commit(wl->surface);
-
if (configure) {
wl->window_size = wl->vdparams;
- wl->geometry = wl->vdparams;
+ wl->geometry = wl->window_size;
wl_display_roundtrip(wl->display);
}
- if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized)
- wl->geometry = wl->window_size;
-
wl->pending_vo_events |= VO_EVENT_RESIZE;
return true;