1 /************************************************************
2 Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
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.
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.
25 ********************************************************/
29 #include "parseutils.h"
33 longText(unsigned long val)
37 LongToKeyName(val, buf);
38 return XkbcKeyNameText(buf);
41 /***====================================================================***/
44 LongToKeyName(unsigned long val, char *name)
46 name[0] = ((val >> 24) & 0xff);
47 name[1] = ((val >> 16) & 0xff);
48 name[2] = ((val >> 8) & 0xff);
49 name[3] = (val & 0xff);
52 /***====================================================================***/
54 typedef struct _IndicatorNameInfo
62 typedef struct _KeyNamesInfo
64 char *name; /* e.g. evdev+aliases(qwerty) */
68 xkb_keycode_t computedMin; /* lowest keycode stored */
69 xkb_keycode_t computedMax; /* highest keycode stored */
70 xkb_keycode_t explicitMin;
71 xkb_keycode_t explicitMax;
72 xkb_keycode_t arraySize;
75 unsigned char *has_alt_forms;
76 IndicatorNameInfo *leds;
80 static void HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
81 unsigned merge, KeyNamesInfo *info);
84 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
89 tmp = uTypedRealloc(info->names, newMax + 1, unsigned long);
92 ("Couldn't reallocate for larger maximum keycode (%d)\n",
94 ACTION("Maximum key value not changed\n");
98 for (i = info->arraySize + 1; i <= newMax; i++)
101 tmp = uTypedRealloc(info->files, newMax + 1, unsigned);
104 ("Couldn't reallocate for larger maximum keycode (%d)\n",
106 ACTION("Maximum key value not changed\n");
110 for (i = info->arraySize + 1; i <= newMax; i++)
113 tmp = uTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
116 ("Couldn't reallocate for larger maximum keycode (%d)\n",
118 ACTION("Maximum key value not changed\n");
121 info->has_alt_forms = tmp;
122 for (i = info->arraySize + 1; i <= newMax; i++)
123 info->has_alt_forms[i] = 0;
125 info->arraySize = newMax;
131 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
133 ii->defs.defined = 0;
134 ii->defs.merge = info->merge;
135 ii->defs.fileID = info->fileID;
136 ii->defs.next = NULL;
138 ii->name = XKB_ATOM_NONE;
143 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
145 if (ii == info->leds)
147 ClearCommonInfo(&ii->defs);
152 static IndicatorNameInfo *
153 NextIndicatorName(KeyNamesInfo * info)
155 IndicatorNameInfo *ii;
157 ii = uTypedAlloc(IndicatorNameInfo);
160 InitIndicatorNameInfo(ii, info);
161 info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
167 static IndicatorNameInfo *
168 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
170 IndicatorNameInfo *old;
172 for (old = info->leds; old != NULL;
173 old = (IndicatorNameInfo *) old->defs.next)
181 static IndicatorNameInfo *
182 FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
184 IndicatorNameInfo *old;
186 for (old = info->leds; old != NULL;
187 old = (IndicatorNameInfo *) old->defs.next)
189 if (old->name == name)
196 AddIndicatorName(KeyNamesInfo *info, struct xkb_keymap *keymap,
197 IndicatorNameInfo *new)
199 IndicatorNameInfo *old;
202 replace = (new->defs.merge == MergeReplace) ||
203 (new->defs.merge == MergeOverride);
204 old = FindIndicatorByName(info, new->name);
207 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
208 || (warningLevel > 9))
210 WARN("Multiple indicators named %s\n",
211 xkb_atom_text(keymap->context, new->name));
212 if (old->ndx == new->ndx)
214 if (old->virtual != new->virtual)
217 old->virtual = new->virtual;
218 ACTION("Using %s instead of %s\n",
219 (old->virtual ? "virtual" : "real"),
220 (old->virtual ? "real" : "virtual"));
224 ACTION("Identical definitions ignored\n");
231 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
233 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
237 if (info->leds == old)
238 info->leds = (IndicatorNameInfo *) old->defs.next;
241 IndicatorNameInfo *tmp;
244 tmp = (IndicatorNameInfo *) tmp->defs.next)
246 if (tmp->defs.next == (CommonInfo *) old)
248 tmp->defs.next = old->defs.next;
257 old = FindIndicatorByIndex(info, new->ndx);
260 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
261 || (warningLevel > 9))
263 WARN("Multiple names for indicator %d\n", new->ndx);
264 if ((old->name == new->name) && (old->virtual == new->virtual))
265 ACTION("Identical definitions ignored\n");
268 const char *oldType, *newType;
269 xkb_atom_t using, ignoring;
271 oldType = "virtual indicator";
273 oldType = "real indicator";
275 newType = "virtual indicator";
277 newType = "real indicator";
281 ignoring = old->name;
286 ignoring = new->name;
288 ACTION("Using %s %s, ignoring %s %s\n",
289 oldType, xkb_atom_text(keymap->context, using),
290 newType, xkb_atom_text(keymap->context, ignoring));
295 old->name = new->name;
296 old->virtual = new->virtual;
301 new = NextIndicatorName(info);
304 WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
308 new->name = old->name;
310 new->virtual = old->virtual;
315 ClearKeyNamesInfo(KeyNamesInfo * info)
319 info->computedMax = info->explicitMax = info->explicitMin = 0;
320 info->computedMin = XKB_KEYCODE_MAX;
326 free(info->has_alt_forms);
327 info->has_alt_forms = NULL;
329 ClearIndicatorNameInfo(info->leds, info);
331 ClearAliases(&info->aliases);
335 InitKeyNamesInfo(KeyNamesInfo * info)
339 info->aliases = NULL;
342 info->has_alt_forms = NULL;
343 ClearKeyNamesInfo(info);
344 info->errorCount = 0;
348 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
352 for (i = info->computedMin; i <= info->computedMax; i++)
354 if (info->names[i] == name)
361 * Store the name of the key as a long in the info struct under the given
362 * keycode. If the same keys is referred to twice, print a warning.
363 * Note that the key's name is stored as a long, the keycode is the index.
366 AddKeyName(KeyNamesInfo * info,
368 char *name, unsigned merge, unsigned fileID, bool reportCollisions)
373 if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
374 ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
375 ACTION("Ignoring key %d\n", kc);
378 if (kc < info->computedMin)
379 info->computedMin = kc;
380 if (kc > info->computedMax)
381 info->computedMax = kc;
382 lval = KeyNameToLong(name);
384 if (reportCollisions)
386 reportCollisions = ((warningLevel > 7) ||
388 && (fileID == info->files[kc])));
391 if (info->names[kc] != 0)
395 LongToKeyName(info->names[kc], buf);
397 if (info->names[kc] == lval)
399 if (info->has_alt_forms[kc] || (merge == MergeAltForm))
401 info->has_alt_forms[kc] = true;
403 else if (reportCollisions)
405 WARN("Multiple identical key name definitions\n");
406 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
411 if (merge == MergeAugment)
413 if (reportCollisions)
415 WARN("Multiple names for keycode %d\n", kc);
416 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
422 if (reportCollisions)
424 WARN("Multiple names for keycode %d\n", kc);
425 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
431 old = FindKeyByLong(info, lval);
432 if ((old != 0) && (old != kc))
434 if (merge == MergeOverride)
436 info->names[old] = 0;
437 info->files[old] = 0;
438 info->has_alt_forms[old] = true;
439 if (reportCollisions)
441 WARN("Key name <%s> assigned to multiple keys\n", name);
442 ACTION("Using %d, ignoring %d\n", kc, old);
445 else if (merge != MergeAltForm)
447 if ((reportCollisions) && (warningLevel > 3))
449 WARN("Key name <%s> assigned to multiple keys\n", name);
450 ACTION("Using %d, ignoring %d\n", old, kc);
452 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
458 info->has_alt_forms[old] = true;
461 info->names[kc] = lval;
462 info->files[kc] = fileID;
463 info->has_alt_forms[kc] = (merge == MergeAltForm);
467 /***====================================================================***/
470 MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
471 KeyNamesInfo *from, unsigned merge)
476 if (from->errorCount > 0)
478 into->errorCount += from->errorCount;
481 if (into->name == NULL)
483 into->name = from->name;
486 if (from->computedMax > into->arraySize &&
487 !ResizeKeyNameArrays(into, from->computedMax)) {
488 ERROR("Couldn't resize KeyNames arrays for key %d\n",
490 ACTION("Ignoring include file %s\n", from->name);
491 into->errorCount += 10;
494 for (i = from->computedMin; i <= from->computedMax; i++)
497 if (from->names[i] == 0)
499 LongToKeyName(from->names[i], buf);
501 if (from->has_alt_forms[i])
502 thisMerge = MergeAltForm;
505 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, false))
510 IndicatorNameInfo *led, *next;
511 for (led = from->leds; led != NULL; led = next)
513 if (merge != MergeDefault)
514 led->defs.merge = merge;
515 if (!AddIndicatorName(into, keymap, led))
517 next = (IndicatorNameInfo *) led->defs.next;
520 if (!MergeAliases(&into->aliases, &from->aliases, merge))
522 if (from->explicitMin != 0)
524 if ((into->explicitMin == 0)
525 || (into->explicitMin > from->explicitMin))
526 into->explicitMin = from->explicitMin;
528 if (from->explicitMax > 0)
530 if ((into->explicitMax == 0)
531 || (into->explicitMax < from->explicitMax))
532 into->explicitMax = from->explicitMax;
537 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
539 * @param stmt The include statement from the keymap file.
540 * @param keymap Unused for all but the keymap->flags.
541 * @param info Struct to store the key info in.
544 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
549 KeyNamesInfo included;
552 memset(&included, 0, sizeof(included));
555 if ((stmt->file == NULL) && (stmt->map == NULL))
559 memset(info, 0, sizeof(KeyNamesInfo));
561 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
563 keymap->flags |= AutoKeyNames;
564 info->explicitMin = 0;
565 info->explicitMax = XKB_KEYCODE_MAX;
566 return (info->errorCount == 0);
567 } /* parse file, store returned info in the xkb struct */
568 else if (ProcessIncludeFile(keymap->context, stmt, XkmKeyNamesIndex,
571 InitKeyNamesInfo(&included);
572 HandleKeycodesFile(rtrn, keymap, MergeOverride, &included);
573 if (stmt->stmt != NULL)
576 included.name = stmt->stmt;
583 info->errorCount += 10; /* XXX: why 10?? */
586 /* Do we have more than one include statement? */
587 if ((stmt->next != NULL) && (included.errorCount < 1))
591 KeyNamesInfo next_incl;
593 for (next = stmt->next; next != NULL; next = next->next)
595 if ((next->file == NULL) && (next->map == NULL))
598 MergeIncludedKeycodes(&included, keymap, info, next->merge);
599 ClearKeyNamesInfo(info);
601 else if (ProcessIncludeFile(keymap->context, next,
602 XkmKeyNamesIndex, &rtrn, &op))
604 InitKeyNamesInfo(&next_incl);
605 HandleKeycodesFile(rtrn, keymap, MergeOverride, &next_incl);
606 MergeIncludedKeycodes(&included, keymap, &next_incl, op);
607 ClearKeyNamesInfo(&next_incl);
612 info->errorCount += 10; /* XXX: Why 10?? */
613 ClearKeyNamesInfo(&included);
622 MergeIncludedKeycodes(info, keymap, &included, newMerge);
623 ClearKeyNamesInfo(&included);
625 return (info->errorCount == 0);
629 * Parse the given statement and store the output in the info struct.
633 HandleKeycodeDef(KeycodeDef *stmt, unsigned merge, KeyNamesInfo *info)
635 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
636 (info->explicitMax != 0 && stmt->value > info->explicitMax))
638 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
639 ACTION("Must be in the range %d-%d inclusive\n",
641 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
644 if (stmt->merge != MergeDefault)
646 if (stmt->merge == MergeReplace)
647 merge = MergeOverride;
651 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
655 #define MIN_KEYCODE_DEF 0
656 #define MAX_KEYCODE_DEF 1
659 * Handle the minimum/maximum statement of the xkb file.
660 * Sets explicitMin/Max of the info struct.
662 * @return 1 on success, 0 otherwise.
665 HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
667 ExprResult tmp, field;
671 if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
672 return 0; /* internal error, already reported */
676 ERROR("Unknown element %s encountered\n", tmp.str);
677 ACTION("Default for field %s ignored\n", field.str);
680 if (strcasecmp(field.str, "minimum") == 0)
681 which = MIN_KEYCODE_DEF;
682 else if (strcasecmp(field.str, "maximum") == 0)
683 which = MAX_KEYCODE_DEF;
686 ERROR("Unknown field encountered\n");
687 ACTION("Assigment to field %s ignored\n", field.str);
690 if (arrayNdx != NULL)
692 ERROR("The %s setting is not an array\n", field.str);
693 ACTION("Illegal array reference ignored\n");
697 if (ExprResolveKeyCode(keymap->context, stmt->value, &tmp) == 0)
699 ACTION("Assignment to field %s ignored\n", field.str);
702 if (tmp.uval > XKB_KEYCODE_MAX)
705 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
706 tmp.uval, 0, XKB_KEYCODE_MAX);
707 ACTION("Value of \"%s\" not changed\n", field.str);
710 if (which == MIN_KEYCODE_DEF)
712 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
715 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
716 tmp.uval, info->explicitMax);
717 ACTION("Minimum key code value not changed\n");
720 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
723 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
724 tmp.uval, info->computedMin);
725 ACTION("Minimum key code value not changed\n");
728 info->explicitMin = tmp.uval;
730 if (which == MAX_KEYCODE_DEF)
732 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
734 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
735 tmp.uval, info->explicitMin);
736 ACTION("Maximum code value not changed\n");
739 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
742 ("Maximum code (%d) must be >= highest defined key (%d)\n",
743 tmp.uval, info->computedMax);
744 ACTION("Maximum code value not changed\n");
747 info->explicitMax = tmp.uval;
759 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
762 IndicatorNameInfo ii;
765 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
768 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
772 InitIndicatorNameInfo(&ii, info);
774 if (!ExprResolveString(keymap->context, def->name, &tmp))
777 snprintf(buf, sizeof(buf), "%d", def->ndx);
779 return ReportBadType("indicator", "name", buf, "string");
781 ii.name = xkb_atom_intern(keymap->context, tmp.str);
783 ii.virtual = def->virtual;
784 if (!AddIndicatorName(info, keymap, &ii))
790 * Handle the xkb_keycodes section of a xkb file.
791 * All information about parsed keys is stored in the info struct.
793 * Such a section may have include statements, in which case this function is
794 * semi-recursive (it calls HandleIncludeKeycodes, which may call
795 * HandleKeycodesFile again).
797 * @param file The input file (parsed xkb_keycodes section)
798 * @param xkb Necessary to pass down, may have flags changed.
799 * @param merge Merge strategy (MergeOverride, etc.)
800 * @param info Struct to contain the fully parsed key information.
803 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
804 unsigned merge, KeyNamesInfo *info)
809 info->name = uDupString(file->name);
813 switch (stmt->stmtType)
815 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
816 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
819 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
820 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
823 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
824 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
828 case StmtVarDef: /* e.g. minimum, maximum */
829 if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
832 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
833 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap, info))
838 ERROR("Keycode files may define key and indicator names only\n");
839 ACTION("Ignoring definition of %s\n",
841 StmtInterpDef) ? "a symbol interpretation" :
842 "virtual modifiers"));
846 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
851 if (info->errorCount > 10)
854 ERROR("Too many errors\n");
856 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
863 * Compile the xkb_keycodes section, parse it's output, return the results.
865 * @param file The parsed XKB file (may have include statements requiring
867 * @param result The effective keycodes, as gathered from the file.
868 * @param merge Merge strategy.
870 * @return true on success, false otherwise.
873 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
875 KeyNamesInfo info; /* contains all the info after parsing */
877 InitKeyNamesInfo(&info);
879 HandleKeycodesFile(file, keymap, merge, &info);
881 /* all the keys are now stored in info */
883 if (info.errorCount != 0)
886 if (info.explicitMin > 0) /* if "minimum" statement was present */
887 keymap->min_key_code = info.explicitMin;
889 keymap->min_key_code = info.computedMin;
891 if (info.explicitMax > 0) /* if "maximum" statement was present */
892 keymap->max_key_code = info.explicitMax;
894 keymap->max_key_code = info.computedMax;
896 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
899 for (i = info.computedMin; i <= info.computedMax; i++)
900 LongToKeyName(info.names[i], keymap->names->keys[i].name);
902 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
907 IndicatorNameInfo *ii;
908 if (XkbcAllocIndicatorMaps(keymap) != Success) {
909 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
910 ACTION("Physical indicators not set\n");
913 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
914 free(UNCONSTIFY(keymap->names->indicators[ii->ndx - 1]));
915 keymap->names->indicators[ii->ndx - 1] =
916 xkb_atom_strdup(keymap->context, ii->name);
920 ApplyAliases(keymap, &info.aliases);
922 ClearKeyNamesInfo(&info);
926 ClearKeyNamesInfo(&info);