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