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,
81 struct xkb_keymap * xkb,
86 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
91 tmp = uTypedRealloc(info->names, newMax + 1, unsigned long);
94 ("Couldn't reallocate for larger maximum keycode (%d)\n",
96 ACTION("Maximum key value not changed\n");
100 for (i = info->arraySize + 1; i <= newMax; i++)
103 tmp = uTypedRealloc(info->files, newMax + 1, unsigned);
106 ("Couldn't reallocate for larger maximum keycode (%d)\n",
108 ACTION("Maximum key value not changed\n");
112 for (i = info->arraySize + 1; i <= newMax; i++)
115 tmp = uTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
118 ("Couldn't reallocate for larger maximum keycode (%d)\n",
120 ACTION("Maximum key value not changed\n");
123 info->has_alt_forms = tmp;
124 for (i = info->arraySize + 1; i <= newMax; i++)
125 info->has_alt_forms[i] = 0;
127 info->arraySize = newMax;
133 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
135 ii->defs.defined = 0;
136 ii->defs.merge = info->merge;
137 ii->defs.fileID = info->fileID;
138 ii->defs.next = NULL;
140 ii->name = XKB_ATOM_NONE;
145 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
147 if (ii == info->leds)
149 ClearCommonInfo(&ii->defs);
154 static IndicatorNameInfo *
155 NextIndicatorName(KeyNamesInfo * info)
157 IndicatorNameInfo *ii;
159 ii = uTypedAlloc(IndicatorNameInfo);
162 InitIndicatorNameInfo(ii, info);
163 info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
169 static IndicatorNameInfo *
170 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
172 IndicatorNameInfo *old;
174 for (old = info->leds; old != NULL;
175 old = (IndicatorNameInfo *) old->defs.next)
183 static IndicatorNameInfo *
184 FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
186 IndicatorNameInfo *old;
188 for (old = info->leds; old != NULL;
189 old = (IndicatorNameInfo *) old->defs.next)
191 if (old->name == name)
198 AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
200 IndicatorNameInfo *old;
203 replace = (new->defs.merge == MergeReplace) ||
204 (new->defs.merge == MergeOverride);
205 old = FindIndicatorByName(info, new->name);
208 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
209 || (warningLevel > 9))
211 WARN("Multiple indicators named %s\n", XkbcAtomText(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, XkbcAtomText(using),
290 newType, XkbcAtomText(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, KeyNamesInfo * from,
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, 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 xkb Unused for all but the xkb->flags.
541 * @param info Struct to store the key info in.
544 HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_keymap * xkb, KeyNamesInfo * info)
548 KeyNamesInfo included;
551 memset(&included, 0, sizeof(included));
554 if ((stmt->file == NULL) && (stmt->map == NULL))
558 memset(info, 0, sizeof(KeyNamesInfo));
560 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
562 xkb->flags |= AutoKeyNames;
563 info->explicitMin = 0;
564 info->explicitMax = XKB_KEYCODE_MAX;
565 return (info->errorCount == 0);
566 } /* parse file, store returned info in the xkb struct */
567 else if (ProcessIncludeFile(xkb->context, stmt, XkmKeyNamesIndex, &rtrn,
570 InitKeyNamesInfo(&included);
571 HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
572 if (stmt->stmt != NULL)
575 included.name = stmt->stmt;
582 info->errorCount += 10; /* XXX: why 10?? */
585 /* Do we have more than one include statement? */
586 if ((stmt->next != NULL) && (included.errorCount < 1))
590 KeyNamesInfo next_incl;
592 for (next = stmt->next; next != NULL; next = next->next)
594 if ((next->file == NULL) && (next->map == NULL))
597 MergeIncludedKeycodes(&included, info, next->merge);
598 ClearKeyNamesInfo(info);
600 else if (ProcessIncludeFile(xkb->context, next, XkmKeyNamesIndex,
603 InitKeyNamesInfo(&next_incl);
604 HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
605 MergeIncludedKeycodes(&included, &next_incl, op);
606 ClearKeyNamesInfo(&next_incl);
611 info->errorCount += 10; /* XXX: Why 10?? */
612 ClearKeyNamesInfo(&included);
621 MergeIncludedKeycodes(info, &included, newMerge);
622 ClearKeyNamesInfo(&included);
624 return (info->errorCount == 0);
628 * Parse the given statement and store the output in the info struct.
632 HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
634 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
635 (info->explicitMax != 0 && stmt->value > info->explicitMax))
637 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
638 ACTION("Must be in the range %d-%d inclusive\n",
640 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
643 if (stmt->merge != MergeDefault)
645 if (stmt->merge == MergeReplace)
646 merge = MergeOverride;
650 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
654 #define MIN_KEYCODE_DEF 0
655 #define MAX_KEYCODE_DEF 1
658 * Handle the minimum/maximum statement of the xkb file.
659 * Sets explicitMin/Max of the info struct.
661 * @return 1 on success, 0 otherwise.
664 HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
666 ExprResult tmp, field;
670 if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
671 return 0; /* internal error, already reported */
675 ERROR("Unknown element %s encountered\n", tmp.str);
676 ACTION("Default for field %s ignored\n", field.str);
679 if (strcasecmp(field.str, "minimum") == 0)
680 which = MIN_KEYCODE_DEF;
681 else if (strcasecmp(field.str, "maximum") == 0)
682 which = MAX_KEYCODE_DEF;
685 ERROR("Unknown field encountered\n");
686 ACTION("Assigment to field %s ignored\n", field.str);
689 if (arrayNdx != NULL)
691 ERROR("The %s setting is not an array\n", field.str);
692 ACTION("Illegal array reference ignored\n");
696 if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
698 ACTION("Assignment to field %s ignored\n", field.str);
701 if (tmp.uval > XKB_KEYCODE_MAX)
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);
709 if (which == MIN_KEYCODE_DEF)
711 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
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");
719 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
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");
727 info->explicitMin = tmp.uval;
729 if (which == MAX_KEYCODE_DEF)
731 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
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");
738 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
741 ("Maximum code (%d) must be >= highest defined key (%d)\n",
742 tmp.uval, info->computedMax);
743 ACTION("Maximum code value not changed\n");
746 info->explicitMax = tmp.uval;
758 HandleIndicatorNameDef(IndicatorNameDef *def, KeyNamesInfo *info)
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_intern_atom(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,
802 struct xkb_keymap * xkb, 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, xkb, 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,
823 merge, info->fileID, &info->aliases))
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, 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 *xkb, unsigned merge)
875 KeyNamesInfo info; /* contains all the info after parsing */
877 InitKeyNamesInfo(&info);
879 HandleKeycodesFile(file, xkb, 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 xkb->min_key_code = info.explicitMin;
889 xkb->min_key_code = info.computedMin;
891 if (info.explicitMax > 0) /* if "maximum" statement was present */
892 xkb->max_key_code = info.explicitMax;
894 xkb->max_key_code = info.computedMax;
896 if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
899 for (i = info.computedMin; i <= info.computedMax; i++)
900 LongToKeyName(info.names[i], xkb->names->keys[i].name);
902 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
907 IndicatorNameInfo *ii;
908 if (XkbcAllocIndicatorMaps(xkb) != 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(xkb->names->indicators[ii->ndx - 1]));
915 xkb->names->indicators[ii->ndx - 1] = XkbcAtomGetString(ii->name);
919 ApplyAliases(xkb, &info.aliases);
921 ClearKeyNamesInfo(&info);
925 ClearKeyNamesInfo(&info);