Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-kbd / x_layout_id_table.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
24 #include "libkbd.h"
25 #include <freerdp/kbd/layouts.h>
26
27 #include "x_layout_id_table.h"
28
29 typedef struct
30 {
31         /* XKB Keyboard layout variant */
32         const char* variant;
33
34         /* Keyboard Layout ID */
35         unsigned int keyboardLayoutID;
36
37 } xkbVariant;
38
39 typedef struct
40 {
41         /* XKB Keyboard layout */
42         const char* layout;
43
44         /* Keyboard Layout ID */
45         unsigned int keyboardLayoutID;
46
47         const xkbVariant* variants;
48
49 } xkbLayout;
50
51 /* Those have been generated automatically and are waiting to be filled by hand */
52
53 /* USA */
54 static const xkbVariant us_variants[] =
55 {
56         { "chr",                0 }, /* Cherokee */
57         { "euro",               0 }, /* With EuroSign on 5 */
58         { "intl",               KBD_UNITED_STATES_INTERNATIONAL }, /* International (with dead keys) */
59         { "alt-intl",           KBD_UNITED_STATES_INTERNATIONAL }, /* Alternative international (former us_intl) */
60         { "colemak",            0 }, /* Colemak */
61         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
62         { "dvorak-intl",        KBD_UNITED_STATES_DVORAK }, /* Dvorak international */
63         { "dvorak-l",           KBD_UNITED_STATES_DVORAK_FOR_LEFT_HAND }, /* Left handed Dvorak */
64         { "dvorak-r",           KBD_UNITED_STATES_DVORAK_FOR_RIGHT_HAND }, /* Right handed Dvorak */
65         { "dvorak-classic",     KBD_UNITED_STATES_DVORAK }, /* Classic Dvorak */
66         { "dvp",                KBD_UNITED_STATES_DVORAK }, /* Programmer Dvorak */
67         { "rus",                0 }, /* Russian phonetic */
68         { "mac",                KBD_US }, /* Macintosh */
69         { "altgr-intl",         KBD_UNITED_STATES_INTERNATIONAL }, /* International (AltGr dead keys) */
70         { "olpc2",              KBD_US }, /* Group toggle on multiply/divide key */
71         { "",                   0 },
72 };
73
74 /* Afghanistan */
75 static const xkbVariant af_variants[] =
76 {
77         { "ps",                 KBD_PASHTO }, /* Pashto */
78         { "uz",                 KBD_UZBEK_CYRILLIC }, /* Southern Uzbek */
79         { "olpc-ps",            KBD_PASHTO }, /* OLPC Pashto */
80         { "olpc-fa",            0 }, /* OLPC Dari */
81         { "olpc-uz",            KBD_UZBEK_CYRILLIC }, /* OLPC Southern Uzbek */
82         { "",                   0 },
83 };
84
85 /* Arabic */
86 static const xkbVariant ara_variants[] =
87 {
88         { "azerty",             KBD_ARABIC_102_AZERTY }, /* azerty */
89         { "azerty_digits",      KBD_ARABIC_102_AZERTY }, /* azerty/digits */
90         { "digits",             KBD_ARABIC_102_AZERTY }, /* digits */
91         { "qwerty",             KBD_ARABIC_101 }, /* qwerty */
92         { "qwerty_digits",      KBD_ARABIC_101 }, /* qwerty/digits */
93         { "buckwalter",         KBD_US_ENGLISH_TABLE_FOR_IBM_ARABIC_238_L }, /* Buckwalter */
94         { "",                   0 },
95 };
96
97 /* Armenia */
98 static const xkbVariant am_variants[] =
99 {
100         { "phonetic",           0 }, /* Phonetic */
101         { "phonetic-alt",       0 }, /* Alternative Phonetic */
102         { "eastern",            KBD_ARMENIAN_EASTERN }, /* Eastern */
103         { "western",            KBD_ARMENIAN_WESTERN }, /* Western */
104         { "eastern-alt",        KBD_ARMENIAN_EASTERN }, /* Alternative Eastern */
105         { "",                   0 },
106 };
107
108 /* Azerbaijan */
109 static const xkbVariant az_variants[] =
110 {
111         { "cyrillic",           KBD_AZERI_CYRILLIC }, /* Cyrillic */
112         { "",                   0 },
113 };
114
115 /* Belarus */
116 static const xkbVariant by_variants[] =
117 {
118         { "winkeys",            KBD_BELARUSIAN }, /* Winkeys */
119         { "latin",              KBD_BELARUSIAN }, /* Latin */
120         { "",                   0 },
121 };
122
123 /* Belgium */
124 static const xkbVariant be_variants[] =
125 {
126         { "oss",                KBD_BELGIAN_FRENCH }, /* Alternative */
127         { "oss_latin9",         KBD_BELGIAN_FRENCH }, /* Alternative, latin-9 only */
128         { "oss_sundeadkeys",    KBD_BELGIAN_PERIOD }, /* Alternative, Sun dead keys */
129         { "iso-alternate",      KBD_BELGIAN_COMMA }, /* ISO Alternate */
130         { "nodeadkeys",         KBD_BELGIAN_COMMA }, /* Eliminate dead keys */
131         { "sundeadkeys",        KBD_BELGIAN_PERIOD }, /* Sun dead keys */
132         { "wang",               KBD_BELGIAN_FRENCH }, /* Wang model 724 azerty */
133         { "",                   0 },
134 };
135
136 /* Bangladesh */
137 static const xkbVariant bd_variants[] =
138 {
139         { "probhat",            KBD_BENGALI_INSCRIPT }, /* Probhat */
140         { "",                   0 },
141 };
142
143 /* India */
144 static const xkbVariant in_variants[] =
145 {
146         { "ben",                KBD_BENGALI }, /* Bengali */
147         { "ben_probhat",        KBD_BENGALI_INSCRIPT }, /* Bengali Probhat */
148         { "guj",                KBD_GUJARATI }, /* Gujarati */
149         { "guru",               0 }, /* Gurmukhi */
150         { "jhelum",             0 }, /* Gurmukhi Jhelum */
151         { "kan",                KBD_KANNADA }, /* Kannada */
152         { "mal",                KBD_MALAYALAM }, /* Malayalam */
153         { "mal_lalitha",        KBD_MALAYALAM }, /* Malayalam Lalitha */
154         { "ori",                0 }, /* Oriya */
155         { "tam_unicode",        KBD_TAMIL }, /* Tamil Unicode */
156         { "tam_TAB",            KBD_TAMIL }, /* Tamil TAB Typewriter */
157         { "tam_TSCII",          KBD_TAMIL }, /* Tamil TSCII Typewriter */
158         { "tam",                KBD_TAMIL }, /* Tamil */
159         { "tel",                KBD_TELUGU }, /* Telugu */
160         { "urd-phonetic",       KBD_URDU }, /* Urdu, Phonetic */
161         { "urd-phonetic3",      KBD_URDU }, /* Urdu, Alternative phonetic */
162         { "urd-winkeys",        KBD_URDU }, /* Urdu, Winkeys */
163         { "bolnagri",           KBD_HINDI_TRADITIONAL }, /* Hindi Bolnagri */
164         { "hin-wx",             KBD_HINDI_TRADITIONAL }, /* Hindi Wx */
165         { "",                   0 },
166 };
167
168 /* Bosnia and Herzegovina */
169 static const xkbVariant ba_variants[] =
170 {
171         { "alternatequotes",    KBD_BOSNIAN }, /* Use guillemets for quotes */
172         { "unicode",            KBD_BOSNIAN }, /* Use Bosnian digraphs */
173         { "unicodeus",          KBD_BOSNIAN }, /* US keyboard with Bosnian digraphs */
174         { "us",                 KBD_BOSNIAN_CYRILLIC }, /* US keyboard with Bosnian letters */
175         { "",                   0 },
176 };
177
178 /* Brazil */
179 static const xkbVariant br_variants[] =
180 {
181         { "nodeadkeys",         KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Eliminate dead keys */
182         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
183         { "nativo",             KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo */
184         { "nativo-us",          KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for USA keyboards */
185         { "nativo-epo",         KBD_PORTUGUESE_BRAZILIAN_ABNT2 }, /* Nativo for Esperanto */
186         { "",                   0 },
187 };
188
189 /* Bulgaria */
190 static const xkbVariant bg_variants[] =
191 {
192         { "phonetic",           KBD_BULGARIAN_LATIN }, /* Traditional Phonetic */
193         { "bas_phonetic",       KBD_BULGARIAN_LATIN }, /* Standard Phonetic */
194         { "",                   0 },
195 };
196
197 /* Morocco */
198 static const xkbVariant ma_variants[] =
199 {
200         { "french",                     KBD_FRENCH }, /* French */
201         { "tifinagh",                   0 }, /* Tifinagh */
202         { "tifinagh-alt",               0 }, /* Tifinagh Alternative */
203         { "tifinagh-alt-phonetic",      0 }, /* Tifinagh Alternative Phonetic */
204         { "tifinagh-extended",          0 }, /* Tifinagh Extended */
205         { "tifinagh-phonetic",          0 }, /* Tifinagh Phonetic */
206         { "tifinagh-extended-phonetic", 0 }, /* Tifinagh Extended Phonetic */
207         { "",                           0 },
208 };
209
210 /* Canada */
211 static const xkbVariant ca_variants[] =
212 {
213         { "fr-dvorak",          KBD_UNITED_STATES_DVORAK }, /* French Dvorak */
214         { "fr-legacy",          KBD_CANADIAN_FRENCH }, /* French (legacy) */
215         { "multix",             KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual */
216         { "multi",              KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, first part */
217         { "multi-2gr",          KBD_CANADIAN_MULTILINGUAL_STANDARD }, /* Multilingual, second part */
218         { "ike",                KBD_INUKTITUT_LATIN }, /* Inuktitut */
219         { "shs",                0 }, /* Secwepemctsin */
220         { "kut",                0 }, /* Ktunaxa */
221         { "eng",                KBD_US }, /* English */
222         { "",                   0 },
223 };
224
225 /* China */
226 static const xkbVariant cn_variants[] =
227 {
228         { "tib",                0 }, /* Tibetan */
229         { "tib_asciinum",       0 }, /* Tibetan (with ASCII numerals) */
230         { "",                   0 },
231 };
232
233 /* Croatia */
234 static const xkbVariant hr_variants[] =
235 {
236         { "alternatequotes",    KBD_CROATIAN }, /* Use guillemets for quotes */
237         { "unicode",            KBD_CROATIAN }, /* Use Croatian digraphs */
238         { "unicodeus",          KBD_CROATIAN }, /* US keyboard with Croatian digraphs */
239         { "us",                 KBD_CROATIAN }, /* US keyboard with Croatian letters */
240         { "",                   0 },
241 };
242
243 /* Czechia */
244 static const xkbVariant cz_variants[] =
245 {
246         { "bksl",               KBD_CZECH_PROGRAMMERS }, /* With &lt;\|&gt; key */
247         { "qwerty",             KBD_CZECH_QWERTY }, /* qwerty */
248         { "qwerty_bksl",        KBD_CZECH_QWERTY }, /* qwerty, extended Backslash */
249         { "ucw",                KBD_CZECH }, /* UCW layout (accented letters only) */
250         { "",                   0 },
251 };
252
253 /* Denmark */
254 static const xkbVariant dk_variants[] =
255 {
256         { "nodeadkeys",         KBD_DANISH }, /* Eliminate dead keys */
257         { "mac",                KBD_DANISH }, /* Macintosh */
258         { "mac_nodeadkeys",     KBD_DANISH }, /* Macintosh, eliminate dead keys */
259         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
260         { "",                   0 },
261 };
262
263 /* Netherlands */
264 static const xkbVariant nl_variants[] =
265 {
266         { "sundeadkeys",        KBD_SWISS_FRENCH }, /* Sun dead keys */
267         { "mac",                KBD_SWISS_FRENCH }, /* Macintosh */
268         { "std",                KBD_SWISS_FRENCH }, /* Standard */
269         { "",                   0 },
270 };
271
272 /* Estonia */
273 static const xkbVariant ee_variants[] =
274 {
275         { "nodeadkeys",         KBD_US }, /* Eliminate dead keys */
276         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
277         { "us",                 KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Estonian letters */
278         { "",                   0 },
279 };
280
281 /* Iran */
282 static const xkbVariant ir_variants[] =
283 {
284         { "pro",                0 }, /* Pro */
285         { "keypad",             0 }, /* Keypad */
286         { "pro_keypad",         0 }, /* Pro Keypad */
287         { "ku",                 0 }, /* Kurdish, Latin Q */
288         { "ku_f",               0 }, /* Kurdish, (F) */
289         { "ku_alt",             0 }, /* Kurdish, Latin Alt-Q */
290         { "ku_ara",             0 }, /* Kurdish, Arabic-Latin */
291         { "",                   0 },
292 };
293
294 /* Iraq */
295 static const xkbVariant iq_variants[] =
296 {
297         { "ku",                 0 }, /* Kurdish, Latin Q */
298         { "ku_f",               0 }, /* Kurdish, (F) */
299         { "ku_alt",             0 }, /* Kurdish, Latin Alt-Q */
300         { "ku_ara",             0 }, /* Kurdish, Arabic-Latin */
301         { "",                   0 },
302 };
303
304 /* Faroe Islands */
305 static const xkbVariant fo_variants[] =
306 {
307         { "nodeadkeys",         0 }, /* Eliminate dead keys */
308         { "",                   0 },
309 };
310
311 /* Finland */
312 static const xkbVariant fi_variants[] =
313 {
314         { "nodeadkeys",         0 }, /* Eliminate dead keys */
315         { "smi",                0 }, /* Northern Saami */
316         { "classic",            0 }, /* Classic */
317         { "mac",                0 }, /* Macintosh */
318         { "",                   0 },
319 };
320
321 /* France */
322 static const xkbVariant fr_variants[] =
323 {
324         { "nodeadkeys",         0 }, /* Eliminate dead keys */
325         { "sundeadkeys",        0 }, /* Sun dead keys */
326         { "oss",                0 }, /* Alternative */
327         { "oss_latin9",         0 }, /* Alternative, latin-9 only */
328         { "oss_nodeadkeys",     0 }, /* Alternative, eliminate dead keys */
329         { "oss_sundeadkeys",    0 }, /* Alternative, Sun dead keys */
330         { "latin9",             0 }, /* (Legacy) Alternative */
331         { "latin9_nodeadkeys",  0 }, /* (Legacy) Alternative, eliminate dead keys */
332         { "latin9_sundeadkeys", 0 }, /* (Legacy) Alternative, Sun dead keys */
333         { "bepo",               0 }, /* Bepo, ergonomic, Dvorak way */
334         { "bepo_latin9",        0 }, /* Bepo, ergonomic, Dvorak way, latin-9 only */
335         { "dvorak",             0 }, /* Dvorak */
336         { "mac",                0 }, /* Macintosh */
337         { "bre",                0 }, /* Breton */
338         { "oci",                0 }, /* Occitan */
339         { "geo",                0 }, /* Georgian AZERTY Tskapo */
340         { "",                   0 },
341 };
342
343 /* Ghana */
344 static const xkbVariant gh_variants[] =
345 {
346         { "generic",            0 }, /* Multilingual */
347         { "akan",               0 }, /* Akan */
348         { "ewe",                0 }, /* Ewe */
349         { "fula",               0 }, /* Fula */
350         { "ga",                 0 }, /* Ga */
351         { "hausa",              0 }, /* Hausa */
352         { "",                   0 },
353 };
354
355 /* Georgia */
356 static const xkbVariant ge_variants[] =
357 {
358         { "ergonomic",          0 }, /* Ergonomic */
359         { "mess",               0 }, /* MESS */
360         { "ru",                 0 }, /* Russian */
361         { "os",                 0 }, /* Ossetian */
362         { "",                   0 },
363 };
364
365 /* Germany */
366 static const xkbVariant de_variants[] =
367 {
368         { "deadacute",          KBD_GERMAN }, /* Dead acute */
369         { "deadgraveacute",     KBD_GERMAN }, /* Dead grave acute */
370         { "nodeadkeys",         KBD_GERMAN }, /* Eliminate dead keys */
371         { "ro",                 KBD_GERMAN }, /* Romanian keyboard with German letters */
372         { "ro_nodeadkeys",      KBD_GERMAN }, /* Romanian keyboard with German letters, eliminate dead keys */
373         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
374         { "sundeadkeys",        KBD_GERMAN }, /* Sun dead keys */
375         { "neo",                KBD_GERMAN_NEO }, /* Neo 2 */
376         { "mac",                KBD_GERMAN }, /* Macintosh */
377         { "mac_nodeadkeys",     KBD_GERMAN }, /* Macintosh, eliminate dead keys */
378         { "dsb",                KBD_GERMAN }, /* Lower Sorbian */
379         { "dsb_qwertz",         KBD_GERMAN }, /* Lower Sorbian (qwertz) */
380         { "qwerty",             KBD_GERMAN_IBM }, /* qwerty */
381         { "",                   0 },
382 };
383
384 /* Greece */
385 static const xkbVariant gr_variants[] =
386 {
387         { "simple",             KBD_GREEK_220 }, /* Simple */
388         { "extended",           KBD_GREEK_319 }, /* Extended */
389         { "nodeadkeys",         KBD_GREEK_319}, /* Eliminate dead keys */
390         { "polytonic",          KBD_GREEK_POLYTONIC }, /* Polytonic */
391         { "",                   0 },
392 };
393
394 /* Hungary */
395 static const xkbVariant hu_variants[] =
396 {
397         { "standard",                           KBD_HUNGARIAN_101_KEY }, /* Standard */
398         { "nodeadkeys",                         KBD_HUNGARIAN_101_KEY }, /* Eliminate dead keys */
399         { "qwerty",                             KBD_HUNGARIAN_101_KEY }, /* qwerty */
400         { "101_qwertz_comma_dead",              KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Dead keys */
401         { "101_qwertz_comma_nodead",            KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/comma/Eliminate dead keys */
402         { "101_qwertz_dot_dead",                KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Dead keys */
403         { "101_qwertz_dot_nodead",              KBD_HUNGARIAN_101_KEY }, /* 101/qwertz/dot/Eliminate dead keys */
404         { "101_qwerty_comma_dead",              KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Dead keys */
405         { "101_qwerty_comma_nodead",            KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/comma/Eliminate dead keys */
406         { "101_qwerty_dot_dead",                KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Dead keys */
407         { "101_qwerty_dot_nodead",              KBD_HUNGARIAN_101_KEY }, /* 101/qwerty/dot/Eliminate dead keys */
408         { "102_qwertz_comma_dead",              KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Dead keys */
409         { "102_qwertz_comma_nodead",            KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/comma/Eliminate dead keys */
410         { "102_qwertz_dot_dead",                KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Dead keys */
411         { "102_qwertz_dot_nodead",              KBD_HUNGARIAN_101_KEY }, /* 102/qwertz/dot/Eliminate dead keys */
412         { "102_qwerty_comma_dead",              KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Dead keys */
413         { "102_qwerty_comma_nodead",            KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/comma/Eliminate dead keys */
414         { "102_qwerty_dot_dead",                KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Dead keys */
415         { "102_qwerty_dot_nodead",              KBD_HUNGARIAN_101_KEY }, /* 102/qwerty/dot/Eliminate dead keys */
416         { "",                                   0 },
417 };
418
419 /* Iceland */
420 static const xkbVariant is_variants[] =
421 {
422         { "Sundeadkeys",        KBD_ICELANDIC }, /* Sun dead keys */
423         { "nodeadkeys",         KBD_ICELANDIC }, /* Eliminate dead keys */
424         { "mac",                KBD_ICELANDIC }, /* Macintosh */
425         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
426         { "",                   0 },
427 };
428
429 /* Israel */
430 static const xkbVariant il_variants[] =
431 {
432         { "lyx",                KBD_HEBREW }, /* lyx */
433         { "phonetic",           KBD_HEBREW }, /* Phonetic */
434         { "biblical",           KBD_HEBREW }, /* Biblical Hebrew (Tiro) */
435         { "",                   0 },
436 };
437
438 /* Italy */
439 static const xkbVariant it_variants[] =
440 {
441         { "nodeadkeys",         KBD_ITALIAN_142 }, /* Eliminate dead keys */
442         { "mac",                KBD_ITALIAN }, /* Macintosh */
443         { "geo",                KBD_GEORGIAN }, /* Georgian */
444         { "",                   0 },
445 };
446
447 /* Japan */
448 static const xkbVariant jp_variants[] =
449 {
450         { "kana",               KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* Kana */
451         { "OADG109A",           KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002 }, /* OADG 109A */
452         { "",                   0 },
453 };
454
455 /* Kyrgyzstan */
456 static const xkbVariant kg_variants[] =
457 {
458         { "phonetic",           KBD_KYRGYZ_CYRILLIC }, /* Phonetic */
459         { "",                   0 },
460 };
461
462 /* Kazakhstan */
463 static const xkbVariant kz_variants[] =
464 {
465         { "ruskaz",             KBD_KAZAKH }, /* Russian with Kazakh */
466         { "kazrus",             KBD_KAZAKH }, /* Kazakh with Russian */
467         { "",                   0 },
468 };
469
470 /* Latin America */
471 static const xkbVariant latam_variants[] =
472 {
473         { "nodeadkeys",         KBD_LATIN_AMERICAN }, /* Eliminate dead keys */
474         { "deadtilde",          KBD_LATIN_AMERICAN }, /* Include dead tilde */
475         { "sundeadkeys",        KBD_LATIN_AMERICAN }, /* Sun dead keys */
476         { "",                   0 },
477 };
478
479 /* Lithuania */
480 static const xkbVariant lt_variants[] =
481 {
482         { "std",                KBD_LITHUANIAN }, /* Standard */
483         { "us",                 KBD_LITHUANIAN_IBM }, /* US keyboard with Lithuanian letters */
484         { "ibm",                KBD_LITHUANIAN_IBM }, /* IBM (LST 1205-92) */
485         { "lekp",               KBD_LITHUANIAN }, /* LEKP */
486         { "lekpa",              KBD_LITHUANIAN }, /* LEKPa */
487         { "balticplus",         KBD_LITHUANIAN }, /* Baltic+ */
488         { "",                   0 },
489 };
490
491 /* Latvia */
492 static const xkbVariant lv_variants[] =
493 {
494         { "apostrophe",         KBD_LATVIAN }, /* Apostrophe (') variant */
495         { "tilde",              KBD_LATVIAN }, /* Tilde (~) variant */
496         { "fkey",               KBD_LATVIAN }, /* F-letter (F) variant */
497         { "",                   0 },
498 };
499
500 /* Montenegro */
501 static const xkbVariant me_variants[] =
502 {
503         { "cyrillic",                   0 }, /* Cyrillic */
504         { "cyrillicyz",                 0 }, /* Cyrillic, Z and ZHE swapped */
505         { "latinunicode",               0 }, /* Latin unicode */
506         { "latinyz",                    0 }, /* Latin qwerty */
507         { "latinunicodeyz",             0 }, /* Latin unicode qwerty */
508         { "cyrillicalternatequotes",    0 }, /* Cyrillic with guillemets */
509         { "latinalternatequotes",       0 }, /* Latin with guillemets */
510         { "",                   0 },
511 };
512
513 /* Macedonia */
514 static const xkbVariant mk_variants[] =
515 {
516         { "nodeadkeys",         KBD_FYRO_MACEDONIAN }, /* Eliminate dead keys */
517         { "",                   0 },
518 };
519
520 /* Malta */
521 static const xkbVariant mt_variants[] =
522 {
523         { "us",                 KBD_MALTESE_48_KEY }, /* Maltese keyboard with US layout */
524         { "",                   0 },
525 };
526
527 /* Norway */
528 static const xkbVariant no_variants[] =
529 {
530         { "nodeadkeys",         KBD_NORWEGIAN }, /* Eliminate dead keys */
531         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
532         { "smi",                KBD_NORWEGIAN_WITH_SAMI }, /* Northern Saami */
533         { "smi_nodeadkeys",     KBD_SAMI_EXTENDED_NORWAY }, /* Northern Saami, eliminate dead keys */
534         { "mac",                KBD_NORWEGIAN }, /* Macintosh */
535         { "mac_nodeadkeys",     KBD_SAMI_EXTENDED_NORWAY }, /* Macintosh, eliminate dead keys */
536         { "",                   0 },
537 };
538
539 /* Poland */
540 static const xkbVariant pl_variants[] =
541 {
542         { "qwertz",             KBD_POLISH_214 }, /* qwertz */
543         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
544         { "dvorak_quotes",      KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on quotemark key */
545         { "dvorak_altquotes",   KBD_UNITED_STATES_DVORAK }, /* Dvorak, Polish quotes on key 1 */
546         { "csb",                0 }, /* Kashubian */
547         { "ru_phonetic_dvorak", KBD_UNITED_STATES_DVORAK }, /* Russian phonetic Dvorak */
548         { "",                   0 },
549 };
550
551 /* Portugal */
552 static const xkbVariant pt_variants[] =
553 {
554         { "nodeadkeys",         KBD_PORTUGUESE }, /* Eliminate dead keys */
555         { "sundeadkeys",        KBD_PORTUGUESE }, /* Sun dead keys */
556         { "mac",                KBD_PORTUGUESE }, /* Macintosh */
557         { "mac_nodeadkeys",     KBD_PORTUGUESE }, /* Macintosh, eliminate dead keys */
558         { "mac_sundeadkeys",    KBD_PORTUGUESE }, /* Macintosh, Sun dead keys */
559         { "nativo",             KBD_PORTUGUESE }, /* Nativo */
560         { "nativo-us",          KBD_PORTUGUESE }, /* Nativo for USA keyboards */
561         { "nativo-epo",         KBD_PORTUGUESE }, /* Nativo for Esperanto */
562         { "",                   0 },
563 };
564
565 /* Romania */
566 static const xkbVariant ro_variants[] =
567 {
568         { "cedilla",            KBD_ROMANIAN }, /* Cedilla */
569         { "std",                KBD_ROMANIAN }, /* Standard */
570         { "std_cedilla",        KBD_ROMANIAN }, /* Standard (Cedilla) */
571         { "winkeys",            KBD_ROMANIAN }, /* Winkeys */
572         { "crh_f",              KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
573         { "crh_alt",            KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
574         { "crh_dobruca1",       KBD_TATAR }, /* Crimean Tatar (Dobruca-1 Q) */
575         { "crh_dobruca2",       KBD_TATAR }, /* Crimean Tatar (Dobruca-2 Q) */
576         { "",                   0 },
577 };
578
579 /* Russia */
580 static const xkbVariant ru_variants[] =
581 {
582         { "phonetic",           KBD_RUSSIAN }, /* Phonetic */
583         { "phonetic_winkeys",   KBD_RUSSIAN }, /* Phonetic Winkeys */
584         { "typewriter",         KBD_RUSSIAN_TYPEWRITER }, /* Typewriter */
585         { "legacy",             KBD_RUSSIAN }, /* Legacy */
586         { "tt",                 KBD_TATAR }, /* Tatar */
587         { "os_legacy",          0 }, /* Ossetian, legacy */
588         { "os_winkeys",         0 }, /* Ossetian, Winkeys */
589         { "cv",                 0 }, /* Chuvash */
590         { "cv_latin",           0 }, /* Chuvash Latin */
591         { "udm",                0 }, /* Udmurt */
592         { "kom",                0 }, /* Komi */
593         { "sah",                0 }, /* Yakut */
594         { "xal",                0 }, /* Kalmyk */
595         { "dos",                0 }, /* DOS */
596         { "",                   0 },
597 };
598
599 /* Serbia */
600 static const xkbVariant rs_variants[] =
601 {
602         { "yz",                         KBD_SERBIAN_CYRILLIC }, /* Z and ZHE swapped */
603         { "latin",                      KBD_SERBIAN_LATIN }, /* Latin */
604         { "latinunicode",               KBD_SERBIAN_LATIN }, /* Latin Unicode */
605         { "latinyz",                    KBD_SERBIAN_LATIN }, /* Latin qwerty */
606         { "latinunicodeyz",             KBD_SERBIAN_LATIN }, /* Latin Unicode qwerty */
607         { "alternatequotes",            KBD_SERBIAN_CYRILLIC }, /* With guillemets */
608         { "latinalternatequotes",       KBD_SERBIAN_LATIN }, /* Latin with guillemets */
609         { "",                           0 },
610 };
611
612 /* Slovenia */
613 static const xkbVariant si_variants[] =
614 {
615         { "alternatequotes",    KBD_SLOVENIAN }, /* Use guillemets for quotes */
616         { "us",                 KBD_UNITED_STATES_INTERNATIONAL }, /* US keyboard with Slovenian letters */
617         { "",                   0 },
618 };
619
620 /* Slovakia */
621 static const xkbVariant sk_variants[] =
622 {
623         { "bksl",               KBD_SLOVAK }, /* Extended Backslash */
624         { "qwerty",             KBD_SLOVAK_QWERTY }, /* qwerty */
625         { "qwerty_bksl",        KBD_SLOVAK_QWERTY }, /* qwerty, extended Backslash */
626         { "",                   0 },
627 };
628
629 /* Spain */
630 static const xkbVariant es_variants[] =
631 {
632         { "nodeadkeys",         KBD_SPANISH_VARIATION }, /* Eliminate dead keys */
633         { "deadtilde",          KBD_SPANISH_VARIATION }, /* Include dead tilde */
634         { "sundeadkeys",        KBD_SPANISH }, /* Sun dead keys */
635         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
636         { "ast",                KBD_SPANISH_VARIATION }, /* Asturian variant with bottom-dot H and bottom-dot L */
637         { "cat",                KBD_SPANISH_VARIATION }, /* Catalan variant with middle-dot L */
638         { "mac",                KBD_SPANISH }, /* Macintosh */
639         { "",                   0 },
640 };
641
642 /* Sweden */
643 static const xkbVariant se_variants[] =
644 {
645         { "nodeadkeys",         KBD_SWEDISH }, /* Eliminate dead keys */
646         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
647         { "rus",                KBD_RUSSIAN }, /* Russian phonetic */
648         { "rus_nodeadkeys",     KBD_RUSSIAN }, /* Russian phonetic, eliminate dead keys */
649         { "smi",                KBD_SWEDISH_WITH_SAMI }, /* Northern Saami */
650         { "mac",                KBD_SWEDISH }, /* Macintosh */
651         { "svdvorak",           KBD_UNITED_STATES_DVORAK }, /* Svdvorak */
652         { "",                   0 },
653 };
654
655 /* Switzerland */
656 static const xkbVariant ch_variants[] =
657 {
658         { "de_nodeadkeys",      KBD_SWISS_GERMAN }, /* German, eliminate dead keys */
659         { "de_sundeadkeys",     KBD_SWISS_GERMAN }, /* German, Sun dead keys */
660         { "fr",                 KBD_SWISS_FRENCH }, /* French */
661         { "fr_nodeadkeys",      KBD_SWISS_FRENCH }, /* French, eliminate dead keys */
662         { "fr_sundeadkeys",     KBD_SWISS_FRENCH }, /* French, Sun dead keys */
663         { "fr_mac",             KBD_SWISS_FRENCH }, /* French (Macintosh) */
664         { "de_mac",             KBD_SWISS_GERMAN }, /* German (Macintosh) */
665         { "",                   0 },
666 };
667
668 /* Syria */
669 static const xkbVariant sy_variants[] =
670 {
671         { "syc",                KBD_SYRIAC }, /* Syriac */
672         { "syc_phonetic",       KBD_SYRIAC_PHONETIC }, /* Syriac phonetic */
673         { "ku",                 0 }, /* Kurdish, Latin Q */
674         { "ku_f",               0 }, /* Kurdish, (F) */
675         { "ku_alt",             0 }, /* Kurdish, Latin Alt-Q */
676         { "",                   0 },
677 };
678
679 /* Tajikistan */
680 static const xkbVariant tj_variants[] =
681 {
682         { "legacy",             0 }, /* Legacy */
683         { "",                   0 },
684 };
685
686 /* Sri Lanka */
687 static const xkbVariant lk_variants[] =
688 {
689         { "tam_unicode",        KBD_TAMIL }, /* Tamil Unicode */
690         { "tam_TAB",            KBD_TAMIL }, /* Tamil TAB Typewriter */
691         { "",                   0 },
692 };
693
694 /* Thailand */
695 static const xkbVariant th_variants[] =
696 {
697         { "tis",                KBD_THAI_KEDMANEE_NON_SHIFTLOCK }, /* TIS-820.2538 */
698         { "pat",                KBD_THAI_PATTACHOTE }, /* Pattachote */
699         { "",                   0 },
700 };
701
702 /* Turkey */
703 static const xkbVariant tr_variants[] =
704 {
705         { "f",                  KBD_TURKISH_F }, /* (F) */
706         { "alt",                KBD_TURKISH_Q }, /* Alt-Q */
707         { "sundeadkeys",        KBD_TURKISH_F }, /* Sun dead keys */
708         { "ku",                 0 }, /* Kurdish, Latin Q */
709         { "ku_f",               0 }, /* Kurdish, (F) */
710         { "ku_alt",             0 }, /* Kurdish, Latin Alt-Q */
711         { "intl",               KBD_TURKISH_F }, /* International (with dead keys) */
712         { "crh",                KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
713         { "crh_f",              KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
714         { "crh_alt",            KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
715         { "",                   0 },
716 };
717
718 /* Ukraine */
719 static const xkbVariant ua_variants[] =
720 {
721         { "phonetic",           KBD_UKRAINIAN }, /* Phonetic */
722         { "typewriter",         KBD_UKRAINIAN }, /* Typewriter */
723         { "winkeys",            KBD_UKRAINIAN }, /* Winkeys */
724         { "legacy",             KBD_UKRAINIAN }, /* Legacy */
725         { "rstu",               KBD_UKRAINIAN }, /* Standard RSTU */
726         { "rstu_ru",            KBD_UKRAINIAN }, /* Standard RSTU on Russian layout */
727         { "homophonic",         KBD_UKRAINIAN }, /* Homophonic */
728         { "crh",                KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
729         { "crh_f",              KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
730         { "crh_alt",            KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
731         { "",                   0 },
732 };
733
734 /* United Kingdom */
735 static const xkbVariant gb_variants[] =
736 {
737         { "extd",               KBD_UNITED_KINGDOM_EXTENDED }, /* Extended - Winkeys */
738         { "intl",               KBD_UNITED_KINGDOM_EXTENDED }, /* International (with dead keys) */
739         { "dvorak",             KBD_UNITED_STATES_DVORAK }, /* Dvorak */
740         { "dvorakukp",          KBD_UNITED_STATES_DVORAK }, /* Dvorak (UK Punctuation) */
741         { "mac",                KBD_UNITED_KINGDOM }, /* Macintosh */
742         { "colemak",            0 }, /* Colemak */
743         { "",                   0 },
744 };
745
746 /* Uzbekistan */
747 static const xkbVariant uz_variants[] =
748 {
749         { "latin",              0 }, /* Latin */
750         { "crh",                KBD_TATAR }, /* Crimean Tatar (Turkish Q) */
751         { "crh_f",              KBD_TURKISH_F }, /* Crimean Tatar (Turkish F) */
752         { "crh_alt",            KBD_TURKISH_Q }, /* Crimean Tatar (Turkish Alt-Q) */
753         { "",                   0 },
754 };
755
756 /* Korea, Republic of */
757 static const xkbVariant kr_variants[] =
758 {
759         { "kr104",              KBD_KOREAN_INPUT_SYSTEM_IME_2000 }, /* 101/104 key Compatible */
760         { "",                   0 },
761 };
762
763 /* Ireland */
764 static const xkbVariant ie_variants[] =
765 {
766         { "CloGaelach",         KBD_GAELIC }, /* CloGaelach */
767         { "UnicodeExpert",      KBD_GAELIC }, /* UnicodeExpert */
768         { "ogam",               KBD_GAELIC }, /* Ogham */
769         { "ogam_is434",         KBD_GAELIC }, /* Ogham IS434 */
770         { "",                   0 },
771 };
772
773 /* Pakistan */
774 static const xkbVariant pk_variants[] =
775 {
776         { "urd-crulp",          0 }, /* CRULP */
777         { "urd-nla",            0 }, /* NLA */
778         { "ara",                KBD_ARABIC_101 }, /* Arabic */
779         { "",                   0 },
780 };
781
782 /* Esperanto */
783 static const xkbVariant epo_variants[] =
784 {
785         { "legacy",             0 }, /* displaced semicolon and quote (obsolete) */
786         { "",                   0 },
787 };
788
789 /* Nigeria */
790 static const xkbVariant ng_variants[] =
791 {
792         { "igbo",               0 }, /* Igbo */
793         { "yoruba",             0 }, /* Yoruba */
794         { "hausa",              0 }, /* Hausa */
795         { "",                   0 },
796 };
797
798 /* Braille */
799 static const xkbVariant brai_variants[] =
800 {
801         { "left_hand",          0 }, /* Left hand */
802         { "right_hand",         0 }, /* Right hand */
803         { "",                   0 },
804 };
805
806 /* Turkmenistan */
807 static const xkbVariant tm_variants[] =
808 {
809         { "alt",                KBD_TURKISH_Q }, /* Alt-Q */
810         { "",                   0 },
811 };
812
813 static const xkbLayout xkbLayouts[] =
814 {
815         { "us",          KBD_US, us_variants }, /* USA */
816         { "ad",          0, NULL }, /* Andorra */
817         { "af",          KBD_FARSI, af_variants }, /* Afghanistan */
818         { "ara",         KBD_ARABIC_101, ara_variants }, /* Arabic */
819         { "al",          0, NULL }, /* Albania */
820         { "am",          KBD_ARMENIAN_EASTERN, am_variants }, /* Armenia */
821         { "az",          KBD_AZERI_CYRILLIC, az_variants }, /* Azerbaijan */
822         { "by",          KBD_BELARUSIAN, by_variants }, /* Belarus */
823         { "be",          KBD_BELGIAN_FRENCH, be_variants }, /* Belgium */
824         { "bd",          KBD_BENGALI, bd_variants }, /* Bangladesh */
825         { "in",          KBD_HINDI_TRADITIONAL, in_variants }, /* India */
826         { "ba",          KBD_CROATIAN, ba_variants }, /* Bosnia and Herzegovina */
827         { "br",          KBD_PORTUGUESE_BRAZILIAN_ABNT, br_variants }, /* Brazil */
828         { "bg",          KBD_BULGARIAN_LATIN, bg_variants }, /* Bulgaria */
829         { "ma",          KBD_FRENCH, ma_variants }, /* Morocco */
830         { "mm",          0, NULL }, /* Myanmar */
831         { "ca",          KBD_US, ca_variants }, /* Canada */
832         { "cd",          0, NULL }, /* Congo, Democratic Republic of the */
833         { "cn",          KBD_CHINESE_TRADITIONAL_PHONETIC, cn_variants }, /* China */
834         { "hr",          KBD_CROATIAN, hr_variants }, /* Croatia */
835         { "cz",          KBD_CZECH, cz_variants }, /* Czechia */
836         { "dk",          KBD_DANISH, dk_variants }, /* Denmark */
837         { "nl",          KBD_DUTCH, nl_variants }, /* Netherlands */
838         { "bt",          0, NULL }, /* Bhutan */
839         { "ee",          KBD_ESTONIAN, ee_variants }, /* Estonia */
840         { "ir",          0, ir_variants }, /* Iran */
841         { "iq",          0, iq_variants }, /* Iraq */
842         { "fo",          0, fo_variants }, /* Faroe Islands */
843         { "fi",          KBD_FINNISH, fi_variants }, /* Finland */
844         { "fr",          KBD_FRENCH, fr_variants }, /* France */
845         { "gh",          0, gh_variants }, /* Ghana */
846         { "gn",          0, NULL }, /* Guinea */
847         { "ge",          KBD_GEORGIAN, ge_variants }, /* Georgia */
848         { "de",          KBD_GERMAN, de_variants }, /* Germany */
849         { "gr",          KBD_GREEK, gr_variants }, /* Greece */
850         { "hu",          KBD_HUNGARIAN, hu_variants }, /* Hungary */
851         { "is",          KBD_ICELANDIC, is_variants }, /* Iceland */
852         { "il",          KBD_HEBREW, il_variants }, /* Israel */
853         { "it",          KBD_ITALIAN, it_variants }, /* Italy */
854         { "jp",          KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002, jp_variants }, /* Japan */
855         { "kg",          0, kg_variants }, /* Kyrgyzstan */
856         { "kh",          0, NULL }, /* Cambodia */
857         { "kz",          KBD_KAZAKH, kz_variants }, /* Kazakhstan */
858         { "la",          0, NULL }, /* Laos */
859         { "latam",       KBD_LATIN_AMERICAN, latam_variants }, /* Latin America */
860         { "lt",          KBD_LITHUANIAN, lt_variants }, /* Lithuania */
861         { "lv",          KBD_LATVIAN, lv_variants }, /* Latvia */
862         { "mao",         KBD_MAORI, NULL }, /* Maori */
863         { "me",          KBD_SERBIAN_LATIN, me_variants }, /* Montenegro */
864         { "mk",          KBD_FYRO_MACEDONIAN, mk_variants }, /* Macedonia */
865         { "mt",          KBD_MALTESE_48_KEY, mt_variants }, /* Malta */
866         { "mn",          KBD_MONGOLIAN_CYRILLIC, NULL }, /* Mongolia */
867         { "no",          KBD_NORWEGIAN, no_variants }, /* Norway */
868         { "pl",          KBD_POLISH_214, pl_variants }, /* Poland */
869         { "pt",          KBD_PORTUGUESE, pt_variants }, /* Portugal */
870         { "ro",          KBD_ROMANIAN, ro_variants }, /* Romania */
871         { "ru",          KBD_RUSSIAN, ru_variants }, /* Russia */
872         { "rs",          KBD_SERBIAN_LATIN, rs_variants }, /* Serbia */
873         { "si",          KBD_SLOVENIAN, si_variants }, /* Slovenia */
874         { "sk",          KBD_SLOVAK, sk_variants }, /* Slovakia */
875         { "es",          KBD_SPANISH, es_variants }, /* Spain */
876         { "se",          KBD_SWEDISH, se_variants }, /* Sweden */
877         { "ch",          KBD_SWISS_FRENCH, ch_variants }, /* Switzerland */
878         { "sy",          KBD_SYRIAC, sy_variants }, /* Syria */
879         { "tj",          0, tj_variants }, /* Tajikistan */
880         { "lk",          0, lk_variants }, /* Sri Lanka */
881         { "th",          KBD_THAI_KEDMANEE, th_variants }, /* Thailand */
882         { "tr",          KBD_TURKISH_Q, tr_variants }, /* Turkey */
883         { "ua",          KBD_UKRAINIAN, ua_variants }, /* Ukraine */
884         { "gb",          KBD_UNITED_KINGDOM, gb_variants }, /* United Kingdom */
885         { "uz",          KBD_UZBEK_CYRILLIC, uz_variants }, /* Uzbekistan */
886         { "vn",          KBD_VIETNAMESE, NULL }, /* Vietnam */
887         { "kr",          KBD_KOREAN_INPUT_SYSTEM_IME_2000, kr_variants }, /* Korea, Republic of */
888         { "ie",          KBD_UNITED_KINGDOM, ie_variants }, /* Ireland */
889         { "pk",          0, pk_variants }, /* Pakistan */
890         { "mv",          0, NULL }, /* Maldives */
891         { "za",          0, NULL }, /* South Africa */
892         { "epo",         0, epo_variants }, /* Esperanto */
893         { "np",          KBD_NEPALI, NULL }, /* Nepal */
894         { "ng",          0, ng_variants }, /* Nigeria */
895         { "et",          0, NULL }, /* Ethiopia */
896         { "sn",          0, NULL }, /* Senegal */
897         { "brai",        0, brai_variants }, /* Braille */
898         { "tm",          KBD_TURKISH_Q, tm_variants }, /* Turkmenistan */
899 };
900
901 /* OpenSolaris 2008.11 and 2009.06 keyboard layouts
902  *
903  * While OpenSolaris comes with Xorg and XKB, it maintains a set of keyboard layout
904  * names that map directly to a particular keyboard layout in XKB. Fortunately for us,
905  * this way of doing things comes from Solaris, which is XKB unaware. The same keyboard
906  * layout naming system is used in Solaris, so we can use the same XKB configuration as
907  * we would on OpenSolaris and get an accurate keyboard layout detection :)
908  *
909  * We can check for the current keyboard layout using the "kbd -l" command:
910  *
911  * type=6
912  * layout=33 (0x21)
913  * delay(ms)=500
914  * rate(ms)=40
915  *
916  * We can check at runtime if the kbd utility is present, parse the output, and use the
917  * keyboard layout indicated by the index given (in this case, 33, or US-English).
918  */
919
920
921 typedef struct _SunOSKeyboard
922 {
923         /* Sun keyboard type */
924         int type;
925
926         /* Layout */
927         int layout;
928
929         /* XKB keyboard */
930         char* xkbType;
931
932         /* XKB keyboard layout */
933         unsigned int keyboardLayoutID;
934 } SunOSKeyboard;
935
936
937 static const SunOSKeyboard SunOSKeyboards[] =
938 {
939         { 4,   0,    "sun(type4)",               KBD_US                                 }, /*  US4 */
940         { 4,   1,    "sun(type4)",               KBD_US                                 }, /*  US4 */
941         { 4,   2,    "sun(type4tuv)",            KBD_FRENCH                             }, /*  FranceBelg4 */
942         { 4,   3,    "sun(type4_ca)",            KBD_US                                 }, /*  Canada4 */
943         { 4,   4,    "sun(type4tuv)",            KBD_DANISH                             }, /*  Denmark4 */
944         { 4,   5,    "sun(type4tuv)",            KBD_GERMAN                             }, /*  Germany4 */
945         { 4,   6,    "sun(type4tuv)",            KBD_ITALIAN                            }, /*  Italy4 */
946         { 4,   7,    "sun(type4tuv)",            KBD_DUTCH                              }, /*  Netherland4 */
947         { 4,   8,    "sun(type4tuv)",            KBD_NORWEGIAN                          }, /*  Norway4 */
948         { 4,   9,    "sun(type4tuv)",            KBD_PORTUGUESE                         }, /*  Portugal4 */
949         { 4,   10,   "sun(type4tuv)",            KBD_SPANISH                            }, /*  SpainLatAm4 */
950         { 4,   11,   "sun(type4tuv)",            KBD_SWEDISH                            }, /*  SwedenFin4 */
951         { 4,   12,   "sun(type4tuv)",            KBD_SWISS_FRENCH                       }, /*  Switzer_Fr4 */
952         { 4,   13,   "sun(type4tuv)",            KBD_SWISS_GERMAN                       }, /*  Switzer_Ge4 */
953         { 4,   14,   "sun(type4tuv)",            KBD_UNITED_KINGDOM                     }, /*  UK4 */
954         { 4,   16,   "sun(type4)",               KBD_KOREAN_INPUT_SYSTEM_IME_2000       }, /*  Korea4 */
955         { 4,   17,   "sun(type4)",               KBD_CHINESE_TRADITIONAL_PHONETIC       }, /*  Taiwan4 */
956         { 4,   32,   "sun(type4jp)",             KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan4 */
957         { 4,   19,   "sun(type5)",               KBD_US                                 }, /*  US101A_PC */
958         { 4,   33,   "sun(type5)",               KBD_US                                 }, /*  US5 */
959         { 4,   34,   "sun(type5unix)",           KBD_US                                 }, /*  US_UNIX5 */
960         { 4,   35,   "sun(type5tuv)",            KBD_FRENCH                             }, /*  France5 */
961         { 4,   36,   "sun(type5tuv)",            KBD_DANISH                             }, /*  Denmark5 */
962         { 4,   37,   "sun(type5tuv)",            KBD_GERMAN                             }, /*  Germany5 */
963         { 4,   38,   "sun(type5tuv)",            KBD_ITALIAN                            }, /*  Italy5 */
964         { 4,   39,   "sun(type5tuv)",            KBD_DUTCH                              }, /*  Netherland5 */
965         { 4,   40,   "sun(type5tuv)",            KBD_NORWEGIAN                          }, /*  Norway5 */
966         { 4,   41,   "sun(type5tuv)",            KBD_PORTUGUESE                         }, /*  Portugal5 */
967         { 4,   42,   "sun(type5tuv)",            KBD_SPANISH                            }, /*  Spain5 */
968         { 4,   43,   "sun(type5tuv)",            KBD_SWEDISH                            }, /*  Sweden5 */
969         { 4,   44,   "sun(type5tuv)",            KBD_SWISS_FRENCH                       }, /*  Switzer_Fr5 */
970         { 4,   45,   "sun(type5tuv)",            KBD_SWISS_GERMAN                       }, /*  Switzer_Ge5 */
971         { 4,   46,   "sun(type5tuv)",            KBD_UNITED_KINGDOM                     }, /*  UK5 */
972         { 4,   47,   "sun(type5)",               KBD_KOREAN_INPUT_SYSTEM_IME_2000       }, /*  Korea5 */
973         { 4,   48,   "sun(type5)",               KBD_CHINESE_TRADITIONAL_PHONETIC       }, /*  Taiwan5 */
974         { 4,   49,   "sun(type5jp)",             KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan5 */
975         { 4,   50,   "sun(type5tuv)",            KBD_CANADIAN_FRENCH                    }, /*  Canada_Fr5 */
976         { 4,   51,   "sun(type5tuv)",            KBD_HUNGARIAN                          }, /*  Hungary5 */
977         { 4,   52,   "sun(type5tuv)",            KBD_POLISH_214                         }, /*  Poland5 */
978         { 4,   53,   "sun(type5tuv)",            KBD_CZECH                              }, /*  Czech5 */
979         { 4,   54,   "sun(type5tuv)",            KBD_RUSSIAN                            }, /*  Russia5 */
980         { 4,   55,   "sun(type5tuv)",            KBD_LATVIAN                            }, /*  Latvia5 */
981         { 4,   57,   "sun(type5tuv)",            KBD_GREEK                              }, /*  Greece5 */
982         { 4,   59,   "sun(type5tuv)",            KBD_LITHUANIAN                         }, /*  Lithuania5 */
983         { 4,   63,   "sun(type5tuv)",            KBD_CANADIAN_FRENCH                    }, /*  Canada_Fr5_TBITS5 */
984         { 4,   56,   "sun(type5tuv)",            KBD_TURKISH_Q                          }, /*  TurkeyQ5 */
985         { 4,   58,   "sun(type5tuv)",            KBD_ARABIC_101                         }, /*  Arabic5 */
986         { 4,   60,   "sun(type5tuv)",            KBD_BELGIAN_FRENCH                     }, /*  Belgian5 */
987         { 4,   62,   "sun(type5tuv)",            KBD_TURKISH_F                          }, /*  TurkeyF5 */
988         { 4,   80,   "sun(type5hobo)",           KBD_US                                 }, /*  US5_Hobo */
989         { 4,   81,   "sun(type5hobo)",           KBD_US                                 }, /*  US_UNIX5_Hobo */
990         { 4,   82,   "sun(type5tuvhobo)",        KBD_FRENCH                             }, /*  France5_Hobo */
991         { 4,   83,   "sun(type5tuvhobo)",        KBD_DANISH                             }, /*  Denmark5_Hobo */
992         { 4,   84,   "sun(type5tuvhobo)",        KBD_GERMAN                             }, /*  Germany5_Hobo */
993         { 4,   85,   "sun(type5tuvhobo)",        KBD_ITALIAN                            }, /*  Italy5_Hobo */
994         { 4,   86,   "sun(type5tuvhobo)",        KBD_DUTCH                              }, /*  Netherland5_Hobo */
995         { 4,   87,   "sun(type5tuvhobo)",        KBD_NORWEGIAN                          }, /*  Norway5_Hobo */
996         { 4,   88,   "sun(type5tuvhobo)",        KBD_PORTUGUESE                         }, /*  Portugal5_Hobo */
997         { 4,   89,   "sun(type5tuvhobo)",        KBD_SPANISH                            }, /*  Spain5_Hobo */
998         { 4,   90,   "sun(type5tuvhobo)",        KBD_SWEDISH                            }, /*  Sweden5_Hobo */
999         { 4,   91,   "sun(type5tuvhobo)",        KBD_SWISS_FRENCH                       }, /*  Switzer_Fr5_Hobo */
1000         { 4,   92,   "sun(type5tuvhobo)",        KBD_SWISS_GERMAN                       }, /*  Switzer_Ge5_Hobo */
1001         { 4,   93,   "sun(type5tuvhobo)",        KBD_UNITED_KINGDOM                     }, /*  UK5_Hobo */
1002         { 4,   94,   "sun(type5hobo)",           KBD_KOREAN_INPUT_SYSTEM_IME_2000       }, /*  Korea5_Hobo */
1003         { 4,   95,   "sun(type5hobo)",           KBD_CHINESE_TRADITIONAL_PHONETIC       }, /*  Taiwan5_Hobo */
1004         { 4,   96,   "sun(type5jphobo)",         KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan5_Hobo */
1005         { 4,   97,   "sun(type5tuvhobo)",        KBD_CANADIAN_FRENCH                    }, /*  Canada_Fr5_Hobo */
1006         { 101, 1,    "digital_vndr/pc(pc104)",   KBD_US                                 }, /*  US101A_x86 */
1007         { 101, 34,   "digital_vndr/pc(pc104)",   KBD_US                                 }, /*  J3100_x86 */
1008         { 101, 35,   "digital_vndr/pc(pc104)",   KBD_FRENCH                             }, /*  France_x86 */
1009         { 101, 36,   "digital_vndr/pc(pc104)",   KBD_DANISH                             }, /*  Denmark_x86 */
1010         { 101, 37,   "digital_vndr/pc(pc104)",   KBD_GERMAN                             }, /*  Germany_x86 */
1011         { 101, 38,   "digital_vndr/pc(pc104)",   KBD_ITALIAN                            }, /*  Italy_x86 */
1012         { 101, 39,   "digital_vndr/pc(pc104)",   KBD_DUTCH                              }, /*  Netherland_x86 */
1013         { 101, 40,   "digital_vndr/pc(pc104)",   KBD_NORWEGIAN                          }, /*  Norway_x86 */
1014         { 101, 41,   "digital_vndr/pc(pc104)",   KBD_PORTUGUESE                         }, /*  Portugal_x86 */
1015         { 101, 42,   "digital_vndr/pc(pc104)",   KBD_SPANISH                            }, /*  Spain_x86 */
1016         { 101, 43,   "digital_vndr/pc(pc104)",   KBD_SWEDISH                            }, /*  Sweden_x86 */
1017         { 101, 44,   "digital_vndr/pc(pc104)",   KBD_SWISS_FRENCH                       }, /*  Switzer_Fr_x86 */
1018         { 101, 45,   "digital_vndr/pc(pc104)",   KBD_SWISS_GERMAN                       }, /*  Switzer_Ge_x86 */
1019         { 101, 46,   "digital_vndr/pc(pc104)",   KBD_UNITED_KINGDOM                     }, /*  UK_x86 */
1020         { 101, 47,   "digital_vndr/pc(pc104)",   KBD_KOREAN_INPUT_SYSTEM_IME_2000       }, /*  Korea_x86 */
1021         { 101, 48,   "digital_vndr/pc(pc104)",   KBD_CHINESE_TRADITIONAL_PHONETIC       }, /*  Taiwan_x86 */
1022         { 101, 49,   "digital_vndr/pc(lk411jj)", KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan_x86 */
1023         { 101, 50,   "digital_vndr/pc(pc104)",   KBD_CANADIAN_FRENCH                    }, /*  Canada_Fr2_x86 */
1024         { 101, 51,   "digital_vndr/pc(pc104)",   KBD_HUNGARIAN                          }, /*  Hungary_x86 */
1025         { 101, 52,   "digital_vndr/pc(pc104)",   KBD_POLISH_214                         }, /*  Poland_x86 */
1026         { 101, 53,   "digital_vndr/pc(pc104)",   KBD_CZECH                              }, /*  Czech_x86 */
1027         { 101, 54,   "digital_vndr/pc(pc104)",   KBD_RUSSIAN                            }, /*  Russia_x86 */
1028         { 101, 55,   "digital_vndr/pc(pc104)",   KBD_LATVIAN                            }, /*  Latvia_x86 */
1029         { 101, 56,   "digital_vndr/pc(pc104)",   KBD_TURKISH_Q                          }, /*  Turkey_x86 */
1030         { 101, 57,   "digital_vndr/pc(pc104)",   KBD_GREEK                              }, /*  Greece_x86 */
1031         { 101, 59,   "digital_vndr/pc(pc104)",   KBD_LITHUANIAN                         }, /*  Lithuania_x86 */
1032         { 101, 1001, "digital_vndr/pc(pc104)",   KBD_US                                 }, /*  MS_US101A_x86 */
1033         { 6,   6,    "sun(type6tuv)",            KBD_DANISH                             }, /*  Denmark6_usb */
1034         { 6,   7,    "sun(type6tuv)",            KBD_FINNISH                            }, /*  Finnish6_usb */
1035         { 6,   8,    "sun(type6tuv)",            KBD_FRENCH                             }, /*  France6_usb */
1036         { 6,   9,    "sun(type6tuv)",            KBD_GERMAN                             }, /*  Germany6_usb */
1037         { 6,   14,   "sun(type6tuv)",            KBD_ITALIAN                            }, /*  Italy6_usb */
1038         { 6,   15,   "sun(type6jp)",             KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan7_usb */
1039         { 6,   16,   "sun(type6)",               KBD_KOREAN_INPUT_SYSTEM_IME_2000       }, /*  Korea6_usb */
1040         { 6,   18,   "sun(type6tuv)",            KBD_DUTCH                              }, /*  Netherland6_usb */
1041         { 6,   19,   "sun(type6tuv)",            KBD_NORWEGIAN                          }, /*  Norway6_usb */
1042         { 6,   22,   "sun(type6tuv)",            KBD_PORTUGUESE                         }, /*  Portugal6_usb */
1043         { 6,   23,   "sun(type6tuv)",            KBD_RUSSIAN                            }, /*  Russia6_usb */
1044         { 6,   25,   "sun(type6tuv)",            KBD_SPANISH                            }, /*  Spain6_usb */
1045         { 6,   26,   "sun(type6tuv)",            KBD_SWEDISH                            }, /*  Sweden6_usb */
1046         { 6,   27,   "sun(type6tuv)",            KBD_SWISS_FRENCH                       }, /*  Switzer_Fr6_usb */
1047         { 6,   28,   "sun(type6tuv)",            KBD_SWISS_GERMAN                       }, /*  Switzer_Ge6_usb */
1048         { 6,   30,   "sun(type6)",               KBD_CHINESE_TRADITIONAL_PHONETIC       }, /*  Taiwan6_usb */
1049         { 6,   32,   "sun(type6tuv)",            KBD_UNITED_KINGDOM                     }, /*  UK6_usb */
1050         { 6,   33,   "sun(type6)",               KBD_US                                 }, /*  US6_usb */
1051         { 6,   1,    "sun(type6tuv)",            KBD_ARABIC_101                         }, /*  Arabic6_usb */
1052         { 6,   2,    "sun(type6tuv)",            KBD_BELGIAN_FRENCH                     }, /*  Belgian6_usb */
1053         { 6,   31,   "sun(type6tuv)",            KBD_TURKISH_Q                          }, /*  TurkeyQ6_usb */
1054         { 6,   35,   "sun(type6tuv)",            KBD_TURKISH_F                          }, /*  TurkeyF6_usb */
1055         { 6,   271,  "sun(type6jp)",             KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002   }, /*  Japan6_usb */
1056         { 6,   264,  "sun(type6tuv)",            KBD_ALBANIAN                           }, /*  Albanian6_usb */
1057         { 6,   261,  "sun(type6tuv)",            KBD_BELARUSIAN                         }, /*  Belarusian6_usb */
1058         { 6,   260,  "sun(type6tuv)",            KBD_BULGARIAN                          }, /*  Bulgarian6_usb */
1059         { 6,   259,  "sun(type6tuv)",            KBD_CROATIAN                           }, /*  Croatian6_usb */
1060         { 6,   5,    "sun(type6tuv)",            KBD_CZECH                              }, /*  Czech6_usb */
1061         { 6,   4,    "sun(type6tuv)",            KBD_CANADIAN_FRENCH                    }, /*  French-Canadian6_usb */
1062         { 6,   12,   "sun(type6tuv)",            KBD_HUNGARIAN                          }, /*  Hungarian6_usb */
1063         { 6,   10,   "sun(type6tuv)",            KBD_GREEK                              }, /*  Greek6_usb */
1064         { 6,   17,   "sun(type6)",               KBD_LATIN_AMERICAN                     }, /*  Latin-American6_usb */
1065         { 6,   265,  "sun(type6tuv)",            KBD_LITHUANIAN                         }, /*  Lithuanian6_usb */
1066         { 6,   266,  "sun(type6tuv)",            KBD_LATVIAN                            }, /*  Latvian6_usb */
1067         { 6,   267,  "sun(type6tuv)",            KBD_FYRO_MACEDONIAN                    }, /*  Macedonian6_usb */
1068         { 6,   263,  "sun(type6tuv)",            KBD_MALTESE_47_KEY                     }, /*  Malta_UK6_usb */
1069         { 6,   262,  "sun(type6tuv)",            KBD_MALTESE_48_KEY                     }, /*  Malta_US6_usb */
1070         { 6,   21,   "sun(type6tuv)",            KBD_POLISH_214                         }, /*  Polish6_usb */
1071         { 6,   257,  "sun(type6tuv)",            KBD_SERBIAN_LATIN                      }, /*  Serbia-And-Montenegro6_usb */
1072         { 6,   256,  "sun(type6tuv)",            KBD_SLOVENIAN                          }, /*  Slovenian6_usb */
1073         { 6,   24,   "sun(type6tuv)",            KBD_SLOVAK                             }, /*  Slovakian6_usb */
1074         { 6,   3,    "sun(type6)",               KBD_CANADIAN_MULTILINGUAL_STANDARD     }, /*  Canada_Bi6_usb */
1075         { 6,   272,  "sun(type6)",               KBD_PORTUGUESE_BRAZILIAN_ABNT          }  /*  Brazil6_usb */
1076 };
1077
1078 unsigned int find_keyboard_layout_in_xorg_rules(char* layout, char* variant)
1079 {
1080         int i;
1081         int j;
1082
1083         if ((layout == NULL) || (variant == NULL))
1084                 return 0;
1085
1086         DEBUG_KBD("xkbLayout: %s\txkbVariant: %s\n", layout, variant);
1087
1088         for (i = 0; i < sizeof(xkbLayouts) / sizeof(xkbLayout); i++)
1089         {
1090                 if (strcmp(xkbLayouts[i].layout, layout) == 0)
1091                 {
1092                         for (j = 0; xkbLayouts[i].variants[j].variant != NULL && strlen(xkbLayouts[i].variants[j].variant) > 0; j++)
1093                         {
1094                                 if (strcmp(xkbLayouts[i].variants[j].variant, variant) == 0)
1095                                 {
1096                                         return xkbLayouts[i].variants[j].keyboardLayoutID;
1097                                 }
1098                         }
1099
1100                         return xkbLayouts[i].keyboardLayoutID;
1101                 }
1102         }
1103
1104         return 0;
1105 }
1106
1107 #if defined(sun)
1108
1109 unsigned int detect_keyboard_type_and_layout_sunos(char* xkbfile, int length)
1110 {
1111         FILE* kbd;
1112
1113         int i;
1114         int type = 0;
1115         int layout = 0;
1116
1117         char* pch;
1118         char* beg;
1119         char* end;
1120
1121         char buffer[1024];
1122
1123         /*
1124                 Sample output for "kbd -t -l" :
1125
1126                 USB keyboard
1127                 type=6
1128                 layout=3 (0x03)
1129                 delay(ms)=500
1130                 rate(ms)=40
1131         */
1132
1133         kbd = popen("kbd -t -l", "r");
1134
1135         if (kbd < 0)
1136                 return 0;
1137
1138         while(fgets(buffer, sizeof(buffer), kbd) != NULL)
1139         {
1140                 if((pch = strstr(buffer, "type=")) != NULL)
1141                 {
1142                         beg = pch + sizeof("type=") - 1;
1143                         end = strchr(beg, '\n');
1144                         end[0] = '\0';
1145                         type = atoi(beg);
1146                 }
1147                 else if((pch = strstr(buffer, "layout=")) != NULL)
1148                 {
1149                         beg = pch + sizeof("layout=") - 1;
1150                         end = strchr(beg, ' ');
1151                         end[0] = '\0';
1152                         layout = atoi(beg);
1153                 }
1154         }
1155         pclose(kbd);
1156
1157         for(i = 0; i < sizeof(SunOSKeyboards) / sizeof(SunOSKeyboard); i++)
1158         {
1159                 if(SunOSKeyboards[i].type == type)
1160                 {
1161                         if(SunOSKeyboards[i].layout == layout)
1162                         {
1163                                 strncpy(xkbfile, SunOSKeyboards[i].xkbType, length);
1164                                 return SunOSKeyboards[i].keyboardLayoutID;
1165                         }
1166                 }
1167         }
1168
1169         return 0;
1170 }
1171
1172 #endif