diff --git a/include/freerdp/locale/locale.h b/include/freerdp/locale/locale.h index 1c00601b4..c36c1027b 100644 --- a/include/freerdp/locale/locale.h +++ b/include/freerdp/locale/locale.h @@ -231,7 +231,7 @@ #define ZULU 0x0435 FREERDP_API DWORD freerdp_get_system_locale_id(void); -FREERDP_API DWORD freerdp_detect_keyboard_layout_from_system_locale(void); FREERDP_API const char* freerdp_get_system_locale_name_from_id(DWORD localeId); +FREERDP_API int freerdp_detect_keyboard_layout_from_system_locale(DWORD* keyboardLayoutId); #endif /* FREERDP_LOCALE_H */ diff --git a/libfreerdp/locale/keyboard.c b/libfreerdp/locale/keyboard.c index 294cf7ca7..edcc39bd0 100644 --- a/libfreerdp/locale/keyboard.c +++ b/libfreerdp/locale/keyboard.c @@ -51,10 +51,10 @@ int freerdp_detect_keyboard(DWORD* keyboardLayoutId) freerdp_detect_keyboard_layout_from_xkb(keyboardLayoutId); if (*keyboardLayoutId == 0) - *keyboardLayoutId = freerdp_detect_keyboard_layout_from_system_locale(); + freerdp_detect_keyboard_layout_from_system_locale(keyboardLayoutId); if (*keyboardLayoutId == 0) - *keyboardLayoutId = 0x0409; + *keyboardLayoutId = ENGLISH_UNITED_STATES; return 0; } diff --git a/libfreerdp/locale/keyboard_xkbfile.c b/libfreerdp/locale/keyboard_xkbfile.c index 68e4a6f32..2215e6fc7 100644 --- a/libfreerdp/locale/keyboard_xkbfile.c +++ b/libfreerdp/locale/keyboard_xkbfile.c @@ -184,7 +184,7 @@ void* freerdp_keyboard_xkb_init() int freerdp_keyboard_init_xkbfile(DWORD* keyboardLayoutId, DWORD x11_keycode_to_rdp_scancode[256]) { void* display; - + ZeroMemory(x11_keycode_to_rdp_scancode, sizeof(DWORD) * 256); display = freerdp_keyboard_xkb_init(); @@ -197,7 +197,7 @@ int freerdp_keyboard_init_xkbfile(DWORD* keyboardLayoutId, DWORD x11_keycode_to_ if (*keyboardLayoutId == 0) { - *keyboardLayoutId = detect_keyboard_layout_from_xkbfile(display); + detect_keyboard_layout_from_xkbfile(display, keyboardLayoutId); DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboardLayoutId); } @@ -211,7 +211,7 @@ int freerdp_keyboard_init_xkbfile(DWORD* keyboardLayoutId, DWORD x11_keycode_to_ /* return substring starting after nth comma, ending at following comma */ static char* comma_substring(char* s, int n) { - char *p; + char* p; if (!s) return ""; @@ -230,15 +230,14 @@ static char* comma_substring(char* s, int n) return s; } -DWORD detect_keyboard_layout_from_xkbfile(void* display) +int detect_keyboard_layout_from_xkbfile(void* display, DWORD* keyboardLayoutId) { char* layout; char* variant; DWORD group = 0; - DWORD keyboard_layout = 0; - XkbRF_VarDefsRec rules_names; - XKeyboardState coreKbdState; XkbStateRec state; + XKeyboardState coreKbdState; + XkbRF_VarDefsRec rules_names; DEBUG_KBD("display: %p", display); @@ -260,7 +259,7 @@ DWORD detect_keyboard_layout_from_xkbfile(void* display) DEBUG_KBD("layout: %s", layout ? layout : ""); DEBUG_KBD("variant: %s", variant ? variant : ""); - keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); + *keyboardLayoutId = find_keyboard_layout_in_xorg_rules(layout, variant); free(rules_names.model); free(rules_names.layout); @@ -268,7 +267,7 @@ DWORD detect_keyboard_layout_from_xkbfile(void* display) free(rules_names.options); } - return keyboard_layout; + return 0; } int freerdp_keyboard_load_map_from_xkbfile(void* display, DWORD x11_keycode_to_rdp_scancode[256]) diff --git a/libfreerdp/locale/keyboard_xkbfile.h b/libfreerdp/locale/keyboard_xkbfile.h index a69209f1b..9218f6378 100644 --- a/libfreerdp/locale/keyboard_xkbfile.h +++ b/libfreerdp/locale/keyboard_xkbfile.h @@ -25,7 +25,7 @@ int freerdp_keyboard_init_xkbfile(DWORD* keyboardLayoutId, DWORD x11_keycode_to_rdp_scancode[256]); -DWORD detect_keyboard_layout_from_xkbfile(void* display); +int detect_keyboard_layout_from_xkbfile(void* display, DWORD* keyboardLayoutId); int freerdp_keyboard_load_map_from_xkbfile(void* display, DWORD x11_keycode_to_rdp_scancode[256]); #endif /* __LOCALE_KEYBOARD_XKB_H */ diff --git a/libfreerdp/locale/locale.c b/libfreerdp/locale/locale.c index 6e530cbb1..4b7b5d41e 100644 --- a/libfreerdp/locale/locale.c +++ b/libfreerdp/locale/locale.c @@ -717,7 +717,7 @@ const char* freerdp_get_system_locale_name_from_id(DWORD localeId) return NULL; } -DWORD freerdp_detect_keyboard_layout_from_system_locale() +int freerdp_detect_keyboard_layout_from_system_locale(DWORD* keyboardLayoutId) { int i, j; char language[4]; @@ -727,12 +727,15 @@ DWORD freerdp_detect_keyboard_layout_from_system_locale() freerdp_get_system_language_and_country_codes(language, country); if ((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0)) - return ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */ + { + *keyboardLayoutId = ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */ + return 0; + } locale = freerdp_detect_system_locale(); - if (locale == NULL) - return 0; + if (!locale) + return -1; DEBUG_KBD("Found locale : %s_%s", locale->language, locale->country); @@ -741,6 +744,7 @@ DWORD freerdp_detect_keyboard_layout_from_system_locale() if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].locale == locale->code) { /* Locale found in list of default keyboard layouts */ + for (j = 0; j < 5; j++) { if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES) @@ -753,7 +757,8 @@ DWORD freerdp_detect_keyboard_layout_from_system_locale() } else { - return LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j]; + *keyboardLayoutId = LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j]; + return 0; } } @@ -763,11 +768,16 @@ DWORD freerdp_detect_keyboard_layout_from_system_locale() */ if (j >= 1) - return ENGLISH_UNITED_STATES; - else + { + *keyboardLayoutId = ENGLISH_UNITED_STATES; return 0; + } + else + { + return -1; + } } } - return 0; /* Could not detect the current keyboard layout from locale */ + return -1; /* Could not detect the current keyboard layout from locale */ } diff --git a/winpr/include/winpr/input.h b/winpr/include/winpr/input.h index 4fd82e337..87b0a8ea9 100644 --- a/winpr/include/winpr/input.h +++ b/winpr/include/winpr/input.h @@ -859,6 +859,7 @@ WINPR_API char* GetVirtualKeyName(DWORD vkcode); WINPR_API DWORD GetVirtualKeyCodeFromName(const char* vkname); +WINPR_API DWORD GetVirtualKeyCodeFromXkbKeyName(const char* xkbname); WINPR_API DWORD GetVirtualKeyCodeFromVirtualScanCode(DWORD scancode, DWORD dwKeyboardType); WINPR_API DWORD GetVirtualScanCodeFromVirtualKeyCode(DWORD vkcode, DWORD dwKeyboardType); diff --git a/winpr/libwinpr/input/virtualkey.c b/winpr/libwinpr/input/virtualkey.c index 93aee3610..29dba4e6a 100644 --- a/winpr/libwinpr/input/virtualkey.c +++ b/winpr/libwinpr/input/virtualkey.c @@ -296,6 +296,129 @@ static const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE_TABLE[256] = { 0, NULL } }; +struct _XKB_KEYNAME +{ + const char* name; + DWORD vkcode; +}; +typedef struct _XKB_KEYNAME XKB_KEYNAME; + +XKB_KEYNAME XKB_KEYNAME_TABLE[] = +{ + { "BKSP", VK_BACK }, + { "TAB", VK_TAB }, + { "RTRN", VK_RETURN }, + { "LFSH", VK_LSHIFT }, + { "LALT", VK_LMENU }, + { "CAPS", VK_CAPITAL }, + { "ESC", VK_ESCAPE }, + { "SPCE", VK_SPACE }, + { "AE10", VK_KEY_0 }, + { "AE01", VK_KEY_1 }, + { "AE02", VK_KEY_2 }, + { "AE03", VK_KEY_3 }, + { "AE04", VK_KEY_4 }, + { "AE05", VK_KEY_5 }, + { "AE06", VK_KEY_6 }, + { "AE07", VK_KEY_7 }, + { "AE08", VK_KEY_8 }, + { "AE09", VK_KEY_9 }, + { "AC01", VK_KEY_A }, + { "AB05", VK_KEY_B }, + { "AB03", VK_KEY_C }, + { "AC03", VK_KEY_D }, + { "AD03", VK_KEY_E }, + { "AC04", VK_KEY_F }, + { "AC05", VK_KEY_G }, + { "AC06", VK_KEY_H }, + { "AD08", VK_KEY_I }, + { "AC07", VK_KEY_J }, + { "AC08", VK_KEY_K }, + { "AC09", VK_KEY_L }, + { "AB07", VK_KEY_M }, + { "AB06", VK_KEY_N }, + { "AD09", VK_KEY_O }, + { "AD10", VK_KEY_P }, + { "AD01", VK_KEY_Q }, + { "AD04", VK_KEY_R }, + { "AC02", VK_KEY_S }, + { "AD05", VK_KEY_T }, + { "AD07", VK_KEY_U }, + { "AB04", VK_KEY_V }, + { "AD02", VK_KEY_W }, + { "AB02", VK_KEY_X }, + { "AD06", VK_KEY_Y }, + { "AB01", VK_KEY_Z }, + { "KP0", VK_NUMPAD0 }, + { "KP1", VK_NUMPAD1 }, + { "KP2", VK_NUMPAD2 }, + { "KP3", VK_NUMPAD3 }, + { "KP4", VK_NUMPAD4 }, + { "KP5", VK_NUMPAD5 }, + { "KP6", VK_NUMPAD6 }, + { "KP7", VK_NUMPAD7 }, + { "KP8", VK_NUMPAD8 }, + { "KP9", VK_NUMPAD9 }, + { "KPMU", VK_MULTIPLY }, + { "KPAD", VK_ADD }, + { "KPSU", VK_SUBTRACT }, + { "KPDL", VK_DECIMAL }, + { "AB10", VK_OEM_2 }, + { "FK01", VK_F1 }, + { "FK02", VK_F2 }, + { "FK03", VK_F3 }, + { "FK04", VK_F4 }, + { "FK05", VK_F5 }, + { "FK06", VK_F6 }, + { "FK07", VK_F7 }, + { "FK08", VK_F8 }, + { "FK09", VK_F9 }, + { "FK10", VK_F10 }, + { "FK11", VK_F11 }, + { "FK12", VK_F12 }, + { "NMLK", VK_NUMLOCK }, + { "SCLK", VK_SCROLL }, + { "RTSH", VK_RSHIFT }, + { "LCTL", VK_LCONTROL }, + { "AC10", VK_OEM_1 }, + { "AE12", VK_OEM_PLUS }, + { "AB08", VK_OEM_COMMA }, + { "AE11", VK_OEM_MINUS }, + { "AB09", VK_OEM_PERIOD }, + { "TLDE", VK_OEM_3 }, + { "AB11", VK_ABNT_C1 }, + { "I129", VK_ABNT_C2 }, + { "AD11", VK_OEM_4 }, + { "BKSL", VK_OEM_5 }, + { "AD12", VK_OEM_6 }, + { "AC11", VK_OEM_7 }, + { "LSGT", VK_OEM_102 }, + { "KPEN", VK_RETURN | KBDEXT }, + { "PAUS", VK_PAUSE | KBDEXT }, + { "PGUP", VK_PRIOR | KBDEXT }, + { "PGDN", VK_NEXT | KBDEXT }, + { "END", VK_END | KBDEXT }, + { "HOME", VK_HOME | KBDEXT }, + { "LEFT", VK_LEFT | KBDEXT }, + { "UP", VK_UP | KBDEXT }, + { "RGHT", VK_RIGHT | KBDEXT }, + { "DOWN", VK_DOWN | KBDEXT }, + { "PRSC", VK_SNAPSHOT | KBDEXT }, + { "INS", VK_INSERT | KBDEXT }, + { "DELE", VK_DELETE | KBDEXT }, + { "LWIN", VK_LWIN | KBDEXT }, + { "RWIN", VK_RWIN | KBDEXT }, + { "COMP", VK_APPS | KBDEXT }, + { "KPDV", VK_DIVIDE | KBDEXT }, + { "RCTL", VK_RCONTROL | KBDEXT }, + { "RALT", VK_RMENU | KBDEXT } +// { "AE13", VK_BACKSLASH_JP }, // JP +// { "HKTG", VK_HIRAGANA }, // JP +// { "HENK", VK_CONVERT_JP }, // JP +// { "MUHE", VK_NONCONVERT_JP } // JP +// { "LVL3", 0x54} +}; + char* GetVirtualKeyName(DWORD vkcode) { char* vkname; @@ -324,3 +447,18 @@ DWORD GetVirtualKeyCodeFromName(const char* vkname) return VK_NONE; } +DWORD GetVirtualKeyCodeFromXkbKeyName(const char* xkbname) +{ + int i; + + for (i = 0; i < ARRAYSIZE(XKB_KEYNAME_TABLE); i++) + { + if (XKB_KEYNAME_TABLE[i].name) + { + if (strcmp(xkbname, XKB_KEYNAME_TABLE[i].name) == 0) + return XKB_KEYNAME_TABLE[i].vkcode; + } + } + + return VK_NONE; +}