diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec index 9b754985f27..4f10c4ce0b5 100644 --- a/dlls/ttydrv/ttydrv.spec +++ b/dlls/ttydrv/ttydrv.spec @@ -35,10 +35,10 @@ # USER driver -@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan -@ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey -@ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText -@ cdecl ToUnicode(long long ptr ptr long long) TTYDRV_ToUnicode +@ cdecl VkKeyScanEx(long long) TTYDRV_VkKeyScanEx +@ cdecl MapVirtualKeyEx(long long long) TTYDRV_MapVirtualKeyEx +@ cdecl GetKeyNameText(long ptr long) TTYDRV_GetKeyNameText +@ cdecl ToUnicodeEx(long long ptr ptr long long long) TTYDRV_ToUnicodeEx @ cdecl Beep() TTYDRV_Beep @ cdecl SetCursor(ptr) TTYDRV_SetCursor @ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c index 9c9afdb09b5..fad2331509f 100644 --- a/dlls/ttydrv/user.c +++ b/dlls/ttydrv/user.c @@ -34,17 +34,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(ttydrv); struct tagCURSORICONINFO; /*********************************************************************** - * VkKeyScan (TTYDRV.@) + * VkKeyScanEx (TTYDRV.@) */ -WORD TTYDRV_VkKeyScan(CHAR cChar) +SHORT TTYDRV_VkKeyScanEx(WCHAR cChar, HKL hkl) { return 0; } /*********************************************************************** - * MapVirtualKey (TTYDRV.@) + * MapVirtualKeyEx (TTYDRV.@) */ -UINT16 TTYDRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType) +UINT TTYDRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl) { return 0; } @@ -52,7 +52,7 @@ UINT16 TTYDRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType) /*********************************************************************** * GetKeyNameText (TTYDRV.@) */ -INT16 TTYDRV_GetKeyNameText( LONG lParam, LPSTR lpBuffer, INT16 nSize ) +INT TTYDRV_GetKeyNameText( LONG lParam, LPWSTR lpBuffer, INT nSize ) { if(lpBuffer && nSize) { @@ -62,10 +62,10 @@ INT16 TTYDRV_GetKeyNameText( LONG lParam, LPSTR lpBuffer, INT16 nSize ) } /*********************************************************************** - * ToUnicode (TTYDRV.@) + * ToUnicodeEx (TTYDRV.@) */ -INT TTYDRV_ToUnicode( UINT virtKey, UINT scanCode, LPBYTE lpKeyState, - LPWSTR pwszBuff, int cchBuff, UINT flags ) +INT TTYDRV_ToUnicodeEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState, + LPWSTR pwszBuff, int cchBuff, UINT flags, HKL hkl ) { return 0; } diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index 22c5705db19..ef3fe23c63a 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec @@ -591,7 +591,7 @@ @ stdcall UnhookWindowsHook(long ptr) @ stdcall UnhookWindowsHookEx(long) @ stdcall UnionRect(ptr ptr ptr) -@ stub UnloadKeyboardLayout +@ stdcall UnloadKeyboardLayout(long) @ stub UnlockWindowStation @ stdcall UnpackDDElParam(long long ptr ptr) @ stdcall UnregisterClassA(str long) diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c index 999c8b10faa..d8e5262ce42 100644 --- a/dlls/user/user_main.c +++ b/dlls/user/user_main.c @@ -76,10 +76,16 @@ static BOOL load_driver(void) } GET_USER_FUNC(InitKeyboard); - GET_USER_FUNC(VkKeyScan); - GET_USER_FUNC(MapVirtualKey); + GET_USER_FUNC(VkKeyScanEx); + GET_USER_FUNC(MapVirtualKeyEx); GET_USER_FUNC(GetKeyNameText); - GET_USER_FUNC(ToUnicode); + GET_USER_FUNC(ToUnicodeEx); + GET_USER_FUNC(GetKeyboardLayoutList); + GET_USER_FUNC(GetKeyboardLayout); + GET_USER_FUNC(GetKeyboardLayoutName); + GET_USER_FUNC(LoadKeyboardLayout); + GET_USER_FUNC(ActivateKeyboardLayout); + GET_USER_FUNC(UnloadKeyboardLayout); GET_USER_FUNC(Beep); GET_USER_FUNC(InitMouse); GET_USER_FUNC(SetCursor); diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in index a083dfe9233..dc24c195be7 100644 --- a/dlls/x11drv/Makefile.in +++ b/dlls/x11drv/Makefile.in @@ -6,7 +6,7 @@ VPATH = @srcdir@ MODULE = x11drv.dll IMPORTS = user32 gdi32 advapi32 kernel32 ntdll EXTRAINCL = @X_CFLAGS@ -EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ +EXTRALIBS = $(LIBUNICODE) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@ C_SRCS = \ $(TOPOBJDIR)/graphics/x11drv/bitblt.c \ diff --git a/dlls/x11drv/keyboard.c b/dlls/x11drv/keyboard.c index 8a8b80f11ca..1c1ce069c10 100644 --- a/dlls/x11drv/keyboard.c +++ b/dlls/x11drv/keyboard.c @@ -44,10 +44,12 @@ #include "windef.h" #include "winbase.h" #include "wingdi.h" +#include "winuser.h" #include "wine/winuser16.h" #include "winnls.h" #include "win.h" #include "x11drv.h" +#include "wine/unicode.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(keyboard); @@ -115,6 +117,16 @@ static const WORD main_key_vkey_qwerty[MAIN_LEN] = VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */ }; +static const WORD main_key_vkey_qwerty_v2[MAIN_LEN] = +{ +/* NOTE: this layout must concur with the scan codes layout above */ + VK_OEM_5,VK_1,VK_2,VK_3,VK_4,VK_5,VK_6,VK_7,VK_8,VK_9,VK_0,VK_OEM_PLUS,VK_OEM_4, + VK_Q,VK_W,VK_E,VK_R,VK_T,VK_Y,VK_U,VK_I,VK_O,VK_P,VK_OEM_6,VK_OEM_1, + VK_A,VK_S,VK_D,VK_F,VK_G,VK_H,VK_J,VK_K,VK_L,VK_OEM_3,VK_OEM_7,VK_OEM_2, + VK_Z,VK_X,VK_C,VK_V,VK_B,VK_N,VK_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_MINUS, + VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */ +}; + static const WORD main_key_vkey_qwertz[MAIN_LEN] = { /* NOTE: this layout must concur with the scan codes layout above */ @@ -738,68 +750,70 @@ static const char main_key_vnc[MAIN_LEN][4] = /*** Layout table. Add your keyboard mappings to this list */ static const struct { + LCID lcid; /* input locale identifier, look for LOCALE_ILANGUAGE + in the appropriate dlls/kernel/nls/.nls file */ const char *comment; const char (*key)[MAIN_LEN][4]; const WORD (*scan)[MAIN_LEN]; /* scan codes mapping */ const WORD (*vkey)[MAIN_LEN]; /* virtual key codes mapping */ } main_key_tab[]={ - {"United States keyboard layout", &main_key_US, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"United States keyboard layout (phantom key version)", &main_key_US_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"United States keyboard layout (dvorak)", &main_key_US_dvorak, &main_key_scan_dvorak, &main_key_vkey_dvorak}, - {"British keyboard layout", &main_key_UK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"German keyboard layout", &main_key_DE, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"German keyboard layout without dead keys", &main_key_DE_nodead, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"German keyboard layout for logitech desktop pro", &main_key_DE_logitech, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"German keyboard layout without dead keys 105", &main_key_DE_nodead_105, &main_key_scan_qwerty, &main_key_vkey_qwertz_105}, - {"Swiss German keyboard layout", &main_key_SG, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Swiss French keyboard layout", &main_key_SF, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Swedish keyboard layout", &main_key_SE, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Estonian keyboard layout", &main_key_ET, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Norwegian keyboard layout", &main_key_NO, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Danish keyboard layout", &main_key_DA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"French keyboard layout", &main_key_FR, &main_key_scan_qwerty, &main_key_vkey_azerty}, - {"Canadian French keyboard layout", &main_key_CF, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Belgian keyboard layout", &main_key_BE, &main_key_scan_qwerty, &main_key_vkey_azerty}, - {"Portuguese keyboard layout", &main_key_PT, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Brazilian ABNT-2 keyboard layout", &main_key_PT_br, &main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty}, - {"Brazilian ABNT-2 keyboard layout ALT GR", &main_key_PT_br_alt_gr,&main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty}, - {"United States International keyboard layout", &main_key_US_intl, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Finnish keyboard layout", &main_key_FI, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Bulgarian bds keyboard layout", &main_key_BG_bds, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Bulgarian phonetic keyboard layout", &main_key_BG_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Belarusian keyboard layout", &main_key_BY, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Russian keyboard layout", &main_key_RU, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Russian keyboard layout (phantom key version)", &main_key_RU_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Russian keyboard layout KOI8-R", &main_key_RU_koi8r, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Russian keyboard layout cp1251", &main_key_RU_cp1251, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Russian phonetic keyboard layout", &main_key_RU_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Ukrainian keyboard layout KOI8-U", &main_key_UA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Spanish keyboard layout", &main_key_ES, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Italian keyboard layout", &main_key_IT, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Icelandic keyboard layout", &main_key_IS, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Hungarian keyboard layout", &main_key_HU, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Polish (programmer's) keyboard layout", &main_key_PL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Czech keyboard layout cz", &main_key_CZ, &main_key_scan_qwerty, &main_key_vkey_qwertz}, - {"Czech keyboard layout cz_qwerty", &main_key_CZ_qwerty, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Latin American keyboard layout", &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Lithuanian (Baltic) keyboard layout", &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Turkish keyboard layout", &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Israelian keyboard layout", &main_key_IL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Israelian phonetic keyboard layout", &main_key_IL_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Israelian Saharon keyboard layout", &main_key_IL_saharon, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"VNC keyboard layout", &main_key_vnc, &main_key_scan_vnc, &main_key_vkey_vnc}, - {"Greek keyboard layout", &main_key_EL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {"Thai (Kedmanee) keyboard layout", &main_key_th, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0409, "United States keyboard layout", &main_key_US, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0409, "United States keyboard layout (phantom key version)", &main_key_US_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0409, "United States keyboard layout (dvorak)", &main_key_US_dvorak, &main_key_scan_dvorak, &main_key_vkey_dvorak}, + {0x0409, "United States International keyboard layout", &main_key_US_intl, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0809, "British keyboard layout", &main_key_UK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0407, "German keyboard layout", &main_key_DE, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x0407, "German keyboard layout without dead keys", &main_key_DE_nodead, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x0407, "German keyboard layout for logitech desktop pro", &main_key_DE_logitech, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x0407, "German keyboard layout without dead keys 105", &main_key_DE_nodead_105, &main_key_scan_qwerty, &main_key_vkey_qwertz_105}, + {0x0807, "Swiss German keyboard layout", &main_key_SG, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x100c, "Swiss French keyboard layout", &main_key_SF, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x041d, "Swedish keyboard layout", &main_key_SE, &main_key_scan_qwerty, &main_key_vkey_qwerty_v2}, + {0x0425, "Estonian keyboard layout", &main_key_ET, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0414, "Norwegian keyboard layout", &main_key_NO, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0406, "Danish keyboard layout", &main_key_DA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040c, "French keyboard layout", &main_key_FR, &main_key_scan_qwerty, &main_key_vkey_azerty}, + {0x0c0c, "Canadian French keyboard layout", &main_key_CF, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x080c, "Belgian keyboard layout", &main_key_BE, &main_key_scan_qwerty, &main_key_vkey_azerty}, + {0x0816, "Portuguese keyboard layout", &main_key_PT, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0416, "Brazilian ABNT-2 keyboard layout", &main_key_PT_br, &main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty}, + {0x0416, "Brazilian ABNT-2 keyboard layout ALT GR", &main_key_PT_br_alt_gr,&main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty}, + {0x040b, "Finnish keyboard layout", &main_key_FI, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0402, "Bulgarian bds keyboard layout", &main_key_BG_bds, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0402, "Bulgarian phonetic keyboard layout", &main_key_BG_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0423, "Belarusian keyboard layout", &main_key_BY, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0419, "Russian keyboard layout", &main_key_RU, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0419, "Russian keyboard layout (phantom key version)", &main_key_RU_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0419, "Russian keyboard layout KOI8-R", &main_key_RU_koi8r, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0419, "Russian keyboard layout cp1251", &main_key_RU_cp1251, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0419, "Russian phonetic keyboard layout", &main_key_RU_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0422, "Ukrainian keyboard layout KOI8-U", &main_key_UA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040a, "Spanish keyboard layout", &main_key_ES, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0410, "Italian keyboard layout", &main_key_IT, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040f, "Icelandic keyboard layout", &main_key_IS, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040e, "Hungarian keyboard layout", &main_key_HU, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x0415, "Polish (programmer's) keyboard layout", &main_key_PL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0424, "Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x041a, "Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x041a, "Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x041b, "Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x041b, "Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0405, "Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0405, "Czech keyboard layout cz", &main_key_CZ, &main_key_scan_qwerty, &main_key_vkey_qwertz}, + {0x0405, "Czech keyboard layout cz_qwerty", &main_key_CZ_qwerty, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040a, "Latin American keyboard layout", &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0427, "Lithuanian (Baltic) keyboard layout", &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x041f, "Turkish keyboard layout", &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040d, "Israelian keyboard layout", &main_key_IL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040d, "Israelian phonetic keyboard layout", &main_key_IL_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x040d, "Israelian Saharon keyboard layout", &main_key_IL_saharon, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x0409, "VNC keyboard layout", &main_key_vnc, &main_key_scan_vnc, &main_key_vkey_vnc}, + {0x0408, "Greek keyboard layout", &main_key_EL, &main_key_scan_qwerty, &main_key_vkey_qwerty}, + {0x041e, "Thai (Kedmanee) keyboard layout", &main_key_th, &main_key_scan_qwerty, &main_key_vkey_qwerty}, - {NULL, NULL, NULL, NULL} /* sentinel */ + {0, NULL, NULL, NULL, NULL} /* sentinel */ }; static unsigned kbd_layout=0; /* index into above table of layouts */ @@ -1487,26 +1501,148 @@ void X11DRV_InitKeyboard( BYTE *key_state_table ) /*********************************************************************** - * X11DRV_MappingNotify + * GetKeyboardLayoutList (X11DRV.@) */ -void X11DRV_MappingNotify( XMappingEvent *event ) +UINT X11DRV_GetKeyboardLayoutList(INT size, HKL *hkl) { - TSXRefreshKeyboardMapping(event); - X11DRV_InitKeyboard( pKeyStateTable ); + INT i; + + TRACE("%d, %p\n", size, hkl); + + if (!size) + { + size = 4096; /* hope we will never have that many */ + hkl = NULL; + } + + for (i = 0; main_key_tab[i].comment && (i < size); i++) + { + if (hkl) + hkl[i] = (HKL)main_key_tab[i].lcid; + } + return i; } /*********************************************************************** - * VkKeyScan (X11DRV.@) + * GetKeyboardLayout (X11DRV.@) */ -WORD X11DRV_VkKeyScan(CHAR cChar) +HKL X11DRV_GetKeyboardLayout(DWORD dwThreadid) +{ + DWORD layout; + LANGID langid; + + if (dwThreadid) + FIXME("couldn't return keyboard layout for thread %04lx\n", dwThreadid); + + layout = main_key_tab[kbd_layout].lcid; + /* + * Microsoft Office expects this value to be something specific + * for Japanese and Korean Windows with an IME the value is 0xe001 + * We should probibly 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 |= 0xe001 << 16; /* FIXME */ + + return (HKL)layout; +} + + +/*********************************************************************** + * GetKeyboardLayoutName (X11DRV.@) + */ +BOOL X11DRV_GetKeyboardLayoutName(LPWSTR name) +{ + static const WCHAR formatW[] = {'%','0','8','l','x',0}; + DWORD layout; + LANGID langid; + + layout = main_key_tab[kbd_layout].lcid; + /* see comment above */ + langid = PRIMARYLANGID(LANGIDFROMLCID(layout)); + if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN) + layout |= 0xe001 << 16; /* FIXME */ + + sprintfW(name, formatW, layout); + TRACE("returning %s\n", debugstr_w(name)); + return TRUE; +} + + +/*********************************************************************** + * LoadKeyboardLayout (X11DRV.@) + */ +HKL X11DRV_LoadKeyboardLayout(LPCWSTR name, UINT flags) +{ + FIXME("%s, %04x: stub!\n", debugstr_w(name), flags); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + + +/*********************************************************************** + * UnloadKeyboardLayout (X11DRV.@) + */ +BOOL X11DRV_UnloadKeyboardLayout(HKL hkl) +{ + FIXME("%p: stub!\n", hkl); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + + +/*********************************************************************** + * ActivateKeyboardLayout (X11DRV.@) + */ +HKL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags) +{ + FIXME("%p, %04x: stub!\n", hkl, flags); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + + +/*********************************************************************** + * X11DRV_MappingNotify + */ +void X11DRV_MappingNotify( XMappingEvent *event ) +{ + HWND hwnd; + + TSXRefreshKeyboardMapping(event); + X11DRV_InitKeyboard( pKeyStateTable ); + + hwnd = GetFocus(); + if (!hwnd) hwnd = GetActiveWindow(); + PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST, + 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0)); +} + + +/*********************************************************************** + * VkKeyScanEx (X11DRV.@) + * + * Note: Windows ignores HKL parameter and uses current active layout instead + */ +SHORT X11DRV_VkKeyScanEx(WCHAR wChar, HKL hkl) { Display *display = thread_display(); KeyCode keycode; KeySym keysym; int i, index; + CHAR cChar; SHORT ret; + if (!WideCharToMultiByte(CP_UNIXCP, 0, &wChar, 1, &cChar, 1, NULL, NULL)) + { + WARN("no translation from unicode to CP_UNIXCP for 0x%02x\n", wChar); + return -1; + } + + TRACE("wChar 0x%02x -> cChar '%c'\n", wChar, cChar); + /* char->keysym (same for ANSI chars) */ keysym = (unsigned char)cChar; /* (!) cChar is signed */ if (keysym <= 27) keysym += 0xFF00; /* special chars : return, backspace... */ @@ -1565,15 +1701,18 @@ WORD X11DRV_VkKeyScan(CHAR cChar) } /*********************************************************************** - * MapVirtualKey (X11DRV.@) + * MapVirtualKeyEx (X11DRV.@) */ -UINT X11DRV_MapVirtualKey(UINT wCode, UINT wMapType) +UINT X11DRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl) { Display *display = thread_display(); #define returnMVK(value) { TRACE("returning 0x%x.\n",value); return value; } - TRACE("wCode=0x%x wMapType=%d ...\n", wCode,wMapType); + TRACE("wCode=0x%x, wMapType=%d, hkl %p\n", wCode, wMapType, hkl); + if (hkl != X11DRV_GetKeyboardLayout(0)) + FIXME("keyboard layout %p is not supported\n", hkl); + switch(wMapType) { case 0: { /* vkey-code to scan-code */ /* let's do vkey -> keycode -> scan */ @@ -1667,7 +1806,7 @@ UINT X11DRV_MapVirtualKey(UINT wCode, UINT wMapType) /*********************************************************************** * GetKeyNameText (X11DRV.@) */ -INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize) +INT X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize) { int vkey, ansi, scanCode; KeyCode keyc; @@ -1679,7 +1818,7 @@ INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize) scanCode &= 0x1ff; /* keep "extended-key" flag with code */ /* FIXME: should use MVK type 3 (NT version that distinguishes right and left */ - vkey = X11DRV_MapVirtualKey(scanCode, 1); + vkey = X11DRV_MapVirtualKeyEx(scanCode, 1, X11DRV_GetKeyboardLayout(0)); /* handle "don't care" bit (0x02000000) */ if (!(lParam & 0x02000000)) { @@ -1701,7 +1840,7 @@ INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize) } } - ansi = X11DRV_MapVirtualKey(vkey, 2); + ansi = X11DRV_MapVirtualKeyEx(vkey, 2, X11DRV_GetKeyboardLayout(0)); TRACE("scan 0x%04x, vkey 0x%04x, ANSI 0x%04x\n", scanCode, vkey, ansi); /* first get the name of the "regular" keys which is the Upper case @@ -1715,7 +1854,7 @@ INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize) { if ((nSize >= 2) && lpBuffer) { - *lpBuffer = toupper((char)ansi); + *lpBuffer = toupperW((WCHAR)ansi); *(lpBuffer+1) = 0; return 1; } @@ -1747,7 +1886,8 @@ INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize) scanCode, keyc, (int)keys, name); if (lpBuffer && nSize && name) { - lstrcpynA(lpBuffer, name, nSize); + MultiByteToWideChar(CP_UNIXCP, 0, name, -1, lpBuffer, nSize); + lpBuffer[nSize - 1] = 0; return 1; } } @@ -1839,7 +1979,7 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym) } /*********************************************************************** - * ToUnicode (X11DRV.@) + * ToUnicodeEx (X11DRV.@) * * The ToUnicode function translates the specified virtual-key code and keyboard * state to the corresponding Windows character or characters. @@ -1856,8 +1996,8 @@ static char KEYBOARD_MapDeadKeysym(KeySym keysym) * FIXME : should do the above (return 2 for non matching deadchar+char combinations) * */ -INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, - LPWSTR bufW, int bufW_size, UINT flags) +INT X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, + LPWSTR bufW, int bufW_size, UINT flags, HKL hkl) { Display *display = thread_display(); XKeyEvent e; @@ -1874,6 +2014,9 @@ INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, return 0; } + if (hkl != X11DRV_GetKeyboardLayout(0)) + FIXME("keyboard layout %p is not supported\n", hkl); + e.display = display; e.keycode = 0; e.state = 0; diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec index c24c67d4d4c..e38f95d1fbd 100644 --- a/dlls/x11drv/x11drv.spec +++ b/dlls/x11drv/x11drv.spec @@ -63,10 +63,16 @@ # USER driver @ cdecl InitKeyboard(ptr) X11DRV_InitKeyboard -@ cdecl VkKeyScan(long) X11DRV_VkKeyScan -@ cdecl MapVirtualKey(long long) X11DRV_MapVirtualKey -@ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText -@ cdecl ToUnicode(long long ptr ptr long long) X11DRV_ToUnicode +@ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx +@ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx +@ cdecl GetKeyNameText(long ptr long) X11DRV_GetKeyNameText +@ cdecl ToUnicodeEx(long long ptr ptr long long long) X11DRV_ToUnicodeEx +@ cdecl GetKeyboardLayoutList(long ptr) X11DRV_GetKeyboardLayoutList +@ cdecl GetKeyboardLayout(long) X11DRV_GetKeyboardLayout +@ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName +@ cdecl LoadKeyboardLayout(wstr long) X11DRV_LoadKeyboardLayout +@ cdecl ActivateKeyboardLayout(long long) X11DRV_ActivateKeyboardLayout +@ cdecl UnloadKeyboardLayout(long) X11DRV_UnloadKeyboardLayout @ cdecl Beep() X11DRV_Beep @ cdecl InitMouse(ptr) X11DRV_InitMouse @ cdecl SetCursor(ptr) X11DRV_SetCursor diff --git a/include/user.h b/include/user.h index d8221ff39b5..f87e0e3d0e4 100644 --- a/include/user.h +++ b/include/user.h @@ -72,10 +72,16 @@ enum wine_internal_message typedef struct tagUSER_DRIVER { /* keyboard functions */ void (*pInitKeyboard)(LPBYTE); - WORD (*pVkKeyScan)(CHAR); - UINT (*pMapVirtualKey)(UINT,UINT); - INT (*pGetKeyNameText)(LONG,LPSTR,INT); - INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT); + SHORT (*pVkKeyScanEx)(WCHAR, HKL); + UINT (*pMapVirtualKeyEx)(UINT, UINT, HKL); + INT (*pGetKeyNameText)(LONG, LPWSTR, INT); + INT (*pToUnicodeEx)(UINT, UINT, LPBYTE, LPWSTR, int, UINT, HKL); + UINT (*pGetKeyboardLayoutList)(INT, HKL *); + HKL (*pGetKeyboardLayout)(DWORD); + BOOL (*pGetKeyboardLayoutName)(LPWSTR); + HKL (*pLoadKeyboardLayout)(LPCWSTR, UINT); + HKL (*pActivateKeyboardLayout)(HKL, UINT); + BOOL (*pUnloadKeyboardLayout)(HKL); void (*pBeep)(void); /* mouse functions */ void (*pInitMouse)(LPBYTE); diff --git a/include/winuser.h b/include/winuser.h index bc3d628069c..43684f9edf5 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3714,7 +3714,7 @@ BOOL WINAPI EnumThreadWindows(DWORD,WNDENUMPROC,LPARAM); BOOL WINAPI ExitWindowsEx(UINT,DWORD); BOOL WINAPI GetIconInfo(HICON,PICONINFO); HKL WINAPI GetKeyboardLayout(DWORD); -INT WINAPI GetKeyboardLayoutList(INT,HKL *); +UINT WINAPI GetKeyboardLayoutList(INT,HKL *); BOOL WINAPI GetComboBoxInfo(HWND,PCOMBOBOXINFO); DWORD WINAPI GetMenuContextHelpId(HMENU); UINT WINAPI GetMenuDefaultItem(HMENU,UINT,UINT); @@ -3767,9 +3767,11 @@ HWINEVENTHOOK WINAPI SetWinEventHook(DWORD,DWORD,HMODULE,WINEVENTPROC,DWORD,DWOR WORD WINAPI TileWindows (HWND, UINT, const LPRECT, UINT, const HWND *); INT WINAPI ToUnicode(UINT,UINT,PBYTE,LPWSTR,int,UINT); +INT WINAPI ToUnicodeEx(UINT,UINT,LPBYTE,LPWSTR,int,UINT,HKL); BOOL WINAPI TrackPopupMenuEx(HMENU,UINT,INT,INT,HWND, LPTPMPARAMS); BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK); +BOOL WINAPI UnloadKeyboardLayout(HKL); BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY); BOOL WINAPI UnregisterHotKey(HWND,INT); DWORD WINAPI WaitForInputIdle(HANDLE,DWORD); @@ -4077,8 +4079,8 @@ INT WINAPI GetKeyboardType(INT); INT WINAPI GetKeyNameTextA(LONG,LPSTR,INT); INT WINAPI GetKeyNameTextW(LONG,LPWSTR,INT); #define GetKeyNameText WINELIB_NAME_AW(GetKeyNameText) -INT WINAPI GetKeyboardLayoutNameA(LPSTR); -INT WINAPI GetKeyboardLayoutNameW(LPWSTR); +BOOL WINAPI GetKeyboardLayoutNameA(LPSTR); +BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR); #define GetKeyboardLayoutName WINELIB_NAME_AW(GetKeyboardLayoutName) SHORT WINAPI GetKeyState(INT); HWND WINAPI GetLastActivePopup(HWND); @@ -4399,8 +4401,8 @@ BOOL WINAPI UpdateWindow(HWND); UINT WINAPI UserRealizePalette(HDC); BOOL WINAPI ValidateRect(HWND,const RECT*); BOOL WINAPI ValidateRgn(HWND,HRGN); -WORD WINAPI VkKeyScanA(CHAR); -WORD WINAPI VkKeyScanW(WCHAR); +SHORT WINAPI VkKeyScanA(CHAR); +SHORT WINAPI VkKeyScanW(WCHAR); #define VkKeyScan WINELIB_NAME_AW(VkKeyScan) WORD WINAPI VkKeyScanExA(CHAR, HKL); WORD WINAPI VkKeyScanExW(WCHAR, HKL); diff --git a/windows/defwnd.c b/windows/defwnd.c index 774a5be6120..71dc3facef7 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -859,6 +859,14 @@ LRESULT WINAPI DefWindowProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam } break; + case WM_INPUTLANGCHANGEREQUEST: + /* notify about the switch only if it's really our current layout */ + if ((HKL)lParam == GetKeyboardLayout(0)) + result = SendMessageA( hwnd, WM_INPUTLANGCHANGE, wParam, lParam ); + else + result = 0; + break; + default: result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam ); break; @@ -970,6 +978,14 @@ LRESULT WINAPI DefWindowProcW( } break; + case WM_INPUTLANGCHANGEREQUEST: + /* notify about the switch only if it's really our current layout */ + if ((HKL)lParam == GetKeyboardLayout(0)) + result = SendMessageW( hwnd, WM_INPUTLANGCHANGE, wParam, lParam ); + else + result = 0; + break; + default: result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam ); break; diff --git a/windows/input.c b/windows/input.c index 5ad72a6a240..ed845daa79f 100644 --- a/windows/input.c +++ b/windows/input.c @@ -645,17 +645,22 @@ BOOL16 WINAPI IsUserIdle16(void) * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00 */ -WORD WINAPI VkKeyScanA(CHAR cChar) +SHORT WINAPI VkKeyScanA(CHAR cChar) { - return USER_Driver.pVkKeyScan( cChar ); + WCHAR wChar; + + if (IsDBCSLeadByte(cChar)) return -1; + + MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1); + return VkKeyScanW(wChar); } /****************************************************************************** * VkKeyScanW (USER32.@) */ -WORD WINAPI VkKeyScanW(WCHAR cChar) +SHORT WINAPI VkKeyScanW(WCHAR cChar) { - return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */ + return VkKeyScanExW(cChar, GetKeyboardLayout(0)); } /********************************************************************** @@ -663,8 +668,12 @@ WORD WINAPI VkKeyScanW(WCHAR cChar) */ WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl) { - /* FIXME: complete workaround this is */ - return VkKeyScanA(cChar); + WCHAR wChar; + + if (IsDBCSLeadByte(cChar)) return -1; + + MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1); + return VkKeyScanExW(wChar, dwhkl); } /****************************************************************************** @@ -672,8 +681,9 @@ WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl) */ WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl) { - /* FIXME: complete workaround this is */ - return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */ + if (USER_Driver.pVkKeyScanEx) + return USER_Driver.pVkKeyScanEx(cChar, dwhkl); + return -1; } /****************************************************************************** @@ -701,7 +711,7 @@ INT WINAPI GetKeyboardType(INT nTypeFlag) */ UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype) { - return USER_Driver.pMapVirtualKey( code, maptype ); + return MapVirtualKeyExA( code, maptype, GetKeyboardLayout(0) ); } /****************************************************************************** @@ -709,7 +719,7 @@ UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype) */ UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype) { - return MapVirtualKeyA(code,maptype); + return MapVirtualKeyExW(code, maptype, GetKeyboardLayout(0)); } /****************************************************************************** @@ -717,9 +727,7 @@ UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype) */ UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl) { - if (hkl) - FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl); - return MapVirtualKeyA(code,maptype); + return MapVirtualKeyExW(code, maptype, hkl); } /****************************************************************************** @@ -727,9 +735,11 @@ UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl) */ UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl) { - if (hkl) - FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl); - return MapVirtualKeyA(code,maptype); + TRACE_(keyboard)("(%d, %d, %p)\n", code, maptype, hkl); + + if (USER_Driver.pMapVirtualKeyEx) + return USER_Driver.pMapVirtualKeyEx(code, maptype, hkl); + return 0; } /**************************************************************************** @@ -751,37 +761,37 @@ INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID) /*********************************************************************** * GetKeyboardLayout (USER32.@) * - * FIXME: - device handle for keyboard layout defaulted to + * - device handle for keyboard layout defaulted to * the language id. This is the way Windows default works. * - the thread identifier (dwLayout) is also ignored. */ HKL WINAPI GetKeyboardLayout(DWORD dwLayout) { - UINT layout; - layout = GetSystemDefaultLCID(); /* FIXME */ - layout |= (layout<<16); /* FIXME */ - TRACE_(keyboard)("returning %08x\n",layout); - return (HKL)layout; + if (USER_Driver.pGetKeyboardLayout) + return USER_Driver.pGetKeyboardLayout(dwLayout); + return 0; } /**************************************************************************** * GetKeyboardLayoutNameA (USER32.@) */ -INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID) +BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pszKLID) { - sprintf(pwszKLID, "%p",GetKeyboardLayout(0)); - return 1; + WCHAR buf[KL_NAMELENGTH]; + + if (GetKeyboardLayoutNameW(buf)) + return WideCharToMultiByte( CP_ACP, 0, buf, -1, pszKLID, KL_NAMELENGTH, NULL, NULL ) != 0; + return FALSE; } /**************************************************************************** * GetKeyboardLayoutNameW (USER32.@) */ -INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID) +BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID) { - char buf[KL_NAMELENGTH]; - int res = GetKeyboardLayoutNameA(buf); - MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH ); - return res; + if (USER_Driver.pGetKeyboardLayoutName) + return USER_Driver.pGetKeyboardLayoutName(pwszKLID); + return FALSE; } /**************************************************************************** @@ -789,7 +799,18 @@ INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID) */ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize) { - return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize ); + WCHAR buf[256]; + INT ret; + + if (!GetKeyNameTextW(lParam, buf, 256)) + return 0; + ret = WideCharToMultiByte(CP_ACP, 0, buf, -1, lpBuffer, nSize, NULL, NULL); + if (!ret && nSize) + { + ret = nSize - 1; + lpBuffer[ret] = 0; + } + return ret; } /**************************************************************************** @@ -797,15 +818,9 @@ INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize) */ INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize) { - int res; - LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize ); - if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/ - res = GetKeyNameTextA(lParam,buf,nSize); - - if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize )) - lpBuffer[nSize-1] = 0; - HeapFree( GetProcessHeap(), 0, buf ); - return res; + if (USER_Driver.pGetKeyNameText) + return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize ); + return 0; } /**************************************************************************** @@ -814,7 +829,7 @@ INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize) INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, LPWSTR lpwStr, int size, UINT flags) { - return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags); + return ToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, GetKeyboardLayout(0)); } /**************************************************************************** @@ -823,24 +838,18 @@ INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState, LPWSTR lpwStr, int size, UINT flags, HKL hkl) { - /* FIXME: need true implementation */ - return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags); + if (USER_Driver.pToUnicodeEx) + return USER_Driver.pToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, hkl); + return 0; } /**************************************************************************** * ToAscii (USER32.@) */ -INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState, - LPWORD lpChar,UINT flags ) +INT WINAPI ToAscii( UINT virtKey, UINT scanCode, LPBYTE lpKeyState, + LPWORD lpChar, UINT flags ) { - WCHAR uni_chars[2]; - INT ret, n_ret; - - ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags); - if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */ - else n_ret = ret; - WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL); - return ret; + return ToAsciiEx(virtKey, scanCode, lpKeyState, lpChar, flags, GetKeyboardLayout(0)); } /**************************************************************************** @@ -849,19 +858,25 @@ INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState, INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState, LPWORD lpChar, UINT flags, HKL dwhkl ) { - /* FIXME: need true implementation */ - return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags); + WCHAR uni_chars[2]; + INT ret, n_ret; + + ret = ToUnicodeEx(virtKey, scanCode, lpKeyState, uni_chars, 2, flags, dwhkl); + if (ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */ + else n_ret = ret; + WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL); + return ret; } /********************************************************************** * ActivateKeyboardLayout (USER32.@) - * - * Call ignored. WINE supports only system default keyboard layout. */ HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags) { TRACE_(keyboard)("(%p, %d)\n", hLayout, flags); - ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n"); + + if (USER_Driver.pActivateKeyboardLayout) + return USER_Driver.pActivateKeyboardLayout(hLayout, flags); return 0; } @@ -869,21 +884,16 @@ HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags) /*********************************************************************** * GetKeyboardLayoutList (USER32.@) * - * FIXME: Supports only the system default language and layout and - * returns only 1 value. - * * Return number of values available if either input parm is * 0, per MS documentation. - * */ -INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts) +UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts) { - TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts); - if (!nBuff || !layouts) - return 1; - if (layouts) - layouts[0] = GetKeyboardLayout(0); - return 1; + TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts); + + if (USER_Driver.pGetKeyboardLayoutList) + return USER_Driver.pGetKeyboardLayoutList(nBuff, layouts); + return 0; } @@ -905,13 +915,14 @@ BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) { /*********************************************************************** * LoadKeyboardLayoutW (USER32.@) - * Call ignored. WINE supports only system default keyboard layout. */ HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags) { TRACE_(keyboard)("(%s, %d)\n", debugstr_w(pwszKLID), Flags); - ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n"); - return 0; + + if (USER_Driver.pLoadKeyboardLayout) + return USER_Driver.pLoadKeyboardLayout(pwszKLID, Flags); + return 0; } /*********************************************************************** @@ -931,6 +942,18 @@ HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags) } +/*********************************************************************** + * UnloadKeyboardLayout (USER32.@) + */ +BOOL WINAPI UnloadKeyboardLayout(HKL hkl) +{ + TRACE_(keyboard)("(%p)\n", hkl); + + if (USER_Driver.pUnloadKeyboardLayout) + return USER_Driver.pUnloadKeyboardLayout(hkl); + return 0; +} + typedef struct __TRACKINGLIST { TRACKMOUSEEVENT tme; POINT pos; /* center of hover rectangle */