libfreerdp-kbd: initial commit

This commit is contained in:
Marc-André Moreau 2011-06-30 15:55:03 -04:00
parent f6723028dc
commit ed3a7a7627
11 changed files with 3755 additions and 0 deletions

587
libfreerdp-kbd/keyboard.h Normal file
View File

@ -0,0 +1,587 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* Microsoft Virtual Key Code Definitions and Conversion Tables
*
* 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.
*/
/* Microsoft Windows Virtual Key Codes: http://msdn.microsoft.com/en-us/library/ms645540.aspx */
#ifndef __KEYBOARD_H
#define __KEYBOARD_H
#include <stddef.h>
#include "layout_ids.h"
/* Mouse buttons */
#define VK_LBUTTON 0x01 /* Left mouse button */
#define VK_RBUTTON 0x02 /* Right mouse button */
#define VK_CANCEL 0x03 /* Control-break processing */
#define VK_MBUTTON 0x04 /* Middle mouse button (three-button mouse) */
#define VK_XBUTTON1 0x05 /* Windows 2000/XP: X1 mouse button */
#define VK_XBUTTON2 0x06 /* Windows 2000/XP: X2 mouse button */
/* 0x07 is undefined */
#define VK_BACK 0x08 /* BACKSPACE key */
#define VK_TAB 0x09 /* TAB key */
/* 0x0A to 0x0B are reserved */
#define VK_CLEAR 0x0C /* CLEAR key */
#define VK_RETURN 0x0D /* ENTER key */
/* 0x0E to 0x0F are undefined */
#define VK_SHIFT 0x10 /* SHIFT key */
#define VK_CONTROL 0x11 /* CTRL key */
#define VK_MENU 0x12 /* ALT key */
#define VK_PAUSE 0x13 /* PAUSE key */
#define VK_CAPITAL 0x14 /* CAPS LOCK key */
#define VK_KANA 0x15 /* Input Method Editor (IME) Kana mode */
#define VK_HANGUEL 0x15 /* IME Hanguel mode (maintained for compatibility; use #define VK_HANGUL) */
#define VK_HANGUL 0x15 /* IME Hangul mode */
/* 0x16 is undefined */
#define VK_JUNJA 0x17 /* IME Junja mode */
#define VK_FINAL 0x18 /* IME final mode */
#define VK_HANJA 0x19 /* IME Hanja mode */
#define VK_KANJI 0x19 /* IME Kanji mode */
/* 0x1A is undefined */
#define VK_ESCAPE 0x1B /* ESC key */
#define VK_CONVERT 0x1C /* IME convert */
#define VK_NONCONVERT 0x1D /* IME nonconvert */
#define VK_ACCEPT 0x1E /* IME accept */
#define VK_MODECHANGE 0x1F /* IME mode change request */
#define VK_SPACE 0x20 /* SPACEBAR */
#define VK_PRIOR 0x21 /* PAGE UP key */
#define VK_NEXT 0x22 /* PAGE DOWN key */
#define VK_END 0x23 /* END key */
#define VK_HOME 0x24 /* HOME key */
#define VK_LEFT 0x25 /* LEFT ARROW key */
#define VK_UP 0x26 /* UP ARROW key */
#define VK_RIGHT 0x27 /* RIGHT ARROW key */
#define VK_DOWN 0x28 /* DOWN ARROW key */
#define VK_SELECT 0x29 /* SELECT key */
#define VK_PRINT 0x2A /* PRINT key */
#define VK_EXECUTE 0x2B /* EXECUTE key */
#define VK_SNAPSHOT 0x2C /* PRINT SCREEN key */
#define VK_INSERT 0x2D /* INS key */
#define VK_DELETE 0x2E /* DEL key */
#define VK_HELP 0x2F /* HELP key */
/* Digits, the last 4 bits of the code represent the corresponding digit */
#define VK_KEY_0 0x30 /* '0' key */
#define VK_KEY_1 0x31 /* '1' key */
#define VK_KEY_2 0x32 /* '2' key */
#define VK_KEY_3 0x33 /* '3' key */
#define VK_KEY_4 0x34 /* '4' key */
#define VK_KEY_5 0x35 /* '5' key */
#define VK_KEY_6 0x36 /* '6' key */
#define VK_KEY_7 0x37 /* '7' key */
#define VK_KEY_8 0x38 /* '8' key */
#define VK_KEY_9 0x39 /* '9' key */
/* 0x3A to 0x40 are undefined */
/* The alphabet, the code corresponds to the capitalized letter in the ASCII code */
#define VK_KEY_A 0x41 /* 'A' key */
#define VK_KEY_B 0x42 /* 'B' key */
#define VK_KEY_C 0x43 /* 'C' key */
#define VK_KEY_D 0x44 /* 'D' key */
#define VK_KEY_E 0x45 /* 'E' key */
#define VK_KEY_F 0x46 /* 'F' key */
#define VK_KEY_G 0x47 /* 'G' key */
#define VK_KEY_H 0x48 /* 'H' key */
#define VK_KEY_I 0x49 /* 'I' key */
#define VK_KEY_J 0x4A /* 'J' key */
#define VK_KEY_K 0x4B /* 'K' key */
#define VK_KEY_L 0x4C /* 'L' key */
#define VK_KEY_M 0x4D /* 'M' key */
#define VK_KEY_N 0x4E /* 'N' key */
#define VK_KEY_O 0x4F /* 'O' key */
#define VK_KEY_P 0x50 /* 'P' key */
#define VK_KEY_Q 0x51 /* 'Q' key */
#define VK_KEY_R 0x52 /* 'R' key */
#define VK_KEY_S 0x53 /* 'S' key */
#define VK_KEY_T 0x54 /* 'T' key */
#define VK_KEY_U 0x55 /* 'U' key */
#define VK_KEY_V 0x56 /* 'V' key */
#define VK_KEY_W 0x57 /* 'W' key */
#define VK_KEY_X 0x58 /* 'X' key */
#define VK_KEY_Y 0x59 /* 'Y' key */
#define VK_KEY_Z 0x5A /* 'Z' key */
#define VK_LWIN 0x5B /* Left Windows key (Microsoft Natural keyboard) */
#define VK_RWIN 0x5C /* Right Windows key (Natural keyboard) */
#define VK_APPS 0x5D /* Applications key (Natural keyboard) */
/* 0x5E is reserved */
#define VK_SLEEP 0x5F /* Computer Sleep key */
/* Numeric keypad digits, the last four bits of the code represent the corresponding digit */
#define VK_NUMPAD0 0x60 /* Numeric keypad '0' key */
#define VK_NUMPAD1 0x61 /* Numeric keypad '1' key */
#define VK_NUMPAD2 0x62 /* Numeric keypad '2' key */
#define VK_NUMPAD3 0x63 /* Numeric keypad '3' key */
#define VK_NUMPAD4 0x64 /* Numeric keypad '4' key */
#define VK_NUMPAD5 0x65 /* Numeric keypad '5' key */
#define VK_NUMPAD6 0x66 /* Numeric keypad '6' key */
#define VK_NUMPAD7 0x67 /* Numeric keypad '7' key */
#define VK_NUMPAD8 0x68 /* Numeric keypad '8' key */
#define VK_NUMPAD9 0x69 /* Numeric keypad '9' key */
/* Numeric keypad operators and special keys */
#define VK_MULTIPLY 0x6A /* Multiply key */
#define VK_ADD 0x6B /* Add key */
#define VK_SEPARATOR 0x6C /* Separator key */
#define VK_SUBTRACT 0x6D /* Subtract key */
#define VK_DECIMAL 0x6E /* Decimal key */
#define VK_DIVIDE 0x6F /* Divide key */
/* Function keys, from F1 to F24 */
#define VK_F1 0x70 /* F1 key */
#define VK_F2 0x71 /* F2 key */
#define VK_F3 0x72 /* F3 key */
#define VK_F4 0x73 /* F4 key */
#define VK_F5 0x74 /* F5 key */
#define VK_F6 0x75 /* F6 key */
#define VK_F7 0x76 /* F7 key */
#define VK_F8 0x77 /* F8 key */
#define VK_F9 0x78 /* F9 key */
#define VK_F10 0x79 /* F10 key */
#define VK_F11 0x7A /* F11 key */
#define VK_F12 0x7B /* F12 key */
#define VK_F13 0x7C /* F13 key */
#define VK_F14 0x7D /* F14 key */
#define VK_F15 0x7E /* F15 key */
#define VK_F16 0x7F /* F16 key */
#define VK_F17 0x80 /* F17 key */
#define VK_F18 0x81 /* F18 key */
#define VK_F19 0x82 /* F19 key */
#define VK_F20 0x83 /* F20 key */
#define VK_F21 0x84 /* F21 key */
#define VK_F22 0x85 /* F22 key */
#define VK_F23 0x86 /* F23 key */
#define VK_F24 0x87 /* F24 key */
/* 0x88 to 0x8F are unassigned */
#define VK_NUMLOCK 0x90 /* NUM LOCK key */
#define VK_SCROLL 0x91 /* SCROLL LOCK key */
/* 0x92 to 0x96 are OEM specific */
/* 0x97 to 0x9F are unassigned */
/* Modifier keys */
#define VK_LSHIFT 0xA0 /* Left SHIFT key */
#define VK_RSHIFT 0xA1 /* Right SHIFT key */
#define VK_LCONTROL 0xA2 /* Left CONTROL key */
#define VK_RCONTROL 0xA3 /* Right CONTROL key */
#define VK_LMENU 0xA4 /* Left MENU key */
#define VK_RMENU 0xA5 /* Right MENU key */
/* Browser related keys */
#define VK_BROWSER_BACK 0xA6 /* Windows 2000/XP: Browser Back key */
#define VK_BROWSER_FORWARD 0xA7 /* Windows 2000/XP: Browser Forward key */
#define VK_BROWSER_REFRESH 0xA8 /* Windows 2000/XP: Browser Refresh key */
#define VK_BROWSER_STOP 0xA9 /* Windows 2000/XP: Browser Stop key */
#define VK_BROWSER_SEARCH 0xAA /* Windows 2000/XP: Browser Search key */
#define VK_BROWSER_FAVORITES 0xAB /* Windows 2000/XP: Browser Favorites key */
#define VK_BROWSER_HOME 0xAC /* Windows 2000/XP: Browser Start and Home key */
/* Volume related keys */
#define VK_VOLUME_MUTE 0xAD /* Windows 2000/XP: Volume Mute key */
#define VK_VOLUME_DOWN 0xAE /* Windows 2000/XP: Volume Down key */
#define VK_VOLUME_UP 0xAF /* Windows 2000/XP: Volume Up key */
/* Media player related keys */
#define VK_MEDIA_NEXT_TRACK 0xB0 /* Windows 2000/XP: Next Track key */
#define VK_MEDIA_PREV_TRACK 0xB1 /* Windows 2000/XP: Previous Track key */
#define VK_MEDIA_STOP 0xB2 /* Windows 2000/XP: Stop Media key */
#define VK_MEDIA_PLAY_PAUSE 0xB3 /* Windows 2000/XP: Play/Pause Media key */
/* Application launcher keys */
#define VK_LAUNCH_MAIL 0xB4 /* Windows 2000/XP: Start Mail key */
#define VK_LAUNCH_MEDIA_SELECT 0xB5 /* Windows 2000/XP: Select Media key */
#define VK_LAUNCH_APP1 0xB6 /* Windows 2000/XP: Start Application 1 key */
#define VK_LAUNCH_APP2 0xB7 /* Windows 2000/XP: Start Application 2 key */
/* 0xB8 and 0xB9 are reserved */
/* OEM keys */
#define VK_OEM_1 0xBA /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ';:' key */
#define VK_OEM_PLUS 0xBB /* Windows 2000/XP: For any country/region, the '+' key */
#define VK_OEM_COMMA 0xBC /* Windows 2000/XP: For any country/region, the ',' key */
#define VK_OEM_MINUS 0xBD /* Windows 2000/XP: For any country/region, the '-' key */
#define VK_OEM_PERIOD 0xBE /* Windows 2000/XP: For any country/region, the '.' key */
#define VK_OEM_2 0xBF /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '/?' key */
#define VK_OEM_3 0xC0 /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '`~' key */
/* 0xC1 to 0xD7 are reserved */
#define VK_ABNT_C1 0xC1 /* Brazilian (ABNT) Keyboard */
#define VK_ABNT_C2 0xC2 /* Brazilian (ABNT) Keyboard */
/* 0xD8 to 0xDA are unassigned */
#define VK_OEM_4 0xDB /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '[{' key */
#define VK_OEM_5 0xDC /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the '\|' key */
#define VK_OEM_6 0xDD /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the ']}' key */
#define VK_OEM_7 0xDE /* Used for miscellaneous characters; it can vary by keyboard. */
/* Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key */
#define VK_OEM_8 0xDF /* Used for miscellaneous characters; it can vary by keyboard. */
/* 0xE0 is reserved */
/* 0xE1 is OEM specific */
#define VK_OEM_102 0xE2 /* Windows 2000/XP: Either the angle bracket key or */
/* the backslash key on the RT 102-key keyboard */
/* 0xE3 and 0xE4 are OEM specific */
#define VK_PROCESSKEY 0xE5 /* Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key */
/* 0xE6 is OEM specific */
#define VK_PACKET 0xE7 /* Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. */
/* The #define VK_PACKET key is the low word of a 32-bit Virtual Key value used */
/* for non-keyboard input methods. For more information, */
/* see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP */
/* 0xE8 is unassigned */
/* 0xE9 to 0xF5 are OEM specific */
#define VK_ATTN 0xF6 /* Attn key */
#define VK_CRSEL 0xF7 /* CrSel key */
#define VK_EXSEL 0xF8 /* ExSel key */
#define VK_EREOF 0xF9 /* Erase EOF key */
#define VK_PLAY 0xFA /* Play key */
#define VK_ZOOM 0xFB /* Zoom key */
#define VK_NONAME 0xFC /* Reserved */
#define VK_PA1 0xFD /* PA1 key */
#define VK_OEM_CLEAR 0xFE /* Clear key */
/* Use the virtual key code as an index in this array in order to get its associated scan code */
typedef 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" },
{ 0x00, 0, "VK_KANA / VK_HANGUL" , NULL },
{ 0x00, 0, "" , NULL },
{ 0x00, 0, "VK_JUNJA" , NULL },
{ 0x00, 0, "VK_FINAL" , NULL },
{ 0x00, 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, 1, "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" },
};
#endif /* __KEYBOARD_H */

