diff options
author | Hans de Goede <hdegoede@redhat.com> | 2019-08-29 23:04:36 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2019-10-12 12:19:14 +0200 |
commit | aca0a588eb40a5e6669094a2ab7f71ca0ba06b16 (patch) | |
tree | 8074b915dc3b4559356c06a7b00d25a4f8f878fa | |
parent | 905cb8b9e27add5f49a45fe167a0005bf05218bc (diff) |
xwayland: Add support for storing per client per output emulated resolution
Add support for storing per output randr/vidmode emulated resolution
into the per client data.
Since we do not have a free/delete callback for the client this uses
a simple static array. The entries are tied to a specific output by the
server_output_id, with a server_output_id of 0 indicating a free slot
(0 is the "None" Wayland object id).
Note that even if we were to store this in a linked list, we would still
need the server_output_id as this is *per client* *per output*.
This is a preparation patch for adding randr/vidmode resolution
change emulation.
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r-- | hw/xwayland/xwayland-output.c | 67 | ||||
-rw-r--r-- | hw/xwayland/xwayland.h | 17 |
2 files changed, 84 insertions, 0 deletions
diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index abbddddf9..f91e676c6 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -245,6 +245,73 @@ update_screen_size(struct xwl_output *xwl_output, int width, int height) update_desktop_dimensions(); } +struct xwl_emulated_mode * +xwl_output_get_emulated_mode_for_client(struct xwl_output *xwl_output, + ClientPtr client) +{ + struct xwl_client *xwl_client = xwl_client_get(client); + int i; + + if (!xwl_output) + return NULL; + + for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) { + if (xwl_client->emulated_modes[i].server_output_id == + xwl_output->server_output_id) + return &xwl_client->emulated_modes[i]; + } + + return NULL; +} + +static void +xwl_output_add_emulated_mode_for_client(struct xwl_output *xwl_output, + ClientPtr client, + RRModePtr mode, + Bool from_vidmode) +{ + struct xwl_client *xwl_client = xwl_client_get(client); + struct xwl_emulated_mode *emulated_mode; + int i; + + emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client); + if (!emulated_mode) { + /* Find a free spot in the emulated modes array */ + for (i = 0; i < XWL_CLIENT_MAX_EMULATED_MODES; i++) { + if (xwl_client->emulated_modes[i].server_output_id == 0) { + emulated_mode = &xwl_client->emulated_modes[i]; + break; + } + } + } + if (!emulated_mode) { + static Bool warned; + + if (!warned) { + ErrorF("Ran out of space for emulated-modes, not adding mode"); + warned = TRUE; + } + + return; + } + + emulated_mode->server_output_id = xwl_output->server_output_id; + emulated_mode->width = mode->mode.width; + emulated_mode->height = mode->mode.height; + emulated_mode->from_vidmode = from_vidmode; +} + +static void +xwl_output_remove_emulated_mode_for_client(struct xwl_output *xwl_output, + ClientPtr client) +{ + struct xwl_emulated_mode *emulated_mode; + + emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, client); + if (emulated_mode) + memset(emulated_mode, 0, sizeof(*emulated_mode)); +} + /* From hw/xfree86/common/xf86DefModeSet.c with some obscure modes dropped */ const int32_t xwl_output_fake_modes[][2] = { /* 4:3 (1.33) */ diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h index 9c7fb6691..5a2397cdc 100644 --- a/hw/xwayland/xwayland.h +++ b/hw/xwayland/xwayland.h @@ -377,7 +377,21 @@ struct xwl_output { Bool xdg_output_done; }; +/* Per client per output emulated randr/vidmode resolution info. */ +struct xwl_emulated_mode { + uint32_t server_output_id; + int32_t width; + int32_t height; + Bool from_vidmode; +}; + +/* Apps which use randr/vidmode to change the mode when going fullscreen, + * usually change the mode of only a single monitor, so this should be plenty. + */ +#define XWL_CLIENT_MAX_EMULATED_MODES 16 + struct xwl_client { + struct xwl_emulated_mode emulated_modes[XWL_CLIENT_MAX_EMULATED_MODES]; }; struct xwl_client *xwl_client_get(ClientPtr client); @@ -421,6 +435,9 @@ void xwl_output_destroy(struct xwl_output *xwl_output); void xwl_output_remove(struct xwl_output *xwl_output); +struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client( + struct xwl_output *xwl_output, ClientPtr client); + RRModePtr xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, Bool Interlaced); |