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.
This commit is contained in:
Alexandros Frantzis 2023-04-24 15:48:00 +03:00 committed by Alexandre Julliard
parent 4a69ec6f96
commit 0031c3b46c
4 changed files with 40 additions and 5 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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();
}
/**********************************************************************

View file

@ -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