301
libfreerdp-kbd/layout_ids.c Normal file
View File

@ -0,0 +1,301 @@
/**
* 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 "libkbd.h"
#include "layout_ids.h"
typedef struct
{
/* Keyboard layout code */
unsigned int code;
/* Keyboard layout name */
char name[50];
} keyboardLayout;
/*
* In Windows XP, this information is available in the system registry at
* HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet001/Control/Keyboard Layouts/
*/
keyboardLayout keyboardLayouts[] =
{
{ KBD_ARABIC_101, "Arabic (101)" },
{ KBD_BULGARIAN, "Bulgarian" },
{ KBD_CHINESE_TRADITIONAL_US, "Chinese (Traditional) - US Keyboard" },
{ KBD_CZECH, "Czech" },
{ KBD_DANISH, "Danish" },
{ KBD_GERMAN, "German" },
{ KBD_GREEK, "Greek" },
{ KBD_US, "US" },
{ KBD_SPANISH, "Spanish" },
{ KBD_FINNISH, "Finnish" },
{ KBD_FRENCH, "French" },
{ KBD_HEBREW, "Hebrew" },
{ KBD_HUNGARIAN, "Hungarian" },
{ KBD_ICELANDIC, "Icelandic" },
{ KBD_ITALIAN, "Italian" },
{ KBD_JAPANESE, "Japanese" },
{ KBD_KOREAN, "Korean" },
{ KBD_DUTCH, "Dutch" },
{ KBD_NORWEGIAN, "Norwegian" },
{ KBD_POLISH_PROGRAMMERS, "Polish (Programmers)" },
{ KBD_PORTUGUESE_BRAZILIAN_ABNT,"Portuguese (Brazilian ABNT)" },
{ KBD_ROMANIAN, "Romanian" },
{ KBD_RUSSIAN, "Russian" },
{ KBD_CROATIAN, "Croatian" },
{ KBD_SLOVAK, "Slovak" },
{ KBD_ALBANIAN, "Albanian" },
{ KBD_SWEDISH, "Swedish" },
{ KBD_THAI_KEDMANEE, "Thai Kedmanee" },
{ KBD_TURKISH_Q, "Turkish Q" },
{ KBD_URDU, "Urdu" },
{ KBD_UKRAINIAN, "Ukrainian" },
{ KBD_BELARUSIAN, "Belarusian" },
{ KBD_SLOVENIAN, "Slovenian" },
{ KBD_ESTONIAN, "Estonian" },
{ KBD_LATVIAN, "Latvian" },
{ KBD_LITHUANIAN_IBM, "Lithuanian IBM" },
{ KBD_FARSI, "Farsi" },
{ KBD_VIETNAMESE, "Vietnamese" },
{ KBD_ARMENIAN_EASTERN, "Armenian Eastern" },
{ KBD_AZERI_LATIN, "Azeri Latin" },
{ KBD_FYRO_MACEDONIAN, "FYRO Macedonian" },
{ KBD_GEORGIAN, "Georgian" },
{ KBD_FAEROESE, "Faeroese" },
{ KBD_DEVANAGARI_INSCRIPT, "Devanagari - INSCRIPT" },
{ KBD_MALTESE_47_KEY, "Maltese 47-key" },
{ KBD_NORWEGIAN_WITH_SAMI, "Norwegian with Sami" },
{ KBD_KAZAKH, "Kazakh" },
{ KBD_KYRGYZ_CYRILLIC, "Kyrgyz Cyrillic" },
{ KBD_TATAR, "Tatar" },
{ KBD_BENGALI, "Bengali" },
{ KBD_PUNJABI, "Punjabi" },
{ KBD_GUJARATI, "Gujarati" },
{ KBD_TAMIL, "Tamil" },
{ KBD_TELUGU, "Telugu" },
{ KBD_KANNADA, "Kannada" },
{ KBD_MALAYALAM, "Malayalam" },
{ KBD_MARATHI, "Marathi" },
{ KBD_MONGOLIAN_CYRILLIC, "Mongolian Cyrillic" },
{ KBD_UNITED_KINGDOM_EXTENDED, "United Kingdom Extended" },
{ KBD_SYRIAC, "Syriac" },
{ KBD_NEPALI, "Nepali" },
{ KBD_PASHTO, "Pashto" },
{ KBD_DIVEHI_PHONETIC, "Divehi Phonetic" },
{ KBD_LUXEMBOURGISH, "Luxembourgish" },
{ KBD_MAORI, "Maori" },
{ KBD_CHINESE_SIMPLIFIED_US, "Chinese (Simplified) - US Keyboard" },
{ KBD_SWISS_GERMAN, "Swiss German" },
{ KBD_UNITED_KINGDOM, "United Kingdom" },
{ KBD_LATIN_AMERICAN, "Latin American" },
{ KBD_BELGIAN_FRENCH, "Belgian French" },
{ KBD_BELGIAN_PERIOD, "Belgian (Period)" },
{ KBD_PORTUGUESE, "Portuguese" },
{ KBD_SERBIAN_LATIN, "Serbian (Latin)" },
{ KBD_AZERI_CYRILLIC, "Azeri Cyrillic" },
{ KBD_SWEDISH_WITH_SAMI, "Swedish with Sami" },
{ KBD_UZBEK_CYRILLIC, "Uzbek Cyrillic" },
{ KBD_INUKTITUT_LATIN, "Inuktitut Latin" },
{ KBD_CANADIAN_FRENCH_LEGACY, "Canadian French (legacy)" },
{ KBD_SERBIAN_CYRILLIC, "Serbian (Cyrillic)" },
{ KBD_CANADIAN_FRENCH, "Canadian French" },
{ KBD_SWISS_FRENCH, "Swiss French" },
{ KBD_BOSNIAN, "Bosnian" },
{ KBD_IRISH, "Irish" },
{ 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];
} keyboardLayoutVariant;
keyboardLayoutVariant keyboardLayoutVariants[] =
{
{ KBD_ARABIC_102, 0x0028, "Arabic (102)" },
{ KBD_BULGARIAN_LATIN, 0x0004, "Bulgarian (Latin)" },
{ KBD_CZECH_QWERTY, 0x0005, "Czech (QWERTY)" },
{ KBD_GERMAN_IBM, 0x0012, "German (IBM)" },
{ KBD_GREEK_220, 0x0016, "Greek (220)" },
{ KBD_UNITED_STATES_DVORAK, 0x0002, "United States-Dvorak" },
{ KBD_SPANISH_VARIATION, 0x0086, "Spanish Variation" },
{ KBD_HUNGARIAN_101_KEY, 0x0006, "Hungarian 101-key" },
{ KBD_ITALIAN_142, 0x0003, "Italian (142)" },
{ KBD_POLISH_214, 0x0007, "Polish (214)" },
{ KBD_PORTUGUESE_BRAZILIAN_ABNT2, 0x001D, "Portuguese (Brazilian ABNT2)" },
{ KBD_RUSSIAN_TYPEWRITER, 0x0008, "Russian (Typewriter)" },
{ KBD_SLOVAK_QWERTY, 0x0013, "Slovak (QWERTY)" },
{ KBD_THAI_PATTACHOTE, 0x0021, "Thai Pattachote" },
{ KBD_TURKISH_F, 0x0014, "Turkish F" },
{ KBD_LATVIAN_QWERTY, 0x0015, "Latvian (QWERTY)" },
{ KBD_LITHUANIAN, 0x0027, "Lithuanian" },
{ KBD_ARMENIAN_WESTERN, 0x0025, "Armenian Western" },
{ KBD_HINDI_TRADITIONAL, 0x000C, "Hindi Traditional" },
{ KBD_MALTESE_48_KEY, 0x002B, "Maltese 48-key" },
{ KBD_SAMI_EXTENDED_NORWAY, 0x002C, "Sami Extended Norway" },
{ KBD_BENGALI_INSCRIPT, 0x002A, "Bengali (Inscript)" },
{ KBD_SYRIAC_PHONETIC, 0x000E, "Syriac Phonetic" },
{ KBD_DIVEHI_TYPEWRITER, 0x000D, "Divehi Typewriter" },
{ KBD_BELGIAN_COMMA, 0x001E, "Belgian (Comma)" },
{ KBD_FINNISH_WITH_SAMI, 0x002D, "Finnish with Sami" },
{ KBD_CANADIAN_MULTILINGUAL_STANDARD, 0x0020, "Canadian Multilingual Standard" },
{ KBD_GAELIC, 0x0026, "Gaelic" },
{ KBD_ARABIC_102_AZERTY, 0x0029, "Arabic (102) AZERTY" },
{ KBD_CZECH_PROGRAMMERS, 0x000A, "Czech Programmers" },
{ KBD_GREEK_319, 0x0018, "Greek (319)" },
{ KBD_UNITED_STATES_INTERNATIONAL, 0x0001, "United States-International" },
{ KBD_THAI_KEDMANEE_NON_SHIFTLOCK, 0x0022, "Thai Kedmanee (non-ShiftLock)" },
{ KBD_SAMI_EXTENDED_FINLAND_SWEDEN, 0x002E, "Sami Extended Finland-Sweden" },
{ KBD_GREEK_220_LATIN, 0x0017, "Greek (220) Latin" },
{ KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND, 0x001A, "United States-Dvorak for left hand" },
{ KBD_THAI_PATTACHOTE_NON_SHIFTLOCK, 0x0023, "Thai Pattachote (non-ShiftLock)" },
{ KBD_GREEK_319_LATIN, 0x0011, "Greek (319) Latin" },
{ KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND, 0x001B, "United States-Dvorak for right hand" },
{ KBD_GREEK_LATIN, 0x0019, "Greek Latin" },
{ KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L, 0x000B, "US English Table for IBM Arabic 238_L" },
{ KBD_GREEK_POLYTONIC, 0x001F, "Greek Polytonic" },
{ KBD_GERMAN_NEO, 0x00C0, "German Neo" }
};
/* Input Method Editor (IME) */
typedef struct
{
/* Keyboard layout code */
unsigned int code;
/* IME file name */
char fileName[32];
/* Keyboard layout name */
char name[50];
} keyboardIME;
/* Global Input Method Editors (IME) */
keyboardIME keyboardIMEs[] =
{
{ KBD_CHINESE_TRADITIONAL_PHONETIC, "phon.ime", "Chinese (Traditional) - Phonetic" },
{ KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, "imjp81.ime", "Japanese Input System (MS-IME2002)" },
{ KBD_KOREAN_INPUT_SYSTEM_IME_2000, "imekr61.ime", "Korean Input System (IME 2000)" },
{ KBD_CHINESE_SIMPLIFIED_QUANPIN, "winpy.ime", "Chinese (Simplified) - QuanPin" },
{ KBD_CHINESE_TRADITIONAL_CHANGJIE, "chajei.ime", "Chinese (Traditional) - ChangJie" },
{ KBD_CHINESE_SIMPLIFIED_SHUANGPIN, "winsp.ime", "Chinese (Simplified) - ShuangPin" },
{ KBD_CHINESE_TRADITIONAL_QUICK, "quick.ime", "Chinese (Traditional) - Quick" },
{ KBD_CHINESE_SIMPLIFIED_ZHENGMA, "winzm.ime", "Chinese (Simplified) - ZhengMa" },
{ KBD_CHINESE_TRADITIONAL_BIG5_CODE, "winime.ime", "Chinese (Traditional) - Big5 Code" },
{ KBD_CHINESE_TRADITIONAL_ARRAY, "winar30.ime", "Chinese (Traditional) - Array" },
{ KBD_CHINESE_SIMPLIFIED_NEIMA, "wingb.ime", "Chinese (Simplified) - NeiMa" },
{ KBD_CHINESE_TRADITIONAL_DAYI, "dayi.ime", "Chinese (Traditional) - DaYi" },
{ KBD_CHINESE_TRADITIONAL_UNICODE, "unicdime.ime", "Chinese (Traditional) - Unicode" },
{ KBD_CHINESE_TRADITIONAL_NEW_PHONETIC, "TINTLGNT.IME", "Chinese (Traditional) - New Phonetic" },
{ KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE, "CINTLGNT.IME", "Chinese (Traditional) - New ChangJie" },
{ KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3, "pintlgnt.ime", "Chinese (Traditional) - Microsoft Pinyin IME 3.0" },
{ KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" }
};
rdpKeyboardLayout *
get_keyboard_layouts(int types)
{
rdpKeyboardLayout * layouts;
int num;
int len;
int i;
num = 0;
layouts = (rdpKeyboardLayout *) malloc((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++)
{
layouts[num].code = keyboardLayouts[i].code;
strcpy(layouts[num].name, keyboardLayouts[i].name);
}
}
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++)
{
layouts[num].code = keyboardLayoutVariants[i].code;
strcpy(layouts[num].name, keyboardLayoutVariants[i].name);
}
}
if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0)
{
len = sizeof(keyboardIMEs) / sizeof(keyboardIME);
layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
for (i = 0; i < len; i++, num++)
{
layouts[num].code = keyboardIMEs[i].code;
strcpy(layouts[num].name, keyboardIMEs[i].name);
}
}
memset(&layouts[num], 0, sizeof(rdpKeyboardLayout));
return layouts;
}
char *
get_layout_name(unsigned int keyboardLayoutID)
{
int i;
for(i = 0; i < sizeof(keyboardLayouts) / sizeof(keyboardLayout); i++)
if(keyboardLayouts[i].code == keyboardLayoutID)
{
return keyboardLayouts[i].name;
}
for(i = 0; i < sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); i++)
if(keyboardLayoutVariants[i].code == keyboardLayoutID)
{
return keyboardLayoutVariants[i].name;
}
for(i = 0; i < sizeof(keyboardIMEs) / sizeof(keyboardIME); i++)
if(keyboardIMEs[i].code == keyboardLayoutID)
{
return keyboardIMEs[i].name;
}
return "unknown";
}

