From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/sysparams.c | 92 ++++++++++------------------------------- 1 file changed, 21 insertions(+), 71 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index ced9c61db06..6ca180473ba 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -111,6 +111,7 @@ struct source UINT state_flags; UINT monitor_count; UINT mode_count; + DEVMODEW current; DEVMODEW *modes; };
@@ -493,37 +494,9 @@ static BOOL source_set_registry_settings( const struct source *source, const DEV return ret; }
-static BOOL source_get_current_settings( const struct source *source, DEVMODEW *mode ) +static void 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) 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 - { - ret = read_source_mode( hkey, ENUM_CURRENT_SETTINGS, mode ); - NtClose( hkey ); - } - - release_display_device_init_mutex( mutex ); - return ret; + memcpy( &mode->dmFields, &source->current.dmFields, sizeof(*mode) - offsetof(DEVMODEW, dmFields) ); }
static BOOL source_set_current_settings( const struct source *source, const DEVMODEW *mode ) @@ -666,6 +639,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 ); @@ -2733,7 +2710,6 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY LONG ret; UINT32 output_id, source_mode_index, path_index = 0, mode_index = 0; const LUID *gpu_luid; - DEVMODEW devmode; struct monitor *monitor;
FIXME( "flags %#x, paths_count %p, paths %p, modes_count %p, modes %p, topology_id %p semi-stub\n", @@ -2777,13 +2753,6 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY gpu_luid = &monitor->source->gpu->luid; output_id = monitor->output_id;
- memset( &devmode, 0, sizeof(devmode) ); - devmode.dmSize = sizeof(devmode); - if (!source_get_current_settings( monitor->source, &devmode )) - { - goto done; - } - if (path_index == *paths_count || mode_index == *modes_count) { ret = ERROR_INSUFFICIENT_BUFFER; @@ -2791,8 +2760,8 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY }
paths[path_index].flags = DISPLAYCONFIG_PATH_ACTIVE; - set_mode_target_info( &modes[mode_index], gpu_luid, output_id, flags, &devmode ); - set_path_target_info( &paths[path_index].targetInfo, gpu_luid, output_id, mode_index, &devmode ); + set_mode_target_info( &modes[mode_index], gpu_luid, output_id, flags, &monitor->source->current ); + set_path_target_info( &paths[path_index].targetInfo, gpu_luid, output_id, mode_index, &monitor->source->current );
mode_index++; if (mode_index == *modes_count) @@ -2806,7 +2775,7 @@ LONG WINAPI NtUserQueryDisplayConfig( UINT32 flags, UINT32 *paths_count, DISPLAY */ if (!source_mode_exists( modes, mode_index, source_index, &source_mode_index )) { - set_mode_source_info( &modes[mode_index], gpu_luid, source_index, &devmode ); + set_mode_source_info( &modes[mode_index], gpu_luid, source_index, &monitor->source->current ); source_mode_index = mode_index; mode_index++; } @@ -3168,14 +3137,11 @@ static BOOL source_get_full_mode( const struct source *source, const DEVMODEW *d
if (!is_detached_mode( full_mode ) && (!full_mode->dmPelsWidth || !full_mode->dmPelsHeight || !(full_mode->dmFields & DM_POSITION))) { - DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; - - if (!source_get_current_settings( source, ¤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->dmPelsWidth) full_mode->dmPelsWidth = source->current.dmPelsWidth; + if (!full_mode->dmPelsHeight) full_mode->dmPelsHeight = source->current.dmPelsHeight; if (!(full_mode->dmFields & DM_POSITION)) { - full_mode->dmPosition = current_mode.dmPosition; + full_mode->dmPosition = source->current.dmPosition; full_mode->dmFields |= DM_POSITION; } } @@ -3195,7 +3161,6 @@ static DEVMODEW *get_display_settings( struct source *target, const DEVMODEW *de { DEVMODEW *mode, *displays; struct source *source; - BOOL ret;
/* allocate an extra mode for easier iteration */ if (!(displays = calloc( list_count( &sources ) + 1, sizeof(DEVMODEW) ))) return NULL; @@ -3210,9 +3175,8 @@ static DEVMODEW *get_display_settings( struct source *target, const DEVMODEW *de memcpy( &mode->dmFields, &devmode->dmFields, devmode->dmSize - offsetof(DEVMODEW, dmFields) ); else { - if (!target) ret = source_get_registry_settings( source, mode ); - else ret = source_get_current_settings( source, mode ); - if (!ret) + if (target) source_get_current_settings( source, mode ); + else if (!source_get_registry_settings( source, mode )) { free( displays ); return NULL; @@ -3417,13 +3381,12 @@ static BOOL all_detached_settings( const DEVMODEW *displays ) static BOOL get_primary_source_mode( DEVMODEW *mode ) { struct source *primary; - BOOL ret;
if (!(primary = find_source( NULL ))) return FALSE; - ret = source_get_current_settings( primary, mode ); + source_get_current_settings( primary, mode ); source_release( primary );
- return ret; + return TRUE; }
static void display_mode_changed( BOOL broadcast ) @@ -3558,19 +3521,12 @@ LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devm
static BOOL source_enum_display_settings( const struct source *source, UINT index, DEVMODEW *devmode, UINT flags ) { - DEVMODEW current_mode = {.dmSize = sizeof(DEVMODEW)}; const DEVMODEW *source_mode;
- if (!(flags & EDS_ROTATEDMODE) && !source_get_current_settings( source, ¤t_mode )) - { - WARN( "Failed to query current display mode for EDS_ROTATEDMODE flag.\n" ); - return FALSE; - } - for (source_mode = source->modes; source_mode->dmSize; source_mode = NEXT_DEVMODEW(source_mode)) { if (!(flags & EDS_ROTATEDMODE) && (source_mode->dmFields & DM_DISPLAYORIENTATION) && - source_mode->dmDisplayOrientation != current_mode.dmDisplayOrientation) + source_mode->dmDisplayOrientation != source->current.dmDisplayOrientation) continue; if (!(flags & EDS_RAWMODE) && (source_mode->dmFields & DM_DISPLAYFLAGS) && (source_mode->dmDisplayFlags & WINE_DM_UNSUPPORTED)) @@ -3595,7 +3551,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM { static const WCHAR wine_display_driverW[] = {'W','i','n','e',' ','D','i','s','p','l','a','y',' ','D','r','i','v','e','r',0}; struct source *source; - BOOL ret; + BOOL ret = TRUE;
TRACE( "device %s, index %#x, devmode %p, flags %#x\n", debugstr_us(device), (int)index, devmode, (int)flags ); @@ -3609,7 +3565,7 @@ BOOL WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD index, DEVM devmode->dmDriverExtra = 0;
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 == ENUM_CURRENT_SETTINGS) source_get_current_settings( source, devmode ); else ret = source_enum_display_settings( source, index, devmode, flags ); source_release( source );
@@ -3667,13 +3623,7 @@ INT get_display_depth( UNICODE_STRING *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 (depth < 0) depth = source->current.dmBitsPerPel;
unlock_display_devices(); return depth;
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 | 20 ------------------ dlls/winex11.drv/init.c | 1 - dlls/winex11.drv/x11drv.h | 1 - include/wine/gdi_driver.h | 3 +-- 9 files changed, 1 insertion(+), 104 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 995b3cab6d9..eea10dfb563 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -756,11 +756,6 @@ static LONG nulldrv_ChangeDisplaySettings( LPDEVMODEW displays, LPCWSTR primary_ return E_NOTIMPL; /* use default implementation */ }
-static BOOL nulldrv_GetCurrentDisplaySettings( LPCWSTR name, BOOL is_primary, LPDEVMODEW mode ) -{ - return FALSE; /* use default implementation */ -} - static INT nulldrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) { return -1; /* use default implementation */ @@ -1115,11 +1110,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 INT loaderdrv_GetDisplayDepth( LPCWSTR name, BOOL is_primary ) { return load_driver()->pGetDisplayDepth( name, is_primary ); @@ -1272,7 +1262,6 @@ static const struct user_driver_funcs lazy_load_driver = loaderdrv_UpdateClipboard, /* display modes */ loaderdrv_ChangeDisplaySettings, - loaderdrv_GetCurrentDisplaySettings, loaderdrv_GetDisplayDepth, loaderdrv_UpdateDisplayDevices, /* windowing functions */ @@ -1363,7 +1352,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(GetDisplayDepth); SET_USER_FUNC(UpdateDisplayDevices); SET_USER_FUNC(CreateDesktop); 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 c160c286d21..7635232d8f5 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; -} - /*********************************************************************** * GetDisplayDepth (MACDRV.@) * diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index 8492b0030c0..8d0fce18273 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, .pGetDisplayDepth = macdrv_GetDisplayDepth, .pUpdateDisplayDevices = macdrv_UpdateDisplayDevices, .pGetCursorPos = macdrv_GetCursorPos, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index d3c54d72542..16d5c60066d 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 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); diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c index 3ce21d203d2..a29943be936 100644 --- a/dlls/winex11.drv/display.c +++ b/dlls/winex11.drv/display.c @@ -216,26 +216,6 @@ INT X11DRV_GetDisplayDepth(LPCWSTR name, BOOL is_primary) return screen_bpp; }
-/*********************************************************************** - * 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) ); - if (!is_detached_mode( devmode )) devmode->dmBitsPerPel = get_display_depth( id ); - 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 0bba9727136..cfcca65bb45 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, .pGetDisplayDepth = X11DRV_GetDisplayDepth, .pUpdateDisplayDevices = X11DRV_UpdateDisplayDevices, .pCreateDesktop = X11DRV_CreateDesktop, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index d2eb35b454e..efc4a57a6f7 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 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 ); diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 6e051cfdaa3..fd3b2146543 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 */ @@ -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); INT (*pGetDisplayDepth)(LPCWSTR,BOOL); UINT (*pUpdateDisplayDevices)(const struct gdi_device_manager *,void*); /* windowing functions */
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 6ca180473ba..a1d619cfbd9 100644 --- a/dlls/win32u/sysparams.c +++ b/dlls/win32u/sysparams.c @@ -1487,10 +1487,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 );
@@ -1500,6 +1586,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 ); @@ -1508,6 +1609,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 = @@ -1846,97 +1949,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 @@ -1978,7 +2000,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 | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c index a1d619cfbd9..93723d17fc3 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; @@ -71,6 +73,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 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[] = @@ -112,6 +115,7 @@ struct source UINT monitor_count; UINT mode_count; DEVMODEW current; + DEVMODEW physical; DEVMODEW *modes; };
@@ -430,10 +434,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) ); @@ -445,10 +450,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; @@ -639,9 +645,11 @@ 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); + 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) ); @@ -1587,7 +1595,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 )) @@ -1598,6 +1609,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 ); } }
@@ -3592,6 +3605,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) 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 93723d17fc3..6b35a995247 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}; @@ -142,7 +141,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; @@ -161,8 +159,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, }; @@ -679,16 +675,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) ); @@ -1416,14 +1402,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 ))) { @@ -1471,7 +1449,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) ); @@ -1693,13 +1670,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 ) @@ -2160,16 +2148,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)) @@ -2199,7 +2201,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 */ @@ -2482,7 +2484,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 ); }
@@ -2504,7 +2506,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) { @@ -2543,7 +2545,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; }
@@ -2561,7 +2563,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; }
@@ -3101,15 +3103,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; @@ -3675,7 +3668,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 ); } @@ -5390,6 +5383,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; @@ -5404,7 +5398,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; }
Hmm, this is obviously breaking the tests sorry, having a look...