mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
libfreerdp-kbd: initial commit
This commit is contained in:
parent
f6723028dc
commit
ed3a7a7627
587
libfreerdp-kbd/keyboard.h
Normal file
587
libfreerdp-kbd/keyboard.h
Normal 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
301
libfreerdp-kbd/layout_ids.c
Normal 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
186
libfreerdp-kbd/layout_ids.h
Normal 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
|
400
libfreerdp-kbd/layouts_xkb.c
Normal file
400
libfreerdp-kbd/layouts_xkb.c
Normal 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
|
54
libfreerdp-kbd/layouts_xkb.h
Normal file
54
libfreerdp-kbd/layouts_xkb.h
Normal 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
152
libfreerdp-kbd/libkbd.c
Normal 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
31
libfreerdp-kbd/libkbd.h
Normal 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
514
libfreerdp-kbd/locales.c
Normal 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
326
libfreerdp-kbd/locales.h
Normal 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 */
|
1171
libfreerdp-kbd/x_layout_id_table.c
Normal file
1171
libfreerdp-kbd/x_layout_id_table.c
Normal file
File diff suppressed because it is too large
Load Diff
33
libfreerdp-kbd/x_layout_id_table.h
Normal file
33
libfreerdp-kbd/x_layout_id_table.h
Normal 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
|
Loading…
Reference in New Issue
Block a user