1 #include <linux/keyboard.h>
10 #include "syms.cp1250.h"
11 #include "syms.ethiopic.h"
12 #include "syms.iso8859_15.h"
13 #include "syms.iso8859_5.h"
14 #include "syms.iso8859_7.h"
15 #include "syms.iso8859_8.h"
16 #include "syms.iso8859_9.h"
17 #include "syms.koi8.h"
18 #include "syms.latin1.h"
19 #include "syms.latin2.h"
20 #include "syms.latin3.h"
21 #include "syms.latin4.h"
22 #include "syms.mazovia.h"
23 #include "syms.sami.h"
24 #include "syms.thai.h"
26 #include "syms.synonyms.h"
28 #include "syms.ktyp.h"
30 #define E(x) { x, sizeof(x) / sizeof(x[0]) }
34 E(iso646_syms), /* KT_LATIN */
35 E(fn_syms), /* KT_FN */
36 E(spec_syms), /* KT_SPEC */
37 E(pad_syms), /* KT_PAD */
38 E(dead_syms), /* KT_DEAD */
39 E(cons_syms), /* KT_CONS */
40 E(cur_syms), /* KT_CUR */
41 E(shift_syms), /* KT_SHIFT */
42 { 0, 0 }, /* KT_META */
43 E(ascii_syms), /* KT_ASCII */
44 E(lock_syms), /* KT_LOCK */
45 { 0, 0 }, /* KT_LETTER */
46 E(sticky_syms), /* KT_SLOCK */
48 E(brl_syms) /* KT_BRL */
53 const unsigned int syms_size = sizeof(syms) / sizeof(syms_entry);
54 const unsigned int syn_size = sizeof(synonyms) / sizeof(synonyms[0]);
62 { "iso-8859-1", latin1_syms, 160 },
63 { "iso-8859-2", latin2_syms, 160 },
64 { "iso-8859-3", latin3_syms, 160 },
65 { "iso-8859-4", latin4_syms, 160 },
66 { "iso-8859-5", iso_8859_5_syms, 160 },
67 { "iso-8859-7", iso_8859_7_syms, 160 },
68 { "iso-8859-8", iso_8859_8_syms, 160 },
69 { "iso-8859-9", iso_8859_9_syms, 208 },
70 { "iso-8859-10", latin6_syms, 160 },
71 { "iso-8859-15", iso_8859_15_syms, 160 },
72 { "mazovia", mazovia_syms, 128 },
73 { "cp-1250", cp1250_syms, 128 },
74 { "koi8-r", koi8_syms, 128 },
75 { "koi8-u", koi8_syms, 128 },
76 { "tis-620", tis_620_syms, 160 }, /* thai */
77 { "iso-10646-18", iso_10646_18_syms, 159 }, /* ethiopic */
78 { "iso-ir-197", iso_ir_197_syms, 160 }, /* sami */
79 { "iso-ir-209", iso_ir_209_syms, 160 }, /* sami */
82 static unsigned int charsets_size = sizeof(charsets) / sizeof(charsets[0]);
84 /* Functions for both dumpkeys and loadkeys. */
87 lk_list_charsets(FILE *f) {
90 char *mm[] = { "iso-8859-", "koi8-" };
92 for (j=0; j<sizeof(mm)/sizeof(mm[0]); j++) {
95 fprintf(f, "%s{", mm[j]);
98 for(i=1; i < charsets_size; i++) {
99 if(!strncmp(charsets[i].charset, mm[j], lth)) {
102 fprintf(f, "%s", charsets[i].charset+lth);
107 for(i=1; i < charsets_size; i++) {
108 for (j=0; j<sizeof(mm)/sizeof(mm[0]); j++) {
110 if(!strncmp(charsets[i].charset, mm[j], lth))
113 fprintf(f, ",%s", charsets[i].charset);
120 lk_get_charset(struct keymap *kmap)
122 if (!kmap || !kmap->charset || kmap->charset >= charsets_size)
125 return charsets[kmap->charset].charset;
129 lk_set_charset(struct keymap *kmap, const char *charset) {
132 for (i = 1; i < charsets_size; i++) {
133 if (!strcasecmp(charsets[i].charset, charset)) {
142 codetoksym(struct keymap *kmap, int code) {
150 if (code < 0x1000) { /* "traditional" keysym */
152 return iso646_syms[code];
154 if (KTYP(code) == KT_META)
157 if (KTYP(code) == KT_LETTER)
158 code = K(KT_LATIN, KVAL(code));
160 if (KTYP(code) > KT_LATIN)
161 return syms[KTYP(code)].table[KVAL(code)];
165 p = (sym *) charsets[i].charnames;
167 p += KVAL(code) - charsets[i].start;
175 if (i == charsets_size)
177 if (i == kmap->charset)
182 else { /* Unicode keysym */
186 return iso646_syms[code];
190 p = (sym *) charsets[i].charnames;
192 for (j = charsets[i].start; j < 256; j++, p++) {
193 if (p->uni == code && p->name[0])
200 if (i == charsets_size)
202 if (i == kmap->charset)
211 /* Functions for loadkeys. */
214 kt_latin(struct keymap *kmap, const char *s, int direction) {
218 sym *p = (sym *) charsets[kmap->charset].charnames;
220 for (i = charsets[kmap->charset].start; i < 256; i++, p++) {
221 if(p->name[0] && !strcmp(s, p->name))
222 return K(KT_LATIN, i);
226 max = (direction == TO_UNICODE ? 128 : syms[KT_LATIN].size);
228 for (i = 0; i < max; i++) {
229 if (!strcmp(s, syms[KT_LATIN].table[i]))
230 return K(KT_LATIN, i);
237 ksymtocode(struct keymap *kmap, const char *s, int direction) {
243 if (direction == TO_AUTO)
244 direction = (kmap->flags & LKFLAG_PREFER_UNICODE)
245 ? TO_UNICODE : TO_8BIT;
247 if (!strncmp(s, "Meta_", 5)) {
248 keycode = ksymtocode(kmap, s+5, TO_8BIT);
249 if (KTYP(keycode) == KT_LATIN)
250 return K(KT_META, KVAL(keycode));
252 /* Avoid error messages for Meta_acute with UTF-8 */
253 else if(direction == TO_UNICODE)
256 /* fall through to error printf */
259 if ((n = kt_latin(kmap, s, direction)) >= 0) {
263 for (i = 1; i < syms_size; i++) {
264 for (j = 0; j < syms[i].size; j++) {
265 if (!strcmp(s,syms[i].table[j]))
270 for (i = 0; i < syn_size; i++)
271 if (!strcmp(s, synonyms[i].synonym))
272 return ksymtocode(kmap, synonyms[i].official_name, direction);
274 if (direction == TO_UNICODE) {
278 p = (sym *) charsets[i].charnames;
280 for (j = charsets[i].start; j < 256; j++, p++) {
281 if (!strcmp(s,p->name))
282 return (p->uni ^ 0xf000);
288 if (i == charsets_size)
290 if (i == kmap->charset)
293 } else /* if (!chosen_charset[0]) */ {
294 /* note: some keymaps use latin1 but with euro,
295 so set_charset() would fail */
296 /* note: some keymaps with charset line still use
297 symbols from more than one character set,
298 so we cannot have the `if (!chosen_charset[0])' here */
300 for (i = 0; i < 256 - 160; i++)
301 if (!strcmp(s, latin1_syms[i].name)) {
302 INFO(kmap, _("assuming iso-8859-1 %s"), s);
303 return K(KT_LATIN, 160 + i);
306 for (i = 0; i < 256 - 160; i++)
307 if (!strcmp(s, iso_8859_15_syms[i].name)) {
308 INFO(kmap, _("assuming iso-8859-15 %s"), s);
309 return K(KT_LATIN, 160 + i);
312 for (i = 0; i < 256 - 160; i++)
313 if (!strcmp(s, latin2_syms[i].name)) {
314 INFO(kmap, _("assuming iso-8859-2 %s"), s);
315 return K(KT_LATIN, 160 + i);
318 for (i = 0; i < 256 - 160; i++)
319 if (!strcmp(s, latin3_syms[i].name)) {
320 INFO(kmap, _("assuming iso-8859-3 %s"), s);
321 return K(KT_LATIN, 160 + i);
324 for (i = 0; i < 256 - 160; i++)
325 if (!strcmp(s, latin4_syms[i].name)) {
326 INFO(kmap, _("assuming iso-8859-4 %s"), s);
327 return K(KT_LATIN, 160 + i);
331 ERR(kmap, _("unknown keysym '%s'\n"), s);
333 return CODE_FOR_UNKNOWN_KSYM;
337 convert_code(struct keymap *kmap, int code, int direction)
340 int unicode_forced = (direction == TO_UNICODE);
341 int input_is_unicode = (code >= 0x1000);
344 if (direction == TO_AUTO)
345 direction = (kmap->flags & LKFLAG_PREFER_UNICODE)
346 ? TO_UNICODE : TO_8BIT;
348 if (KTYP(code) == KT_META)
350 else if (!input_is_unicode && code < 0x80)
351 /* basic ASCII is fine in every situation */
353 else if (input_is_unicode && (code ^ 0xf000) < 0x80)
354 /* so is Unicode "Basic Latin" */
355 return code ^ 0xf000;
356 else if ((input_is_unicode && direction == TO_UNICODE) ||
357 (!input_is_unicode && direction == TO_8BIT))
358 /* no conversion necessary */
361 /* depending on direction, this will give us either an 8-bit
362 * K(KTYP, KVAL) or a Unicode keysym xor 0xf000 */
363 ksym = codetoksym(kmap, code);
365 result = ksymtocode(kmap, ksym, direction);
370 /* if direction was TO_UNICODE from the beginning, we return the true
371 * Unicode value (without the 0xf000 mask) */
372 if (unicode_forced && result >= 0x1000)
373 return result ^ 0xf000;
379 add_capslock(struct keymap *kmap, int code)
381 if (KTYP(code) == KT_LATIN && (!(kmap->flags & LKFLAG_PREFER_UNICODE) || code < 0x80))
382 return K(KT_LETTER, KVAL(code));
383 else if ((code ^ 0xf000) < 0x100)
384 /* Unicode Latin-1 Supplement */
385 /* a bit dirty to use KT_LETTER here, but it should work */
386 return K(KT_LETTER, code ^ 0xf000);
388 return convert_code(kmap, code, TO_AUTO);