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