diff --git a/client/DirectFB/df_event.c b/client/DirectFB/df_event.c index 05928c411..add5ba5a8 100644 --- a/client/DirectFB/df_event.c +++ b/client/DirectFB/df_event.c @@ -202,7 +202,7 @@ void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8 else return; - scancode = freerdp_keyboard_get_scancode_from_vkcode(vkcode, &extended); + scancode = freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(vkcode, &extended); flags = (extended) ? KBD_FLAGS_EXTENDED : 0; flags |= (down) ? KBD_FLAGS_DOWN : KBD_FLAGS_RELEASE; diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 639e39fdf..56bc5de62 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -64,7 +64,7 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode) rdpInput* input; input = xfi->instance->input; - scancode = freerdp_keyboard_get_scancode_from_keycode(keycode, &extended); + scancode = freerdp_keyboard_get_rdp_scancode_from_x11_keycode(keycode, &extended); if (scancode == 0) { diff --git a/include/freerdp/locale/keyboard.h b/include/freerdp/locale/keyboard.h index cc4f6e5b5..7d5327a5d 100644 --- a/include/freerdp/locale/keyboard.h +++ b/include/freerdp/locale/keyboard.h @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based keyboard mapping + * FreeRDP: A Remote Desktop Protocol Implementation + * Keyboard Mapping * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,15 +48,6 @@ struct _VIRTUAL_KEY_CODE }; typedef struct _VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE; -struct _VIRTUAL_KEY -{ - uint32 scancode; /* Windows "scan code" */ - boolean extended; /* extended key flag */ - const char* name; /* Windows virtual key name */ - const char* x_keyname; /* XKB keyname */ -}; -typedef struct _VIRTUAL_KEY VIRTUAL_KEY; - /* Mouse buttons */ #define VK_LBUTTON 0x01 /* Left mouse button */ @@ -488,11 +479,12 @@ typedef struct _VIRTUAL_KEY VIRTUAL_KEY; #define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804 #define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404 -FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboard_layout_id); +FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboardLayoutId); FREERDP_API RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types); -FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutID); -FREERDP_API uint32 freerdp_keyboard_get_scancode_from_keycode(uint32 keycode, boolean* extended); -FREERDP_API uint32 freerdp_keyboard_get_keycode_from_scancode(uint32 scancode, boolean extended); -FREERDP_API uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended); +FREERDP_API const char* freerdp_keyboard_get_layout_name_from_id(uint32 keyboardLayoutId); +FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_x11_keycode(uint32 keycode, boolean* extended); +FREERDP_API uint32 freerdp_keyboard_get_x11_keycode_from_rdp_scancode(uint32 scancode, boolean extended); +FREERDP_API uint32 freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(uint32 vkcode, boolean* extended); +FREERDP_API char* freerdp_keyboard_get_virtual_key_code_name(uint32 vkcode); #endif /* __FREERDP_LOCALE_KEYBOARD_H */ diff --git a/include/freerdp/locale/locale.h b/include/freerdp/locale/locale.h index 681a77e6d..389c753b4 100644 --- a/include/freerdp/locale/locale.h +++ b/include/freerdp/locale/locale.h @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * Microsoft Locales * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libfreerdp-locale/CMakeLists.txt b/libfreerdp-locale/CMakeLists.txt index 59e03ea6c..faf5af530 100644 --- a/libfreerdp-locale/CMakeLists.txt +++ b/libfreerdp-locale/CMakeLists.txt @@ -20,7 +20,6 @@ set(FREERDP_LOCALE_SRCS keyboard_layout.c keyboard.c - keyboard.h locale.c liblocale.h) diff --git a/libfreerdp-locale/keyboard.c b/libfreerdp-locale/keyboard.c index 9b6d3b8ab..9b6316716 100644 --- a/libfreerdp-locale/keyboard.c +++ b/libfreerdp-locale/keyboard.c @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * Localization Services + * FreeRDP: A Remote Desktop Protocol Implementation + * Keyboard Localization * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,36 +43,29 @@ #include #include -#include "keyboard.h" +uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2]; +RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256]; -extern const VIRTUAL_KEY virtualKeyboard[258]; +extern const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE_TABLE[256]; +extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[256]; -/* - * The actual mapping from X keycodes to RDP keycodes, initialized from xkb keycodes or similar. - * Used directly by freerdp_kbd_get_scancode_by_keycode. The mapping is a global variable, - * but it only depends on which keycodes the X servers keyboard driver uses and is thus very static. - */ - -RDP_KEYCODE x11_keycode_to_rdp_scancode[256]; - -uint32 rdp_scancode_to_x11_keycode[256][2]; - -static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) +static int freerdp_keyboard_load_map(uint32 keycode_to_vkcode[256], char* name) { FILE* fp; char* pch; char* beg; char* end; int i = 0; - int kbdFound = 0; + int kbd_found = 0; char* keymap_path; uint32 keycode = 0; char buffer[1024] = ""; char keymap_name[256] = ""; char keymap_include[256] = ""; char keymap_filename[256] = ""; - char keycodeString[32] = ""; - char vkcodeName[128] = ""; + char keycode_string[32] = ""; + char vkcode_name[128] = ""; + VIRTUAL_KEY_CODE* vkcode; beg = name; @@ -111,7 +104,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) continue; /* Skip comments */ } - if (kbdFound) + if (kbd_found) { /* Closing curly bracket and semicolon */ if ((pch = strstr(buffer, "};")) != NULL) @@ -125,8 +118,8 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) /* We copy the virtual key code name in a string */ beg = pch; - strncpy(vkcodeName, beg, end - beg); - vkcodeName[end - beg] = '\0'; + strncpy(vkcode_name, beg, end - beg); + vkcode_name[end - beg] = '\0'; /* Now we want to extract the virtual key code itself which is in between '<' and '>' */ if ((beg = strchr(pch + 3, '<')) == NULL) @@ -138,24 +131,30 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) break; /* We copy the string representing the number in a string */ - strncpy(keycodeString, beg, end - beg); - keycodeString[end - beg] = '\0'; + strncpy(keycode_string, beg, end - beg); + keycode_string[end - beg] = '\0'; /* Convert the string representing the code to an integer */ - keycode = atoi(keycodeString); + keycode = atoi(keycode_string); /* Make sure it is a valid keycode */ if (keycode < 0 || keycode > 255) break; /* Load this key mapping in the keyboard mapping */ - for(i = 0; i < sizeof(virtualKeyboard) / sizeof(VIRTUAL_KEY); i++) + + i = 0; + + do { - if (strcmp(vkcodeName, virtualKeyboard[i].name) == 0) - { - map[keycode] = i; - } + vkcode = (VIRTUAL_KEY_CODE*) &VIRTUAL_KEY_CODE_TABLE[i]; + + if (strcmp(vkcode_name, vkcode->name) == 0) + keycode_to_vkcode[keycode] = vkcode->code; + + i++; } + while (vkcode->code != 0); } else if ((pch = strstr(buffer, ": extends")) != NULL) { @@ -174,7 +173,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) strncpy(keymap_include, beg, end - beg); keymap_include[end - beg] = '\0'; - freerdp_keyboard_load_map(map, keymap_include); /* Load included keymap */ + freerdp_keyboard_load_map(keycode_to_vkcode, keymap_include); /* Load included keymap */ } } else if ((pch = strstr(buffer, "keyboard")) != NULL) @@ -192,7 +191,7 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) /* Does it match our keymap name? */ if (strncmp(keymap_name, pch, strlen(keymap_name)) == 0) - kbdFound = 1; + kbd_found = 1; } } @@ -201,37 +200,36 @@ static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* name) return 1; } -void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* names) +void freerdp_keyboard_load_maps(uint32 keycode_to_vkcode[256], char* names) { char* kbd; - char* namesEnd; - int keymapLoaded = 0; + char* names_end; + int keymap_loaded = 0; - memset(keycodeToVkcode, 0, sizeof(keycodeToVkcode)); + memset(keycode_to_vkcode, 0, sizeof(keycode_to_vkcode)); kbd = names; - namesEnd = names + strlen(names); + names_end = names + strlen(names); do { - /* Multiple maps are separated by '+' */ - int kbdlen = strcspn(kbd + 1, "+") + 1; - kbd[kbdlen] = '\0'; + /* multiple maps are separated by '+' */ + int kbd_length = strcspn(kbd + 1, "+") + 1; + kbd[kbd_length] = '\0'; /* Load keyboard map */ - keymapLoaded += freerdp_keyboard_load_map(keycodeToVkcode, kbd); + keymap_loaded += freerdp_keyboard_load_map(keycode_to_vkcode, kbd); - kbd += kbdlen + 1; + kbd += kbd_length + 1; } - while (kbd < namesEnd); + while (kbd < names_end); - DEBUG_KBD("loaded %d keymaps", keymapLoaded); + DEBUG_KBD("loaded %d keymaps", keymap_loaded); - if (keymapLoaded <= 0) + if (keymap_loaded <= 0) printf("error: no keyboard mapping available!\n"); } - uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID) { if (keyboardLayoutID != 0) @@ -252,82 +250,6 @@ uint32 freerdp_detect_keyboard(uint32 keyboardLayoutID) return keyboardLayoutID; } -#ifdef WITH_XKB -uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId) -{ - void* display; - memset(x11_keycode_to_rdp_scancode, 0, sizeof(x11_keycode_to_rdp_scancode)); - memset(rdp_scancode_to_x11_keycode, '\0', sizeof(rdp_scancode_to_x11_keycode)); - - display = freerdp_keyboard_xkb_init(); - - if (!display) - { - DEBUG_KBD("Error initializing xkb"); - return 0; - } - - if (keyboardLayoutId == 0) - { - keyboardLayoutId = detect_keyboard_layout_from_xkb(display); - DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboardLayoutId); - } - - freerdp_keyboard_load_map_from_xkb(display, x11_keycode_to_rdp_scancode, rdp_scancode_to_x11_keycode); - - return keyboardLayoutId; -} -#endif - -#ifdef WITH_X11 -uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId) -{ - uint32 vkcode; - uint32 keycode; - KeycodeToVkcode keycodeToVkcode; - - memset(x11_keycode_to_rdp_scancode, 0, sizeof(x11_keycode_to_rdp_scancode)); - memset(rdp_scancode_to_x11_keycode, '\0', sizeof(rdp_scancode_to_x11_keycode)); - - if (keyboardLayoutId == 0) - { - keyboardLayoutId = freerdp_detect_keyboard_layout_from_locale(); - DEBUG_KBD("using keyboard layout: %X", keyboardLayoutID); - } - - if (keyboardLayoutId == 0) - { - keyboardLayoutId = 0x0409; - DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID); - } - -#ifdef __APPLE__ - /* Apple X11 breaks XKB detection */ - freerdp_keyboard_load_map(keycodeToVkcode, "macosx(macosx)"); -#endif - - for (keycode = 0; keycode < 256; keycode++) - { - vkcode = keycodeToVkcode[keycode]; - - DEBUG_KBD("X keycode %3d VK %3d %-19s-> RDP scancode %d/%d", - keycode, vkcode, virtualKeyboard[vkcode].name, - virtualKeyboard[vkcode].extended, virtualKeyboard[vkcode].scancode); - - x11_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode; - x11_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended; - x11_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name; - - if (x11_keycode_to_rdp_scancode[keycode].extended) - rdp_scancode_to_x11_keycode[virtualKeyboard[vkcode].scancode][1] = keycode; - else - rdp_scancode_to_x11_keycode[virtualKeyboard[vkcode].scancode][0] = keycode; - } - - return keyboardLayoutId; -} -#endif - uint32 freerdp_keyboard_init(uint32 keyboardLayoutId) { #ifdef WITH_XKB @@ -345,26 +267,27 @@ uint32 freerdp_keyboard_init(uint32 keyboardLayoutId) return keyboardLayoutId; } -uint32 freerdp_keyboard_get_scancode_from_keycode(uint32 keycode, boolean* extended) +uint32 freerdp_keyboard_get_rdp_scancode_from_x11_keycode(uint32 keycode, boolean* extended) { - DEBUG_KBD("%2x %4s -> %d/%d", keycode, x11_keycode_to_rdp_scancode[keycode].keyname, - x11_keycode_to_rdp_scancode[keycode].extended, x11_keycode_to_rdp_scancode[keycode].keycode); - - *extended = x11_keycode_to_rdp_scancode[keycode].extended; - - return x11_keycode_to_rdp_scancode[keycode].keycode; + *extended = X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended; + return X11_KEYCODE_TO_RDP_SCANCODE[keycode].code; } -uint32 freerdp_keyboard_get_keycode_from_scancode(uint32 scancode, boolean extended) +uint32 freerdp_keyboard_get_x11_keycode_from_rdp_scancode(uint32 scancode, boolean extended) { if (extended) - return rdp_scancode_to_x11_keycode[scancode][1]; + return RDP_SCANCODE_TO_X11_KEYCODE[scancode][1]; else - return rdp_scancode_to_x11_keycode[scancode][0]; + return RDP_SCANCODE_TO_X11_KEYCODE[scancode][0]; } -uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended) +uint32 freerdp_keyboard_get_rdp_scancode_from_virtual_key_code(uint32 vkcode, boolean* extended) { - *extended = virtualKeyboard[vkcode].extended; - return virtualKeyboard[vkcode].scancode; + *extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended; + return VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code; +} + +char* freerdp_keyboard_get_virtual_key_code_name(uint32 vkcode) +{ + return (char*) VIRTUAL_KEY_CODE_TABLE[vkcode].name; } diff --git a/libfreerdp-locale/keyboard.h b/libfreerdp-locale/keyboard.h deleted file mode 100644 index 9a971e6d2..000000000 --- a/libfreerdp-locale/keyboard.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System - * - * Copyright 2009 Marc-Andre Moreau - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __KEYBOARD_H -#define __KEYBOARD_H - -#include - -typedef uint32 KeycodeToVkcode[256]; - -struct _RDP_KEYCODE -{ - uint32 extended; - uint32 keycode; - const char* keyname; -}; -typedef struct _RDP_KEYCODE RDP_KEYCODE; - -void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* names); - -#endif /* __KEYBOARD_H */ diff --git a/libfreerdp-locale/keyboard_layout.c b/libfreerdp-locale/keyboard_layout.c index b2c07a2ec..0ca3a4301 100644 --- a/libfreerdp-locale/keyboard_layout.c +++ b/libfreerdp-locale/keyboard_layout.c @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * Keyboard Layouts * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -207,30 +207,35 @@ static const RDP_KEYBOARD_IME RDP_KEYBOARD_IME_TABLE[] = { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" } }; -const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = +const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODE_TABLE[256] = { + { 0, "" }, { VK_LBUTTON, "VK_LBUTTON" }, { VK_RBUTTON, "VK_RBUTTON" }, { VK_CANCEL, "VK_CANCEL" }, { VK_MBUTTON, "VK_MBUTTON" }, { VK_XBUTTON1, "VK_XBUTTON1" }, { VK_XBUTTON2, "VK_XBUTTON2" }, + { 0, "" }, { VK_BACK, "VK_BACK" }, { VK_TAB, "VK_TAB" }, + { 0, "" }, + { 0, "" }, { VK_CLEAR, "VK_CLEAR" }, { VK_RETURN, "VK_RETURN" }, + { 0, "" }, + { 0, "" }, { VK_SHIFT, "VK_SHIFT" }, { VK_CONTROL, "VK_CONTROL" }, { VK_MENU, "VK_MENU" }, { VK_PAUSE, "VK_PAUSE" }, { VK_CAPITAL, "VK_CAPITAL" }, - { VK_KANA, "VK_KANA" }, - { VK_HANGUEL, "VK_HANGUEL" }, - { VK_HANGUL, "VK_HANGUL" }, + { VK_KANA, "VK_KANA" }, /* also VK_HANGUL */ + { 0, "" }, { VK_JUNJA, "VK_JUNJA" }, { VK_FINAL, "VK_FINAL" }, - { VK_HANJA, "VK_HANJA" }, - { VK_KANJI, "VK_KANJI" }, + { VK_KANJI, "VK_KANJI" }, /* also VK_HANJA */ + { 0, "" }, { VK_ESCAPE, "VK_ESCAPE" }, { VK_CONVERT, "VK_CONVERT" }, { VK_NONCONVERT, "VK_NONCONVERT" }, @@ -262,6 +267,13 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_KEY_7, "VK_KEY_7" }, { VK_KEY_8, "VK_KEY_8" }, { VK_KEY_9, "VK_KEY_9" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, { VK_KEY_A, "VK_KEY_A" }, { VK_KEY_B, "VK_KEY_B" }, { VK_KEY_C, "VK_KEY_C" }, @@ -291,6 +303,7 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_LWIN, "VK_LWIN" }, { VK_RWIN, "VK_RWIN" }, { VK_APPS, "VK_APPS" }, + { 0, "" }, { VK_SLEEP, "VK_SLEEP" }, { VK_NUMPAD0, "VK_NUMPAD0" }, { VK_NUMPAD1, "VK_NUMPAD1" }, @@ -332,8 +345,30 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_F22, "VK_F22" }, { VK_F23, "VK_F23" }, { VK_F24, "VK_F24" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, { VK_NUMLOCK, "VK_NUMLOCK" }, { VK_SCROLL, "VK_SCROLL" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, { VK_LSHIFT, "VK_LSHIFT" }, { VK_RSHIFT, "VK_RSHIFT" }, { VK_LCONTROL, "VK_LCONTROL" }, @@ -358,6 +393,8 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_MEDIA_SELECT, "VK_MEDIA_SELECT" }, { VK_LAUNCH_APP1, "VK_LAUNCH_APP1" }, { VK_LAUNCH_APP2, "VK_LAUNCH_APP2" }, + { 0, "" }, + { 0, "" }, { VK_OEM_1, "VK_OEM_1" }, { VK_OEM_PLUS, "VK_OEM_PLUS" }, { VK_OEM_COMMA, "VK_OEM_COMMA" }, @@ -367,14 +404,57 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_OEM_3, "VK_OEM_3" }, { VK_ABNT_C1, "VK_ABNT_C1" }, { VK_ABNT_C2, "VK_ABNT_C2" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, { VK_OEM_4, "VK_OEM_4" }, { VK_OEM_5, "VK_OEM_5" }, { VK_OEM_6, "VK_OEM_6" }, { VK_OEM_7, "VK_OEM_7" }, { VK_OEM_8, "VK_OEM_8" }, + { 0, "" }, + { 0, "" }, { VK_OEM_102, "VK_OEM_102" }, + { 0, "" }, + { 0, "" }, { VK_PROCESSKEY, "VK_PROCESSKEY" }, + { 0, "" }, { VK_PACKET, "VK_PACKET" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, + { 0, "" }, { VK_ATTN, "VK_ATTN" }, { VK_CRSEL, "VK_CRSEL" }, { VK_EXSEL, "VK_EXSEL" }, @@ -383,12 +463,13 @@ const VIRTUAL_KEY_CODE VIRTUAL_KEY_CODES[] = { VK_ZOOM, "VK_ZOOM" }, { VK_NONAME, "VK_NONAME" }, { VK_PA1, "VK_PA1" }, - { VK_OEM_CLEAR, "VK_OEM_CLEAR" } + { VK_OEM_CLEAR, "VK_OEM_CLEAR" }, + { 0, "" } }; /* the index in this table is the virtual key code */ -const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[] = +const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[256] = { { 0x00, 0 }, { 0x00, 0 }, /* VK_LBUTTON */ @@ -648,269 +729,6 @@ const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[] = { 0x00, 0 } }; -const VIRTUAL_KEY virtualKeyboard[] = -{ - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_LBUTTON" , NULL }, - { 0x00, 0, "VK_RBUTTON" , NULL }, - { 0x00, 0, "VK_CANCEL" , NULL }, - { 0x00, 0, "VK_MBUTTON" , NULL }, - { 0x00, 0, "VK_XBUTTON1" , NULL }, - { 0x00, 0, "VK_XBUTTON2" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x0E, 0, "VK_BACK" , "BKSP" }, - { 0x0F, 0, "VK_TAB" , "TAB" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_CLEAR" , NULL }, - { 0x1C, 0, "VK_RETURN" , "RTRN" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x2A, 0, "VK_SHIFT" , "LFSH" }, - { 0x00, 0, "VK_CONTROL" , NULL }, - { 0x38, 0, "VK_MENU" , "LALT" }, - { 0x46, 1, "VK_PAUSE" , "PAUS" }, - { 0x3A, 0, "VK_CAPITAL" , "CAPS" }, - { 0x72, 0, "VK_KANA / VK_HANGUL" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_JUNJA" , NULL }, - { 0x00, 0, "VK_FINAL" , NULL }, - { 0x71, 0, "VK_HANJA / VK_KANJI" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x01, 0, "VK_ESCAPE" , "ESC" }, - { 0x00, 0, "VK_CONVERT" , NULL }, - { 0x00, 0, "VK_NONCONVERT" , NULL }, - { 0x00, 0, "VK_ACCEPT" , NULL }, - { 0x00, 0, "VK_MODECHANGE" , NULL }, - { 0x39, 0, "VK_SPACE" , "SPCE" }, - { 0x49, 1, "VK_PRIOR" , "PGUP" }, - { 0x51, 1, "VK_NEXT" , "PGDN" }, - { 0x4F, 1, "VK_END" , "END" }, - { 0x47, 1, "VK_HOME" , "HOME" }, - { 0x4B, 1, "VK_LEFT" , "LEFT" }, - { 0x48, 1, "VK_UP" , "UP" }, - { 0x4D, 1, "VK_RIGHT" , "RGHT" }, - { 0x50, 1, "VK_DOWN" , "DOWN" }, - { 0x00, 0, "VK_SELECT" , NULL }, - { 0x37, 1, "VK_PRINT" , "PRSC" }, - { 0x37, 1, "VK_EXECUTE" , NULL }, - { 0x37, 1, "VK_SNAPSHOT" , NULL }, - { 0x52, 1, "VK_INSERT" , "INS" }, - { 0x53, 1, "VK_DELETE" , "DELE" }, - { 0x63, 0, "VK_HELP" , NULL }, - { 0x0B, 0, "VK_KEY_0" , "AE10" }, - { 0x02, 0, "VK_KEY_1" , "AE01" }, - { 0x03, 0, "VK_KEY_2" , "AE02" }, - { 0x04, 0, "VK_KEY_3" , "AE03" }, - { 0x05, 0, "VK_KEY_4" , "AE04" }, - { 0x06, 0, "VK_KEY_5" , "AE05" }, - { 0x07, 0, "VK_KEY_6" , "AE06" }, - { 0x08, 0, "VK_KEY_7" , "AE07" }, - { 0x09, 0, "VK_KEY_8" , "AE08" }, - { 0x0A, 0, "VK_KEY_9" , "AE09" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x1E, 0, "VK_KEY_A" , "AC01" }, - { 0x30, 0, "VK_KEY_B" , "AB05" }, - { 0x2E, 0, "VK_KEY_C" , "AB03" }, - { 0x20, 0, "VK_KEY_D" , "AC03" }, - { 0x12, 0, "VK_KEY_E" , "AD03" }, - { 0x21, 0, "VK_KEY_F" , "AC04" }, - { 0x22, 0, "VK_KEY_G" , "AC05" }, - { 0x23, 0, "VK_KEY_H" , "AC06" }, - { 0x17, 0, "VK_KEY_I" , "AD08" }, - { 0x24, 0, "VK_KEY_J" , "AC07" }, - { 0x25, 0, "VK_KEY_K" , "AC08" }, - { 0x26, 0, "VK_KEY_L" , "AC09" }, - { 0x32, 0, "VK_KEY_M" , "AB07" }, - { 0x31, 0, "VK_KEY_N" , "AB06" }, - { 0x18, 0, "VK_KEY_O" , "AD09" }, - { 0x19, 0, "VK_KEY_P" , "AD10" }, - { 0x10, 0, "VK_KEY_Q" , "AD01" }, - { 0x13, 0, "VK_KEY_R" , "AD04" }, - { 0x1F, 0, "VK_KEY_S" , "AC02" }, - { 0x14, 0, "VK_KEY_T" , "AD05" }, - { 0x16, 0, "VK_KEY_U" , "AD07" }, - { 0x2F, 0, "VK_KEY_V" , "AB04" }, - { 0x11, 0, "VK_KEY_W" , "AD02" }, - { 0x2D, 0, "VK_KEY_X" , "AB02" }, - { 0x15, 0, "VK_KEY_Y" , "AD06" }, - { 0x2C, 0, "VK_KEY_Z" , "AB01" }, - { 0x5B, 1, "VK_LWIN" , "LWIN" }, - { 0x5C, 1, "VK_RWIN" , "RWIN" }, - { 0x5D, 1, "VK_APPS" , "COMP" }, - { 0x00, 0, "" , NULL }, - { 0x5F, 0, "VK_SLEEP" , NULL }, - { 0x52, 0, "VK_NUMPAD0" , "KP0" }, - { 0x4F, 0, "VK_NUMPAD1" , "KP1" }, - { 0x50, 0, "VK_NUMPAD2" , "KP2" }, - { 0x51, 0, "VK_NUMPAD3" , "KP3" }, - { 0x4B, 0, "VK_NUMPAD4" , "KP4" }, - { 0x4C, 0, "VK_NUMPAD5" , "KP5" }, - { 0x4D, 0, "VK_NUMPAD6" , "KP6" }, - { 0x47, 0, "VK_NUMPAD7" , "KP7" }, - { 0x48, 0, "VK_NUMPAD8" , "KP8" }, - { 0x49, 0, "VK_NUMPAD9" , "KP9" }, - { 0x37, 0, "VK_MULTIPLY" , "KPMU" }, - { 0x4E, 0, "VK_ADD" , "KPAD" }, - { 0x00, 0, "VK_SEPARATOR" , NULL }, - { 0x4A, 0, "VK_SUBTRACT" , "KPSU" }, - { 0x53, 0, "VK_DECIMAL" , "KPDL" }, - { 0x35, 0, "VK_DIVIDE" , "KPDV" }, - { 0x3B, 0, "VK_F1" , "FK01" }, - { 0x3C, 0, "VK_F2" , "FK02" }, - { 0x3D, 0, "VK_F3" , "FK03" }, - { 0x3E, 0, "VK_F4" , "FK04" }, - { 0x3F, 0, "VK_F5" , "FK05" }, - { 0x40, 0, "VK_F6" , "FK06" }, - { 0x41, 0, "VK_F7" , "FK07" }, - { 0x42, 0, "VK_F8" , "FK08" }, - { 0x43, 0, "VK_F9" , "FK09" }, - { 0x44, 0, "VK_F10" , "FK10" }, - { 0x57, 0, "VK_F11" , "FK11" }, - { 0x58, 0, "VK_F12" , "FK12" }, - { 0x64, 0, "VK_F13" , NULL }, - { 0x65, 0, "VK_F14" , NULL }, - { 0x66, 0, "VK_F15" , NULL }, - { 0x67, 0, "VK_F16" , NULL }, - { 0x68, 0, "VK_F17" , NULL }, - { 0x69, 0, "VK_F18" , NULL }, - { 0x6A, 0, "VK_F19" , NULL }, - { 0x6B, 0, "VK_F20" , NULL }, - { 0x6C, 0, "VK_F21" , NULL }, - { 0x6D, 0, "VK_F22" , NULL }, - { 0x6E, 0, "VK_F23" , NULL }, - { 0x6F, 0, "VK_F24" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x45, 0, "VK_NUMLOCK" , "NMLK" }, - { 0x46, 0, "VK_SCROLL" , "SCLK" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x2A, 0, "VK_LSHIFT" , NULL }, - { 0x36, 0, "VK_RSHIFT" , "RTSH" }, - { 0x1D, 0, "VK_LCONTROL" , "LCTL" }, - { 0x1D, 1, "VK_RCONTROL" , "RCTL" }, - { 0x38, 0, "VK_LMENU" , NULL }, - { 0x38, 1, "VK_RMENU" , "RALT" }, - { 0x00, 0, "VK_BROWSER_BACK" , NULL }, - { 0x00, 0, "VK_BROWSER_FORWARD" , NULL }, - { 0x00, 0, "VK_BROWSER_REFRESH" , NULL }, - { 0x00, 0, "VK_BROWSER_STOP" , NULL }, - { 0x00, 0, "VK_BROWSER_SEARCH" , NULL }, - { 0x00, 0, "VK_BROWSER_FAVORITES", NULL }, - { 0x00, 0, "VK_BROWSER_HOME" , NULL }, - { 0x00, 0, "VK_VOLUME_MUTE" , NULL }, - { 0x00, 0, "VK_VOLUME_DOWN" , NULL }, - { 0x00, 0, "VK_VOLUME_UP" , NULL }, - { 0x00, 0, "VK_MEDIA_NEXT_TRACK" , NULL }, - { 0x00, 0, "VK_MEDIA_PREV_TRACK" , NULL }, - { 0x00, 0, "VK_MEDIA_STOP" , NULL }, - { 0x00, 0, "VK_MEDIA_PLAY_PAUSE" , NULL }, - { 0x00, 0, "VK_LAUNCH_MAIL" , NULL }, - { 0x00, 0, "VK_MEDIA_SELECT" , NULL }, - { 0x00, 0, "VK_LAUNCH_APP1" , NULL }, - { 0x00, 0, "VK_LAUNCH_APP2" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x27, 0, "VK_OEM_1" , "AC10" }, - { 0x0D, 0, "VK_OEM_PLUS" , "AE12" }, - { 0x33, 0, "VK_OEM_COMMA" , "AB08" }, - { 0x0C, 0, "VK_OEM_MINUS" , "AE11" }, - { 0x34, 0, "VK_OEM_PERIOD" , "AB09" }, - { 0x35, 0, "VK_OEM_2" , "AB10" }, - { 0x29, 0, "VK_OEM_3" , "TLDE" }, - { 0x73, 0, "VK_ABNT_C1" , "AB11" }, - { 0x7E, 0, "VK_ABNT_C2" , "I129" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x1A, 0, "VK_OEM_4" , "AD11" }, - { 0x2B, 0, "VK_OEM_5" , "BKSL" }, - { 0x1B, 0, "VK_OEM_6" , "AD12" }, - { 0x28, 0, "VK_OEM_7" , "AC11" }, - { 0x1D, 0, "VK_OEM_8" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x56, 0, "VK_OEM_102" , "LSGT" }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_PROCESSKEY" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_PACKET" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "" , NULL }, - { 0x00, 0, "VK_ATTN" , NULL }, - { 0x00, 0, "VK_CRSEL" , NULL }, - { 0x00, 0, "VK_EXSEL" , NULL }, - { 0x00, 0, "VK_EREOF" , NULL }, - { 0x00, 0, "VK_PLAY" , NULL }, - { 0x62, 0, "VK_ZOOM" , NULL }, - { 0x00, 0, "VK_NONAME" , NULL }, - { 0x00, 0, "VK_PA1" , NULL }, - { 0x00, 0, "VK_OEM_CLEAR" , NULL }, - { 0x00, 0, "" , NULL }, - /* end of 256 VK entries */ - { 0x54, 0, "" , "LVL3" }, - { 0x1C, 1, "" , "KPEN" } -}; - RDP_KEYBOARD_LAYOUT* freerdp_keyboard_get_layouts(uint32 types) { int num, length, i; diff --git a/libfreerdp-locale/keyboard_sun.c b/libfreerdp-locale/keyboard_sun.c index e28224b65..8494ad950 100644 --- a/libfreerdp-locale/keyboard_sun.c +++ b/libfreerdp-locale/keyboard_sun.c @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * Solaris Keyboard Mapping * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ #include #include "liblocale.h" -#include +#include #include "keyboard_x11.h" @@ -47,16 +47,16 @@ * keyboard layout indicated by the index given (in this case, 33, or US-English). */ -struct _SunOSKeyboard +struct _SOLARIS_KEYBOARD { - int type; /* Sun keyboard type */ - int layout; /* Layout */ + uint32 type; /* Solaris keyboard type */ + uint32 layout; /* Layout */ char* xkbType; /* XKB keyboard */ - uint32 keyboardLayoutID; /* XKB keyboard layout */ + uint32 keyboardLayoutId; /* XKB keyboard layout */ }; -typedef struct _SunOSKeyboard SunOSKeyboard; +typedef struct _SOLARIS_KEYBOARD SOLARIS_KEYBOARD; -static const SunOSKeyboard SunOSKeyboards[] = +static const SOLARIS_KEYBOARD SOLARIS_KEYBOARD_TABLE[] = { { 4, 0, "sun(type4)", KBD_US }, /* US4 */ { 4, 1, "sun(type4)", KBD_US }, /* US4 */ @@ -197,7 +197,7 @@ static const SunOSKeyboard SunOSKeyboards[] = { 6, 272, "sun(type6)", KBD_PORTUGUESE_BRAZILIAN_ABNT } /* Brazil6_usb */ }; -uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) +uint32 freerdp_detect_keyboard_type_and_layout_solaris(char* xkbfile, int length) { FILE* kbd; @@ -245,18 +245,17 @@ uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) } pclose(kbd); - for (i = 0; i < sizeof(SunOSKeyboards) / sizeof(SunOSKeyboard); i++) + for (i = 0; i < sizeof(SOLARIS_KEYBOARD_TABLE) / sizeof(SOLARIS_KEYBOARD); i++) { - if (SunOSKeyboards[i].type == type) + if (SOLARIS_KEYBOARD_TABLE[i].type == type) { - if (SunOSKeyboards[i].layout == layout) + if (SOLARIS_KEYBOARD_TABLE[i].layout == layout) { - strncpy(xkbfile, SunOSKeyboards[i].xkbType, length); - return SunOSKeyboards[i].keyboardLayoutID; + strncpy(xkbfile, SOLARIS_KEYBOARD_TABLE[i].xkbType, length); + return SOLARIS_KEYBOARD_TABLE[i].keyboardLayoutId; } } } return 0; } - diff --git a/libfreerdp-locale/keyboard_sun.h b/libfreerdp-locale/keyboard_sun.h index 91a2a4471..96367d411 100644 --- a/libfreerdp-locale/keyboard_sun.h +++ b/libfreerdp-locale/keyboard_sun.h @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * Solaris Keyboard Mapping * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,11 +17,11 @@ * limitations under the License. */ -#ifndef __KEYBOARD_SUN_H -#define __KEYBOARD_SUN_H +#ifndef __LOCALE_KEYBOARD_SUN_H +#define __LOCALE_KEYBOARD_SUN_H #include "keyboard_x11.h" -uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); +uint32 freerdp_detect_keyboard_type_and_layout_solaris(char* xkbfile, int length); -#endif +#endif /* __LOCALE_KEYBOARD_SUN_H */ diff --git a/libfreerdp-locale/keyboard_x11.c b/libfreerdp-locale/keyboard_x11.c index c8fb99b0a..efa61908c 100644 --- a/libfreerdp-locale/keyboard_x11.c +++ b/libfreerdp-locale/keyboard_x11.c @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Keyboard Mapping * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,10 +22,15 @@ #include #include "liblocale.h" +#include #include #include "keyboard_x11.h" +extern uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2]; +extern RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256]; +extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[]; + struct _XKB_VARIANT { const char* variant; /* XKB Keyboard layout variant */ @@ -891,6 +896,48 @@ static const XKB_LAYOUT xkbLayouts[] = { "tm", KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */ }; +uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId) +{ + uint32 vkcode; + uint32 keycode; + uint32 keycode_to_vkcode[256]; + + memset(X11_KEYCODE_TO_RDP_SCANCODE, 0, sizeof(X11_KEYCODE_TO_RDP_SCANCODE)); + memset(RDP_SCANCODE_TO_X11_KEYCODE, 0, sizeof(RDP_SCANCODE_TO_X11_KEYCODE)); + + if (keyboardLayoutId == 0) + { + keyboardLayoutId = freerdp_detect_keyboard_layout_from_locale(); + DEBUG_KBD("using keyboard layout: %X", keyboardLayoutID); + } + + if (keyboardLayoutId == 0) + { + keyboardLayoutId = 0x0409; + DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID); + } + +#ifdef __APPLE__ + /* Apple X11 breaks XKB detection */ + freerdp_keyboard_load_map(keycode_to_vkcode, "macosx(macosx)"); +#endif + + for (keycode = 0; keycode < 256; keycode++) + { + vkcode = keycode_to_vkcode[keycode]; + + X11_KEYCODE_TO_RDP_SCANCODE[keycode].code = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code; + X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended; + + if (X11_KEYCODE_TO_RDP_SCANCODE[keycode].extended) + RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = keycode; + else + RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = keycode; + } + + return keyboardLayoutId; +} + uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant) { int i, j; diff --git a/libfreerdp-locale/keyboard_x11.h b/libfreerdp-locale/keyboard_x11.h index 1dc7e5704..0e3b13bda 100644 --- a/libfreerdp-locale/keyboard_x11.h +++ b/libfreerdp-locale/keyboard_x11.h @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * X11 Keyboard Mapping * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,10 @@ * limitations under the License. */ -/* Hardcoded mapping from xkb layout names and variants to RDP layout ids */ - -#ifndef __LAYOUTS_X_H -#define __LAYOUTS_X_H +#ifndef __LOCALE_KEYBOARD_X11_H +#define __LOCALE_KEYBOARD_X11_H +uint32 freerdp_keyboard_init_x11(uint32 keyboardLayoutId); uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant); -#ifdef sun -uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); -#endif - -#endif +#endif /* __LOCALE_KEYBOARD_X11_H */ diff --git a/libfreerdp-locale/keyboard_xkb.c b/libfreerdp-locale/keyboard_xkb.c index 9b6fd5b9b..99e007c08 100644 --- a/libfreerdp-locale/keyboard_xkb.c +++ b/libfreerdp-locale/keyboard_xkb.c @@ -1,6 +1,6 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * XKB Keyboard Mapping * * Copyright 2009-2012 Marc-Andre Moreau * @@ -23,6 +23,8 @@ #include "keyboard_x11.h" #include +extern uint32 RDP_SCANCODE_TO_X11_KEYCODE[256][2]; +extern RDP_SCANCODE X11_KEYCODE_TO_RDP_SCANCODE[256]; extern const RDP_SCANCODE VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[]; #include @@ -314,6 +316,31 @@ void* freerdp_keyboard_xkb_init() return (void*) display; } +uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId) +{ + void* display; + memset(X11_KEYCODE_TO_RDP_SCANCODE, 0, sizeof(X11_KEYCODE_TO_RDP_SCANCODE)); + memset(RDP_SCANCODE_TO_X11_KEYCODE, 0, sizeof(RDP_SCANCODE_TO_X11_KEYCODE)); + + display = freerdp_keyboard_xkb_init(); + + if (!display) + { + DEBUG_KBD("Error initializing xkb"); + return 0; + } + + if (keyboardLayoutId == 0) + { + keyboardLayoutId = detect_keyboard_layout_from_xkb(display); + DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboardLayoutId); + } + + freerdp_keyboard_load_map_from_xkb(display); + + return keyboardLayoutId; +} + /* return substring starting after nth comma, ending at following comma */ static char* comma_substring(char* s, int n) { @@ -377,7 +404,7 @@ uint32 detect_keyboard_layout_from_xkb(void* display) return keyboard_layout; } -int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x_keycode_to_rdp_scancode[256], uint32 rdp_scancode_to_x_keycode[256][2]) +int freerdp_keyboard_load_map_from_xkb(void* display) { int i, j; boolean found; @@ -411,14 +438,13 @@ int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x_keycode_to_r { uint32 vkcode = VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME_TABLE[j].vkcode; - x_keycode_to_rdp_scancode[i].keycode = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code; - x_keycode_to_rdp_scancode[i].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended; - x_keycode_to_rdp_scancode[i].keyname = VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME_TABLE[j].xkb_keyname; + X11_KEYCODE_TO_RDP_SCANCODE[i].code = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code; + X11_KEYCODE_TO_RDP_SCANCODE[i].extended = VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].extended; - if (x_keycode_to_rdp_scancode[i].extended) - rdp_scancode_to_x_keycode[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = i; + if (X11_KEYCODE_TO_RDP_SCANCODE[i].extended) + RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][1] = i; else - rdp_scancode_to_x_keycode[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = i; + RDP_SCANCODE_TO_X11_KEYCODE[VIRTUAL_KEY_CODE_TO_RDP_SCANCODE_TABLE[vkcode].code][0] = i; } } diff --git a/libfreerdp-locale/keyboard_xkb.h b/libfreerdp-locale/keyboard_xkb.h index d569a4e2d..2a8ac5867 100644 --- a/libfreerdp-locale/keyboard_xkb.h +++ b/libfreerdp-locale/keyboard_xkb.h @@ -1,6 +1,6 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * XKB Keyboard Mapping * * Copyright 2009-2012 Marc-Andre Moreau * @@ -17,9 +17,11 @@ * limitations under the License. */ -#include +#ifndef __LOCALE_KEYBOARD_XKB_H +#define __LOCALE_KEYBOARD_XKB_H -#include "keyboard.h" +#include +#include struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME { @@ -28,6 +30,8 @@ struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME }; typedef struct _VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME VIRTUAL_KEY_CODE_TO_XKB_KEY_NAME; -void* freerdp_keyboard_xkb_init(); +uint32 freerdp_keyboard_init_xkb(uint32 keyboardLayoutId); uint32 detect_keyboard_layout_from_xkb(void* display); -int freerdp_keyboard_load_map_from_xkb(void* display, RDP_KEYCODE x11_keycode_to_rdp_scancode[256], uint32 rdp_scancode_to_x11_keycode[256][2]); +int freerdp_keyboard_load_map_from_xkb(void* display); + +#endif /* __LOCALE_KEYBOARD_XKB_H */ diff --git a/libfreerdp-locale/liblocale.h b/libfreerdp-locale/liblocale.h index ffd561e80..79cbc6ad3 100644 --- a/libfreerdp-locale/liblocale.h +++ b/libfreerdp-locale/liblocale.h @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * RDP Localization * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,8 +17,8 @@ * limitations under the License. */ -#ifndef __LIBKBD_H -#define __LIBKBD_H +#ifndef __LIBLOCALE_H +#define __LIBLOCALE_H #include @@ -28,4 +28,4 @@ #define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif -#endif /* __LIBKBD_H */ +#endif /* __LIBLOCALE_H */ diff --git a/libfreerdp-locale/locale.c b/libfreerdp-locale/locale.c index be2d5b4a4..510bb4a4a 100644 --- a/libfreerdp-locale/locale.c +++ b/libfreerdp-locale/locale.c @@ -1,8 +1,8 @@ /** - * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * FreeRDP: A Remote Desktop Protocol Implementation + * Microsoft Locales * - * Copyright 2009 Marc-Andre Moreau + * Copyright 2009-2012 Marc-Andre Moreau * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ typedef struct _SYSTEM_LOCALE SYSTEM_LOCALE; * http://msdn.microsoft.com/en-us/library/ms776260.aspx */ -static const SYSTEM_LOCALE SystemLocaleTable[] = +static const SYSTEM_LOCALE SYSTEM_LOCALE_TABLE[] = { { "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */ { "sq", "AL", ALBANIAN }, /* Albanian (Albania) */ @@ -241,17 +241,17 @@ static const SYSTEM_LOCALE SystemLocaleTable[] = }; -struct _localeAndKeyboardLayout +struct _LOCALE_KEYBOARD_LAYOUTS { uint32 locale; /* Locale ID */ uint32 keyboardLayouts[5]; /* array of associated keyboard layouts */ }; -typedef struct _localeAndKeyboardLayout localeAndKeyboardLayout; +typedef struct _LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS; /* TODO: Use KBD_* defines instead of hardcoded values */ -static const localeAndKeyboardLayout defaultKeyboardLayouts[] = +static const LOCALE_KEYBOARD_LAYOUTS LOCALE_KEYBOARD_LAYOUTS_TABLE[] = { { AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, { ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } }, @@ -464,11 +464,11 @@ SYSTEM_LOCALE* freerdp_detect_system_locale() freerdp_get_system_language_and_country_codes(language, country); - for (i = 0; i < sizeof(SystemLocaleTable) / sizeof(SYSTEM_LOCALE); i++) + for (i = 0; i < sizeof(SYSTEM_LOCALE_TABLE) / sizeof(SYSTEM_LOCALE); i++) { - if ((strcmp(language, SystemLocaleTable[i].language) == 0) && (strcmp(country, SystemLocaleTable[i].country) == 0)) + if ((strcmp(language, SYSTEM_LOCALE_TABLE[i].language) == 0) && (strcmp(country, SYSTEM_LOCALE_TABLE[i].country) == 0)) { - locale = (SYSTEM_LOCALE*) &SystemLocaleTable[i]; + locale = (SYSTEM_LOCALE*) &SYSTEM_LOCALE_TABLE[i]; break; } } @@ -495,24 +495,24 @@ uint32 freerdp_detect_keyboard_layout_from_locale() DEBUG_KBD("Found locale : %s_%s", locale.language, locale.country); - for (i = 0; i < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); i++) + for (i = 0; i < sizeof(LOCALE_KEYBOARD_LAYOUTS_TABLE) / sizeof(LOCALE_KEYBOARD_LAYOUTS); i++) { - if (defaultKeyboardLayouts[i].locale == locale->code) + if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].locale == locale->code) { /* Locale found in list of default keyboard layouts */ for (j = 0; j < 5; j++) { - if (defaultKeyboardLayouts[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES) + if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == ENGLISH_UNITED_STATES) { continue; /* Skip, try to get a more localized keyboard layout */ } - else if (defaultKeyboardLayouts[i].keyboardLayouts[j] == 0) + else if (LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j] == 0) { break; /* No more keyboard layouts */ } else { - return defaultKeyboardLayouts[i].keyboardLayouts[j]; + return LOCALE_KEYBOARD_LAYOUTS_TABLE[i].keyboardLayouts[j]; } } diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c index a013c7be9..649613647 100644 --- a/server/X11/xf_input.c +++ b/server/X11/xf_input.c @@ -37,7 +37,7 @@ void xf_input_keyboard_event(rdpInput* input, uint16 flags, uint16 code) if (flags & KBD_FLAGS_EXTENDED) extended = true; - keycode = freerdp_keyboard_get_keycode_from_scancode(code, extended); + keycode = freerdp_keyboard_get_x11_keycode_from_rdp_scancode(code, extended); if (keycode != 0) {