-- v3: win32u: Use the current display mode as monitor rect. win32u: Keep track of the display source physical display mode. win32u: Add virtual modes when drivers report a single display mode. win32u: Remove unnecessary GetCurrentDisplaySettings call. win32u: Cache display source current display settings. win32u: Remove now unnecessary GetDisplayDepth driver entry. win32u: Keep the source depth separately from the current mode. win32u: Always write the source current mode to the registry. win32u: Make sure to load drivers when updating the display cache.
From: Rémi Bernon rbernon@codeweavers.com
If the registry is initialized, a process calling ChangeDisplaySettings will only load the driver when calling GetCurrentDisplaySettings in source_get_full_mode / source_get_current_settings.
As we're going to cache the current display mode, this will not be called anymore and the driver won't be loaded at all. So, make sure we load it earlier instead. --- dlls/win32u/sysparams.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ced9c61db06..73a2a062f16 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -2051,7 +2051,8 @@ BOOL update_display_cache( BOOL force ) return TRUE; }
- if (force) + if (!force) get_display_driver(); /* make sure at least to load the user driver */ + else { if (!get_vulkan_gpus( &ctx.vulkan_gpus )) WARN( "Failed to find any vulkan GPU\n" ); if (!(status = update_display_devices( &ctx ))) add_vulkan_only_gpus( &ctx );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 2 +- dlls/win32u/sysparams.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 995b3cab6d9..54e5c04fce9 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -753,7 +753,7 @@ static void nulldrv_UpdateClipboard(void) static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lparam ) { - return E_NOTIMPL; /* use default implementation */ + return DISP_CHANGE_SUCCESSFUL; }
static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode ) diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 73a2a062f16..a995432d01c 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -3497,12 +3497,11 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo }
/* use the default implementation in virtual desktop mode */ - if (is_virtual_desktop()) ret = E_NOTIMPL; + if (is_virtual_desktop()) ret = DISP_CHANGE_SUCCESSFUL; else ret = user_driver->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam );
- if (ret == E_NOTIMPL) + if (ret == DISP_CHANGE_SUCCESSFUL) { - /* default implementation: write current display settings to the registry. */ mode = displays; LIST_FOR_EACH_ENTRY( source, &sources, struct source, entry ) { @@ -3510,7 +3509,6 @@ static LONG apply_display_settings( struct source *target, const DEVMODEW *devmo WARN( "Failed to write source %u current mode.\n", source->id ); mode = NEXT_DEVMODEW(mode); } - ret = DISP_CHANGE_SUCCESSFUL; } unlock_display_devices();
From: Rémi Bernon rbernon@codeweavers.com
The host may not actually have support for the selected depth, when emulating 8 or 16bpp display modes, and we'll get display device updates with the default display depth instead.
We still want to report the desired display depth to the applications, so keep it with the sources. --- dlls/win32u/sysparams.c | 49 ++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a995432d01c..86c3a9de025 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -71,6 +71,7 @@ static const WCHAR noW[] = {'N','o',0}; static const WCHAR modesW[] = {'M','o','d','e','s',0}; static const WCHAR mode_countW[] = {'M','o','d','e','C','o','u','n','t',0}; static const WCHAR dpiW[] = {'D','p','i',0}; +static const WCHAR depthW[] = {'D','e','p','t','h',0};
static const char guid_devclass_displayA[] = "{4D36E968-E325-11CE-BFC1-08002BE10318}"; static const WCHAR guid_devclass_displayW[] = @@ -108,6 +109,7 @@ struct source unsigned int id; struct gpu *gpu; UINT dpi; + UINT depth; /* emulated depth */ UINT state_flags; UINT monitor_count; UINT mode_count; @@ -509,20 +511,20 @@ static BOOL source_get_current_settings( const struct source *source, DEVMODEW * if (is_virtual_desktop()) ret = FALSE; else ret = user_driver->pGetCurrentDisplaySettings( device_nameW, is_primary, mode );
- if (ret) return TRUE; - - /* default implementation: read current display settings from the registry. */ - - mutex = get_display_device_init_mutex(); - - if (!(hkey = reg_open_ascii_key( config_key, source->path ))) ret = FALSE; - else + if (!ret) { - ret = read_source_mode( hkey, ENUM_CURRENT_SETTINGS, mode ); - NtClose( hkey ); + /* default implementation: read current display settings from the registry. */ + mutex = get_display_device_init_mutex(); + if (!(hkey = reg_open_ascii_key( config_key, source->path ))) ret = FALSE; + else + { + ret = read_source_mode( hkey, ENUM_CURRENT_SETTINGS, mode ); + NtClose( hkey ); + } + release_display_device_init_mutex( mutex ); }
- release_display_device_init_mutex( mutex ); + if (ret && source->depth) mode->dmBitsPerPel = source->depth; return ret; }
@@ -538,6 +540,7 @@ static BOOL source_set_current_settings( const struct source *source, const DEVM else { ret = write_source_mode( hkey, ENUM_CURRENT_SETTINGS, mode ); + if (ret) set_reg_value( hkey, depthW, REG_DWORD, &mode->dmBitsPerPel, sizeof(mode->dmBitsPerPel) ); NtClose( hkey ); }
@@ -649,6 +652,10 @@ static BOOL read_source_from_registry( unsigned int index, struct source *source if (query_reg_ascii_value( hkey, "Dpi", value, sizeof(buffer) ) && value->Type == REG_DWORD) source->dpi = *(DWORD *)value->Data;
+ /* Depth */ + if (query_reg_ascii_value( hkey, "Depth", value, sizeof(buffer) ) && value->Type == REG_DWORD) + source->depth = *(const DWORD *)value->Data; + /* ModeCount */ if (query_reg_ascii_value( hkey, "ModeCount", value, sizeof(buffer) ) && value->Type == REG_DWORD) source->mode_count = *(const DWORD *)value->Data; @@ -3641,10 +3648,8 @@ static unsigned int active_unique_monitor_count(void)
INT get_display_depth( UNICODE_STRING *name ) { - WCHAR device_nameW[CCHDEVICENAME]; - char device_name[CCHDEVICENAME]; + DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; struct source *source; - BOOL is_primary; INT depth;
if (!lock_display_devices()) @@ -3659,20 +3664,8 @@ INT get_display_depth( UNICODE_STRING *name ) return 32; }
- is_primary = !!(source->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); - snprintf( device_name, sizeof(device_name), "\\.\DISPLAY%d", source->id + 1 ); - asciiz_to_unicode( device_nameW, device_name ); - - /* use the default implementation in virtual desktop mode */ - if (is_virtual_desktop()) depth = -1; - else depth = user_driver->pGetDisplayDepth( device_nameW, is_primary ); - - if (depth < 0) - { - DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - if (!source_get_current_settings( source, ¤t_mode )) depth = 32; - else depth = current_mode.dmBitsPerPel; - } + if (!source_get_current_settings( source, ¤t_mode )) depth = 32; + else depth = current_mode.dmBitsPerPel;
unlock_display_devices(); return depth;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 12 ------- dlls/winemac.drv/display.c | 9 ----- dlls/winemac.drv/gdi.c | 1 - dlls/winemac.drv/macdrv.h | 1 - dlls/winex11.drv/display.c | 73 -------------------------------------- dlls/winex11.drv/init.c | 1 - dlls/winex11.drv/x11drv.h | 1 - include/wine/gdi_driver.h | 3 +- 8 files changed, 1 insertion(+), 100 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 54e5c04fce9..628b6f92c23 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -761,11 +761,6 @@ static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LP return FALSE; /* use default implementation */ }
-static INT nulldrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) -{ - return -1; /* use default implementation */ -} - static UINT nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, void *param ) { return STATUS_NOT_IMPLEMENTED; @@ -1120,11 +1115,6 @@ static BOOL loaderdrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, return load_driver()->pGetCurrentDisplaySettings( name, is_primary, mode ); }
-static INT loaderdrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) -{ - return load_driver()->pGetDisplayDepth( name, is_primary ); -} - static void loaderdrv_SetCursor( HWND hwnd, HCURSOR cursor ) { load_driver()->pSetCursor( hwnd, cursor ); @@ -1273,7 +1263,6 @@ static const struct user_driver_funcs lazy_load_driver = /* display modes */ loaderdrv_ChangeDisplaySettings, loaderdrv_GetCurrentDisplaySettings, - loaderdrv_GetDisplayDepth, loaderdrv_UpdateDisplayDevices, /* windowing functions */ loaderdrv_CreateDesktop, @@ -1364,7 +1353,6 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(UpdateClipboard); SET_USER_FUNC(ChangeDisplaySettings); SET_USER_FUNC(GetCurrentDisplaySettings); - SET_USER_FUNC(GetDisplayDepth); SET_USER_FUNC(UpdateDisplayDevices); SET_USER_FUNC(CreateDesktop); SET_USER_FUNC(CreateWindow); diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index c160c286d21..54745bf6005 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -953,15 +953,6 @@ BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, BOOL is_primary, LPDEVMOD return TRUE; }
-/*********************************************************************** - * GetDisplayDepth (MACDRV.@) - * - */ -INT macdrv_GetDisplayDepth(LPCWSTR name, BOOL is_primary) -{ - return get_default_bpp(); -} - /*********************************************************************** * GetDeviceGammaRamp (MACDRV.@) */ diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 8492b0030c0..87b07e51460 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -276,7 +276,6 @@ static const struct user_driver_funcs macdrv_funcs = .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, .pGetCurrentDisplaySettings = macdrv_GetCurrentDisplaySettings, - .pGetDisplayDepth = macdrv_GetDisplayDepth, .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, .pGetKeyboardLayoutList = macdrv_GetKeyboardLayoutList, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index d3c54d72542..74e03d95f4d 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -130,7 +130,6 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern void macdrv_Beep(void); extern LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid); extern BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode); -extern INT macdrv_GetDisplayDepth(LPCWSTR name, BOOL is_primary); extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern UINT macdrv_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param); extern BOOL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp); diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 3ce21d203d2..6560f9efe85 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -36,16 +36,6 @@ static struct x11drv_settings_handler settings_handler;
#define NEXT_DEVMODEW(mode) ((DEVMODEW *)((char *)((mode) + 1) + (mode)->dmDriverExtra))
-struct x11drv_display_depth -{ - struct list entry; - x11drv_settings_id display_id; - DWORD depth; -}; - -/* Display device emulated depth list, protected by modes_section */ -static struct list x11drv_display_depth_list = LIST_INIT(x11drv_display_depth_list); - /* All Windows drivers seen so far either support 32 bit depths, or 24 bit depths, but never both. So if we have * a 32 bit framebuffer, report 32 bit bpps, otherwise 24 bit ones. */ @@ -53,8 +43,6 @@ static const unsigned int depths_24[] = {8, 16, 24}; static const unsigned int depths_32[] = {8, 16, 32}; const unsigned int *depths;
-static pthread_mutex_t settings_mutex = PTHREAD_MUTEX_INITIALIZER; - void X11DRV_Settings_SetHandler(const struct x11drv_settings_handler *new_handler) { if (new_handler->priority > settings_handler.priority) @@ -158,64 +146,6 @@ void X11DRV_Settings_Init(void) X11DRV_Settings_SetHandler(&nores_handler); }
-static void set_display_depth(x11drv_settings_id display_id, DWORD depth) -{ - struct x11drv_display_depth *display_depth; - - pthread_mutex_lock( &settings_mutex ); - LIST_FOR_EACH_ENTRY(display_depth, &x11drv_display_depth_list, struct x11drv_display_depth, entry) - { - if (display_depth->display_id.id == display_id.id) - { - display_depth->depth = depth; - pthread_mutex_unlock( &settings_mutex ); - return; - } - } - - display_depth = malloc(sizeof(*display_depth)); - if (!display_depth) - { - ERR("Failed to allocate memory.\n"); - pthread_mutex_unlock( &settings_mutex ); - return; - } - - display_depth->display_id = display_id; - display_depth->depth = depth; - list_add_head(&x11drv_display_depth_list, &display_depth->entry); - pthread_mutex_unlock( &settings_mutex ); -} - -static DWORD get_display_depth(x11drv_settings_id display_id) -{ - struct x11drv_display_depth *display_depth; - DWORD depth; - - pthread_mutex_lock( &settings_mutex ); - LIST_FOR_EACH_ENTRY(display_depth, &x11drv_display_depth_list, struct x11drv_display_depth, entry) - { - if (display_depth->display_id.id == display_id.id) - { - depth = display_depth->depth; - pthread_mutex_unlock( &settings_mutex ); - return depth; - } - } - pthread_mutex_unlock( &settings_mutex ); - return screen_bpp; -} - -INT X11DRV_GetDisplayDepth(LPCWSTR name, BOOL is_primary) -{ - x11drv_settings_id id; - - if (settings_handler.get_id( name, is_primary, &id )) - return get_display_depth( id ); - - return screen_bpp; -} - /*********************************************************************** * GetCurrentDisplaySettings (X11DRV.@) * @@ -232,7 +162,6 @@ BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW }
memcpy( &devmode->dmFields, &mode.dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); - if (!is_detached_mode( devmode )) devmode->dmBitsPerPel = get_display_depth( id ); return TRUE; }
@@ -326,8 +255,6 @@ static LONG apply_display_settings( DEVMODEW *displays, x11drv_settings_id *ids, (int)full_mode->dmBitsPerPel, (int)full_mode->dmDisplayOrientation);
ret = settings_handler.set_current_mode(*id, full_mode); - if (attached_mode && ret == DISP_CHANGE_SUCCESSFUL) - set_display_depth(*id, full_mode->dmBitsPerPel); free_full_mode(full_mode); if (ret != DISP_CHANGE_SUCCESSFUL) return ret; diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 0bba9727136..b02ed921a7b 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -444,7 +444,6 @@ static const struct user_driver_funcs x11drv_funcs = .pSystrayDockRemove = X11DRV_SystrayDockRemove, .pChangeDisplaySettings = X11DRV_ChangeDisplaySettings, .pGetCurrentDisplaySettings = X11DRV_GetCurrentDisplaySettings, - .pGetDisplayDepth = X11DRV_GetDisplayDepth, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktop = X11DRV_CreateDesktop, .pCreateWindow = X11DRV_CreateWindow, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index d2eb35b454e..7aecea229d3 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -217,7 +217,6 @@ extern void X11DRV_SystrayDockClear( HWND hwnd ); extern BOOL X11DRV_SystrayDockRemove( HWND hwnd ); extern LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid ); extern BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode ); -extern INT X11DRV_GetDisplayDepth( LPCWSTR name, BOOL is_primary ); extern UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, void *param ); extern BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height ); extern BOOL X11DRV_CreateWindow( HWND hwnd ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 6e051cfdaa3..9cdf00a5625 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -219,7 +219,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 97 +#define WINE_GDI_DRIVER_VERSION 98
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -360,7 +360,6 @@ struct user_driver_funcs /* display modes */ LONG (*pChangeDisplaySettings)(LPDEVMODEW,LPCWSTR,HWND,DWORD,LPVOID); BOOL (*pGetCurrentDisplaySettings)(LPCWSTR,BOOL,LPDEVMODEW); - INT (*pGetDisplayDepth)(LPCWSTR,BOOL); UINT (*pUpdateDisplayDevices)(const struct gdi_device_manager *,void*); /* windowing functions */ BOOL (*pCreateDesktop)(const WCHAR *,UINT,UINT);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 37 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 86c3a9de025..badd26c78e9 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -113,6 +113,7 @@ struct source UINT state_flags; UINT monitor_count; UINT mode_count; + DEVMODEW current; DEVMODEW *modes; };
@@ -497,35 +498,9 @@ static BOOL source_set_registry_settings( const struct source *source, const DEV
static BOOL source_get_current_settings( const struct source *source, DEVMODEW *mode ) { - BOOL is_primary = !!(source->state_flags & DISPLAY_DEVICE_PRIMARY_DEVICE); - WCHAR device_nameW[CCHDEVICENAME]; - char device_name[CCHDEVICENAME]; - HANDLE mutex; - HKEY hkey; - BOOL ret; - - snprintf( device_name, sizeof(device_name), "\\.\DISPLAY%d", source->id + 1 ); - asciiz_to_unicode( device_nameW, device_name ); - - /* use the default implementation in virtual desktop mode */ - if (is_virtual_desktop()) ret = FALSE; - else ret = user_driver->pGetCurrentDisplaySettings( device_nameW, is_primary, mode ); - - if (!ret) - { - /* default implementation: read current display settings from the registry. */ - mutex = get_display_device_init_mutex(); - if (!(hkey = reg_open_ascii_key( config_key, source->path ))) ret = FALSE; - else - { - ret = read_source_mode( hkey, ENUM_CURRENT_SETTINGS, mode ); - NtClose( hkey ); - } - release_display_device_init_mutex( mutex ); - } - - if (ret && source->depth) mode->dmBitsPerPel = source->depth; - return ret; + memcpy( &mode->dmFields, &source->current.dmFields, sizeof(*mode) - offsetof(DEVMODEW, dmFields) ); + if (source->depth) mode->dmBitsPerPel = source->depth; + return TRUE; }
static BOOL source_set_current_settings( const struct source *source, const DEVMODEW *mode ) @@ -673,6 +648,10 @@ static BOOL read_source_from_registry( unsigned int index, struct source *source } value = (void *)buffer;
+ /* Cache current display mode */ + if (read_source_mode( hkey, ENUM_CURRENT_SETTINGS, &source->current )) + source->current.dmSize = sizeof(source->current); + /* DeviceID */ size = query_reg_ascii_value( hkey, "GPUID", value, sizeof(buffer) ); NtClose( hkey );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 12 ----------- dlls/wineandroid.drv/init.c | 24 --------------------- dlls/winemac.drv/display.c | 42 ------------------------------------- dlls/winemac.drv/gdi.c | 1 - dlls/winemac.drv/macdrv.h | 1 - dlls/winex11.drv/display.c | 19 ----------------- dlls/winex11.drv/init.c | 1 - dlls/winex11.drv/x11drv.h | 1 - include/wine/gdi_driver.h | 3 +-- 9 files changed, 1 insertion(+), 103 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 628b6f92c23..02478b18a8a 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -756,11 +756,6 @@ static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_ return DISP_CHANGE_SUCCESSFUL; }
-static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode ) -{ - return FALSE; /* use default implementation */ -} - static UINT nulldrv_UpdateDisplayDevices( const struct gdi_device_manager *manager, void *param ) { return STATUS_NOT_IMPLEMENTED; @@ -1110,11 +1105,6 @@ static LONG loaderdrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primar return load_driver()->pChangeDisplaySettings( displays, primary_name, hwnd, flags, lparam ); }
-static BOOL loaderdrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode ) -{ - return load_driver()->pGetCurrentDisplaySettings( name, is_primary, mode ); -} - static void loaderdrv_SetCursor( HWND hwnd, HCURSOR cursor ) { load_driver()->pSetCursor( hwnd, cursor ); @@ -1262,7 +1252,6 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateClipboard, /* display modes */ loaderdrv_ChangeDisplaySettings, - loaderdrv_GetCurrentDisplaySettings, loaderdrv_UpdateDisplayDevices, /* windowing functions */ loaderdrv_CreateDesktop, @@ -1352,7 +1341,6 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(ClipboardWindowProc); SET_USER_FUNC(UpdateClipboard); SET_USER_FUNC(ChangeDisplaySettings); - SET_USER_FUNC(GetCurrentDisplaySettings); SET_USER_FUNC(UpdateDisplayDevices); SET_USER_FUNC(CreateDesktop); SET_USER_FUNC(CreateWindow); diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 7f21a3b13f1..75e1d5bc8e2 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -294,29 +294,6 @@ UINT ANDROID_UpdateDisplayDevices( const struct gdi_device_manager *device_manag }
-/*********************************************************************** - * ANDROID_GetCurrentDisplaySettings - */ -BOOL ANDROID_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode ) -{ - devmode->dmDisplayFlags = 0; - devmode->dmPosition.x = 0; - devmode->dmPosition.y = 0; - devmode->dmDisplayOrientation = 0; - devmode->dmDisplayFixedOutput = 0; - devmode->dmPelsWidth = screen_width; - devmode->dmPelsHeight = screen_height; - devmode->dmBitsPerPel = screen_bpp; - devmode->dmDisplayFrequency = 60; - devmode->dmFields = DM_POSITION | DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | - DM_BITSPERPEL | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY; - TRACE( "current mode -- %dx%d %d bpp @%d Hz\n", - (int)devmode->dmPelsWidth, (int)devmode->dmPelsHeight, - (int)devmode->dmBitsPerPel, (int)devmode->dmDisplayFrequency ); - return TRUE; -} - - /********************************************************************** * ANDROID_wine_get_wgl_driver */ @@ -338,7 +315,6 @@ static const struct user_driver_funcs android_drv_funcs = .pVkKeyScanEx = ANDROID_VkKeyScanEx, .pSetCursor = ANDROID_SetCursor, .pChangeDisplaySettings = ANDROID_ChangeDisplaySettings, - .pGetCurrentDisplaySettings = ANDROID_GetCurrentDisplaySettings, .pUpdateDisplayDevices = ANDROID_UpdateDisplayDevices, .pCreateDesktop = ANDROID_CreateDesktop, .pCreateWindow = ANDROID_CreateWindow, diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c index 54745bf6005..5aad67f1809 100644 --- a/dlls/winemac.drv/display.c +++ b/dlls/winemac.drv/display.c @@ -911,48 +911,6 @@ static void display_get_current_mode(struct macdrv_display *display, DEVMODEW *d CFRelease(display_mode); }
-/*********************************************************************** - * GetCurrentDisplaySettings (MACDRV.@) - * - */ -BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR devname, BOOL is_primary, LPDEVMODEW devmode) -{ - struct macdrv_display *displays = NULL; - int num_displays, display_idx; - WCHAR *end; - - TRACE("%s, %u, %p + %hu\n", debugstr_w(devname), is_primary, devmode, devmode->dmSize); - - init_original_display_mode(); - - if (macdrv_get_displays(&displays, &num_displays)) - return FALSE; - - display_idx = wcstol(devname + 11, &end, 10) - 1; - if (display_idx >= num_displays) - { - macdrv_free_displays(displays); - return FALSE; - } - - display_get_current_mode(&displays[display_idx], devmode); - macdrv_free_displays(displays); - - TRACE("current mode -- %dx%d-%dx%dx%dbpp @%d Hz", - (int)devmode->dmPosition.x, (int)devmode->dmPosition.y, - (int)devmode->dmPelsWidth, (int)devmode->dmPelsHeight, (int)devmode->dmBitsPerPel, - (int)devmode->dmDisplayFrequency); - if (devmode->dmDisplayOrientation) - TRACE(" rotated %u degrees", (unsigned int)devmode->dmDisplayOrientation * 90); - if (devmode->dmDisplayFixedOutput == DMDFO_STRETCH) - TRACE(" stretched"); - if (devmode->dmDisplayFlags & DM_INTERLACED) - TRACE(" interlaced"); - TRACE("\n"); - - return TRUE; -} - /*********************************************************************** * GetDeviceGammaRamp (MACDRV.@) */ diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 87b07e51460..f5c4c5eb7f1 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -275,7 +275,6 @@ static const struct user_driver_funcs macdrv_funcs = .pDesktopWindowProc = macdrv_DesktopWindowProc, .pDestroyCursorIcon = macdrv_DestroyCursorIcon, .pDestroyWindow = macdrv_DestroyWindow, - .pGetCurrentDisplaySettings = macdrv_GetCurrentDisplaySettings, .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, .pGetKeyboardLayoutList = macdrv_GetKeyboardLayoutList, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 74e03d95f4d..76a1ffbed60 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -129,7 +129,6 @@ static inline RECT rect_from_cgrect(CGRect cgrect) extern BOOL macdrv_ActivateKeyboardLayout(HKL hkl, UINT flags); extern void macdrv_Beep(void); extern LONG macdrv_ChangeDisplaySettings(LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid); -extern BOOL macdrv_GetCurrentDisplaySettings(LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode); extern LRESULT macdrv_ClipboardWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern UINT macdrv_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param); extern BOOL macdrv_GetDeviceGammaRamp(PHYSDEV dev, LPVOID ramp); diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 6560f9efe85..c3a40f300db 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -146,25 +146,6 @@ void X11DRV_Settings_Init(void) X11DRV_Settings_SetHandler(&nores_handler); }
-/*********************************************************************** - * GetCurrentDisplaySettings (X11DRV.@) - * - */ -BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode ) -{ - DEVMODEW mode; - x11drv_settings_id id; - - if (!settings_handler.get_id( name, is_primary, &id ) || !settings_handler.get_current_mode( id, &mode )) - { - ERR("Failed to get %s current display settings.\n", wine_dbgstr_w(name)); - return FALSE; - } - - memcpy( &devmode->dmFields, &mode.dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); - return TRUE; -} - BOOL is_detached_mode(const DEVMODEW *mode) { return mode->dmFields & DM_POSITION && diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index b02ed921a7b..9f94a902620 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -443,7 +443,6 @@ static const struct user_driver_funcs x11drv_funcs = .pSystrayDockClear = X11DRV_SystrayDockClear, .pSystrayDockRemove = X11DRV_SystrayDockRemove, .pChangeDisplaySettings = X11DRV_ChangeDisplaySettings, - .pGetCurrentDisplaySettings = X11DRV_GetCurrentDisplaySettings, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktop = X11DRV_CreateDesktop, .pCreateWindow = X11DRV_CreateWindow, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 7aecea229d3..02cba58f09f 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -216,7 +216,6 @@ extern BOOL X11DRV_SystrayDockInsert( HWND owner, UINT cx, UINT cy, void *icon ) extern void X11DRV_SystrayDockClear( HWND hwnd ); extern BOOL X11DRV_SystrayDockRemove( HWND hwnd ); extern LONG X11DRV_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_name, HWND hwnd, DWORD flags, LPVOID lpvoid ); -extern BOOL X11DRV_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW devmode ); extern UINT X11DRV_UpdateDisplayDevices( const struct gdi_device_manager *device_manager, void *param ); extern BOOL X11DRV_CreateDesktop( const WCHAR *name, UINT width, UINT height ); extern BOOL X11DRV_CreateWindow( HWND hwnd ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 9cdf00a5625..8d628a426ae 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -219,7 +219,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 98 +#define WINE_GDI_DRIVER_VERSION 99
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -359,7 +359,6 @@ struct user_driver_funcs void (*pUpdateClipboard)(void); /* display modes */ LONG (*pChangeDisplaySettings)(LPDEVMODEW,LPCWSTR,HWND,DWORD,LPVOID); - BOOL (*pGetCurrentDisplaySettings)(LPCWSTR,BOOL,LPDEVMODEW); UINT (*pUpdateDisplayDevices)(const struct gdi_device_manager *,void*); /* windowing functions */ BOOL (*pCreateDesktop)(const WCHAR *,UINT,UINT);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 196 +++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 85 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index badd26c78e9..80966ee0eff 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1496,10 +1496,96 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) } }
+static DEVMODEW *get_virtual_modes( const DEVMODEW *current, const DEVMODEW *initial, + const DEVMODEW *maximum, UINT32 *modes_count ) +{ + static struct screen_size + { + unsigned int width; + unsigned int height; + } screen_sizes[] = { + /* 4:3 */ + { 320, 240}, + { 400, 300}, + { 512, 384}, + { 640, 480}, + { 768, 576}, + { 800, 600}, + {1024, 768}, + {1152, 864}, + {1280, 960}, + {1400, 1050}, + {1600, 1200}, + {2048, 1536}, + /* 5:4 */ + {1280, 1024}, + {2560, 2048}, + /* 16:9 */ + {1280, 720}, + {1366, 768}, + {1600, 900}, + {1920, 1080}, + {2560, 1440}, + {3840, 2160}, + /* 16:10 */ + { 320, 200}, + { 640, 400}, + {1280, 800}, + {1440, 900}, + {1680, 1050}, + {1920, 1200}, + {2560, 1600} + }; + UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, count; + BOOL vertical = initial->dmDisplayOrientation & 1; + DEVMODEW *modes; + + modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) ); + + for (count = i = 0; modes && i < ARRAY_SIZE(depths); ++i) + { + DEVMODEW mode = + { + .dmSize = sizeof(mode), + .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, + .dmDisplayFrequency = 60, + .dmBitsPerPel = depths[i], + .dmDisplayOrientation = initial->dmDisplayOrientation, + }; + + for (j = 0; j < ARRAY_SIZE(screen_sizes); ++j) + { + mode.dmPelsWidth = vertical ? screen_sizes[j].height : screen_sizes[j].width; + mode.dmPelsHeight = vertical ? screen_sizes[j].width : screen_sizes[j].height; + + if (mode.dmPelsWidth > maximum->dmPelsWidth || mode.dmPelsHeight > maximum->dmPelsHeight) continue; + if (mode.dmPelsWidth == maximum->dmPelsWidth && mode.dmPelsHeight == maximum->dmPelsHeight) continue; + if (mode.dmPelsWidth == initial->dmPelsWidth && mode.dmPelsHeight == initial->dmPelsHeight) continue; + modes[count++] = mode; + } + + mode.dmPelsWidth = vertical ? initial->dmPelsHeight : initial->dmPelsWidth; + mode.dmPelsHeight = vertical ? initial->dmPelsWidth : initial->dmPelsHeight; + modes[count++] = mode; + + if (maximum->dmPelsWidth != initial->dmPelsWidth || maximum->dmPelsHeight != initial->dmPelsHeight) + { + mode.dmPelsWidth = vertical ? maximum->dmPelsHeight : maximum->dmPelsWidth; + mode.dmPelsHeight = vertical ? maximum->dmPelsWidth : maximum->dmPelsHeight; + modes[count++] = mode; + } + } + + *modes_count = count; + return modes; +} + static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW *modes, void *param ) { struct device_manager_ctx *ctx = param; - DEVMODEW dummy, detached = *current; + DEVMODEW dummy, detached = *current, virtual, *virtual_modes = NULL; + const DEVMODEW physical = modes_count == 1 ? *modes : *current; + UINT virtual_count;
TRACE( "current %s, modes_count %u, modes %p, param %p\n", debugstr_devmodew( current ), modes_count, modes, param );
@@ -1509,6 +1595,21 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW detached.dmPelsHeight = 0; if (!(ctx->source.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) current = &detached;
+ if (modes_count > 1 || current == &detached) + virtual_modes = NULL; + else + { + if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, &virtual )) + virtual = physical; + + if ((virtual_modes = get_virtual_modes( &virtual, current, &physical, &virtual_count ))) + { + modes_count = virtual_count; + modes = virtual_modes; + current = &virtual; + } + } + if (current == &detached || !read_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, &dummy )) write_source_mode( ctx->source_key, ENUM_REGISTRY_SETTINGS, current ); write_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, current ); @@ -1517,6 +1618,8 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW set_reg_value( ctx->source_key, modesW, REG_BINARY, modes, modes_count * sizeof(*modes) ); set_reg_value( ctx->source_key, mode_countW, REG_DWORD, &modes_count, sizeof(modes_count) ); ctx->source.mode_count = modes_count; + + free( virtual_modes ); }
static const struct gdi_device_manager device_manager = @@ -1855,97 +1958,16 @@ static BOOL get_default_desktop_size( DWORD *width, DWORD *height ) return TRUE; }
-static void add_virtual_modes( struct device_manager_ctx *ctx, const DEVMODEW *current, - const DEVMODEW *initial, const DEVMODEW *maximum ) -{ - static struct screen_size - { - unsigned int width; - unsigned int height; - } screen_sizes[] = { - /* 4:3 */ - { 320, 240}, - { 400, 300}, - { 512, 384}, - { 640, 480}, - { 768, 576}, - { 800, 600}, - {1024, 768}, - {1152, 864}, - {1280, 960}, - {1400, 1050}, - {1600, 1200}, - {2048, 1536}, - /* 5:4 */ - {1280, 1024}, - {2560, 2048}, - /* 16:9 */ - {1280, 720}, - {1366, 768}, - {1600, 900}, - {1920, 1080}, - {2560, 1440}, - {3840, 2160}, - /* 16:10 */ - { 320, 200}, - { 640, 400}, - {1280, 800}, - {1440, 900}, - {1680, 1050}, - {1920, 1200}, - {2560, 1600} - }; - UINT depths[] = {8, 16, initial->dmBitsPerPel}, i, j, modes_count; - DEVMODEW *modes; - - if (!(modes = malloc( ARRAY_SIZE(depths) * (ARRAY_SIZE(screen_sizes) + 2) * sizeof(*modes) ))) return; - - for (modes_count = i = 0; i < ARRAY_SIZE(depths); ++i) - { - DEVMODEW mode = - { - .dmSize = sizeof(mode), - .dmFields = DM_DISPLAYORIENTATION | DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY, - .dmDisplayFrequency = 60, - .dmBitsPerPel = depths[i], - }; - - for (j = 0; j < ARRAY_SIZE(screen_sizes); ++j) - { - mode.dmPelsWidth = screen_sizes[j].width; - mode.dmPelsHeight = screen_sizes[j].height; - - if (mode.dmPelsWidth > maximum->dmPelsWidth || mode.dmPelsHeight > maximum->dmPelsHeight) continue; - if (mode.dmPelsWidth == maximum->dmPelsWidth && mode.dmPelsHeight == maximum->dmPelsHeight) continue; - if (mode.dmPelsWidth == initial->dmPelsWidth && mode.dmPelsHeight == initial->dmPelsHeight) continue; - modes[modes_count++] = mode; - } - - mode.dmPelsWidth = initial->dmPelsWidth; - mode.dmPelsHeight = initial->dmPelsHeight; - modes[modes_count++] = mode; - - if (maximum->dmPelsWidth != initial->dmPelsWidth || maximum->dmPelsWidth != initial->dmPelsHeight) - { - mode.dmPelsWidth = maximum->dmPelsWidth; - mode.dmPelsHeight = maximum->dmPelsHeight; - modes[modes_count++] = mode; - } - } - - add_modes( current, modes_count, modes, ctx ); - free( modes ); -} - static BOOL add_virtual_source( struct device_manager_ctx *ctx ) { - DEVMODEW current = {.dmSize = sizeof(current)}, initial = ctx->primary, maximum = ctx->primary; + DEVMODEW current = {.dmSize = sizeof(current)}, initial = ctx->primary, maximum = ctx->primary, *modes; struct source virtual_source = { .state_flags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_VGA_COMPATIBLE, .gpu = &ctx->gpu, }; struct gdi_monitor monitor = {0}; + UINT modes_count;
if (ctx->has_primary) ctx->source.id = ctx->source_count; else @@ -1987,7 +2009,11 @@ static BOOL add_virtual_source( struct device_manager_ctx *ctx ) monitor.rc_work.right = current.dmPelsWidth; monitor.rc_work.bottom = current.dmPelsHeight; add_monitor( &monitor, ctx ); - add_virtual_modes( ctx, ¤t, &initial, &maximum ); + + /* Expose the virtual source display modes as physical modes, to avoid DPI scaling */ + if (!(modes = get_virtual_modes( ¤t, &initial, &maximum, &modes_count ))) return STATUS_NO_MEMORY; + add_modes( ¤t, modes_count, modes, ctx ); + free( modes );
return STATUS_SUCCESS; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index 80966ee0eff..ccc6a24bc2d 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -39,6 +39,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(system);
+#define WINE_ENUM_PHYSICAL_SETTINGS ((DWORD) -3) + static LONG dpi_context; /* process DPI awareness context */
static HKEY video_key, enum_key, control_key, config_key, volatile_base_key; @@ -72,6 +74,7 @@ static const WCHAR modesW[] = {'M','o','d','e','s',0}; static const WCHAR mode_countW[] = {'M','o','d','e','C','o','u','n','t',0}; static const WCHAR dpiW[] = {'D','p','i',0}; static const WCHAR depthW[] = {'D','e','p','t','h',0}; +static const WCHAR physicalW[] = {'P','h','y','s','i','c','a','l',0};
static const char guid_devclass_displayA[] = "{4D36E968-E325-11CE-BFC1-08002BE10318}"; static const WCHAR guid_devclass_displayW[] = @@ -114,6 +117,7 @@ struct source UINT monitor_count; UINT mode_count; DEVMODEW current; + DEVMODEW physical; DEVMODEW *modes; };
@@ -432,10 +436,11 @@ static BOOL write_source_mode( HKEY hkey, UINT index, const DEVMODEW *mode ) { WCHAR bufferW[MAX_PATH] = {0};
- assert( index == ENUM_CURRENT_SETTINGS || index == ENUM_REGISTRY_SETTINGS ); + assert( index == ENUM_CURRENT_SETTINGS || index == ENUM_REGISTRY_SETTINGS || index == WINE_ENUM_PHYSICAL_SETTINGS );
if (index == ENUM_CURRENT_SETTINGS) asciiz_to_unicode( bufferW, "Current" ); else if (index == ENUM_REGISTRY_SETTINGS) asciiz_to_unicode( bufferW, "Registry" ); + else if (index == WINE_ENUM_PHYSICAL_SETTINGS) asciiz_to_unicode( bufferW, "Physical" ); else return FALSE;
return set_reg_value( hkey, bufferW, REG_BINARY, &mode->dmFields, sizeof(*mode) - offsetof(DEVMODEW, dmFields) ); @@ -447,10 +452,11 @@ static BOOL read_source_mode( HKEY hkey, UINT index, DEVMODEW *mode ) KEY_VALUE_PARTIAL_INFORMATION *value = (void *)value_buf; const char *key;
- assert( index == ENUM_CURRENT_SETTINGS || index == ENUM_REGISTRY_SETTINGS ); + assert( index == ENUM_CURRENT_SETTINGS || index == ENUM_REGISTRY_SETTINGS || index == WINE_ENUM_PHYSICAL_SETTINGS );
if (index == ENUM_CURRENT_SETTINGS) key = "Current"; else if (index == ENUM_REGISTRY_SETTINGS) key = "Registry"; + else if (index == WINE_ENUM_PHYSICAL_SETTINGS) key = "Physical"; else return FALSE;
if (!query_reg_ascii_value( hkey, key, value, sizeof(value_buf) )) return FALSE; @@ -648,9 +654,12 @@ static BOOL read_source_from_registry( unsigned int index, struct source *source } value = (void *)buffer;
- /* Cache current display mode */ + /* Cache current and physical display modes */ if (read_source_mode( hkey, ENUM_CURRENT_SETTINGS, &source->current )) source->current.dmSize = sizeof(source->current); + source->physical = source->current; + if (read_source_mode( hkey, WINE_ENUM_PHYSICAL_SETTINGS, &source->physical )) + source->physical.dmSize = sizeof(source->physical);
/* DeviceID */ size = query_reg_ascii_value( hkey, "GPUID", value, sizeof(buffer) ); @@ -1596,7 +1605,10 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW if (!(ctx->source.state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) current = &detached;
if (modes_count > 1 || current == &detached) + { + reg_delete_value( ctx->source_key, physicalW ); virtual_modes = NULL; + } else { if (!read_source_mode( ctx->source_key, ENUM_CURRENT_SETTINGS, &virtual )) @@ -1607,6 +1619,8 @@ static void add_modes( const DEVMODEW *current, UINT modes_count, const DEVMODEW modes_count = virtual_count; modes = virtual_modes; current = &virtual; + + write_source_mode( ctx->source_key, WINE_ENUM_PHYSICAL_SETTINGS, &physical ); } }
@@ -3621,6 +3635,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM
if (index == ENUM_REGISTRY_SETTINGS) ret = source_get_registry_settings( source, devmode ); else if (index == ENUM_CURRENT_SETTINGS) ret = source_get_current_settings( source, devmode ); + else if (index == WINE_ENUM_PHYSICAL_SETTINGS) ret = FALSE; else ret = source_enum_display_settings( source, index, devmode, flags ); source_release( source );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 83 +++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 44 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ccc6a24bc2d..60113f2608e 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -58,7 +58,6 @@ static const char devpkey_device_removal_policy[] = "Properties\{A45C254E-DF1C- static const char devpropkey_device_ispresentA[] = "Properties\{540B947E-8B40-45BC-A8A2-6A0B894CBDA2}\0005"; static const char devpropkey_monitor_gpu_luidA[] = "Properties\{CA085853-16CE-48AA-B114-DE9C72334223}\0001"; static const char devpropkey_monitor_output_idA[] = "Properties\{CA085853-16CE-48AA-B114-DE9C72334223}\0002"; -static const char wine_devpropkey_monitor_rcmonitorA[] = "Properties\{233a9ef3-afc4-4abd-b564-c32f21f1535b}\0003"; static const char wine_devpropkey_monitor_rcworkA[] = "Properties\{233a9ef3-afc4-4abd-b564-c32f21f1535b}\0004";
static const WCHAR linkedW[] = {'L','i','n','k','e','d',0}; @@ -144,7 +143,6 @@ struct monitor HANDLE handle; unsigned int id; unsigned int output_id; - RECT rc_monitor; RECT rc_work; BOOL is_clone; struct edid_monitor_info edid_info; @@ -163,8 +161,6 @@ UINT64 thunk_lock_callback = 0; static struct monitor virtual_monitor = { .handle = VIRTUAL_HMONITOR, - .rc_monitor.right = 1024, - .rc_monitor.bottom = 768, .rc_work.right = 1024, .rc_work.bottom = 768, }; @@ -689,16 +685,6 @@ static BOOL read_monitor_from_registry( struct monitor *monitor ) } monitor->output_id = *(const unsigned int *)value->Data;
- /* rc_monitor, WINE_DEVPROPKEY_MONITOR_RCMONITOR */ - size = query_reg_subkey_value( hkey, wine_devpropkey_monitor_rcmonitorA, - value, sizeof(buffer) ); - if (size != sizeof(monitor->rc_monitor)) - { - NtClose( hkey ); - return FALSE; - } - monitor->rc_monitor = *(const RECT *)value->Data; - /* rc_work, WINE_DEVPROPKEY_MONITOR_RCWORK */ size = query_reg_subkey_value( hkey, wine_devpropkey_monitor_rcworkA, value, sizeof(buffer) ); @@ -1426,14 +1412,6 @@ static BOOL write_monitor_to_registry( struct monitor *monitor, const BYTE *edid NtClose( subkey ); }
- /* WINE_DEVPROPKEY_MONITOR_RCMONITOR */ - if ((subkey = reg_create_ascii_key( hkey, wine_devpropkey_monitor_rcmonitorA, 0, NULL ))) - { - set_reg_value( subkey, NULL, 0xffff0000 | DEVPROP_TYPE_BINARY, &monitor->rc_monitor, - sizeof(monitor->rc_monitor) ); - NtClose( subkey ); - } - /* WINE_DEVPROPKEY_MONITOR_RCWORK */ if ((subkey = reg_create_ascii_key( hkey, wine_devpropkey_monitor_rcworkA, 0, NULL ))) { @@ -1481,7 +1459,6 @@ static void add_monitor( const struct gdi_monitor *gdi_monitor, void *param ) monitor.source = &ctx->source; monitor.id = ctx->source.monitor_count; monitor.output_id = ctx->monitor_count; - monitor.rc_monitor = gdi_monitor->rc_monitor; monitor.rc_work = gdi_monitor->rc_work;
TRACE( "%u %s %s\n", monitor.id, wine_dbgstr_rect(&gdi_monitor->rc_monitor), wine_dbgstr_rect(&gdi_monitor->rc_work) ); @@ -1703,13 +1680,24 @@ static void clear_display_devices(void) } }
+static BOOL is_detached_mode( const DEVMODEW *mode ) +{ + return mode->dmFields & DM_POSITION && + mode->dmFields & DM_PELSWIDTH && + mode->dmFields & DM_PELSHEIGHT && + mode->dmPelsWidth == 0 && + mode->dmPelsHeight == 0; +} + static BOOL is_monitor_active( struct monitor *monitor ) { + DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; struct source *source; /* services do not have any adapters, only a virtual monitor */ if (!(source = monitor->source)) return TRUE; if (!(source->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return FALSE; - return !IsRectEmpty( &monitor->rc_monitor ); + source_get_current_settings( source, ¤t_mode ); + return !is_detached_mode( ¤t_mode ); }
static BOOL is_monitor_primary( struct monitor *monitor ) @@ -2171,16 +2159,30 @@ static UINT monitor_get_dpi( struct monitor *monitor ) }
/* display_lock must be held */ -static RECT monitor_get_rect( struct monitor *monitor, BOOL work, UINT dpi ) +static RECT monitor_get_rect( struct monitor *monitor, UINT dpi ) { - RECT rect = work ? monitor->rc_work : monitor->rc_monitor; + DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; + RECT rect = {0, 0, 1024, 768}; + struct source *source; + + /* services do not have any adapters, only a virtual monitor */ + if (!(source = monitor->source)) return rect; + + SetRectEmpty( &rect ); + if (!(source->state_flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) return rect; + source_get_current_settings( source, ¤t_mode ); + + SetRect( &rect, current_mode.dmPosition.x, current_mode.dmPosition.y, + current_mode.dmPosition.x + current_mode.dmPelsWidth, + current_mode.dmPosition.y + current_mode.dmPelsHeight ); + return map_dpi_rect( rect, monitor_get_dpi( monitor ), dpi ); }
static void monitor_get_info( struct monitor *monitor, MONITORINFO *info, UINT dpi ) { - info->rcMonitor = monitor_get_rect( monitor, FALSE, dpi ); - info->rcWork = monitor_get_rect( monitor, TRUE, dpi ); + info->rcMonitor = monitor_get_rect( monitor, dpi ); + info->rcWork = map_dpi_rect( monitor->rc_work, monitor_get_dpi( monitor ), dpi ); info->dwFlags = is_monitor_primary( monitor ) ? MONITORINFOF_PRIMARY : 0;
if (info->cbSize >= sizeof(MONITORINFOEXW)) @@ -2210,7 +2212,7 @@ static struct monitor *get_monitor_from_rect( RECT rect, UINT flags, UINT dpi )
if (!is_monitor_active( monitor ) || monitor->is_clone) continue;
- monitor_rect = monitor_get_rect( monitor, FALSE, dpi ); + monitor_rect = monitor_get_rect( monitor, dpi ); if (intersect_rect( &intersect, &monitor_rect, &rect )) { /* check for larger intersecting area */ @@ -2493,7 +2495,7 @@ RECT get_virtual_screen_rect( UINT dpi ) { RECT monitor_rect; if (!is_monitor_active( monitor ) || monitor->is_clone) continue; - monitor_rect = monitor_get_rect( monitor, FALSE, dpi ); + monitor_rect = monitor_get_rect( monitor, dpi ); union_rect( &rect, &rect, &monitor_rect ); }
@@ -2515,7 +2517,7 @@ BOOL is_window_rect_full_screen( const RECT *rect, UINT dpi )
if (!is_monitor_active( monitor ) || monitor->is_clone) continue;
- monrect = monitor_get_rect( monitor, FALSE, dpi ); + monrect = monitor_get_rect( monitor, dpi ); if (rect->left <= monrect.left && rect->right >= monrect.right && rect->top <= monrect.top && rect->bottom >= monrect.bottom) { @@ -2554,7 +2556,7 @@ RECT get_display_rect( const WCHAR *display ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!monitor->source || monitor->source->id + 1 != index) continue; - rect = monitor_get_rect( monitor, FALSE, dpi ); + rect = monitor_get_rect( monitor, dpi ); break; }
@@ -2572,7 +2574,7 @@ RECT get_primary_monitor_rect( UINT dpi ) LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!is_monitor_primary( monitor )) continue; - rect = monitor_get_rect( monitor, FALSE, dpi ); + rect = monitor_get_rect( monitor, dpi ); break; }
@@ -3120,15 +3122,6 @@ static void trace_devmode( const DEVMODEW *devmode ) TRACE("\n"); }
-static BOOL is_detached_mode( const DEVMODEW *mode ) -{ - return mode->dmFields & DM_POSITION && - mode->dmFields & DM_PELSWIDTH && - mode->dmFields & DM_PELSHEIGHT && - mode->dmPelsWidth == 0 && - mode->dmPelsHeight == 0; -} - static const DEVMODEW *find_display_mode( const DEVMODEW *modes, DEVMODEW *devmode ) { const DEVMODEW *mode; @@ -3697,7 +3690,7 @@ static BOOL should_enumerate_monitor( struct monitor *monitor, const POINT *orig if (!is_monitor_active( monitor )) return FALSE; if (monitor->is_clone) return FALSE;
- *rect = monitor_get_rect( monitor, FALSE, get_thread_dpi() ); + *rect = monitor_get_rect( monitor, get_thread_dpi() ); OffsetRect( rect, -origin->x, -origin->y ); return intersect_rect( rect, rect, limit ); } @@ -5412,6 +5405,7 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w } case SPI_GETWORKAREA: { + MONITORINFO info = {.cbSize = sizeof(info)}; UINT dpi = get_thread_dpi();
if (!ptr) return FALSE; @@ -5426,7 +5420,8 @@ BOOL WINAPI NtUserSystemParametersInfo( UINT action, UINT val, void *ptr, UINT w LIST_FOR_EACH_ENTRY( monitor, &monitors, struct monitor, entry ) { if (!is_monitor_primary( monitor )) continue; - work_area = monitor_get_rect( monitor, TRUE, dpi ); + monitor_get_info( monitor, &info, dpi ); + work_area = info.rcWork; break; }
v3: Default physical mode to the current display mode if not set.