From: Alexandros Frantzis alexandros.frantzis@collabora.com
Update the gdi_device_manager API to enable drivers to set the registry mode (if not already set) in UpdateDisplayDevices.
Signed-off-by: Alexandros Frantzis alexandros.frantzis@collabora.com --- dlls/win32u/sysparams.c | 13 +++- dlls/wineandroid.drv/init.c | 2 +- dlls/winemac.drv/display.c | 115 +++++++++++++++------------------ dlls/winewayland.drv/display.c | 10 ++- dlls/winex11.drv/display.c | 50 ++++---------- dlls/winex11.drv/x11drv.h | 1 - dlls/winex11.drv/xrandr.c | 1 - include/wine/gdi_driver.h | 5 +- 8 files changed, 87 insertions(+), 110 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 60b12321953..2c423e2fe45 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1482,7 +1482,7 @@ static void add_monitor( const struct gdi_monitor *monitor, void *param ) if (hkey) NtClose( hkey ); }
-static void add_mode( const DEVMODEW *mode, void *param ) +static void add_mode( const DEVMODEW *mode, DWORD target, void *param ) { struct device_manager_ctx *ctx = param;
@@ -1496,7 +1496,14 @@ static void add_mode( const DEVMODEW *mode, void *param ) add_adapter( &default_adapter, ctx ); }
- if (write_adapter_mode( ctx->adapter_key, ctx->mode_count, mode )) + if (target == GDI_MODE_REGISTRY_IF_EMPTY) + { + DEVMODEW stored = {.dmSize = sizeof(DEVMODEW)}; + if (!read_adapter_mode( ctx->adapter_key, ENUM_REGISTRY_SETTINGS, &stored )) + write_adapter_mode( ctx->adapter_key, ENUM_REGISTRY_SETTINGS, mode ); + } + else if (target == GDI_MODE_NEXT && + write_adapter_mode( ctx->adapter_key, ctx->mode_count, mode )) { ctx->mode_count++; set_reg_value( ctx->adapter_key, mode_countW, REG_DWORD, &ctx->mode_count, sizeof(ctx->mode_count) ); @@ -1690,7 +1697,7 @@ static BOOL update_display_cache( BOOL force ) monitor.rc_work.bottom = mode.dmPelsHeight;
add_monitor( &monitor, &ctx ); - for (i = 0; i < ARRAY_SIZE(modes); ++i) add_mode( modes + i, &ctx ); + for (i = 0; i < ARRAY_SIZE(modes); ++i) add_mode( modes + i, GDI_MODE_NEXT, &ctx ); } release_display_manager_ctx( &ctx );
diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 074aa6c6257..09425ae8659 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -295,7 +295,7 @@ BOOL ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag device_manager->add_gpu( &gpu, param ); device_manager->add_adapter( &adapter, param ); device_manager->add_monitor( &gdi_monitor, param ); - device_manager->add_mode( &mode, param ); + device_manager->add_mode( &mode, GDI_MODE_NEXT, param ); force_display_devices_refresh = FALSE; }
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 6a798994e47..27cdb7575ff 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -864,6 +864,33 @@ static DEVMODEW *display_get_modes(CGDirectDisplayID display_id, int *modes_coun return devmodes; }
+static void display_get_current_mode(struct macdrv_display *display, DEVMODEW *devmode) +{ + CGDisplayModeRef display_mode; + CGDirectDisplayID display_id; + + display_id = display->displayID; + display_mode = CGDisplayCopyDisplayMode(display_id); + + devmode->dmPosition.x = CGRectGetMinX(display->frame); + devmode->dmPosition.y = CGRectGetMinY(display->frame); + devmode->dmFields |= DM_POSITION; + + display_mode_to_devmode(display_id, display_mode, devmode); + if (retina_enabled) + { + struct display_mode_descriptor *desc = create_original_display_mode_descriptor(display_id); + if (display_mode_matches_descriptor(display_mode, desc)) + { + devmode->dmPelsWidth *= 2; + devmode->dmPelsHeight *= 2; + } + free_display_mode_descriptor(desc); + } + + CFRelease(display_mode); +} + /*********************************************************************** * GetCurrentDisplaySettings (MACDRV.@) * @@ -872,8 +899,6 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, BOOL is_primary, LPDEVMOD { struct macdrv_display *displays = NULL; int num_displays, display_idx; - CGDisplayModeRef display_mode; - CGDirectDisplayID display_id; WCHAR *end;
TRACE("%s, %u, %p + %hu\n", debugstr_w(devname), is_primary, devmode, devmode->dmSize); @@ -890,26 +915,7 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, BOOL is_primary, LPDEVMOD return FALSE; }
- display_id = displays[display_idx].displayID; - display_mode = CGDisplayCopyDisplayMode(display_id); - - devmode->dmPosition.x = CGRectGetMinX(displays[display_idx].frame); - devmode->dmPosition.y = CGRectGetMinY(displays[display_idx].frame); - devmode->dmFields |= DM_POSITION; - - display_mode_to_devmode(display_id, display_mode, devmode); - if (retina_enabled) - { - struct display_mode_descriptor *desc = create_original_display_mode_descriptor(display_id); - if (display_mode_matches_descriptor(display_mode, desc)) - { - devmode->dmPelsWidth *= 2; - devmode->dmPelsHeight *= 2; - } - free_display_mode_descriptor(desc); - } - - CFRelease(display_mode); + display_get_current_mode(&displays[display_idx], devmode); macdrv_free_displays(displays);
TRACE("current mode -- %dx%d-%dx%dx%dbpp @%d Hz", @@ -1070,45 +1076,6 @@ done: return (err == kCGErrorSuccess); }
-/*********************************************************************** - * init_registry_display_settings - * - * Initialize registry display settings when new display devices are added. - */ -static void init_registry_display_settings(void) -{ - DEVMODEW dm = {.dmSize = sizeof(dm)}; - DISPLAY_DEVICEW dd = {sizeof(dd)}; - UNICODE_STRING str; - DWORD i = 0; - int ret; - - while (!NtUserEnumDisplayDevices(NULL, i++, &dd, 0)) - { - RtlInitUnicodeString(&str, dd.DeviceName); - - /* Skip if the device already has registry display settings */ - if (NtUserEnumDisplaySettings(&str, ENUM_REGISTRY_SETTINGS, &dm, 0)) - continue; - - if (!NtUserEnumDisplaySettings(&str, ENUM_CURRENT_SETTINGS, &dm, 0)) - { - ERR("Failed to query current display settings for %s.\n", wine_dbgstr_w(dd.DeviceName)); - continue; - } - - TRACE("Device %s current display mode %ux%u %ubits %uHz at %d,%d.\n", - wine_dbgstr_w(dd.DeviceName), (unsigned int)dm.dmPelsWidth, (unsigned int)dm.dmPelsHeight, - (unsigned int)dm.dmBitsPerPel, (unsigned int)dm.dmDisplayFrequency, (int)dm.dmPosition.x, (int)dm.dmPosition.y); - - ret = NtUserChangeDisplaySettings(&str, &dm, NULL, - CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY, NULL); - if (ret != DISP_CHANGE_SUCCESSFUL) - ERR("Failed to save registry display settings for %s, returned %d.\n", - wine_dbgstr_w(dd.DeviceName), ret); - } -} - /*********************************************************************** * macdrv_displays_changed * @@ -1127,7 +1094,6 @@ void macdrv_displays_changed(const macdrv_event *event) NtUserGetWindowThread(hwnd, NULL) == GetCurrentThreadId()) { macdrv_init_display_devices(TRUE); - init_registry_display_settings(); macdrv_resize_desktop(); } } @@ -1139,7 +1105,8 @@ BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage struct macdrv_adapter *adapters, *adapter; struct macdrv_monitor *monitors, *monitor; struct macdrv_gpu *gpus, *gpu; - INT gpu_count, adapter_count, monitor_count, mode_count; + struct macdrv_display *displays, *display; + INT gpu_count, adapter_count, monitor_count, mode_count, display_count; DEVMODEW *mode, *modes; DWORD len;
@@ -1205,11 +1172,31 @@ BOOL macdrv_UpdateDisplayDevices( const struct gdi_device_manager *device_manage (int)mode->dmBitsPerPel, (int)mode->dmDisplayFrequency, mode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un", mode->dmDisplayFlags & DM_INTERLACED ? "" : "non-"); - device_manager->add_mode( mode, param ); + device_manager->add_mode( mode, GDI_MODE_NEXT, param ); }
free(modes); macdrv_free_monitors(monitors); + + if (macdrv_get_displays(&displays, &display_count)) break; + + /* Initialize registry mode */ + for (display = displays; display < displays + display_count; display++) + { + if (display->id == adapter->id) + { + DEVMODEW current_mode = { .dmSize = sizeof(current_mode) }; + display_get_current_mode(display, ¤t_mode); + TRACE("current mode: %ux%u %ubits %uHz at %d,%d.\n", + (int)current_mode.dmPelsWidth, (int)current_mode.dmPelsHeight, + (int)current_mode.dmBitsPerPel, (int)current_mode.dmDisplayFrequency, + (int)current_mode.dmPosition.x, (int)current_mode.dmPosition.y); + device_manager->add_mode(¤t_mode, GDI_MODE_REGISTRY_IF_EMPTY, param); + break; + } + } + + macdrv_free_displays(displays); }
macdrv_free_adapters(adapters); diff --git a/dlls/winewayland.drv/display.c b/dlls/winewayland.drv/display.c index e72b26a9da0..b3f875dd8af 100644 --- a/dlls/winewayland.drv/display.c +++ b/dlls/winewayland.drv/display.c @@ -121,13 +121,19 @@ static void wayland_add_device_modes(const struct gdi_device_manager *device_man void *param, struct wayland_output *output) { struct wayland_output_mode *output_mode; + DEVMODEW mode = {.dmSize = sizeof(mode)};
RB_FOR_EACH_ENTRY(output_mode, &output->modes, struct wayland_output_mode, entry) { - DEVMODEW mode; populate_devmode(output_mode, &mode); - device_manager->add_mode(&mode, param); + device_manager->add_mode(&mode, GDI_MODE_NEXT, param); } + + populate_devmode(output->current_mode, &mode); + mode.dmFields |= DM_POSITION; + mode.dmPosition.x = 0; + mode.dmPosition.y = 0; + device_manager->add_mode(&mode, GDI_MODE_REGISTRY_IF_EMPTY, param); }
/*********************************************************************** diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 78de6a6f88b..6cf4a8da0ba 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -156,41 +156,6 @@ void X11DRV_Settings_Init(void) X11DRV_Settings_SetHandler(&nores_handler); }
-/* Initialize registry display settings when new display devices are added */ -void init_registry_display_settings(void) -{ - DEVMODEW dm = {.dmSize = sizeof(dm)}; - DISPLAY_DEVICEW dd = {sizeof(dd)}; - UNICODE_STRING device_name; - DWORD i = 0; - int ret; - - while (!NtUserEnumDisplayDevices( NULL, i++, &dd, 0 )) - { - RtlInitUnicodeString( &device_name, dd.DeviceName ); - - /* Skip if the device already has registry display settings */ - if (NtUserEnumDisplaySettings( &device_name, ENUM_REGISTRY_SETTINGS, &dm, 0 )) - continue; - - if (!NtUserEnumDisplaySettings( &device_name, ENUM_CURRENT_SETTINGS, &dm, 0 )) - { - ERR("Failed to query current display settings for %s.\n", wine_dbgstr_w(dd.DeviceName)); - continue; - } - - TRACE("Device %s current display mode %ux%u %ubits %uHz at %d,%d.\n", - wine_dbgstr_w(dd.DeviceName), (int)dm.dmPelsWidth, (int)dm.dmPelsHeight, - (int)dm.dmBitsPerPel, (int)dm.dmDisplayFrequency, (int)dm.dmPosition.x, (int)dm.dmPosition.y); - - ret = NtUserChangeDisplaySettings( &device_name, &dm, NULL, - CDS_GLOBAL | CDS_NORESET | CDS_UPDATEREGISTRY, NULL ); - if (ret != DISP_CHANGE_SUCCESSFUL) - ERR("Failed to save registry display settings for %s, returned %d.\n", - wine_dbgstr_w(dd.DeviceName), ret); - } -} - static void set_display_depth(ULONG_PTR display_id, DWORD depth) { struct x11drv_display_depth *display_depth; @@ -559,7 +524,7 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage struct gdi_gpu *gpus; INT gpu_count, adapter_count, monitor_count; INT gpu, adapter, monitor; - DEVMODEW *modes, *mode; + DEVMODEW *modes, *mode, current_mode; UINT mode_count;
if (!force && !force_display_devices_refresh) return TRUE; @@ -599,11 +564,22 @@ BOOL X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manage for (mode = modes; mode_count; mode_count--) { TRACE( "mode: %p\n", mode ); - device_manager->add_mode( mode, param ); + device_manager->add_mode( mode, GDI_MODE_NEXT, param ); mode = (DEVMODEW *)((char *)mode + sizeof(*modes) + modes[0].dmDriverExtra); }
settings_handler.free_modes( modes ); + + memset( ¤t_mode, 0, sizeof(current_mode) ); + current_mode.dmSize = sizeof(current_mode); + if (settings_handler.get_current_mode( adapters[adapter].id, ¤t_mode )) + { + TRACE("current mode: %ux%u %ubits %uHz at %d,%d.\n", + (int)current_mode.dmPelsWidth, (int)current_mode.dmPelsHeight, + (int)current_mode.dmBitsPerPel, (int)current_mode.dmDisplayFrequency, + (int)current_mode.dmPosition.x, (int)current_mode.dmPosition.y); + device_manager->add_mode( ¤t_mode, GDI_MODE_REGISTRY_IF_EMPTY, param ); + } }
handler->free_adapters(adapters); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index c6328cf3fde..f3ca8f0cbb2 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -758,7 +758,6 @@ extern void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *han
extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height ) DECLSPEC_HIDDEN; extern void X11DRV_resize_desktop(void) DECLSPEC_HIDDEN; -extern void init_registry_display_settings(void) DECLSPEC_HIDDEN; extern BOOL is_virtual_desktop(void) DECLSPEC_HIDDEN; extern BOOL is_desktop_fullscreen(void) DECLSPEC_HIDDEN; extern BOOL is_detached_mode(const DEVMODEW *) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index 7c32e683c5d..3731ca6b4d0 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -1188,7 +1188,6 @@ static BOOL xrandr14_device_change_handler( HWND hwnd, XEvent *event ) if (hwnd == NtUserGetDesktopWindow() && NtUserGetWindowThread( hwnd, NULL ) == GetCurrentThreadId()) { X11DRV_DisplayDevices_Init( TRUE ); - init_registry_display_settings(); X11DRV_resize_desktop(); } /* Update xinerama monitors for xinerama_get_fullscreen_monitors() */ diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index c492252d4ab..53607bbcc4b 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -261,12 +261,15 @@ struct gdi_monitor UINT edid_len; };
+#define GDI_MODE_NEXT 0 +#define GDI_MODE_REGISTRY_IF_EMPTY 1 + struct gdi_device_manager { void (*add_gpu)( const struct gdi_gpu *gpu, void *param ); void (*add_adapter)( const struct gdi_adapter *adapter, void *param ); void (*add_monitor)( const struct gdi_monitor *monitor, void *param ); - void (*add_mode)( const DEVMODEW *mode, void *param ); + void (*add_mode)( const DEVMODEW *mode, DWORD target, void *param ); };
#define WINE_DM_UNSUPPORTED 0x80000000