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 darray(unsigned long) names;
73 darray(unsigned int) files;
74 darray(unsigned char) has_alt_forms;
75 IndicatorNameInfo *leds;
79 static void HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
80 unsigned merge, KeyNamesInfo *info);
83 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
85 if (newMax < darray_size(info->names))
88 darray_resize0(info->names, newMax + 1);
89 darray_resize0(info->files, newMax + 1);
90 darray_resize0(info->has_alt_forms, newMax + 1);
94 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
97 ii->defs.merge = info->merge;
98 ii->defs.fileID = info->fileID;
101 ii->name = XKB_ATOM_NONE;
106 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
108 if (ii == info->leds)
110 ClearCommonInfo(&ii->defs);
115 static IndicatorNameInfo *
116 NextIndicatorName(KeyNamesInfo * info)
118 IndicatorNameInfo *ii;
120 ii = uTypedAlloc(IndicatorNameInfo);
123 InitIndicatorNameInfo(ii, info);
124 info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
130 static IndicatorNameInfo *
131 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
133 IndicatorNameInfo *old;
135 for (old = info->leds; old != NULL;
136 old = (IndicatorNameInfo *) old->defs.next)
144 static IndicatorNameInfo *
145 FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
147 IndicatorNameInfo *old;
149 for (old = info->leds; old != NULL;
150 old = (IndicatorNameInfo *) old->defs.next)
152 if (old->name == name)
159 AddIndicatorName(KeyNamesInfo *info, struct xkb_keymap *keymap, unsigned merge,
160 IndicatorNameInfo *new)
162 IndicatorNameInfo *old;
165 replace = (merge == MergeReplace) || (merge == MergeOverride);
166 old = FindIndicatorByName(info, new->name);
169 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
170 || (warningLevel > 9))
172 WARN("Multiple indicators named %s\n",
173 xkb_atom_text(keymap->ctx, new->name));
174 if (old->ndx == new->ndx)
176 if (old->virtual != new->virtual)
179 old->virtual = new->virtual;
180 ACTION("Using %s instead of %s\n",
181 (old->virtual ? "virtual" : "real"),
182 (old->virtual ? "real" : "virtual"));
186 ACTION("Identical definitions ignored\n");
193 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
195 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
199 if (info->leds == old)
200 info->leds = (IndicatorNameInfo *) old->defs.next;
203 IndicatorNameInfo *tmp;
206 tmp = (IndicatorNameInfo *) tmp->defs.next)
208 if (tmp->defs.next == (CommonInfo *) old)
210 tmp->defs.next = old->defs.next;
219 old = FindIndicatorByIndex(info, new->ndx);
222 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
223 || (warningLevel > 9))
225 WARN("Multiple names for indicator %d\n", new->ndx);
226 if ((old->name == new->name) && (old->virtual == new->virtual))
227 ACTION("Identical definitions ignored\n");
230 const char *oldType, *newType;
231 xkb_atom_t using, ignoring;
233 oldType = "virtual indicator";
235 oldType = "real indicator";
237 newType = "virtual indicator";
239 newType = "real indicator";
243 ignoring = old->name;
248 ignoring = new->name;
250 ACTION("Using %s %s, ignoring %s %s\n",
251 oldType, xkb_atom_text(keymap->ctx, using),
252 newType, xkb_atom_text(keymap->ctx, ignoring));
257 old->name = new->name;
258 old->virtual = new->virtual;
263 new = NextIndicatorName(info);
266 WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
270 new->name = old->name;
272 new->virtual = old->virtual;
277 ClearKeyNamesInfo(KeyNamesInfo * info)
281 info->computedMax = info->explicitMax = info->explicitMin = 0;
282 info->computedMin = XKB_KEYCODE_MAX;
283 darray_free(info->names);
284 darray_init(info->names);
285 darray_free(info->files);
286 darray_init(info->files);
287 darray_free(info->has_alt_forms);
288 darray_init(info->has_alt_forms);
290 ClearIndicatorNameInfo(info->leds, info);
292 ClearAliases(&info->aliases);
296 InitKeyNamesInfo(KeyNamesInfo * info)
300 info->aliases = NULL;
301 darray_init(info->names);
302 darray_init(info->files);
303 darray_init(info->has_alt_forms);
304 ClearKeyNamesInfo(info);
305 info->errorCount = 0;
309 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
313 for (i = info->computedMin; i <= info->computedMax; i++)
314 if (darray_item(info->names, i) == name)
321 * Store the name of the key as a long in the info struct under the given
322 * keycode. If the same keys is referred to twice, print a warning.
323 * Note that the key's name is stored as a long, the keycode is the index.
326 AddKeyName(KeyNamesInfo * info,
328 char *name, unsigned merge, unsigned fileID, bool reportCollisions)
333 ResizeKeyNameArrays(info, kc);
335 if (kc < info->computedMin)
336 info->computedMin = kc;
337 if (kc > info->computedMax)
338 info->computedMax = kc;
339 lval = KeyNameToLong(name);
341 if (reportCollisions)
343 reportCollisions = (warningLevel > 7 ||
345 fileID == darray_item(info->files, kc)));
348 if (darray_item(info->names, kc) != 0)
352 LongToKeyName(darray_item(info->names, kc), buf);
354 if (darray_item(info->names, kc) == lval)
356 if (darray_item(info->has_alt_forms, kc) || (merge == MergeAltForm)) {
357 darray_item(info->has_alt_forms, kc) = true;
359 else if (reportCollisions) {
360 WARN("Multiple identical key name definitions\n");
361 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
366 if (merge == MergeAugment)
368 if (reportCollisions)
370 WARN("Multiple names for keycode %d\n", kc);
371 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
377 if (reportCollisions)
379 WARN("Multiple names for keycode %d\n", kc);
380 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
382 darray_item(info->names, kc) = 0;
383 darray_item(info->files, kc) = 0;
386 old = FindKeyByLong(info, lval);
387 if ((old != 0) && (old != kc))
389 if (merge == MergeOverride)
391 darray_item(info->names, old) = 0;
392 darray_item(info->files, old) = 0;
393 darray_item(info->has_alt_forms, old) = true;
394 if (reportCollisions)
396 WARN("Key name <%s> assigned to multiple keys\n", name);
397 ACTION("Using %d, ignoring %d\n", kc, old);
400 else if (merge != MergeAltForm)
402 if ((reportCollisions) && (warningLevel > 3))
404 WARN("Key name <%s> assigned to multiple keys\n", name);
405 ACTION("Using %d, ignoring %d\n", old, kc);
407 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
413 darray_item(info->has_alt_forms, old) = true;
416 darray_item(info->names, kc) = lval;
417 darray_item(info->files, kc) = fileID;
418 darray_item(info->has_alt_forms, kc) = (merge == MergeAltForm);
422 /***====================================================================***/
425 MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
426 KeyNamesInfo *from, unsigned merge)
431 if (from->errorCount > 0)
433 into->errorCount += from->errorCount;
436 if (into->name == NULL)
438 into->name = from->name;
442 ResizeKeyNameArrays(into, from->computedMax);
444 for (i = from->computedMin; i <= from->computedMax; i++)
447 if (darray_item(from->names, i) == 0)
449 LongToKeyName(darray_item(from->names, i), buf);
451 if (darray_item(from->has_alt_forms, i))
452 thisMerge = MergeAltForm;
455 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, false))
460 IndicatorNameInfo *led, *next;
461 for (led = from->leds; led != NULL; led = next)
463 if (merge != MergeDefault)
464 led->defs.merge = merge;
465 if (!AddIndicatorName(into, keymap, led->defs.merge, led))
467 next = (IndicatorNameInfo *) led->defs.next;
470 if (!MergeAliases(&into->aliases, &from->aliases, merge))
472 if (from->explicitMin != 0)
474 if ((into->explicitMin == 0)
475 || (into->explicitMin > from->explicitMin))
476 into->explicitMin = from->explicitMin;
478 if (from->explicitMax > 0)
480 if ((into->explicitMax == 0)
481 || (into->explicitMax < from->explicitMax))
482 into->explicitMax = from->explicitMax;
487 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
489 * @param stmt The include statement from the keymap file.
490 * @param keymap Unused for all but the keymap->flags.
491 * @param info Struct to store the key info in.
494 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
499 KeyNamesInfo included;
502 memset(&included, 0, sizeof(included));
505 if ((stmt->file == NULL) && (stmt->map == NULL))
509 memset(info, 0, sizeof(KeyNamesInfo));
511 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
513 keymap->flags |= AutoKeyNames;
514 info->explicitMin = 0;
515 info->explicitMax = XKB_KEYCODE_MAX;
516 return (info->errorCount == 0);
517 } /* parse file, store returned info in the xkb struct */
518 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmKeyNamesIndex, &rtrn,
521 InitKeyNamesInfo(&included);
522 HandleKeycodesFile(rtrn, keymap, MergeOverride, &included);
523 if (stmt->stmt != NULL)
526 included.name = stmt->stmt;
533 info->errorCount += 10; /* XXX: why 10?? */
536 /* Do we have more than one include statement? */
537 if ((stmt->next != NULL) && (included.errorCount < 1))
541 KeyNamesInfo next_incl;
543 for (next = stmt->next; next != NULL; next = next->next)
545 if ((next->file == NULL) && (next->map == NULL))
548 MergeIncludedKeycodes(&included, keymap, info, next->merge);
549 ClearKeyNamesInfo(info);
551 else if (ProcessIncludeFile(keymap->ctx, next, XkmKeyNamesIndex,
554 InitKeyNamesInfo(&next_incl);
555 HandleKeycodesFile(rtrn, keymap, MergeOverride, &next_incl);
556 MergeIncludedKeycodes(&included, keymap, &next_incl, op);
557 ClearKeyNamesInfo(&next_incl);
562 info->errorCount += 10; /* XXX: Why 10?? */
563 ClearKeyNamesInfo(&included);
572 MergeIncludedKeycodes(info, keymap, &included, newMerge);
573 ClearKeyNamesInfo(&included);
575 return (info->errorCount == 0);
579 * Parse the given statement and store the output in the info struct.
583 HandleKeycodeDef(KeycodeDef *stmt, unsigned merge, KeyNamesInfo *info)
585 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
586 (info->explicitMax != 0 && stmt->value > info->explicitMax))
588 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
589 ACTION("Must be in the range %d-%d inclusive\n",
591 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
594 if (stmt->merge != MergeDefault)
596 if (stmt->merge == MergeReplace)
597 merge = MergeOverride;
601 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
605 #define MIN_KEYCODE_DEF 0
606 #define MAX_KEYCODE_DEF 1
609 * Handle the minimum/maximum statement of the xkb file.
610 * Sets explicitMin/Max of the info struct.
612 * @return 1 on success, 0 otherwise.
615 HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
617 ExprResult tmp, field;
621 if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
622 return 0; /* internal error, already reported */
626 ERROR("Unknown element %s encountered\n", tmp.str);
627 ACTION("Default for field %s ignored\n", field.str);
630 if (strcasecmp(field.str, "minimum") == 0)
631 which = MIN_KEYCODE_DEF;
632 else if (strcasecmp(field.str, "maximum") == 0)
633 which = MAX_KEYCODE_DEF;
636 ERROR("Unknown field encountered\n");
637 ACTION("Assigment to field %s ignored\n", field.str);
640 if (arrayNdx != NULL)
642 ERROR("The %s setting is not an array\n", field.str);
643 ACTION("Illegal array reference ignored\n");
647 if (ExprResolveKeyCode(keymap->ctx, stmt->value, &tmp) == 0)
649 ACTION("Assignment to field %s ignored\n", field.str);
652 if (tmp.uval > XKB_KEYCODE_MAX)
655 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
656 tmp.uval, 0, XKB_KEYCODE_MAX);
657 ACTION("Value of \"%s\" not changed\n", field.str);
660 if (which == MIN_KEYCODE_DEF)
662 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
665 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
666 tmp.uval, info->explicitMax);
667 ACTION("Minimum key code value not changed\n");
670 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
673 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
674 tmp.uval, info->computedMin);
675 ACTION("Minimum key code value not changed\n");
678 info->explicitMin = tmp.uval;
680 if (which == MAX_KEYCODE_DEF)
682 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
684 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
685 tmp.uval, info->explicitMin);
686 ACTION("Maximum code value not changed\n");
689 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
692 ("Maximum code (%d) must be >= highest defined key (%d)\n",
693 tmp.uval, info->computedMax);
694 ACTION("Maximum code value not changed\n");
697 info->explicitMax = tmp.uval;
709 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
710 unsigned merge, KeyNamesInfo *info)
712 IndicatorNameInfo ii;
715 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
718 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
722 InitIndicatorNameInfo(&ii, info);
724 if (!ExprResolveString(keymap->ctx, def->name, &tmp))
727 snprintf(buf, sizeof(buf), "%d", def->ndx);
729 return ReportBadType("indicator", "name", buf, "string");
731 ii.name = xkb_atom_intern(keymap->ctx, tmp.str);
733 ii.virtual = def->virtual;
734 if (!AddIndicatorName(info, keymap, merge, &ii))
740 * Handle the xkb_keycodes section of a xkb file.
741 * All information about parsed keys is stored in the info struct.
743 * Such a section may have include statements, in which case this function is
744 * semi-recursive (it calls HandleIncludeKeycodes, which may call
745 * HandleKeycodesFile again).
747 * @param file The input file (parsed xkb_keycodes section)
748 * @param xkb Necessary to pass down, may have flags changed.
749 * @param merge Merge strategy (MergeOverride, etc.)
750 * @param info Struct to contain the fully parsed key information.
753 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
754 unsigned merge, KeyNamesInfo *info)
759 info->name = uDupString(file->name);
763 switch (stmt->stmtType)
765 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
766 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
769 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
770 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
773 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
774 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
778 case StmtVarDef: /* e.g. minimum, maximum */
779 if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
782 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
783 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap,
789 ERROR("Keycode files may define key and indicator names only\n");
790 ACTION("Ignoring definition of %s\n",
792 StmtInterpDef) ? "a symbol interpretation" :
793 "virtual modifiers"));
797 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
802 if (info->errorCount > 10)
805 ERROR("Too many errors\n");
807 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
814 * Compile the xkb_keycodes section, parse it's output, return the results.
816 * @param file The parsed XKB file (may have include statements requiring
818 * @param result The effective keycodes, as gathered from the file.
819 * @param merge Merge strategy.
821 * @return true on success, false otherwise.
824 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
826 KeyNamesInfo info; /* contains all the info after parsing */
828 InitKeyNamesInfo(&info);
830 HandleKeycodesFile(file, keymap, merge, &info);
832 /* all the keys are now stored in info */
834 if (info.errorCount != 0)
837 if (info.explicitMin > 0) /* if "minimum" statement was present */
838 keymap->min_key_code = info.explicitMin;
840 keymap->min_key_code = info.computedMin;
842 if (info.explicitMax > 0) /* if "maximum" statement was present */
843 keymap->max_key_code = info.explicitMax;
845 keymap->max_key_code = info.computedMax;
847 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
850 for (i = info.computedMin; i <= info.computedMax; i++)
851 LongToKeyName(darray_item(info.names, i),
852 darray_item(keymap->names->keys, i).name);
854 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
859 IndicatorNameInfo *ii;
860 if (XkbcAllocIndicatorMaps(keymap) != Success) {
861 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
862 ACTION("Physical indicators not set\n");
865 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
866 free(keymap->names->indicators[ii->ndx - 1]);
867 keymap->names->indicators[ii->ndx - 1] =
868 xkb_atom_strdup(keymap->ctx, ii->name);
872 ApplyAliases(keymap, &info.aliases);
874 ClearKeyNamesInfo(&info);
878 ClearKeyNamesInfo(&info);