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) */
67 enum merge_mode merge;
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 IndicatorNameInfo *leds;
78 static void HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
79 enum merge_mode merge, KeyNamesInfo *info);
82 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
84 if (newMax < darray_size(info->names))
87 darray_resize0(info->names, newMax + 1);
88 darray_resize0(info->files, newMax + 1);
92 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
95 ii->defs.merge = info->merge;
96 ii->defs.fileID = info->fileID;
99 ii->name = XKB_ATOM_NONE;
104 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
106 if (ii == info->leds)
108 ClearCommonInfo(&ii->defs);
113 static IndicatorNameInfo *
114 NextIndicatorName(KeyNamesInfo * info)
116 IndicatorNameInfo *ii;
118 ii = uTypedAlloc(IndicatorNameInfo);
121 InitIndicatorNameInfo(ii, info);
122 info->leds = AddCommonInfo(&info->leds->defs, &ii->defs);
127 static IndicatorNameInfo *
128 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
130 IndicatorNameInfo *old;
132 for (old = info->leds; old != NULL;
133 old = (IndicatorNameInfo *) old->defs.next)
141 static IndicatorNameInfo *
142 FindIndicatorByName(KeyNamesInfo * info, xkb_atom_t name)
144 IndicatorNameInfo *old;
146 for (old = info->leds; old != NULL;
147 old = (IndicatorNameInfo *) old->defs.next)
149 if (old->name == name)
156 AddIndicatorName(KeyNamesInfo *info, struct xkb_keymap *keymap, enum merge_mode merge,
157 IndicatorNameInfo *new)
159 IndicatorNameInfo *old;
162 replace = (merge == MERGE_REPLACE) || (merge == MERGE_OVERRIDE);
163 old = FindIndicatorByName(info, new->name);
166 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
167 || (warningLevel > 9))
169 WARN("Multiple indicators named %s\n",
170 xkb_atom_text(keymap->ctx, new->name));
171 if (old->ndx == new->ndx)
173 if (old->virtual != new->virtual)
176 old->virtual = new->virtual;
177 ACTION("Using %s instead of %s\n",
178 (old->virtual ? "virtual" : "real"),
179 (old->virtual ? "real" : "virtual"));
183 ACTION("Identical definitions ignored\n");
190 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
192 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
196 if (info->leds == old)
197 info->leds = (IndicatorNameInfo *) old->defs.next;
200 IndicatorNameInfo *tmp;
203 tmp = (IndicatorNameInfo *) tmp->defs.next)
205 if (tmp->defs.next == (CommonInfo *) old)
207 tmp->defs.next = old->defs.next;
216 old = FindIndicatorByIndex(info, new->ndx);
219 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
220 || (warningLevel > 9))
222 WARN("Multiple names for indicator %d\n", new->ndx);
223 if ((old->name == new->name) && (old->virtual == new->virtual))
224 ACTION("Identical definitions ignored\n");
227 const char *oldType, *newType;
228 xkb_atom_t using, ignoring;
230 oldType = "virtual indicator";
232 oldType = "real indicator";
234 newType = "virtual indicator";
236 newType = "real indicator";
240 ignoring = old->name;
245 ignoring = new->name;
247 ACTION("Using %s %s, ignoring %s %s\n",
248 oldType, xkb_atom_text(keymap->ctx, using),
249 newType, xkb_atom_text(keymap->ctx, ignoring));
254 old->name = new->name;
255 old->virtual = new->virtual;
260 new = NextIndicatorName(info);
263 WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
267 new->name = old->name;
269 new->virtual = old->virtual;
274 ClearKeyNamesInfo(KeyNamesInfo * info)
278 info->computedMax = info->explicitMax = info->explicitMin = 0;
279 info->computedMin = XKB_KEYCODE_MAX;
280 darray_free(info->names);
281 darray_free(info->files);
283 ClearIndicatorNameInfo(info->leds, info);
285 ClearAliases(&info->aliases);
289 InitKeyNamesInfo(KeyNamesInfo * info)
293 info->aliases = NULL;
294 darray_init(info->names);
295 darray_init(info->files);
296 ClearKeyNamesInfo(info);
297 info->errorCount = 0;
301 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
305 for (i = info->computedMin; i <= info->computedMax; i++)
306 if (darray_item(info->names, i) == name)
313 * Store the name of the key as a long in the info struct under the given
314 * keycode. If the same keys is referred to twice, print a warning.
315 * Note that the key's name is stored as a long, the keycode is the index.
318 AddKeyName(KeyNamesInfo * info,
320 char *name, enum merge_mode merge, unsigned fileID, bool reportCollisions)
325 ResizeKeyNameArrays(info, kc);
327 if (kc < info->computedMin)
328 info->computedMin = kc;
329 if (kc > info->computedMax)
330 info->computedMax = kc;
331 lval = KeyNameToLong(name);
333 if (reportCollisions)
335 reportCollisions = (warningLevel > 7 ||
337 fileID == darray_item(info->files, kc)));
340 if (darray_item(info->names, kc) != 0)
344 LongToKeyName(darray_item(info->names, kc), buf);
346 if (darray_item(info->names, kc) == lval && reportCollisions)
348 WARN("Multiple identical key name definitions\n");
349 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
353 if (merge == MERGE_AUGMENT)
355 if (reportCollisions)
357 WARN("Multiple names for keycode %d\n", kc);
358 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
364 if (reportCollisions)
366 WARN("Multiple names for keycode %d\n", kc);
367 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
369 darray_item(info->names, kc) = 0;
370 darray_item(info->files, kc) = 0;
373 old = FindKeyByLong(info, lval);
374 if ((old != 0) && (old != kc))
376 if (merge == MERGE_OVERRIDE)
378 darray_item(info->names, old) = 0;
379 darray_item(info->files, old) = 0;
380 if (reportCollisions)
382 WARN("Key name <%s> assigned to multiple keys\n", name);
383 ACTION("Using %d, ignoring %d\n", kc, old);
388 if ((reportCollisions) && (warningLevel > 3))
390 WARN("Key name <%s> assigned to multiple keys\n", name);
391 ACTION("Using %d, ignoring %d\n", old, kc);
396 darray_item(info->names, kc) = lval;
397 darray_item(info->files, kc) = fileID;
401 /***====================================================================***/
404 MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
405 KeyNamesInfo *from, enum merge_mode merge)
410 if (from->errorCount > 0)
412 into->errorCount += from->errorCount;
415 if (into->name == NULL)
417 into->name = from->name;
421 ResizeKeyNameArrays(into, from->computedMax);
423 for (i = from->computedMin; i <= from->computedMax; i++)
425 if (darray_item(from->names, i) == 0)
427 LongToKeyName(darray_item(from->names, i), buf);
429 if (!AddKeyName(into, i, buf, merge, from->fileID, false))
434 IndicatorNameInfo *led, *next;
435 for (led = from->leds; led != NULL; led = next)
437 if (merge != MERGE_DEFAULT)
438 led->defs.merge = merge;
439 if (!AddIndicatorName(into, keymap, led->defs.merge, led))
441 next = (IndicatorNameInfo *) led->defs.next;
444 if (!MergeAliases(&into->aliases, &from->aliases, merge))
446 if (from->explicitMin != 0)
448 if ((into->explicitMin == 0)
449 || (into->explicitMin > from->explicitMin))
450 into->explicitMin = from->explicitMin;
452 if (from->explicitMax > 0)
454 if ((into->explicitMax == 0)
455 || (into->explicitMax < from->explicitMax))
456 into->explicitMax = from->explicitMax;
461 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
463 * @param stmt The include statement from the keymap file.
464 * @param keymap Unused for all but the keymap->flags.
465 * @param info Struct to store the key info in.
468 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
473 KeyNamesInfo included;
476 memset(&included, 0, sizeof(included));
479 if ((stmt->file == NULL) && (stmt->map == NULL))
483 memset(info, 0, sizeof(KeyNamesInfo));
485 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
487 keymap->flags |= AutoKeyNames;
488 info->explicitMin = 0;
489 info->explicitMax = XKB_KEYCODE_MAX;
490 return (info->errorCount == 0);
491 } /* parse file, store returned info in the xkb struct */
492 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_KEYCODES, &rtrn,
495 InitKeyNamesInfo(&included);
496 HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &included);
497 if (stmt->stmt != NULL)
500 included.name = stmt->stmt;
507 info->errorCount += 10; /* XXX: why 10?? */
510 /* Do we have more than one include statement? */
511 if ((stmt->next != NULL) && (included.errorCount < 1))
515 KeyNamesInfo next_incl;
517 for (next = stmt->next; next != NULL; next = next->next)
519 if ((next->file == NULL) && (next->map == NULL))
522 MergeIncludedKeycodes(&included, keymap, info, next->merge);
523 ClearKeyNamesInfo(info);
525 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_KEYCODES,
528 InitKeyNamesInfo(&next_incl);
529 HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
530 MergeIncludedKeycodes(&included, keymap, &next_incl, op);
531 ClearKeyNamesInfo(&next_incl);
536 info->errorCount += 10; /* XXX: Why 10?? */
537 ClearKeyNamesInfo(&included);
546 MergeIncludedKeycodes(info, keymap, &included, newMerge);
547 ClearKeyNamesInfo(&included);
549 return (info->errorCount == 0);
553 * Parse the given statement and store the output in the info struct.
557 HandleKeycodeDef(KeycodeDef *stmt, enum merge_mode merge, KeyNamesInfo *info)
559 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
560 (info->explicitMax != 0 && stmt->value > info->explicitMax))
562 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
563 ACTION("Must be in the range %d-%d inclusive\n",
565 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
568 if (stmt->merge != MERGE_DEFAULT)
570 if (stmt->merge == MERGE_REPLACE)
571 merge = MERGE_OVERRIDE;
575 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
579 #define MIN_KEYCODE_DEF 0
580 #define MAX_KEYCODE_DEF 1
583 * Handle the minimum/maximum statement of the xkb file.
584 * Sets explicitMin/Max of the info struct.
586 * @return 1 on success, 0 otherwise.
589 HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
591 ExprResult tmp, field;
595 if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
596 return 0; /* internal error, already reported */
600 ERROR("Unknown element %s encountered\n", tmp.str);
601 ACTION("Default for field %s ignored\n", field.str);
604 if (strcasecmp(field.str, "minimum") == 0)
605 which = MIN_KEYCODE_DEF;
606 else if (strcasecmp(field.str, "maximum") == 0)
607 which = MAX_KEYCODE_DEF;
610 ERROR("Unknown field encountered\n");
611 ACTION("Assigment to field %s ignored\n", field.str);
614 if (arrayNdx != NULL)
616 ERROR("The %s setting is not an array\n", field.str);
617 ACTION("Illegal array reference ignored\n");
621 if (ExprResolveKeyCode(keymap->ctx, stmt->value, &tmp) == 0)
623 ACTION("Assignment to field %s ignored\n", field.str);
626 if (tmp.uval > XKB_KEYCODE_MAX)
629 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
630 tmp.uval, 0, XKB_KEYCODE_MAX);
631 ACTION("Value of \"%s\" not changed\n", field.str);
634 if (which == MIN_KEYCODE_DEF)
636 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
639 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
640 tmp.uval, info->explicitMax);
641 ACTION("Minimum key code value not changed\n");
644 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
647 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
648 tmp.uval, info->computedMin);
649 ACTION("Minimum key code value not changed\n");
652 info->explicitMin = tmp.uval;
654 if (which == MAX_KEYCODE_DEF)
656 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
658 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
659 tmp.uval, info->explicitMin);
660 ACTION("Maximum code value not changed\n");
663 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
666 ("Maximum code (%d) must be >= highest defined key (%d)\n",
667 tmp.uval, info->computedMax);
668 ACTION("Maximum code value not changed\n");
671 info->explicitMax = tmp.uval;
683 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
684 enum merge_mode merge, KeyNamesInfo *info)
686 IndicatorNameInfo ii;
689 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
692 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
696 InitIndicatorNameInfo(&ii, info);
698 if (!ExprResolveString(keymap->ctx, def->name, &tmp))
701 snprintf(buf, sizeof(buf), "%d", def->ndx);
703 return ReportBadType("indicator", "name", buf, "string");
705 ii.name = xkb_atom_intern(keymap->ctx, tmp.str);
707 ii.virtual = def->virtual;
708 if (!AddIndicatorName(info, keymap, merge, &ii))
714 * Handle the xkb_keycodes section of a xkb file.
715 * All information about parsed keys is stored in the info struct.
717 * Such a section may have include statements, in which case this function is
718 * semi-recursive (it calls HandleIncludeKeycodes, which may call
719 * HandleKeycodesFile again).
721 * @param file The input file (parsed xkb_keycodes section)
722 * @param xkb Necessary to pass down, may have flags changed.
723 * @param merge Merge strategy (MERGE_OVERRIDE, etc.)
724 * @param info Struct to contain the fully parsed key information.
727 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
728 enum merge_mode merge, KeyNamesInfo *info)
733 info->name = uDupString(file->name);
737 switch (stmt->stmtType)
739 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
740 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
743 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
744 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
747 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
748 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
752 case StmtVarDef: /* e.g. minimum, maximum */
753 if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
756 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
757 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap,
763 ERROR("Keycode files may define key and indicator names only\n");
764 ACTION("Ignoring definition of %s\n",
766 StmtInterpDef) ? "a symbol interpretation" :
767 "virtual modifiers"));
771 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
776 if (info->errorCount > 10)
779 ERROR("Too many errors\n");
781 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
788 * Compile the xkb_keycodes section, parse it's output, return the results.
790 * @param file The parsed XKB file (may have include statements requiring
792 * @param result The effective keycodes, as gathered from the file.
793 * @param merge Merge strategy.
795 * @return true on success, false otherwise.
798 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
800 KeyNamesInfo info; /* contains all the info after parsing */
802 InitKeyNamesInfo(&info);
804 HandleKeycodesFile(file, keymap, merge, &info);
806 /* all the keys are now stored in info */
808 if (info.errorCount != 0)
811 if (info.explicitMin > 0) /* if "minimum" statement was present */
812 keymap->min_key_code = info.explicitMin;
814 keymap->min_key_code = info.computedMin;
816 if (info.explicitMax > 0) /* if "maximum" statement was present */
817 keymap->max_key_code = info.explicitMax;
819 keymap->max_key_code = info.computedMax;
821 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
824 for (i = info.computedMin; i <= info.computedMax; i++)
825 LongToKeyName(darray_item(info.names, i),
826 darray_item(keymap->names->keys, i).name);
828 keymap->names->keycodes = strdup(info.name);
830 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
835 IndicatorNameInfo *ii;
836 if (XkbcAllocIndicatorMaps(keymap) != Success) {
837 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
838 ACTION("Physical indicators not set\n");
841 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
842 free(keymap->names->indicators[ii->ndx - 1]);
843 keymap->names->indicators[ii->ndx - 1] =
844 xkb_atom_strdup(keymap->ctx, ii->name);
848 ApplyAliases(keymap, &info.aliases);
850 ClearKeyNamesInfo(&info);
854 ClearKeyNamesInfo(&info);