186
libfreerdp-kbd/layout_ids.h Normal file
View File

@ -0,0 +1,186 @@
/**
* 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.
*/
/* Keyboard layout IDs used in the RDP protocol */
#ifndef __LAYOUT_IDS_H
#define __LAYOUT_IDS_H
#include <freerdp/kbd.h>
/* Keyboard layout IDs */
#define KBD_ARABIC_101 0x00000401
#define KBD_BULGARIAN 0x00000402
#define KBD_CHINESE_TRADITIONAL_US 0x00000404
#define KBD_CZECH 0x00000405
#define KBD_DANISH 0x00000406
#define KBD_GERMAN 0x00000407
#define KBD_GREEK 0x00000408
#define KBD_US 0x00000409
#define KBD_SPANISH 0x0000040A
#define KBD_FINNISH 0x0000040B
#define KBD_FRENCH 0x0000040C
#define KBD_HEBREW 0x0000040D
#define KBD_HUNGARIAN 0x0000040E
#define KBD_ICELANDIC 0x0000040F
#define KBD_ITALIAN 0x00000410
#define KBD_JAPANESE 0x00000411
#define KBD_KOREAN 0x00000412
#define KBD_DUTCH 0x00000413
#define KBD_NORWEGIAN 0x00000414
#define KBD_POLISH_PROGRAMMERS 0x00000415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT 0x00000416
#define KBD_ROMANIAN 0x00000418
#define KBD_RUSSIAN 0x00000419
#define KBD_CROATIAN 0x0000041A
#define KBD_SLOVAK 0x0000041B
#define KBD_ALBANIAN 0x0000041C
#define KBD_SWEDISH 0x0000041D
#define KBD_THAI_KEDMANEE 0x0000041E
#define KBD_TURKISH_Q 0x0000041F
#define KBD_URDU 0x00000420
#define KBD_UKRAINIAN 0x00000422
#define KBD_BELARUSIAN 0x00000423
#define KBD_SLOVENIAN 0x00000424
#define KBD_ESTONIAN 0x00000425
#define KBD_LATVIAN 0x00000426
#define KBD_LITHUANIAN_IBM 0x00000427
#define KBD_FARSI 0x00000429
#define KBD_VIETNAMESE 0x0000042A
#define KBD_ARMENIAN_EASTERN 0x0000042B
#define KBD_AZERI_LATIN 0x0000042C
#define KBD_FYRO_MACEDONIAN 0x0000042F
#define KBD_GEORGIAN 0x00000437
#define KBD_FAEROESE 0x00000438
#define KBD_DEVANAGARI_INSCRIPT 0x00000439
#define KBD_MALTESE_47_KEY 0x0000043A
#define KBD_NORWEGIAN_WITH_SAMI 0x0000043B
#define KBD_KAZAKH 0x0000043F
#define KBD_KYRGYZ_CYRILLIC 0x00000440
#define KBD_TATAR 0x00000444
#define KBD_BENGALI 0x00000445
#define KBD_PUNJABI 0x00000446
#define KBD_GUJARATI 0x00000447
#define KBD_TAMIL 0x00000449
#define KBD_TELUGU 0x0000044A
#define KBD_KANNADA 0x0000044B
#define KBD_MALAYALAM 0x0000044C
#define KBD_MARATHI 0x0000044E
#define KBD_MONGOLIAN_CYRILLIC 0x00000450
#define KBD_UNITED_KINGDOM_EXTENDED 0x00000452
#define KBD_SYRIAC 0x0000045A
#define KBD_NEPALI 0x00000461
#define KBD_PASHTO 0x00000463
#define KBD_DIVEHI_PHONETIC 0x00000465
#define KBD_LUXEMBOURGISH 0x0000046E
#define KBD_MAORI 0x00000481
#define KBD_CHINESE_SIMPLIFIED_US 0x00000804
#define KBD_SWISS_GERMAN 0x00000807
#define KBD_UNITED_KINGDOM 0x00000809
#define KBD_LATIN_AMERICAN 0x0000080A
#define KBD_BELGIAN_FRENCH 0x0000080C
#define KBD_BELGIAN_PERIOD 0x00000813
#define KBD_PORTUGUESE 0x00000816
#define KBD_SERBIAN_LATIN 0x0000081A
#define KBD_AZERI_CYRILLIC 0x0000082C
#define KBD_SWEDISH_WITH_SAMI 0x0000083B
#define KBD_UZBEK_CYRILLIC 0x00000843
#define KBD_INUKTITUT_LATIN 0x0000085D
#define KBD_CANADIAN_FRENCH_LEGACY 0x00000C0C
#define KBD_SERBIAN_CYRILLIC 0x00000C1A
#define KBD_CANADIAN_FRENCH 0x00001009
#define KBD_SWISS_FRENCH 0x0000100C
#define KBD_BOSNIAN 0x0000141A
#define KBD_IRISH 0x00001809
#define KBD_BOSNIAN_CYRILLIC 0x0000201A
/* Keyboard layout variant IDs */
#define KBD_ARABIC_102 0x00010401
#define KBD_BULGARIAN_LATIN 0x00010402
#define KBD_CZECH_QWERTY 0x00010405
#define KBD_GERMAN_IBM 0x00010407
#define KBD_GREEK_220 0x00010408
#define KBD_UNITED_STATES_DVORAK 0x00010409
#define KBD_SPANISH_VARIATION 0x0001040A
#define KBD_HUNGARIAN_101_KEY 0x0001040E
#define KBD_ITALIAN_142 0x00010410
#define KBD_POLISH_214 0x00010415
#define KBD_PORTUGUESE_BRAZILIAN_ABNT2 0x00010416
#define KBD_RUSSIAN_TYPEWRITER 0x00010419
#define KBD_SLOVAK_QWERTY 0x0001041B
#define KBD_THAI_PATTACHOTE 0x0001041E
#define KBD_TURKISH_F 0x0001041F
#define KBD_LATVIAN_QWERTY 0x00010426
#define KBD_LITHUANIAN 0x00010427
#define KBD_ARMENIAN_WESTERN 0x0001042B
#define KBD_HINDI_TRADITIONAL 0x00010439
#define KBD_MALTESE_48_KEY 0x0001043A
#define KBD_SAMI_EXTENDED_NORWAY 0x0001043B
#define KBD_BENGALI_INSCRIPT 0x00010445
#define KBD_SYRIAC_PHONETIC 0x0001045A
#define KBD_DIVEHI_TYPEWRITER 0x00010465
#define KBD_BELGIAN_COMMA 0x0001080C
#define KBD_FINNISH_WITH_SAMI 0x0001083B
#define KBD_CANADIAN_MULTILINGUAL_STANDARD 0x00011009
#define KBD_GAELIC 0x00011809
#define KBD_ARABIC_102_AZERTY 0x00020401
#define KBD_CZECH_PROGRAMMERS 0x00020405
#define KBD_GREEK_319 0x00020408
#define KBD_UNITED_STATES_INTERNATIONAL 0x00020409
#define KBD_THAI_KEDMANEE_NON_SHIFTLOCK 0x0002041E
#define KBD_SAMI_EXTENDED_FINLAND_SWEDEN 0x0002083B
#define KBD_GREEK_220_LATIN 0x00030408
#define KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND 0x00030409
#define KBD_THAI_PATTACHOTE_NON_SHIFTLOCK 0x0003041E
#define KBD_GREEK_319_LATIN 0x00040408
#define KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND 0x00040409
#define KBD_GREEK_LATIN 0x00050408
#define KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L 0x00050409
#define KBD_GREEK_POLYTONIC 0x00060408
#define KBD_GERMAN_NEO 0xB0000407
/* Global Input Method Editor (IME) IDs */
#define KBD_CHINESE_TRADITIONAL_PHONETIC 0xE0010404
#define KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 0xE0010411
#define KBD_KOREAN_INPUT_SYSTEM_IME_2000 0xE0010412
#define KBD_CHINESE_SIMPLIFIED_QUANPIN 0xE0010804
#define KBD_CHINESE_TRADITIONAL_CHANGJIE 0xE0020404
#define KBD_CHINESE_SIMPLIFIED_SHUANGPIN 0xE0020804
#define KBD_CHINESE_TRADITIONAL_QUICK 0xE0030404
#define KBD_CHINESE_SIMPLIFIED_ZHENGMA 0xE0030804
#define KBD_CHINESE_TRADITIONAL_BIG5_CODE 0xE0040404
#define KBD_CHINESE_TRADITIONAL_ARRAY 0xE0050404
#define KBD_CHINESE_SIMPLIFIED_NEIMA 0xE0050804
#define KBD_CHINESE_TRADITIONAL_DAYI 0xE0060404
#define KBD_CHINESE_TRADITIONAL_UNICODE 0xE0070404
#define KBD_CHINESE_TRADITIONAL_NEW_PHONETIC 0xE0080404
#define KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE 0xE0090404
#define KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3 0xE00E0804
#define KBD_CHINESE_TRADITIONAL_ALPHANUMERIC 0xE00F0404
rdpKeyboardLayout *
get_keyboard_layouts(int types);
char *
get_layout_name(unsigned int keyboardLayoutID);
#endif

