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, IndicatorNameInfo * new)
198 IndicatorNameInfo *old;
201 replace = (new->defs.merge == MergeReplace) ||
202 (new->defs.merge == MergeOverride);
203 old = FindIndicatorByName(info, new->name);
206 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
207 || (warningLevel > 9))
209 WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
210 if (old->ndx == new->ndx)
212 if (old->virtual != new->virtual)
215 old->virtual = new->virtual;
216 ACTION("Using %s instead of %s\n",
217 (old->virtual ? "virtual" : "real"),
218 (old->virtual ? "real" : "virtual"));
222 ACTION("Identical definitions ignored\n");
229 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
231 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
235 if (info->leds == old)
236 info->leds = (IndicatorNameInfo *) old->defs.next;
239 IndicatorNameInfo *tmp;
242 tmp = (IndicatorNameInfo *) tmp->defs.next)
244 if (tmp->defs.next == (CommonInfo *) old)
246 tmp->defs.next = old->defs.next;
255 old = FindIndicatorByIndex(info, new->ndx);
258 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
259 || (warningLevel > 9))
261 WARN("Multiple names for indicator %d\n", new->ndx);
262 if ((old->name == new->name) && (old->virtual == new->virtual))
263 ACTION("Identical definitions ignored\n");
266 const char *oldType, *newType;
267 xkb_atom_t using, ignoring;
269 oldType = "virtual indicator";
271 oldType = "real indicator";
273 newType = "virtual indicator";
275 newType = "real indicator";
279 ignoring = old->name;
284 ignoring = new->name;
286 ACTION("Using %s %s, ignoring %s %s\n",
287 oldType, XkbcAtomText(using),
288 newType, XkbcAtomText(ignoring));
293 old->name = new->name;
294 old->virtual = new->virtual;
299 new = NextIndicatorName(info);
302 WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
306 new->name = old->name;
308 new->virtual = old->virtual;
313 ClearKeyNamesInfo(KeyNamesInfo * info)
317 info->computedMax = info->explicitMax = info->explicitMin = 0;
318 info->computedMin = XKB_KEYCODE_MAX;
324 free(info->has_alt_forms);
325 info->has_alt_forms = NULL;
327 ClearIndicatorNameInfo(info->leds, info);
329 ClearAliases(&info->aliases);
333 InitKeyNamesInfo(KeyNamesInfo * info)
337 info->aliases = NULL;
340 info->has_alt_forms = NULL;
341 ClearKeyNamesInfo(info);
342 info->errorCount = 0;
346 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
350 for (i = info->computedMin; i <= info->computedMax; i++)
352 if (info->names[i] == name)
359 * Store the name of the key as a long in the info struct under the given
360 * keycode. If the same keys is referred to twice, print a warning.
361 * Note that the key's name is stored as a long, the keycode is the index.
364 AddKeyName(KeyNamesInfo * info,
366 char *name, unsigned merge, unsigned fileID, bool reportCollisions)
371 if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
372 ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
373 ACTION("Ignoring key %d\n", kc);
376 if (kc < info->computedMin)
377 info->computedMin = kc;
378 if (kc > info->computedMax)
379 info->computedMax = kc;
380 lval = KeyNameToLong(name);
382 if (reportCollisions)
384 reportCollisions = ((warningLevel > 7) ||
386 && (fileID == info->files[kc])));
389 if (info->names[kc] != 0)
393 LongToKeyName(info->names[kc], buf);
395 if (info->names[kc] == lval)
397 if (info->has_alt_forms[kc] || (merge == MergeAltForm))
399 info->has_alt_forms[kc] = true;
401 else if (reportCollisions)
403 WARN("Multiple identical key name definitions\n");
404 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
409 if (merge == MergeAugment)
411 if (reportCollisions)
413 WARN("Multiple names for keycode %d\n", kc);
414 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
420 if (reportCollisions)
422 WARN("Multiple names for keycode %d\n", kc);
423 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
429 old = FindKeyByLong(info, lval);
430 if ((old != 0) && (old != kc))
432 if (merge == MergeOverride)
434 info->names[old] = 0;
435 info->files[old] = 0;
436 info->has_alt_forms[old] = true;
437 if (reportCollisions)
439 WARN("Key name <%s> assigned to multiple keys\n", name);
440 ACTION("Using %d, ignoring %d\n", kc, old);
443 else if (merge != MergeAltForm)
445 if ((reportCollisions) && (warningLevel > 3))
447 WARN("Key name <%s> assigned to multiple keys\n", name);
448 ACTION("Using %d, ignoring %d\n", old, kc);
450 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
456 info->has_alt_forms[old] = true;
459 info->names[kc] = lval;
460 info->files[kc] = fileID;
461 info->has_alt_forms[kc] = (merge == MergeAltForm);
465 /***====================================================================***/
468 MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
474 if (from->errorCount > 0)
476 into->errorCount += from->errorCount;
479 if (into->name == NULL)
481 into->name = from->name;
484 if (from->computedMax > into->arraySize &&
485 !ResizeKeyNameArrays(into, from->computedMax)) {
486 ERROR("Couldn't resize KeyNames arrays for key %d\n",
488 ACTION("Ignoring include file %s\n", from->name);
489 into->errorCount += 10;
492 for (i = from->computedMin; i <= from->computedMax; i++)
495 if (from->names[i] == 0)
497 LongToKeyName(from->names[i], buf);
499 if (from->has_alt_forms[i])
500 thisMerge = MergeAltForm;
503 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, false))
508 IndicatorNameInfo *led, *next;
509 for (led = from->leds; led != NULL; led = next)
511 if (merge != MergeDefault)
512 led->defs.merge = merge;
513 if (!AddIndicatorName(into, led))
515 next = (IndicatorNameInfo *) led->defs.next;
518 if (!MergeAliases(&into->aliases, &from->aliases, merge))
520 if (from->explicitMin != 0)
522 if ((into->explicitMin == 0)
523 || (into->explicitMin > from->explicitMin))
524 into->explicitMin = from->explicitMin;
526 if (from->explicitMax > 0)
528 if ((into->explicitMax == 0)
529 || (into->explicitMax < from->explicitMax))
530 into->explicitMax = from->explicitMax;
535 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
537 * @param stmt The include statement from the keymap file.
538 * @param keymap Unused for all but the keymap->flags.
539 * @param info Struct to store the key info in.
542 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
547 KeyNamesInfo included;
550 memset(&included, 0, sizeof(included));
553 if ((stmt->file == NULL) && (stmt->map == NULL))
557 memset(info, 0, sizeof(KeyNamesInfo));
559 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
561 keymap->flags |= AutoKeyNames;
562 info->explicitMin = 0;
563 info->explicitMax = XKB_KEYCODE_MAX;
564 return (info->errorCount == 0);
565 } /* parse file, store returned info in the xkb struct */
566 else if (ProcessIncludeFile(keymap->context, stmt, XkmKeyNamesIndex,
569 InitKeyNamesInfo(&included);
570 HandleKeycodesFile(rtrn, keymap, MergeOverride, &included);
571 if (stmt->stmt != NULL)
574 included.name = stmt->stmt;
581 info->errorCount += 10; /* XXX: why 10?? */
584 /* Do we have more than one include statement? */
585 if ((stmt->next != NULL) && (included.errorCount < 1))
589 KeyNamesInfo next_incl;
591 for (next = stmt->next; next != NULL; next = next->next)
593 if ((next->file == NULL) && (next->map == NULL))
596 MergeIncludedKeycodes(&included, info, next->merge);
597 ClearKeyNamesInfo(info);
599 else if (ProcessIncludeFile(keymap->context, next,
600 XkmKeyNamesIndex, &rtrn, &op))
602 InitKeyNamesInfo(&next_incl);
603 HandleKeycodesFile(rtrn, keymap, MergeOverride, &next_incl);
604 MergeIncludedKeycodes(&included, &next_incl, op);
605 ClearKeyNamesInfo(&next_incl);
610 info->errorCount += 10; /* XXX: Why 10?? */
611 ClearKeyNamesInfo(&included);
620 MergeIncludedKeycodes(info, &included, newMerge);
621 ClearKeyNamesInfo(&included);
623 return (info->errorCount == 0);
627 * Parse the given statement and store the output in the info struct.
631 HandleKeycodeDef(KeycodeDef *stmt, unsigned merge, KeyNamesInfo *info)
633 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
634 (info->explicitMax != 0 && stmt->value > info->explicitMax))
636 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
637 ACTION("Must be in the range %d-%d inclusive\n",
639 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
642 if (stmt->merge != MergeDefault)
644 if (stmt->merge == MergeReplace)
645 merge = MergeOverride;
649 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
653 #define MIN_KEYCODE_DEF 0
654 #define MAX_KEYCODE_DEF 1
657 * Handle the minimum/maximum statement of the xkb file.
658 * Sets explicitMin/Max of the info struct.
660 * @return 1 on success, 0 otherwise.
663 HandleKeyNameVar(VarDef *stmt, KeyNamesInfo *info)
665 ExprResult tmp, field;
669 if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
670 return 0; /* internal error, already reported */
674 ERROR("Unknown element %s encountered\n", tmp.str);
675 ACTION("Default for field %s ignored\n", field.str);
678 if (strcasecmp(field.str, "minimum") == 0)
679 which = MIN_KEYCODE_DEF;
680 else if (strcasecmp(field.str, "maximum") == 0)
681 which = MAX_KEYCODE_DEF;
684 ERROR("Unknown field encountered\n");
685 ACTION("Assigment to field %s ignored\n", field.str);
688 if (arrayNdx != NULL)
690 ERROR("The %s setting is not an array\n", field.str);
691 ACTION("Illegal array reference ignored\n");
695 if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
697 ACTION("Assignment to field %s ignored\n", field.str);
700 if (tmp.uval > XKB_KEYCODE_MAX)
703 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
704 tmp.uval, 0, XKB_KEYCODE_MAX);
705 ACTION("Value of \"%s\" not changed\n", field.str);
708 if (which == MIN_KEYCODE_DEF)
710 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
713 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
714 tmp.uval, info->explicitMax);
715 ACTION("Minimum key code value not changed\n");
718 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
721 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
722 tmp.uval, info->computedMin);
723 ACTION("Minimum key code value not changed\n");
726 info->explicitMin = tmp.uval;
728 if (which == MAX_KEYCODE_DEF)
730 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
732 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
733 tmp.uval, info->explicitMin);
734 ACTION("Maximum code value not changed\n");
737 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
740 ("Maximum code (%d) must be >= highest defined key (%d)\n",
741 tmp.uval, info->computedMax);
742 ACTION("Maximum code value not changed\n");
745 info->explicitMax = tmp.uval;
757 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *xkb,
760 IndicatorNameInfo ii;
763 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
766 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
770 InitIndicatorNameInfo(&ii, info);
772 if (!ExprResolveString(def->name, &tmp))
775 snprintf(buf, sizeof(buf), "%d", def->ndx);
777 return ReportBadType("indicator", "name", buf, "string");
779 ii.name = xkb_atom_intern(xkb->context, tmp.str);
781 ii.virtual = def->virtual;
782 if (!AddIndicatorName(info, &ii))
788 * Handle the xkb_keycodes section of a xkb file.
789 * All information about parsed keys is stored in the info struct.
791 * Such a section may have include statements, in which case this function is
792 * semi-recursive (it calls HandleIncludeKeycodes, which may call
793 * HandleKeycodesFile again).
795 * @param file The input file (parsed xkb_keycodes section)
796 * @param xkb Necessary to pass down, may have flags changed.
797 * @param merge Merge strategy (MergeOverride, etc.)
798 * @param info Struct to contain the fully parsed key information.
801 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
802 unsigned merge, KeyNamesInfo *info)
807 info->name = uDupString(file->name);
811 switch (stmt->stmtType)
813 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
814 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
817 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
818 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
821 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
822 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
826 case StmtVarDef: /* e.g. minimum, maximum */
827 if (!HandleKeyNameVar((VarDef *) stmt, info))
830 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
831 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap, info))
836 ERROR("Keycode files may define key and indicator names only\n");
837 ACTION("Ignoring definition of %s\n",
839 StmtInterpDef) ? "a symbol interpretation" :
840 "virtual modifiers"));
844 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
849 if (info->errorCount > 10)
852 ERROR("Too many errors\n");
854 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
861 * Compile the xkb_keycodes section, parse it's output, return the results.
863 * @param file The parsed XKB file (may have include statements requiring
865 * @param result The effective keycodes, as gathered from the file.
866 * @param merge Merge strategy.
868 * @return true on success, false otherwise.
871 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
873 KeyNamesInfo info; /* contains all the info after parsing */
875 InitKeyNamesInfo(&info);
877 HandleKeycodesFile(file, keymap, merge, &info);
879 /* all the keys are now stored in info */
881 if (info.errorCount != 0)
884 if (info.explicitMin > 0) /* if "minimum" statement was present */
885 keymap->min_key_code = info.explicitMin;
887 keymap->min_key_code = info.computedMin;
889 if (info.explicitMax > 0) /* if "maximum" statement was present */
890 keymap->max_key_code = info.explicitMax;
892 keymap->max_key_code = info.computedMax;
894 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
897 for (i = info.computedMin; i <= info.computedMax; i++)
898 LongToKeyName(info.names[i], keymap->names->keys[i].name);
900 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
905 IndicatorNameInfo *ii;
906 if (XkbcAllocIndicatorMaps(keymap) != Success) {
907 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
908 ACTION("Physical indicators not set\n");
911 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
912 free(UNCONSTIFY(keymap->names->indicators[ii->ndx - 1]));
913 keymap->names->indicators[ii->ndx - 1] = XkbcAtomGetString(ii->name);
917 ApplyAliases(keymap, &info.aliases);
919 ClearKeyNamesInfo(&info);
923 ClearKeyNamesInfo(&info);