b207fdc07d6ab8a0cd1066e65bad345bc3c81151
[platform/upstream/libxkbcommon.git] / src / xkbcomp / keycodes.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 "xkballoc.h"
29 #include "xkbmisc.h"
30 #include "expr.h"
31 #include "keycodes.h"
32 #include "misc.h"
33 #include "alias.h"
34 #include "parseutils.h"
35
36 const char *
37 longText(unsigned long val)
38 {
39     char buf[4];
40
41     LongToKeyName(val, buf);
42     return XkbcKeyNameText(buf);
43 }
44
45 /***====================================================================***/
46
47 void
48 LongToKeyName(unsigned long val, char *name)
49 {
50     name[0] = ((val >> 24) & 0xff);
51     name[1] = ((val >> 16) & 0xff);
52     name[2] = ((val >> 8) & 0xff);
53     name[3] = (val & 0xff);
54 }
55
56 /***====================================================================***/
57
58 typedef struct _IndicatorNameInfo
59 {
60     CommonInfo defs;
61     int ndx;
62     uint32_t name;
63     Bool virtual;
64 } IndicatorNameInfo;
65
66 typedef struct _KeyNamesInfo
67 {
68     char *name;     /* e.g. evdev+aliases(qwerty) */
69     int errorCount;
70     unsigned fileID;
71     unsigned merge;
72     xkb_keycode_t computedMin; /* lowest keycode stored */
73     xkb_keycode_t computedMax; /* highest keycode stored */
74     xkb_keycode_t explicitMin;
75     xkb_keycode_t explicitMax;
76     xkb_keycode_t arraySize;
77     unsigned long *names;
78     unsigned *files;
79     unsigned char *has_alt_forms;
80     IndicatorNameInfo *leds;
81     AliasInfo *aliases;
82 } KeyNamesInfo;
83
84 static void HandleKeycodesFile(XkbFile * file,
85                                struct xkb_desc * xkb,
86                                unsigned merge,
87                                KeyNamesInfo * info);
88
89 static int
90 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
91 {
92     void *tmp;
93     int i;
94
95     tmp = _XkbTypedRealloc(info->names, newMax + 1, unsigned long);
96     if (!tmp) {
97         ERROR
98             ("Couldn't reallocate for larger maximum keycode (%d)\n",
99              newMax);
100         ACTION("Maximum key value not changed\n");
101         return 0;
102     }
103     info->names = tmp;
104     for (i = info->arraySize + 1; i <= newMax; i++)
105         info->names[i] = 0;
106
107     tmp = _XkbTypedRealloc(info->files, newMax + 1, unsigned);
108     if (!tmp) {
109         ERROR
110             ("Couldn't reallocate for larger maximum keycode (%d)\n",
111              newMax);
112         ACTION("Maximum key value not changed\n");
113         return 0;
114     }
115     info->files = tmp;
116     for (i = info->arraySize + 1; i <= newMax; i++)
117         info->files[i] = 0;
118
119     tmp = _XkbTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
120     if (!tmp) {
121         ERROR
122             ("Couldn't reallocate for larger maximum keycode (%d)\n",
123              newMax);
124         ACTION("Maximum key value not changed\n");
125         return 0;
126     }
127     info->has_alt_forms = tmp;
128     for (i = info->arraySize + 1; i <= newMax; i++)
129         info->has_alt_forms[i] = 0;
130
131     info->arraySize = newMax;
132
133     return 1;
134 }
135
136 static void
137 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
138 {
139     ii->defs.defined = 0;
140     ii->defs.merge = info->merge;
141     ii->defs.fileID = info->fileID;
142     ii->defs.next = NULL;
143     ii->ndx = 0;
144     ii->name = None;
145     ii->virtual = False;
146 }
147
148 static void
149 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
150 {
151     if (ii == info->leds)
152     {
153         ClearCommonInfo(&ii->defs);
154         info->leds = NULL;
155     }
156 }
157
158 static IndicatorNameInfo *
159 NextIndicatorName(KeyNamesInfo * info)
160 {
161     IndicatorNameInfo *ii;
162
163     ii = uTypedAlloc(IndicatorNameInfo);
164     if (ii)
165     {
166         InitIndicatorNameInfo(ii, info);
167         info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
168                                                          (CommonInfo *) ii);
169     }
170     return ii;
171 }
172
173 static IndicatorNameInfo *
174 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
175 {
176     IndicatorNameInfo *old;
177
178     for (old = info->leds; old != NULL;
179          old = (IndicatorNameInfo *) old->defs.next)
180     {
181         if (old->ndx == ndx)
182             return old;
183     }
184     return NULL;
185 }
186
187 static IndicatorNameInfo *
188 FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
189 {
190     IndicatorNameInfo *old;
191
192     for (old = info->leds; old != NULL;
193          old = (IndicatorNameInfo *) old->defs.next)
194     {
195         if (old->name == name)
196             return old;
197     }
198     return NULL;
199 }
200
201 static Bool
202 AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
203 {
204     IndicatorNameInfo *old;
205     Bool replace;
206
207     replace = (new->defs.merge == MergeReplace) ||
208         (new->defs.merge == MergeOverride);
209     old = FindIndicatorByName(info, new->name);
210     if (old)
211     {
212         if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
213             || (warningLevel > 9))
214         {
215             WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
216             if (old->ndx == new->ndx)
217             {
218                 if (old->virtual != new->virtual)
219                 {
220                     if (replace)
221                         old->virtual = new->virtual;
222                     ACTION("Using %s instead of %s\n",
223                            (old->virtual ? "virtual" : "real"),
224                            (old->virtual ? "real" : "virtual"));
225                 }
226                 else
227                 {
228                     ACTION("Identical definitions ignored\n");
229                 }
230                 return True;
231             }
232             else
233             {
234                 if (replace)
235                     ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
236                 else
237                     ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
238             }
239             if (replace)
240             {
241                 if (info->leds == old)
242                     info->leds = (IndicatorNameInfo *) old->defs.next;
243                 else
244                 {
245                     IndicatorNameInfo *tmp;
246                     tmp = info->leds;
247                     for (; tmp != NULL;
248                          tmp = (IndicatorNameInfo *) tmp->defs.next)
249                     {
250                         if (tmp->defs.next == (CommonInfo *) old)
251                         {
252                             tmp->defs.next = old->defs.next;
253                             break;
254                         }
255                     }
256                 }
257                 free(old);
258             }
259         }
260     }
261     old = FindIndicatorByIndex(info, new->ndx);
262     if (old)
263     {
264         if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
265             || (warningLevel > 9))
266         {
267             WARN("Multiple names for indicator %d\n", new->ndx);
268             if ((old->name == new->name) && (old->virtual == new->virtual))
269                 ACTION("Identical definitions ignored\n");
270             else
271             {
272                 const char *oldType, *newType;
273                 uint32_t using, ignoring;
274                 if (old->virtual)
275                     oldType = "virtual indicator";
276                 else
277                     oldType = "real indicator";
278                 if (new->virtual)
279                     newType = "virtual indicator";
280                 else
281                     newType = "real indicator";
282                 if (replace)
283                 {
284                     using = new->name;
285                     ignoring = old->name;
286                 }
287                 else
288                 {
289                     using = old->name;
290                     ignoring = new->name;
291                 }
292                 ACTION("Using %s %s, ignoring %s %s\n",
293                         oldType, XkbcAtomText(using),
294                         newType, XkbcAtomText(ignoring));
295             }
296         }
297         if (replace)
298         {
299             old->name = new->name;
300             old->virtual = new->virtual;
301         }
302         return True;
303     }
304     old = new;
305     new = NextIndicatorName(info);
306     if (!new)
307     {
308         WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
309         ACTION("Ignored\n");
310         return False;
311     }
312     new->name = old->name;
313     new->ndx = old->ndx;
314     new->virtual = old->virtual;
315     return True;
316 }
317
318 static void
319 ClearKeyNamesInfo(KeyNamesInfo * info)
320 {
321     free(info->name);
322     info->name = NULL;
323     info->computedMax = info->explicitMax = info->explicitMin = 0;
324     info->computedMin = XKB_KEYCODE_MAX;
325     info->arraySize = 0;
326     free(info->names);
327     info->names = NULL;
328     free(info->files);
329     info->files = NULL;
330     free(info->has_alt_forms);
331     info->has_alt_forms = NULL;
332     if (info->leds)
333         ClearIndicatorNameInfo(info->leds, info);
334     if (info->aliases)
335         ClearAliases(&info->aliases);
336 }
337
338 static void
339 InitKeyNamesInfo(KeyNamesInfo * info)
340 {
341     info->name = NULL;
342     info->leds = NULL;
343     info->aliases = NULL;
344     info->names = NULL;
345     info->files = NULL;
346     info->has_alt_forms = NULL;
347     ClearKeyNamesInfo(info);
348     info->errorCount = 0;
349 }
350
351 static int
352 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
353 {
354     int i;
355
356     for (i = info->computedMin; i <= info->computedMax; i++)
357     {
358         if (info->names[i] == name)
359             return i;
360     }
361     return 0;
362 }
363
364 /**
365  * Store the name of the key as a long in the info struct under the given
366  * keycode. If the same keys is referred to twice, print a warning.
367  * Note that the key's name is stored as a long, the keycode is the index.
368  */
369 static Bool
370 AddKeyName(KeyNamesInfo * info,
371            xkb_keycode_t kc,
372            char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
373 {
374     int old;
375     unsigned long lval;
376
377     if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
378         ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
379         ACTION("Ignoring key %d\n", kc);
380         return False;
381     }
382     if (kc < info->computedMin)
383         info->computedMin = kc;
384     if (kc > info->computedMax)
385         info->computedMax = kc;
386     lval = KeyNameToLong(name);
387
388     if (reportCollisions)
389     {
390         reportCollisions = ((warningLevel > 7) ||
391                             ((warningLevel > 0)
392                              && (fileID == info->files[kc])));
393     }
394
395     if (info->names[kc] != 0)
396     {
397         char buf[6];
398
399         LongToKeyName(info->names[kc], buf);
400         buf[4] = '\0';
401         if (info->names[kc] == lval)
402         {
403             if (info->has_alt_forms[kc] || (merge == MergeAltForm))
404             {
405                 info->has_alt_forms[kc] = True;
406             }
407             else if (reportCollisions)
408             {
409                 WARN("Multiple identical key name definitions\n");
410                 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
411                         buf, kc);
412             }
413             return True;
414         }
415         if (merge == MergeAugment)
416         {
417             if (reportCollisions)
418             {
419                 WARN("Multiple names for keycode %d\n", kc);
420                 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
421             }
422             return True;
423         }
424         else
425         {
426             if (reportCollisions)
427             {
428                 WARN("Multiple names for keycode %d\n", kc);
429                 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
430             }
431             info->names[kc] = 0;
432             info->files[kc] = 0;
433         }
434     }
435     old = FindKeyByLong(info, lval);
436     if ((old != 0) && (old != kc))
437     {
438         if (merge == MergeOverride)
439         {
440             info->names[old] = 0;
441             info->files[old] = 0;
442             info->has_alt_forms[old] = True;
443             if (reportCollisions)
444             {
445                 WARN("Key name <%s> assigned to multiple keys\n", name);
446                 ACTION("Using %d, ignoring %d\n", kc, old);
447             }
448         }
449         else if (merge != MergeAltForm)
450         {
451             if ((reportCollisions) && (warningLevel > 3))
452             {
453                 WARN("Key name <%s> assigned to multiple keys\n", name);
454                 ACTION("Using %d, ignoring %d\n", old, kc);
455                 ACTION
456                     ("Use 'alternate' keyword to assign the same name to multiple keys\n");
457             }
458             return True;
459         }
460         else
461         {
462             info->has_alt_forms[old] = True;
463         }
464     }
465     info->names[kc] = lval;
466     info->files[kc] = fileID;
467     info->has_alt_forms[kc] = (merge == MergeAltForm);
468     return True;
469 }
470
471 /***====================================================================***/
472
473 static void
474 MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
475                       unsigned merge)
476 {
477     int i;
478     char buf[5];
479
480     if (from->errorCount > 0)
481     {
482         into->errorCount += from->errorCount;
483         return;
484     }
485     if (into->name == NULL)
486     {
487         into->name = from->name;
488         from->name = NULL;
489     }
490     if (from->computedMax > into->arraySize &&
491         !ResizeKeyNameArrays(into, from->computedMax)) {
492         ERROR("Couldn't resize KeyNames arrays for key %d\n",
493               from->computedMax);
494         ACTION("Ignoring include file %s\n", from->name);
495         into->errorCount += 10;
496         return;
497     }
498     for (i = from->computedMin; i <= from->computedMax; i++)
499     {
500         unsigned thisMerge;
501         if (from->names[i] == 0)
502             continue;
503         LongToKeyName(from->names[i], buf);
504         buf[4] = '\0';
505         if (from->has_alt_forms[i])
506             thisMerge = MergeAltForm;
507         else
508             thisMerge = merge;
509         if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
510             into->errorCount++;
511     }
512     if (from->leds)
513     {
514         IndicatorNameInfo *led, *next;
515         for (led = from->leds; led != NULL; led = next)
516         {
517             if (merge != MergeDefault)
518                 led->defs.merge = merge;
519             if (!AddIndicatorName(into, led))
520                 into->errorCount++;
521             next = (IndicatorNameInfo *) led->defs.next;
522         }
523     }
524     if (!MergeAliases(&into->aliases, &from->aliases, merge))
525         into->errorCount++;
526     if (from->explicitMin != 0)
527     {
528         if ((into->explicitMin == 0)
529             || (into->explicitMin > from->explicitMin))
530             into->explicitMin = from->explicitMin;
531     }
532     if (from->explicitMax > 0)
533     {
534         if ((into->explicitMax == 0)
535             || (into->explicitMax < from->explicitMax))
536             into->explicitMax = from->explicitMax;
537     }
538 }
539
540 /**
541  * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
542  *
543  * @param stmt The include statement from the keymap file.
544  * @param xkb Unused for all but the xkb->flags.
545  * @param info Struct to store the key info in.
546  */
547 static Bool
548 HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo * info)
549 {
550     unsigned newMerge;
551     XkbFile *rtrn;
552     KeyNamesInfo included = {NULL};
553     Bool haveSelf;
554
555     haveSelf = False;
556     if ((stmt->file == NULL) && (stmt->map == NULL))
557     {
558         haveSelf = True;
559         included = *info;
560         memset(info, 0, sizeof(KeyNamesInfo));
561     }
562     else if (stmt->file && strcmp(stmt->file, "computed") == 0)
563     {
564         xkb->flags |= AutoKeyNames;
565         info->explicitMin = 0;
566         info->explicitMax = XKB_KEYCODE_MAX;
567         return (info->errorCount == 0);
568     } /* parse file, store returned info in the xkb struct */
569     else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
570     {
571         InitKeyNamesInfo(&included);
572         HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
573         if (stmt->stmt != NULL)
574         {
575             free(included.name);
576             included.name = stmt->stmt;
577             stmt->stmt = NULL;
578         }
579         FreeXKBFile(rtrn);
580     }
581     else
582     {
583         info->errorCount += 10; /* XXX: why 10?? */
584         return False;
585     }
586     /* Do we have more than one include statement? */
587     if ((stmt->next != NULL) && (included.errorCount < 1))
588     {
589         IncludeStmt *next;
590         unsigned op;
591         KeyNamesInfo next_incl;
592
593         for (next = stmt->next; next != NULL; next = next->next)
594         {
595             if ((next->file == NULL) && (next->map == NULL))
596             {
597                 haveSelf = True;
598                 MergeIncludedKeycodes(&included, info, next->merge);
599                 ClearKeyNamesInfo(info);
600             }
601             else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
602             {
603                 InitKeyNamesInfo(&next_incl);
604                 HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
605                 MergeIncludedKeycodes(&included, &next_incl, op);
606                 ClearKeyNamesInfo(&next_incl);
607                 FreeXKBFile(rtrn);
608             }
609             else
610             {
611                 info->errorCount += 10; /* XXX: Why 10?? */
612                 ClearKeyNamesInfo(&included);
613                 return False;
614             }
615         }
616     }
617     if (haveSelf)
618         *info = included;
619     else
620     {
621         MergeIncludedKeycodes(info, &included, newMerge);
622         ClearKeyNamesInfo(&included);
623     }
624     return (info->errorCount == 0);
625 }
626
627 /**
628  * Parse the given statement and store the output in the info struct.
629  * e.g. <ESC> = 9
630  */
631 static int
632 HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
633 {
634     if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
635         (info->explicitMax != 0 && stmt->value > info->explicitMax))
636     {
637         ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
638         ACTION("Must be in the range %d-%d inclusive\n",
639                 info->explicitMin,
640                 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
641         return 0;
642     }
643     if (stmt->merge != MergeDefault)
644     {
645         if (stmt->merge == MergeReplace)
646             merge = MergeOverride;
647         else
648             merge = stmt->merge;
649     }
650     return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
651                       True);
652 }
653
654 #define MIN_KEYCODE_DEF         0
655 #define MAX_KEYCODE_DEF         1
656
657 /**
658  * Handle the minimum/maximum statement of the xkb file.
659  * Sets explicitMin/Max of the info struct.
660  *
661  * @return 1 on success, 0 otherwise.
662  */
663 static int
664 HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
665 {
666     ExprResult tmp, field;
667     ExprDef *arrayNdx;
668     int which;
669
670     if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
671         return 0;               /* internal error, already reported */
672
673     if (tmp.str != NULL)
674     {
675         ERROR("Unknown element %s encountered\n", tmp.str);
676         ACTION("Default for field %s ignored\n", field.str);
677         goto err_out;
678     }
679     if (uStrCaseCmp(field.str, "minimum") == 0)
680         which = MIN_KEYCODE_DEF;
681     else if (uStrCaseCmp(field.str, "maximum") == 0)
682         which = MAX_KEYCODE_DEF;
683     else
684     {
685         ERROR("Unknown field encountered\n");
686         ACTION("Assigment to field %s ignored\n", field.str);
687         goto err_out;
688     }
689     if (arrayNdx != NULL)
690     {
691         ERROR("The %s setting is not an array\n", field.str);
692         ACTION("Illegal array reference ignored\n");
693         goto err_out;
694     }
695
696     if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
697     {
698         ACTION("Assignment to field %s ignored\n", field.str);
699         goto err_out;
700     }
701     if (tmp.uval > XKB_KEYCODE_MAX)
702     {
703         ERROR
704             ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
705              tmp.uval, 0, XKB_KEYCODE_MAX);
706         ACTION("Value of \"%s\" not changed\n", field.str);
707         goto err_out;
708     }
709     if (which == MIN_KEYCODE_DEF)
710     {
711         if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
712         {
713             ERROR
714                 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
715                  tmp.uval, info->explicitMax);
716             ACTION("Minimum key code value not changed\n");
717             goto err_out;
718         }
719         if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
720         {
721             ERROR
722                 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
723                  tmp.uval, info->computedMin);
724             ACTION("Minimum key code value not changed\n");
725             goto err_out;
726         }
727         info->explicitMin = tmp.uval;
728     }
729     if (which == MAX_KEYCODE_DEF)
730     {
731         if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
732         {
733             ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
734                    tmp.uval, info->explicitMin);
735             ACTION("Maximum code value not changed\n");
736             goto err_out;
737         }
738         if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
739         {
740             ERROR
741                 ("Maximum code (%d) must be >= highest defined key (%d)\n",
742                  tmp.uval, info->computedMax);
743             ACTION("Maximum code value not changed\n");
744             goto err_out;
745         }
746         info->explicitMax = tmp.uval;
747     }
748
749     free(field.str);
750     return 1;
751
752 err_out:
753     free(field.str);
754     return 0;
755 }
756
757 static int
758 HandleIndicatorNameDef(IndicatorNameDef * def,
759                        unsigned merge, KeyNamesInfo * info)
760 {
761     IndicatorNameInfo ii;
762     ExprResult tmp;
763
764     if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
765     {
766         info->errorCount++;
767         ERROR("Name specified for illegal indicator index %d\n", def->ndx);
768         ACTION("Ignored\n");
769         return False;
770     }
771     InitIndicatorNameInfo(&ii, info);
772     ii.ndx = def->ndx;
773     if (!ExprResolveString(def->name, &tmp))
774     {
775         char buf[20];
776         snprintf(buf, sizeof(buf), "%d", def->ndx);
777         info->errorCount++;
778         return ReportBadType("indicator", "name", buf, "string");
779     }
780     ii.name = xkb_intern_atom(tmp.str);
781     free(tmp.str);
782     ii.virtual = def->virtual;
783     if (!AddIndicatorName(info, &ii))
784         return False;
785     return True;
786 }
787
788 /**
789  * Handle the xkb_keycodes section of a xkb file.
790  * All information about parsed keys is stored in the info struct.
791  *
792  * Such a section may have include statements, in which case this function is
793  * semi-recursive (it calls HandleIncludeKeycodes, which may call
794  * HandleKeycodesFile again).
795  *
796  * @param file The input file (parsed xkb_keycodes section)
797  * @param xkb Necessary to pass down, may have flags changed.
798  * @param merge Merge strategy (MergeOverride, etc.)
799  * @param info Struct to contain the fully parsed key information.
800  */
801 static void
802 HandleKeycodesFile(XkbFile * file,
803                    struct xkb_desc * xkb, unsigned merge, KeyNamesInfo * info)
804 {
805     ParseCommon *stmt;
806
807     free(info->name);
808     info->name = _XkbDupString(file->name);
809     stmt = file->defs;
810     while (stmt)
811     {
812         switch (stmt->stmtType)
813         {
814         case StmtInclude:    /* e.g. include "evdev+aliases(qwerty)" */
815             if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info))
816                 info->errorCount++;
817             break;
818         case StmtKeycodeDef: /* e.g. <ESC> = 9; */
819             if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
820                 info->errorCount++;
821             break;
822         case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
823             if (!HandleAliasDef((KeyAliasDef *) stmt,
824                                 merge, info->fileID, &info->aliases))
825                 info->errorCount++;
826             break;
827         case StmtVarDef: /* e.g. minimum, maximum */
828             if (!HandleKeyNameVar((VarDef *) stmt, info))
829                 info->errorCount++;
830             break;
831         case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
832             if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt,
833                                         merge, info))
834             {
835                 info->errorCount++;
836             }
837             break;
838         case StmtInterpDef:
839         case StmtVModDef:
840             ERROR("Keycode files may define key and indicator names only\n");
841             ACTION("Ignoring definition of %s\n",
842                     ((stmt->stmtType ==
843                       StmtInterpDef) ? "a symbol interpretation" :
844                      "virtual modifiers"));
845             info->errorCount++;
846             break;
847         default:
848             WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
849                   stmt->stmtType);
850             break;
851         }
852         stmt = stmt->next;
853         if (info->errorCount > 10)
854         {
855 #ifdef NOISY
856             ERROR("Too many errors\n");
857 #endif
858             ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
859             break;
860         }
861     }
862 }
863
864 /**
865  * Compile the xkb_keycodes section, parse it's output, return the results.
866  *
867  * @param file The parsed XKB file (may have include statements requiring
868  * further parsing)
869  * @param result The effective keycodes, as gathered from the file.
870  * @param merge Merge strategy.
871  *
872  * @return True on success, False otherwise.
873  */
874 Bool
875 CompileKeycodes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
876 {
877     KeyNamesInfo info; /* contains all the info after parsing */
878
879     InitKeyNamesInfo(&info);
880     HandleKeycodesFile(file, xkb, merge, &info);
881
882     /* all the keys are now stored in info */
883
884     if (info.errorCount == 0)
885     {
886         if (info.explicitMin > 0) /* if "minimum" statement was present */
887             xkb->min_key_code = info.explicitMin;
888         else
889             xkb->min_key_code = info.computedMin;
890         if (info.explicitMax > 0) /* if "maximum" statement was present */
891             xkb->max_key_code = info.explicitMax;
892         else
893             xkb->max_key_code = info.computedMax;
894         if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
895                 == Success)
896         {
897             int i;
898             for (i = info.computedMin; i <= info.computedMax; i++)
899                 LongToKeyName(info.names[i], xkb->names->keys[i].name);
900         }
901         else
902         {
903             WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
904             return False;
905         }
906         if (info.leds)
907         {
908             IndicatorNameInfo *ii;
909             if (XkbcAllocIndicatorMaps(xkb) != Success)
910             {
911                 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
912                 ACTION("Physical indicators not set\n");
913             }
914             for (ii = info.leds; ii != NULL;
915                  ii = (IndicatorNameInfo *) ii->defs.next)
916             {
917                 free((char *) xkb->names->indicators[ii->ndx - 1]);
918                 xkb->names->indicators[ii->ndx - 1] = XkbcAtomGetString(ii->name);
919                 if (xkb->indicators != NULL)
920                 {
921                     unsigned bit;
922                     bit = 1 << (ii->ndx - 1);
923                     if (ii->virtual)
924                         xkb->indicators->phys_indicators &= ~bit;
925                     else
926                         xkb->indicators->phys_indicators |= bit;
927                 }
928             }
929         }
930         if (info.aliases)
931             ApplyAliases(xkb, &info.aliases);
932         ClearKeyNamesInfo(&info);
933         return True;
934     }
935     ClearKeyNamesInfo(&info);
936     return False;
937 }