Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-kbd / layouts.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * XKB-based Keyboard Mapping to Microsoft Keyboard System
4  *
5  * Copyright 2009 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include "libkbd.h"
24
25 #include <freerdp/kbd/layouts.h>
26
27 typedef struct
28 {
29         /* Keyboard layout code */
30         unsigned int code;
31
32         /* Keyboard layout name */
33         char name[50];
34
35 } keyboardLayout;
36
37 /*
38  * In Windows XP, this information is available in the system registry at
39  * HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet001/Control/Keyboard Layouts/
40  */
41
42 static const keyboardLayout keyboardLayouts[] =
43 {
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" },
51         { KBD_US,                       "US" },
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" },
73         { KBD_URDU,                     "Urdu" },
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" }
128 };
129
130
131 typedef struct
132 {
133         /* Keyboard layout code */
134         unsigned int code;
135
136         /* Keyboard variant ID */
137         unsigned short id;
138
139         /* Keyboard layout variant name */
140         char name[50];
141
142 } keyboardLayoutVariant;
143
144
145 static const keyboardLayoutVariant keyboardLayoutVariants[] =
146 {
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" }
190 };
191
192 /* Input Method Editor (IME) */
193
194 typedef struct
195 {
196         /* Keyboard layout code */
197         unsigned int code;
198
199         /* IME file name */
200         char fileName[32];
201
202         /* Keyboard layout name */
203         char name[50];
204
205 } keyboardIME;
206
207
208 /* Global Input Method Editors (IME) */
209
210 static const keyboardIME keyboardIMEs[] =
211 {
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" }
229 };
230
231
232 rdpKeyboardLayout* get_keyboard_layouts(int types)
233 {
234         int num, len, i;
235         rdpKeyboardLayout * layouts;
236
237         num = 0;
238         layouts = (rdpKeyboardLayout *) malloc((num + 1) * sizeof(rdpKeyboardLayout));
239
240         if ((types & RDP_KEYBOARD_LAYOUT_TYPE_STANDARD) != 0)
241         {
242                 len = sizeof(keyboardLayouts) / sizeof(keyboardLayout);
243                 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
244                 for (i = 0; i < len; i++, num++)
245                 {
246                         layouts[num].code = keyboardLayouts[i].code;
247                         strcpy(layouts[num].name, keyboardLayouts[i].name);
248                 }
249         }
250         if ((types & RDP_KEYBOARD_LAYOUT_TYPE_VARIANT) != 0)
251         {
252                 len = sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant);
253                 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
254                 for (i = 0; i < len; i++, num++)
255                 {
256                         layouts[num].code = keyboardLayoutVariants[i].code;
257                         strcpy(layouts[num].name, keyboardLayoutVariants[i].name);
258                 }
259         }
260         if ((types & RDP_KEYBOARD_LAYOUT_TYPE_IME) != 0)
261         {
262                 len = sizeof(keyboardIMEs) / sizeof(keyboardIME);
263                 layouts = (rdpKeyboardLayout *) realloc(layouts, (num + len + 1) * sizeof(rdpKeyboardLayout));
264
265                 for (i = 0; i < len; i++, num++)
266                 {
267                         layouts[num].code = keyboardIMEs[i].code;
268                         strcpy(layouts[num].name, keyboardIMEs[i].name);
269                 }
270         }
271
272         memset(&layouts[num], 0, sizeof(rdpKeyboardLayout));
273
274         return layouts;
275 }
276
277 const char* get_layout_name(unsigned int keyboardLayoutID)
278 {
279         int i;
280
281         for (i = 0; i < sizeof(keyboardLayouts) / sizeof(keyboardLayout); i++)
282         {
283                 if (keyboardLayouts[i].code == keyboardLayoutID)
284                         return keyboardLayouts[i].name;
285         }
286
287         for (i = 0; i < sizeof(keyboardLayoutVariants) / sizeof(keyboardLayoutVariant); i++)
288         {
289                 if (keyboardLayoutVariants[i].code == keyboardLayoutID)
290                         return keyboardLayoutVariants[i].name;
291         }
292
293         for (i = 0; i < sizeof(keyboardIMEs) / sizeof(keyboardIME); i++)
294         {
295                 if (keyboardIMEs[i].code == keyboardLayoutID)
296                         return keyboardIMEs[i].name;
297         }
298
299         return "unknown";
300 }