From: Rémi Bernon rbernon@codeweavers.com
Avoiding NtUserEnumDisplayDevices calls from GetCurrentDisplaySettings or ChangeDisplaySettings, as it requires entering the display device lock again. --- dlls/win32u/sysparams.c | 22 +++++++++++++++++----- dlls/winemac.drv/display.c | 24 +----------------------- dlls/winex11.drv/desktop.c | 8 ++------ dlls/winex11.drv/display.c | 31 ++++--------------------------- dlls/winex11.drv/x11drv.h | 6 +++--- dlls/winex11.drv/xrandr.c | 13 ++++--------- dlls/winex11.drv/xvidmode.c | 9 ++------- include/wine/gdi_driver.h | 3 ++- 8 files changed, 35 insertions(+), 81 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 900c8a92871..1bbbc7cdc32 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -542,6 +542,17 @@ static BOOL adapter_get_registry_settings( const struct adapter *adapter, DEVMOD return ret; }
+static BOOL adapter_get_current_settings( const struct adapter *adapter, DEVMODEW *mode ) +{ + BOOL ret; + + if (adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) mode->dmDisplayFlags |= WINE_DM_PRIMARY_DEVICE; + ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, mode ); + mode->dmDisplayFlags &= ~WINE_DM_PRIMARY_DEVICE; + + return ret; +} + static BOOL adapter_set_registry_settings( const struct adapter *adapter, const DEVMODEW *mode ) { HANDLE mutex; @@ -2214,7 +2225,7 @@ static BOOL adapter_get_full_mode( const struct adapter *adapter, const DEVMODEW if (!is_detached_mode( full_mode ) && (!full_mode->dmPelsWidth || !full_mode->dmPelsHeight || !(full_mode->dmFields & DM_POSITION))) { DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - if (!user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, ¤t_mode )) return FALSE; + if (!adapter_get_current_settings( adapter, ¤t_mode )) return FALSE; if (!full_mode->dmPelsWidth) full_mode->dmPelsWidth = current_mode.dmPelsWidth; if (!full_mode->dmPelsHeight) full_mode->dmPelsHeight = current_mode.dmPelsHeight; if (!(full_mode->dmFields & DM_POSITION)) @@ -2255,10 +2266,11 @@ static DEVMODEW *get_display_settings( const WCHAR *devname, const DEVMODEW *dev else { if (!devname) ret = adapter_get_registry_settings( adapter, mode ); - else ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, mode ); + else ret = adapter_get_current_settings( adapter, mode ); if (!ret) goto done; }
+ if (adapter->dev.state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE) mode->dmDisplayFlags |= WINE_DM_PRIMARY_DEVICE; lstrcpyW( mode->dmDeviceName, adapter->dev.device_name ); mode = NEXT_DEVMODEW(mode); } @@ -2489,7 +2501,7 @@ static LONG apply_display_settings( const WCHAR *devname, const DEVMODEW *devmod if ((adapter = find_adapter( NULL ))) { DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, ¤t_mode ); + if (!adapter_get_current_settings( adapter, ¤t_mode )) WARN( "Failed to get primary adapter current display settings.\n" ); adapter_release( adapter );
send_message( NtUserGetDesktopWindow(), WM_DISPLAYCHANGE, current_mode.dmBitsPerPel, @@ -2534,7 +2546,7 @@ static BOOL adapter_enum_display_settings( const struct adapter *adapter, DWORD DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; const DEVMODEW *adapter_mode;
- if (!(flags & EDS_ROTATEDMODE) && !user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, ¤t_mode )) + if (!(flags & EDS_ROTATEDMODE) && !adapter_get_current_settings( adapter, ¤t_mode )) { WARN( "Failed to query current display mode for EDS_ROTATEDMODE flag.\n" ); return FALSE; @@ -2582,7 +2594,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM devmode->dmDriverExtra = 0;
if (index == ENUM_REGISTRY_SETTINGS) ret = adapter_get_registry_settings( adapter, devmode ); - else if (index == ENUM_CURRENT_SETTINGS) ret = user_driver->pGetCurrentDisplaySettings( adapter->dev.device_name, devmode ); + else if (index == ENUM_CURRENT_SETTINGS) ret = adapter_get_current_settings( adapter, devmode ); else ret = adapter_enum_display_settings( adapter, index, devmode, flags ); adapter_release( adapter );
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 9012f54ad3d..bb1535f0d9c 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -685,24 +685,6 @@ void check_retina_status(void) } }
-static BOOL get_primary_adapter(WCHAR *name) -{ - DISPLAY_DEVICEW dd; - DWORD i; - - dd.cb = sizeof(dd); - for (i = 0; !NtUserEnumDisplayDevices(NULL, i, &dd, 0); ++i) - { - if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) - { - lstrcpyW(name, dd.DeviceName); - return TRUE; - } - } - - return FALSE; -} - static BOOL is_detached_mode(const DEVMODEW *mode) { return mode->dmFields & DM_POSITION && @@ -771,7 +753,6 @@ static CGDisplayModeRef find_best_display_mode(DEVMODEW *devmode, CFArrayRef dis */ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, LPVOID lpvoid) { - WCHAR primary_adapter[CCHDEVICENAME]; LONG ret = DISP_CHANGE_SUCCESSFUL; DEVMODEW *mode; int bpp; @@ -785,9 +766,6 @@ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, L
init_original_display_mode();
- if (!get_primary_adapter(primary_adapter)) - return DISP_CHANGE_FAILED; - if (macdrv_get_displays(&macdrv_displays, &num_displays)) return DISP_CHANGE_FAILED;
@@ -804,7 +782,7 @@ LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, HWND hwnd, DWORD flags, L
for (mode = displays; mode->dmSize && !ret; mode = NEXT_DEVMODEW(mode)) { - if (wcsicmp(primary_adapter, mode->dmDeviceName)) + if (!(mode->dmDisplayFlags & WINE_DM_PRIMARY_DEVICE)) { FIXME("Changing non-primary adapter settings is currently unsupported.\n"); continue; diff --git a/dlls/winex11.drv/desktop.c b/dlls/winex11.drv/desktop.c index c6a08291f6a..a9b20713ca1 100644 --- a/dlls/winex11.drv/desktop.c +++ b/dlls/winex11.drv/desktop.c @@ -123,13 +123,9 @@ BOOL is_virtual_desktop(void) }
/* Virtual desktop display settings handler */ -static BOOL X11DRV_desktop_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL X11DRV_desktop_get_id( const DEVMODEW *display, ULONG_PTR *id ) { - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter ) || wcsicmp( primary_adapter, device_name )) - return FALSE; - + if (!(display->u2.dmDisplayFlags & WINE_DM_PRIMARY_DEVICE)) return FALSE; *id = 0; return TRUE; } diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 2a4a34e2c02..24c12d253b2 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -66,14 +66,9 @@ void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handle * Default handlers if resolution switching is not enabled * */ -static BOOL nores_get_id(const WCHAR *device_name, ULONG_PTR *id) +static BOOL nores_get_id(const DEVMODEW *display, ULONG_PTR *id) { - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter )) - return FALSE; - - *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *id = (display->dmDisplayFlags & WINE_DM_PRIMARY_DEVICE) ? 1 : 0; return TRUE; }
@@ -196,24 +191,6 @@ void init_registry_display_settings(void) } }
-BOOL get_primary_adapter(WCHAR *name) -{ - DISPLAY_DEVICEW dd; - DWORD i; - - dd.cb = sizeof(dd); - for (i = 0; !NtUserEnumDisplayDevices( NULL, i, &dd, 0 ); ++i) - { - if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) - { - lstrcpyW(name, dd.DeviceName); - return TRUE; - } - } - - return FALSE; -} - static void set_display_depth(ULONG_PTR display_id, DWORD depth) { struct x11drv_display_depth *display_depth; @@ -271,7 +248,7 @@ BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, LPDEVMODEW devmode ) DEVMODEW mode; ULONG_PTR id;
- if (!settings_handler.get_id( name, &id ) || !settings_handler.get_current_mode( id, &mode )) + if (!settings_handler.get_id( devmode, &id ) || !settings_handler.get_current_mode( id, &mode )) { ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name)); return FALSE; @@ -409,7 +386,7 @@ LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, HWND hwnd, DWORD flags, if (!(ids = calloc( count, sizeof(*ids) ))) return DISP_CHANGE_FAILED; for (count = 0, mode = displays; mode->dmSize; mode = NEXT_DEVMODEW(mode), count++) { - if (!settings_handler.get_id( mode->dmDeviceName, ids + count )) goto done; + if (!settings_handler.get_id( mode, ids + count )) goto done; mode->dmPosition.x -= left_most; mode->dmPosition.y -= top_most; } diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f8f8fe3d4d1..523b474d349 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -706,11 +706,12 @@ struct x11drv_settings_handler /* Higher priority can override handlers with a lower priority */ UINT priority;
- /* get_id() will be called to map a device name, e.g., \.\DISPLAY1 to a driver specific id. + /* get_id() will be called to map a display settings to a driver specific id, + * from its device name, e.g., \.\DISPLAY1 and WINE_DM_PRIMARY_DEVICE dmDisplayFlag. * Following functions use this id to identify the device. * * Return FALSE if the device cannot be found and TRUE on success */ - BOOL (*get_id)(const WCHAR *device_name, ULONG_PTR *id); + BOOL (*get_id)(const DEVMODEW *display, ULONG_PTR *id);
/* get_modes() will be called to get a list of supported modes of the device of id in modes * with respect to flags, which could be 0, EDS_RAWMODE or EDS_ROTATEDMODE. If the implementation @@ -751,7 +752,6 @@ 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; extern BOOL create_desktop_win_data( Window win ) DECLSPEC_HIDDEN; -extern BOOL get_primary_adapter(WCHAR *) DECLSPEC_HIDDEN; void X11DRV_Settings_Init(void) DECLSPEC_HIDDEN;
void X11DRV_XF86VM_Init(void) DECLSPEC_HIDDEN; diff --git a/dlls/winex11.drv/xrandr.c b/dlls/winex11.drv/xrandr.c index c7f922b1aae..a0f7329e4ad 100644 --- a/dlls/winex11.drv/xrandr.c +++ b/dlls/winex11.drv/xrandr.c @@ -144,17 +144,12 @@ static int XRandRErrorHandler(Display *dpy, XErrorEvent *event, void *arg) }
/* XRandR 1.0 display settings handler */ -static BOOL xrandr10_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL xrandr10_get_id( const DEVMODEW *display, ULONG_PTR *id ) { - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter )) - return FALSE; - /* RandR 1.0 only supports changing the primary adapter settings. * For non-primary adapters, an id is still provided but getting * and changing non-primary adapters' settings will be ignored. */ - *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *id = (display->u2.dmDisplayFlags & WINE_DM_PRIMARY_DEVICE) ? 1 : 0; return TRUE; }
@@ -1224,7 +1219,7 @@ static void xrandr14_register_event_handlers(void) }
/* XRandR 1.4 display settings handler */ -static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) +static BOOL xrandr14_get_id( const DEVMODEW *display, ULONG_PTR *id ) { struct current_mode *tmp_modes, *new_current_modes = NULL; INT gpu_count, adapter_count, new_current_mode_count = 0; @@ -1234,7 +1229,7 @@ static BOOL xrandr14_get_id( const WCHAR *device_name, ULONG_PTR *id ) WCHAR *end;
/* Parse \.\DISPLAY%d */ - display_idx = wcstol( device_name + 11, &end, 10 ) - 1; + display_idx = wcstol( display->dmDeviceName + 11, &end, 10 ) - 1; if (*end) return FALSE;
diff --git a/dlls/winex11.drv/xvidmode.c b/dlls/winex11.drv/xvidmode.c index 95342a84223..b804b49d0d6 100644 --- a/dlls/winex11.drv/xvidmode.c +++ b/dlls/winex11.drv/xvidmode.c @@ -85,17 +85,12 @@ static int XVidModeErrorHandler(Display *dpy, XErrorEvent *event, void *arg) }
/* XF86VidMode display settings handler */ -static BOOL xf86vm_get_id(const WCHAR *device_name, ULONG_PTR *id) +static BOOL xf86vm_get_id(const DEVMODEW *display, ULONG_PTR *id) { - WCHAR primary_adapter[CCHDEVICENAME]; - - if (!get_primary_adapter( primary_adapter )) - return FALSE; - /* XVidMode only supports changing the primary adapter settings. * For non-primary adapters, an id is still provided but getting * and changing non-primary adapters' settings will be ignored. */ - *id = !wcsicmp( device_name, primary_adapter ) ? 1 : 0; + *id = (display->u2.dmDisplayFlags & WINE_DM_PRIMARY_DEVICE) ? 1 : 0; return TRUE; }
diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 596d27156af..5cfe89e6440 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -269,7 +269,8 @@ struct gdi_device_manager void (*add_mode)( const DEVMODEW *mode, void *param ); };
-#define WINE_DM_UNSUPPORTED 0x80000000 +#define WINE_DM_UNSUPPORTED 0x80000000 /* maybe set internally on added / enumerated modes */ +#define WINE_DM_PRIMARY_DEVICE 0x40000000 /* maybe set internally for GetCurrentDisplaySettings / ChangeDisplaySettings */
struct tagUPDATELAYEREDWINDOWINFO;