Fix the keyboard config to match Tizen 2.0 alpha
[profile/ivi/libxkbcommon.git] / src / xkbcomp / keymap.c
index 9221852..f3bf821 100644 (file)
 
  ********************************************************/
 
-#include "xkbcomp.h"
-#include "xkbmisc.h"
-#include "expr.h"
-#include "vmod.h"
-#include "action.h"
-#include "misc.h"
+#include "xkbcomp-priv.h"
 #include "indicators.h"
 
-#define        KEYCODES        0
-#define        GEOMETRY        1
-#define        TYPES           2
-#define        COMPAT          3
-#define        SYMBOLS         4
-#define        MAX_SECTIONS    5
-
 /**
  * Compile the given file and store the output in xkb.
  * @param file A list of XkbFiles, each denoting one type (e.g.
  * XkmKeyNamesIdx, etc.)
  */
-Bool
-CompileKeymap(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
+struct xkb_keymap *
+CompileKeymap(struct xkb_context *ctx, XkbFile *file)
 {
     unsigned have;
-    Bool ok;
+    bool ok;
     unsigned required, legal;
     unsigned mainType;
-    char *mainName;
-    LEDInfo *unbound = NULL;
-    XkbFile *sections[MAX_SECTIONS];
+    const char *mainName;
+    LEDInfo *unbound = NULL, *next;
+    struct xkb_keymap *keymap = XkbcAllocKeyboard(ctx);
+    struct {
+        XkbFile *keycodes;
+        XkbFile *types;
+        XkbFile *compat;
+        XkbFile *symbols;
+    } sections;
+
+    if (!keymap)
+        return NULL;
 
-    memset(sections, 0, sizeof(sections));
+    memset(&sections, 0, sizeof(sections));
     mainType = file->type;
-    mainName = file->name;
+    mainName = file->name ? file->name : "(unnamed)";
     switch (mainType)
     {
-    case XkmSemanticsFile:
-        required = XkmSemanticsRequired;
-        legal = XkmSemanticsLegal;
-        break;
-    case XkmLayoutFile:        /* standard type  if setxkbmap -print */
-        required = XkmLayoutRequired;
-        legal = XkmKeymapLegal;
-        break;
     case XkmKeymapFile:
-        required = XkmKeymapRequired;
+        required = XkmKeyNamesIndex | XkmTypesIndex | XkmSymbolsIndex |
+                   XkmCompatMapIndex;
         legal = XkmKeymapLegal;
         break;
     default:
         ERROR("Cannot compile %s alone into an XKM file\n",
                XkbcConfigText(mainType));
-        return False;
+        return false;
     }
     have = 0;
-    ok = 1;
-    file = (XkbFile *) file->defs;
+
     /* Check for duplicate entries in the input file */
-    while ((file) && (ok))
+    for (file = (XkbFile *) file->defs; file; file = (XkbFile *) file->common.next)
     {
-        if (file->topName != mainName) {
-            free(file->topName);
-            file->topName = strdup(mainName);
-        }
         if ((have & (1 << file->type)) != 0)
         {
             ERROR("More than one %s section in a %s file\n",
                    XkbcConfigText(file->type), XkbcConfigText(mainType));
             ACTION("All sections after the first ignored\n");
-            ok = False;
+            continue;
         }
         else if ((1 << file->type) & (~legal))
         {
             ERROR("Cannot define %s in a %s file\n",
                    XkbcConfigText(file->type), XkbcConfigText(mainType));
-            ok = False;
+            continue;
         }
-        else
-            switch (file->type)
-            {
-            case XkmSemanticsFile:
-            case XkmLayoutFile:
-            case XkmKeymapFile:
-                WSGO("Illegal %s configuration in a %s file\n",
-                      XkbcConfigText(file->type), XkbcConfigText(mainType));
-                ACTION("Ignored\n");
-                ok = False;
-                break;
-            case XkmKeyNamesIndex:
-                sections[KEYCODES] = file;
-                break;
-            case XkmTypesIndex:
-                sections[TYPES] = file;
-                break;
-            case XkmSymbolsIndex:
-                sections[SYMBOLS] = file;
-                break;
-            case XkmCompatMapIndex:
-                sections[COMPAT] = file;
-                break;
-            case XkmGeometryIndex:
-            case XkmGeometryFile:
-                sections[GEOMETRY] = file;
-                break;
-            case XkmVirtualModsIndex:
-            case XkmIndicatorsIndex:
-                WSGO("Found an isolated %s section\n",
-                      XkbcConfigText(file->type));
-                break;
-            default:
-                WSGO("Unknown file type %d\n", file->type);
-                break;
-            }
-        if (ok)
-            have |= (1 << file->type);
-        file = (XkbFile *) file->common.next;
-    }
-    /* compile the sections we have in the file one-by-one, or fail. */
-    if (ok)
-    {
-        if (ok && (sections[KEYCODES] != NULL))
-            ok = CompileKeycodes(sections[KEYCODES], xkb, MergeOverride);
-        if (ok && (sections[GEOMETRY] != NULL))
-            ok = CompileGeometry(sections[GEOMETRY], xkb, MergeOverride);
-        if (ok && (sections[TYPES] != NULL))
-            ok = CompileKeyTypes(sections[TYPES], xkb, MergeOverride);
-        if (ok && (sections[COMPAT] != NULL))
-            ok = CompileCompatMap(sections[COMPAT], xkb, MergeOverride,
-                                  &unbound);
-        if (ok && (sections[SYMBOLS] != NULL))
-            ok = CompileSymbols(sections[SYMBOLS], xkb, MergeOverride);
+
+        switch (file->type)
+        {
+        case XkmKeyNamesIndex:
+            sections.keycodes = file;
+            break;
+        case XkmTypesIndex:
+            sections.types = file;
+            break;
+        case XkmSymbolsIndex:
+            sections.symbols = file;
+            break;
+        case XkmCompatMapIndex:
+            sections.compat = file;
+            break;
+        case XkmGeometryIndex:
+            continue;
+        default:
+            WSGO("Unknown file type %d\n", file->type);
+            ACTION("Ignored\n");
+            continue;
+        case XkmKeymapFile:
+            WSGO("Illegal %s configuration in a %s file\n",
+                  XkbcConfigText(file->type), XkbcConfigText(mainType));
+            ACTION("Ignored\n");
+            continue;
+        }
+
+        if (!file->topName || strcmp(file->topName, mainName) != 0) {
+            free(file->topName);
+            file->topName = strdup(mainName);
+        }
+
+        have |= (1 << file->type);
     }
-    if (!ok)
-        return False;
-    xkb->defined = have;
+
     if (required & (~have))
     {
         int i, bit;
@@ -167,15 +130,56 @@ CompileKeymap(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
         {
             if (missing & bit)
             {
-                ERROR("Missing %s section in a %s file\n",
-                       XkbcConfigText(i), XkbcConfigText(mainType));
+                ERROR("Required section %s missing from keymap\n", XkbcConfigText(i));
                 missing &= ~bit;
             }
         }
-        ACTION("Description of %s not compiled\n",
-                XkbcConfigText(mainType));
-        return False;
+        goto err;
+    }
+
+    /* compile the sections we have in the file one-by-one, or fail. */
+    if (sections.keycodes == NULL ||
+        !CompileKeycodes(sections.keycodes, keymap, MergeOverride))
+    {
+        ERROR("Failed to compile keycodes\n");
+        goto err;
+    }
+    if (sections.types == NULL ||
+        !CompileKeyTypes(sections.types, keymap, MergeOverride))
+    {
+        ERROR("Failed to compile key types\n");
+        goto err;
+    }
+    if (sections.compat == NULL ||
+        !CompileCompatMap(sections.compat, keymap, MergeOverride, &unbound))
+    {
+        ERROR("Failed to compile compat map\n");
+        goto err;
+    }
+    if (sections.symbols == NULL ||
+        !CompileSymbols(sections.symbols, keymap, MergeOverride))
+    {
+        ERROR("Failed to compile symbols\n");
+        goto err;
+    }
+
+    ok = BindIndicators(keymap, true, unbound, NULL);
+    if (!ok)
+        goto err;
+
+    ok = UpdateModifiersFromCompat(keymap);
+    if (!ok)
+        goto err;
+
+    return keymap;
+
+err:
+    ACTION("Failed to compile keymap\n");
+    xkb_map_unref(keymap);
+    while (unbound) {
+        next = (LEDInfo *) unbound->defs.next;
+        free(unbound);
+        unbound = next;
     }
-    ok = BindIndicators(xkb, True, unbound, NULL);
-    return ok;
+    return NULL;
 }