FreeRDP
Loading...
Searching...
No Matches
libfreerdp/locale/xkb_layout_ids.c
1
20#include <freerdp/config.h>
21
22#include "xkb_layout_ids.h"
23
24#include <string.h>
25
26#include <winpr/crt.h>
27
28#include <freerdp/locale/keyboard.h>
29
30#include "liblocale.h"
31
32typedef struct
33{
34 const char* variant; /* XKB Keyboard layout variant */
35 INT64 keyboardLayoutID; /* Keyboard Layout ID */
36} XKB_VARIANT;
37
38typedef struct
39{
40 const char* layout; /* XKB Keyboard layout */
41 INT64 keyboardLayoutID; /* Keyboard Layout ID */
42 const XKB_VARIANT* variants;
43} XKB_LAYOUT;
44
45/* Those have been generated automatically and are waiting to be filled by hand */
46
47/* USA */
48static const XKB_VARIANT us_variants[] = {
49 { "chr", 0 }, /* Cherokee */
50 { "euro", 0 }, /* With EuroSign on 5 */
51 { "intl", KBD_UNITED_STATES_INTERNATIONAL }, /* International (with dead keys) */
52 { "alt-intl",
53 KBD_UNITED_STATES_INTERNATIONAL }, /* Alternative international (former us_intl) */
54 { "colemak", 0 }, /* Colemak */
55 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
56 { "dvorak-intl", KBD_UNITED_STATES_DVORAK }, /* Dvorak international */
57 { "dvorak-l", KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND }, /* Left handed Dvorak */
58 { "dvorak-r", KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND }, /* Right handed Dvorak */
59 { "dvorak-classic", KBD_UNITED_STATES_DVORAK }, /* Classic Dvorak */
60 { "dvp", KBD_UNITED_STATES_DVORAK_PROGRAMMER }, /* Programmer Dvorak */
61 { "rus", 0 }, /* Russian phonetic */
62 { "mac", KBD_US }, /* Macintosh */
63 { "altgr-intl", KBD_UNITED_STATES_INTERNATIONAL }, /* International (AltGr dead keys) */
64 { "olpc2", KBD_US }, /* Group toggle on multiply/divide key */
65 { "", 0 },
66};
67
68/* Afghanistan */
69static const XKB_VARIANT af_variants[] = {
70 { "ps", KBD_PASHTO }, /* Pashto */
71 { "uz", KBD_UZBEK_CYRILLIC }, /* Southern Uzbek */
72 { "olpc-ps", KBD_PASHTO }, /* OLPC Pashto */
73 { "olpc-fa", 0 }, /* OLPC Dari */
74 { "olpc-uz", KBD_UZBEK_CYRILLIC }, /* OLPC Southern Uzbek */
75 { "", 0 },
76};
77
78/* Arabic */
79static const XKB_VARIANT ara_variants[] = {
80 { "azerty", KBD_ARABIC_102_AZERTY }, /* azerty */
81 { "azerty_digits", KBD_ARABIC_102_AZERTY }, /* azerty/digits */
82 { "digits", KBD_ARABIC_102_AZERTY }, /* digits */
83 { "qwerty", KBD_ARABIC_101 }, /* qwerty */
84 { "qwerty_digits", KBD_ARABIC_101 }, /* qwerty/digits */
85 { "buckwalter", KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L }, /* Buckwalter */
86 { "", 0 },
87};
88
89/* Armenia */
90static const XKB_VARIANT am_variants[] = {
91 { "phonetic", 0 }, /* Phonetic */
92 { "phonetic-alt", 0 }, /* Alternative Phonetic */
93 { "eastern", KBD_ARMENIAN_EASTERN }, /* Eastern */
94 { "western", KBD_ARMENIAN_WESTERN }, /* Western */
95 { "eastern-alt", KBD_ARMENIAN_EASTERN }, /* Alternative Eastern */
96 { "", 0 },
97};
98
99/* Azerbaijan */
100static const XKB_VARIANT az_variants[] = {
101 { "cyrillic", KBD_AZERI_CYRILLIC }, /* Cyrillic */
102 { "", 0 },
103};
104
105/* Belarus */
106static const XKB_VARIANT by_variants[] = {
107 { "winkeys", KBD_BELARUSIAN }, /* Winkeys */
108 { "latin", KBD_BELARUSIAN }, /* Latin */
109 { "", 0 },
110};
111
112/* Belgium */
113static const XKB_VARIANT be_variants[] = {
114 { "oss", KBD_BELGIAN_FRENCH }, /* Alternative */
115 { "oss_latin9", KBD_BELGIAN_FRENCH }, /* Alternative, latin-9 only */
116 { "oss_sundeadkeys", KBD_BELGIAN_PERIOD }, /* Alternative, Sun dead keys */
117 { "iso-alternate", KBD_BELGIAN_COMMA }, /* ISO Alternate */
118 { "nodeadkeys", KBD_BELGIAN_COMMA }, /* Eliminate dead keys */
119 { "sundeadkeys", KBD_BELGIAN_PERIOD }, /* Sun dead keys */
120 { "wang", KBD_BELGIAN_FRENCH }, /* Wang model 724 azerty */
121 { "", 0 },
122};
123
124/* Bangladesh */
125static const XKB_VARIANT bd_variants[] = {
126 { "probhat", KBD_BENGALI_INSCRIPT }, /* Probhat */
127 { "", 0 },
128};
129
130/* India */
131static const XKB_VARIANT in_variants[] = {
132 { "ben", KBD_BENGALI }, /* Bengali */
133 { "ben_probhat", KBD_BENGALI_INSCRIPT }, /* Bengali Probhat */
134 { "guj", KBD_GUJARATI }, /* Gujarati */
135 { "guru", 0 }, /* Gurmukhi */
136 { "jhelum", 0 }, /* Gurmukhi Jhelum */
137 { "kan", KBD_KANNADA }, /* Kannada */
138 { "mal", KBD_MALAYALAM }, /* Malayalam */
139 { "mal_lalitha", KBD_MALAYALAM }, /* Malayalam Lalitha */
140 { "ori", 0 }, /* Oriya */
141 { "tam_unicode", KBD_TAMIL }, /* Tamil Unicode */
142 { "tam_TAB", KBD_TAMIL }, /* Tamil TAB Typewriter */
143 { "tam_TSCII", KBD_TAMIL }, /* Tamil TSCII Typewriter */
144 { "tam", KBD_TAMIL }, /* Tamil */
145 { "tel", KBD_TELUGU }, /* Telugu */
146 { "urd-phonetic", KBD_URDU }, /* Urdu, Phonetic */
147 { "urd-phonetic3", KBD_URDU }, /* Urdu, Alternative phonetic */
148 { "urd-winkeys", KBD_URDU }, /* Urdu, Winkeys */
149 { "bolnagri", KBD_HINDI_TRADITIONAL }, /* Hindi Bolnagri */
150 { "hin-wx", KBD_HINDI_TRADITIONAL }, /* Hindi Wx */
151 { "", 0 },
152};
153
154/* Bosnia and Herzegovina */
155static const XKB_VARIANT ba_variants[] = {
156 { "alternatequotes", KBD_BOSNIAN }, /* Use guillemets for quotes */
157 { "unicode", KBD_BOSNIAN }, /* Use Bosnian digraphs */
158 { "unicodeus", KBD_BOSNIAN }, /* US keyboard with Bosnian digraphs */
159 { "us", KBD_BOSNIAN_CYRILLIC }, /* US keyboard with Bosnian letters */
160 { "", 0 },
161};
162
163/* Brazil */
164static const XKB_VARIANT br_variants[] = {
165 { "nodeadkeys", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Eliminate dead keys */
166 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
167 { "nativo", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo */
168 { "nativo-us", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for USA keyboards */
169 { "nativo-epo", KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for Esperanto */
170 { "", 0 },
171};
172
173/* Bulgaria */
174static const XKB_VARIANT bg_variants[] = {
175 { "phonetic", KBD_BULGARIAN_LATIN }, /* Traditional Phonetic */
176 { "bas_phonetic", KBD_BULGARIAN_LATIN }, /* Standard Phonetic */
177 { "", 0 },
178};
179
180/* Morocco */
181static const XKB_VARIANT ma_variants[] = {
182 { "french", KBD_FRENCH }, /* French */
183 { "tifinagh", 0 }, /* Tifinagh */
184 { "tifinagh-alt", 0 }, /* Tifinagh Alternative */
185 { "tifinagh-alt-phonetic", 0 }, /* Tifinagh Alternative Phonetic */
186 { "tifinagh-extended", 0 }, /* Tifinagh Extended */
187 { "tifinagh-phonetic", 0 }, /* Tifinagh Phonetic */
188 { "tifinagh-extended-phonetic", 0 }, /* Tifinagh Extended Phonetic */
189 { "", 0 },
190};
191
192/* Canada */
193static const XKB_VARIANT ca_variants[] = {
194 { "fr", KBD_CANADIAN_FRENCH }, /* French Dvorak */
195 { "fr-dvorak", KBD_UNITED_STATES_DVORAK }, /* French Dvorak */
196 { "fr-legacy", KBD_CANADIAN_FRENCH_LEGACY }, /* French (legacy) */
197 { "multix", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual */
198 { "multi", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, first part */
199 { "multi-2gr", KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, second part */
200 { "ike", KBD_INUKTITUT_LATIN }, /* Inuktitut */
201 { "shs" /* codespell:ignore shs */, 0 }, /* Secwepemctsin */
202 { "kut", 0 }, /* Ktunaxa */
203 { "", 0 },
204};
205
206/* China */
207static const XKB_VARIANT cn_variants[] = {
208 { "tib", 0 }, /* Tibetan */
209 { "tib_asciinum", 0 }, /* Tibetan (with ASCII numerals) */
210 { "", 0 },
211};
212
213/* Croatia */
214static const XKB_VARIANT hr_variants[] = {
215 { "alternatequotes", KBD_CROATIAN }, /* Use guillemets for quotes */
216 { "unicode", KBD_CROATIAN }, /* Use Croatian digraphs */
217 { "unicodeus", KBD_CROATIAN }, /* US keyboard with Croatian digraphs */
218 { "us", KBD_CROATIAN }, /* US keyboard with Croatian letters */
219 { "", 0 },
220};
221
222/* Czechia */
223static const XKB_VARIANT cz_variants[] = {
224 { "bksl", KBD_CZECH_PROGRAMMERS }, /* With &lt;\|&gt; key */
225 { "qwerty", KBD_CZECH_QWERTY }, /* qwerty */
226 { "qwerty_bksl", KBD_CZECH_QWERTY }, /* qwerty, extended Backslash */
227 { "ucw", KBD_CZECH }, /* UCW layout (accented letters only) */
228 { "", 0 },
229};
230
231/* Denmark */
232static const XKB_VARIANT dk_variants[] = {
233 { "nodeadkeys", KBD_DANISH }, /* Eliminate dead keys */
234 { "mac", KBD_DANISH }, /* Macintosh */
235 { "mac_nodeadkeys", KBD_DANISH }, /* Macintosh, eliminate dead keys */
236 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
237 { "", 0 },
238};
239
240/* Netherlands */
241static const XKB_VARIANT nl_variants[] = {
242 { "sundeadkeys", KBD_SWISS_FRENCH }, /* Sun dead keys */
243 { "mac", KBD_SWISS_FRENCH }, /* Macintosh */
244 { "std", KBD_SWISS_FRENCH }, /* Standard */
245 { "", 0 },
246};
247
248/* Estonia */
249static const XKB_VARIANT ee_variants[] = {
250 { "nodeadkeys", KBD_US }, /* Eliminate dead keys */
251 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
252 { "us", KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Estonian letters */
253 { "", 0 },
254};
255
256/* Iran */
257static const XKB_VARIANT ir_variants[] = {
258 { "pro", 0 }, /* Pro */
259 { "keypad", 0 }, /* Keypad */
260 { "pro_keypad", 0 }, /* Pro Keypad */
261 { "ku", 0 }, /* Kurdish, Latin Q */
262 { "ku_f", 0 }, /* Kurdish, (F) */
263 { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */
264 { "ku_ara", 0 }, /* Kurdish, Arabic-Latin */
265 { "", 0 },
266};
267
268/* Iraq */
269static const XKB_VARIANT iq_variants[] = {
270 { "ku", 0 }, /* Kurdish, Latin Q */
271 { "ku_f", 0 }, /* Kurdish, (F) */
272 { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */
273 { "ku_ara", 0 }, /* Kurdish, Arabic-Latin */
274 { "", 0 },
275};
276
277/* Faroe Islands */
278static const XKB_VARIANT fo_variants[] = {
279 { "nodeadkeys", 0 }, /* Eliminate dead keys */
280 { "", 0 },
281};
282
283/* Finland */
284static const XKB_VARIANT fi_variants[] = {
285 { "nodeadkeys", 0 }, /* Eliminate dead keys */
286 { "smi", 0 }, /* Northern Saami */
287 { "classic", 0 }, /* Classic */
288 { "mac", 0 }, /* Macintosh */
289 { "", 0 },
290};
291
292/* France */
293static const XKB_VARIANT fr_variants[] = {
294 { "nodeadkeys", 0 }, /* Eliminate dead keys */
295 { "sundeadkeys", 0 }, /* Sun dead keys */
296 { "oss", 0 }, /* Alternative */
297 { "oss_latin9", 0 }, /* Alternative, latin-9 only */
298 { "oss_nodeadkeys", 0 }, /* Alternative, eliminate dead keys */
299 { "oss_sundeadkeys", 0 }, /* Alternative, Sun dead keys */
300 { "latin9", 0 }, /* (Legacy) Alternative */
301 { "latin9_nodeadkeys", 0 }, /* (Legacy) Alternative, eliminate dead keys */
302 { "latin9_sundeadkeys", 0 }, /* (Legacy) Alternative, Sun dead keys */
303 { "bepo", KBD_FRENCH_BEPO }, /* Bepo, ergonomic, Dvorak way */
304 { "bepo_latin9", 0 }, /* Bepo, ergonomic, Dvorak way, latin-9 only */
305 { "dvorak", 0 }, /* Dvorak */
306 { "mac", 0 }, /* Macintosh */
307 { "bre", 0 }, /* Breton */
308 { "oci", 0 }, /* Occitan */
309 { "geo", 0 }, /* Georgian AZERTY Tskapo */
310 { "", 0 },
311};
312
313/* Ghana */
314static const XKB_VARIANT gh_variants[] = {
315 { "generic", 0 }, /* Multilingual */
316 { "akan", 0 }, /* Akan */
317 { "ewe", 0 }, /* Ewe */
318 { "fula", 0 }, /* Fula */
319 { "ga", 0 }, /* Ga */
320 { "hausa", 0 }, /* Hausa */
321 { "", 0 },
322};
323
324/* Georgia */
325static const XKB_VARIANT ge_variants[] = {
326 { "ergonomic", 0 }, /* Ergonomic */
327 { "mess", 0 }, /* MESS */
328 { "ru", 0 }, /* Russian */
329 { "os", 0 }, /* Ossetian */
330 { "", 0 },
331};
332
333/* Germany */
334static const XKB_VARIANT de_variants[] = {
335 { "deadacute", KBD_GERMAN }, /* Dead acute */
336 { "deadgraveacute", KBD_GERMAN }, /* Dead grave acute */
337 { "nodeadkeys", KBD_GERMAN }, /* Eliminate dead keys */
338 { "ro", KBD_GERMAN }, /* Romanian keyboard with German letters */
339 { "ro_nodeadkeys",
340 KBD_GERMAN }, /* Romanian keyboard with German letters, eliminate dead keys */
341 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
342 { "sundeadkeys", KBD_GERMAN }, /* Sun dead keys */
343 { "neo", KBD_GERMAN_NEO }, /* Neo 2 */
344 { "mac", KBD_GERMAN }, /* Macintosh */
345 { "mac_nodeadkeys", KBD_GERMAN }, /* Macintosh, eliminate dead keys */
346 { "dsb", KBD_GERMAN }, /* Lower Sorbian */
347 { "dsb_qwertz", KBD_GERMAN }, /* Lower Sorbian (qwertz) */
348 { "qwerty", KBD_GERMAN_IBM }, /* qwerty */
349 { "", 0 },
350};
351
352/* Greece */
353static const XKB_VARIANT gr_variants[] = {
354 { "simple", KBD_GREEK_220 }, /* Simple */
355 { "extended", KBD_GREEK_319 }, /* Extended */
356 { "nodeadkeys", KBD_GREEK_319 }, /* Eliminate dead keys */
357 { "polytonic", KBD_GREEK_POLYTONIC }, /* Polytonic */
358 { "", 0 },
359};
360
361/* Hungary */
362static const XKB_VARIANT hu_variants[] = {
363 { "standard", KBD_HUNGARIAN_101_KEY }, /* Standard */
364 { "nodeadkeys", KBD_HUNGARIAN_101_KEY }, /* Eliminate dead keys */
365 { "qwerty", KBD_HUNGARIAN_101_KEY }, /* qwerty */
366 { "101_qwertz_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Dead keys */
367 { "101_qwertz_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Eliminate dead keys */
368 { "101_qwertz_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Dead keys */
369 { "101_qwertz_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Eliminate dead keys */
370 { "101_qwerty_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Dead keys */
371 { "101_qwerty_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Eliminate dead keys */
372 { "101_qwerty_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Dead keys */
373 { "101_qwerty_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Eliminate dead keys */
374 { "102_qwertz_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Dead keys */
375 { "102_qwertz_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Eliminate dead keys */
376 { "102_qwertz_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Dead keys */
377 { "102_qwertz_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Eliminate dead keys */
378 { "102_qwerty_comma_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Dead keys */
379 { "102_qwerty_comma_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Eliminate dead keys */
380 { "102_qwerty_dot_dead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Dead keys */
381 { "102_qwerty_dot_nodead", KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Eliminate dead keys */
382 { "", 0 },
383};
384
385/* Iceland */
386static const XKB_VARIANT is_variants[] = {
387 { "Sundeadkeys", KBD_ICELANDIC }, /* Sun dead keys */
388 { "nodeadkeys", KBD_ICELANDIC }, /* Eliminate dead keys */
389 { "mac", KBD_ICELANDIC }, /* Macintosh */
390 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
391 { "", 0 },
392};
393
394/* Israel */
395static const XKB_VARIANT il_variants[] = {
396 { "lyx", KBD_HEBREW }, /* lyx */
397 { "phonetic", KBD_HEBREW }, /* Phonetic */
398 { "biblical", KBD_HEBREW }, /* Biblical Hebrew (Tiro) */
399 { "", 0 },
400};
401
402/* Italy */
403static const XKB_VARIANT it_variants[] = {
404 { "nodeadkeys", KBD_ITALIAN_142 }, /* Eliminate dead keys */
405 { "mac", KBD_ITALIAN }, /* Macintosh */
406 { "geo", KBD_GEORGIAN }, /* Georgian */
407 { "", 0 },
408};
409
410/* Japan */
411static const XKB_VARIANT jp_variants[] = {
412 { "kana", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Kana */
413 { "OADG109A", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* OADG 109A */
414 { "", 0 },
415};
416
417/* Kyrgyzstan */
418static const XKB_VARIANT kg_variants[] = {
419 { "phonetic", KBD_KYRGYZ_CYRILLIC }, /* Phonetic */
420 { "", 0 },
421};
422
423/* Kazakhstan */
424static const XKB_VARIANT kz_variants[] = {
425 { "ruskaz", KBD_KAZAKH }, /* Russian with Kazakh */
426 { "kazrus", KBD_KAZAKH }, /* Kazakh with Russian */
427 { "", 0 },
428};
429
430/* Latin America */
431static const XKB_VARIANT latam_variants[] = {
432 { "nodeadkeys", KBD_LATIN_AMERICAN }, /* Eliminate dead keys */
433 { "deadtilde", KBD_LATIN_AMERICAN }, /* Include dead tilde */
434 { "sundeadkeys", KBD_LATIN_AMERICAN }, /* Sun dead keys */
435 { "", 0 },
436};
437
438/* Lithuania */
439static const XKB_VARIANT lt_variants[] = {
440 { "std", KBD_LITHUANIAN }, /* Standard */
441 { "us", KBD_LITHUANIAN_IBM }, /* US keyboard with Lithuanian letters */
442 { "ibm", KBD_LITHUANIAN_IBM }, /* IBM (LST 1205-92) */
443 { "lekp", KBD_LITHUANIAN }, /* LEKP */
444 { "lekpa", KBD_LITHUANIAN }, /* LEKPa */
445 { "balticplus", KBD_LITHUANIAN }, /* Baltic+ */
446 { "", 0 },
447};
448
449/* Latvia */
450static const XKB_VARIANT lv_variants[] = {
451 { "apostrophe", KBD_LATVIAN }, /* Apostrophe (') variant */
452 { "tilde", KBD_LATVIAN }, /* Tilde (~) variant */
453 { "fkey", KBD_LATVIAN }, /* F-letter (F) variant */
454 { "", 0 },
455};
456
457/* Montenegro */
458static const XKB_VARIANT me_variants[] = {
459 { "cyrillic", 0 }, /* Cyrillic */
460 { "cyrillicyz", 0 }, /* Cyrillic, Z and ZHE swapped */
461 { "latinunicode", 0 }, /* Latin unicode */
462 { "latinyz", 0 }, /* Latin qwerty */
463 { "latinunicodeyz", 0 }, /* Latin unicode qwerty */
464 { "cyrillicalternatequotes", 0 }, /* Cyrillic with guillemets */
465 { "latinalternatequotes", 0 }, /* Latin with guillemets */
466 { "", 0 },
467};
468
469/* Macedonia */
470static const XKB_VARIANT mk_variants[] = {
471 { "nodeadkeys", KBD_FYRO_MACEDONIAN }, /* Eliminate dead keys */
472 { "", 0 },
473};
474
475/* Malta */
476static const XKB_VARIANT mt_variants[] = {
477 { "us", KBD_MALTESE_48_KEY }, /* Maltese keyboard with US layout */
478 { "", 0 },
479};
480
481/* Norway */
482static const XKB_VARIANT no_variants[] = {
483 { "nodeadkeys", KBD_NORWEGIAN }, /* Eliminate dead keys */
484 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
485 { "smi", KBD_NORWEGIAN_WITH_SAMI }, /* Northern Saami */
486 { "smi_nodeadkeys", KBD_SAMI_EXTENDED_NORWAY }, /* Northern Saami, eliminate dead keys */
487 { "mac", KBD_NORWEGIAN }, /* Macintosh */
488 { "mac_nodeadkeys", KBD_SAMI_EXTENDED_NORWAY }, /* Macintosh, eliminate dead keys */
489 { "", 0 },
490};
491
492/* Poland */
493static const XKB_VARIANT pl_variants[] = {
494 { "qwertz", KBD_POLISH_214 }, /* qwertz */
495 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
496 { "dvorak_quotes", KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on quotemark key */
497 { "dvorak_altquotes", KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on key 1 */
498 { "csb", 0 }, /* Kashubian */
499 { "ru_phonetic_dvorak", KBD_UNITED_STATES_DVORAK }, /* Russian phonetic Dvorak */
500 { "", 0 },
501};
502
503/* Portugal */
504static const XKB_VARIANT pt_variants[] = {
505 { "nodeadkeys", KBD_PORTUGUESE }, /* Eliminate dead keys */
506 { "sundeadkeys", KBD_PORTUGUESE }, /* Sun dead keys */
507 { "mac", KBD_PORTUGUESE }, /* Macintosh */
508 { "mac_nodeadkeys", KBD_PORTUGUESE }, /* Macintosh, eliminate dead keys */
509 { "mac_sundeadkeys", KBD_PORTUGUESE }, /* Macintosh, Sun dead keys */
510 { "nativo", KBD_PORTUGUESE }, /* Nativo */
511 { "nativo-us", KBD_PORTUGUESE }, /* Nativo for USA keyboards */
512 { "nativo-epo", KBD_PORTUGUESE }, /* Nativo for Esperanto */
513 { "", 0 },
514};
515
516/* Romania */
517static const XKB_VARIANT ro_variants[] = {
518 { "cedilla", KBD_ROMANIAN }, /* Cedilla */
519 { "std", KBD_ROMANIAN }, /* Standard */
520 { "std_cedilla", KBD_ROMANIAN }, /* Standard (Cedilla) */
521 { "winkeys", KBD_ROMANIAN }, /* Winkeys */
522 { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
523 { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
524 { "crh_dobruca1", KBD_TATAR }, /* Crimean Tatar (Dobruca-1 Q) */
525 { "crh_dobruca2", KBD_TATAR }, /* Crimean Tatar (Dobruca-2 Q) */
526 { "", 0 },
527};
528
529/* Russia */
530static const XKB_VARIANT ru_variants[] = {
531 { "phonetic", KBD_RUSSIAN }, /* Phonetic */
532 { "phonetic_winkeys", KBD_RUSSIAN }, /* Phonetic Winkeys */
533 { "typewriter", KBD_RUSSIAN_TYPEWRITER }, /* Typewriter */
534 { "legacy", KBD_RUSSIAN }, /* Legacy */
535 { "tt", KBD_TATAR }, /* Tatar */
536 { "os_legacy", 0 }, /* Ossetian, legacy */
537 { "os_winkeys", 0 }, /* Ossetian, Winkeys */
538 { "cv", 0 }, /* Chuvash */
539 { "cv_latin", 0 }, /* Chuvash Latin */
540 { "udm", 0 }, /* Udmurt */
541 { "kom", 0 }, /* Komi */
542 { "sah", 0 }, /* Yakut */
543 { "xal", 0 }, /* Kalmyk */
544 { "dos", 0 }, /* DOS */
545 { "", 0 },
546};
547
548/* Serbia */
549static const XKB_VARIANT rs_variants[] = {
550 { "yz", KBD_SERBIAN_CYRILLIC }, /* Z and ZHE swapped */
551 { "latin", KBD_SERBIAN_LATIN }, /* Latin */
552 { "latinunicode", KBD_SERBIAN_LATIN }, /* Latin Unicode */
553 { "latinyz", KBD_SERBIAN_LATIN }, /* Latin qwerty */
554 { "latinunicodeyz", KBD_SERBIAN_LATIN }, /* Latin Unicode qwerty */
555 { "alternatequotes", KBD_SERBIAN_CYRILLIC }, /* With guillemets */
556 { "latinalternatequotes", KBD_SERBIAN_LATIN }, /* Latin with guillemets */
557 { "", 0 },
558};
559
560/* Slovenia */
561static const XKB_VARIANT si_variants[] = {
562 { "alternatequotes", KBD_SLOVENIAN }, /* Use guillemets for quotes */
563 { "us", KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Slovenian letters */
564 { "", 0 },
565};
566
567/* Slovakia */
568static const XKB_VARIANT sk_variants[] = {
569 { "bksl", KBD_SLOVAK }, /* Extended Backslash */
570 { "qwerty", KBD_SLOVAK_QWERTY }, /* qwerty */
571 { "qwerty_bksl", KBD_SLOVAK_QWERTY }, /* qwerty, extended Backslash */
572 { "", 0 },
573};
574
575/* Spain */
576static const XKB_VARIANT es_variants[] = {
577 { "nodeadkeys", KBD_SPANISH_VARIATION }, /* Eliminate dead keys */
578 { "deadtilde", KBD_SPANISH_VARIATION }, /* Include dead tilde */
579 { "sundeadkeys", KBD_SPANISH }, /* Sun dead keys */
580 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
581 { "ast", KBD_SPANISH_VARIATION }, /* Asturian variant with bottom-dot H and bottom-dot L */
582 { "cat", KBD_SPANISH_VARIATION }, /* Catalan variant with middle-dot L */
583 { "mac", KBD_SPANISH }, /* Macintosh */
584 { "", 0 },
585};
586
587/* Sweden */
588static const XKB_VARIANT se_variants[] = {
589 { "nodeadkeys", KBD_SWEDISH }, /* Eliminate dead keys */
590 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
591 { "rus", KBD_RUSSIAN }, /* Russian phonetic */
592 { "rus_nodeadkeys", KBD_RUSSIAN }, /* Russian phonetic, eliminate dead keys */
593 { "smi", KBD_SWEDISH_WITH_SAMI }, /* Northern Saami */
594 { "mac", KBD_SWEDISH }, /* Macintosh */
595 { "svdvorak", KBD_UNITED_STATES_DVORAK }, /* Svdvorak */
596 { "", 0 },
597};
598
599/* Switzerland */
600static const XKB_VARIANT ch_variants[] = {
601 { "de_nodeadkeys", KBD_SWISS_GERMAN }, /* German, eliminate dead keys */
602 { "de_sundeadkeys", KBD_SWISS_GERMAN }, /* German, Sun dead keys */
603 { "fr", KBD_SWISS_FRENCH }, /* French */
604 { "fr_nodeadkeys", KBD_SWISS_FRENCH }, /* French, eliminate dead keys */
605 { "fr_sundeadkeys", KBD_SWISS_FRENCH }, /* French, Sun dead keys */
606 { "fr_mac", KBD_SWISS_FRENCH }, /* French (Macintosh) */
607 { "de_mac", KBD_SWISS_GERMAN }, /* German (Macintosh) */
608 { "", 0 },
609};
610
611/* Syria */
612static const XKB_VARIANT sy_variants[] = {
613 { "syc", KBD_SYRIAC }, /* Syriac */
614 { "syc_phonetic", KBD_SYRIAC_PHONETIC }, /* Syriac phonetic */
615 { "ku", 0 }, /* Kurdish, Latin Q */
616 { "ku_f", 0 }, /* Kurdish, (F) */
617 { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */
618 { "", 0 },
619};
620
621/* Tajikistan */
622static const XKB_VARIANT tj_variants[] = {
623 { "legacy", 0 }, /* Legacy */
624 { "", 0 },
625};
626
627/* Sri Lanka */
628static const XKB_VARIANT lk_variants[] = {
629 { "tam_unicode", KBD_TAMIL }, /* Tamil Unicode */
630 { "tam_TAB", KBD_TAMIL }, /* Tamil TAB Typewriter */
631 { "", 0 },
632};
633
634/* Thailand */
635static const XKB_VARIANT th_variants[] = {
636 { "tis", KBD_THAI_KEDMANEE_NON_SHIFTLOCK }, /* TIS-820.2538 */
637 { "pat", KBD_THAI_PATTACHOTE }, /* Pattachote */
638 { "", 0 },
639};
640
641/* Turkey */
642static const XKB_VARIANT tr_variants[] = {
643 { "f", KBD_TURKISH_F }, /* (F) */
644 { "alt", KBD_TURKISH_Q }, /* Alt-Q */
645 { "sundeadkeys", KBD_TURKISH_F }, /* Sun dead keys */
646 { "ku", 0 }, /* Kurdish, Latin Q */
647 { "ku_f", 0 }, /* Kurdish, (F) */
648 { "ku_alt", 0 }, /* Kurdish, Latin Alt-Q */
649 { "intl", KBD_TURKISH_F }, /* International (with dead keys) */
650 { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
651 { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
652 { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
653 { "", 0 },
654};
655
656/* Ukraine */
657static const XKB_VARIANT ua_variants[] = {
658 { "phonetic", KBD_UKRAINIAN }, /* Phonetic */
659 { "typewriter", KBD_UKRAINIAN }, /* Typewriter */
660 { "winkeys", KBD_UKRAINIAN }, /* Winkeys */
661 { "legacy", KBD_UKRAINIAN }, /* Legacy */
662 { "rstu", KBD_UKRAINIAN }, /* Standard RSTU */
663 { "rstu_ru", KBD_UKRAINIAN }, /* Standard RSTU on Russian layout */
664 { "homophonic", KBD_UKRAINIAN }, /* Homophonic */
665 { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
666 { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
667 { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
668 { "", 0 },
669};
670
671/* United Kingdom */
672static const XKB_VARIANT gb_variants[] = {
673 { "extd", KBD_UNITED_KINGDOM_EXTENDED }, /* Extended - Winkeys */
674 { "intl", KBD_UNITED_KINGDOM_EXTENDED }, /* International (with dead keys) */
675 { "dvorak", KBD_UNITED_STATES_DVORAK }, /* Dvorak */
676 { "dvorakukp", KBD_UNITED_STATES_DVORAK }, /* Dvorak (UK Punctuation) */
677 { "mac", KBD_UNITED_KINGDOM }, /* Macintosh */
678 { "colemak", 0 }, /* Colemak */
679 { "", 0 },
680};
681
682/* Uzbekistan */
683static const XKB_VARIANT uz_variants[] = {
684 { "latin", 0 }, /* Latin */
685 { "crh", KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
686 { "crh_f", KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
687 { "crh_alt", KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
688 { "", 0 },
689};
690
691/* Korea, Republic of */
692static const XKB_VARIANT kr_variants[] = {
693 { "kr104", KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* 101/104 key Compatible */
694 { "", 0 },
695};
696
697/* Ireland */
698static const XKB_VARIANT ie_variants[] = {
699 { "CloGaelach", KBD_GAELIC }, /* CloGaelach */
700 { "UnicodeExpert", KBD_GAELIC }, /* UnicodeExpert */
701 { "ogam", KBD_GAELIC }, /* Ogham */
702 { "ogam_is434", KBD_GAELIC }, /* Ogham IS434 */
703 { "", 0 },
704};
705
706/* Pakistan */
707static const XKB_VARIANT pk_variants[] = {
708 { "urd-crulp", 0 }, /* CRULP */
709 { "urd-nla", 0 }, /* NLA */
710 { "ara", KBD_ARABIC_101 }, /* Arabic */
711 { "", 0 },
712};
713
714/* Esperanto */
715static const XKB_VARIANT epo_variants[] = {
716 { "legacy", 0 }, /* displaced semicolon and quote (obsolete) */
717 { "", 0 },
718};
719
720/* Nigeria */
721static const XKB_VARIANT ng_variants[] = {
722 { "igbo", 0 }, /* Igbo */
723 { "yoruba", 0 }, /* Yoruba */
724 { "hausa", 0 }, /* Hausa */
725 { "", 0 },
726};
727
728/* Braille */
729static const XKB_VARIANT brai_variants[] = {
730 { "left_hand", 0 }, /* Left hand */
731 { "right_hand", 0 }, /* Right hand */
732 { "", 0 },
733};
734
735/* Turkmenistan */
736static const XKB_VARIANT tm_variants[] = {
737 { "alt", KBD_TURKISH_Q }, /* Alt-Q */
738 { "", 0 },
739};
740
741static const XKB_LAYOUT xkbLayouts[] = {
742 { "us", KBD_US, us_variants }, /* USA */
743 { "ad", 0, NULL }, /* Andorra */
744 { "af", KBD_FARSI, af_variants }, /* Afghanistan */
745 { "ara", KBD_ARABIC_101, ara_variants }, /* Arabic */
746 { "al", 0, NULL }, /* Albania */
747 { "am", KBD_ARMENIAN_EASTERN, am_variants }, /* Armenia */
748 { "az", KBD_AZERI_CYRILLIC, az_variants }, /* Azerbaijan */
749 { "by", KBD_BELARUSIAN, by_variants }, /* Belarus */
750 { "be", KBD_BELGIAN_FRENCH, be_variants }, /* Belgium */
751 { "bd", KBD_BENGALI, bd_variants }, /* Bangladesh */
752 { "in", KBD_HINDI_TRADITIONAL, in_variants }, /* India */
753 { "ba", KBD_CROATIAN, ba_variants }, /* Bosnia and Herzegovina */
754 { "br", KBD_PORTUGUESE_BRAZILIAN_ABNT, br_variants }, /* Brazil */
755 { "bg", KBD_BULGARIAN_LATIN, bg_variants }, /* Bulgaria */
756 { "ma", KBD_FRENCH, ma_variants }, /* Morocco */
757 { "mm", 0, NULL }, /* Myanmar */
758 { "ca", KBD_US, ca_variants }, /* Canada */
759 { "cd", 0, NULL }, /* Congo, Democratic Republic of the */
760 { "cn", KBD_CHINESE_TRADITIONAL_PHONETIC, cn_variants }, /* China */
761 { "hr", KBD_CROATIAN, hr_variants }, /* Croatia */
762 { "cz", KBD_CZECH, cz_variants }, /* Czechia */
763 { "dk", KBD_DANISH, dk_variants }, /* Denmark */
764 { "nl", KBD_DUTCH, nl_variants }, /* Netherlands */
765 { "bt", 0, NULL }, /* Bhutan */
766 { "ee", KBD_ESTONIAN, ee_variants }, /* Estonia */
767 { "ir", 0, ir_variants }, /* Iran */
768 { "iq", 0, iq_variants }, /* Iraq */
769 { "fo", 0, fo_variants }, /* Faroe Islands */
770 { "fi", KBD_FINNISH, fi_variants }, /* Finland */
771 { "fr", KBD_FRENCH, fr_variants }, /* France */
772 { "gh", 0, gh_variants }, /* Ghana */
773 { "gn", 0, NULL }, /* Guinea */
774 { "ge", KBD_GEORGIAN, ge_variants }, /* Georgia */
775 { "at", KBD_GERMAN, de_variants }, /* Austria */
776 { "de", KBD_GERMAN, de_variants }, /* Germany */
777 { "gr", KBD_GREEK, gr_variants }, /* Greece */
778 { "hu", KBD_HUNGARIAN, hu_variants }, /* Hungary */
779 { "is", KBD_ICELANDIC, is_variants }, /* Iceland */
780 { "il", KBD_HEBREW, il_variants }, /* Israel */
781 { "it", KBD_ITALIAN, it_variants }, /* Italy */
782 { "jp", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, jp_variants }, /* Japan */
783 { "kg", 0, kg_variants }, /* Kyrgyzstan */
784 { "kh", 0, NULL }, /* Cambodia */
785 { "kz", KBD_KAZAKH, kz_variants }, /* Kazakhstan */
786 { "la", 0, NULL }, /* Laos */
787 { "latam", KBD_LATIN_AMERICAN, latam_variants }, /* Latin America */
788 { "lt", KBD_LITHUANIAN, lt_variants }, /* Lithuania */
789 { "lv", KBD_LATVIAN, lv_variants }, /* Latvia */
790 { "mao", KBD_MAORI, NULL }, /* Maori */
791 { "me", KBD_SERBIAN_LATIN, me_variants }, /* Montenegro */
792 { "mk", KBD_FYRO_MACEDONIAN, mk_variants }, /* Macedonia */
793 { "mt", KBD_MALTESE_48_KEY, mt_variants }, /* Malta */
794 { "mn", KBD_MONGOLIAN_CYRILLIC, NULL }, /* Mongolia */
795 { "no", KBD_NORWEGIAN, no_variants }, /* Norway */
796 { "pl", KBD_POLISH_PROGRAMMERS, pl_variants }, /* Poland */
797 { "pt", KBD_PORTUGUESE, pt_variants }, /* Portugal */
798 { "ro", KBD_ROMANIAN, ro_variants }, /* Romania */
799 { "ru", KBD_RUSSIAN, ru_variants }, /* Russia */
800 { "rs", KBD_SERBIAN_LATIN, rs_variants }, /* Serbia */
801 { "si", KBD_SLOVENIAN, si_variants }, /* Slovenia */
802 { "sk", KBD_SLOVAK, sk_variants }, /* Slovakia */
803 { "es", KBD_SPANISH, es_variants }, /* Spain */
804 { "se", KBD_SWEDISH, se_variants }, /* Sweden */
805 { "ch", KBD_SWISS_GERMAN, ch_variants }, /* Switzerland */
806 { "sy", KBD_SYRIAC, sy_variants }, /* Syria */
807 { "tj", 0, tj_variants }, /* Tajikistan */
808 { "lk", 0, lk_variants }, /* Sri Lanka */
809 { "th", KBD_THAI_KEDMANEE, th_variants }, /* Thailand */
810 { "tr", KBD_TURKISH_Q, tr_variants }, /* Turkey */
811 { "ua", KBD_UKRAINIAN, ua_variants }, /* Ukraine */
812 { "gb", KBD_UNITED_KINGDOM, gb_variants }, /* United Kingdom */
813 { "uz", KBD_UZBEK_CYRILLIC, uz_variants }, /* Uzbekistan */
814 { "vn", KBD_VIETNAMESE, NULL }, /* Vietnam */
815 { "kr", KBD_KOREAN_INPUT_SYSTEM_IME_2000, kr_variants }, /* Korea, Republic of */
816 { "ie", KBD_UNITED_KINGDOM, ie_variants }, /* Ireland */
817 { "pk", 0, pk_variants }, /* Pakistan */
818 { "mv", 0, NULL }, /* Maldives */
819 { "za", KBD_US, NULL }, /* South Africa */
820 { "epo", 0, epo_variants }, /* Esperanto */
821 { "np", KBD_NEPALI, NULL }, /* Nepal */
822 { "ng", 0, ng_variants }, /* Nigeria */
823 { "et", 0, NULL }, /* Ethiopia */
824 { "sn", 0, NULL }, /* Senegal */
825 { "brai", 0, brai_variants }, /* Braille */
826 { "tm", KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */
827};
828
829static uint32_t convert(int64_t val)
830{
831 WINPR_ASSERT(val <= UINT32_MAX);
832 WINPR_ASSERT(val >= INT32_MIN);
833 return WINPR_CXX_COMPAT_CAST(uint32_t, val);
834}
835
836static UINT32 find_keyboard_layout_variant(const XKB_LAYOUT* layout, const char* variant)
837{
838 WINPR_ASSERT(layout);
839 WINPR_ASSERT(variant);
840
841 const XKB_VARIANT* variants = layout->variants;
842 if (variants)
843 {
844 const XKB_VARIANT* var = variants;
845 while (var->variant && (strlen(var->variant) != 0))
846 {
847 if (strcmp(var->variant, variant) == 0)
848 return convert(var->keyboardLayoutID);
849 var++;
850 }
851 }
852
853 return convert(layout->keyboardLayoutID);
854}
855
856UINT32 find_keyboard_layout_in_xorg_rules(const char* layout, const char* variant)
857{
858 if ((layout == NULL) || (variant == NULL))
859 return 0;
860
861 DEBUG_KBD("xkbLayout: %s\txkbVariant: %s", layout, variant);
862
863 for (size_t i = 0; i < ARRAYSIZE(xkbLayouts); i++)
864 {
865 const XKB_LAYOUT* cur = &xkbLayouts[i];
866 if (strcmp(cur->layout, layout) == 0)
867 return find_keyboard_layout_variant(cur, variant);
868 }
869
870 return 0;
871}