diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ea2e2cd6..0aa25a788 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,8 +126,9 @@ endif() # Endian test_big_endian(BIG_ENDIAN) -# Path to put keymaps -set(FREERDP_KEYMAP_PATH "${CMAKE_INSTALL_PREFIX}/freerdp/keymaps") +# Path to put FreeRDP data +set(FREERDP_DATA_PATH "${CMAKE_INSTALL_PREFIX}/share/freerdp") +set(FREERDP_KEYMAP_PATH "${FREERDP_DATA_PATH}/keymaps") # Path to put plugins set(FREERDP_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/freerdp") @@ -153,7 +154,6 @@ endif() # Sub-directories add_subdirectory(include) add_subdirectory(libfreerdp-utils) -add_subdirectory(libfreerdp-locale) add_subdirectory(libfreerdp-gdi) add_subdirectory(libfreerdp-rail) add_subdirectory(libfreerdp-cache) @@ -161,6 +161,7 @@ add_subdirectory(libfreerdp-codec) add_subdirectory(libfreerdp-crypto) add_subdirectory(libfreerdp-auth) add_subdirectory(libfreerdp-channels) +add_subdirectory(libfreerdp-locale) add_subdirectory(libfreerdp-core) if(NOT WIN32) diff --git a/client/DirectFB/df_event.c b/client/DirectFB/df_event.c index b731d029f..a691e7c0d 100644 --- a/client/DirectFB/df_event.c +++ b/client/DirectFB/df_event.c @@ -203,7 +203,7 @@ void df_send_keyboard_event(rdpInput* input, boolean down, uint8 keycode, uint8 else return; - scancode = freerdp_kbd_get_scancode_by_virtualkey(vkcode, &extended); + scancode = freerdp_keyboard_get_scancode_from_vkcode(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 020b5e4f8..639e39fdf 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -30,7 +30,7 @@ void xf_kbd_init(xfInfo* xfi) { memset(xfi->pressed_keys, 0, 256 * sizeof(boolean)); xfi->keyboard_layout_id = xfi->instance->settings->kbd_layout; - xfi->keyboard_layout_id = freerdp_kbd_init(xfi->display, xfi->keyboard_layout_id); + xfi->keyboard_layout_id = freerdp_keyboard_init(xfi->keyboard_layout_id); xfi->instance->settings->kbd_layout = xfi->keyboard_layout_id; } @@ -64,7 +64,7 @@ void xf_kbd_send_key(xfInfo* xfi, boolean down, uint8 keycode) rdpInput* input; input = xfi->instance->input; - scancode = freerdp_kbd_get_scancode_by_keycode(keycode, &extended); + scancode = freerdp_keyboard_get_scancode_from_keycode(keycode, &extended); if (scancode == 0) { diff --git a/client/X11/xfreerdp.c b/client/X11/xfreerdp.c index 999dc09fd..44450d674 100644 --- a/client/X11/xfreerdp.c +++ b/client/X11/xfreerdp.c @@ -779,19 +779,19 @@ int xf_process_client_args(rdpSettings* settings, const char* opt, const char* v int i; rdpKeyboardLayout* layouts; - layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD); + layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD); printf("\nKeyboard Layouts\n"); for (i = 0; layouts[i].code; i++) printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); free(layouts); - layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); + layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT); printf("\nKeyboard Layout Variants\n"); for (i = 0; layouts[i].code; i++) printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); free(layouts); - layouts = freerdp_kbd_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME); + layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME); printf("\nKeyboard Input Method Editors (IMEs)\n"); for (i = 0; layouts[i].code; i++) printf("0x%08X\t%s\n", layouts[i].code, layouts[i].name); diff --git a/config.h.in b/config.h.in index baf8ce140..89399791d 100644 --- a/config.h.in +++ b/config.h.in @@ -7,6 +7,10 @@ #define FREERDP_VERSION_MINOR ${FREERDP_VERSION_MINOR} #define FREERDP_VERSION_REVISION ${FREERDP_VERSION_REVISION} +#define FREERDP_DATA_PATH "${FREERDP_DATA_PATH}" +#define FREERDP_PLUGIN_PATH "${FREERDP_PLUGIN_PATH}" +#define FREERDP_KEYMAP_PATH "${FREERDP_KEYMAP_PATH}" + /* Include files */ #cmakedefine HAVE_SYS_PARAM_H #cmakedefine HAVE_SYS_SOCKET_H diff --git a/freerdp.pc.in b/freerdp.pc.in index 6a44529c7..b7ede32ac 100644 --- a/freerdp.pc.in +++ b/freerdp.pc.in @@ -8,6 +8,6 @@ Description: A free remote desktop protocol client URL: http://www.freerdp.com/ Version: @FREERDP_VERSION_FULL@ Requires: -Libs: -L${libdir} -lfreerdp-core -lfreerdp-codec -lfreerdp-gdi -lfreerdp-kbd -lfreerdp-rail -lfreerdp-channels -lfreerdp-utils +Libs: -L${libdir} -lfreerdp-core -lfreerdp-codec -lfreerdp-gdi -lfreerdp-locale -lfreerdp-crypto -lfreeerdp-auth -lfreerdp-rail -lfreerdp-channels -lfreerdp-utils Cflags: -I${includedir} diff --git a/include/freerdp/locale/keyboard.h b/include/freerdp/locale/keyboard.h index 82d102438..b3df40d89 100644 --- a/include/freerdp/locale/keyboard.h +++ b/include/freerdp/locale/keyboard.h @@ -27,16 +27,17 @@ #define RDP_KEYBOARD_LAYOUT_TYPE_VARIANT 2 #define RDP_KEYBOARD_LAYOUT_TYPE_IME 4 -typedef struct rdp_keyboard_layout +struct rdp_keyboard_layout { uint32 code; - char name[50]; -} rdpKeyboardLayout; + char name[64]; +}; +typedef struct rdp_keyboard_layout rdpKeyboardLayout; -FREERDP_API rdpKeyboardLayout* freerdp_kbd_get_layouts(int types); -FREERDP_API uint32 freerdp_kbd_init(void *dpy, uint32 keyboard_layout_id); -FREERDP_API uint8 freerdp_kbd_get_scancode_by_keycode(uint8 keycode, boolean* extended); -FREERDP_API uint8 freerdp_kbd_get_keycode_by_scancode(uint8 scancode, boolean extended); -FREERDP_API uint8 freerdp_kbd_get_scancode_by_virtualkey(int vkcode, boolean* extended); +FREERDP_API uint32 freerdp_keyboard_init(uint32 keyboard_layout_id); +FREERDP_API rdpKeyboardLayout* freerdp_keyboard_get_layouts(uint32 types); +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); #endif /* __FREERDP_KBD_H */ diff --git a/include/freerdp/locale/layouts.h b/include/freerdp/locale/layouts.h index c275b8fd6..3d7e81740 100644 --- a/include/freerdp/locale/layouts.h +++ b/include/freerdp/locale/layouts.h @@ -23,6 +23,7 @@ #define __LAYOUT_IDS_H #include +#include #include /* Keyboard layout IDs */ @@ -178,7 +179,7 @@ #define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804 #define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404 -FREERDP_API rdpKeyboardLayout* get_keyboard_layouts(int types); +FREERDP_API rdpKeyboardLayout* get_keyboard_layouts(uint32 types); FREERDP_API const char* get_layout_name(uint32 keyboardLayoutID); #endif diff --git a/include/freerdp/locale/locales.h b/include/freerdp/locale/locales.h index b98a06e36..601fb4eb2 100644 --- a/include/freerdp/locale/locales.h +++ b/include/freerdp/locale/locales.h @@ -230,99 +230,6 @@ #define YORUBA 0x046A #define ZULU 0x0435 - -/* -Time zones, taken from Windows Server 2008 - -(GMT -12:00) International Date Line West -(GMT -11:00) Midway Island, Samoa -(GMT -10:00) Hawaii -(GMT -09:00) Alaska -(GMT -08:00) Pacific Time (US & Canada) -(GMT -08:00) Tijuana, Baja California -(GMT -07:00) Arizona -(GMT -07:00) Chihuahua, La Paz, Mazatlan -(GMT -07:00) Mountain Time (US & Canada) -(GMT -06:00) Central America -(GMT -06:00) Central Time (US & Canada) -(GMT -06:00) Guadalajara, Mexico City, Monterrey -(GMT -06:00) Saskatchewan -(GMT -05:00) Bogota, Lima, Quito, Rio Branco -(GMT -05:00) Eastern Time (US & Canada) -(GMT -05:00) Indiana (East) -(GMT -04:30) Caracas -(GMT -04:00) Atlantic Time (Canada) -(GMT -04:00) La Paz -(GMT -04:00) Manaus -(GMT -04:00) Santiago -(GMT -03:30) Newfoundland -(GMT -03:00) Brasilia -(GMT -03:00) Buenos Aires -(GMT -03:00) Georgetown -(GMT -03:00) Greenland -(GMT -03:00) Montevideo -(GMT -02:00) Mid-Atlantic -(GMT -01:00) Azores -(GMT -01:00) Cape Verde Is. -(GMT +00:00) Casablanca -(GMT +00:00) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London -(GMT +00:00) Monrovia, Reykjavik -(GMT +01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna -(GMT +01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague -(GMT +01:00) Brussels, Copenhagen, Madrid, Paris -(GMT +01:00) Sarajevo, Skopje, Warsaw, Zagreb -(GMT +01:00) West Central Africa -(GMT +02:00) Amman -(GMT +02:00) Athens, Bucharest, Istanbul -(GMT +02:00) Beirut -(GMT +02:00) Cairo -(GMT +02:00) Harare, Pretoria -(GMT +02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius -(GMT +02:00) Jerusalem -(GMT +02:00) Minsk -(GMT +02:00) Windhoek -(GMT +03:00) Baghdad -(GMT +03:00) Kuwait, Riyadh -(GMT +03:00) Moscow, St. Petersburg, Volgograd -(GMT +03:00) Nairobi -(GMT +03:00) Tbilisi -(GMT +03:30) Tehran -(GMT +04:00) Abu Dhabi, Muscat -(GMT +04:00) Baku -(GMT +04:00) Port Louis -(GMT +04:00) Yerevan -(GMT +04:30) Kabul -(GMT +05:00) Ekaterinburg -(GMT +05:00) Islamabad, Karachi -(GMT +05:00) Tashkent -(GMT +05:30) Chennai, Kolkata, Mumbai, New Delhi -(GMT +05:30) Sri Jayawardenepura -(GMT +05:45) Kathmandu -(GMT +06:00) Almaty, Novosibirsk -(GMT +06:00) Astana, Dhaka -(GMT +06:30) Yangon (Rangoon) -(GMT +07:00) Bangkok, Hanoi, Jakarta -(GMT +07:00) Krasnoyarsk -(GMT +08:00) Beijing, Chongqing, Hong Kong, Urumqi -(GMT +08:00) Irkutsk, Ulaan Bataar -(GMT +08:00) Kuala Lumpur, Singapore -(GMT +08:00) Perth -(GMT +08:00) Taipei -(GMT +09:00) Osaka, Sapporo, Tokyo -(GMT +09:00) Seoul -(GMT +09:00) Yakutsk -(GMT +09:30) Adelaide -(GMT +09:30) Darwin -(GMT +10:00) Brisbane -(GMT +10:00) Canberra, Melbourne, Sydney -(GMT +10:00) Guam, Port Moresby -(GMT +10:00) Hobart, Vladivostok -(GMT +11:00) Magadan, Solomon Is., New Caledonia -(GMT +12:00) Auckland, Wellington -(GMT +12:00) Fiji, Kamchatka, Marshall Is. -(GMT +13:00) Nuku'alofa -*/ - FREERDP_API uint32 detect_keyboard_layout_from_locale(); #endif /* __LOCALES_H */ diff --git a/include/freerdp/locale/vkcodes.h b/include/freerdp/locale/vkcodes.h index f5b7d5c2e..3b4ae2ad7 100644 --- a/include/freerdp/locale/vkcodes.h +++ b/include/freerdp/locale/vkcodes.h @@ -24,6 +24,7 @@ #include #include +#include #include /* Mouse buttons */ @@ -306,282 +307,13 @@ /* Use the virtual key code as an index in this array in order to get its associated scan code */ -typedef struct _virtualKey +struct _virtualKey { - /* Windows "scan code", aka keycode in RDP */ - unsigned char scancode; - - /* Windows "extended" flag, boolean */ - unsigned char extended; - - /* Windows virtual key name */ - char *name; - - /* XKB keyname */ - char *x_keyname; -} virtualKey; - -static const virtualKey virtualKeyboard[256 + 2] = -{ - { 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" }, + uint32 scancode; /* Windows "scan code", aka keycode in RDP */ + boolean extended; /* Windows "extended" flag, boolean */ + const char* name; /* Windows virtual key name */ + const char* x_keyname; /* XKB keyname */ }; +typedef struct _virtualKey virtualKey; #endif /* __VKCODES_H */ diff --git a/keymaps/CMakeLists.txt b/keymaps/CMakeLists.txt index 13ff08ee6..8970011be 100644 --- a/keymaps/CMakeLists.txt +++ b/keymaps/CMakeLists.txt @@ -17,7 +17,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -install(FILES aliases amiga ataritt empty evdev fujitsu hp ibm macintosh macosx sony sun xfree86 xfree98 DESTINATION share/freerdp/keymaps) -install(DIRECTORY digital_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*") -install(DIRECTORY sgi_vndr DESTINATION share/freerdp/keymaps FILES_MATCHING PATTERN "*") +install(FILES aliases amiga ataritt empty evdev fujitsu hp ibm macintosh macosx sony sun xfree86 xfree98 DESTINATION ${FREERDP_KEYMAP_PATH}) +install(DIRECTORY digital_vndr DESTINATION ${FREERDP_KEYMAP_PATH} FILES_MATCHING PATTERN "*") +install(DIRECTORY sgi_vndr DESTINATION ${FREERDP_KEYMAP_PATH} FILES_MATCHING PATTERN "*") diff --git a/libfreerdp-channels/CMakeLists.txt b/libfreerdp-channels/CMakeLists.txt index 55a139a94..56f2fa710 100644 --- a/libfreerdp-channels/CMakeLists.txt +++ b/libfreerdp-channels/CMakeLists.txt @@ -1,5 +1,5 @@ # FreeRDP: A Remote Desktop Protocol Client -# libfreerdp-chanman cmake build script +# libfreerdp-channels cmake build script # # Copyright 2011 O.S. Systems Software Ltda. # Copyright 2011 Otavio Salvador diff --git a/libfreerdp-locale/CMakeLists.txt b/libfreerdp-locale/CMakeLists.txt index 102343642..910f5412c 100644 --- a/libfreerdp-locale/CMakeLists.txt +++ b/libfreerdp-locale/CMakeLists.txt @@ -18,34 +18,43 @@ # limitations under the License. set(FREERDP_LOCALE_SRCS - locales.c + locale.c layouts.c - layouts_xkb.c - layouts_xkb.h - x_layout_id_table.c - x_layout_id_table.h - libkbd.c - libkbd.h) + keyboard.c + keyboard.h + keyboard_x11.c + keyboard_x11.h + liblocale.h) -add_library(freerdp-locale ${FREERDP_LOCALE_SRCS}) +set(FREERDP_LOCALE_XKB_SRCS + keyboard_xkb.c + keyboard_xkb.h) -find_suggested_package(X11) -if(WITH_X11) - target_link_libraries(freerdp-locale ${X11_LIBRARIES}) -endif() - -if(NOT APPLE) - find_suggested_package(XKBFile) - if(WITH_X11) - if(WITH_XKBFILE) - add_definitions(-DWITH_XKBFILE) - include_directories(${XKBFILE_INCLUDE_DIRS}) - target_link_libraries(freerdp-locale ${XKBFILE_LIBRARIES}) +if(NOT WIN32) + find_suggested_package(X11) + if(NOT APPLE) + find_suggested_package(XKBFile) + if (WITH_X11) + add_definitions(-DWITH_X11) + if(WITH_XKBFILE) + add_definitions(-DWITH_XKB) + include_directories(${XKBFILE_INCLUDE_DIRS}) + set(FREERDP_LOCALE_SRCS ${FREERDP_LOCALE_SRCS} ${FREERDP_LOCALE_XKB_SRCS}) + endif() endif() endif() endif() -add_definitions(-DKEYMAP_PATH="${FREERDP_KEYMAP_PATH}") +add_library(freerdp-locale ${FREERDP_LOCALE_SRCS}) + +if(NOT WIN32) + if(WITH_X11) + target_link_libraries(freerdp-locale ${X11_LIBRARIES}) + if(WITH_XKBFILE) + target_link_libraries(freerdp-locale ${XKBFILE_LIBRARIES}) + endif() + endif() +endif() set_target_properties(freerdp-locale PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") diff --git a/libfreerdp-locale/layouts_xkb.c b/libfreerdp-locale/keyboard.c similarity index 52% rename from libfreerdp-locale/layouts_xkb.c rename to libfreerdp-locale/keyboard.c index ef9f6b9a0..709025999 100644 --- a/libfreerdp-locale/layouts_xkb.c +++ b/libfreerdp-locale/keyboard.c @@ -1,6 +1,6 @@ /** * FreeRDP: A Remote Desktop Protocol Client - * XKB-based Keyboard Mapping to Microsoft Keyboard System + * Localization Services * * Copyright 2009 Marc-Andre Moreau * @@ -21,144 +21,133 @@ #include #include -#ifdef WITH_XKBFILE -#include -#include -#include -#include +#include +#include +#include +#include + +#include "liblocale.h" + +#ifdef WITH_XKB +#include "keyboard_xkb.h" #endif -#include "libkbd.h" +#include #include -#include "x_layout_id_table.h" +#include -#include "layouts_xkb.h" +#include "keyboard.h" -#ifndef KEYMAP_PATH -#define KEYMAP_PATH "/usr/local/freerdp/keymaps" +extern const virtualKey virtualKeyboard[258]; + +/* + * 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. + */ + +RdpScancodes x_keycode_to_rdp_scancode; + +uint8 rdp_scancode_to_x_keycode[256][2]; + +uint32 freerdp_detect_keyboard(void* display, uint32 keyboardLayoutID, char* xkbfile, size_t xkbfile_length) +{ + xkbfile[0] = '\0'; + + if (keyboardLayoutID != 0) + DEBUG_KBD("keyboard layout configuration: %X", keyboardLayoutID); + +#if defined(sun) + if (keyboardLayoutID == 0) + { + keyboardLayoutID = detect_keyboard_type_and_layout_sunos(xkbfile, xkbfile_length); + DEBUG_KBD("detect_keyboard_type_and_layout_sunos: %X %s", keyboardLayoutID, xkbfile); + } #endif -#ifdef WITH_XKBFILE - -int init_xkb(void* dpy) -{ - return XkbQueryExtension(dpy, NULL, NULL, NULL, NULL, NULL); -} - -/* return substring starting after nth comma, ending at following comma */ -static char* comma_substring(char* s, int n) -{ - char *p; - - if (!s) - return ""; - - while (n-- > 0) + if (keyboardLayoutID == 0) { - if (!(p = strchr(s, ','))) - break; - - s = p + 1; + keyboardLayoutID = detect_keyboard_layout_from_locale(); + DEBUG_KBD("detect_keyboard_layout_from_locale: %X", keyboardLayoutID); } - if ((p = strchr(s, ','))) - *p = 0; - - return s; -} - -unsigned int detect_keyboard_layout_from_xkb(void* dpy) -{ - char *layout, *variant; - unsigned int keyboard_layout = 0, group = 0; - XkbRF_VarDefsRec rules_names; - XKeyboardState coreKbdState; - XkbStateRec state; - - DEBUG_KBD("display: %p", dpy); - - if (dpy && XkbRF_GetNamesProp(dpy, NULL, &rules_names)) + if (keyboardLayoutID == 0) { - DEBUG_KBD("layouts: %s", rules_names.layout ? rules_names.layout : ""); - DEBUG_KBD("variants: %s", rules_names.variant ? rules_names.variant : ""); - - XGetKeyboardControl(dpy, &coreKbdState); - - if (XkbGetState(dpy, XkbUseCoreKbd, &state) == Success) - group = state.group; - - DEBUG_KBD("group: %d", state.group); - - layout = comma_substring(rules_names.layout, group); - variant = comma_substring(rules_names.variant, group); - - DEBUG_KBD("layout: %s", layout ? layout : ""); - DEBUG_KBD("variant: %s", variant ? variant : ""); - - keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); - - free(rules_names.model); - free(rules_names.layout); - free(rules_names.variant); - free(rules_names.options); + keyboardLayoutID = 0x0409; + DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID); } - return keyboard_layout; -} - -int init_keycodes_from_xkb(void* dpy, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]) -{ - int ret = 0; - XkbDescPtr xkb; - - if (dpy && (xkb = XkbGetMap(dpy, 0, XkbUseCoreKbd))) + if (xkbfile[0] == '\0') { - if (XkbGetNames(dpy, XkbKeyNamesMask, xkb) == Success) - { - int i, j; - char buf[5] = {42, 42, 42, 42, 0}; /* end-of-string at pos 5 */ - - for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) - { - memcpy(buf, xkb->names->keys[i].name, 4); - - /* TODO: Use more efficient search ... but it is so fast that it doesn't matter */ - j = sizeof(virtualKeyboard) / sizeof(virtualKeyboard[0]) - 1; - - while (j >= 0) - { - if (virtualKeyboard[j].x_keyname && !strcmp(buf, virtualKeyboard[j].x_keyname)) - break; - j--; - } - - if (j >= 0) - { - DEBUG_KBD("X keycode %3d has keyname %-4s -> RDP scancode %d/%d", - i, buf, virtualKeyboard[j].extended, virtualKeyboard[j].scancode); - - x_keycode_to_rdp_scancode[i].extended = virtualKeyboard[j].extended; - x_keycode_to_rdp_scancode[i].keycode = virtualKeyboard[j].scancode; - x_keycode_to_rdp_scancode[i].keyname = virtualKeyboard[j].x_keyname; - - if (x_keycode_to_rdp_scancode[i].extended) - rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][1] = i; - else - rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][0] = i; - } - else - { - DEBUG_KBD("X key code %3d has keyname %-4s -> ??? - not found", i, buf); - } - } - ret = 1; - } - XkbFreeKeyboard(xkb, 0, 1); + strncpy(xkbfile, "base", xkbfile_length); + DEBUG_KBD("using default keyboard layout: %s", xkbfile); } - return ret; + + return keyboardLayoutID; } +/* + * Initialize global keyboard mapping and return the suggested server side layout. + * display must be a X Display* or NULL. + */ + +uint32 freerdp_keyboard_init(uint32 keyboard_layout_id) +{ + void* display; + memset(x_keycode_to_rdp_scancode, 0, sizeof(x_keycode_to_rdp_scancode)); + memset(rdp_scancode_to_x_keycode, '\0', sizeof(rdp_scancode_to_x_keycode)); + +#ifdef WITH_XKB + display = freerdp_keyboard_xkb_init(); + + if (!display) + { + DEBUG_KBD("Error initializing xkb"); + return 0; + } + + if (keyboard_layout_id == 0) + { + keyboard_layout_id = detect_keyboard_layout_from_xkb(display); + DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboard_layout_id); + } + + freerdp_keyboard_load_map_from_xkb(display, x_keycode_to_rdp_scancode, rdp_scancode_to_x_keycode); #else + int vkcode; + int keycode; + char xkbfile[256]; + KeycodeToVkcode keycodeToVkcode; + + if (keyboard_layout_id == 0) + keyboard_layout_id = freerdp_detect_keyboard(display, keyboard_layout_id, xkbfile, sizeof(xkbfile)); + + DEBUG_KBD("Using keyboard layout 0x%X with xkb name %s and xkbfile %s", + keyboard_layout_id, get_layout_name(keyboard_layout_id), xkbfile); + + freerdp_keyboard_load_maps(keycodeToVkcode, xkbfile); + + 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); + + x_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode; + x_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended; + x_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name; + + if (x_keycode_to_rdp_scancode[keycode].extended) + rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][1] = keycode; + else + rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][0] = keycode; + } +#endif + + return keyboard_layout_id; +} /* Default built-in keymap */ static const KeycodeToVkcode defaultKeycodeToVkcode = @@ -181,16 +170,16 @@ static const KeycodeToVkcode defaultKeycodeToVkcode = 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static int load_xkb_keyboard(KeycodeToVkcode map, char* kbd) +static int freerdp_keyboard_load_map(KeycodeToVkcode map, char* kbd) { char* pch; - char *beg, *end; - char* home; - char buffer[1024] = ""; - char xkbfile[256] = ""; - char xkbfilepath[512] = ""; + char* beg; + char* end; + char* xkbfile_path; char xkbmap[256] = ""; char xkbinc[256] = ""; + char buffer[1024] = ""; + char xkbfile[256] = ""; FILE* fp; int kbdFound = 0; @@ -222,65 +211,16 @@ static int load_xkb_keyboard(KeycodeToVkcode map, char* kbd) } /* Get path to file relative to freerdp's directory */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "keymaps/%s", xkbfile); - DEBUG_KBD("Loading keymap %s, first trying %s", kbd, xkbfilepath); + xkbfile_path = freerdp_construct_path(FREERDP_KEYMAP_PATH, xkbfile); - /* - * Open the file for reading only - * It can happen that the same file is opened twice at the same time - * in order to load multiple keyboard maps from the same file, but - * it does not matter: files can be opened as many times as we want - * when it is for reading only. - */ + DEBUG_KBD("Loading keymap %s, first trying %s", kbd, xkbfile_path); - if ((fp = fopen(xkbfilepath, "r")) == NULL) + if ((fp = fopen(xkbfile_path, "r")) == NULL) { - /* Look first in path given at compile time (install path) */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "%s/%s", KEYMAP_PATH, xkbfile); - - if ((fp = fopen(xkbfilepath, "r")) == NULL) - { - /* If ran from the root of the source tree */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "./keymaps/%s", xkbfile); - - /* If ran from the client directory */ - if((fp = fopen(xkbfilepath, "r")) == NULL) - snprintf(xkbfilepath, sizeof(xkbfilepath), "../../keymaps/%s", xkbfile); - - if ((fp = fopen(xkbfilepath, "r")) == NULL) - { - /* File wasn't found in the source tree, try ~/.freerdp/ folder */ - if ((home = getenv("HOME")) == NULL) - return 0; - - /* Get path to file in ~/.freerdp/ folder */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "%s/.freerdp/keymaps/%s", home, xkbfile); - - if ((fp = fopen(xkbfilepath, "r")) == NULL) - { - /* Try /usr/share/freerdp folder */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "/usr/share/freerdp/keymaps/%s", xkbfile); - - if ((fp = fopen(xkbfilepath, "r")) == NULL) - { - /* Try /usr/local/share/freerdp folder */ - snprintf(xkbfilepath, sizeof(xkbfilepath), "/usr/local/share/freerdp/keymaps/%s", xkbfile); - - if ((fp = fopen(xkbfilepath, "r")) == NULL) - { - /* Error: Could not find keymap */ - DEBUG_KBD("keymaps for %s not found", xkbfile); - return 0; - } - } - } - } - } + return 0; } - DEBUG_KBD("xkbfilepath: %s", xkbfilepath); - - while(fgets(buffer, sizeof(buffer), fp) != NULL) + while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (buffer[0] == '#') { @@ -350,7 +290,7 @@ static int load_xkb_keyboard(KeycodeToVkcode map, char* kbd) strncpy(xkbinc, beg, end - beg); xkbinc[end - beg] = '\0'; - load_xkb_keyboard(map, xkbinc); /* Load included keymap */ + freerdp_keyboard_load_map(map, xkbinc); /* Load included keymap */ } } else if ((pch = strstr(buffer, "keyboard")) != NULL) @@ -377,7 +317,7 @@ static int load_xkb_keyboard(KeycodeToVkcode map, char* kbd) return 1; } -void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile) +void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* xkbfile) { char* kbd; char* xkbfileEnd; @@ -390,7 +330,7 @@ void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile) #ifdef __APPLE__ /* Apple X11 breaks XKB detection */ - keymapLoaded += load_xkb_keyboard(keycodeToVkcode, "macosx(macosx)"); + keymapLoaded += freerdp_keyboard_load_map(keycodeToVkcode, "macosx(macosx)"); #else do { @@ -399,7 +339,7 @@ void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile) kbd[kbdlen] = '\0'; /* Load keyboard map */ - keymapLoaded += load_xkb_keyboard(keycodeToVkcode, kbd); + keymapLoaded += freerdp_keyboard_load_map(keycodeToVkcode, kbd); kbd += kbdlen + 1; } @@ -415,4 +355,31 @@ void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile) } } -#endif +rdpKeyboardLayout* freerdp_keyboard_get_layouts(uint32 types) +{ + return get_keyboard_layouts(types); +} + +uint32 freerdp_keyboard_get_scancode_from_keycode(uint32 keycode, boolean* extended) +{ + DEBUG_KBD("%2x %4s -> %d/%d", keycode, x_keycode_to_rdp_scancode[keycode].keyname, + x_keycode_to_rdp_scancode[keycode].extended, x_keycode_to_rdp_scancode[keycode].keycode); + + *extended = x_keycode_to_rdp_scancode[keycode].extended; + + return x_keycode_to_rdp_scancode[keycode].keycode; +} + +uint32 freerdp_keyboard_get_keycode_from_scancode(uint32 scancode, boolean extended) +{ + if (extended) + return rdp_scancode_to_x_keycode[scancode][1]; + else + return rdp_scancode_to_x_keycode[scancode][0]; +} + +uint32 freerdp_keyboard_get_scancode_from_vkcode(uint32 vkcode, boolean* extended) +{ + *extended = virtualKeyboard[vkcode].extended; + return virtualKeyboard[vkcode].scancode; +} diff --git a/libfreerdp-locale/layouts_xkb.h b/libfreerdp-locale/keyboard.h similarity index 70% rename from libfreerdp-locale/layouts_xkb.h rename to libfreerdp-locale/keyboard.h index dc0c7697e..d3ed6446d 100644 --- a/libfreerdp-locale/layouts_xkb.h +++ b/libfreerdp-locale/keyboard.h @@ -20,25 +20,17 @@ #ifndef __LAYOUTS_XKB_H #define __LAYOUTS_XKB_H +#include + typedef unsigned char KeycodeToVkcode[256]; typedef struct { - unsigned char extended; - unsigned char keycode; - char* keyname; + uint8 extended; + uint8 keycode; + const char* keyname; } RdpKeycodeRec, RdpScancodes[256]; -#ifdef WITH_XKBFILE - -int init_xkb(void *dpy); -unsigned int detect_keyboard_layout_from_xkb(void *dpy); -int init_keycodes_from_xkb(void* dpy, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]); - -#else - -void load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile); - -#endif +void freerdp_keyboard_load_maps(KeycodeToVkcode keycodeToVkcode, char* xkbfile); #endif diff --git a/libfreerdp-locale/x_layout_id_table.c b/libfreerdp-locale/keyboard_x11.c similarity index 91% rename from libfreerdp-locale/x_layout_id_table.c rename to libfreerdp-locale/keyboard_x11.c index 68060c68e..99828ea0d 100644 --- a/libfreerdp-locale/x_layout_id_table.c +++ b/libfreerdp-locale/keyboard_x11.c @@ -21,37 +21,30 @@ #include #include -#include "libkbd.h" +#include "liblocale.h" #include -#include "x_layout_id_table.h" +#include "keyboard_x11.h" -typedef struct +struct _XKB_VARIANT { - /* XKB Keyboard layout variant */ - const char* variant; + const char* variant; /* XKB Keyboard layout variant */ + uint32 keyboardLayoutID; /* Keyboard Layout ID */ +}; +typedef struct _XKB_VARIANT XKB_VARIANT; - /* Keyboard Layout ID */ - unsigned int keyboardLayoutID; - -} xkbVariant; - -typedef struct +struct _XKB_LAYOUT { - /* XKB Keyboard layout */ - const char* layout; - - /* Keyboard Layout ID */ - unsigned int keyboardLayoutID; - - const xkbVariant* variants; - -} xkbLayout; + const char* layout; /* XKB Keyboard layout */ + uint32 keyboardLayoutID; /* Keyboard Layout ID */ + const XKB_VARIANT* variants; +}; +typedef struct _XKB_LAYOUT XKB_LAYOUT; /* Those have been generated automatically and are waiting to be filled by hand */ /* USA */ -static const xkbVariant us_variants[] = +static const XKB_VARIANT us_variants[] = { { "chr", 0 }, /* Cherokee */ { "euro", 0 }, /* With EuroSign on 5 */ @@ -72,7 +65,7 @@ static const xkbVariant us_variants[] = }; /* Afghanistan */ -static const xkbVariant af_variants[] = +static const XKB_VARIANT af_variants[] = { { "ps", KBD_PASHTO }, /* Pashto */ { "uz", KBD_UZBEK_CYRILLIC }, /* Southern Uzbek */ @@ -83,7 +76,7 @@ static const xkbVariant af_variants[] = }; /* Arabic */ -static const xkbVariant ara_variants[] = +static const XKB_VARIANT ara_variants[] = { { "azerty", KBD_ARABIC_102_AZERTY }, /* azerty */ { "azerty_digits", KBD_ARABIC_102_AZERTY }, /* azerty/digits */ @@ -95,7 +88,7 @@ static const xkbVariant ara_variants[] = }; /* Armenia */ -static const xkbVariant am_variants[] = +static const XKB_VARIANT am_variants[] = { { "phonetic", 0 }, /* Phonetic */ { "phonetic-alt", 0 }, /* Alternative Phonetic */ @@ -106,14 +99,14 @@ static const xkbVariant am_variants[] = }; /* Azerbaijan */ -static const xkbVariant az_variants[] = +static const XKB_VARIANT az_variants[] = { { "cyrillic", KBD_AZERI_CYRILLIC }, /* Cyrillic */ { "", 0 }, }; /* Belarus */ -static const xkbVariant by_variants[] = +static const XKB_VARIANT by_variants[] = { { "winkeys", KBD_BELARUSIAN }, /* Winkeys */ { "latin", KBD_BELARUSIAN }, /* Latin */ @@ -121,7 +114,7 @@ static const xkbVariant by_variants[] = }; /* Belgium */ -static const xkbVariant be_variants[] = +static const XKB_VARIANT be_variants[] = { { "oss", KBD_BELGIAN_FRENCH }, /* Alternative */ { "oss_latin9", KBD_BELGIAN_FRENCH }, /* Alternative, latin-9 only */ @@ -134,14 +127,14 @@ static const xkbVariant be_variants[] = }; /* Bangladesh */ -static const xkbVariant bd_variants[] = +static const XKB_VARIANT bd_variants[] = { { "probhat", KBD_BENGALI_INSCRIPT }, /* Probhat */ { "", 0 }, }; /* India */ -static const xkbVariant in_variants[] = +static const XKB_VARIANT in_variants[] = { { "ben", KBD_BENGALI }, /* Bengali */ { "ben_probhat", KBD_BENGALI_INSCRIPT }, /* Bengali Probhat */ @@ -166,7 +159,7 @@ static const xkbVariant in_variants[] = }; /* Bosnia and Herzegovina */ -static const xkbVariant ba_variants[] = +static const XKB_VARIANT ba_variants[] = { { "alternatequotes", KBD_BOSNIAN }, /* Use guillemets for quotes */ { "unicode", KBD_BOSNIAN }, /* Use Bosnian digraphs */ @@ -176,7 +169,7 @@ static const xkbVariant ba_variants[] = }; /* Brazil */ -static const xkbVariant br_variants[] = +static const XKB_VARIANT br_variants[] = { { "nodeadkeys", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Eliminate dead keys */ { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ @@ -187,7 +180,7 @@ static const xkbVariant br_variants[] = }; /* Bulgaria */ -static const xkbVariant bg_variants[] = +static const XKB_VARIANT bg_variants[] = { { "phonetic", KBD_BULGARIAN_LATIN }, /* Traditional Phonetic */ { "bas_phonetic", KBD_BULGARIAN_LATIN }, /* Standard Phonetic */ @@ -195,7 +188,7 @@ static const xkbVariant bg_variants[] = }; /* Morocco */ -static const xkbVariant ma_variants[] = +static const XKB_VARIANT ma_variants[] = { { "french", KBD_FRENCH }, /* French */ { "tifinagh", 0 }, /* Tifinagh */ @@ -208,7 +201,7 @@ static const xkbVariant ma_variants[] = }; /* Canada */ -static const xkbVariant ca_variants[] = +static const XKB_VARIANT ca_variants[] = { { "fr-dvorak", KBD_UNITED_STATES_DVORAK }, /* French Dvorak */ { "fr-legacy", KBD_CANADIAN_FRENCH }, /* French (legacy) */ @@ -223,7 +216,7 @@ static const xkbVariant ca_variants[] = }; /* China */ -static const xkbVariant cn_variants[] = +static const XKB_VARIANT cn_variants[] = { { "tib", 0 }, /* Tibetan */ { "tib_asciinum", 0 }, /* Tibetan (with ASCII numerals) */ @@ -231,7 +224,7 @@ static const xkbVariant cn_variants[] = }; /* Croatia */ -static const xkbVariant hr_variants[] = +static const XKB_VARIANT hr_variants[] = { { "alternatequotes", KBD_CROATIAN }, /* Use guillemets for quotes */ { "unicode", KBD_CROATIAN }, /* Use Croatian digraphs */ @@ -241,7 +234,7 @@ static const xkbVariant hr_variants[] = }; /* Czechia */ -static const xkbVariant cz_variants[] = +static const XKB_VARIANT cz_variants[] = { { "bksl", KBD_CZECH_PROGRAMMERS }, /* With <\|> key */ { "qwerty", KBD_CZECH_QWERTY }, /* qwerty */ @@ -251,7 +244,7 @@ static const xkbVariant cz_variants[] = }; /* Denmark */ -static const xkbVariant dk_variants[] = +static const XKB_VARIANT dk_variants[] = { { "nodeadkeys", KBD_DANISH }, /* Eliminate dead keys */ { "mac", KBD_DANISH }, /* Macintosh */ @@ -261,7 +254,7 @@ static const xkbVariant dk_variants[] = }; /* Netherlands */ -static const xkbVariant nl_variants[] = +static const XKB_VARIANT nl_variants[] = { { "sundeadkeys", KBD_SWISS_FRENCH }, /* Sun dead keys */ { "mac", KBD_SWISS_FRENCH }, /* Macintosh */ @@ -270,7 +263,7 @@ static const xkbVariant nl_variants[] = }; /* Estonia */ -static const xkbVariant ee_variants[] = +static const XKB_VARIANT ee_variants[] = { { "nodeadkeys", KBD_US }, /* Eliminate dead keys */ { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ @@ -279,7 +272,7 @@ static const xkbVariant ee_variants[] = }; /* Iran */ -static const xkbVariant ir_variants[] = +static const XKB_VARIANT ir_variants[] = { { "pro", 0 }, /* Pro */ { "keypad", 0 }, /* Keypad */ @@ -292,7 +285,7 @@ static const xkbVariant ir_variants[] = }; /* Iraq */ -static const xkbVariant iq_variants[] = +static const XKB_VARIANT iq_variants[] = { { "ku", 0 }, /* Kurdish, Latin Q */ { "ku_f", 0 }, /* Kurdish, (F) */ @@ -302,14 +295,14 @@ static const xkbVariant iq_variants[] = }; /* Faroe Islands */ -static const xkbVariant fo_variants[] = +static const XKB_VARIANT fo_variants[] = { { "nodeadkeys", 0 }, /* Eliminate dead keys */ { "", 0 }, }; /* Finland */ -static const xkbVariant fi_variants[] = +static const XKB_VARIANT fi_variants[] = { { "nodeadkeys", 0 }, /* Eliminate dead keys */ { "smi", 0 }, /* Northern Saami */ @@ -319,7 +312,7 @@ static const xkbVariant fi_variants[] = }; /* France */ -static const xkbVariant fr_variants[] = +static const XKB_VARIANT fr_variants[] = { { "nodeadkeys", 0 }, /* Eliminate dead keys */ { "sundeadkeys", 0 }, /* Sun dead keys */ @@ -341,7 +334,7 @@ static const xkbVariant fr_variants[] = }; /* Ghana */ -static const xkbVariant gh_variants[] = +static const XKB_VARIANT gh_variants[] = { { "generic", 0 }, /* Multilingual */ { "akan", 0 }, /* Akan */ @@ -353,7 +346,7 @@ static const xkbVariant gh_variants[] = }; /* Georgia */ -static const xkbVariant ge_variants[] = +static const XKB_VARIANT ge_variants[] = { { "ergonomic", 0 }, /* Ergonomic */ { "mess", 0 }, /* MESS */ @@ -363,7 +356,7 @@ static const xkbVariant ge_variants[] = }; /* Germany */ -static const xkbVariant de_variants[] = +static const XKB_VARIANT de_variants[] = { { "deadacute", KBD_GERMAN }, /* Dead acute */ { "deadgraveacute", KBD_GERMAN }, /* Dead grave acute */ @@ -382,7 +375,7 @@ static const xkbVariant de_variants[] = }; /* Greece */ -static const xkbVariant gr_variants[] = +static const XKB_VARIANT gr_variants[] = { { "simple", KBD_GREEK_220 }, /* Simple */ { "extended", KBD_GREEK_319 }, /* Extended */ @@ -392,7 +385,7 @@ static const xkbVariant gr_variants[] = }; /* Hungary */ -static const xkbVariant hu_variants[] = +static const XKB_VARIANT hu_variants[] = { { "standard", KBD_HUNGARIAN_101_KEY }, /* Standard */ { "nodeadkeys", KBD_HUNGARIAN_101_KEY }, /* Eliminate dead keys */ @@ -417,7 +410,7 @@ static const xkbVariant hu_variants[] = }; /* Iceland */ -static const xkbVariant is_variants[] = +static const XKB_VARIANT is_variants[] = { { "Sundeadkeys", KBD_ICELANDIC }, /* Sun dead keys */ { "nodeadkeys", KBD_ICELANDIC }, /* Eliminate dead keys */ @@ -427,7 +420,7 @@ static const xkbVariant is_variants[] = }; /* Israel */ -static const xkbVariant il_variants[] = +static const XKB_VARIANT il_variants[] = { { "lyx", KBD_HEBREW }, /* lyx */ { "phonetic", KBD_HEBREW }, /* Phonetic */ @@ -436,7 +429,7 @@ static const xkbVariant il_variants[] = }; /* Italy */ -static const xkbVariant it_variants[] = +static const XKB_VARIANT it_variants[] = { { "nodeadkeys", KBD_ITALIAN_142 }, /* Eliminate dead keys */ { "mac", KBD_ITALIAN }, /* Macintosh */ @@ -445,7 +438,7 @@ static const xkbVariant it_variants[] = }; /* Japan */ -static const xkbVariant jp_variants[] = +static const XKB_VARIANT jp_variants[] = { { "kana", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Kana */ { "OADG109A", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* OADG 109A */ @@ -453,14 +446,14 @@ static const xkbVariant jp_variants[] = }; /* Kyrgyzstan */ -static const xkbVariant kg_variants[] = +static const XKB_VARIANT kg_variants[] = { { "phonetic", KBD_KYRGYZ_CYRILLIC }, /* Phonetic */ { "", 0 }, }; /* Kazakhstan */ -static const xkbVariant kz_variants[] = +static const XKB_VARIANT kz_variants[] = { { "ruskaz", KBD_KAZAKH }, /* Russian with Kazakh */ { "kazrus", KBD_KAZAKH }, /* Kazakh with Russian */ @@ -468,7 +461,7 @@ static const xkbVariant kz_variants[] = }; /* Latin America */ -static const xkbVariant latam_variants[] = +static const XKB_VARIANT latam_variants[] = { { "nodeadkeys", KBD_LATIN_AMERICAN }, /* Eliminate dead keys */ { "deadtilde", KBD_LATIN_AMERICAN }, /* Include dead tilde */ @@ -477,7 +470,7 @@ static const xkbVariant latam_variants[] = }; /* Lithuania */ -static const xkbVariant lt_variants[] = +static const XKB_VARIANT lt_variants[] = { { "std", KBD_LITHUANIAN }, /* Standard */ { "us", KBD_LITHUANIAN_IBM }, /* US keyboard with Lithuanian letters */ @@ -489,7 +482,7 @@ static const xkbVariant lt_variants[] = }; /* Latvia */ -static const xkbVariant lv_variants[] = +static const XKB_VARIANT lv_variants[] = { { "apostrophe", KBD_LATVIAN }, /* Apostrophe (') variant */ { "tilde", KBD_LATVIAN }, /* Tilde (~) variant */ @@ -498,7 +491,7 @@ static const xkbVariant lv_variants[] = }; /* Montenegro */ -static const xkbVariant me_variants[] = +static const XKB_VARIANT me_variants[] = { { "cyrillic", 0 }, /* Cyrillic */ { "cyrillicyz", 0 }, /* Cyrillic, Z and ZHE swapped */ @@ -511,21 +504,21 @@ static const xkbVariant me_variants[] = }; /* Macedonia */ -static const xkbVariant mk_variants[] = +static const XKB_VARIANT mk_variants[] = { { "nodeadkeys", KBD_FYRO_MACEDONIAN }, /* Eliminate dead keys */ { "", 0 }, }; /* Malta */ -static const xkbVariant mt_variants[] = +static const XKB_VARIANT mt_variants[] = { { "us", KBD_MALTESE_48_KEY }, /* Maltese keyboard with US layout */ { "", 0 }, }; /* Norway */ -static const xkbVariant no_variants[] = +static const XKB_VARIANT no_variants[] = { { "nodeadkeys", KBD_NORWEGIAN }, /* Eliminate dead keys */ { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ @@ -537,7 +530,7 @@ static const xkbVariant no_variants[] = }; /* Poland */ -static const xkbVariant pl_variants[] = +static const XKB_VARIANT pl_variants[] = { { "qwertz", KBD_POLISH_214 }, /* qwertz */ { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ @@ -549,7 +542,7 @@ static const xkbVariant pl_variants[] = }; /* Portugal */ -static const xkbVariant pt_variants[] = +static const XKB_VARIANT pt_variants[] = { { "nodeadkeys", KBD_PORTUGUESE }, /* Eliminate dead keys */ { "sundeadkeys", KBD_PORTUGUESE }, /* Sun dead keys */ @@ -563,7 +556,7 @@ static const xkbVariant pt_variants[] = }; /* Romania */ -static const xkbVariant ro_variants[] = +static const XKB_VARIANT ro_variants[] = { { "cedilla", KBD_ROMANIAN }, /* Cedilla */ { "std", KBD_ROMANIAN }, /* Standard */ @@ -577,7 +570,7 @@ static const xkbVariant ro_variants[] = }; /* Russia */ -static const xkbVariant ru_variants[] = +static const XKB_VARIANT ru_variants[] = { { "phonetic", KBD_RUSSIAN }, /* Phonetic */ { "phonetic_winkeys", KBD_RUSSIAN }, /* Phonetic Winkeys */ @@ -597,7 +590,7 @@ static const xkbVariant ru_variants[] = }; /* Serbia */ -static const xkbVariant rs_variants[] = +static const XKB_VARIANT rs_variants[] = { { "yz", KBD_SERBIAN_CYRILLIC }, /* Z and ZHE swapped */ { "latin", KBD_SERBIAN_LATIN }, /* Latin */ @@ -610,7 +603,7 @@ static const xkbVariant rs_variants[] = }; /* Slovenia */ -static const xkbVariant si_variants[] = +static const XKB_VARIANT si_variants[] = { { "alternatequotes", KBD_SLOVENIAN }, /* Use guillemets for quotes */ { "us", KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Slovenian letters */ @@ -618,7 +611,7 @@ static const xkbVariant si_variants[] = }; /* Slovakia */ -static const xkbVariant sk_variants[] = +static const XKB_VARIANT sk_variants[] = { { "bksl", KBD_SLOVAK }, /* Extended Backslash */ { "qwerty", KBD_SLOVAK_QWERTY }, /* qwerty */ @@ -627,7 +620,7 @@ static const xkbVariant sk_variants[] = }; /* Spain */ -static const xkbVariant es_variants[] = +static const XKB_VARIANT es_variants[] = { { "nodeadkeys", KBD_SPANISH_VARIATION }, /* Eliminate dead keys */ { "deadtilde", KBD_SPANISH_VARIATION }, /* Include dead tilde */ @@ -640,7 +633,7 @@ static const xkbVariant es_variants[] = }; /* Sweden */ -static const xkbVariant se_variants[] = +static const XKB_VARIANT se_variants[] = { { "nodeadkeys", KBD_SWEDISH }, /* Eliminate dead keys */ { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */ @@ -653,7 +646,7 @@ static const xkbVariant se_variants[] = }; /* Switzerland */ -static const xkbVariant ch_variants[] = +static const XKB_VARIANT ch_variants[] = { { "de_nodeadkeys", KBD_SWISS_GERMAN }, /* German, eliminate dead keys */ { "de_sundeadkeys", KBD_SWISS_GERMAN }, /* German, Sun dead keys */ @@ -666,7 +659,7 @@ static const xkbVariant ch_variants[] = }; /* Syria */ -static const xkbVariant sy_variants[] = +static const XKB_VARIANT sy_variants[] = { { "syc", KBD_SYRIAC }, /* Syriac */ { "syc_phonetic", KBD_SYRIAC_PHONETIC }, /* Syriac phonetic */ @@ -677,14 +670,14 @@ static const xkbVariant sy_variants[] = }; /* Tajikistan */ -static const xkbVariant tj_variants[] = +static const XKB_VARIANT tj_variants[] = { { "legacy", 0 }, /* Legacy */ { "", 0 }, }; /* Sri Lanka */ -static const xkbVariant lk_variants[] = +static const XKB_VARIANT lk_variants[] = { { "tam_unicode", KBD_TAMIL }, /* Tamil Unicode */ { "tam_TAB", KBD_TAMIL }, /* Tamil TAB Typewriter */ @@ -692,7 +685,7 @@ static const xkbVariant lk_variants[] = }; /* Thailand */ -static const xkbVariant th_variants[] = +static const XKB_VARIANT th_variants[] = { { "tis", KBD_THAI_KEDMANEE_NON_SHIFTLOCK }, /* TIS-820.2538 */ { "pat", KBD_THAI_PATTACHOTE }, /* Pattachote */ @@ -700,7 +693,7 @@ static const xkbVariant th_variants[] = }; /* Turkey */ -static const xkbVariant tr_variants[] = +static const XKB_VARIANT tr_variants[] = { { "f", KBD_TURKISH_F }, /* (F) */ { "alt", KBD_TURKISH_Q }, /* Alt-Q */ @@ -716,7 +709,7 @@ static const xkbVariant tr_variants[] = }; /* Ukraine */ -static const xkbVariant ua_variants[] = +static const XKB_VARIANT ua_variants[] = { { "phonetic", KBD_UKRAINIAN }, /* Phonetic */ { "typewriter", KBD_UKRAINIAN }, /* Typewriter */ @@ -732,7 +725,7 @@ static const xkbVariant ua_variants[] = }; /* United Kingdom */ -static const xkbVariant gb_variants[] = +static const XKB_VARIANT gb_variants[] = { { "extd", KBD_UNITED_KINGDOM_EXTENDED }, /* Extended - Winkeys */ { "intl", KBD_UNITED_KINGDOM_EXTENDED }, /* International (with dead keys) */ @@ -744,7 +737,7 @@ static const xkbVariant gb_variants[] = }; /* Uzbekistan */ -static const xkbVariant uz_variants[] = +static const XKB_VARIANT uz_variants[] = { { "latin", 0 }, /* Latin */ { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */ @@ -754,14 +747,14 @@ static const xkbVariant uz_variants[] = }; /* Korea, Republic of */ -static const xkbVariant kr_variants[] = +static const XKB_VARIANT kr_variants[] = { { "kr104", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* 101/104 key Compatible */ { "", 0 }, }; /* Ireland */ -static const xkbVariant ie_variants[] = +static const XKB_VARIANT ie_variants[] = { { "CloGaelach", KBD_GAELIC }, /* CloGaelach */ { "UnicodeExpert", KBD_GAELIC }, /* UnicodeExpert */ @@ -771,7 +764,7 @@ static const xkbVariant ie_variants[] = }; /* Pakistan */ -static const xkbVariant pk_variants[] = +static const XKB_VARIANT pk_variants[] = { { "urd-crulp", 0 }, /* CRULP */ { "urd-nla", 0 }, /* NLA */ @@ -780,14 +773,14 @@ static const xkbVariant pk_variants[] = }; /* Esperanto */ -static const xkbVariant epo_variants[] = +static const XKB_VARIANT epo_variants[] = { { "legacy", 0 }, /* displaced semicolon and quote (obsolete) */ { "", 0 }, }; /* Nigeria */ -static const xkbVariant ng_variants[] = +static const XKB_VARIANT ng_variants[] = { { "igbo", 0 }, /* Igbo */ { "yoruba", 0 }, /* Yoruba */ @@ -796,7 +789,7 @@ static const xkbVariant ng_variants[] = }; /* Braille */ -static const xkbVariant brai_variants[] = +static const XKB_VARIANT brai_variants[] = { { "left_hand", 0 }, /* Left hand */ { "right_hand", 0 }, /* Right hand */ @@ -804,13 +797,13 @@ static const xkbVariant brai_variants[] = }; /* Turkmenistan */ -static const xkbVariant tm_variants[] = +static const XKB_VARIANT tm_variants[] = { { "alt", KBD_TURKISH_Q }, /* Alt-Q */ { "", 0 }, }; -static const xkbLayout xkbLayouts[] = +static const XKB_LAYOUT xkbLayouts[] = { { "us", KBD_US, us_variants }, /* USA */ { "ad", 0, NULL }, /* Andorra */ @@ -917,22 +910,14 @@ static const xkbLayout xkbLayouts[] = * keyboard layout indicated by the index given (in this case, 33, or US-English). */ - -typedef struct _SunOSKeyboard +struct _SunOSKeyboard { - /* Sun keyboard type */ - int type; - - /* Layout */ - int layout; - - /* XKB keyboard */ - char* xkbType; - - /* XKB keyboard layout */ - unsigned int keyboardLayoutID; -} SunOSKeyboard; - + int type; /* Sun keyboard type */ + int layout; /* Layout */ + char* xkbType; /* XKB keyboard */ + uint32 keyboardLayoutID; /* XKB keyboard layout */ +}; +typedef struct _SunOSKeyboard SunOSKeyboard; static const SunOSKeyboard SunOSKeyboards[] = { @@ -1075,17 +1060,16 @@ static const SunOSKeyboard SunOSKeyboards[] = { 6, 272, "sun(type6)", KBD_PORTUGUESE_BRAZILIAN_ABNT } /* Brazil6_usb */ }; -unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant) +uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant) { - int i; - int j; + int i, j; if ((layout == NULL) || (variant == NULL)) return 0; DEBUG_KBD("xkbLayout: %s\txkbVariant: %s\n", layout, variant); - for (i = 0; i < sizeof(xkbLayouts) / sizeof(xkbLayout); i++) + for (i = 0; i < sizeof(xkbLayouts) / sizeof(XKB_LAYOUT); i++) { if (strcmp(xkbLayouts[i].layout, layout) == 0) { @@ -1104,9 +1088,9 @@ unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant) return 0; } -#if defined(sun) +#ifdef sun -unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) +uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) { FILE* kbd; @@ -1135,16 +1119,16 @@ unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length) if (kbd < 0) return 0; - while(fgets(buffer, sizeof(buffer), kbd) != NULL) + while (fgets(buffer, sizeof(buffer), kbd) != NULL) { - if((pch = strstr(buffer, "type=")) != NULL) + if ((pch = strstr(buffer, "type=")) != NULL) { beg = pch + sizeof("type=") - 1; end = strchr(beg, '\n'); end[0] = '\0'; type = atoi(beg); } - else if((pch = strstr(buffer, "layout=")) != NULL) + else if ((pch = strstr(buffer, "layout=")) != NULL) { beg = pch + sizeof("layout=") - 1; end = strchr(beg, ' '); @@ -1154,11 +1138,11 @@ unsigned int 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(SunOSKeyboards) / sizeof(SunOSKeyboard); i++) { - if(SunOSKeyboards[i].type == type) + if (SunOSKeyboards[i].type == type) { - if(SunOSKeyboards[i].layout == layout) + if (SunOSKeyboards[i].layout == layout) { strncpy(xkbfile, SunOSKeyboards[i].xkbType, length); return SunOSKeyboards[i].keyboardLayoutID; diff --git a/libfreerdp-locale/x_layout_id_table.h b/libfreerdp-locale/keyboard_x11.h similarity index 83% rename from libfreerdp-locale/x_layout_id_table.h rename to libfreerdp-locale/keyboard_x11.h index 11db11a12..1dc7e5704 100644 --- a/libfreerdp-locale/x_layout_id_table.h +++ b/libfreerdp-locale/keyboard_x11.h @@ -22,10 +22,10 @@ #ifndef __LAYOUTS_X_H #define __LAYOUTS_X_H -unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant); +uint32 find_keyboard_layout_in_xorg_rules(char* layout, char* variant); -#if defined(sun) -unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); +#ifdef sun +uint32 detect_keyboard_type_and_layout_sunos(char* xkbfile, int length); #endif #endif diff --git a/libfreerdp-locale/keyboard_xkb.c b/libfreerdp-locale/keyboard_xkb.c new file mode 100644 index 000000000..032652467 --- /dev/null +++ b/libfreerdp-locale/keyboard_xkb.c @@ -0,0 +1,166 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * 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. + * 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. + */ + +#include "liblocale.h" + +#include "keyboard_xkb.h" +#include "keyboard_x11.h" +#include + +extern const virtualKey virtualKeyboard[258]; + +#include +#include +#include +#include + +#include + +void* freerdp_keyboard_xkb_init() +{ + int status; + + Display* display = XOpenDisplay(NULL); + + if (display == NULL) + return NULL; + + status = XkbQueryExtension(display, NULL, NULL, NULL, NULL, NULL); + + if (!status) + return NULL; + + return (void*) display; +} + +/* return substring starting after nth comma, ending at following comma */ +static char* comma_substring(char* s, int n) +{ + char *p; + + if (!s) + return ""; + + while (n-- > 0) + { + if (!(p = strchr(s, ','))) + break; + + s = p + 1; + } + + if ((p = strchr(s, ','))) + *p = 0; + + return s; +} + +uint32 detect_keyboard_layout_from_xkb(void* display) +{ + char* layout; + char* variant; + uint32 group = 0; + uint32 keyboard_layout = 0; + XkbRF_VarDefsRec rules_names; + XKeyboardState coreKbdState; + XkbStateRec state; + + DEBUG_KBD("display: %p", display); + + if (display && XkbRF_GetNamesProp(display, NULL, &rules_names)) + { + DEBUG_KBD("layouts: %s", rules_names.layout ? rules_names.layout : ""); + DEBUG_KBD("variants: %s", rules_names.variant ? rules_names.variant : ""); + + XGetKeyboardControl(display, &coreKbdState); + + if (XkbGetState(display, XkbUseCoreKbd, &state) == Success) + group = state.group; + + DEBUG_KBD("group: %d", state.group); + + layout = comma_substring(rules_names.layout, group); + variant = comma_substring(rules_names.variant, group); + + DEBUG_KBD("layout: %s", layout ? layout : ""); + DEBUG_KBD("variant: %s", variant ? variant : ""); + + keyboard_layout = find_keyboard_layout_in_xorg_rules(layout, variant); + + xfree(rules_names.model); + xfree(rules_names.layout); + xfree(rules_names.variant); + xfree(rules_names.options); + } + + return keyboard_layout; +} + +int freerdp_keyboard_load_map_from_xkb(void* display, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]) +{ + int status = 0; + XkbDescPtr xkb; + + if (display && (xkb = XkbGetMap(display, 0, XkbUseCoreKbd))) + { + if (XkbGetNames(display, XkbKeyNamesMask, xkb) == Success) + { + int i, j; + char buf[5] = {42, 42, 42, 42, 0}; /* end-of-string at pos 5 */ + + for (i = xkb->min_key_code; i <= xkb->max_key_code; i++) + { + memcpy(buf, xkb->names->keys[i].name, 4); + + j = sizeof(virtualKeyboard) / sizeof(virtualKeyboard[0]) - 1; + + while (j >= 0) + { + if (virtualKeyboard[j].x_keyname && !strcmp(buf, virtualKeyboard[j].x_keyname)) + break; + j--; + } + + if (j >= 0) + { + DEBUG_KBD("X keycode %3d has keyname %-4s -> RDP scancode %d/%d", + i, buf, virtualKeyboard[j].extended, virtualKeyboard[j].scancode); + + x_keycode_to_rdp_scancode[i].extended = virtualKeyboard[j].extended; + x_keycode_to_rdp_scancode[i].keycode = virtualKeyboard[j].scancode; + x_keycode_to_rdp_scancode[i].keyname = virtualKeyboard[j].x_keyname; + + if (x_keycode_to_rdp_scancode[i].extended) + rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][1] = i; + else + rdp_scancode_to_x_keycode[virtualKeyboard[j].scancode][0] = i; + } + else + { + DEBUG_KBD("X key code %3d has keyname %-4s -> ??? - not found", i, buf); + } + } + status = 1; + } + + XkbFreeKeyboard(xkb, 0, 1); + } + + return status; +} diff --git a/libfreerdp-locale/keyboard_xkb.h b/libfreerdp-locale/keyboard_xkb.h new file mode 100644 index 000000000..b7041e155 --- /dev/null +++ b/libfreerdp-locale/keyboard_xkb.h @@ -0,0 +1,26 @@ +/** + * FreeRDP: A Remote Desktop Protocol Client + * XKB-based Keyboard Mapping to Microsoft Keyboard System + * + * 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. + * 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. + */ + +#include + +#include "keyboard.h" + +void* freerdp_keyboard_xkb_init(); +uint32 detect_keyboard_layout_from_xkb(void* display); +int freerdp_keyboard_load_map_from_xkb(void* display, RdpScancodes x_keycode_to_rdp_scancode, uint8 rdp_scancode_to_x_keycode[256][2]); diff --git a/libfreerdp-locale/layouts.c b/libfreerdp-locale/layouts.c index 3f6660746..8fb90f1f8 100644 --- a/libfreerdp-locale/layouts.c +++ b/libfreerdp-locale/layouts.c @@ -20,19 +20,19 @@ #include #include #include -#include "libkbd.h" +#include "liblocale.h" +#include +#include +#include #include -typedef struct +struct _keyboardLayout { - /* Keyboard layout code */ - unsigned int code; - - /* Keyboard layout name */ - char name[50]; - -} keyboardLayout; + uint32 code; /* Keyboard layout code */ + const char* name; /* Keyboard layout name */ +}; +typedef struct _keyboardLayout keyboardLayout; /* * In Windows XP, this information is available in the system registry at @@ -127,21 +127,14 @@ static const keyboardLayout keyboardLayouts[] = { KBD_BOSNIAN_CYRILLIC, "Bosnian Cyrillic" } }; - typedef struct { - /* Keyboard layout code */ - unsigned int code; - - /* Keyboard variant ID */ - unsigned short id; - - /* Keyboard layout variant name */ - char name[50]; + uint32 code; /* Keyboard layout code */ + uint16 id; /* Keyboard variant ID */ + const char* name; /* Keyboard layout variant name */ } keyboardLayoutVariant; - static const keyboardLayoutVariant keyboardLayoutVariants[] = { { KBD_ARABIC_102, 0x0028, "Arabic (102)" }, @@ -193,14 +186,9 @@ static const keyboardLayoutVariant keyboardLayoutVariants[] = typedef struct { - /* Keyboard layout code */ - unsigned int code; - - /* IME file name */ - char fileName[32]; - - /* Keyboard layout name */ - char name[50]; + uint32 code; /* Keyboard layout code */ + const char* fileName; /* IME file name */ + const char* name; /* Keyboard layout name */ } keyboardIME; @@ -228,20 +216,284 @@ static const keyboardIME keyboardIMEs[] = { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" } }; - -rdpKeyboardLayout* get_keyboard_layouts(int types) +const virtualKey virtualKeyboard[] = { - int num, len, i; - rdpKeyboardLayout * layouts; + { 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" } +}; + +rdpKeyboardLayout* get_keyboard_layouts(uint32 types) +{ + int num, length, i; + rdpKeyboardLayout* layouts; num = 0; - layouts = (rdpKeyboardLayout *) malloc((num + 1) * sizeof(rdpKeyboardLayout)); + layouts = (rdpKeyboardLayout*) xmalloc((num + 1) * sizeof(rdpKeyboardLayout)); if ((types & RDP_KEYBOARD_LAYOUT_TYPE_STANDARD) != 0) { - len = sizeof(keyboardLayouts) / sizeof(keyboardLayout); - layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); - for (i = 0; i < len; i++, num++) + length = sizeof(keyboardLayouts) / sizeof(keyboardLayout); + + layouts = (rdpKeyboardLayout *) xrealloc(layouts, (num + length + 1) * sizeof(rdpKeyboardLayout)); + + for (i = 0; i < length; i++, num++) { layouts[num].code = keyboardLayouts[i].code; strcpy(layouts[num].name, keyboardLayouts[i].name); @@ -249,9 +501,10 @@ rdpKeyboardLayout* get_keyboard_layouts(int types) } if ((types & RDP_KEYBOARD_LAYOUT_TYPE_VARIANT) != 0) { - len = sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); - layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); - for (i = 0; i < len; i++, num++) + length = sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); + layouts = (rdpKeyboardLayout *) xrealloc(layouts, (num + length + 1) * sizeof(rdpKeyboardLayout)); + + for (i = 0; i < length; i++, num++) { layouts[num].code = keyboardLayoutVariants[i].code; strcpy(layouts[num].name, keyboardLayoutVariants[i].name); @@ -259,10 +512,10 @@ rdpKeyboardLayout* get_keyboard_layouts(int types) } if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0) { - len = sizeof(keyboardIMEs) / sizeof(keyboardIME); - layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout)); + length = sizeof(keyboardIMEs) / sizeof(keyboardIME); + layouts = (rdpKeyboardLayout *) realloc(layouts, (num + length + 1) * sizeof(rdpKeyboardLayout)); - for (i = 0; i < len; i++, num++) + for (i = 0; i < length; i++, num++) { layouts[num].code = keyboardIMEs[i].code; strcpy(layouts[num].name, keyboardIMEs[i].name); @@ -274,7 +527,7 @@ rdpKeyboardLayout* get_keyboard_layouts(int types) return layouts; } -const char* get_layout_name(unsigned int keyboardLayoutID) +const char* get_layout_name(uint32 keyboardLayoutID) { int i; diff --git a/libfreerdp-locale/libkbd.c b/libfreerdp-locale/libkbd.c deleted file mode 100644 index b29bfbf48..000000000 --- a/libfreerdp-locale/libkbd.c +++ /dev/null @@ -1,168 +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. - */ - -#include -#include -#include -#include -#include - -#include "libkbd.h" - -#include -#include -#include -#include "layouts_xkb.h" - -/* - * 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. - */ - -RdpScancodes x_keycode_to_rdp_scancode; - -uint8 rdp_scancode_to_x_keycode[256][2]; - -#ifndef WITH_XKBFILE - -static unsigned int detect_keyboard(void* dpy, unsigned int keyboardLayoutID, char* xkbfile, size_t xkbfilelength) -{ - xkbfile[0] = '\0'; - - if (keyboardLayoutID != 0) - DEBUG_KBD("keyboard layout configuration: %X", keyboardLayoutID); - -#if defined(sun) - if (keyboardLayoutID == 0) - { - keyboardLayoutID = detect_keyboard_type_and_layout_sunos(xkbfile, xkbfilelength); - DEBUG_KBD("detect_keyboard_type_and_layout_sunos: %X %s", keyboardLayoutID, xkbfile); - } -#endif - - if (keyboardLayoutID == 0) - { - keyboardLayoutID = detect_keyboard_layout_from_locale(); - DEBUG_KBD("detect_keyboard_layout_from_locale: %X", keyboardLayoutID); - } - - if (keyboardLayoutID == 0) - { - keyboardLayoutID = 0x0409; - DEBUG_KBD("using default keyboard layout: %X", keyboardLayoutID); - } - - if (xkbfile[0] == '\0') - { - strncpy(xkbfile, "base", xkbfilelength); - DEBUG_KBD("using default keyboard layout: %s", xkbfile); - } - - return keyboardLayoutID; -} - -#endif - -/* - * Initialize global keyboard mapping and return the suggested server side layout. - * dpy must be a X Display* or NULL. - */ - -unsigned int freerdp_kbd_init(void* dpy, unsigned int keyboard_layout_id) -{ - memset(x_keycode_to_rdp_scancode, 0, sizeof(x_keycode_to_rdp_scancode)); - memset(rdp_scancode_to_x_keycode, '\0', sizeof(rdp_scancode_to_x_keycode)); - -#ifdef WITH_XKBFILE - if (!init_xkb(dpy)) - { - DEBUG_KBD("Error initializing xkb"); - return 0; - } - if (keyboard_layout_id == 0) - { - keyboard_layout_id = detect_keyboard_layout_from_xkb(dpy); - DEBUG_KBD("detect_keyboard_layout_from_xkb: %X", keyboard_layout_id); - } - init_keycodes_from_xkb(dpy, x_keycode_to_rdp_scancode, rdp_scancode_to_x_keycode); -#else - int vkcode; - int keycode; - char xkbfile[256]; - KeycodeToVkcode keycodeToVkcode; - - if (keyboard_layout_id == 0) - keyboard_layout_id = detect_keyboard(dpy, keyboard_layout_id, xkbfile, sizeof(xkbfile)); - - DEBUG_KBD("Using keyboard layout 0x%X with xkb name %s and xkbfile %s", - keyboard_layout_id, get_layout_name(keyboard_layout_id), xkbfile); - - load_keyboard_map(keycodeToVkcode, xkbfile); - - 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); - - x_keycode_to_rdp_scancode[keycode].keycode = virtualKeyboard[vkcode].scancode; - x_keycode_to_rdp_scancode[keycode].extended = virtualKeyboard[vkcode].extended; - x_keycode_to_rdp_scancode[keycode].keyname = virtualKeyboard[vkcode].name; - - if (x_keycode_to_rdp_scancode[keycode].extended) - rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][1] = keycode; - else - rdp_scancode_to_x_keycode[virtualKeyboard[vkcode].scancode][0] = keycode; - } -#endif - - return keyboard_layout_id; -} - -rdpKeyboardLayout* freerdp_kbd_get_layouts(int types) -{ - return get_keyboard_layouts(types); -} - -uint8 freerdp_kbd_get_scancode_by_keycode(uint8 keycode, boolean* extended) -{ - DEBUG_KBD("%2x %4s -> %d/%d", keycode, x_keycode_to_rdp_scancode[keycode].keyname, - x_keycode_to_rdp_scancode[keycode].extended, x_keycode_to_rdp_scancode[keycode].keycode); - - *extended = x_keycode_to_rdp_scancode[keycode].extended; - - return x_keycode_to_rdp_scancode[keycode].keycode; -} - -uint8 freerdp_kbd_get_keycode_by_scancode(uint8 scancode, boolean extended) -{ - if (extended) - return rdp_scancode_to_x_keycode[scancode][1]; - else - return rdp_scancode_to_x_keycode[scancode][0]; -} - -uint8 freerdp_kbd_get_scancode_by_virtualkey(int vkcode, boolean* extended) -{ - *extended = virtualKeyboard[vkcode].extended; - return virtualKeyboard[vkcode].scancode; -} diff --git a/libfreerdp-locale/libkbd.h b/libfreerdp-locale/liblocale.h similarity index 100% rename from libfreerdp-locale/libkbd.h rename to libfreerdp-locale/liblocale.h diff --git a/libfreerdp-locale/locales.c b/libfreerdp-locale/locale.c similarity index 98% rename from libfreerdp-locale/locales.c rename to libfreerdp-locale/locale.c index 4003b2821..0e3f2eab6 100644 --- a/libfreerdp-locale/locales.c +++ b/libfreerdp-locale/locale.c @@ -20,22 +20,17 @@ #include #include #include -#include "libkbd.h" +#include "liblocale.h" #include -typedef struct +struct _locale { - /* Two or three letter language code */ - char language[4]; - - /* Two or three letter country code (Sometimes with Cyrl_ prefix) */ - char country[10]; - - /* 32-bit unsigned integer corresponding to the locale */ - unsigned int code; - -} locale; + char language[4]; /* Two or three letter language code */ + char country[10]; /* Two or three letter country code (Sometimes with Cyrl_ prefix) */ + uint32 code; /* 32-bit unsigned integer corresponding to the locale */ +}; +typedef struct _locale locale; /* * Refer to MSDN article "Locale Identifier Constants and Strings": @@ -421,7 +416,7 @@ static const localeAndKeyboardLayout defaultKeyboardLayouts[] = { XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } }, }; -unsigned int detect_keyboard_layout_from_locale() +uint32 detect_keyboard_layout_from_locale() { int dot; int i, j, k; diff --git a/libfreerdp-utils/CMakeLists.txt b/libfreerdp-utils/CMakeLists.txt index 6757afcd8..52b15690d 100644 --- a/libfreerdp-utils/CMakeLists.txt +++ b/libfreerdp-utils/CMakeLists.txt @@ -49,8 +49,6 @@ set(FREERDP_UTILS_SRCS unicode.c wait_obj.c) -add_definitions(-DPLUGIN_PATH="${FREERDP_PLUGIN_PATH}") - add_library(freerdp-utils ${FREERDP_UTILS_SRCS}) set_target_properties(freerdp-utils PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib") diff --git a/libfreerdp-utils/load_plugin.c b/libfreerdp-utils/load_plugin.c index adab66eef..720906146 100644 --- a/libfreerdp-utils/load_plugin.c +++ b/libfreerdp-utils/load_plugin.c @@ -25,6 +25,8 @@ #include #include +#include "config.h" + #ifdef _WIN32 #include @@ -128,7 +130,7 @@ void* freerdp_load_plugin(const char* name, const char* entry_name) if (!freerdp_path_contains_separator(suffixed_name)) { /* no explicit path given, use default path */ - path = freerdp_construct_path(PLUGIN_PATH, suffixed_name); + path = freerdp_construct_path(FREERDP_PLUGIN_PATH, suffixed_name); } else { @@ -164,7 +166,7 @@ void* freerdp_load_channel_plugin(rdpSettings* settings, const char* name, const if (!settings->development_mode) { - path = freerdp_construct_path(PLUGIN_PATH, suffixed_name); + path = freerdp_construct_path(FREERDP_PLUGIN_PATH, suffixed_name); } else { diff --git a/server/X11/xf_input.c b/server/X11/xf_input.c index 8f87a1a24..a013c7be9 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_kbd_get_keycode_by_scancode(code, extended); + keycode = freerdp_keyboard_get_keycode_from_scancode(code, extended); if (keycode != 0) { diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index b60944410..6886d00cb 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -249,7 +249,7 @@ xfInfo* xf_info_init() xfi->bytesPerPixel = 4; - freerdp_kbd_init(xfi->display, 0); + freerdp_keyboard_init(0); return xfi; }