mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-locale: refactoring step 1
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define __LAYOUT_IDS_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
/* 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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/locale/layouts.h>
|
||||
|
||||
/* 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 */
|
||||
|
||||
@@ -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 "*")
|
||||
|
||||
|
||||
@@ -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 <otavio@ossystems.com.br>
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
@@ -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 <marcandre.moreau@gmail.com>
|
||||
*
|
||||
@@ -21,144 +21,133 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WITH_XKBFILE
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBfile.h>
|
||||
#include <X11/extensions/XKBrules.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/file.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
#include "liblocale.h"
|
||||
|
||||
#ifdef WITH_XKB
|
||||
#include "keyboard_xkb.h"
|
||||
#endif
|
||||
|
||||
#include "libkbd.h"
|
||||
#include <freerdp/locale/locales.h>
|
||||
#include <freerdp/locale/vkcodes.h>
|
||||
#include "x_layout_id_table.h"
|
||||
#include <freerdp/locale/layouts.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -20,25 +20,17 @@
|
||||
#ifndef __LAYOUTS_XKB_H
|
||||
#define __LAYOUTS_XKB_H
|
||||
|
||||
#include <freerdp/types.h>
|
||||
|
||||
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
|
||||
@@ -21,37 +21,30 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libkbd.h"
|
||||
#include "liblocale.h"
|
||||
#include <freerdp/locale/layouts.h>
|
||||
|
||||
#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;
|
||||
@@ -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
|
||||
166
libfreerdp-locale/keyboard_xkb.c
Normal file
166
libfreerdp-locale/keyboard_xkb.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* XKB-based Keyboard Mapping to Microsoft Keyboard System
|
||||
*
|
||||
* Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 <freerdp/locale/vkcodes.h>
|
||||
|
||||
extern const virtualKey virtualKeyboard[258];
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <X11/extensions/XKBfile.h>
|
||||
#include <X11/extensions/XKBrules.h>
|
||||
|
||||
#include <freerdp/utils/memory.h>
|
||||
|
||||
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;
|
||||
}
|
||||
26
libfreerdp-locale/keyboard_xkb.h
Normal file
26
libfreerdp-locale/keyboard_xkb.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* XKB-based Keyboard Mapping to Microsoft Keyboard System
|
||||
*
|
||||
* Copyright 2009-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 <freerdp/types.h>
|
||||
|
||||
#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]);
|
||||
@@ -20,19 +20,19 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libkbd.h"
|
||||
#include "liblocale.h"
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/locale/vkcodes.h>
|
||||
#include <freerdp/locale/layouts.h>
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Client
|
||||
* XKB-based Keyboard Mapping to Microsoft Keyboard System
|
||||
*
|
||||
* Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/locale/keyboard.h>
|
||||
|
||||
#include "libkbd.h"
|
||||
|
||||
#include <freerdp/locale/locales.h>
|
||||
#include <freerdp/locale/vkcodes.h>
|
||||
#include <freerdp/locale/layouts.h>
|
||||
#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;
|
||||
}
|
||||
@@ -20,22 +20,17 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "libkbd.h"
|
||||
#include "liblocale.h"
|
||||
|
||||
#include <freerdp/locale/locales.h>
|
||||
|
||||
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;
|
||||
@@ -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")
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/load_plugin.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -249,7 +249,7 @@ xfInfo* xf_info_init()
|
||||
|
||||
xfi->bytesPerPixel = 4;
|
||||
|
||||
freerdp_kbd_init(xfi->display, 0);
|
||||
freerdp_keyboard_init(0);
|
||||
|
||||
return xfi;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user