2 * FreeRDP: A Remote Desktop Protocol Client
3 * XKB-based Keyboard Mapping to Microsoft Keyboard System
5 * Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
25 #include <freerdp/kbd/layouts.h>
29 /* Keyboard layout code */
32 /* Keyboard layout name */
38 * In Windows XP, this information is available in the system registry at
39 * HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet001/Control/Keyboard Layouts/
42 static const keyboardLayout keyboardLayouts[] =
44 { KBD_ARABIC_101, "Arabic (101)" },
45 { KBD_BULGARIAN, "Bulgarian" },
46 { KBD_CHINESE_TRADITIONAL_US, "Chinese (Traditional) - US Keyboard" },
47 { KBD_CZECH, "Czech" },
48 { KBD_DANISH, "Danish" },
49 { KBD_GERMAN, "German" },
50 { KBD_GREEK, "Greek" },
52 { KBD_SPANISH, "Spanish" },
53 { KBD_FINNISH, "Finnish" },
54 { KBD_FRENCH, "French" },
55 { KBD_HEBREW, "Hebrew" },
56 { KBD_HUNGARIAN, "Hungarian" },
57 { KBD_ICELANDIC, "Icelandic" },
58 { KBD_ITALIAN, "Italian" },
59 { KBD_JAPANESE, "Japanese" },
60 { KBD_KOREAN, "Korean" },
61 { KBD_DUTCH, "Dutch" },
62 { KBD_NORWEGIAN, "Norwegian" },
63 { KBD_POLISH_PROGRAMMERS, "Polish (Programmers)" },
64 { KBD_PORTUGUESE_BRAZILIAN_ABNT,"Portuguese (Brazilian ABNT)" },
65 { KBD_ROMANIAN, "Romanian" },
66 { KBD_RUSSIAN, "Russian" },
67 { KBD_CROATIAN, "Croatian" },
68 { KBD_SLOVAK, "Slovak" },
69 { KBD_ALBANIAN, "Albanian" },
70 { KBD_SWEDISH, "Swedish" },
71 { KBD_THAI_KEDMANEE, "Thai Kedmanee" },
72 { KBD_TURKISH_Q, "Turkish Q" },
74 { KBD_UKRAINIAN, "Ukrainian" },
75 { KBD_BELARUSIAN, "Belarusian" },
76 { KBD_SLOVENIAN, "Slovenian" },
77 { KBD_ESTONIAN, "Estonian" },
78 { KBD_LATVIAN, "Latvian" },
79 { KBD_LITHUANIAN_IBM, "Lithuanian IBM" },
80 { KBD_FARSI, "Farsi" },
81 { KBD_VIETNAMESE, "Vietnamese" },
82 { KBD_ARMENIAN_EASTERN, "Armenian Eastern" },
83 { KBD_AZERI_LATIN, "Azeri Latin" },
84 { KBD_FYRO_MACEDONIAN, "FYRO Macedonian" },
85 { KBD_GEORGIAN, "Georgian" },
86 { KBD_FAEROESE, "Faeroese" },
87 { KBD_DEVANAGARI_INSCRIPT, "Devanagari - INSCRIPT" },
88 { KBD_MALTESE_47_KEY, "Maltese 47-key" },
89 { KBD_NORWEGIAN_WITH_SAMI, "Norwegian with Sami" },
90 { KBD_KAZAKH, "Kazakh" },
91 { KBD_KYRGYZ_CYRILLIC, "Kyrgyz Cyrillic" },
92 { KBD_TATAR, "Tatar" },
93 { KBD_BENGALI, "Bengali" },
94 { KBD_PUNJABI, "Punjabi" },
95 { KBD_GUJARATI, "Gujarati" },
96 { KBD_TAMIL, "Tamil" },
97 { KBD_TELUGU, "Telugu" },
98 { KBD_KANNADA, "Kannada" },
99 { KBD_MALAYALAM, "Malayalam" },
100 { KBD_MARATHI, "Marathi" },
101 { KBD_MONGOLIAN_CYRILLIC, "Mongolian Cyrillic" },
102 { KBD_UNITED_KINGDOM_EXTENDED, "United Kingdom Extended" },
103 { KBD_SYRIAC, "Syriac" },
104 { KBD_NEPALI, "Nepali" },
105 { KBD_PASHTO, "Pashto" },
106 { KBD_DIVEHI_PHONETIC, "Divehi Phonetic" },
107 { KBD_LUXEMBOURGISH, "Luxembourgish" },
108 { KBD_MAORI, "Maori" },
109 { KBD_CHINESE_SIMPLIFIED_US, "Chinese (Simplified) - US Keyboard" },
110 { KBD_SWISS_GERMAN, "Swiss German" },
111 { KBD_UNITED_KINGDOM, "United Kingdom" },
112 { KBD_LATIN_AMERICAN, "Latin American" },
113 { KBD_BELGIAN_FRENCH, "Belgian French" },
114 { KBD_BELGIAN_PERIOD, "Belgian (Period)" },
115 { KBD_PORTUGUESE, "Portuguese" },
116 { KBD_SERBIAN_LATIN, "Serbian (Latin)" },
117 { KBD_AZERI_CYRILLIC, "Azeri Cyrillic" },
118 { KBD_SWEDISH_WITH_SAMI, "Swedish with Sami" },
119 { KBD_UZBEK_CYRILLIC, "Uzbek Cyrillic" },
120 { KBD_INUKTITUT_LATIN, "Inuktitut Latin" },
121 { KBD_CANADIAN_FRENCH_LEGACY, "Canadian French (legacy)" },
122 { KBD_SERBIAN_CYRILLIC, "Serbian (Cyrillic)" },
123 { KBD_CANADIAN_FRENCH, "Canadian French" },
124 { KBD_SWISS_FRENCH, "Swiss French" },
125 { KBD_BOSNIAN, "Bosnian" },
126 { KBD_IRISH, "Irish" },
127 { KBD_BOSNIAN_CYRILLIC, "Bosnian Cyrillic" }
133 /* Keyboard layout code */
136 /* Keyboard variant ID */
139 /* Keyboard layout variant name */
142 } keyboardLayoutVariant;
145 static const keyboardLayoutVariant keyboardLayoutVariants[] =
147 { KBD_ARABIC_102, 0x0028, "Arabic (102)" },
148 { KBD_BULGARIAN_LATIN, 0x0004, "Bulgarian (Latin)" },
149 { KBD_CZECH_QWERTY, 0x0005, "Czech (QWERTY)" },
150 { KBD_GERMAN_IBM, 0x0012, "German (IBM)" },
151 { KBD_GREEK_220, 0x0016, "Greek (220)" },
152 { KBD_UNITED_STATES_DVORAK, 0x0002, "United States-Dvorak" },
153 { KBD_SPANISH_VARIATION, 0x0086, "Spanish Variation" },
154 { KBD_HUNGARIAN_101_KEY, 0x0006, "Hungarian 101-key" },
155 { KBD_ITALIAN_142, 0x0003, "Italian (142)" },
156 { KBD_POLISH_214, 0x0007, "Polish (214)" },
157 { KBD_PORTUGUESE_BRAZILIAN_ABNT2, 0x001D, "Portuguese (Brazilian ABNT2)" },
158 { KBD_RUSSIAN_TYPEWRITER, 0x0008, "Russian (Typewriter)" },
159 { KBD_SLOVAK_QWERTY, 0x0013, "Slovak (QWERTY)" },
160 { KBD_THAI_PATTACHOTE, 0x0021, "Thai Pattachote" },
161 { KBD_TURKISH_F, 0x0014, "Turkish F" },
162 { KBD_LATVIAN_QWERTY, 0x0015, "Latvian (QWERTY)" },
163 { KBD_LITHUANIAN, 0x0027, "Lithuanian" },
164 { KBD_ARMENIAN_WESTERN, 0x0025, "Armenian Western" },
165 { KBD_HINDI_TRADITIONAL, 0x000C, "Hindi Traditional" },
166 { KBD_MALTESE_48_KEY, 0x002B, "Maltese 48-key" },
167 { KBD_SAMI_EXTENDED_NORWAY, 0x002C, "Sami Extended Norway" },
168 { KBD_BENGALI_INSCRIPT, 0x002A, "Bengali (Inscript)" },
169 { KBD_SYRIAC_PHONETIC, 0x000E, "Syriac Phonetic" },
170 { KBD_DIVEHI_TYPEWRITER, 0x000D, "Divehi Typewriter" },
171 { KBD_BELGIAN_COMMA, 0x001E, "Belgian (Comma)" },
172 { KBD_FINNISH_WITH_SAMI, 0x002D, "Finnish with Sami" },
173 { KBD_CANADIAN_MULTILINGUAL_STANDARD, 0x0020, "Canadian Multilingual Standard" },
174 { KBD_GAELIC, 0x0026, "Gaelic" },
175 { KBD_ARABIC_102_AZERTY, 0x0029, "Arabic (102) AZERTY" },
176 { KBD_CZECH_PROGRAMMERS, 0x000A, "Czech Programmers" },
177 { KBD_GREEK_319, 0x0018, "Greek (319)" },
178 { KBD_UNITED_STATES_INTERNATIONAL, 0x0001, "United States-International" },
179 { KBD_THAI_KEDMANEE_NON_SHIFTLOCK, 0x0022, "Thai Kedmanee (non-ShiftLock)" },
180 { KBD_SAMI_EXTENDED_FINLAND_SWEDEN, 0x002E, "Sami Extended Finland-Sweden" },
181 { KBD_GREEK_220_LATIN, 0x0017, "Greek (220) Latin" },
182 { KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND, 0x001A, "United States-Dvorak for left hand" },
183 { KBD_THAI_PATTACHOTE_NON_SHIFTLOCK, 0x0023, "Thai Pattachote (non-ShiftLock)" },
184 { KBD_GREEK_319_LATIN, 0x0011, "Greek (319) Latin" },
185 { KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND, 0x001B, "United States-Dvorak for right hand" },
186 { KBD_GREEK_LATIN, 0x0019, "Greek Latin" },
187 { KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L, 0x000B, "US English Table for IBM Arabic 238_L" },
188 { KBD_GREEK_POLYTONIC, 0x001F, "Greek Polytonic" },
189 { KBD_GERMAN_NEO, 0x00C0, "German Neo" }
192 /* Input Method Editor (IME) */
196 /* Keyboard layout code */
202 /* Keyboard layout name */
208 /* Global Input Method Editors (IME) */
210 static const keyboardIME keyboardIMEs[] =
212 { KBD_CHINESE_TRADITIONAL_PHONETIC, "phon.ime", "Chinese (Traditional) - Phonetic" },
213 { KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, "imjp81.ime", "Japanese Input System (MS-IME2002)" },
214 { KBD_KOREAN_INPUT_SYSTEM_IME_2000, "imekr61.ime", "Korean Input System (IME 2000)" },
215 { KBD_CHINESE_SIMPLIFIED_QUANPIN, "winpy.ime", "Chinese (Simplified) - QuanPin" },
216 { KBD_CHINESE_TRADITIONAL_CHANGJIE, "chajei.ime", "Chinese (Traditional) - ChangJie" },
217 { KBD_CHINESE_SIMPLIFIED_SHUANGPIN, "winsp.ime", "Chinese (Simplified) - ShuangPin" },
218 { KBD_CHINESE_TRADITIONAL_QUICK, "quick.ime", "Chinese (Traditional) - Quick" },
219 { KBD_CHINESE_SIMPLIFIED_ZHENGMA, "winzm.ime", "Chinese (Simplified) - ZhengMa" },
220 { KBD_CHINESE_TRADITIONAL_BIG5_CODE, "winime.ime", "Chinese (Traditional) - Big5 Code" },
221 { KBD_CHINESE_TRADITIONAL_ARRAY, "winar30.ime", "Chinese (Traditional) - Array" },
222 { KBD_CHINESE_SIMPLIFIED_NEIMA, "wingb.ime", "Chinese (Simplified) - NeiMa" },
223 { KBD_CHINESE_TRADITIONAL_DAYI, "dayi.ime", "Chinese (Traditional) - DaYi" },
224 { KBD_CHINESE_TRADITIONAL_UNICODE, "unicdime.ime", "Chinese (Traditional) - Unicode" },
225 { KBD_CHINESE_TRADITIONAL_NEW_PHONETIC, "TINTLGNT.IME", "Chinese (Traditional) - New Phonetic" },
226 { KBD_CHINESE_TRADITIONAL_NEW_CHANGJIE, "CINTLGNT.IME", "Chinese (Traditional) - New ChangJie" },
227 { KBD_CHINESE_TRADITIONAL_MICROSOFT_PINYIN_IME_3, "pintlgnt.ime", "Chinese (Traditional) - Microsoft Pinyin IME 3.0" },
228 { KBD_CHINESE_TRADITIONAL_ALPHANUMERIC, "romanime.ime", "Chinese (Traditional) - Alphanumeric" }
232 rdpKeyboardLayout* get_keyboard_layouts(int types)
235 rdpKeyboardLayout * layouts;
238 layouts = (rdpKeyboardLayout *) malloc((num + 1) * sizeof(rdpKeyboardLayout));
240 if ((types & RDP_KEYBOARD_LAYOUT_TYPE_STANDARD) != 0)
242 len = sizeof(keyboardLayouts) / sizeof(keyboardLayout);
243 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
244 for (i = 0; i < len; i++, num++)
246 layouts[num].code = keyboardLayouts[i].code;
247 strcpy(layouts[num].name, keyboardLayouts[i].name);
250 if ((types & RDP_KEYBOARD_LAYOUT_TYPE_VARIANT) != 0)
252 len = sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant);
253 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
254 for (i = 0; i < len; i++, num++)
256 layouts[num].code = keyboardLayoutVariants[i].code;
257 strcpy(layouts[num].name, keyboardLayoutVariants[i].name);
260 if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0)
262 len = sizeof(keyboardIMEs) / sizeof(keyboardIME);
263 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
265 for (i = 0; i < len; i++, num++)
267 layouts[num].code = keyboardIMEs[i].code;
268 strcpy(layouts[num].name, keyboardIMEs[i].name);
272 memset(&layouts[num], 0, sizeof(rdpKeyboardLayout));
277 const char* get_layout_name(unsigned int keyboardLayoutID)
281 for (i = 0; i < sizeof(keyboardLayouts) / sizeof(keyboardLayout); i++)
283 if (keyboardLayouts[i].code == keyboardLayoutID)
284 return keyboardLayouts[i].name;
287 for (i = 0; i < sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); i++)
289 if (keyboardLayoutVariants[i].code == keyboardLayoutID)
290 return keyboardLayoutVariants[i].name;
293 for (i = 0; i < sizeof(keyboardIMEs) / sizeof(keyboardIME); i++)
295 if (keyboardIMEs[i].code == keyboardLayoutID)
296 return keyboardIMEs[i].name;