Free XkbFile's when no longer needed
[profile/ivi/libxkbcommon.git] / src / xkbcomp / keymap.c
1 /************************************************************
2  Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
3
4  Permission to use, copy, modify, and distribute this
5  software and its documentation for any purpose and without
6  fee is hereby granted, provided that the above copyright
7  notice appear in all copies and that both that copyright
8  notice and this permission notice appear in supporting
9  documentation, and that the name of Silicon Graphics not be
10  used in advertising or publicity pertaining to distribution
11  of the software without specific prior written permission.
12  Silicon Graphics makes no representation about the suitability
13  of this software for any purpose. It is provided "as is"
14  without any express or implied warranty.
15
16  SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
17  SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18  AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
19  GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
20  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
23  THE USE OR PERFORMANCE OF THIS SOFTWARE.
24
25  ********************************************************/
26
27 #include "xkbcomp.h"
28 #include "xkbmisc.h"
29 #include "expr.h"
30 #include "vmod.h"
31 #include "action.h"
32 #include "misc.h"
33 #include "indicators.h"
34
35 #define KEYCODES        0
36 #define GEOMETRY        1
37 #define TYPES           2
38 #define COMPAT          3
39 #define SYMBOLS         4
40 #define MAX_SECTIONS    5
41
42 /**
43  * Compile the given file and store the output in xkb.
44  * @param file A list of XkbFiles, each denoting one type (e.g.
45  * XkmKeyNamesIdx, etc.)
46  */
47 Bool
48 CompileKeymap(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
49 {
50     unsigned have;
51     Bool ok;
52     unsigned required, legal;
53     unsigned mainType;
54     char *mainName;
55     LEDInfo *unbound = NULL;
56     XkbFile *sections[MAX_SECTIONS];
57
58     memset(sections, 0, sizeof(sections));
59     mainType = file->type;
60     mainName = file->name;
61     switch (mainType)
62     {
63     case XkmSemanticsFile:
64         required = XkmSemanticsRequired;
65         legal = XkmSemanticsLegal;
66         break;
67     case XkmLayoutFile:        /* standard type  if setxkbmap -print */
68         required = XkmLayoutRequired;
69         legal = XkmKeymapLegal;
70         break;
71     case XkmKeymapFile:
72         required = XkmKeymapRequired;
73         legal = XkmKeymapLegal;
74         break;
75     default:
76         ERROR("Cannot compile %s alone into an XKM file\n",
77                XkbcConfigText(mainType));
78         return False;
79     }
80     have = 0;
81     ok = 1;
82     file = (XkbFile *) file->defs;
83     /* Check for duplicate entries in the input file */
84     while ((file) && (ok))
85     {
86         if (file->topName != mainName) {
87             free(file->topName);
88             file->topName = strdup(mainName);
89         }
90         if ((have & (1 << file->type)) != 0)
91         {
92             ERROR("More than one %s section in a %s file\n",
93                    XkbcConfigText(file->type), XkbcConfigText(mainType));
94             ACTION("All sections after the first ignored\n");
95             ok = False;
96         }
97         else if ((1 << file->type) & (~legal))
98         {
99             ERROR("Cannot define %s in a %s file\n",
100                    XkbcConfigText(file->type), XkbcConfigText(mainType));
101             ok = False;
102         }
103         else
104             switch (file->type)
105             {
106             case XkmSemanticsFile:
107             case XkmLayoutFile:
108             case XkmKeymapFile:
109                 WSGO("Illegal %s configuration in a %s file\n",
110                       XkbcConfigText(file->type), XkbcConfigText(mainType));
111                 ACTION("Ignored\n");
112                 ok = False;
113                 break;
114             case XkmKeyNamesIndex:
115                 sections[KEYCODES] = file;
116                 break;
117             case XkmTypesIndex:
118                 sections[TYPES] = file;
119                 break;
120             case XkmSymbolsIndex:
121                 sections[SYMBOLS] = file;
122                 break;
123             case XkmCompatMapIndex:
124                 sections[COMPAT] = file;
125                 break;
126             case XkmGeometryIndex:
127             case XkmGeometryFile:
128                 sections[GEOMETRY] = file;
129                 break;
130             case XkmVirtualModsIndex:
131             case XkmIndicatorsIndex:
132                 WSGO("Found an isolated %s section\n",
133                       XkbcConfigText(file->type));
134                 break;
135             default:
136                 WSGO("Unknown file type %d\n", file->type);
137                 break;
138             }
139         if (ok)
140             have |= (1 << file->type);
141         file = (XkbFile *) file->common.next;
142     }
143     /* compile the sections we have in the file one-by-one, or fail. */
144     if (ok)
145     {
146         if (ok && (sections[KEYCODES] != NULL))
147             ok = CompileKeycodes(sections[KEYCODES], xkb, MergeOverride);
148         if (ok && (sections[GEOMETRY] != NULL))
149             ok = CompileGeometry(sections[GEOMETRY], xkb, MergeOverride);
150         if (ok && (sections[TYPES] != NULL))
151             ok = CompileKeyTypes(sections[TYPES], xkb, MergeOverride);
152         if (ok && (sections[COMPAT] != NULL))
153             ok = CompileCompatMap(sections[COMPAT], xkb, MergeOverride,
154                                   &unbound);
155         if (ok && (sections[SYMBOLS] != NULL))
156             ok = CompileSymbols(sections[SYMBOLS], xkb, MergeOverride);
157     }
158     if (!ok)
159         return False;
160     xkb->defined = have;
161     if (required & (~have))
162     {
163         int i, bit;
164         unsigned missing;
165         missing = required & (~have);
166         for (i = 0, bit = 1; missing != 0; i++, bit <<= 1)
167         {
168             if (missing & bit)
169             {
170                 ERROR("Missing %s section in a %s file\n",
171                        XkbcConfigText(i), XkbcConfigText(mainType));
172                 missing &= ~bit;
173             }
174         }
175         ACTION("Description of %s not compiled\n",
176                 XkbcConfigText(mainType));
177         return False;
178     }
179     ok = BindIndicators(xkb, True, unbound, NULL);
180     return ok;
181 }