win32u: Move NtUserChangeDisplaySettings implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-12-02 01:14:35 +01:00 committed by Alexandre Julliard
parent 8731afe70f
commit 3867d253ed
9 changed files with 190 additions and 203 deletions

View File

@ -263,12 +263,6 @@ static void CDECL loaderdrv_UpdateClipboard(void)
load_driver()->pUpdateClipboard();
}
static LONG CDECL loaderdrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd,
DWORD flags, LPVOID lparam )
{
return load_driver()->pChangeDisplaySettingsEx( name, mode, hwnd, flags, lparam );
}
static BOOL CDECL loaderdrv_CreateDesktopWindow( HWND hwnd )
{
return load_driver()->pCreateDesktopWindow( hwnd );
@ -328,7 +322,7 @@ static struct user_driver_funcs lazy_load_driver =
/* clipboard functions */
loaderdrv_UpdateClipboard,
/* display modes */
loaderdrv_ChangeDisplaySettingsEx,
NULL,
NULL,
NULL,
/* windowing functions */

View File

@ -370,39 +370,6 @@ static INT get_monitor_count(void)
return count;
}
static BOOL get_primary_adapter(WCHAR *name)
{
DISPLAY_DEVICEW dd;
DWORD i;
dd.cb = sizeof(dd);
for (i = 0; EnumDisplayDevicesW(NULL, i, &dd, 0); ++i)
{
if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{
lstrcpyW(name, dd.DeviceName);
return TRUE;
}
}
return FALSE;
}
static BOOL is_valid_adapter_name(const WCHAR *name)
{
long int adapter_idx;
WCHAR *end;
if (wcsnicmp(name, L"\\\\.\\DISPLAY", lstrlenW(L"\\\\.\\DISPLAY")))
return FALSE;
adapter_idx = wcstol(name + lstrlenW(L"\\\\.\\DISPLAY"), &end, 10);
if (*end || adapter_idx < 1)
return FALSE;
return TRUE;
}
/* get text metrics and/or "average" char width of the specified logfont
* for the specified dc */
static void get_text_metr_size( HDC hdc, LOGFONTW *plf, TEXTMETRICW * ptm, UINT *psz)
@ -3040,83 +3007,6 @@ LONG WINAPI ChangeDisplaySettingsExA( LPCSTR devname, LPDEVMODEA devmode, HWND h
return ret;
}
#define _X_FIELD(prefix, bits) \
if ((fields) & prefix##_##bits) \
{ \
p += sprintf(p, "%s%s", first ? "" : ",", #bits); \
first = FALSE; \
}
static const CHAR *_CDS_flags(DWORD fields)
{
BOOL first = TRUE;
CHAR buf[128];
CHAR *p = buf;
_X_FIELD(CDS, UPDATEREGISTRY)
_X_FIELD(CDS, TEST)
_X_FIELD(CDS, FULLSCREEN)
_X_FIELD(CDS, GLOBAL)
_X_FIELD(CDS, SET_PRIMARY)
_X_FIELD(CDS, VIDEOPARAMETERS)
_X_FIELD(CDS, ENABLE_UNSAFE_MODES)
_X_FIELD(CDS, DISABLE_UNSAFE_MODES)
_X_FIELD(CDS, RESET)
_X_FIELD(CDS, RESET_EX)
_X_FIELD(CDS, NORESET)
*p = 0;
return wine_dbg_sprintf("%s", buf);
}
static const CHAR *_DM_fields(DWORD fields)
{
BOOL first = TRUE;
CHAR buf[128];
CHAR *p = buf;
_X_FIELD(DM, BITSPERPEL)
_X_FIELD(DM, PELSWIDTH)
_X_FIELD(DM, PELSHEIGHT)
_X_FIELD(DM, DISPLAYFLAGS)
_X_FIELD(DM, DISPLAYFREQUENCY)
_X_FIELD(DM, POSITION)
_X_FIELD(DM, DISPLAYORIENTATION)
*p = 0;
return wine_dbg_sprintf("%s", buf);
}
#undef _X_FIELD
static void trace_devmode(const DEVMODEW *devmode)
{
TRACE("dmFields=%s ", _DM_fields(devmode->dmFields));
if (devmode->dmFields & DM_BITSPERPEL)
TRACE("dmBitsPerPel=%u ", devmode->dmBitsPerPel);
if (devmode->dmFields & DM_PELSWIDTH)
TRACE("dmPelsWidth=%u ", devmode->dmPelsWidth);
if (devmode->dmFields & DM_PELSHEIGHT)
TRACE("dmPelsHeight=%u ", devmode->dmPelsHeight);
if (devmode->dmFields & DM_DISPLAYFREQUENCY)
TRACE("dmDisplayFrequency=%u ", devmode->dmDisplayFrequency);
if (devmode->dmFields & DM_POSITION)
TRACE("dmPosition=(%d,%d) ", devmode->u1.s2.dmPosition.x, devmode->u1.s2.dmPosition.y);
if (devmode->dmFields & DM_DISPLAYFLAGS)
TRACE("dmDisplayFlags=%#x ", devmode->u2.dmDisplayFlags);
if (devmode->dmFields & DM_DISPLAYORIENTATION)
TRACE("dmDisplayOrientation=%u ", devmode->u1.s2.dmDisplayOrientation);
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;
}
/***********************************************************************
* ChangeDisplaySettingsExW (USER32.@)
@ -3124,91 +3014,9 @@ static BOOL is_detached_mode(const DEVMODEW *mode)
LONG WINAPI ChangeDisplaySettingsExW( LPCWSTR devname, LPDEVMODEW devmode, HWND hwnd,
DWORD flags, LPVOID lparam )
{
WCHAR primary_adapter[CCHDEVICENAME];
BOOL def_mode = TRUE;
DEVMODEW dm;
LONG ret;
TRACE("%s %p %p %#x %p\n", debugstr_w(devname), devmode, hwnd, flags, lparam);
TRACE("flags=%s\n", _CDS_flags(flags));
if (!devname && !devmode)
{
ret = USER_Driver->pChangeDisplaySettingsEx(NULL, NULL, hwnd, flags, lparam);
if (ret != DISP_CHANGE_SUCCESSFUL)
ERR("Restoring all displays to their registry settings returned %d.\n", ret);
return ret;
}
if (!devname && devmode)
{
if (!get_primary_adapter(primary_adapter))
return DISP_CHANGE_FAILED;
devname = primary_adapter;
}
if (!is_valid_adapter_name(devname))
{
ERR("Invalid device name %s.\n", wine_dbgstr_w(devname));
return DISP_CHANGE_BADPARAM;
}
if (devmode)
{
trace_devmode(devmode);
if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmICMMethod))
return DISP_CHANGE_BADMODE;
if (is_detached_mode(devmode) ||
((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel) ||
((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth) ||
((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight) ||
((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency))
def_mode = FALSE;
}
if (def_mode)
{
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsExW(devname, ENUM_REGISTRY_SETTINGS, &dm, 0))
{
ERR("Default mode not found!\n");
return DISP_CHANGE_BADMODE;
}
TRACE("Return to original display mode\n");
devmode = &dm;
}
if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
{
WARN("devmode doesn't specify the resolution: %#x\n", devmode->dmFields);
return DISP_CHANGE_BADMODE;
}
if (!is_detached_mode(devmode) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight))
{
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsExW(devname, ENUM_CURRENT_SETTINGS, &dm, 0))
{
ERR("Current mode not found!\n");
return DISP_CHANGE_BADMODE;
}
if (!devmode->dmPelsWidth)
devmode->dmPelsWidth = dm.dmPelsWidth;
if (!devmode->dmPelsHeight)
devmode->dmPelsHeight = dm.dmPelsHeight;
}
ret = USER_Driver->pChangeDisplaySettingsEx(devname, devmode, hwnd, flags, lparam);
if (ret != DISP_CHANGE_SUCCESSFUL)
ERR("Changing %s display settings returned %d.\n", wine_dbgstr_w(devname), ret);
return ret;
UNICODE_STRING str;
RtlInitUnicodeString( &str, devname );
return NtUserChangeDisplaySettings( &str, devmode, hwnd, flags, lparam );
}

View File

@ -1021,6 +1021,12 @@ static SHORT CDECL loaderdrv_VkKeyScanEx( WCHAR ch, HKL layout )
return load_driver()->pVkKeyScanEx( ch, layout );
}
static LONG CDECL loaderdrv_ChangeDisplaySettingsEx( LPCWSTR name, LPDEVMODEW mode, HWND hwnd,
DWORD flags, LPVOID lparam )
{
return load_driver()->pChangeDisplaySettingsEx( name, mode, hwnd, flags, lparam );
}
static BOOL CDECL loaderdrv_EnumDisplaySettingsEx( LPCWSTR name, DWORD num, LPDEVMODEW mode, DWORD flags )
{
return load_driver()->pEnumDisplaySettingsEx( name, num, mode, flags );
@ -1046,6 +1052,7 @@ static const struct user_driver_funcs lazy_load_driver =
.pToUnicodeEx = loaderdrv_ToUnicodeEx,
.pUnregisterHotKey = loaderdrv_UnregisterHotKey,
.pVkKeyScanEx = loaderdrv_VkKeyScanEx,
.pChangeDisplaySettingsEx = loaderdrv_ChangeDisplaySettingsEx,
.pEnumDisplaySettingsEx = loaderdrv_EnumDisplaySettingsEx,
.pUpdateDisplayDevices = loaderdrv_UpdateDisplayDevices,
.pUpdateClipboard = loaderdrv_UpdateClipboard,

View File

@ -1169,6 +1169,7 @@ static struct unix_funcs unix_funcs =
NtGdiWidenPath,
NtUserActivateKeyboardLayout,
NtUserCallTwoParam,
NtUserChangeDisplaySettings,
NtUserCountClipboardFormats,
NtUserEnumDisplayDevices,
NtUserEnumDisplayMonitors,

View File

@ -1347,6 +1347,173 @@ BOOL WINAPI NtUserEnumDisplayDevices( UNICODE_STRING *device, DWORD index,
return !!found;
}
#define _X_FIELD(prefix, bits) \
if ((fields) & prefix##_##bits) \
{ \
p += sprintf( p, "%s%s", first ? "" : ",", #bits ); \
first = FALSE; \
}
static const char *_CDS_flags( DWORD fields )
{
BOOL first = TRUE;
CHAR buf[128];
CHAR *p = buf;
_X_FIELD(CDS, UPDATEREGISTRY)
_X_FIELD(CDS, TEST)
_X_FIELD(CDS, FULLSCREEN)
_X_FIELD(CDS, GLOBAL)
_X_FIELD(CDS, SET_PRIMARY)
_X_FIELD(CDS, VIDEOPARAMETERS)
_X_FIELD(CDS, ENABLE_UNSAFE_MODES)
_X_FIELD(CDS, DISABLE_UNSAFE_MODES)
_X_FIELD(CDS, RESET)
_X_FIELD(CDS, RESET_EX)
_X_FIELD(CDS, NORESET)
*p = 0;
return wine_dbg_sprintf( "%s", buf );
}
static const char *_DM_fields( DWORD fields )
{
BOOL first = TRUE;
CHAR buf[128];
CHAR *p = buf;
_X_FIELD(DM, BITSPERPEL)
_X_FIELD(DM, PELSWIDTH)
_X_FIELD(DM, PELSHEIGHT)
_X_FIELD(DM, DISPLAYFLAGS)
_X_FIELD(DM, DISPLAYFREQUENCY)
_X_FIELD(DM, POSITION)
_X_FIELD(DM, DISPLAYORIENTATION)
*p = 0;
return wine_dbg_sprintf( "%s", buf );
}
#undef _X_FIELD
static void trace_devmode( const DEVMODEW *devmode )
{
TRACE( "dmFields=%s ", _DM_fields(devmode->dmFields) );
if (devmode->dmFields & DM_BITSPERPEL)
TRACE( "dmBitsPerPel=%u ", devmode->dmBitsPerPel );
if (devmode->dmFields & DM_PELSWIDTH)
TRACE( "dmPelsWidth=%u ", devmode->dmPelsWidth );
if (devmode->dmFields & DM_PELSHEIGHT)
TRACE( "dmPelsHeight=%u ", devmode->dmPelsHeight );
if (devmode->dmFields & DM_DISPLAYFREQUENCY)
TRACE( "dmDisplayFrequency=%u ", devmode->dmDisplayFrequency );
if (devmode->dmFields & DM_POSITION)
TRACE( "dmPosition=(%d,%d) ", devmode->dmPosition.x, devmode->dmPosition.y );
if (devmode->dmFields & DM_DISPLAYFLAGS)
TRACE( "dmDisplayFlags=%#x ", devmode->dmDisplayFlags );
if (devmode->dmFields & DM_DISPLAYORIENTATION)
TRACE( "dmDisplayOrientation=%u ", devmode->dmDisplayOrientation );
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;
}
/***********************************************************************
* NtUserChangeDisplaySettingsExW (win32u.@)
*/
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam )
{
WCHAR device_name[CCHDEVICENAME];
struct adapter *adapter;
BOOL def_mode = TRUE;
DEVMODEW dm;
LONG ret;
TRACE( "%s %p %p %#x %p\n", debugstr_us(devname), devmode, hwnd, flags, lparam );
TRACE( "flags=%s\n", _CDS_flags(flags) );
if ((!devname || !devname->Length) && !devmode)
{
ret = user_driver->pChangeDisplaySettingsEx( NULL, NULL, hwnd, flags, lparam );
if (ret != DISP_CHANGE_SUCCESSFUL)
ERR( "Restoring all displays to their registry settings returned %d.\n", ret );
return ret;
}
if (!lock_display_devices()) return FALSE;
if ((adapter = find_adapter( devname ))) lstrcpyW( device_name, adapter->dev.device_name );
unlock_display_devices();
if (!adapter)
{
WARN( "Invalid device name %s.\n", debugstr_us(devname) );
return DISP_CHANGE_BADPARAM;
}
if (devmode)
{
trace_devmode( devmode );
if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmICMMethod))
return DISP_CHANGE_BADMODE;
if (is_detached_mode(devmode) ||
((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel) ||
((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth) ||
((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight) ||
((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency))
def_mode = FALSE;
}
if (def_mode)
{
memset( &dm, 0, sizeof(dm) );
dm.dmSize = sizeof(dm);
if (!NtUserEnumDisplaySettings( devname, ENUM_REGISTRY_SETTINGS, &dm, 0 ))
{
ERR( "Default mode not found!\n" );
return DISP_CHANGE_BADMODE;
}
TRACE( "Return to original display mode\n" );
devmode = &dm;
}
if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
{
WARN( "devmode doesn't specify the resolution: %#x\n", devmode->dmFields );
return DISP_CHANGE_BADMODE;
}
if (!is_detached_mode(devmode) && (!devmode->dmPelsWidth || !devmode->dmPelsHeight))
{
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!NtUserEnumDisplaySettings( devname, ENUM_CURRENT_SETTINGS, &dm, 0 ))
{
ERR( "Current mode not found!\n" );
return DISP_CHANGE_BADMODE;
}
if (!devmode->dmPelsWidth)
devmode->dmPelsWidth = dm.dmPelsWidth;
if (!devmode->dmPelsHeight)
devmode->dmPelsHeight = dm.dmPelsHeight;
}
ret = user_driver->pChangeDisplaySettingsEx( device_name, devmode, hwnd, flags, lparam );
if (ret != DISP_CHANGE_SUCCESSFUL)
ERR( "Changing %s display settings returned %d.\n", debugstr_us(devname), ret );
return ret;
}
/***********************************************************************
* NtUserEnumDisplaySettings (win32u.@)
*/

View File

@ -783,7 +783,7 @@
@ stdcall NtUserCallTwoParam(long long long)
@ stub NtUserCanBrokerForceForeground
@ stub NtUserChangeClipboardChain
@ stub NtUserChangeDisplaySettings
@ stdcall NtUserChangeDisplaySettings(ptr ptr long long ptr)
@ stub NtUserChangeWindowMessageFilterEx
@ stub NtUserCheckAccessForIntegrityLevel
@ stub NtUserCheckMenuItem

View File

@ -196,6 +196,8 @@ struct unix_funcs
BOOL (WINAPI *pNtGdiWidenPath)( HDC hdc );
HKL (WINAPI *pNtUserActivateKeyboardLayout)( HKL layout, UINT flags );
ULONG_PTR (WINAPI *pNtUserCallTwoParam)( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code );
LONG (WINAPI *pNtUserChangeDisplaySettings)( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam );
INT (WINAPI *pNtUserCountClipboardFormats)(void);
BOOL (WINAPI *pNtUserEnumDisplayDevices)( UNICODE_STRING *device, DWORD index,
DISPLAY_DEVICEW *info, DWORD flags );

View File

@ -606,6 +606,12 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
return unix_funcs->pNtUserCallTwoParam( arg1, arg2, code );
}
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam )
{
return unix_funcs->pNtUserChangeDisplaySettings( devname, devmode, hwnd, flags, lparam );
}
INT WINAPI NtUserCountClipboardFormats(void)
{
return unix_funcs->pNtUserCountClipboardFormats();

View File

@ -79,6 +79,8 @@ HKL WINAPI NtUserActivateKeyboardLayout( HKL layout, UINT flags );
BOOL WINAPI NtUserAddClipboardFormatListener( HWND hwnd );
BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach );
ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code );
LONG WINAPI NtUserChangeDisplaySettings( UNICODE_STRING *devname, DEVMODEW *devmode, HWND hwnd,
DWORD flags, void *lparam );
BOOL WINAPI NtUserCloseDesktop( HDESK handle );
BOOL WINAPI NtUserCloseWindowStation( HWINSTA handle );
INT WINAPI NtUserCountClipboardFormats(void);