Commit d08808d8 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Implement NtUserGetSystemDpiForProcess.

parent aab62429
......@@ -1197,7 +1197,6 @@ static DWORD_ENTRY( FONTSMOOTHINGORIENTATION, FE_FONTSMOOTHINGORIENTATIONRGB, DE
static DWORD_ENTRY( FONTSMOOTHINGTYPE, FE_FONTSMOOTHINGSTANDARD, DESKTOP_KEY, L"FontSmoothingType" );
static DWORD_ENTRY( FOREGROUNDFLASHCOUNT, 3, DESKTOP_KEY, L"ForegroundFlashCount" );
static DWORD_ENTRY( FOREGROUNDLOCKTIMEOUT, 0, DESKTOP_KEY, L"ForegroundLockTimeout" );
static DWORD_ENTRY( LOGPIXELS, 0, DESKTOP_KEY, L"LogPixels" );
static DWORD_ENTRY( MOUSECLICKLOCKTIME, 1200, DESKTOP_KEY, L"ClickLockTime" );
static DWORD_ENTRY( AUDIODESC_LOCALE, 0, AUDIODESC_KEY, L"Locale" );
......@@ -1356,19 +1355,7 @@ void SYSPARAMS_Init(void)
RegCloseKey( key );
get_dword_entry( (union sysparam_all_entry *)&entry_LOGPIXELS, 0, &system_dpi, 0 );
if (!system_dpi) /* check fallback key */
{
if (!RegOpenKeyW( HKEY_CURRENT_CONFIG, L"Software\\Fonts", &key ))
{
DWORD type, size = sizeof(system_dpi);
if (RegQueryValueExW( key, L"LogPixels", NULL, &type, (void *)&system_dpi, &size ) ||
type != REG_DWORD)
system_dpi = 0;
RegCloseKey( key );
}
}
if (!system_dpi) system_dpi = USER_DEFAULT_SCREEN_DPI;
system_dpi = NtUserGetSystemDpiForProcess( NULL );
/* FIXME: what do the DpiScalingVer flags mean? */
get_dword_entry( (union sysparam_all_entry *)&entry_DPISCALINGVER, 0, &dpi_scaling, 0 );
......
......@@ -608,11 +608,11 @@ HKEY reg_open_hkcu_key( const char *name )
return reg_open_key( hkcu_key, nameW, asciiz_to_unicode( nameW, name ) - sizeof(WCHAR) );
}
void set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value, DWORD count )
BOOL set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value, DWORD count )
{
unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0;
UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name };
NtSetValueKey( hkey, &nameW, 0, type, value, count );
return !NtSetValueKey( hkey, &nameW, 0, type, value, count );
}
void set_reg_ascii_value( HKEY hkey, const char *name, const char *value )
......@@ -661,7 +661,7 @@ static BOOL reg_enum_value( HKEY hkey, unsigned int index, KEY_VALUE_FULL_INFORM
return TRUE;
}
static void reg_delete_value( HKEY hkey, const WCHAR *name )
void reg_delete_value( HKEY hkey, const WCHAR *name )
{
unsigned int name_size = lstrlenW( name ) * sizeof(WCHAR);
UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name };
......
......@@ -123,6 +123,7 @@ static void * const syscalls[] =
NtUserGetProcessDpiAwarenessContext,
NtUserGetProcessWindowStation,
NtUserGetProp,
NtUserGetSystemDpiForProcess,
NtUserGetThreadDesktop,
NtUserOpenDesktop,
NtUserOpenInputDesktop,
......
......@@ -34,7 +34,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(system);
static HKEY video_key, enum_key, control_key, config_key;
static HKEY video_key, enum_key, control_key, config_key, volatile_base_key;
static const WCHAR devicemap_video_keyW[] =
{
......@@ -235,6 +235,123 @@ static struct monitor virtual_monitor =
.dev.state_flags = DISPLAY_DEVICE_ACTIVE | DISPLAY_DEVICE_ATTACHED,
};
/* the various registry keys that are used to store parameters */
enum parameter_key
{
COLORS_KEY,
DESKTOP_KEY,
KEYBOARD_KEY,
MOUSE_KEY,
METRICS_KEY,
SOUND_KEY,
VERSION_KEY,
SHOWSOUNDS_KEY,
KEYBOARDPREF_KEY,
SCREENREADER_KEY,
AUDIODESC_KEY,
NB_PARAM_KEYS
};
static const char *parameter_key_names[NB_PARAM_KEYS] =
{
"Control Panel\\Colors",
"Control Panel\\Desktop",
"Control Panel\\Keyboard",
"Control Panel\\Mouse",
"Control Panel\\Desktop\\WindowMetrics",
"Control Panel\\Sound",
"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",
"Control Panel\\Accessibility\\ShowSounds",
"Control Panel\\Accessibility\\Keyboard Preference",
"Control Panel\\Accessibility\\Blind Access",
"Control Panel\\Accessibility\\AudioDescription",
};
/* System parameters storage */
union sysparam_all_entry;
struct sysparam_entry
{
BOOL (*get)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi );
BOOL (*set)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT flags );
BOOL (*init)( union sysparam_all_entry *entry );
enum parameter_key base_key;
const char *regval;
enum parameter_key mirror_key;
const char *mirror;
BOOL loaded;
};
struct sysparam_uint_entry
{
struct sysparam_entry hdr;
UINT val;
};
struct sysparam_bool_entry
{
struct sysparam_entry hdr;
BOOL val;
};
struct sysparam_dword_entry
{
struct sysparam_entry hdr;
DWORD val;
};
struct sysparam_rgb_entry
{
struct sysparam_entry hdr;
COLORREF val;
HBRUSH brush;
HPEN pen;
};
struct sysparam_binary_entry
{
struct sysparam_entry hdr;
void *ptr;
size_t size;
};
struct sysparam_path_entry
{
struct sysparam_entry hdr;
WCHAR path[MAX_PATH];
};
struct sysparam_font_entry
{
struct sysparam_entry hdr;
UINT weight;
LOGFONTW val;
WCHAR fullname[LF_FACESIZE];
};
struct sysparam_pref_entry
{
struct sysparam_entry hdr;
struct sysparam_binary_entry *parent;
UINT offset;
UINT mask;
};
union sysparam_all_entry
{
struct sysparam_entry hdr;
struct sysparam_uint_entry uint;
struct sysparam_bool_entry bool;
struct sysparam_dword_entry dword;
struct sysparam_rgb_entry rgb;
struct sysparam_binary_entry bin;
struct sysparam_path_entry path;
struct sysparam_font_entry font;
struct sysparam_pref_entry pref;
};
static UINT system_dpi;
static HANDLE get_display_device_init_mutex( void )
{
static const WCHAR display_device_initW[] =
......@@ -267,8 +384,6 @@ static BOOL read_display_adapter_settings( unsigned int index, struct adapter *i
if (!enum_key && !(enum_key = reg_open_key( NULL, enum_keyW, sizeof(enum_keyW) )))
return FALSE;
if (!config_key && !(config_key = reg_open_key( NULL, config_keyW, sizeof(config_keyW) )))
return FALSE;
/* Find adapter */
sprintf( buffer, "\\Device\\Video%d", index );
......@@ -476,7 +591,6 @@ static void prepare_devices(void)
if (!enum_key) enum_key = reg_create_key( NULL, enum_keyW, sizeof(enum_keyW), 0, NULL );
if (!control_key) control_key = reg_create_key( NULL, control_keyW, sizeof(control_keyW), 0, NULL );
if (!config_key) config_key = reg_create_key( NULL, config_keyW, sizeof(config_keyW), 0, NULL );
if (!video_key) video_key = reg_create_key( NULL, devicemap_video_keyW, sizeof(devicemap_video_keyW),
REG_OPTION_VOLATILE, NULL );
......@@ -1636,6 +1750,168 @@ static BOOL get_monitor_info( HMONITOR handle, MONITORINFO *info )
return FALSE;
}
/***********************************************************************
* NtUserGetSystemDpiForProcess (win32u.@)
*/
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process )
{
if (process && process != GetCurrentProcess())
{
FIXME( "not supported on other process %p\n", process );
return 0;
}
return system_dpi;
}
/* retrieve the cached base keys for a given entry */
static BOOL get_base_keys( enum parameter_key index, HKEY *base_key, HKEY *volatile_key )
{
static HKEY base_keys[NB_PARAM_KEYS];
static HKEY volatile_keys[NB_PARAM_KEYS];
WCHAR bufferW[128];
HKEY key;
if (!base_keys[index] && base_key)
{
if (!(key = reg_create_key( hkcu_key, bufferW,
asciiz_to_unicode( bufferW, parameter_key_names[index] ) - sizeof(WCHAR),
0, NULL )))
return FALSE;
if (InterlockedCompareExchangePointer( (void **)&base_keys[index], key, 0 ))
NtClose( key );
}
if (!volatile_keys[index] && volatile_key)
{
if (!(key = reg_create_key( volatile_base_key, bufferW,
asciiz_to_unicode( bufferW, parameter_key_names[index] ) - sizeof(WCHAR),
REG_OPTION_VOLATILE, NULL )))
return FALSE;
if (InterlockedCompareExchangePointer( (void **)&volatile_keys[index], key, 0 ))
NtClose( key );
}
if (base_key) *base_key = base_keys[index];
if (volatile_key) *volatile_key = volatile_keys[index];
return TRUE;
}
/* load a value to a registry entry */
static DWORD load_entry( struct sysparam_entry *entry, void *data, DWORD size )
{
char buffer[4096];
KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
DWORD count;
HKEY base_key, volatile_key;
if (!get_base_keys( entry->base_key, &base_key, &volatile_key )) return FALSE;
if (!(count = query_reg_ascii_value( volatile_key, entry->regval, value, sizeof(buffer) )))
count = query_reg_ascii_value( base_key, entry->regval, value, sizeof(buffer) );
if (count > size)
{
count = size;
/* make sure strings are null-terminated */
if (value->Type == REG_SZ) ((WCHAR *)value->Data)[count / sizeof(WCHAR) - 1] = 0;
}
if (count) memcpy( data, value->Data, count );
entry->loaded = TRUE;
return count;
}
/* save a value to a registry entry */
static BOOL save_entry( const struct sysparam_entry *entry, const void *data, DWORD size,
DWORD type, UINT flags )
{
HKEY base_key, volatile_key;
WCHAR nameW[64];
asciiz_to_unicode( nameW, entry->regval );
if (flags & SPIF_UPDATEINIFILE)
{
if (!get_base_keys( entry->base_key, &base_key, &volatile_key )) return FALSE;
if (!set_reg_value( base_key, nameW, type, data, size )) return FALSE;
reg_delete_value( volatile_key, nameW );
if (entry->mirror && get_base_keys( entry->mirror_key, &base_key, NULL ))
{
asciiz_to_unicode( nameW, entry->mirror );
set_reg_value( base_key, nameW, type, data, size );
}
}
else
{
if (!get_base_keys( entry->base_key, NULL, &volatile_key )) return FALSE;
if (!set_reg_value( volatile_key, nameW, type, data, size )) return FALSE;
}
return TRUE;
}
/* initialize an entry in the registry if missing */
static BOOL init_entry( struct sysparam_entry *entry, const void *data, DWORD size, DWORD type )
{
KEY_VALUE_PARTIAL_INFORMATION value;
UNICODE_STRING name;
WCHAR nameW[64];
HKEY base_key;
DWORD count;
NTSTATUS status;
if (!get_base_keys( entry->base_key, &base_key, NULL )) return FALSE;
name.Buffer = nameW;
name.MaximumLength = asciiz_to_unicode( nameW, entry->regval );
name.Length = name.MaximumLength - sizeof(WCHAR);
status = NtQueryValueKey( base_key, &name, KeyValuePartialInformation,
&value, sizeof(value), &count );
if (!status || status == STATUS_BUFFER_OVERFLOW) return TRUE;
if (!set_reg_value( base_key, nameW, type, data, size )) return FALSE;
if (entry->mirror && get_base_keys( entry->mirror_key, &base_key, NULL ))
{
asciiz_to_unicode( nameW, entry->mirror );
set_reg_value( base_key, nameW, type, data, size );
}
entry->loaded = TRUE;
return TRUE;
}
/* load a dword (binary) parameter from the registry */
static BOOL get_dword_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{
if (!ptr_param) return FALSE;
if (!entry->hdr.loaded)
{
DWORD val;
if (load_entry( &entry->hdr, &val, sizeof(val) ) == sizeof(DWORD)) entry->dword.val = val;
}
*(DWORD *)ptr_param = entry->dword.val;
return TRUE;
}
/* set a dword (binary) parameter in the registry */
static BOOL set_dword_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT flags )
{
DWORD val = PtrToUlong( ptr_param );
if (!save_entry( &entry->hdr, &val, sizeof(val), REG_DWORD, flags )) return FALSE;
entry->dword.val = val;
entry->hdr.loaded = TRUE;
return TRUE;
}
/* initialize a dword parameter */
static BOOL init_dword_entry( union sysparam_all_entry *entry )
{
return init_entry( &entry->hdr, &entry->dword.val, sizeof(entry->dword.val), REG_DWORD );
}
#define DWORD_ENTRY(name,val,base,reg) \
struct sysparam_dword_entry entry_##name = { { get_dword_entry, set_dword_entry, init_dword_entry, \
base, reg }, (val) }
static DWORD_ENTRY( LOGPIXELS, 0, DESKTOP_KEY, "LogPixels" );
/**********************************************************************
* sysparams_init
*/
......@@ -1644,6 +1920,8 @@ void sysparams_init(void)
WCHAR layout[KL_NAMELENGTH];
HKEY hkey;
static const WCHAR log_pixelsW[] = {'L','o','g','P','i','x','e','l','s',0};
static const WCHAR software_fontsW[] = {'S','o','f','t','w','a','r','e','\\','F','o','n','t','s'};
static const WCHAR oneW[] = {'1',0};
static const WCHAR kl_preloadW[] =
{'K','e','y','b','o','a','r','d',' ','L','a','y','o','u','t','\\','P','r','e','l','o','a','d'};
......@@ -1655,6 +1933,26 @@ void sysparams_init(void)
(lstrlenW(layout) + 1) * sizeof(WCHAR) );
NtClose( hkey );
}
volatile_base_key = reg_open_hkcu_key( "Software\\Wine\\Temporary System Parameters" );
config_key = reg_create_key( NULL, config_keyW, sizeof(config_keyW), 0, NULL );
get_dword_entry( (union sysparam_all_entry *)&entry_LOGPIXELS, 0, &system_dpi, 0 );
if (!system_dpi) /* check fallback key */
{
HKEY hkey;
if ((hkey = reg_open_key( config_key, software_fontsW, sizeof(software_fontsW) )))
{
char buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(DWORD)];
KEY_VALUE_PARTIAL_INFORMATION *value = (void *)buffer;
if (query_reg_value( hkey, log_pixelsW, value, sizeof(buffer) ) && value->Type == REG_DWORD)
system_dpi = *(const DWORD *)value->Data;
NtClose( hkey );
}
}
if (!system_dpi) system_dpi = USER_DEFAULT_SCREEN_DPI;
}
static DPI_AWARENESS dpi_awareness;
......
......@@ -993,7 +993,7 @@
@ stub NtUserGetResizeDCompositionSynchronizationObject
@ stub NtUserGetScrollBarInfo
@ stub NtUserGetSharedWindowData
@ stub NtUserGetSystemDpiForProcess
@ stdcall -syscall NtUserGetSystemDpiForProcess(long)
@ stub NtUserGetSystemMenu
@ stdcall -syscall NtUserGetThreadDesktop(long)
@ stub NtUserGetThreadState
......
......@@ -258,9 +258,10 @@ extern ULONG query_reg_value( HKEY hkey, const WCHAR *name,
extern ULONG query_reg_ascii_value( HKEY hkey, const char *name,
KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) DECLSPEC_HIDDEN;
extern void set_reg_ascii_value( HKEY hkey, const char *name, const char *value ) DECLSPEC_HIDDEN;
extern void set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value,
extern BOOL set_reg_value( HKEY hkey, const WCHAR *name, UINT type, const void *value,
DWORD count ) DECLSPEC_HIDDEN;
extern BOOL reg_delete_tree( HKEY parent, const WCHAR *name, ULONG name_len ) DECLSPEC_HIDDEN;
extern void reg_delete_value( HKEY hkey, const WCHAR *name ) DECLSPEC_HIDDEN;
extern HKEY hkcu_key DECLSPEC_HIDDEN;
......
......@@ -110,6 +110,7 @@
SYSCALL_ENTRY( NtUserGetProcessDpiAwarenessContext ) \
SYSCALL_ENTRY( NtUserGetProcessWindowStation ) \
SYSCALL_ENTRY( NtUserGetProp ) \
SYSCALL_ENTRY( NtUserGetSystemDpiForProcess ) \
SYSCALL_ENTRY( NtUserGetThreadDesktop ) \
SYSCALL_ENTRY( NtUserOpenDesktop ) \
SYSCALL_ENTRY( NtUserOpenInputDesktop ) \
......
......@@ -308,3 +308,10 @@ NTSTATUS WINAPI wow64_NtUserGetProcessDpiAwarenessContext( UINT *args )
return NtUserGetProcessDpiAwarenessContext( process );
}
NTSTATUS WINAPI wow64_NtUserGetSystemDpiForProcess( UINT *args )
{
HANDLE process = get_handle( &args );
return NtUserGetSystemDpiForProcess( process );
}
......@@ -131,6 +131,7 @@ INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count );
HWINSTA WINAPI NtUserGetProcessWindowStation(void);
HANDLE WINAPI NtUserGetProp( HWND hwnd, const WCHAR *str );
ULONG WINAPI NtUserGetProcessDpiAwarenessContext( HANDLE process );
ULONG WINAPI NtUserGetSystemDpiForProcess( HANDLE process );
HDESK WINAPI NtUserGetThreadDesktop( DWORD thread );
BOOL WINAPI NtUserGetUpdatedClipboardFormats( UINT *formats, UINT size, UINT *out_size );
BOOL WINAPI NtUserIsClipboardFormatAvailable( UINT format );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment