Module: wine Branch: master Commit: 0031c3b46c89ca81d169213fae38d1a94ccc2506 URL: https://gitlab.winehq.org/wine/wine/-/commit/0031c3b46c89ca81d169213fae38d1a...
Author: Alexandros Frantzis alexandros.frantzis@collabora.com Date: Mon Apr 24 15:48:00 2023 +0300
winewayland.drv: Handle dynamic Wayland output events.
Handle Wayland output events sent after process initialization, and update the win32u display devices when handling these events in the desktop window process.
---
dlls/winewayland.drv/display.c | 14 +++++++++++--- dlls/winewayland.drv/wayland.c | 4 +++- dlls/winewayland.drv/wayland_output.c | 24 ++++++++++++++++++++++++ dlls/winewayland.drv/waylanddrv.h | 3 ++- 4 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/dlls/winewayland.drv/display.c b/dlls/winewayland.drv/display.c index d822a785898..f734c1714fa 100644 --- a/dlls/winewayland.drv/display.c +++ b/dlls/winewayland.drv/display.c @@ -34,9 +34,15 @@
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
-void wayland_init_display_devices(void) +static BOOL force_display_devices_refresh; + +void wayland_init_display_devices(BOOL force) { UINT32 num_path, num_mode; + + TRACE("force=%d\n", force); + + if (force) force_display_devices_refresh = TRUE; /* Trigger refresh in win32u */ NtUserGetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &num_path, &num_mode); } @@ -284,9 +290,11 @@ BOOL WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage struct wl_array output_info_array; struct output_info *output_info;
- if (!force) return TRUE; + if (!force && !force_display_devices_refresh) return TRUE;
- TRACE("force=%d\n", force); + TRACE("force=%d force_refresh=%d\n", force, force_display_devices_refresh); + + force_display_devices_refresh = FALSE;
wl_array_init(&output_info_array);
diff --git a/dlls/winewayland.drv/wayland.c b/dlls/winewayland.drv/wayland.c index dab23a555a2..38c53e280c5 100644 --- a/dlls/winewayland.drv/wayland.c +++ b/dlls/winewayland.drv/wayland.c @@ -135,7 +135,9 @@ BOOL wayland_process_init(void) wl_display_roundtrip_queue(process_wayland.wl_display, process_wayland.wl_event_queue); wl_display_roundtrip_queue(process_wayland.wl_display, process_wayland.wl_event_queue);
- wayland_init_display_devices(); + wayland_init_display_devices(FALSE); + + process_wayland.initialized = TRUE;
return TRUE; } diff --git a/dlls/winewayland.drv/wayland_output.c b/dlls/winewayland.drv/wayland_output.c index 5c93e16f3e1..8293f43b56f 100644 --- a/dlls/winewayland.drv/wayland_output.c +++ b/dlls/winewayland.drv/wayland_output.c @@ -97,6 +97,26 @@ static void wayland_output_add_mode(struct wayland_output *output, if (current) output->current_mode = mode; }
+static void maybe_init_display_devices(void) +{ + DWORD desktop_pid = 0; + HWND desktop_hwnd; + + /* Right after process init we initialize all the display devices, so there + * is no need to react to each individual event at that time. This check + * also helps us avoid calling NtUserGetDesktopWindow() (see below) at + * process init time, since it may not be safe. */ + if (!process_wayland.initialized) return; + + desktop_hwnd = NtUserGetDesktopWindow(); + NtUserGetWindowThread(desktop_hwnd, &desktop_pid); + + /* We only update the display devices from the desktop process. */ + if (GetCurrentProcessId() != desktop_pid) return; + + wayland_init_display_devices(TRUE); +} + static void wayland_output_done(struct wayland_output *output) { struct wayland_output_mode *mode; @@ -111,6 +131,8 @@ static void wayland_output_done(struct wayland_output *output) mode->width, mode->height, mode->refresh, output->current_mode == mode ? "*" : ""); } + + maybe_init_display_devices(); }
static void output_handle_geometry(void *data, struct wl_output *wl_output, @@ -283,6 +305,8 @@ void wayland_output_destroy(struct wayland_output *output) wl_output_destroy(output->wl_output); free(output->name); free(output); + + maybe_init_display_devices(); }
/********************************************************************** diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index d5cbb47bf9e..95d115113b3 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -47,6 +47,7 @@ extern struct wayland process_wayland DECLSPEC_HIDDEN;
struct wayland { + BOOL initialized; struct wl_display *wl_display; struct wl_event_queue *wl_event_queue; struct wl_registry *wl_registry; @@ -80,7 +81,7 @@ struct wayland_output */
BOOL wayland_process_init(void) DECLSPEC_HIDDEN; -void wayland_init_display_devices(void) DECLSPEC_HIDDEN; +void wayland_init_display_devices(BOOL force) DECLSPEC_HIDDEN;
/********************************************************************** * Wayland output