1 |
dmorgan |
391 |
package keyboard; # $Id: keyboard.pm 263727 2009-11-27 09:26:40Z cfergeau $ |
2 |
|
|
|
3 |
|
|
use diagnostics; |
4 |
|
|
use strict; |
5 |
|
|
|
6 |
|
|
#-###################################################################################### |
7 |
|
|
#- misc imports |
8 |
|
|
#-###################################################################################### |
9 |
|
|
use common; |
10 |
|
|
use detect_devices; |
11 |
|
|
use run_program; |
12 |
|
|
use lang; |
13 |
|
|
use log; |
14 |
|
|
use c; |
15 |
|
|
|
16 |
|
|
|
17 |
|
|
#-###################################################################################### |
18 |
|
|
#- Globals |
19 |
|
|
#-###################################################################################### |
20 |
|
|
my $KMAP_MAGIC = 0x8B39C07F; |
21 |
|
|
|
22 |
|
|
#- a best guess of the keyboard layout, based on the choosen locale |
23 |
|
|
#- beware only the first 5 characters of the locale are used |
24 |
|
|
our %lang2keyboard = |
25 |
|
|
( |
26 |
|
|
'af' => 'us_intl', |
27 |
|
|
'am' => 'us:90', |
28 |
|
|
'ar' => 'ara:90', |
29 |
|
|
'as' => 'ben:90 ben2:80 us_intl:5', |
30 |
pterjan |
1062 |
'ast' => 'es:85 lat:80 us_intl:50', |
31 |
dmorgan |
391 |
'az' => 'az:90 tr_q:10 us_intl:5', |
32 |
|
|
'az_IR' => 'ir:90', |
33 |
|
|
'be' => 'by:90 ru:50 ru_yawerty:40', |
34 |
|
|
'ber' => 'tifinagh:80 tifinagh_p:70', |
35 |
|
|
'bg' => 'bg_phonetic:60 bg:50', |
36 |
|
|
'bn' => 'ben:90 ben2:80 dev:20 us_intl:5', |
37 |
|
|
'bo' => 'bt', |
38 |
|
|
'br' => 'fr:90', |
39 |
|
|
'bs' => 'bs:90', |
40 |
|
|
'ca' => 'es:90 fr:15', |
41 |
|
|
'ca@valencian' => 'es', |
42 |
|
|
'chr' => 'chr:80 us:60 us_intl:60', |
43 |
|
|
'cs' => 'cz_qwerty:70 cz:50', |
44 |
|
|
'cy' => 'gb:90', |
45 |
|
|
'da' => 'dk:90', |
46 |
|
|
'de' => 'de_nodeadkeys:70 de:50 be:50 ch_de:50', |
47 |
|
|
'dz' => 'bt', |
48 |
|
|
'el' => 'gr:90', |
49 |
|
|
'en' => 'us:89 us3:80 us_intl:50 qc:50 gb:50 dvorak:10', |
50 |
|
|
'en_AU' => 'us:80 us3:70 us_intl:50 gb:40 dvorak:10 dvorak_gb:5', |
51 |
|
|
'en_CA' => 'us:80 us3:70 us_intl:50 qc:50 gb:40 dvorak:10', |
52 |
|
|
'en_GB' => 'gb:89 us:60 us_intl:50 dvorak_gb:10', |
53 |
|
|
'en_IE' => 'ie:80 gb:70 dvorak_gb:10', |
54 |
|
|
'en_NG' => 'ng:80 us:60', |
55 |
|
|
'en_NZ' => 'us:80 us3:70 us_intl:50 gb:40 dvorak:10 dvorak_gb:5', |
56 |
|
|
'en_US' => 'us:89 us3:80 us_intl:50 dvorak:10', |
57 |
|
|
'eo' => 'us_intl:89 dvorak_eo:30 dvorak:10', |
58 |
|
|
'es' => 'es:85 lat:80 us_intl:50', |
59 |
|
|
'et' => 'ee:90', |
60 |
|
|
'eu' => 'es:90 fr:15', |
61 |
|
|
'fa' => 'ir:90', |
62 |
|
|
'fi' => 'fi:90', |
63 |
|
|
'fo' => 'fo:80 is:70 dk:60', |
64 |
|
|
'fr' => 'fr:89 qc:85 be:85 ch_fr:70 dvorak_fr:20', |
65 |
|
|
'fr_CA' => 'qc:89', |
66 |
|
|
'fr_CH' => 'ch_fr:89', |
67 |
|
|
'fr_BE' => 'be:89', |
68 |
|
|
'fur' => 'it:90', |
69 |
|
|
'ga' => 'ie:80 gb:70 dvorak_gb:10', |
70 |
|
|
'gd' => 'gb:80 ie:70 dvorak_gb:10', |
71 |
|
|
'gl' => 'es:90', |
72 |
|
|
'gn' => 'lat:85 es:80 us_intl:50', |
73 |
|
|
'gu' => 'guj:90', |
74 |
|
|
'gv' => 'gb:80 ie:70', |
75 |
|
|
'ha' => 'ng', |
76 |
|
|
'he' => 'il:90 il_phonetic:10', |
77 |
|
|
'hi' => 'dev:90', |
78 |
|
|
'hr' => 'hr:90 si:50', |
79 |
|
|
'hu' => 'hu:90', |
80 |
|
|
'hy' => 'am:90 am_old:10 am_phonetic:5', |
81 |
|
|
'ia' => 'us:90 us_intl:20', |
82 |
|
|
'id' => 'us:90 us_intl:20', |
83 |
|
|
'ig' => 'ng', |
84 |
|
|
'is' => 'is:90', |
85 |
|
|
'it' => 'it:90 ch_fr:50 ch_de:50', |
86 |
|
|
'iu' => 'iku:90', |
87 |
|
|
'ja' => 'jp:90', |
88 |
|
|
'ka' => 'ge_la:90 ge_ru:50', |
89 |
|
|
'kl' => 'dk:80 us_intl:30', |
90 |
|
|
'kn' => 'kan:90', |
91 |
|
|
'ko' => 'kr:90 us:60', |
92 |
|
|
'ku' => 'tr_q:90 tr_f:30', |
93 |
|
|
'ku_IQ' => 'kur:90', |
94 |
|
|
'kw' => 'gb:80 ie:70', |
95 |
|
|
'ky' => 'kg:90 ru_yawerty:40', |
96 |
|
|
'lb' => 'ch_fr:89 be:85 us_intl:70 fr:60 dvorak_fr:20', |
97 |
|
|
'li' => 'us_intl:80 be:70 nl:10 us:5', |
98 |
|
|
'lo' => 'lao:90', |
99 |
|
|
'lt' => 'lt:80', |
100 |
|
|
'ltg' => 'lv:90 lt:40 ee:5', |
101 |
|
|
'lv' => 'lv:90 lt:40 ee:5', |
102 |
|
|
'mi' => 'mao:90 gb:30 us_intl:20', |
103 |
|
|
'mk' => 'mk:90', |
104 |
|
|
'ml' => 'mal:90', |
105 |
|
|
'mn' => 'mn:90 ru:20 ru_yawerty:5', |
106 |
|
|
'mr' => 'dev:90', |
107 |
|
|
'ms' => 'us:90 us_intl:20', |
108 |
|
|
'mt' => 'mt:90 mt_us:35 us_intl:10', |
109 |
|
|
'my' => 'mm:90', |
110 |
|
|
'nb' => 'no:90 dvorak_no:10', |
111 |
|
|
'nds' => 'de_nodeadkeys:70 de:50 us_intl:40 nl:10 us:5', |
112 |
|
|
'ne' => 'dev:90', |
113 |
|
|
'nl' => 'us_intl:80 be:70 nl:10 us:5', |
114 |
|
|
'nn' => 'no:90 dvorak_no:10', |
115 |
|
|
'no' => 'no:90 dvorak_no:10', # for compatiblity only |
116 |
|
|
'oc' => 'fr:90', |
117 |
|
|
'or' => 'ori:90', |
118 |
|
|
'pa' => 'gur:90', |
119 |
|
|
'ph' => 'us:90 us_intl:20', |
120 |
|
|
'pl' => 'pl:90 pl2:60 dvorak_pl:10', |
121 |
|
|
'pp' => 'br:80 lat:20 pt:10 us_intl:30', |
122 |
|
|
'ps' => 'pus:80 snd:60', |
123 |
|
|
'pt_BR' => 'br:90 lat:20 pt:10 us_intl:30', |
124 |
|
|
'pt' => 'pt:90', |
125 |
|
|
'ro' => 'ro:80 ro_qwertz:40 us_intl:10', |
126 |
|
|
'ru' => 'ru:85 ru_yawerty:80 ua:50', |
127 |
|
|
'sc' => 'it:90', |
128 |
|
|
'sd' => 'snd:80 ara:20', |
129 |
|
|
'se' => 'smi:70 smi_sefi:50', |
130 |
|
|
'sh' => 'yu:80', |
131 |
|
|
'si' => 'sin', |
132 |
|
|
'sk' => 'sk_qwerty:80 sk:70', |
133 |
|
|
'sl' => 'si:90 hr:50', |
134 |
|
|
'sq' => 'al:90', |
135 |
|
|
'sr' => 'srp:80', |
136 |
|
|
'ss' => 'us_intl', |
137 |
|
|
'st' => 'us_intl', |
138 |
|
|
'sv' => 'se:90 fi:30 dvorak_se:10', |
139 |
|
|
'ta' => 'tscii:80 tml:20', |
140 |
|
|
'te' => 'tel:90', |
141 |
|
|
'tg' => 'tj:90 ru_yawerty:40', |
142 |
|
|
'th' => 'th:80 th_pat:50 th_tis:60', |
143 |
|
|
'tk' => 'tm:80 tr_q:50 tr_f:40', |
144 |
|
|
'tl' => 'us:90 us_intl:20', |
145 |
|
|
'tr' => 'tr_q:90 tr_f:30', |
146 |
|
|
'tt' => 'ru:50 ru_yawerty:40', |
147 |
|
|
'uk' => 'ua:90 ru:50 ru_yawerty:40', |
148 |
|
|
'ur' => 'urd:80 snd:60 ara:20', |
149 |
|
|
'uz' => 'uz:80 ru_yawerty:40', |
150 |
|
|
'uz\@Cyrl' => 'uz:80 ru_yawerty:40', |
151 |
|
|
'uz\@Latn' => 'us:80 uz:80', |
152 |
|
|
've' => 'us_intl', |
153 |
|
|
'vi' => 'vn:80 us:70 us_intl:60', |
154 |
|
|
'wa' => 'be:90 fr:5', |
155 |
|
|
'xh' => 'us_intl', |
156 |
|
|
'yi' => 'il_phonetic:90 il:10 us_intl:10', |
157 |
|
|
'yo' => 'ng', |
158 |
|
|
'zh_CN' => 'us:90', |
159 |
|
|
'zh_TW' => 'us:90', |
160 |
|
|
'zu' => 'us_intl', |
161 |
|
|
); |
162 |
|
|
|
163 |
|
|
# USB kbd table |
164 |
|
|
# The numeric values are the bCountryCode field (5th byte) of HID descriptor |
165 |
|
|
# NOTE: we do not trust when the layout is declared as US layout (0x21) |
166 |
|
|
# as most manufacturers just use that value when selling physical devices |
167 |
|
|
# with different layouts printed on the keys. |
168 |
|
|
my @usb2keyboard = |
169 |
|
|
( |
170 |
|
|
qw(SKIP ara_SKIP be ca_SKIP qc cz dk fi fr de gr il hu us_intl it jp), |
171 |
|
|
#- 0x10 |
172 |
|
|
qw(kr lat nl no ir pl pt ru sk es se ch_fr ch_de ch_de tw_SKIP tr_q), |
173 |
|
|
#- 0x20 |
174 |
|
|
qw(gb us_SKIP yu tr_f), |
175 |
|
|
#- higher codes not attribued as of 2002-02 |
176 |
|
|
); |
177 |
|
|
|
178 |
|
|
#- key = extension for Xmodmap file, [0] = description of the keyboard, |
179 |
|
|
#- [1] = name for loadkeys, [2] = name for XKB, [3] = "1" if it is |
180 |
|
|
#- a multigroup layout (eg: one with latin/non-latin letters) |
181 |
|
|
#- |
182 |
|
|
#- note: there seems to be a limit of 4 stackable xkb layouts |
183 |
|
|
my %keyboards = ( |
184 |
|
|
arch() =~ /^sparc/ ? ( |
185 |
|
|
#- do we still support those? all but "se" and "us" have dissapeared from |
186 |
|
|
#- symbols/sun/ directory in Xorg package. |
187 |
|
|
"cz" => [ N_("_: keyboard\nCzech (QWERTZ)"), "sunt5-cz-us", "cz", 0 ], |
188 |
|
|
"de" => [ N_("_: keyboard\nGerman"), "sunt5-de-latin1", "de", 0 ], |
189 |
|
|
"dvorak" => [ N_("_: keyboard\nDvorak"), "sundvorak", "dvorak",0 ], |
190 |
|
|
"es" => [ N_("_: keyboard\nSpanish"), "sunt5-es", "es", 0 ], |
191 |
|
|
"fi" => [ N_("_: keyboard\nFinnish"), "sunt5-fi-latin1", "fi", 0 ], |
192 |
|
|
"fr" => [ N_("_: keyboard\nFrench"), "sunt5-fr-latin1", "fr", 0 ], |
193 |
|
|
"gb" => [ N_("UK keyboard"), "sunt5-uk", "gb", 0 ], |
194 |
|
|
"no" => [ N_("_: keyboard\nNorwegian"), "sunt4-no-latin1", "no", 0 ], |
195 |
|
|
"pl" => [ N_("_: keyboard\nPolish"), "sun-pl-altgraph", "pl", 0 ], |
196 |
|
|
"ru" => [ N_("_: keyboard\nRussian"), "sunt5-ru", "ru", 1 ], |
197 |
|
|
"se" => [ N_("_: keyboard\nSwedish"), "sunt5-fi-latin1", "se", 0 ], |
198 |
|
|
"us" => [ N_("US keyboard"), "sunkeymap", "us", 0 ], |
199 |
|
|
) : ( |
200 |
|
|
"al" => [ N_("_: keyboard\nAlbanian"), "al", "al", 0 ], |
201 |
|
|
"am_old" => [ N_("_: keyboard\nArmenian (old)"), "am_old", "am(old)", 1 ], |
202 |
|
|
"am" => [ N_("_: keyboard\nArmenian (typewriter)"), "am-armscii8", "am", 1 ], |
203 |
|
|
"am_phonetic" => [ N_("_: keyboard\nArmenian (phonetic)"), "am_phonetic", "am(phonetic)",1 ], |
204 |
|
|
"ara" => [ N_("_: keyboard\nArabic"), "us", "ara(digits)", 1 ], |
205 |
pterjan |
1062 |
"ast" => [ N_("_: keyboard\nAsturian"), "es", "es(ast)", 0 ], |
206 |
dmorgan |
391 |
"az" => [ N_("_: keyboard\nAzerbaidjani (latin)"), "az", "az", 0 ], |
207 |
|
|
"be" => [ N_("_: keyboard\nBelgian"), "be2-latin1", "be", 0 ], |
208 |
|
|
"ben" => [ N_("_: keyboard\nBengali (Inscript-layout)"), "us", "in(ben)", 1 ], |
209 |
|
|
"ben2" => [ N_("_: keyboard\nBengali (Probhat)"), "us", "in(ben_probhat)", 1 ], |
210 |
|
|
"bg_phonetic" => [ N_("_: keyboard\nBulgarian (phonetic)"), "bg", "bg(phonetic)", 1 ], |
211 |
|
|
"bg" => [ N_("_: keyboard\nBulgarian (BDS)"), "bg_bds", "bg", 1 ], |
212 |
|
|
"br" => [ N_("_: keyboard\nBrazilian (ABNT-2)"), "br-abnt2", "br", 0 ], |
213 |
|
|
"bs" => [ N_("_: keyboard\nBosnian"), "croat", "ba", 0 ], |
214 |
|
|
"bt" => [ N_("_: keyboard\nDzongkha/Tibetan"), "us", "bt", 1 ], |
215 |
|
|
"by" => [ N_("_: keyboard\nBelarusian"), "by-cp1251", "by", 1 ], |
216 |
|
|
"ch_de" => [ N_("_: keyboard\nSwiss (German layout)"), "sg-latin1", "ch(de)", 0 ], |
217 |
|
|
"ch_fr" => [ N_("_: keyboard\nSwiss (French layout)"), "fr_CH-latin1", "ch(fr)", 0 ], |
218 |
|
|
# TODO: console map |
219 |
|
|
"chr" => [ N_("_: keyboard\nCherokee syllabics"), "us", "chr", 1 ], |
220 |
|
|
"cz" => [ N_("_: keyboard\nCzech (QWERTZ)"), "cz", "cz", 0 ], |
221 |
|
|
"cz_qwerty" => [ N_("_: keyboard\nCzech (QWERTY)"), "cz-lat2", "cz(qwerty)", 0 ], |
222 |
|
|
"de" => [ N_("_: keyboard\nGerman"), "de-latin1", "de", 0 ], |
223 |
|
|
"de_nodeadkeys" => [ N_("_: keyboard\nGerman (no dead keys)"), "de-latin1-nodeadkeys", "de(nodeadkeys)", 0 ], |
224 |
|
|
"dev" => [ N_("_: keyboard\nDevanagari"), "us", "in(deva)", 1 ], |
225 |
|
|
"dk" => [ N_("_: keyboard\nDanish"), "dk-latin1", "dk", 0 ], |
226 |
|
|
"dvorak" => [ N_("_: keyboard\nDvorak (US)"), "pc-dvorak-latin1", "us(dvorak)", 0 ], |
227 |
|
|
"dvorak_eo" => [ N_("_: keyboard\nDvorak (Esperanto)"), "eo-dvorak", "dvorak(eo)", 0 ], |
228 |
|
|
"dvorak_fr" => [ N_("_: keyboard\nDvorak (French)"), "fr-dvorak", "fr(dvorak)", 0 ], |
229 |
|
|
"dvorak_gb" => [ N_("_: keyboard\nDvorak (UK)"), "pc-dvorak-latin1", "gb(dvorak)", 0 ], |
230 |
|
|
"dvorak_no" => [ N_("_: keyboard\nDvorak (Norwegian)"), "no-dvorak", "no(dvorak)", 0 ], |
231 |
|
|
"dvorak_pl" => [ N_("_: keyboard\nDvorak (Polish)"), "pl-dvorak", "pl(dvorak)", 0 ], |
232 |
|
|
"dvorak_se" => [ N_("_: keyboard\nDvorak (Swedish)"), "se-dvorak", "se(dvorak)", 0 ], |
233 |
|
|
"ee" => [ N_("_: keyboard\nEstonian"), "ee-latin9", "ee", 0 ], |
234 |
|
|
"es" => [ N_("_: keyboard\nSpanish"), "es-latin1", "es", 0 ], |
235 |
|
|
"fi" => [ N_("_: keyboard\nFinnish"), "fi-latin1", "fi", 0 ], |
236 |
|
|
"fo" => [ N_("_: keyboard\nFaroese"), "is-latin1", "fo", 0 ], |
237 |
|
|
"fr" => [ N_("_: keyboard\nFrench"), "fr-latin1", "fr", 0 ], |
238 |
|
|
"gb" => [ N_("UK keyboard"), "uk-latin1", "gb", 0 ], |
239 |
|
|
"ge_ru" => [N_("_: keyboard\nGeorgian (\"Russian\" layout)"), "ge_ru-georgian_academy", "ge(ru)",1], |
240 |
|
|
"ge_la" => [N_("_: keyboard\nGeorgian (\"Latin\" layout)"), "ge_la-georgian_academy", "ge(la)",1], |
241 |
|
|
"gr" => [ N_("_: keyboard\nGreek"), "gr-8859_7", "gr(extended)", 1 ], |
242 |
|
|
"gr_pl" => [ N_("_: keyboard\nGreek (polytonic)"), "gr-8859_7", "gr(polytonic)", 1 ], |
243 |
|
|
"guj" => [ N_("_: keyboard\nGujarati"), "us", "in(guj)", 1 ], |
244 |
|
|
"gur" => [ N_("_: keyboard\nGurmukhi"), "us", "in(guru)", 1 ], |
245 |
|
|
"hr" => [ N_("_: keyboard\nCroatian"), "croat", "hr", 0 ], |
246 |
|
|
"hu" => [ N_("_: keyboard\nHungarian"), "hu-latin2", "hu", 0 ], |
247 |
|
|
"ie" => [ N_("_: keyboard\nIrish"), "uk-latin1", "ie", 0 ], |
248 |
|
|
"iku" => [ N_("_: keyboard\nInuktitut"), "us", "ca(ike)", 1 ], |
249 |
|
|
"il" => [ N_("_: keyboard\nIsraeli"), "il-8859_8", "il", 1 ], |
250 |
|
|
"il_phonetic" => [ N_("_: keyboard\nIsraeli (phonetic)"), "hebrew", "il(phonetic)", 1 ], |
251 |
|
|
"ir" => [ N_("_: keyboard\nIranian"), "ir-isiri_3342", "ir", 1 ], |
252 |
|
|
"is" => [ N_("_: keyboard\nIcelandic"), "is-latin1", "is", 0 ], |
253 |
|
|
"it" => [ N_("_: keyboard\nItalian"), "it-latin1", "it", 0 ], |
254 |
|
|
# Japanese keyboard is dual latin/kana; but telling it here shows a |
255 |
|
|
# message to choose the switching key that is misleading, as input methods |
256 |
|
|
# are not automatically enabled when typing in kana |
257 |
|
|
"jp" => [ N_("_: keyboard\nJapanese 106 keys"), "jp106", "jp", 0 ], |
258 |
|
|
"kan" => [ N_("_: keyboard\nKannada"), "us", "in(kan)", 1 ], |
259 |
|
|
"kg" => [ N_("_: keyboard\nKyrgyz"), "ky", "kg(direct)", 1 ], |
260 |
|
|
"kr" => [ N_("_: keyboard\nKorean"), "us", "kr(kr104)", 0 ], |
261 |
|
|
# TODO: console map |
262 |
|
|
"kur" => [ N_("_: keyboard\nKurdish (arabic script)"), "us", "kur", 1 ], |
263 |
|
|
"lat" => [ N_("_: keyboard\nLatin American"), "la-latin1", "latam", 0 ], |
264 |
|
|
# TODO: console map |
265 |
|
|
"lao" => [ N_("_: keyboard\nLaotian"), "us", "la", 1 ], |
266 |
|
|
"lt" => [ N_("_: keyboard\nLithuanian"), "lt-latin7", "lt,us", 1 ], |
267 |
|
|
"lv" => [ N_("_: keyboard\nLatvian"), "lv-latin7", "lv", 0 ], |
268 |
|
|
"mal" => [ N_("_: keyboard\nMalayalam"), "us", "in(mal)", 1 ], |
269 |
|
|
"mao" => [ N_("_: keyboard\nMaori"), "us", "mao", 0 ], |
270 |
|
|
"mk" => [ N_("_: keyboard\nMacedonian"), "mk", "mkd", 1 ], |
271 |
|
|
"mm" => [ N_("_: keyboard\nMyanmar (Burmese)"), "us", "mm", 1 ], |
272 |
|
|
"mn" => [ N_("_: keyboard\nMongolian (cyrillic)"), "us", "mn", 1 ], |
273 |
|
|
"mt" => [ N_("_: keyboard\nMaltese (UK)"), "mt", "mt", 0 ], |
274 |
|
|
"mt_us" => [ N_("_: keyboard\nMaltese (US)"), "mt_us", "mt(us)", 0 ], |
275 |
|
|
"ng" => [ N_("_: keyboard\nNigerian"), "us", "ng", 0 ], |
276 |
|
|
"nl" => [ N_("_: keyboard\nDutch"), "nl-latin1", "nl", 0 ], |
277 |
|
|
"no" => [ N_("_: keyboard\nNorwegian"), "no-latin1", "no", 0 ], |
278 |
|
|
"ori" => [ N_("_: keyboard\nOriya"), "us", "in(ori)", 1 ], |
279 |
|
|
"pl" => [ N_("_: keyboard\nPolish (qwerty layout)"), "pl", "pl", 0 ], |
280 |
|
|
"pl2" => [ N_("_: keyboard\nPolish (qwertz layout)"), "pl-latin2", "pl(qwertz)", 0 ], |
281 |
|
|
# TODO: console map |
282 |
|
|
"pus" => [ N_("_: keyboard\nPashto"), "us", "pus", 1 ], |
283 |
|
|
"pt" => [ N_("_: keyboard\nPortuguese"), "pt-latin1", "pt", 0 ], |
284 |
|
|
"qc" => [ N_("_: keyboard\nCanadian (Quebec)"), "qc-latin1", "ca", 0 ], |
285 |
|
|
"ro_qwertz" => [ N_("_: keyboard\nRomanian (qwertz)"), "ro2", "ro(winkeys)", 0 ], |
286 |
|
|
"ro" => [ N_("_: keyboard\nRomanian (qwerty)"), "ro", "ro(std_cedilla)", 0 ], |
287 |
|
|
"ru" => [ N_("_: keyboard\nRussian"), "ru4", "ru(winkeys)", 1 ], |
288 |
|
|
"ru_yawerty" => [ N_("_: keyboard\nRussian (phonetic)"), "ru-yawerty", "ru(phonetic)", 1 ], |
289 |
|
|
"se" => [ N_("_: keyboard\nSwedish"), "se-latin1", "se", 0 ], |
290 |
|
|
"si" => [ N_("_: keyboard\nSlovenian"), "slovene", "si", 0 ], |
291 |
|
|
# TODO: console map |
292 |
|
|
"sin" => [ N_("_: keyboard\nSinhala"), "us", "lk", 1 ], |
293 |
|
|
"sk" => [ N_("_: keyboard\nSlovakian (QWERTZ)"), "sk-qwertz", "sk", 0 ], |
294 |
|
|
"sk_qwerty" => [ N_("_: keyboard\nSlovakian (QWERTY)"), "sk-qwerty", "sk(qwerty)", 0 ], |
295 |
|
|
"smi" => [ N_("_: keyboard\nSaami (norwegian)"), "no-latin1", "no(smi)", 0 ], |
296 |
|
|
"smi_sefi" => [ N_("_: keyboard\nSaami (swedish/finnish)"), "se-latin1", "se(smi)", 0 ], |
297 |
|
|
# TODO: console map |
298 |
|
|
"snd" => [ N_("_: keyboard\nSindhi"), "us", "snd(digits)", 1 ], |
299 |
|
|
# TODO: console map |
300 |
|
|
"srp" => [ N_("_: keyboard\nSerbian (cyrillic)"), "sr", "srp(basic),srp(latin)", 1 ], |
301 |
|
|
"syr" => [ N_("_: keyboard\nSyriac"), "us", "sy(syc)", 1 ], |
302 |
|
|
"syr_p" => [ N_("_: keyboard\nSyriac (phonetic)"), "us", "sy(syc_phonetic)", 1 ], |
303 |
|
|
"tel" => [ N_("_: keyboard\nTelugu"), "us", "in(tel)", 1 ], |
304 |
|
|
# no console kbd that I'm aware of |
305 |
|
|
"tml" => [ N_("_: keyboard\nTamil (ISCII-layout)"), "us", "in(tam)", 1 ], |
306 |
|
|
"tscii" => [ N_("_: keyboard\nTamil (Typewriter-layout)"), "us", "in(tam_unicode)", 1 ], |
307 |
|
|
"th" => [ N_("_: keyboard\nThai (Kedmanee)"), "th", "th", 1 ], |
308 |
|
|
"th_tis" => [ N_("_: keyboard\nThai (TIS-820)"), "th", "th(tis)", 1 ], |
309 |
|
|
# TODO: console map |
310 |
|
|
"th_pat" => [ N_("_: keyboard\nThai (Pattachote)"), "us", "th(pat)", 1 ], |
311 |
|
|
# NOTE: we define a triple layout here |
312 |
|
|
"tifinagh" => [ N_("_: keyboard\nTifinagh (moroccan layout) (+latin/arabic)"), "fr-tifinagh", "fr,tifinagh(basic),ara(azerty)", 1 ], |
313 |
|
|
"tifinagh_p" => [ N_("_: keyboard\nTifinagh (phonetic) (+latin/arabic)"), "fr-tifinaghp", "fr,tifinagh(phonetic),ara(azerty)", 1 ], |
314 |
|
|
# TODO: console map |
315 |
|
|
"tj" => [ N_("_: keyboard\nTajik"), "ru4", "tj", 1 ], |
316 |
|
|
# TODO: console map |
317 |
|
|
"tm" => [ N_("_: keyboard\nTurkmen"), "us", "tm", 0 ], |
318 |
|
|
"tr_f" => [ N_("_: keyboard\nTurkish (traditional \"F\" model)"), "trf", "tr(f)", 0 ], |
319 |
|
|
"tr_q" => [ N_("_: keyboard\nTurkish (modern \"Q\" model)"), "tr_q-latin5", "tr", 0 ], |
320 |
|
|
#-"tw => [ N_("_: keyboard\nChineses bopomofo"), "tw", "tw", 1 ], |
321 |
|
|
"ua" => [ N_("_: keyboard\nUkrainian"), "ua", "ua", 1 ], |
322 |
|
|
# TODO: console map |
323 |
|
|
"urd" => [ N_("_: keyboard\nUrdu keyboard"), "us", "urd", 1 ], |
324 |
|
|
"us" => [ N_("US keyboard"), "us", "us", 0 ], |
325 |
|
|
"us_intl" => [ N_("US keyboard (international)"), "us-intl", "us(alt-intl)", 0 ], |
326 |
|
|
"us3" => [ N_("ISO9995-3 (US keyboard with 3 levels per key)"), "us", "latin+level3(ralt_switch)", 0 ], |
327 |
|
|
"uz" => [ N_("_: keyboard\nUzbek (cyrillic)"), "uz", "uz", 1 ], |
328 |
|
|
# old XKB layout |
329 |
|
|
"vn" => [ N_("_: keyboard\nVietnamese \"numeric row\" QWERTY"), "vn-tcvn", "vn", 0 ], |
330 |
|
|
"yu" => [ N_("_: keyboard\nYugoslavian (latin)"), "sr", "srp(latin)", 0 ], |
331 |
|
|
), |
332 |
|
|
); |
333 |
|
|
|
334 |
|
|
#- list of possible choices for the key combinations to toggle XKB groups |
335 |
|
|
#- (eg in X86Config file: XkbOptions "grp:toggle") |
336 |
|
|
my %grp_toggles = ( |
337 |
|
|
toggle => N_("Right Alt key"), |
338 |
|
|
shifts_toggle => N_("Both Shift keys simultaneously"), |
339 |
|
|
ctrl_shift_toggle => N_("Control and Shift keys simultaneously"), |
340 |
|
|
caps_toggle => N_("CapsLock key"), |
341 |
|
|
shift_caps_toggle => N_("Shift and CapsLock keys simultaneously"), |
342 |
|
|
ctrl_alt_toggle => N_("Ctrl and Alt keys simultaneously"), |
343 |
|
|
alt_shift_toggle => N_("Alt and Shift keys simultaneously"), |
344 |
|
|
menu_toggle => N_("\"Menu\" key"), |
345 |
|
|
lwin_toggle => N_("Left \"Windows\" key"), |
346 |
|
|
rwin_toggle => N_("Right \"Windows\" key"), |
347 |
|
|
ctrls_toggle => N_("Both Control keys simultaneously"), |
348 |
|
|
alts_toggle => N_("Both Alt keys simultaneously"), |
349 |
|
|
lshift_toggle => N_("Left Shift key"), |
350 |
|
|
rshift_toggle => N_("Right Shift key"), |
351 |
|
|
lalt_toggle => N_("Left Alt key"), |
352 |
|
|
lctrl_toggle => N_("Left Control key"), |
353 |
|
|
rctrl_toggle => N_("Right Control key"), |
354 |
|
|
); |
355 |
|
|
|
356 |
|
|
|
357 |
|
|
#-###################################################################################### |
358 |
|
|
#- Functions |
359 |
|
|
#-###################################################################################### |
360 |
|
|
sub KEYBOARDs() { keys %keyboards } |
361 |
|
|
sub KEYBOARD2text { $keyboards{$_[0]} && $keyboards{$_[0]}[0] } |
362 |
|
|
sub _keyboards() { map { { KEYBOARD => $_ } } keys %keyboards } |
363 |
|
|
sub _keyboard2one { |
364 |
|
|
my ($keyboard, $nb) = @_; |
365 |
|
|
ref $keyboard or (detect_devices::is_xbox() ? return undef : internal_error()); |
366 |
|
|
my $l = $keyboards{$keyboard->{KEYBOARD}} or return; |
367 |
|
|
$l->[$nb]; |
368 |
|
|
} |
369 |
|
|
sub keyboard2text { _keyboard2one($_[0], 0) } |
370 |
|
|
sub keyboard2kmap { _keyboard2one($_[0], 1) } |
371 |
|
|
sub _keyboard2xkb { _keyboard2one($_[0], 2) } |
372 |
|
|
|
373 |
|
|
sub xkb_models() { |
374 |
|
|
my $models = _parse_xkb_rules()->{model}; |
375 |
|
|
[ map { $_->[0] } @$models ], { map { @$_ } @$models }; |
376 |
|
|
} |
377 |
|
|
|
378 |
|
|
sub _grp_toggles { |
379 |
|
|
my ($keyboard) = @_; |
380 |
|
|
_keyboard2one($keyboard, 3) or return; |
381 |
|
|
\%grp_toggles; |
382 |
|
|
} |
383 |
|
|
|
384 |
|
|
sub group_toggle_choose { |
385 |
|
|
my ($in, $keyboard) = @_; |
386 |
|
|
|
387 |
|
|
if (my $grp_toggles = _grp_toggles($keyboard)) { |
388 |
|
|
my $GRP_TOGGLE = $keyboard->{GRP_TOGGLE} || 'caps_toggle'; |
389 |
|
|
$GRP_TOGGLE = $in->ask_from_listf('', N("Here you can choose the key or key combination that will |
390 |
|
|
allow switching between the different keyboard layouts |
391 |
|
|
(eg: latin and non latin)"), sub { translate($grp_toggles->{$_[0]}) }, [ sort keys %$grp_toggles ], $GRP_TOGGLE) or return; |
392 |
|
|
|
393 |
|
|
if ($::isInstall && $GRP_TOGGLE ne 'rctrl_toggle') { |
394 |
|
|
$in->ask_warn(N("Warning"), formatAlaTeX( |
395 |
|
|
N("This setting will be activated after the installation. |
396 |
|
|
During installation, you will need to use the Right Control |
397 |
|
|
key to switch between the different keyboard layouts."))); |
398 |
|
|
} |
399 |
|
|
log::l("GRP_TOGGLE: $GRP_TOGGLE"); |
400 |
|
|
$keyboard->{GRP_TOGGLE} = $GRP_TOGGLE; |
401 |
|
|
} else { |
402 |
|
|
$keyboard->{GRP_TOGGLE} = ''; |
403 |
|
|
} |
404 |
|
|
1; |
405 |
|
|
} |
406 |
|
|
|
407 |
tv |
4298 |
# used by rescue's make_rescue_img: |
408 |
dmorgan |
391 |
sub loadkeys_files { |
409 |
|
|
my ($err) = @_; |
410 |
|
|
my $archkbd = arch() =~ /^sparc/ ? "sun" : arch() =~ /i.86|x86_64/ ? "i386" : arch() =~ /ppc/ ? "mac" : arch(); |
411 |
|
|
my $p = "/usr/lib/kbd/keymaps/$archkbd"; |
412 |
|
|
my $post = ".map.gz"; |
413 |
|
|
my %trans = ("cz-latin2" => "cz-lat2"); |
414 |
|
|
my %find_file; |
415 |
|
|
foreach my $dir (all($p)) { |
416 |
|
|
$find_file{$dir} = ''; |
417 |
|
|
foreach (all("$p/$dir")) { |
418 |
|
|
$find_file{$_} and $err->("file $_ is both in $find_file{$_} and $dir") if $err; |
419 |
|
|
$find_file{$_} = "$p/$dir/$_"; |
420 |
|
|
} |
421 |
|
|
} |
422 |
|
|
my (@l, %l); |
423 |
|
|
foreach (values %keyboards) { |
424 |
|
|
local $_ = $trans{$_->[1]} || $_->[1]; |
425 |
|
|
my $l = $find_file{"$_$post"} || $find_file{first(/(..)/) . $post}; |
426 |
|
|
if ($l) { |
427 |
|
|
push @l, $l; |
428 |
|
|
foreach (`zgrep include $l | grep "^include"`) { |
429 |
|
|
/include\s+"(.*)"/ or die "bad line $_"; |
430 |
|
|
@l{grep { -e $_ } ("$p/$1.inc.gz")} = (); |
431 |
|
|
} |
432 |
|
|
} else { |
433 |
|
|
$err->("invalid loadkeys keytable $_") if $err; |
434 |
|
|
} |
435 |
|
|
} |
436 |
|
|
uniq(@l, keys %l, grep { -e $_ } map { "$p/$_.inc.gz" } qw(compose euro windowkeys linux-keys-bare)); |
437 |
|
|
} |
438 |
|
|
|
439 |
|
|
sub _unpack_keyboards { |
440 |
|
|
my ($k) = @_; $k or return; |
441 |
|
|
[ grep { |
442 |
|
|
my $b = $keyboards{$_->[0]}; |
443 |
|
|
$b or log::l("bad keyboard $_->[0] in %keyboard::lang2keyboard"); |
444 |
|
|
$b; |
445 |
|
|
} map { [ split ':' ] } split ' ', $k ]; |
446 |
|
|
} |
447 |
|
|
sub lang2keyboards { |
448 |
|
|
my @li = sort { $b->[1] <=> $a->[1] } map { @$_ } map { |
449 |
|
|
my $h = lang::analyse_locale_name($_); |
450 |
|
|
#- example: pt_BR and pt |
451 |
|
|
my @l = (if_($h->{country}, $h->{main} . '_' . $h->{country}), $h->{main}, 'en'); |
452 |
|
|
my $k = find { $_ } map { $lang2keyboard{$_} } @l; |
453 |
|
|
_unpack_keyboards($k) || internal_error(); |
454 |
|
|
} @_; |
455 |
|
|
\@li; |
456 |
|
|
} |
457 |
|
|
sub lang2keyboard { |
458 |
|
|
my ($l) = @_; |
459 |
|
|
|
460 |
|
|
my $kb = lang2keyboards($l)->[0][0]; |
461 |
|
|
{ KEYBOARD => $keyboards{$kb} ? $kb : 'us' }; #- handle incorrect keyboard mapping to us. |
462 |
|
|
} |
463 |
|
|
|
464 |
|
|
sub default { |
465 |
|
|
my ($o_locale) = @_; |
466 |
|
|
|
467 |
|
|
my $keyboard = from_usb() || lang2keyboard(($o_locale || lang::read())->{lang}); |
468 |
|
|
add2hash($keyboard, from_DMI()); |
469 |
|
|
$keyboard; |
470 |
|
|
} |
471 |
|
|
|
472 |
|
|
sub from_usb() { |
473 |
|
|
return if $::noauto; |
474 |
|
|
my ($usb_kbd) = detect_devices::usbKeyboards() or return; |
475 |
|
|
my $country_code = detect_devices::usbKeyboard2country_code($usb_kbd) or return; |
476 |
|
|
my $keyboard = $usb2keyboard[$country_code]; |
477 |
|
|
$keyboard !~ /SKIP/ && { KEYBOARD => $keyboard }; |
478 |
|
|
} |
479 |
|
|
|
480 |
|
|
sub from_DMI() { |
481 |
|
|
my $XkbModel = detect_devices::probe_unique_name('XkbModel'); |
482 |
|
|
$XkbModel && { XkbModel => $XkbModel }; |
483 |
|
|
} |
484 |
|
|
|
485 |
|
|
sub _builtin_loadkeys { |
486 |
|
|
my ($keymap) = @_; |
487 |
|
|
return if $::testing; |
488 |
|
|
|
489 |
|
|
my ($magic, $tables_given, @tables) = common::unpack_with_refs('I' . |
490 |
|
|
'i' . c::MAX_NR_KEYMAPS() . |
491 |
|
|
's' . c::NR_KEYS() . '*', |
492 |
|
|
$keymap); |
493 |
|
|
$magic != $KMAP_MAGIC and die "failed to read kmap magic"; |
494 |
|
|
|
495 |
|
|
sysopen(my $F, "/dev/console", 2) or die "failed to open /dev/console: $!"; |
496 |
|
|
|
497 |
|
|
my $i_tables = 0; |
498 |
|
|
each_index { |
499 |
|
|
my $table_index = $::i; |
500 |
|
|
if (!$_) { |
501 |
|
|
#- deallocate table |
502 |
|
|
ioctl($F, c::KDSKBENT(), pack("CCS", $table_index, 0, c::K_NOSUCHMAP())) or log::l("removing table $table_index failed: $!"); |
503 |
|
|
} else { |
504 |
|
|
each_index { |
505 |
|
|
ioctl($F, c::KDSKBENT(), pack("CCS", $table_index, $::i, $_)) or log::l("keymap ioctl failed ($table_index $::i $_): $!"); |
506 |
|
|
} @{$tables[$i_tables++]}; |
507 |
|
|
} |
508 |
|
|
} @$tables_given; |
509 |
|
|
} |
510 |
|
|
|
511 |
|
|
sub _parse_xkb_rules() { |
512 |
|
|
my $cat; |
513 |
|
|
my %l; |
514 |
|
|
my $lst_file = "$::prefix/usr/share/X11/xkb/rules/xorg.lst"; |
515 |
|
|
foreach (cat_($lst_file)) { |
516 |
|
|
next if m!^\s*//! || m!^\s*$!; |
517 |
|
|
chomp; |
518 |
|
|
if (/^!\s*(\S+)$/) { |
519 |
|
|
$cat = $1; |
520 |
|
|
} elsif (/^\s*(\w\S*)\s+(.*)/) { |
521 |
|
|
push @{$l{$cat}}, [ $1, $2 ]; |
522 |
|
|
} else { |
523 |
|
|
log::l("_parse_xkb_rules:$lst_file: bad line $_"); |
524 |
|
|
} |
525 |
|
|
} |
526 |
|
|
\%l; |
527 |
|
|
} |
528 |
|
|
|
529 |
|
|
sub default_XkbModel { |
530 |
|
|
my ($keyboard) = @_; |
531 |
|
|
|
532 |
|
|
my $Layout = _keyboard2xkb($keyboard); |
533 |
|
|
|
534 |
|
|
(arch() =~ /sparc/ ? 'sun' : |
535 |
|
|
$Layout eq 'jp' ? 'jp106' : |
536 |
|
|
$Layout eq 'br' ? 'abnt2' : 'pc105'); |
537 |
|
|
} |
538 |
|
|
|
539 |
|
|
sub keyboard2full_xkb { |
540 |
|
|
my ($keyboard) = @_; |
541 |
|
|
|
542 |
|
|
my $Layout = _keyboard2xkb($keyboard) or return { XkbDisable => '' }; |
543 |
|
|
if ($keyboard->{GRP_TOGGLE} && $Layout !~ /,/) { |
544 |
|
|
$Layout = join(',', 'us', $Layout); |
545 |
|
|
} |
546 |
|
|
|
547 |
|
|
my $Model = $keyboard->{XkbModel} || default_XkbModel($keyboard); |
548 |
|
|
|
549 |
|
|
my $Options = join(',', |
550 |
|
|
if_($keyboard->{GRP_TOGGLE}, "grp:$keyboard->{GRP_TOGGLE}", 'grp_led:scroll'), |
551 |
|
|
if_($keyboard->{GRP_TOGGLE} ne 'rwin_toggle', 'compose:rwin'), |
552 |
|
|
); |
553 |
|
|
|
554 |
|
|
{ XkbModel => $Model, XkbLayout => $Layout, XkbOptions => $Options }; |
555 |
|
|
} |
556 |
|
|
|
557 |
|
|
sub _xmodmap_file { |
558 |
|
|
my ($keyboard) = @_; |
559 |
|
|
my $f = "$ENV{SHARE_PATH}/xmodmap/xmodmap.$keyboard->{KEYBOARD}"; |
560 |
|
|
-e $f && $f; |
561 |
|
|
} |
562 |
|
|
|
563 |
|
|
sub _setxkbmap { |
564 |
|
|
my ($keyboard) = @_; |
565 |
|
|
my $xkb = keyboard2full_xkb($keyboard) or return; |
566 |
|
|
run_program::run('setxkbmap', '-option', '') if $xkb->{XkbOptions}; #- need re-initialised other toggles are cumulated |
567 |
|
|
run_program::run('setxkbmap', $xkb->{XkbLayout}, '-model' => $xkb->{XkbModel}, '-option' => $xkb->{XkbOptions} || '', '-compat' => $xkb->{XkbCompat} || ''); |
568 |
|
|
} |
569 |
|
|
|
570 |
|
|
sub setup_install { |
571 |
|
|
my ($keyboard) = @_; |
572 |
|
|
|
573 |
|
|
return if arch() =~ /^sparc/ || $::local_install; |
574 |
|
|
|
575 |
|
|
#- Xpmac does not map keys quite right |
576 |
|
|
if (arch() =~ /ppc/ && !$::testing && $ENV{DISPLAY}) { |
577 |
|
|
log::l("Fixing Mac keyboard"); |
578 |
|
|
run_program::run('xmodmap', "-e", "keycode 59 = BackSpace"); |
579 |
|
|
run_program::run('xmodmap', "-e", "keycode 131 = Shift_R"); |
580 |
|
|
run_program::run('xmodmap', "-e", "add shift = Shift_R"); |
581 |
|
|
return; |
582 |
|
|
} |
583 |
|
|
|
584 |
|
|
my $kmap = keyboard2kmap($keyboard) or return; |
585 |
|
|
|
586 |
|
|
log::l("loading keymap $kmap"); |
587 |
|
|
if (-e (my $f = "$ENV{SHARE_PATH}/keymaps/$kmap.bkmap")) { |
588 |
|
|
_builtin_loadkeys(scalar cat_($f)); |
589 |
|
|
} elsif (-x '/bin/loadkeys') { |
590 |
|
|
run_program::run('loadkeys', $kmap); |
591 |
|
|
} else { |
592 |
|
|
log::l("ERROR: can not load keymap"); |
593 |
|
|
} |
594 |
tv |
3199 |
setup_install_X11($keyboard) if $::o->{interactive} ne "curses"; |
595 |
tv |
3197 |
} |
596 |
dmorgan |
391 |
|
597 |
tv |
3197 |
sub setup_install_X11 { |
598 |
|
|
my ($keyboard) = @_; |
599 |
dmorgan |
391 |
if (-x "/usr/bin/setxkbmap") { |
600 |
|
|
_setxkbmap($keyboard) or log::l("setxkbmap failed"); |
601 |
|
|
} else { |
602 |
|
|
my $f = _xmodmap_file($keyboard); |
603 |
|
|
#- timeout is needed for drakx-in-chroot to kill xmodmap when it gets crazy with: |
604 |
|
|
#- please release the following keys within 2 seconds: Alt_L (keysym 0xffe9, keycode 64) |
605 |
|
|
eval { run_program::raw({ timeout => 3 }, 'xmodmap', $f) } if $f && !$::testing && $ENV{DISPLAY}; |
606 |
|
|
} |
607 |
|
|
} |
608 |
|
|
|
609 |
|
|
sub write { |
610 |
|
|
my ($keyboard) = @_; |
611 |
|
|
log::l("keyboard::write $keyboard->{KEYBOARD}"); |
612 |
|
|
|
613 |
|
|
$keyboard = { %$keyboard }; |
614 |
|
|
put_in_hash($keyboard, keyboard2full_xkb($keyboard)); |
615 |
|
|
delete $keyboard->{unsafe}; |
616 |
|
|
$keyboard->{KEYTABLE} = keyboard2kmap($keyboard); |
617 |
|
|
|
618 |
|
|
setVarsInSh("$::prefix/etc/sysconfig/keyboard", $keyboard); |
619 |
|
|
if (arch() =~ /ppc/) { |
620 |
|
|
my $s = "dev.mac_hid.keyboard_sends_linux_keycodes = 1\n"; |
621 |
|
|
substInFile { |
622 |
|
|
$_ = '' if /^\Qdev.mac_hid.keyboard_sends_linux_keycodes/; |
623 |
|
|
$_ .= $s if eof; |
624 |
|
|
} "$::prefix/etc/sysctl.conf"; |
625 |
|
|
} else { |
626 |
|
|
run_program::rooted($::prefix, 'dumpkeys', '>', '/etc/sysconfig/console/default.kmap') or log::l("dumpkeys failed"); |
627 |
|
|
} |
628 |
dmorgan |
865 |
run_program::run('mageia-setup-keyboard'); |
629 |
dmorgan |
391 |
} |
630 |
|
|
|
631 |
|
|
sub configure_and_set_standalone { |
632 |
|
|
my ($keyboard) = @_; |
633 |
|
|
|
634 |
|
|
_setxkbmap($keyboard); |
635 |
|
|
run_program::run('loadkeys', keyboard2kmap($keyboard)); |
636 |
|
|
|
637 |
|
|
&write($keyboard); |
638 |
|
|
} |
639 |
|
|
|
640 |
|
|
sub read() { |
641 |
|
|
my %keyboard = getVarsFromSh("$::prefix/etc/sysconfig/keyboard") or return; |
642 |
|
|
if (!$keyboard{KEYBOARD}) { |
643 |
|
|
add2hash(\%keyboard, grep { keyboard2kmap($_) eq $keyboard{KEYTABLE} } _keyboards()); |
644 |
|
|
} |
645 |
|
|
keyboard2text(\%keyboard) && \%keyboard; |
646 |
|
|
} |
647 |
|
|
sub read_or_default() { &read() || default() } |
648 |
|
|
|
649 |
|
|
sub check() { |
650 |
|
|
$^W = 0; |
651 |
|
|
|
652 |
|
|
my $not_ok = 0; |
653 |
|
|
my $warn = sub { |
654 |
|
|
print STDERR "$_[0]\n"; |
655 |
|
|
}; |
656 |
|
|
my $err = sub { |
657 |
|
|
&$warn; |
658 |
|
|
$not_ok = 1; |
659 |
|
|
}; |
660 |
|
|
|
661 |
|
|
if (my @l = grep { is_empty_array_ref(lang2keyboards($_)) } lang::list_langs()) { |
662 |
|
|
$warn->("no keyboard for langs " . join(" ", @l)); |
663 |
|
|
} |
664 |
|
|
foreach my $lang (lang::list_langs()) { |
665 |
|
|
my $l = lang2keyboards($lang); |
666 |
|
|
foreach (@$l) { |
667 |
|
|
0 <= $_->[1] && $_->[1] <= 100 or $err->("invalid value $_->[1] in $lang2keyboard{$lang} for $lang in \%lang2keyboard keyboard.pm"); |
668 |
|
|
$keyboards{$_->[0]} or $err->("invalid keyboard $_->[0] in $lang2keyboard{$lang} for $lang in \%lang2keyboard keyboard.pm"); |
669 |
|
|
} |
670 |
|
|
} |
671 |
|
|
/SKIP/ || $keyboards{$_} or $err->("invalid keyboard $_ in \@usb2keyboard keyboard.pm") foreach @usb2keyboard; |
672 |
|
|
$usb2keyboard[0x21] eq 'us_SKIP' or $err->('@usb2keyboard is badly modified, 0x21 is not us keyboard'); |
673 |
|
|
|
674 |
|
|
my @xkb_groups = map { if_(/grp:(\S+)/, $1) } cat_('/usr/lib/X11/xkb/rules/xfree86.lst'); |
675 |
|
|
$err->("invalid xkb group toggle '$_' in \%grp_toggles") foreach difference2([ keys %grp_toggles ], \@xkb_groups); |
676 |
|
|
$warn->("unused xkb group toggle '$_'") foreach grep { !/switch/ } difference2(\@xkb_groups, [ keys %grp_toggles ]); |
677 |
|
|
|
678 |
|
|
my @xkb_layouts = (#- (map { (split)[0] } grep { /^! layout/ .. /^\s*$/ } cat_('/usr/lib/X11/xkb/rules/xfree86.lst')), |
679 |
|
|
all('/usr/lib/X11/xkb/symbols'), |
680 |
|
|
(map { (split)[2] } cat_('/usr/lib/X11/xkb/symbols.dir'))); |
681 |
|
|
$err->("invalid xkb layout $_") foreach difference2([ map { _keyboard2xkb($_) } _keyboards() ], \@xkb_layouts); |
682 |
|
|
|
683 |
|
|
my @kmaps_available = map { if_(m|.*/(.*)\.bkmap|, $1) } `tar tfj share/keymaps.tar.bz2`; |
684 |
|
|
my @kmaps_wanted = map { keyboard2kmap($_) } _keyboards(); |
685 |
|
|
$err->("missing KEYTABLE $_ (either share/keymaps.tar.bz2 need updating or $_ is bad)") foreach difference2(\@kmaps_wanted, \@kmaps_available); |
686 |
|
|
$err->("unused KEYTABLE $_ (update share/keymaps.tar.bz2 using share/keymaps_generate)") foreach difference2(\@kmaps_available, \@kmaps_wanted); |
687 |
|
|
|
688 |
|
|
loadkeys_files($err); |
689 |
|
|
|
690 |
|
|
exit($not_ok); |
691 |
|
|
} |
692 |
|
|
|
693 |
|
|
1; |