View File

@ -0,0 +1,400 @@
/**
* 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 "config.h"
#include "libkbd.h"
#include "keyboard.h"
#include "x_layout_id_table.h"
#include "layouts_xkb.h"
#ifdef WITH_XKBFILE
#include <X11/XKBlib.h>
#include <X11/extensions/XKBfile.h>
#include <X11/extensions/XKBrules.h>
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 (!(p = strchr(s, ',')))
break;
s = p + 1;
}
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))
{
DEBUG_KBD("layouts: %s", rules_names.layout);
DEBUG_KBD("variants: %s", 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);
DEBUG_KBD("variant: %s", 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);
}
return keyboard_layout;
}
int
init_keycodes_from_xkb(void *dpy, RdpKeycodes x_keycode_to_rdp_keycode)
{
int ret = 0;
XkbDescPtr xkb;
if (dpy && (xkb = XkbGetMap(dpy, 0, XkbUseCoreKbd)))
{
if (XkbGetNames(dpy, XkbKeyNamesMask, xkb) == Success)
{
char buf[5] = {42, 42, 42, 42, 0}; /* end-of-string at pos 5 */
int i, j;
memset(x_keycode_to_rdp_keycode, 0, sizeof(x_keycode_to_rdp_keycode));
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 key code %3d has keyname %-4s -> RDP keycode %d/%d",
i, buf, virtualKeyboard[j].extended, virtualKeyboard[j].scancode);
x_keycode_to_rdp_keycode[i].extended = virtualKeyboard[j].extended;
x_keycode_to_rdp_keycode[i].keycode = virtualKeyboard[j].scancode;
#ifdef WITH_DEBUG_KBD
x_keycode_to_rdp_keycode[i].keyname = virtualKeyboard[j].x_keyname;
#endif
}
else
DEBUG_KBD("X key code %3d has keyname %-4s -> ??? - not found", i, buf);
}
ret = 1;
}
XkbFreeKeyboard(xkb, 0, 1);
}
return ret;
}
#else
/* Default built-in keymap */
static const KeycodeToVkcode defaultKeycodeToVkcode =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
0x37, 0x38, 0x39, 0x30, 0xBD, 0xBB, 0x08, 0x09, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49,
0x4F, 0x50, 0xDB, 0xDD, 0x0D, 0xA2, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0xBA,
0xDE, 0xC0, 0xA0, 0x00, 0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0xBC, 0xBE, 0xBF, 0xA1, 0x6A,
0x12, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x67,
0x68, 0x69, 0x6D, 0x64, 0x65, 0x66, 0x6B, 0x61, 0x62, 0x63, 0x60, 0x6E, 0x00, 0x00, 0x00, 0x7A,
0x7B, 0x24, 0x26, 0x21, 0x25, 0x00, 0x27, 0x23, 0x28, 0x22, 0x2D, 0x2E, 0x0D, 0xA3, 0x13, 0x2C,
0x6F, 0x12, 0x00, 0x5B, 0x5C, 0x5D, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
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)
{
char* pch;
char *beg, *end;
char* home;
char buffer[1024] = "";
char xkbfile[256] = "";
char xkbfilepath[512] = "";
char xkbmap[256] = "";
char xkbinc[256] = "";
FILE* fp;
int kbdFound = 0;
int i = 0;
int keycode = 0;
char keycodeString[32] = "";
char vkcodeName[128] = "";
beg = kbd;
/* Extract file name and keymap name */
if((end = strrchr(kbd, '(')) != NULL)
{
strncpy(xkbfile, &kbd[beg - kbd], end - beg);
beg = end + 1;
if((end = strrchr(kbd, ')')) != NULL)
{
strncpy(xkbmap, &kbd[beg - kbd], end - beg);
xkbmap[end - beg] = '\0';
}
}
else
{
/* The keyboard name is the same as the file name */
strcpy(xkbfile, kbd);
strcpy(xkbmap, 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);
/*
* 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.
*/
if((fp = fopen(xkbfilepath, "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 source tree, the keymaps will be in the parent directory */
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;
}
}
}
}
}
}
DEBUG_KBD("xkbfilepath: %s", xkbfilepath);
while(fgets(buffer, sizeof(buffer), fp) != NULL)
{
if(buffer[0] == '#')
{
continue; /* Skip comments */
}
if(kbdFound)
{
/* Closing curly bracket and semicolon */
if((pch = strstr(buffer, "};")) != NULL)
{
break;
}
else if((pch = strstr(buffer, "VK_")) != NULL)
{
/* The end is delimited by the first white space */
end = strcspn(pch, " \t\n\0") + pch;
/* We copy the virtual key code name in a string */
beg = pch;
strncpy(vkcodeName, beg, end - beg);
vkcodeName[end - beg] = '\0';
/* Now we want to extract the virtual key code itself which is in between '<' and '>' */
if((beg = strchr(pch + 3, '<')) == NULL)
break;
else
beg++;
if((end = strchr(beg, '>')) == NULL)
break;
/* We copy the string representing the number in a string */
strncpy(keycodeString, beg, end - beg);
keycodeString[end - beg] = '\0';
/* Convert the string representing the code to an integer */
keycode = atoi(keycodeString);
/* Make sure it is a valid keycode */
if(keycode < 0 || keycode > 255)
break;
/* Load this key mapping in the keyboard mapping */
for(i = 0; i < sizeof(virtualKeyboard) / sizeof(virtualKey); i++)
{
if(strcmp(vkcodeName, virtualKeyboard[i].name) == 0)
{
map[keycode] = i;
}
}
}
else if((pch = strstr(buffer, ": extends")) != NULL)
{
/*
* This map extends another keymap We extract its name
* and we recursively load the keymap we need to include.
*/
if((beg = strchr(pch + sizeof(": extends"), '"')) == NULL)
break;
beg++;
if((end = strchr(beg, '"')) == NULL)
break;
strncpy(xkbinc, beg, end - beg);
xkbinc[end - beg] = '\0';
load_xkb_keyboard(map, xkbinc); /* Load included keymap */
}
}
else if((pch = strstr(buffer, "keyboard")) != NULL)
{
/* Keyboard map identifier */
if((beg = strchr(pch + sizeof("keyboard"), '"')) == NULL)
break;
beg++;
if((end = strchr(beg, '"')) == NULL)
break;
pch = beg;
buffer[end - beg] = '\0';
/* Does it match our keymap name? */
if(strncmp(xkbmap, pch, strlen(xkbmap)) == 0)
kbdFound = 1;
}
}
fclose(fp); /* Don't forget to close file */
return 1;
}
void
load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile)
{
char* kbd;
char* xkbfileEnd;
int keymapLoaded = 0;
memset(keycodeToVkcode, 0, sizeof(keycodeToVkcode));
kbd = xkbfile;
xkbfileEnd = xkbfile + strlen(xkbfile);
#ifdef __APPLE__
/* Apple X11 breaks XKB detection */
keymapLoaded += load_xkb_keyboard(keycodeToVkcode, "macosx(macosx)");
#else
do
{
/* Multiple maps are separated by '+' */
int kbdlen = strcspn(kbd + 1, "+") + 1;
kbd[kbdlen] = '\0';
/* Load keyboard map */
keymapLoaded += load_xkb_keyboard(keycodeToVkcode, kbd);
kbd += kbdlen + 1;
}
while (kbd < xkbfileEnd);
#endif
DEBUG_KBD("loaded %d keymaps", keymapLoaded);
if(keymapLoaded <= 0)
{
/* No keymap was loaded, load default hard-coded keymap */
DEBUG_KBD("using default keymap");
memcpy(keycodeToVkcode, defaultKeycodeToVkcode, sizeof(keycodeToVkcode));
}
}
#endif

View File

@ -0,0 +1,54 @@
/**
* 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.
*/
#ifndef __LAYOUTS_XKB_H
#define __LAYOUTS_XKB_H
#include "config.h"
typedef unsigned char KeycodeToVkcode[256];
typedef struct
{
unsigned char extended;
unsigned char keycode;
#ifdef WITH_DEBUG_KBD
char *keyname;
#endif
} RdpKeycodeRec, RdpKeycodes[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, RdpKeycodes x_keycode_to_rdp_keycode);
#else
void
load_keyboard_map(KeycodeToVkcode keycodeToVkcode, char *xkbfile);
#endif
#endif

