mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-04-05 11:20:38 +02:00
xwayland: Add emulated modes larger than the logical mode
Up to the native mode, as reported by the wl_output protocol. This ensures that fullscreen apps can always use the native mode. Also ensure the root window is large enough for the output at its current position with the native mode.
This commit is contained in:
parent
52ea534bff
commit
90d2a1dc29
1 changed files with 44 additions and 22 deletions
|
|
@ -164,15 +164,23 @@ output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *heigh
|
|||
static inline void
|
||||
output_get_new_size(struct xwl_output *xwl_output, int *width, int *height)
|
||||
{
|
||||
int logical_width, logical_height;
|
||||
int logical_width, logical_height, max_width, max_height;
|
||||
|
||||
output_get_logical_extents(xwl_output, &logical_width, &logical_height);
|
||||
|
||||
if (*width < xwl_output->logical_x + logical_width)
|
||||
*width = xwl_output->logical_x + logical_width;
|
||||
if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) {
|
||||
max_width = max(logical_width, xwl_output->mode_width);
|
||||
max_height = max(logical_height, xwl_output->mode_height);
|
||||
} else {
|
||||
max_width = max(logical_width, xwl_output->mode_height);
|
||||
max_height = max(logical_height, xwl_output->mode_width);
|
||||
}
|
||||
|
||||
if (*height < xwl_output->logical_y + logical_height)
|
||||
*height = xwl_output->logical_y + logical_height;
|
||||
if (*width < xwl_output->logical_x + max_width)
|
||||
*width = xwl_output->logical_x + max_width;
|
||||
|
||||
if (*height < xwl_output->logical_y + max_height)
|
||||
*height = xwl_output->logical_y + max_height;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
@ -372,11 +380,11 @@ const int32_t xwl_output_fake_modes[][2] = {
|
|||
static RRModePtr *
|
||||
output_get_rr_modes(struct xwl_output *xwl_output,
|
||||
int32_t width, int32_t height,
|
||||
int *count)
|
||||
int *count, int *logical_mode)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_output->xwl_screen;
|
||||
RRModePtr *rr_modes;
|
||||
int i;
|
||||
int i = 0;
|
||||
|
||||
rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 2, sizeof(RRModePtr));
|
||||
if (!rr_modes)
|
||||
|
|
@ -385,8 +393,7 @@ output_get_rr_modes(struct xwl_output *xwl_output,
|
|||
*count = 0;
|
||||
|
||||
if (xwl_screen_has_resolution_change_emulation(xwl_screen) &&
|
||||
(width > xwl_output->mode_width ||
|
||||
(width == xwl_output->mode_width && height > xwl_output->mode_height))) {
|
||||
(width != xwl_output->mode_width || height != xwl_output->mode_height)) {
|
||||
/* Add native output mode as preferred */
|
||||
rr_modes[0] = xwayland_cvt(xwl_output->mode_width, xwl_output->mode_height,
|
||||
xwl_output->refresh / 1000.0, 0, 0);
|
||||
|
|
@ -394,6 +401,26 @@ output_get_rr_modes(struct xwl_output *xwl_output,
|
|||
goto err;
|
||||
|
||||
*count = 1;
|
||||
|
||||
/* Add fake modes larger than logical mode */
|
||||
for (; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
|
||||
if (xwl_output_fake_modes[i][0] <= width &&
|
||||
xwl_output_fake_modes[i][1] <= height)
|
||||
break;
|
||||
|
||||
/* Skip modes which are too big, avoid downscaling */
|
||||
if (xwl_output_fake_modes[i][0] >= xwl_output->mode_width &&
|
||||
xwl_output_fake_modes[i][1] >= xwl_output->mode_height)
|
||||
continue;
|
||||
|
||||
rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
|
||||
xwl_output_fake_modes[i][1],
|
||||
xwl_output->refresh / 1000.0, 0, 0);
|
||||
if (!rr_modes[*count])
|
||||
goto err;
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add logical output mode */
|
||||
|
|
@ -401,13 +428,13 @@ output_get_rr_modes(struct xwl_output *xwl_output,
|
|||
if (!rr_modes[*count])
|
||||
goto err;
|
||||
|
||||
(*count)++;
|
||||
*logical_mode = (*count)++;
|
||||
|
||||
if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation)
|
||||
return rr_modes;
|
||||
|
||||
/* Add fake modes */
|
||||
for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
|
||||
for (; i < ARRAY_SIZE(xwl_output_fake_modes); i++) {
|
||||
/* Skip logical output mode, already added */
|
||||
if (xwl_output_fake_modes[i][0] == width &&
|
||||
xwl_output_fake_modes[i][1] == height)
|
||||
|
|
@ -419,8 +446,8 @@ output_get_rr_modes(struct xwl_output *xwl_output,
|
|||
continue;
|
||||
|
||||
/* Skip modes which are too big, avoid downscaling */
|
||||
if (xwl_output_fake_modes[i][0] > width ||
|
||||
xwl_output_fake_modes[i][1] > height)
|
||||
if (xwl_output_fake_modes[i][0] > max(width, xwl_output->mode_width) ||
|
||||
xwl_output_fake_modes[i][1] > max(height, xwl_output->mode_height))
|
||||
continue;
|
||||
|
||||
rr_modes[*count] = xwayland_cvt(xwl_output_fake_modes[i][0],
|
||||
|
|
@ -679,7 +706,7 @@ apply_output_change(struct xwl_output *xwl_output)
|
|||
struct xwl_output *it;
|
||||
int logical_width, logical_height, count, has_this_output = 0;
|
||||
RRModePtr *randr_modes;
|
||||
RRModePtr default_mode;
|
||||
int logical_mode;
|
||||
|
||||
/* Clear out the "done" received flags */
|
||||
xwl_output->wl_output_done = FALSE;
|
||||
|
|
@ -689,16 +716,11 @@ apply_output_change(struct xwl_output *xwl_output)
|
|||
|
||||
if (xwl_output->randr_output) {
|
||||
/* Build a fresh modes array using the current refresh rate */
|
||||
randr_modes = output_get_rr_modes(xwl_output, logical_width, logical_height, &count);
|
||||
|
||||
if (randr_modes[0]->mode.width == logical_width &&
|
||||
randr_modes[0]->mode.height == logical_height)
|
||||
default_mode = randr_modes[0];
|
||||
else
|
||||
default_mode = randr_modes[1];
|
||||
randr_modes = output_get_rr_modes(xwl_output, logical_width, logical_height,
|
||||
&count, &logical_mode);
|
||||
|
||||
RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1);
|
||||
RRCrtcNotify(xwl_output->randr_crtc, default_mode,
|
||||
RRCrtcNotify(xwl_output->randr_crtc, randr_modes[logical_mode],
|
||||
xwl_output->logical_x, xwl_output->logical_y,
|
||||
xwl_output->rotation, NULL, 1, &xwl_output->randr_output);
|
||||
/* RROutputSetModes takes ownership of the passed in modes, so we only
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue