diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index f22b7f4f25e..252505f80e6 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -823,7 +823,7 @@ extern void X11DRV_DisplayDevices_Update(BOOL) DECLSPEC_HIDDEN; extern struct x11drv_display_device_handler desktop_handler DECLSPEC_HIDDEN; /* XIM support */ -extern BOOL X11DRV_InitXIM( const char *input_style ) DECLSPEC_HIDDEN; +extern BOOL X11DRV_InitXIM( const WCHAR *input_style ) DECLSPEC_HIDDEN; extern XIC X11DRV_CreateIC(XIM xim, struct x11drv_win_data *data) DECLSPEC_HIDDEN; extern void X11DRV_SetupXIM(void) DECLSPEC_HIDDEN; extern void X11DRV_XIMLookupChars( const char *str, DWORD count ) DECLSPEC_HIDDEN; @@ -841,4 +841,18 @@ static inline BOOL is_window_rect_mapped( const RECT *rect ) max( rect->bottom, rect->top + 1 ) > virtual_rect.top); } +/* string helpers */ + +static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len ) +{ + while (len--) *dst++ = (unsigned char)*src++; +} + +static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src ) +{ + WCHAR *p = dst; + while ((*p++ = *src++)); + return (p - dst) * sizeof(WCHAR); +} + #endif /* __WINE_X11DRV_H */ diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c index f52e504f468..df3c672708e 100644 --- a/dlls/winex11.drv/x11drv_main.c +++ b/dlls/winex11.drv/x11drv_main.c @@ -93,7 +93,7 @@ static int err_callback_result; /* error callback result */ static unsigned long err_serial; /* serial number of first request */ static int (*old_error_handler)( Display *, XErrorEvent * ); static BOOL use_xim = TRUE; -static char input_style[20]; +static WCHAR input_style[20]; static CRITICAL_SECTION x11drv_section; static CRITICAL_SECTION_DEBUG critsect_debug = @@ -336,16 +336,99 @@ static void init_pixmap_formats( Display *display ) } +static HKEY reg_open_key( HKEY root, const WCHAR *name, ULONG name_len ) +{ + UNICODE_STRING nameW = { name_len, name_len, (WCHAR *)name }; + OBJECT_ATTRIBUTES attr; + HANDLE ret; + + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + + return NtOpenKeyEx( &ret, MAXIMUM_ALLOWED, &attr, 0 ) ? 0 : ret; +} + + +static HKEY open_hkcu_key( const char *name ) +{ + WCHAR bufferW[256]; + static HKEY hkcu; + + if (!hkcu) + { + char buffer[256]; + DWORD_PTR sid_data[(sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE) / sizeof(DWORD_PTR)]; + DWORD i, len = sizeof(sid_data); + SID *sid; + + if (NtQueryInformationToken( GetCurrentThreadEffectiveToken(), TokenUser, sid_data, len, &len )) + return 0; + + sid = ((TOKEN_USER *)sid_data)->User.Sid; + len = sprintf( buffer, "\\Registry\\User\\S-%u-%u", sid->Revision, + MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5], + sid->IdentifierAuthority.Value[4] ), + MAKEWORD( sid->IdentifierAuthority.Value[3], + sid->IdentifierAuthority.Value[2] ))); + for (i = 0; i < sid->SubAuthorityCount; i++) + len += sprintf( buffer + len, "-%u", sid->SubAuthority[i] ); + + ascii_to_unicode( bufferW, buffer, len ); + hkcu = reg_open_key( NULL, bufferW, len * sizeof(WCHAR) ); + } + + return reg_open_key( hkcu, bufferW, asciiz_to_unicode( bufferW, name ) - sizeof(WCHAR) ); +} + + +static ULONG query_reg_value( HKEY hkey, const WCHAR *name, + KEY_VALUE_PARTIAL_INFORMATION *info, ULONG size ) +{ + unsigned int name_size = name ? lstrlenW( name ) * sizeof(WCHAR) : 0; + UNICODE_STRING nameW = { name_size, name_size, (WCHAR *)name }; + + if (NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, + info, size, &size )) + return 0; + + return size - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); +} + + /*********************************************************************** * get_config_key * * Get a config key from either the app-specific or the default config */ static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name, - char *buffer, DWORD size ) + WCHAR *buffer, DWORD size ) { - if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0; - if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, (LPBYTE)buffer, &size )) return 0; + WCHAR nameW[128]; + char buf[2048]; + KEY_VALUE_PARTIAL_INFORMATION *info = (void *)buf; + + asciiz_to_unicode( nameW, name ); + + if (appkey && query_reg_value( appkey, nameW, info, sizeof(buf) )) + { + size = min( info->DataLength, size - sizeof(WCHAR) ); + memcpy( buffer, info->Data, size ); + buffer[size / sizeof(WCHAR)] = 0; + return 0; + } + + if (defkey && query_reg_value( defkey, nameW, info, sizeof(buf) )) + { + size = min( info->DataLength, size - sizeof(WCHAR) ); + memcpy( buffer, info->Data, size ); + buffer[size / sizeof(WCHAR)] = 0; + return 0; + } + return ERROR_FILE_NOT_FOUND; } @@ -358,21 +441,20 @@ static inline DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name, static void setup_options(void) { static const WCHAR x11driverW[] = {'\\','X','1','1',' ','D','r','i','v','e','r',0}; - char buffer[64]; - WCHAR bufferW[MAX_PATH+16]; + WCHAR buffer[MAX_PATH+16]; HKEY hkey, appkey = 0; DWORD len; /* @@ Wine registry key: HKCU\Software\Wine\X11 Driver */ - if (RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\X11 Driver", &hkey )) hkey = 0; + hkey = open_hkcu_key( "Software\\Wine\\X11 Driver" ); /* open the app-specific key */ - len = (GetModuleFileNameW( 0, bufferW, MAX_PATH )); + len = GetModuleFileNameW( 0, buffer, MAX_PATH ); if (len && len < MAX_PATH) { HKEY tmpkey; - WCHAR *p, *appname = bufferW; + WCHAR *p, *appname = buffer; if ((p = strrchrW( appname, '/' ))) appname = p + 1; if ((p = strrchrW( appname, '\\' ))) appname = p + 1; CharLowerW(appname); @@ -381,10 +463,10 @@ static void setup_options(void) WideCharToMultiByte( CP_UNIXCP, 0, appname, -1, process_name, len, NULL, NULL ); strcatW( appname, x11driverW ); /* @@ Wine registry key: HKCU\Software\Wine\AppDefaults\app.exe\X11 Driver */ - if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Wine\\AppDefaults", &tmpkey )) + if ((tmpkey = open_hkcu_key( "Software\\Wine\\AppDefaults" ))) { - if (RegOpenKeyW( tmpkey, appname, &appkey )) appkey = 0; - RegCloseKey( tmpkey ); + appkey = reg_open_key( tmpkey, appname, lstrlenW( appname ) * sizeof(WCHAR) ); + NtClose( tmpkey ); } } @@ -419,7 +501,7 @@ static void setup_options(void) grab_fullscreen = IS_OPTION_TRUE( buffer[0] ); if (!get_config_key( hkey, appkey, "ScreenDepth", buffer, sizeof(buffer) )) - default_visual.depth = atoi(buffer); + default_visual.depth = strtolW( buffer, NULL, 0 ); if (!get_config_key( hkey, appkey, "ClientSideGraphics", buffer, sizeof(buffer) )) client_side_graphics = IS_OPTION_TRUE( buffer[0] ); @@ -437,18 +519,18 @@ static void setup_options(void) private_color_map = IS_OPTION_TRUE( buffer[0] ); if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) )) - primary_monitor = atoi( buffer ); + primary_monitor = strtolW( buffer, NULL, 0 ); if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) )) - copy_default_colors = atoi(buffer); + copy_default_colors = strtolW( buffer, NULL, 0 ); if (!get_config_key( hkey, appkey, "AllocSystemColors", buffer, sizeof(buffer) )) - alloc_system_colors = atoi(buffer); + alloc_system_colors = strtolW( buffer, NULL, 0 ); get_config_key( hkey, appkey, "InputStyle", input_style, sizeof(input_style) ); - if (appkey) RegCloseKey( appkey ); - if (hkey) RegCloseKey( hkey ); + NtClose( appkey ); + NtClose( hkey ); } #ifdef SONAME_LIBXCOMPOSITE diff --git a/dlls/winex11.drv/xim.c b/dlls/winex11.drv/xim.c index 3994c2106cc..6adf2475de7 100644 --- a/dlls/winex11.drv/xim.c +++ b/dlls/winex11.drv/xim.c @@ -30,6 +30,7 @@ #include "x11drv.h" #include "imm.h" #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(xim); @@ -290,13 +291,17 @@ void X11DRV_SetPreeditState(HWND hwnd, BOOL fOpen) * * Process-wide XIM initialization. */ -BOOL X11DRV_InitXIM( const char *input_style ) +BOOL X11DRV_InitXIM( const WCHAR *input_style ) { - if (!_strnicmp(input_style, "offthespot", -1)) + static const WCHAR offthespotW[] = {'o','f','f','t','h','e','s','p','o','t',0}; + static const WCHAR overthespotW[] = {'o','v','e','r','t','h','e','s','p','o','t',0}; + static const WCHAR rootW[] = {'r','o','o','t',0}; + + if (!strcmpiW(input_style, offthespotW)) ximStyleRequest = STYLE_OFFTHESPOT; - else if (!_strnicmp(input_style, "overthespot", -1)) + else if (!strcmpiW(input_style, overthespotW)) ximStyleRequest = STYLE_OVERTHESPOT; - else if (!_strnicmp(input_style, "root", -1)) + else if (!strcmpiW(input_style, rootW)) ximStyleRequest = STYLE_ROOT; if (!XSupportsLocale())