152
libfreerdp-kbd/libkbd.c Normal file
View File

@ -0,0 +1,152 @@
/**
* 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/freerdp.h>
#include <freerdp/kbd.h>
#include "config.h"
#include "locales.h"
#include "layout_ids.h"
#include "layouts_xkb.h"
#include "keyboard.h"
#include "libkbd.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.
*/
RdpKeycodes x_keycode_to_rdp_keycode;
#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)
{
#ifdef WITH_XKBFILE
if (!init_xkb(dpy))
{
DEBUG_KBD("Error initializing xkb");
return 0;
}
if (!keyboard_layout_id)
{
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_keycode);
#else
char xkbfile[256];
KeycodeToVkcode keycodeToVkcode;
int keycode;
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++)
{
int vkcode;
vkcode = keycodeToVkcode[keycode];
DEBUG_KBD("X key code %3d VK %3d %-19s-> RDP keycode %d/%d",
keycode, vkcode, virtualKeyboard[vkcode].name,
virtualKeyboard[vkcode].extended, virtualKeyboard[vkcode].scancode);
x_keycode_to_rdp_keycode[keycode].keycode = virtualKeyboard[vkcode].scancode;
x_keycode_to_rdp_keycode[keycode].extended = virtualKeyboard[vkcode].extended;
#ifdef WITH_DEBUG_KBD
x_keycode_to_rdp_keycode[keycode].keyname = virtualKeyboard[vkcode].name;
#endif
}
#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, RD_BOOL * extended)
{
DEBUG_KBD("%2x %4s -> %d/%d", keycode, x_keycode_to_rdp_keycode[keycode].keyname,
x_keycode_to_rdp_keycode[keycode].extended, x_keycode_to_rdp_keycode[keycode].keycode);
*extended = x_keycode_to_rdp_keycode[keycode].extended;
return x_keycode_to_rdp_keycode[keycode].keycode;
}
uint8
freerdp_kbd_get_scancode_by_virtualkey(int vkcode, RD_BOOL * extended)
{
*extended = virtualKeyboard[vkcode].extended;
return virtualKeyboard[vkcode].scancode;
}

31
libfreerdp-kbd/libkbd.h Normal file
View File

@ -0,0 +1,31 @@
/**
* 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.
*/
#ifndef __LIBKBD_H
#define __LIBKBD_H
#include <freerdp/utils/debug.h>
#ifdef WITH_DEBUG_KBD
#define DEBUG_KBD(fmt, ...) DEBUG_CLASS(KBD, fmt, ## __VA_ARGS__)
#else
#define DEBUG_KBD(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
#endif
#endif /* __LIBKBD_H */

514
libfreerdp-kbd/locales.c Normal file
View File

