Move lk_ctx content to private part of library
[platform/upstream/kbd.git] / src / libkeymap / ksyms.c
index 75b9ccf..0c2d6c1 100644 (file)
@@ -2,11 +2,13 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include "ksyms.h"
-#include "nls.h"
 
 #include "keymap.h"
 
+#include "contextP.h"
+#include "ksyms.h"
+#include "nls.h"
+
 #include "syms.cp1250.h"
 #include "syms.ethiopic.h"
 #include "syms.iso8859_15.h"
@@ -29,8 +31,8 @@
 
 #define E(x) { x, sizeof(x) / sizeof(x[0]) }
 
-syms_entry
-const syms[] = {
+const syms_entry
+syms[] = {
        E(iso646_syms),         /* KT_LATIN */
        E(fn_syms),             /* KT_FN */
        E(spec_syms),           /* KT_SPEC */
@@ -53,36 +55,38 @@ const syms[] = {
 const unsigned int syms_size = sizeof(syms) / sizeof(syms_entry);
 const unsigned int syn_size = sizeof(synonyms) / sizeof(synonyms[0]);
 
-struct cs {
-    const char *charset;
-    sym *charnames;
-    int start;
+const struct cs {
+       const char *charset;
+       const sym *charnames;
+       const int start;
 } charsets[] = {
-    { "", NULL, 256 },
-    { "iso-8859-1",    latin1_syms, 160 },
-    { "iso-8859-2",    latin2_syms, 160 },
-    { "iso-8859-3",    latin3_syms, 160 },
-    { "iso-8859-4",    latin4_syms, 160 },
-    { "iso-8859-5",    iso_8859_5_syms, 160 },
-    { "iso-8859-7",    iso_8859_7_syms, 160 },
-    { "iso-8859-8",    iso_8859_8_syms, 160 },
-    { "iso-8859-9",    iso_8859_9_syms, 208 },
-    { "iso-8859-10",   latin6_syms, 160 },
-    { "iso-8859-15",   iso_8859_15_syms, 160 },
-    { "mazovia",       mazovia_syms, 128 },
-    { "cp-1250",       cp1250_syms, 128 },
-    { "koi8-r",                koi8_syms, 128 },
-    { "koi8-u",                koi8_syms, 128 },
-    { "tis-620",       tis_620_syms, 160 },            /* thai */
-    { "iso-10646-18",  iso_10646_18_syms, 159 },       /* ethiopic */
-    { "iso-ir-197",    iso_ir_197_syms, 160 },         /* sami */
-    { "iso-ir-209",    iso_ir_209_syms, 160 },         /* sami */
+       { "",             NULL,                0 },
+       { "iso-8859-1",   latin1_syms,       160 },
+       { "iso-8859-2",   latin2_syms,       160 },
+       { "iso-8859-3",   latin3_syms,       160 },
+       { "iso-8859-4",   latin4_syms,       160 },
+       { "iso-8859-5",   iso_8859_5_syms,   160 },
+       { "iso-8859-7",   iso_8859_7_syms,   160 },
+       { "iso-8859-8",   iso_8859_8_syms,   160 },
+       { "iso-8859-9",   iso_8859_9_syms,   208 },
+       { "iso-8859-10",  latin6_syms,       160 },
+       { "iso-8859-15",  iso_8859_15_syms,  160 },
+       { "mazovia",      mazovia_syms,      128 },
+       { "cp-1250",      cp1250_syms,       128 },
+       { "koi8-r",       koi8_syms,         128 },
+       { "koi8-u",       koi8_syms,         128 },
+       { "tis-620",      tis_620_syms,      160 }, /* thai */
+       { "iso-10646-18", iso_10646_18_syms, 159 }, /* ethiopic */
+       { "iso-ir-197",   iso_ir_197_syms,   160 }, /* sami */
+       { "iso-ir-209",   iso_ir_209_syms,   160 }, /* sami */
 };
 
+static unsigned int charsets_size = sizeof(charsets) / sizeof(charsets[0]);
+
 /* Functions for both dumpkeys and loadkeys. */
 
 void
-list_charsets(FILE *f) {
+lk_list_charsets(FILE *f) {
        int lth,ct;
        unsigned int i, j;
        char *mm[] = { "iso-8859-", "koi8-" };
@@ -93,7 +97,7 @@ list_charsets(FILE *f) {
                fprintf(f, "%s{", mm[j]);
                ct = 0;
                lth = strlen(mm[j]);
-               for(i=1; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
+               for(i=1; i < charsets_size; i++) {
                        if(!strncmp(charsets[i].charset, mm[j], lth)) {
                                if(ct++)
                                        fprintf(f, ",");
@@ -102,7 +106,7 @@ list_charsets(FILE *f) {
                }
                fprintf(f, "}");
        }
-       for(i=1; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
+       for(i=1; i < charsets_size; i++) {
                for (j=0; j<sizeof(mm)/sizeof(mm[0]); j++) {
                        lth = strlen(mm[j]);
                        if(!strncmp(charsets[i].charset, mm[j], lth))
@@ -114,21 +118,22 @@ list_charsets(FILE *f) {
        fprintf(f, "\n");
 }
 
+const char *
+lk_get_charset(struct lk_ctx *ctx)
+{
+       if (!ctx || !ctx->charset || ctx->charset >= charsets_size)
+               return NULL;
+
+       return charsets[ctx->charset].charset;
+}
+
 int
-set_charset(const char *charset) {
-       sym *p;
+lk_set_charset(struct lk_ctx *ctx, const char *charset) {
        unsigned int i;
 
-       for (i = 1; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
+       for (i = 1; i < charsets_size; i++) {
                if (!strcasecmp(charsets[i].charset, charset)) {
-                       charsets[0].charset = charsets[i].charset;
-                       charsets[0].charnames = charsets[i].charnames;
-                       charsets[0].start = charsets[i].start;
-                       p = charsets[i].charnames;
-                       for (i = charsets[i].start; i < 256; i++,p++) {
-                               if(p->name[0])
-                                       syms[0].table[i] = p->name;
-                       }
+                       ctx->charset = i;
                        return 0;
                }
        }
@@ -136,7 +141,7 @@ set_charset(const char *charset) {
 }
 
 const char *
-codetoksym(int code) {
+codetoksym(struct lk_ctx *ctx, int code) {
        unsigned int i;
        int j;
        sym *p;
@@ -147,20 +152,32 @@ codetoksym(int code) {
        if (code < 0x1000) {    /* "traditional" keysym */
                if (code < 0x80)
                        return iso646_syms[code];
+
                if (KTYP(code) == KT_META)
                        return NULL;
+
                if (KTYP(code) == KT_LETTER)
                        code = K(KT_LATIN, KVAL(code));
+
                if (KTYP(code) > KT_LATIN)
                        return syms[KTYP(code)].table[KVAL(code)];
 
-               for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
-                       p = charsets[i].charnames;
-                       if (!p)
-                               continue;
-                       p += KVAL(code) - charsets[i].start;
-                       if (p->name[0])
-                               return p->name;
+               i = ctx->charset;
+               while (1) {
+                       p = (sym *) charsets[i].charnames;
+                       if (p) {
+                               p += KVAL(code) - charsets[i].start;
+
+                               if (p->name[0])
+                                       return p->name;
+                       }
+
+                       i++;
+
+                       if (i == charsets_size)
+                               i = 0;
+                       if (i == ctx->charset)
+                               break;
                }
        }
 
@@ -170,15 +187,24 @@ codetoksym(int code) {
                if (code < 0x80)
                        return iso646_syms[code];
 
-               for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
-                       p = charsets[i].charnames;
-                       if (!p)
-                               continue;
-                       for (j = charsets[i].start; j < 256; j++, p++) {
-                               if (p->uni == code && p->name[0])
-                                       return p->name;
+               i = ctx->charset;
+               while (1) {
+                       p = (sym *) charsets[i].charnames;
+                       if (p) {
+                               for (j = charsets[i].start; j < 256; j++, p++) {
+                                       if (p->uni == code && p->name[0])
+                                               return p->name;
+                               }
                        }
+
+                       i++;
+
+                       if (i == charsets_size)
+                               i = 0;
+                       if (i == ctx->charset)
+                               break;
                }
+
        }
 
        return NULL;
@@ -186,18 +212,42 @@ codetoksym(int code) {
 
 /* Functions for loadkeys. */
 
+static int
+kt_latin(struct lk_ctx *ctx, const char *s, int direction) {
+       int i, max;
+
+       if (ctx->charset) {
+               sym *p = (sym *) charsets[ctx->charset].charnames;
+
+               for (i = charsets[ctx->charset].start; i < 256; i++, p++) {
+                       if(p->name[0] && !strcmp(s, p->name))
+                               return K(KT_LATIN, i);
+               }
+       }
+
+       max = (direction == TO_UNICODE ? 128 : syms[KT_LATIN].size);
+
+       for (i = 0; i < max; i++) {
+               if (!strcmp(s, syms[KT_LATIN].table[i]))
+                       return K(KT_LATIN, i);
+       }
+
+       return -1;
+}
+
 int
-ksymtocode(struct keymap *kmap, const char *s, int direction) {
+ksymtocode(struct lk_ctx *ctx, const char *s, int direction) {
        unsigned int i;
-       int j, jmax;
+       int n, j;
        int keycode;
        sym *p;
 
        if (direction == TO_AUTO)
-               direction = kmap->prefer_unicode ? TO_UNICODE : TO_8BIT;
+               direction = (ctx->flags & LK_FLAG_PREFER_UNICODE)
+                       ? TO_UNICODE : TO_8BIT;
 
        if (!strncmp(s, "Meta_", 5)) {
-               keycode = ksymtocode(kmap, s+5, TO_8BIT);
+               keycode = ksymtocode(ctx, s+5, TO_8BIT);
                if (KTYP(keycode) == KT_LATIN)
                        return K(KT_META, KVAL(keycode));
 
@@ -208,23 +258,39 @@ ksymtocode(struct keymap *kmap, const char *s, int direction) {
                /* fall through to error printf */
        }
 
-       for (i = 0; i < syms_size; i++) {
-               jmax = ((i == 0 && direction == TO_UNICODE) ? 128 : syms[i].size);
-               for (j = 0; j < jmax; j++)
+       if ((n = kt_latin(ctx, s, direction)) >= 0) {
+               return n;
+       }
+
+       for (i = 1; i < syms_size; i++) {
+               for (j = 0; j < syms[i].size; j++) {
                        if (!strcmp(s,syms[i].table[j]))
                                return K(i, j);
+               }
        }
 
        for (i = 0; i < syn_size; i++)
                if (!strcmp(s, synonyms[i].synonym))
-                       return ksymtocode(kmap, synonyms[i].official_name, direction);
+                       return ksymtocode(ctx, synonyms[i].official_name, direction);
 
        if (direction == TO_UNICODE) {
-               for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
-                       p = charsets[i].charnames;
-                       for (j = charsets[i].start; j < 256; j++, p++)
-                               if (!strcmp(s,p->name))
-                                       return (p->uni ^ 0xf000);
+               i = ctx->charset;
+
+               while (1) {
+                       p = (sym *) charsets[i].charnames;
+                       if (p) {
+                               for (j = charsets[i].start; j < 256; j++, p++) {
+                                       if (!strcmp(s,p->name))
+                                               return (p->uni ^ 0xf000);
+                               }
+                       }
+
+                       i++;
+
+                       if (i == charsets_size)
+                               i = 0;
+                       if (i == ctx->charset)
+                               break;
                }
        } else /* if (!chosen_charset[0]) */ {
                /* note: some keymaps use latin1 but with euro,
@@ -235,47 +301,42 @@ ksymtocode(struct keymap *kmap, const char *s, int direction) {
 
                for (i = 0; i < 256 - 160; i++)
                        if (!strcmp(s, latin1_syms[i].name)) {
-                               log_verbose(kmap, LOG_VERBOSE1,
-                                       _("assuming iso-8859-1 %s\n"), s);
+                               INFO(ctx, _("assuming iso-8859-1 %s"), s);
                                return K(KT_LATIN, 160 + i);
                        }
 
                for (i = 0; i < 256 - 160; i++)
                        if (!strcmp(s, iso_8859_15_syms[i].name)) {
-                               log_verbose(kmap, LOG_VERBOSE1,
-                                       _("assuming iso-8859-15 %s\n"), s);
+                               INFO(ctx, _("assuming iso-8859-15 %s"), s);
                                return K(KT_LATIN, 160 + i);
                        }
 
                for (i = 0; i < 256 - 160; i++)
                        if (!strcmp(s, latin2_syms[i].name)) {
-                               log_verbose(kmap, LOG_VERBOSE1,
-                                       _("assuming iso-8859-2 %s\n"), s);
+                               INFO(ctx, _("assuming iso-8859-2 %s"), s);
                                return K(KT_LATIN, 160 + i);
                        }
 
                for (i = 0; i < 256 - 160; i++)
                        if (!strcmp(s, latin3_syms[i].name)) {
-                               log_verbose(kmap, LOG_VERBOSE1,
-                                       _("assuming iso-8859-3 %s\n"), s);
+                               INFO(ctx, _("assuming iso-8859-3 %s"), s);
                                return K(KT_LATIN, 160 + i);
                        }
 
                for (i = 0; i < 256 - 160; i++)
                        if (!strcmp(s, latin4_syms[i].name)) {
-                               log_verbose(kmap, LOG_VERBOSE1,
-                                       _("assuming iso-8859-4 %s\n"), s);
+                               INFO(ctx, _("assuming iso-8859-4 %s"), s);
                                return K(KT_LATIN, 160 + i);
                        }
        }
 
-       log_error(kmap, _("unknown keysym '%s'\n"), s);
+       ERR(ctx, _("unknown keysym '%s'\n"), s);
 
        return CODE_FOR_UNKNOWN_KSYM;
 }
 
 int
-convert_code(struct keymap *kmap, int code, int direction)
+convert_code(struct lk_ctx *ctx, int code, int direction)
 {
        const char *ksym;
        int unicode_forced = (direction == TO_UNICODE);
@@ -283,7 +344,8 @@ convert_code(struct keymap *kmap, int code, int direction)
        int result;
 
        if (direction == TO_AUTO)
-               direction = kmap->prefer_unicode ? TO_UNICODE : TO_8BIT;
+               direction = (ctx->flags & LK_FLAG_PREFER_UNICODE)
+                   ? TO_UNICODE : TO_8BIT;
 
        if (KTYP(code) == KT_META)
                return code;
@@ -300,9 +362,9 @@ convert_code(struct keymap *kmap, int code, int direction)
        else {
                /* depending on direction, this will give us either an 8-bit
                 * K(KTYP, KVAL) or a Unicode keysym xor 0xf000 */
-               ksym = codetoksym(code);
+               ksym = codetoksym(ctx, code);
                if (ksym)
-                       result = ksymtocode(kmap, ksym, direction);
+                       result = ksymtocode(ctx, ksym, direction);
                else
                        result = code;
        }
@@ -316,14 +378,14 @@ convert_code(struct keymap *kmap, int code, int direction)
 }
 
 int
-add_capslock(struct keymap *kmap, int code)
+add_capslock(struct lk_ctx *ctx, int code)
 {
-       if (KTYP(code) == KT_LATIN && (!(kmap->prefer_unicode) || code < 0x80))
+       if (KTYP(code) == KT_LATIN && (!(ctx->flags & LK_FLAG_PREFER_UNICODE) || code < 0x80))
                return K(KT_LETTER, KVAL(code));
        else if ((code ^ 0xf000) < 0x100)
                /* Unicode Latin-1 Supplement */
                /* a bit dirty to use KT_LETTER here, but it should work */
                return K(KT_LETTER, code ^ 0xf000);
        else
-               return convert_code(kmap, code, TO_AUTO);
+               return convert_code(ctx, code, TO_AUTO);
 }