Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
April 2021
- 70 participants
- 1934 messages
[PATCH 5/5] user32: Read "Layout Id" from registry in GetKeyboardLayoutList.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/input.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 4895a007500..97be83369d9 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -1336,8 +1336,8 @@ BOOL WINAPI BlockInput(BOOL fBlockIt)
*/
UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts )
{
- WCHAR klid[KL_NAMELENGTH];
- UINT count, tmp, i = 0;
+ WCHAR klid[KL_NAMELENGTH], value[5];
+ DWORD value_size, count, tmp, i = 0;
HKEY hkey;
HKL layout;
@@ -1360,6 +1360,10 @@ UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts )
while (!RegEnumKeyW( hkey, i++, klid, ARRAY_SIZE(klid) ))
{
tmp = wcstoul( klid, NULL, 16 );
+ value_size = sizeof(value);
+ if (!RegGetValueW( hkey, klid, L"Layout Id", RRF_RT_REG_SZ, NULL, (void *)&value, &value_size ))
+ tmp = MAKELONG( LOWORD( tmp ), 0xf000 | (wcstoul( value, NULL, 16 ) & 0xfff) );
+
if (layout == UlongToHandle( tmp )) continue;
count++;
--
2.31.0
April 30, 2021
[PATCH 4/5] user32: Move GetKeyboardLayoutList from nulldrv.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/driver.c | 54 +------------------------------
dlls/user32/input.c | 77 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 75 insertions(+), 56 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index e3cf41561b5..c075a49a350 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -198,59 +198,7 @@ static void CDECL nulldrv_Beep(void)
static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts )
{
- HKEY hKeyKeyboard;
- DWORD rc;
- INT count = 0;
- ULONG_PTR baselayout;
- LANGID langid;
-
- baselayout = GetUserDefaultLCID();
- langid = PRIMARYLANGID(LANGIDFROMLCID(baselayout));
- if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
- baselayout = MAKELONG( baselayout, 0xe001 ); /* IME */
- else
- baselayout |= baselayout << 16;
-
- /* Enumerate the Registry */
- rc = RegOpenKeyW(HKEY_LOCAL_MACHINE,L"System\\CurrentControlSet\\Control\\Keyboard Layouts",&hKeyKeyboard);
- if (rc == ERROR_SUCCESS)
- {
- do {
- WCHAR szKeyName[9];
- HKL layout;
- rc = RegEnumKeyW(hKeyKeyboard, count, szKeyName, 9);
- if (rc == ERROR_SUCCESS)
- {
- layout = (HKL)(ULONG_PTR)wcstoul(szKeyName,NULL,16);
- if (baselayout != 0 && layout == (HKL)baselayout)
- baselayout = 0; /* found in the registry do not add again */
- if (size && layouts)
- {
- if (count >= size ) break;
- layouts[count] = layout;
- }
- count ++;
- }
- } while (rc == ERROR_SUCCESS);
- RegCloseKey(hKeyKeyboard);
- }
-
- /* make sure our base layout is on the list */
- if (baselayout != 0)
- {
- if (size && layouts)
- {
- if (count < size)
- {
- layouts[count] = (HKL)baselayout;
- count++;
- }
- }
- else
- count++;
- }
-
- return count;
+ return ~0; /* use default implementation */
}
static INT CDECL nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 4ecc73c4ad0..4895a007500 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -77,6 +77,43 @@ static WORD get_key_state(void)
}
+/***********************************************************************
+ * get_locale_kbd_layout
+ */
+static HKL get_locale_kbd_layout(void)
+{
+ ULONG_PTR layout;
+ LANGID langid;
+
+ /* FIXME:
+ *
+ * layout = main_key_tab[kbd_layout].lcid;
+ *
+ * Winword uses return value of GetKeyboardLayout as a codepage
+ * to translate ANSI keyboard messages to unicode. But we have
+ * a problem with it: for instance Polish keyboard layout is
+ * identical to the US one, and therefore instead of the Polish
+ * locale id we return the US one.
+ */
+
+ layout = GetUserDefaultLCID();
+
+ /*
+ * Microsoft Office expects this value to be something specific
+ * for Japanese and Korean Windows with an IME the value is 0xe001
+ * We should probably check to see if an IME exists and if so then
+ * set this word properly.
+ */
+ langid = PRIMARYLANGID( LANGIDFROMLCID( layout ) );
+ if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+ layout = MAKELONG( layout, 0xe001 ); /* IME */
+ else
+ layout = MAKELONG( layout, layout );
+
+ return (HKL)layout;
+}
+
+
/**********************************************************************
* set_capture_window
*/
@@ -1297,11 +1334,45 @@ BOOL WINAPI BlockInput(BOOL fBlockIt)
* Return number of values available if either input parm is
* 0, per MS documentation.
*/
-UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts)
+UINT WINAPI GetKeyboardLayoutList( INT size, HKL *layouts )
{
- TRACE_(keyboard)( "(%d, %p)\n", nBuff, layouts );
+ WCHAR klid[KL_NAMELENGTH];
+ UINT count, tmp, i = 0;
+ HKEY hkey;
+ HKL layout;
+
+ TRACE_(keyboard)( "size %d, layouts %p.\n", size, layouts );
+
+ if ((count = USER_Driver->pGetKeyboardLayoutList( size, layouts )) != ~0) return count;
+
+ layout = get_locale_kbd_layout();
+ count = 0;
+
+ count++;
+ if (size && layouts)
+ {
+ layouts[count - 1] = layout;
+ if (count == size) return count;
+ }
+
+ if (!RegOpenKeyW( HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Control\\Keyboard Layouts", &hkey ))
+ {
+ while (!RegEnumKeyW( hkey, i++, klid, ARRAY_SIZE(klid) ))
+ {
+ tmp = wcstoul( klid, NULL, 16 );
+ if (layout == UlongToHandle( tmp )) continue;
+
+ count++;
+ if (size && layouts)
+ {
+ layouts[count - 1] = UlongToHandle( tmp );
+ if (count == size) break;
+ }
+ }
+ RegCloseKey( hkey );
+ }
- return USER_Driver->pGetKeyboardLayoutList( nBuff, layouts );
+ return count;
}
--
2.31.0
April 30, 2021
[PATCH 3/5] user32: Add a default VkKeyScanEx implementation.
by Rémi Bernon
This is basically the reverse of ToUnicodeEx.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/driver.c | 9 +------
dlls/user32/input.c | 61 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 60 insertions(+), 10 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index 97733bb9bd3..e3cf41561b5 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -300,14 +300,7 @@ static void CDECL nulldrv_UnregisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
static SHORT CDECL nulldrv_VkKeyScanEx( WCHAR ch, HKL layout )
{
- static const short ctrl_vks[] = {
- 0x332, 0x241, 0x242, 0x003, 0x244, 0x245, 0x246, 0x247,
- 0x008, 0x009, 0x20d, 0x24b, 0x24c, 0x00d, 0x24e, 0x24f,
- 0x250, 0x251, 0x252, 0x253, 0x254, 0x255, 0x256, 0x257,
- 0x258, 0x259, 0x25a, 0x01b, 0x2dc, 0x2dd, 0x336, 0x3bd
- };
-
- return ch < ARRAY_SIZE(ctrl_vks) ? ctrl_vks[ch] : -1;
+ return -256; /* use default implementation */
}
static void CDECL nulldrv_DestroyCursorIcon( HCURSOR cursor )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index d2e41cd8212..4ecc73c4ad0 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -674,9 +674,66 @@ WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
/******************************************************************************
* VkKeyScanExW (USER32.@)
*/
-WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
+WORD WINAPI VkKeyScanExW( WCHAR chr, HKL layout )
{
- return USER_Driver->pVkKeyScanEx(cChar, dwhkl);
+ WORD shift = 0x100, ctrl = 0x200;
+ SHORT ret;
+
+ TRACE_(keyboard)( "chr %s, layout %p\n", debugstr_wn(&chr, 1), layout );
+
+ if ((ret = USER_Driver->pVkKeyScanEx( chr, layout )) != -256) return ret;
+
+ /* FIXME: English keyboard layout specific */
+
+ if (chr == VK_CANCEL || chr == VK_BACK || chr == VK_TAB || chr == VK_RETURN ||
+ chr == VK_ESCAPE || chr == VK_SPACE) ret = chr;
+ else if (chr >= '0' && chr <= '9') ret = chr;
+ else if (chr == ')') ret = shift + '0';
+ else if (chr == '!') ret = shift + '1';
+ else if (chr == '@') ret = shift + '2';
+ else if (chr == '#') ret = shift + '3';
+ else if (chr == '$') ret = shift + '4';
+ else if (chr == '%') ret = shift + '5';
+ else if (chr == '^') ret = shift + '6';
+ else if (chr == '&') ret = shift + '7';
+ else if (chr == '*') ret = shift + '8';
+ else if (chr == '(') ret = shift + '9';
+ else if (chr >= 'a' && chr <= 'z') ret = chr - 'a' + 'A';
+ else if (chr >= 'A' && chr <= 'Z') ret = shift + chr;
+ else if (chr == ';') ret = VK_OEM_1;
+ else if (chr == '=') ret = VK_OEM_PLUS;
+ else if (chr == ',') ret = VK_OEM_COMMA;
+ else if (chr == '-') ret = VK_OEM_MINUS;
+ else if (chr == '.') ret = VK_OEM_PERIOD;
+ else if (chr == '/') ret = VK_OEM_2;
+ else if (chr == '`') ret = VK_OEM_3;
+ else if (chr == '[') ret = VK_OEM_4;
+ else if (chr == '\\') ret = VK_OEM_5;
+ else if (chr == ']') ret = VK_OEM_6;
+ else if (chr == '\'') ret = VK_OEM_7;
+ else if (chr == ':') ret = shift + VK_OEM_1;
+ else if (chr == '+') ret = shift + VK_OEM_PLUS;
+ else if (chr == '<') ret = shift + VK_OEM_COMMA;
+ else if (chr == '_') ret = shift + VK_OEM_MINUS;
+ else if (chr == '>') ret = shift + VK_OEM_PERIOD;
+ else if (chr == '?') ret = shift + VK_OEM_2;
+ else if (chr == '~') ret = shift + VK_OEM_3;
+ else if (chr == '{') ret = shift + VK_OEM_4;
+ else if (chr == '|') ret = shift + VK_OEM_5;
+ else if (chr == '}') ret = shift + VK_OEM_6;
+ else if (chr == '\"') ret = shift + VK_OEM_7;
+ else if (chr == 0x7f) ret = ctrl + VK_BACK;
+ else if (chr == '\n') ret = ctrl + VK_RETURN;
+ else if (chr == 0xf000) ret = ctrl + '2';
+ else if (chr == 0x0000) ret = ctrl + shift + '2';
+ else if (chr >= 0x0001 && chr <= 0x001a) ret = ctrl + 'A' + chr - 1;
+ else if (chr >= 0x001c && chr <= 0x001d) ret = ctrl + VK_OEM_3 + chr;
+ else if (chr == 0x001e) ret = ctrl + shift + '6';
+ else if (chr == 0x001f) ret = ctrl + shift + VK_OEM_MINUS;
+ else ret = -1;
+
+ TRACE_(keyboard)( "ret %04x\n", ret );
+ return ret;
}
/**********************************************************************
--
2.31.0
April 30, 2021
[PATCH 2/5] user32: Add a default GetKeyNameTextW implementation.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/driver.c | 2 +-
dlls/user32/input.c | 85 ++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 83 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index aedc0366615..97733bb9bd3 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -255,7 +255,7 @@ static UINT CDECL nulldrv_GetKeyboardLayoutList( INT size, HKL *layouts )
static INT CDECL nulldrv_GetKeyNameText( LONG lparam, LPWSTR buffer, INT size )
{
- return 0;
+ return -1; /* use default implementation */
}
static HKL CDECL nulldrv_GetKeyboardLayout( DWORD thread_id )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index 4eaac54343e..d2e41cd8212 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -853,6 +853,43 @@ static const UINT kbd_en_vk2char[] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
+static const WCHAR *kbd_en_vscname[] =
+{
+ 0, L"Esc", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Backspace", L"Tab",
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Enter", L"Ctrl", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Shift", 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, L"Right Shift", L"Num *", L"Alt", L"Space", L"Caps Lock", L"F1", L"F2", L"F3", L"F4", L"F5",
+ L"F6", L"F7", L"F8", L"F9", L"F10", L"Pause", L"Scroll Lock", L"Num 7", L"Num 8", L"Num 9", L"Num -", L"Num 4", L"Num 5", L"Num 6", L"Num +", L"Num 1",
+ L"Num 2", L"Num 3", L"Num 0", L"Num Del", L"Sys Req", 0, 0, L"F11", L"F12", 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"F13", L"F14", L"F15", L"F16",
+ L"F17", L"F18", L"F19", L"F20", L"F21", L"F22", L"F23", L"F24", 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* extended */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Num Enter", L"Right Ctrl", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, L"Num /", 0, L"Prnt Scrn", L"Right Alt", 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, L"Num Lock", L"Break", L"Home", L"Up", L"Page Up", 0, L"Left", 0, L"Right", 0, L"End",
+ L"Down", L"Page Down", L"Insert", L"Delete", L"<00>", 0, L"Help", 0, 0, 0, 0, L"Left Windows", L"Right Windows", L"Application", 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
/******************************************************************************
* MapVirtualKeyExW (USER32.@)
@@ -1007,10 +1044,52 @@ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
/****************************************************************************
* GetKeyNameTextW (USER32.@)
*/
-INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
+INT WINAPI GetKeyNameTextW( LONG lparam, LPWSTR buffer, INT size )
{
- if (!lpBuffer || !nSize) return 0;
- return USER_Driver->pGetKeyNameText( lParam, lpBuffer, nSize );
+ INT code = ((lparam >> 16) & 0x1ff), vkey, len;
+ UINT vsc2vk_size, vscname_size;
+ const WCHAR *const *vscname;
+ const UINT *vsc2vk;
+ WCHAR tmp[2];
+
+ TRACE_(keyboard)( "lparam %d, buffer %p, size %d.\n", lparam, buffer, size );
+
+ if (!buffer || !size) return 0;
+ if ((len = USER_Driver->pGetKeyNameText( lparam, buffer, size )) >= 0) return len;
+
+ /* FIXME: English keyboard layout specific */
+
+ vsc2vk = kbd_en_vsc2vk;
+ vsc2vk_size = ARRAYSIZE(kbd_en_vsc2vk);
+ vscname = kbd_en_vscname;
+ vscname_size = ARRAYSIZE(kbd_en_vscname);
+
+ if (lparam & 0x2000000)
+ {
+ switch ((vkey = vsc2vk[code]))
+ {
+ case VK_RSHIFT:
+ case VK_RCONTROL:
+ case VK_RMENU:
+ for (code = 0; code < vsc2vk_size; ++code)
+ if (vsc2vk[code] == (vkey - 1)) break;
+ break;
+ }
+ }
+
+ if (code >= vscname_size) buffer[0] = 0;
+ else if (vscname[code]) lstrcpynW( buffer, vscname[code], size );
+ else
+ {
+ vkey = MapVirtualKeyW( code & 0xff, MAPVK_VSC_TO_VK );
+ tmp[0] = MapVirtualKeyW( vkey, MAPVK_VK_TO_CHAR );
+ tmp[1] = 0;
+ lstrcpynW( buffer, tmp, size );
+ }
+ len = wcslen( buffer );
+
+ TRACE_(keyboard)( "ret %d, str %s.\n", len, debugstr_w(buffer) );
+ return len;
}
/****************************************************************************
--
2.31.0
April 30, 2021
[PATCH 1/5] user32: Add a default MapVirtualKeyEx implementation.
by Rémi Bernon
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/user32/driver.c | 2 +-
dlls/user32/input.c | 154 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 152 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/driver.c b/dlls/user32/driver.c
index e5855e1c51b..aedc0366615 100644
--- a/dlls/user32/driver.c
+++ b/dlls/user32/driver.c
@@ -275,7 +275,7 @@ static HKL CDECL nulldrv_LoadKeyboardLayout( LPCWSTR name, UINT flags )
static UINT CDECL nulldrv_MapVirtualKeyEx( UINT code, UINT type, HKL layout )
{
- return 0;
+ return -1; /* use default implementation */
}
static BOOL CDECL nulldrv_RegisterHotKey( HWND hwnd, UINT modifiers, UINT vk )
diff --git a/dlls/user32/input.c b/dlls/user32/input.c
index b21ec73696d..4eaac54343e 100644
--- a/dlls/user32/input.c
+++ b/dlls/user32/input.c
@@ -777,14 +777,162 @@ UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
return ret;
}
+
+/* English keyboard layout (0x0409) */
+static const UINT kbd_en_vsc2vk[] =
+{
+ 0x00, 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xbd, 0xbb, 0x08, 0x09,
+ 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4f, 0x50, 0xdb, 0xdd, 0x0d, 0xa2, 0x41, 0x53,
+ 0x44, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0xba, 0xde, 0xc0, 0xa0, 0xdc, 0x5a, 0x58, 0x43, 0x56,
+ 0x42, 0x4e, 0x4d, 0xbc, 0xbe, 0xbf, 0xa1, 0x6a, 0xa4, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74,
+ 0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x24, 0x26, 0x21, 0x6d, 0x25, 0x0c, 0x27, 0x6b, 0x23,
+ 0x28, 0x22, 0x2d, 0x2e, 0x2c, 0x00, 0xe2, 0x7a, 0x7b, 0x0c, 0xee, 0xf1, 0xea, 0xf9, 0xf5, 0xf3,
+ 0x00, 0x00, 0xfb, 0x2f, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xed,
+ 0x00, 0xe9, 0x00, 0xc1, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x09, 0x00, 0xc2, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0xe000 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x0d, 0xa3, 0x00, 0x00,
+ 0xad, 0xb7, 0xb3, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x00,
+ 0xaf, 0x00, 0xac, 0x00, 0x00, 0x6f, 0x00, 0x2c, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x24, 0x26, 0x21, 0x00, 0x25, 0x00, 0x27, 0x00, 0x23,
+ 0x28, 0x22, 0x2d, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5c, 0x5d, 0x00, 0x5f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xab, 0xa8, 0xa9, 0xa7, 0xa6, 0xb6, 0xb4, 0xb5, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /* 0xe100 */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const UINT kbd_en_vk2char[] =
+{
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00,
+ ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '+', 0x00, '-', '.', '/',
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ';', '=', ',', '-', '.', '/',
+ '`', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, '[', '\\', ']', '\'', 0x00,
+ 0x00, 0x00, '\\', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+
/******************************************************************************
* MapVirtualKeyExW (USER32.@)
*/
-UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
+UINT WINAPI MapVirtualKeyExW( UINT code, UINT type, HKL layout )
{
- TRACE_(keyboard)("(%X, %d, %p)\n", code, maptype, hkl);
+ const UINT *vsc2vk, *vk2char;
+ UINT vsc2vk_size, vk2char_size;
+ UINT ret;
+
+ TRACE_(keyboard)( "code %u, type %u, layout %p.\n", code, type, layout );
- return USER_Driver->pMapVirtualKeyEx(code, maptype, hkl);
+ if ((ret = USER_Driver->pMapVirtualKeyEx( code, type, layout )) != -1) return ret;
+
+ /* FIXME: English keyboard layout specific */
+
+ vsc2vk = kbd_en_vsc2vk;
+ vsc2vk_size = ARRAYSIZE(kbd_en_vsc2vk);
+ vk2char = kbd_en_vk2char;
+ vk2char_size = ARRAYSIZE(kbd_en_vk2char);
+
+ switch (type)
+ {
+ case MAPVK_VK_TO_VSC_EX:
+ case MAPVK_VK_TO_VSC:
+ switch (code)
+ {
+ case VK_SHIFT: code = VK_LSHIFT; break;
+ case VK_CONTROL: code = VK_LCONTROL; break;
+ case VK_MENU: code = VK_LMENU; break;
+ case VK_NUMPAD0: code = VK_INSERT; break;
+ case VK_NUMPAD1: code = VK_END; break;
+ case VK_NUMPAD2: code = VK_DOWN; break;
+ case VK_NUMPAD3: code = VK_NEXT; break;
+ case VK_NUMPAD4: code = VK_LEFT; break;
+ case VK_NUMPAD5: code = VK_CLEAR; break;
+ case VK_NUMPAD6: code = VK_RIGHT; break;
+ case VK_NUMPAD7: code = VK_HOME; break;
+ case VK_NUMPAD8: code = VK_UP; break;
+ case VK_NUMPAD9: code = VK_PRIOR; break;
+ case VK_DECIMAL: code = VK_DELETE; break;
+ }
+
+ for (ret = 0; ret < vsc2vk_size; ++ret) if (vsc2vk[ret] == code) break;
+ if (ret >= vsc2vk_size) ret = 0;
+
+ if (type == MAPVK_VK_TO_VSC)
+ {
+ if (ret >= 0x200) ret = 0;
+ else ret &= 0xff;
+ }
+ else if (ret >= 0x100) ret += 0xdf00;
+ break;
+ case MAPVK_VSC_TO_VK:
+ case MAPVK_VSC_TO_VK_EX:
+ if (code & 0xe000) code -= 0xdf00;
+ if (code >= vsc2vk_size) ret = 0;
+ else ret = vsc2vk[code];
+
+ if (type == MAPVK_VSC_TO_VK)
+ {
+ switch (ret)
+ {
+ case VK_LSHIFT: case VK_RSHIFT: ret = VK_SHIFT; break;
+ case VK_LCONTROL: case VK_RCONTROL: ret = VK_CONTROL; break;
+ case VK_LMENU: case VK_RMENU: ret = VK_MENU; break;
+ }
+ }
+ break;
+ case MAPVK_VK_TO_CHAR:
+ if (code >= vk2char_size) ret = 0;
+ else ret = vk2char[code];
+ break;
+ default:
+ FIXME_(keyboard)( "unknown type %d\n", type );
+ return 0;
+ }
+
+ TRACE_(keyboard)( "returning 0x%04x\n", ret );
+ return ret;
}
/****************************************************************************
--
2.31.0
April 30, 2021
Re: [PATCH resend] ws2_32: Hook up IPV6_HOPLIMIT
by Alexandre Julliard
Alex Henrie <alexhenrie24(a)gmail.com> writes:
> Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
> ---
> FelgoLiveClient.exe from https://felgo.com/ sets this option.
> ---
> dlls/ws2_32/socket.c | 4 ++++
> 1 file changed, 4 insertions(+)
You'd need to add #ifdefs like for the other similar options.
--
Alexandre Julliard
julliard(a)winehq.org
April 30, 2021
[PATCH] urlmon/tests: Allow x64 to be last in the user agent.
by Francois Gouget
Windows would normally have .Net strings that follow but Wine does not
in 64-bit mode. Still the formatting makes sense so allow it.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This fixes a test failure in Wine in wow64 mode.
https://test.winehq.org/data/patterns.html#urlmon:misc
https://testbot.winehq.org/JobDetails.pl?Key=89589
An alternative would be to turn it into a todo if i == 1.
---
dlls/urlmon/tests/misc.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/urlmon/tests/misc.c b/dlls/urlmon/tests/misc.c
index 2b3df65d5fc..5b179b55770 100644
--- a/dlls/urlmon/tests/misc.c
+++ b/dlls/urlmon/tests/misc.c
@@ -1544,7 +1544,9 @@ static void test_user_agent(void)
}else if(sizeof(void*) == 8) {
p += check_prefix(p, "Win64; ");
#ifdef __x86_64__
- p += check_prefix(p, "x64; ");
+ p += check_prefix(p, "x64");
+ if (*p == ';')
+ p += check_prefix(p, "; ");
#endif
}
if(i != 1) {
--
2.20.1
April 30, 2021
[PATCH] msado15: Use Recordset_Open in Connection_Execute
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/msado15/connection.c | 36 +++++++++++++++++-------------------
1 file changed, 17 insertions(+), 19 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c
index a3c9a450be6..2d43aff787f 100644
--- a/dlls/msado15/connection.c
+++ b/dlls/msado15/connection.c
@@ -339,51 +339,49 @@ static HRESULT WINAPI connection_Execute( _Connection *iface, BSTR command, VARI
{
struct connection *connection = impl_from_Connection( iface );
HRESULT hr;
- ICommandText *command_text;
- DBROWCOUNT affected;
- IUnknown *rowset;
_Recordset *recordset;
- ADORecordsetConstruction *construct;
+ VARIANT source, active;
+ IDispatch *dispatch;
FIXME( "%p, %s, %p, 0x%08x, %p Semi-stub\n", iface, debugstr_w(command), records_affected, options, record_set );
if (connection->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
- hr = create_command_text(connection->session, command, &command_text);
+ hr = Recordset_create( (void**)&recordset);
if (FAILED(hr))
+ {
return hr;
+ }
- hr = ICommandText_Execute(command_text, NULL, &IID_IUnknown, NULL, &affected, &rowset);
- ICommandText_Release(command_text);
- if (FAILED(hr))
- return hr;
+ _Recordset_put_CursorLocation(recordset, connection->location);
- hr = Recordset_create( (void**)&recordset);
+ V_VT(&source) = VT_BSTR;
+ V_BSTR(&source) = command;
+
+ hr = _Connection_QueryInterface(&connection->Connection_iface, &IID_IDispatch, (void**)&dispatch);
if (FAILED(hr))
{
- IUnknown_Release(rowset);
+ _Recordset_Release(recordset);
return hr;
}
- hr = _Recordset_QueryInterface(recordset, &IID_ADORecordsetConstruction, (void**)&construct);
+ V_VT(&active) = VT_DISPATCH;
+ V_DISPATCH(&active) = dispatch;
+
+ hr = _Recordset_Open(recordset, source, active, adOpenDynamic, adLockPessimistic, 0);
+ VariantClear(&active);
if (FAILED(hr))
{
- IUnknown_Release(rowset);
_Recordset_Release(recordset);
return hr;
}
- ADORecordsetConstruction_put_Rowset(construct, rowset);
- ADORecordsetConstruction_Release(construct);
- IUnknown_Release(rowset);
-
if (records_affected)
{
V_VT(records_affected) = VT_I4;
- V_I4(records_affected) = affected;
+ _Recordset_get_RecordCount(recordset, &V_I4(records_affected));
}
- _Recordset_put_CursorLocation(recordset, connection->location);
*record_set = recordset;
return hr;
--
2.30.2
April 30, 2021
Re: [PATCH 2/5] ws2_32/tests: Rewrite test_events().
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=89584
Your paranoid android.
=== w7u_adm (32 bit report) ===
ws2_32:
sock.c:4376: Test failed: got 3
sock.c:4378: Test failed: got unexpected event 0x1
sock.c:4378: Test failed: event series matches
April 30, 2021
Re: [PATCH 1/5] ws2_32/tests: Add some tests for bind().
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=89583
Your paranoid android.
=== debiant2 (32 bit report) ===
ws2_32:
sock.c:6946: Test succeeded inside todo block: GetQueuedCompletionStatus returned 0
sock.c:6947: Test succeeded inside todo block: Last error was 64
April 30, 2021