@ -0,0 +1,514 @@
/**
* 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 "libkbd.h"
#include "locales.h"
typedef struct
{
/* 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;
/*
* Refer to MSDN article "Locale Identifier Constants and Strings":
* http://msdn.microsoft.com/en-us/library/ms776260.aspx
*/
static const locale locales[] =
{
{ "af", "ZA", AFRIKAANS }, /* Afrikaans (South Africa) */
{ "sq", "AL", ALBANIAN }, /* Albanian (Albania) */
{ "gsw", "FR", ALSATIAN }, /* Windows Vista and later: Alsatian (France) */
{ "am", "ET", AMHARIC }, /* Windows Vista and later: Amharic (Ethiopia) */
{ "ar", "DZ", ARABIC_ALGERIA }, /* Arabic (Algeria) */
{ "ar", "BH", ARABIC_BAHRAIN }, /* Arabic (Bahrain) */
{ "ar", "EG", ARABIC_EGYPT }, /* Arabic (Egypt) */
{ "ar", "IQ", ARABIC_IRAQ }, /* Arabic (Iraq) */
{ "ar", "JO", ARABIC_JORDAN }, /* Arabic (Jordan) */
{ "ar", "KW", ARABIC_KUWAIT }, /* Arabic (Kuwait) */
{ "ar", "LB", ARABIC_LEBANON }, /* Arabic (Lebanon) */
{ "ar", "LY", ARABIC_LIBYA }, /* Arabic (Libya) */
{ "ar", "MA", ARABIC_MOROCCO }, /* Arabic (Morocco) */
{ "ar", "OM", ARABIC_OMAN }, /* Arabic (Oman) */
{ "ar", "QA", ARABIC_QATAR }, /* Arabic (Qatar) */
{ "ar", "SA", ARABIC_SAUDI_ARABIA }, /* Arabic (Saudi Arabia) */
{ "ar", "SY", ARABIC_SYRIA }, /* Arabic (Syria) */
{ "ar", "TN", ARABIC_TUNISIA }, /* Arabic (Tunisia) */
{ "ar", "AE", ARABIC_UAE }, /* Arabic (U.A.E.) */
{ "ar", "YE", ARABIC_YEMEN }, /* Arabic (Yemen) */
{ "az", "AZ", AZERI_LATIN }, /* Azeri (Latin) */
{ "az", "Cyrl_AZ", AZERI_CYRILLIC }, /* Azeri (Cyrillic) */
{ "hy", "AM", ARMENIAN }, /* Windows 2000 and later: Armenian (Armenia) */
{ "as", "IN", ASSAMESE }, /* Windows Vista and later: Assamese (India) */
{ "ba", "RU", BASHKIR }, /* Windows Vista and later: Bashkir (Russia) */
{ "eu", "ES", BASQUE }, /* Basque (Basque) */
{ "be", "BY", BELARUSIAN }, /* Belarusian (Belarus) */
{ "bn", "IN", BENGALI_INDIA }, /* Windows XP SP2 and later: Bengali (India) */
{ "br", "FR", BRETON }, /* Breton (France) */
{ "bs", "BA", BOSNIAN_LATIN }, /* Bosnian (Latin) */
{ "bg", "BG", BULGARIAN }, /* Bulgarian (Bulgaria) */
{ "ca", "ES", CATALAN }, /* Catalan (Catalan) */
{ "zh", "HK", CHINESE_HONG_KONG }, /* Chinese (Hong Kong SAR, PRC) */
{ "zh", "MO", CHINESE_MACAU }, /* Windows 98/Me, Windows XP and later: Chinese (Macao SAR) */
{ "zh", "CN", CHINESE_PRC }, /* Chinese (PRC) */
{ "zh", "SG", CHINESE_SINGAPORE }, /* Chinese (Singapore) */
{ "zh", "TW", CHINESE_TAIWAN }, /* Chinese (Taiwan) */
{ "hr", "BA", CROATIAN_BOSNIA_HERZEGOVINA }, /* Windows XP SP2 and later: Croatian (Bosnia and Herzegovina, Latin) */
{ "hr", "HR", CROATIAN }, /* Croatian (Croatia) */
{ "cs", "CZ", CZECH }, /* Czech (Czech Republic) */
{ "da", "DK", DANISH }, /* Danish (Denmark) */
{ "prs", "AF", DARI }, /* Windows XP and later: Dari (Afghanistan) */
{ "dv", "MV", DIVEHI }, /* Windows XP and later: Divehi (Maldives) */
{ "nl", "BE", DUTCH_BELGIAN }, /* Dutch (Belgium) */
{ "nl", "NL", DUTCH_STANDARD }, /* Dutch (Netherlands) */
{ "en", "AU", ENGLISH_AUSTRALIAN }, /* English (Australia) */
{ "en", "BZ", ENGLISH_BELIZE }, /* English (Belize) */
{ "en", "CA", ENGLISH_CANADIAN }, /* English (Canada) */
{ "en", "CB", ENGLISH_CARIBBEAN }, /* English (Carribean) */
{ "en", "IN", ENGLISH_INDIA }, /* Windows Vista and later: English (India) */
{ "en", "IE", ENGLISH_IRELAND }, /* English (Ireland) */
{ "en", "JM", ENGLISH_JAMAICA }, /* English (Jamaica) */
{ "en", "MY", ENGLISH_MALAYSIA }, /* Windows Vista and later: English (Malaysia) */
{ "en", "NZ", ENGLISH_NEW_ZEALAND }, /* English (New Zealand) */
{ "en", "PH", ENGLISH_PHILIPPINES }, /* Windows 98/Me, Windows 2000 and later: English (Philippines) */
{ "en", "SG", ENGLISH_SINGAPORE }, /* Windows Vista and later: English (Singapore) */
{ "en", "ZA", ENGLISH_SOUTH_AFRICA }, /* English (South Africa) */
{ "en", "TT", ENGLISH_TRINIDAD }, /* English (Trinidad and Tobago) */
{ "en", "GB", ENGLISH_UNITED_KINGDOM }, /* English (United Kingdom) */
{ "en", "US", ENGLISH_UNITED_STATES }, /* English (United States) */
{ "en", "ZW", ENGLISH_ZIMBABWE }, /* Windows 98/Me, Windows 2000 and later: English (Zimbabwe) */
{ "et", "EE", ESTONIAN }, /* Estonian (Estonia) */
{ "fo", "FO", FAEROESE }, /* Faroese (Faroe Islands) */
{ "fil", "PH", FILIPINO }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Filipino (Philippines) */
{ "fi", "FI", FINNISH }, /* Finnish (Finland) */
{ "fr", "BE", FRENCH_BELGIAN }, /* French (Belgium) */
{ "fr", "CA", FRENCH_CANADIAN }, /* French (Canada) */
{ "fr", "FR", FRENCH_STANDARD }, /* French (France) */
{ "fr", "LU", FRENCH_LUXEMBOURG }, /* French (Luxembourg) */
{ "fr", "MC", FRENCH_MONACO }, /* French (Monaco) */
{ "fr", "CH", FRENCH_SWISS }, /* French (Switzerland) */
{ "fy", "NL", FRISIAN }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Frisian (Netherlands) */
{ "gl", "ES", GALICIAN }, /* Windows XP and later: Galician (Spain) */
{ "ka", "GE", GEORGIAN }, /* Windows 2000 and later: Georgian (Georgia) */
{ "de", "AT", GERMAN_AUSTRIAN }, /* German (Austria) */
{ "de", "DE", GERMAN_STANDARD }, /* German (Germany) */
{ "de", "LI", GERMAN_LIECHTENSTEIN }, /* German (Liechtenstein) */
{ "de", "LU", GERMAN_LUXEMBOURG }, /* German (Luxembourg) */
{ "de", "CH", GERMAN_SWISS }, /* German (Switzerland) */
{ "el", "GR", GREEK }, /* Greek (Greece) */
{ "kl", "GL", GREENLANDIC }, /* Windows Vista and later: Greenlandic (Greenland) */
{ "gu", "IN", GUJARATI }, /* Windows XP and later: Gujarati (India) */
{ "he", "IL", HEBREW }, /* Hebrew (Israel) */
{ "hi", "IN", HINDI }, /* Windows 2000 and later: Hindi (India) */
{ "hu", "HU", HUNGARIAN }, /* Hungarian (Hungary) */
{ "is", "IS", ICELANDIC }, /* Icelandic (Iceland) */
{ "ig", "NG", IGBO }, /* Igbo (Nigeria) */
{ "id", "ID", INDONESIAN }, /* Indonesian (Indonesia) */
{ "ga", "IE", IRISH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Irish (Ireland) */
{ "it", "IT", ITALIAN_STANDARD }, /* Italian (Italy) */
{ "it", "CH", ITALIAN_SWISS }, /* Italian (Switzerland) */
{ "ja", "JP", JAPANESE }, /* Japanese (Japan) */
{ "kn", "IN", KANNADA }, /* Windows XP and later: Kannada (India) */
{ "kk", "KZ", KAZAKH }, /* Windows 2000 and later: Kazakh (Kazakhstan) */
{ "kh", "KH", KHMER }, /* Windows Vista and later: Khmer (Cambodia) */
{ "qut", "GT", KICHE }, /* Windows Vista and later: K'iche (Guatemala) */
{ "rw", "RW", KINYARWANDA }, /* Windows Vista and later: Kinyarwanda (Rwanda) */
{ "kok", "IN", KONKANI }, /* Windows 2000 and later: Konkani (India) */
{ "ko", "KR", KOREAN }, /* Korean (Korea) */
{ "ky", "KG", KYRGYZ }, /* Windows XP and later: Kyrgyz (Kyrgyzstan) */
{ "lo", "LA", LAO }, /* Windows Vista and later: Lao (Lao PDR) */
{ "lv", "LV", LATVIAN }, /* Latvian (Latvia) */
{ "lt", "LT", LITHUANIAN }, /* Lithuanian (Lithuania) */
{ "dsb", "DE", LOWER_SORBIAN }, /* Windows Vista and later: Lower Sorbian (Germany) */
{ "lb", "LU", LUXEMBOURGISH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Luxembourgish (Luxembourg) */
{ "mk", "MK", MACEDONIAN }, /* Windows 2000 and later: Macedonian (Macedonia, FYROM) */
{ "ms", "BN", MALAY_BRUNEI_DARUSSALAM }, /* Windows 2000 and later: Malay (Brunei Darussalam) */
{ "ms", "MY", MALAY_MALAYSIA }, /* Windows 2000 and later: Malay (Malaysia) */
{ "ml", "IN", MALAYALAM }, /* Windows XP SP2 and later: Malayalam (India) */
{ "mt", "MT", MALTESE }, /* Windows XP SP2 and later: Maltese (Malta) */
{ "mi", "NZ", MAORI }, /* Windows XP SP2 and later: Maori (New Zealand) */
{ "arn", "CL", MAPUDUNGUN }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Mapudungun (Chile) */
{ "mr", "IN", MARATHI }, /* Windows 2000 and later: Marathi (India) */
{ "moh", "CA", MOHAWK }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Mohawk (Canada) */
{ "mn", "MN", MONGOLIAN }, /* Mongolian */
{ "ne", "NP", NEPALI }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Nepali (Nepal) */
{ "nb", "NO", NORWEGIAN_BOKMAL }, /* Norwegian (Bokmal, Norway) */
{ "nn", "NO", NORWEGIAN_NYNORSK }, /* Norwegian (Nynorsk, Norway) */
{ "oc", "FR", OCCITAN }, /* Occitan (France) */
{ "or", "IN", ORIYA }, /* Oriya (India) */
{ "ps", "AF", PASHTO }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Pashto (Afghanistan) */
{ "fa", "IR", FARSI }, /* Persian (Iran) */
{ "pl", "PL", POLISH }, /* Polish (Poland) */
{ "pt", "BR", PORTUGUESE_BRAZILIAN }, /* Portuguese (Brazil) */
{ "pt", "PT", PORTUGUESE_STANDARD }, /* Portuguese (Portugal) */
{ "pa", "IN", PUNJABI }, /* Windows XP and later: Punjabi (India) */
{ "quz", "BO", QUECHUA_BOLIVIA }, /* Windows XP SP2 and later: Quechua (Bolivia) */
{ "quz", "EC", QUECHUA_ECUADOR }, /* Windows XP SP2 and later: Quechua (Ecuador) */
{ "quz", "PE", QUECHUA_PERU }, /* Windows XP SP2 and later: Quechua (Peru) */
{ "ro", "RO", ROMANIAN }, /* Romanian (Romania) */
{ "rm", "CH", ROMANSH }, /* Windows XP SP2 and later (downloadable); Windows Vista and later: Romansh (Switzerland) */
{ "ru", "RU", RUSSIAN }, /* Russian (Russia) */
{ "smn", "FI", SAMI_INARI }, /* Windows XP SP2 and later: Sami (Inari, Finland) */
{ "smj", "NO", SAMI_LULE_NORWAY }, /* Windows XP SP2 and later: Sami (Lule, Norway) */
{ "smj", "SE", SAMI_LULE_SWEDEN }, /* Windows XP SP2 and later: Sami (Lule, Sweden) */
{ "se", "FI", SAMI_NORTHERN_FINLAND }, /* Windows XP SP2 and later: Sami (Northern, Finland) */
{ "se", "NO", SAMI_NORTHERN_NORWAY }, /* Windows XP SP2 and later: Sami (Northern, Norway) */
{ "se", "SE", SAMI_NORTHERN_SWEDEN }, /* Windows XP SP2 and later: Sami (Northern, Sweden) */
{ "sms", "FI", SAMI_SKOLT }, /* Windows XP SP2 and later: Sami (Skolt, Finland) */
{ "sma", "NO", SAMI_SOUTHERN_NORWAY }, /* Windows XP SP2 and later: Sami (Southern, Norway) */
{ "sma", "SE", SAMI_SOUTHERN_SWEDEN }, /* Windows XP SP2 and later: Sami (Southern, Sweden) */
{ "sa", "IN", SANSKRIT }, /* Windows 2000 and later: Sanskrit (India) */
{ "sr", "SP", SERBIAN_LATIN }, /* Serbian (Latin) */
{ "sr", "SIH", SERBIAN_LATIN_BOSNIA_HERZEGOVINA }, /* Serbian (Latin) (Bosnia and Herzegovina) */
{ "sr", "Cyrl_SP", SERBIAN_CYRILLIC }, /* Serbian (Cyrillic) */
{ "sr", "Cyrl_SIH", SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA }, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */
{ "ns", "ZA", SESOTHO_SA_LEBOA }, /* Windows XP SP2 and later: Sesotho sa Leboa/Northern Sotho (South Africa) */
{ "tn", "ZA", TSWANA }, /* Windows XP SP2 and later: Setswana/Tswana (South Africa) */
{ "si", "LK", SINHALA }, /* Windows Vista and later: Sinhala (Sri Lanka) */
{ "sk", "SK", SLOVAK }, /* Slovak (Slovakia) */
{ "sl", "SI", SLOVENIAN }, /* Slovenian (Slovenia) */
{ "es", "AR", SPANISH_ARGENTINA }, /* Spanish (Argentina) */
{ "es", "BO", SPANISH_BOLIVIA }, /* Spanish (Bolivia) */
{ "es", "CL", SPANISH_CHILE }, /* Spanish (Chile) */
{ "es", "CO", SPANISH_COLOMBIA }, /* Spanish (Colombia) */
{ "es", "CR", SPANISH_COSTA_RICA }, /* Spanish (Costa Rica) */
{ "es", "DO", SPANISH_DOMINICAN_REPUBLIC }, /* Spanish (Dominican Republic) */
{ "es", "EC", SPANISH_ECUADOR }, /* Spanish (Ecuador) */
{ "es", "SV", SPANISH_EL_SALVADOR }, /* Spanish (El Salvador) */
{ "es", "GT", SPANISH_GUATEMALA }, /* Spanish (Guatemala) */
{ "es", "HN", SPANISH_HONDURAS }, /* Spanish (Honduras) */
{ "es", "MX", SPANISH_MEXICAN }, /* Spanish (Mexico) */
{ "es", "NI", SPANISH_NICARAGUA }, /* Spanish (Nicaragua) */
{ "es", "PA", SPANISH_PANAMA }, /* Spanish (Panama) */
{ "es", "PY", SPANISH_PARAGUAY }, /* Spanish (Paraguay) */
{ "es", "PE", SPANISH_PERU }, /* Spanish (Peru) */
{ "es", "PR", SPANISH_PUERTO_RICO }, /* Spanish (Puerto Rico) */
{ "es", "ES", SPANISH_MODERN_SORT }, /* Spanish (Spain) */
{ "es", "ES", SPANISH_TRADITIONAL_SORT }, /* Spanish (Spain, Traditional Sort) */
{ "es", "US", SPANISH_UNITED_STATES }, /* Windows Vista and later: Spanish (United States) */
{ "es", "UY", SPANISH_URUGUAY }, /* Spanish (Uruguay) */
{ "es", "VE", SPANISH_VENEZUELA }, /* Spanish (Venezuela) */
{ "sw", "KE", SWAHILI }, /* Windows 2000 and later: Swahili (Kenya) */
{ "sv", "FI", SWEDISH_FINLAND }, /* Swedish (Finland) */
{ "sv", "SE", SWEDISH }, /* Swedish (Sweden) */
{ "syr", "SY", SYRIAC }, /* Windows XP and later: Syriac (Syria) */
{ "ta", "IN", TAMIL }, /* Windows 2000 and later: Tamil (India) */
{ "tt", "RU", TATAR }, /* Windows XP and later: Tatar (Russia) */
{ "te", "IN", TELUGU }, /* Windows XP and later: Telugu (India) */
{ "th", "TH", THAI }, /* Thai (Thailand) */
{ "bo", "BT", TIBETAN_BHUTAN }, /* Windows Vista and later: Tibetan (Bhutan) */
{ "bo", "CN", TIBETAN_PRC }, /* Windows Vista and later: Tibetan (PRC) */
{ "tr", "TR", TURKISH }, /* Turkish (Turkey) */
{ "tk", "TM", TURKMEN }, /* Windows Vista and later: Turkmen (Turkmenistan) */
{ "ug", "CN", UIGHUR }, /* Windows Vista and later: Uighur (PRC) */
{ "uk", "UA", UKRAINIAN }, /* Ukrainian (Ukraine) */
{ "wen", "DE", UPPER_SORBIAN }, /* Windows Vista and later: Upper Sorbian (Germany) */
{ "tr", "IN", URDU_INDIA }, /* Urdu (India) */
{ "ur", "PK", URDU }, /* Windows 98/Me, Windows 2000 and later: Urdu (Pakistan) */
{ "uz", "UZ", UZBEK_LATIN }, /* Uzbek (Latin) */
{ "uz", "Cyrl_UZ", UZBEK_CYRILLIC }, /* Uzbek (Cyrillic) */
{ "vi", "VN", VIETNAMESE }, /* Windows 98/Me, Windows NT 4.0 and later: Vietnamese (Vietnam) */
{ "cy", "GB", WELSH }, /* Windows XP SP2 and later: Welsh (United Kingdom) */
{ "wo", "SN", WOLOF }, /* Windows Vista and later: Wolof (Senegal) */
{ "xh", "ZA", XHOSA }, /* Windows XP SP2 and later: Xhosa/isiXhosa (South Africa) */
{ "sah", "RU", YAKUT }, /* Windows Vista and later: Yakut (Russia) */
{ "ii", "CN", YI }, /* Windows Vista and later: Yi (PRC) */
{ "yo", "NG", YORUBA }, /* Windows Vista and later: Yoruba (Nigeria) */
{ "zu", "ZA", ZULU } /* Windows XP SP2 and later: Zulu/isiZulu (South Africa) */
};
typedef struct
{
/* Locale ID */
unsigned int locale;
/* Array of associated keyboard layouts */
unsigned int keyboardLayouts[5];
} localeAndKeyboardLayout;
/* TODO: Use KBD_* defines instead of hardcoded values */
static const localeAndKeyboardLayout defaultKeyboardLayouts[] =
{
{ AFRIKAANS, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
{ ALBANIAN, { 0x0000041c, 0x00000409, 0x0, 0x0, 0x0 } },
{ ARABIC_SAUDI_ARABIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_IRAQ, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_EGYPT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_LIBYA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
{ ARABIC_ALGERIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
{ ARABIC_MOROCCO, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
{ ARABIC_TUNISIA, { 0x0000040c, 0x00020401, 0x0, 0x0, 0x0 } },
{ ARABIC_OMAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_YEMEN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_SYRIA, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_JORDAN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_LEBANON, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_KUWAIT, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_UAE, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_BAHRAIN, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARABIC_QATAR, { 0x00000409, 0x00000401, 0x0, 0x0, 0x0 } },
{ ARMENIAN, { 0x0000042b, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ AZERI_LATIN, { 0x0000042c, 0x0000082c, 0x00000419, 0x0, 0x0 } },
{ AZERI_CYRILLIC, { 0x0000082c, 0x0000042c, 0x00000419, 0x0, 0x0 } },
{ BASQUE, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
{ BELARUSIAN, { 0x00000423, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ BENGALI_INDIA, { 0x00000445, 0x00000409, 0x0, 0x0, 0x0 } },
{ BOSNIAN_LATIN, { 0x0000141A, 0x00000409, 0x0, 0x0, 0x0 } },
{ BULGARIAN, { 0x00000402, 0x00000409, 0x0, 0x0, 0x0 } },
{ CATALAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
{ CHINESE_TAIWAN, { 0x00000404, 0xe0080404, 0xE0010404, 0x0, 0x0 } },
{ CHINESE_PRC, { 0x00000804, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } },
{ CHINESE_HONG_KONG, { 0x00000409, 0xe0080404, 0x0, 0x0, 0x0 } },
{ CHINESE_SINGAPORE, { 0x00000409, 0xe00e0804, 0xe0010804, 0xe0030804, 0xe0040804 } },
{ CHINESE_MACAU, { 0x00000409, 0xe00e0804, 0xe0020404, 0xe0080404 } },
{ CROATIAN, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } },
{ CROATIAN_BOSNIA_HERZEGOVINA, { 0x0000041a, 0x00000409, 0x0, 0x0, 0x0 } },
{ CZECH, { 0x00000405, 0x00000409, 0x0, 0x0, 0x0 } },
{ DANISH, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } },
{ DIVEHI, { 0x00000409, 0x00000465, 0x0, 0x0, 0x0 } },
{ DUTCH_STANDARD, { 0x00020409, 0x00000413, 0x00000409, 0x0, 0x0 } },
{ DUTCH_BELGIAN, { 0x00000813, 0x00000409, 0x0, 0x0, 0x0 } },
{ ENGLISH_UNITED_STATES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_UNITED_KINGDOM, { 0x00000809, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_AUSTRALIAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_CANADIAN, { 0x00000409, 0x00011009, 0x00001009, 0x0, 0x0 } },
{ ENGLISH_NEW_ZEALAND, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_IRELAND, { 0x00001809, 0x00011809, 0x0, 0x0, 0x0 } },
{ ENGLISH_SOUTH_AFRICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_JAMAICA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_CARIBBEAN, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_BELIZE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_TRINIDAD, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_ZIMBABWE, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ENGLISH_PHILIPPINES, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ ESTONIAN, { 0x00000425, 0x0, 0x0, 0x0, 0x0 } },
{ FAEROESE, { 0x00000406, 0x00000409, 0x0, 0x0, 0x0 } },
{ FARSI, { 0x00000409, 0x00000429, 0x00000401, 0x0, 0x0 } },
{ FINNISH, { 0x0000040b, 0x00000409, 0x0, 0x0, 0x0 } },
{ FRENCH_STANDARD, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
{ FRENCH_BELGIAN, { 0x0000080c, 0x00000409, 0x0, 0x0, 0x0 } },
{ FRENCH_CANADIAN, { 0x00000C0C, 0x00011009, 0x00000409, 0x0, 0x0 } },
{ FRENCH_SWISS, { 0x0000100c, 0x00000409, 0x0, 0x0, 0x0 } },
{ FRENCH_LUXEMBOURG, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
{ FRENCH_MONACO, { 0x0000040c, 0x00000409, 0x0, 0x0, 0x0 } },
{ GEORGIAN, { 0x00000437, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ GALICIAN, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
{ GERMAN_STANDARD, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
{ GERMAN_SWISS, { 0x00000807, 0x00000409, 0x0, 0x0, 0x0 } },
{ GERMAN_AUSTRIAN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
{ GERMAN_LUXEMBOURG, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
{ GERMAN_LIECHTENSTEIN, { 0x00000407, 0x00000409, 0x0, 0x0, 0x0 } },
{ GREEK, { 0x00000408, 0x00000409, 0x0, 0x0, 0x0 } },
{ GUJARATI, { 0x00000409, 0x00000447, 0x00010439, 0x0, 0x0 } },
{ HEBREW, { 0x00000409, 0x0000040d, 0x0, 0x0, 0x0 } },
{ HINDI, { 0x00000409, 0x00010439, 0x00000439, 0x0, 0x0 } },
{ HUNGARIAN, { 0x0000040e, 0x00000409, 0x0, 0x0, 0x0 } },
{ ICELANDIC, { 0x0000040f, 0x00000409, 0x0, 0x0, 0x0 } },
{ INDONESIAN, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
{ ITALIAN_STANDARD, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } },
{ ITALIAN_SWISS, { 0x00000410, 0x00000409, 0x0, 0x0, 0x0 } },
{ JAPANESE, { 0xe0010411, 0x0, 0x0, 0x0, 0x0 } },
{ KANNADA, { 0x00000409, 0x0000044b, 0x00010439, 0x0, 0x0 } },
{ KAZAKH, { 0x0000043f, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ KONKANI, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } },
{ KOREAN, { 0xE0010412, 0x0, 0x0, 0x0, 0x0 } },
{ KYRGYZ, { 0x00000440, 0x00000409, 0x0, 0x0, 0x0 } },
{ LATVIAN, { 0x00010426, 0x0, 0x0, 0x0, 0x0 } },
{ LITHUANIAN, { 0x00010427, 0x0, 0x0, 0x0, 0x0 } },
{ MACEDONIAN, { 0x0000042f, 0x00000409, 0x0, 0x0, 0x0 } },
{ MALAY_MALAYSIA, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ MALAY_BRUNEI_DARUSSALAM, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ MALAYALAM, { 0x00000409, 0x0000044c, 0x0, 0x0, 0x0 } },
{ MALTESE, { 0x00000409, 0x0000043a, 0x0, 0x0, 0x0 } },
{ MAORI, { 0x00000409, 0x00000481, 0x0, 0x0, 0x0 } },
{ MARATHI, { 0x00000409, 0x0000044e, 0x00000439, 0x0, 0x0 } },
{ MONGOLIAN, { 0x00000450, 0x00000409, 0x0, 0x0, 0x0 } },
{ NORWEGIAN_BOKMAL, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } },
{ NORWEGIAN_NYNORSK, { 0x00000414, 0x00000409, 0x0, 0x0, 0x0 } },
{ POLISH, { 0x00010415, 0x00000415, 0x00000409, 0x0, 0x0 } },
{ PORTUGUESE_BRAZILIAN, { 0x00000416, 0x00000409, 0x0, 0x0, 0x0 } },
{ PORTUGUESE_STANDARD, { 0x00000816, 0x00000409, 0x0, 0x0, 0x0 } },
{ PUNJABI, { 0x00000409, 0x00000446, 0x00010439, 0x0, 0x0 } },
{ QUECHUA_BOLIVIA, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
{ QUECHUA_ECUADOR, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
{ QUECHUA_PERU, { 0x00000409, 0x0000080A, 0x0, 0x0, 0x0 } },
{ ROMANIAN, { 0x00000418, 0x00000409, 0x0, 0x0, 0x0 } },
{ RUSSIAN, { 0x00000419, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_INARI, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_LULE_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_LULE_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_NORTHERN_FINLAND, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_NORTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_NORTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_SKOLT, { 0x0001083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_SOUTHERN_NORWAY, { 0x0000043b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SAMI_SOUTHERN_SWEDEN, { 0x0000083b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SANSKRIT, { 0x00000409, 0x00000439, 0x0, 0x0, 0x0 } },
{ SERBIAN_LATIN, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SERBIAN_LATIN_BOSNIA_HERZEGOVINA, { 0x0000081a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SERBIAN_CYRILLIC, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA, { 0x00000c1a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SLOVAK, { 0x0000041b, 0x00000409, 0x0, 0x0, 0x0 } },
{ SLOVENIAN, { 0x00000424, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_TRADITIONAL_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_MEXICAN, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_MODERN_SORT, { 0x0000040a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_GUATEMALA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_COSTA_RICA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_PANAMA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_DOMINICAN_REPUBLIC, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_VENEZUELA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_COLOMBIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_PERU, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_ARGENTINA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_ECUADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_CHILE, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_URUGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_PARAGUAY, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_BOLIVIA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_EL_SALVADOR, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_HONDURAS, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_NICARAGUA, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SPANISH_PUERTO_RICO, { 0x0000080a, 0x00000409, 0x0, 0x0, 0x0 } },
{ SWAHILI, { 0x00000409, 0x0, 0x0, 0x0, 0x0 } },
{ SWEDISH, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } },
{ SWEDISH_FINLAND, { 0x0000041d, 0x00000409, 0x0, 0x0, 0x0 } },
{ SYRIAC, { 0x00000409, 0x0000045a, 0x0, 0x0, 0x0 } },
{ TAMIL, { 0x00000409, 0x00000449, 0x0, 0x0, 0x0 } },
{ TATAR, { 0x00000444, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ TELUGU, { 0x00000409, 0x0000044a, 0x00010439, 0x0, 0x0 } },
{ THAI, { 0x00000409, 0x0000041e, 0x0, 0x0, 0x0 } },
{ TSWANA, { 0x00000409, 0x0000041f, 0x0, 0x0, 0x0 } },
{ UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } },
{ TURKISH, { 0x0000041f, 0x0000041f, 0x0, 0x0, 0x0 } },
{ UKRAINIAN, { 0x00000422, 0x00000409, 0x0, 0x0, 0x0 } },
{ URDU, { 0x00000401, 0x00000409, 0x0, 0x0, 0x0 } },
{ UZBEK_LATIN, { 0x00000409, 0x00000843, 0x00000419, 0x0, 0x0 } },
{ UZBEK_CYRILLIC, { 0x00000843, 0x00000409, 0x00000419, 0x0, 0x0 } },
{ VIETNAMESE, { 0x00000409, 0x0000042a, 0x0, 0x0, 0x0 } },
{ WELSH, { 0x00000452, 0x00000809, 0x0, 0x0, 0x0 } },
{ XHOSA, { 0x00000409, 0x00000409, 0x0, 0x0, 0x0 } },
};
unsigned int
detect_keyboard_layout_from_locale()
{
int i;
int j;
int k;
int dot;
int underscore;
char language[4];
char country[10];
/* LANG = <language>_<country>.<encoding> */
char* envLang = getenv("LANG"); /* Get locale from environment variable LANG */
if(envLang == NULL)
return 0; /* LANG environment variable was not set */
underscore = strcspn(envLang, "_");
if(underscore > 3)
return 0; /* The language name should not be more than 3 letters long */
else
{
/* Get language code */
strncpy(language, envLang, underscore);
language[underscore] = '\0';
}
/*
* There is always the special case of "C" or "POSIX" as locale name
* In this case, use a U.S. keyboard and a U.S. keyboard layout
*/
if((strcmp(language, "C") == 0) || (strcmp(language, "POSIX") == 0))
return ENGLISH_UNITED_STATES; /* U.S. Keyboard Layout */
dot = strcspn(envLang, ".");
/* Get country code */
if(dot > underscore)
{
strncpy(country, &envLang[underscore + 1], dot - underscore - 1);
country[dot - underscore - 1] = '\0';
}
else
return 0; /* Invalid locale */
for(i = 0; i < sizeof(locales) / sizeof(locale); i++)
{
if((strcmp(language, locales[i].language) == 0) && (strcmp(country, locales[i].country) == 0))
break;
}
DEBUG_KBD("Found locale : %s_%s", locales[i].language, locales[i].country);
for(j = 0; j < sizeof(defaultKeyboardLayouts) / sizeof(localeAndKeyboardLayout); j++)
{
if(defaultKeyboardLayouts[j].locale == locales[i].code)
{
/* Locale found in list of default keyboard layouts */
for(k = 0; k < 5; k++)
{
if(defaultKeyboardLayouts[j].keyboardLayouts[k] == ENGLISH_UNITED_STATES)
{
continue; /* Skip, try to get a more localized keyboard layout */
}
else if(defaultKeyboardLayouts[j].keyboardLayouts[k] == 0)
{
break; /* No more keyboard layouts */
}
else
{
return defaultKeyboardLayouts[j].keyboardLayouts[k];
}
}
/*
* If we skip the ENGLISH_UNITED_STATES keyboard layout but there are no
* other possible keyboard layout for the locale, we end up here with k > 1
*/
if(k >= 1)
return ENGLISH_UNITED_STATES;
else
return 0;
}
}
return 0; /* Could not detect the current keyboard layout from locale */
}

326
libfreerdp-kbd/locales.h Normal file
View File

@ -0,0 +1,326 @@
/**
* 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.
*/
/* Detection of plausible keyboard layout id based on current locale (LANG) setting. */
/*
* Refer to "Windows XP/Server 2003 - List of Locale IDs, Input Locale, and Language Collection":
* http://www.microsoft.com/globaldev/reference/winxp/xp-lcid.mspx
*/
#ifndef __LOCALES_H
#define __LOCALES_H
#define AFRIKAANS 0x0436
#define ALBANIAN 0x041c
#define ALSATIAN 0x0484
#define AMHARIC 0x045E
#define ARABIC_SAUDI_ARABIA 0x0401
#define ARABIC_IRAQ 0x0801
#define ARABIC_EGYPT 0x0c01
#define ARABIC_LIBYA 0x1001
#define ARABIC_ALGERIA 0x1401
#define ARABIC_MOROCCO 0x1801
#define ARABIC_TUNISIA 0x1c01
#define ARABIC_OMAN 0x2001
#define ARABIC_YEMEN 0x2401
#define ARABIC_SYRIA 0x2801
#define ARABIC_JORDAN 0x2c01
#define ARABIC_LEBANON 0x3001
#define ARABIC_KUWAIT 0x3401
#define ARABIC_UAE 0x3801
#define ARABIC_BAHRAIN 0x3c01
#define ARABIC_QATAR 0x4001
#define ARMENIAN 0x042b
#define ASSAMESE 0x044D
#define AZERI_LATIN 0x042c
#define AZERI_CYRILLIC 0x082c
#define BASHKIR 0x046D
#define BASQUE 0x042d
#define BELARUSIAN 0x0423
#define BENGALI_INDIA 0x0445
#define BOSNIAN_LATIN 0x141A
#define BRETON 0x047E
#define BULGARIAN 0x0402
#define CATALAN 0x0403
#define CHINESE_TAIWAN 0x0404
#define CHINESE_PRC 0x0804
#define CHINESE_HONG_KONG 0x0c04
#define CHINESE_SINGAPORE 0x1004
#define CHINESE_MACAU 0x1404
#define CROATIAN 0x041a
#define CROATIAN_BOSNIA_HERZEGOVINA 0x101A
#define CZECH 0x0405
#define DANISH 0x0406
#define DARI 0x048C
#define DIVEHI 0x0465
#define DUTCH_STANDARD 0x0413
#define DUTCH_BELGIAN 0x0813
#define ENGLISH_UNITED_STATES 0x0409
#define ENGLISH_UNITED_KINGDOM 0x0809
#define ENGLISH_AUSTRALIAN 0x0c09
#define ENGLISH_CANADIAN 0x1009
#define ENGLISH_NEW_ZEALAND 0x1409
#define ENGLISH_INDIA 0x4009
#define ENGLISH_IRELAND 0x1809
#define ENGLISH_MALAYSIA 0x4409
#define ENGLISH_SOUTH_AFRICA 0x1c09
#define ENGLISH_JAMAICA 0x2009
#define ENGLISH_CARIBBEAN 0x2409
#define ENGLISH_BELIZE 0x2809
#define ENGLISH_TRINIDAD 0x2c09
#define ENGLISH_ZIMBABWE 0x3009
#define ENGLISH_PHILIPPINES 0x3409
#define ENGLISH_SINGAPORE 0x4809
#define ESTONIAN 0x0425
#define FAEROESE 0x0438
#define FARSI 0x0429
#define FILIPINO 0x0464
#define FINNISH 0x040b
#define FRENCH_STANDARD 0x040c
#define FRENCH_BELGIAN 0x080c
#define FRENCH_CANADIAN 0x0c0c
#define FRENCH_SWISS 0x100c
#define FRENCH_LUXEMBOURG 0x140c
#define FRENCH_MONACO 0x180c
#define FRISIAN 0x0462
#define GEORGIAN 0x0437
#define GALICIAN 0x0456
#define GERMAN_STANDARD 0x0407
#define GERMAN_SWISS 0x0807
#define GERMAN_AUSTRIAN 0x0c07
#define GERMAN_LUXEMBOURG 0x1007
#define GERMAN_LIECHTENSTEIN 0x1407
#define GREEK 0x0408
#define GREENLANDIC 0x046F
#define GUJARATI 0x0447
#define HEBREW 0x040d
#define HINDI 0x0439
#define HUNGARIAN 0x040e
#define ICELANDIC 0x040f
#define IGBO 0x0470
#define INDONESIAN 0x0421
#define IRISH 0x083C
#define ITALIAN_STANDARD 0x0410
#define ITALIAN_SWISS 0x0810
#define JAPANESE 0x0411
#define KANNADA 0x044b
#define KAZAKH 0x043f
#define KHMER 0x0453
#define KICHE 0x0486
#define KINYARWANDA 0x0487
#define KONKANI 0x0457
#define KOREAN 0x0412
#define KYRGYZ 0x0440
#define LAO 0x0454
#define LATVIAN 0x0426
#define LITHUANIAN 0x0427
#define LOWER_SORBIAN 0x082E
#define LUXEMBOURGISH 0x046E
#define MACEDONIAN 0x042f
#define MALAY_MALAYSIA 0x043e
#define MALAY_BRUNEI_DARUSSALAM 0x083e
#define MALAYALAM 0x044c
#define MALTESE 0x043a
#define MAPUDUNGUN 0x047A
#define MAORI 0x0481
#define MARATHI 0x044e
#define MOHAWK 0x047C
#define MONGOLIAN 0x0450
#define NEPALI 0x0461
#define NORWEGIAN_BOKMAL 0x0414
#define NORWEGIAN_NYNORSK 0x0814
#define OCCITAN 0x0482
#define ORIYA 0x0448
#define PASHTO 0x0463
#define POLISH 0x0415
#define PORTUGUESE_BRAZILIAN 0x0416
#define PORTUGUESE_STANDARD 0x0816
#define PUNJABI 0x0446
#define QUECHUA_BOLIVIA 0x046b
#define QUECHUA_ECUADOR 0x086b
#define QUECHUA_PERU 0x0c6b
#define ROMANIAN 0x0418
#define ROMANSH 0x0417
#define RUSSIAN 0x0419
#define SAMI_INARI 0x243b
#define SAMI_LULE_NORWAY 0x103b
#define SAMI_LULE_SWEDEN 0x143b
#define SAMI_NORTHERN_FINLAND 0x0c3b
#define SAMI_NORTHERN_NORWAY 0x043b
#define SAMI_NORTHERN_SWEDEN 0x083b
#define SAMI_SKOLT 0x203b
#define SAMI_SOUTHERN_NORWAY 0x183b
#define SAMI_SOUTHERN_SWEDEN 0x1c3b
#define SANSKRIT 0x044f
#define SERBIAN_LATIN 0x081a
#define SERBIAN_LATIN_BOSNIA_HERZEGOVINA 0x181a
#define SERBIAN_CYRILLIC 0x0c1a
#define SERBIAN_CYRILLIC_BOSNIA_HERZEGOVINA 0x1c1a
#define SESOTHO_SA_LEBOA 0x046C
#define SINHALA 0x045B
#define SLOVAK 0x041b
#define SLOVENIAN 0x0424
#define SPANISH_TRADITIONAL_SORT 0x040a
#define SPANISH_MEXICAN 0x080a
#define SPANISH_MODERN_SORT 0x0c0a
#define SPANISH_GUATEMALA 0x100a
#define SPANISH_COSTA_RICA 0x140a
#define SPANISH_PANAMA 0x180a
#define SPANISH_DOMINICAN_REPUBLIC 0x1c0a
#define SPANISH_VENEZUELA 0x200a
#define SPANISH_COLOMBIA 0x240a
#define SPANISH_PERU 0x280a
#define SPANISH_ARGENTINA 0x2c0a
#define SPANISH_ECUADOR 0x300a
#define SPANISH_CHILE 0x340a
#define SPANISH_UNITED_STATES 0x540A
#define SPANISH_URUGUAY 0x380a
#define SPANISH_PARAGUAY 0x3c0a
#define SPANISH_BOLIVIA 0x400a
#define SPANISH_EL_SALVADOR 0x440a
#define SPANISH_HONDURAS 0x480a
#define SPANISH_NICARAGUA 0x4c0a
#define SPANISH_PUERTO_RICO 0x500a
#define SWAHILI 0x0441
#define SWEDISH 0x041d
#define SWEDISH_FINLAND 0x081d
#define SYRIAC 0x045a
#define TAMIL 0x0449
#define TATAR 0x0444
#define TELUGU 0x044a
#define THAI 0x041e
#define TIBETAN_BHUTAN 0x0851
#define TIBETAN_PRC 0x0451
#define TSWANA 0x0432
#define UKRAINIAN 0x0422
#define TURKISH 0x041f
#define TURKMEN 0x0442
#define UIGHUR 0x0480
#define UPPER_SORBIAN 0x042E
#define URDU 0x0420
#define URDU_INDIA 0x0820
#define UZBEK_LATIN 0x0443
#define UZBEK_CYRILLIC 0x0843
#define VIETNAMESE 0x042a
#define WELSH 0x0452
#define WOLOF 0x0488
#define XHOSA 0x0434
#define YAKUT 0x0485
#define YI 0x0478
#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
*/
unsigned int
detect_keyboard_layout_from_locale();
#endif /* __LOCALES_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
/**
* 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.
*/
/* Hardcoded mapping from xkb layout names and variants to RDP layout ids */
#ifndef __LAYOUTS_X_H
#define __LAYOUTS_X_H
unsigned int
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);
#endif
#endif