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.file_id = info->file_id;
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.file_id == new->defs.file_id) && (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.file_id == new->defs.file_id) && (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, unsigned file_id)
293 info->aliases = NULL;
294 info->file_id = file_id;
295 darray_init(info->names);
296 darray_init(info->files);
297 ClearKeyNamesInfo(info);
298 info->errorCount = 0;
302 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
306 for (i = info->computedMin; i <= info->computedMax; i++)
307 if (darray_item(info->names, i) == name)
314 * Store the name of the key as a long in the info struct under the given
315 * keycode. If the same keys is referred to twice, print a warning.
316 * Note that the key's name is stored as a long, the keycode is the index.
319 AddKeyName(KeyNamesInfo * info,
320 xkb_keycode_t kc, char *name, enum merge_mode merge,
321 unsigned file_id, bool reportCollisions)
326 ResizeKeyNameArrays(info, kc);
328 if (kc < info->computedMin)
329 info->computedMin = kc;
330 if (kc > info->computedMax)
331 info->computedMax = kc;
332 lval = KeyNameToLong(name);
334 if (reportCollisions)
336 reportCollisions = (warningLevel > 7 ||
338 file_id == darray_item(info->files, kc)));
341 if (darray_item(info->names, kc) != 0)
345 LongToKeyName(darray_item(info->names, kc), buf);
347 if (darray_item(info->names, kc) == lval && reportCollisions)
349 WARN("Multiple identical key name definitions\n");
350 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
354 if (merge == MERGE_AUGMENT)
356 if (reportCollisions)
358 WARN("Multiple names for keycode %d\n", kc);
359 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
365 if (reportCollisions)
367 WARN("Multiple names for keycode %d\n", kc);
368 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
370 darray_item(info->names, kc) = 0;
371 darray_item(info->files, kc) = 0;
374 old = FindKeyByLong(info, lval);
375 if ((old != 0) && (old != kc))
377 if (merge == MERGE_OVERRIDE)
379 darray_item(info->names, old) = 0;
380 darray_item(info->files, old) = 0;
381 if (reportCollisions)
383 WARN("Key name <%s> assigned to multiple keys\n", name);
384 ACTION("Using %d, ignoring %d\n", kc, old);
389 if ((reportCollisions) && (warningLevel > 3))
391 WARN("Key name <%s> assigned to multiple keys\n", name);
392 ACTION("Using %d, ignoring %d\n", old, kc);
397 darray_item(info->names, kc) = lval;
398 darray_item(info->files, kc) = file_id;
402 /***====================================================================***/
405 MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
406 KeyNamesInfo *from, enum merge_mode merge)
411 if (from->errorCount > 0)
413 into->errorCount += from->errorCount;
416 if (into->name == NULL)
418 into->name = from->name;
422 ResizeKeyNameArrays(into, from->computedMax);
424 for (i = from->computedMin; i <= from->computedMax; i++)
426 if (darray_item(from->names, i) == 0)
428 LongToKeyName(darray_item(from->names, i), buf);
430 if (!AddKeyName(into, i, buf, merge, from->file_id, false))
435 IndicatorNameInfo *led, *next;
436 for (led = from->leds; led != NULL; led = next)
438 if (merge != MERGE_DEFAULT)
439 led->defs.merge = merge;
440 if (!AddIndicatorName(into, keymap, led->defs.merge, led))
442 next = (IndicatorNameInfo *) led->defs.next;
445 if (!MergeAliases(&into->aliases, &from->aliases, merge))
447 if (from->explicitMin != 0)
449 if ((into->explicitMin == 0)
450 || (into->explicitMin > from->explicitMin))
451 into->explicitMin = from->explicitMin;
453 if (from->explicitMax > 0)
455 if ((into->explicitMax == 0)
456 || (into->explicitMax < from->explicitMax))
457 into->explicitMax = from->explicitMax;
462 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
464 * @param stmt The include statement from the keymap file.
465 * @param keymap Unused for all but the keymap->flags.
466 * @param info Struct to store the key info in.
469 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
472 enum merge_mode newMerge;
474 KeyNamesInfo included;
477 memset(&included, 0, sizeof(included));
480 if ((stmt->file == NULL) && (stmt->map == NULL))
484 memset(info, 0, sizeof(KeyNamesInfo));
486 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
488 keymap->flags |= AutoKeyNames;
489 info->explicitMin = 0;
490 info->explicitMax = XKB_KEYCODE_MAX;
491 return (info->errorCount == 0);
492 } /* parse file, store returned info in the xkb struct */
493 else if (ProcessIncludeFile(keymap->ctx, stmt, FILE_TYPE_KEYCODES, &rtrn,
496 InitKeyNamesInfo(&included, rtrn->id);
497 HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &included);
498 if (stmt->stmt != NULL)
501 included.name = stmt->stmt;
508 info->errorCount += 10; /* XXX: why 10?? */
511 /* Do we have more than one include statement? */
512 if ((stmt->next != NULL) && (included.errorCount < 1))
516 KeyNamesInfo next_incl;
518 for (next = stmt->next; next != NULL; next = next->next)
520 if ((next->file == NULL) && (next->map == NULL))
523 MergeIncludedKeycodes(&included, keymap, info, next->merge);
524 ClearKeyNamesInfo(info);
526 else if (ProcessIncludeFile(keymap->ctx, next, FILE_TYPE_KEYCODES,
529 InitKeyNamesInfo(&next_incl, rtrn->id);
530 HandleKeycodesFile(rtrn, keymap, MERGE_OVERRIDE, &next_incl);
531 MergeIncludedKeycodes(&included, keymap, &next_incl, op);
532 ClearKeyNamesInfo(&next_incl);
537 info->errorCount += 10; /* XXX: Why 10?? */
538 ClearKeyNamesInfo(&included);
547 MergeIncludedKeycodes(info, keymap, &included, newMerge);
548 ClearKeyNamesInfo(&included);
550 return (info->errorCount == 0);
554 * Parse the given statement and store the output in the info struct.
558 HandleKeycodeDef(KeycodeDef *stmt, enum merge_mode merge, KeyNamesInfo *info)
560 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
561 (info->explicitMax != 0 && stmt->value > info->explicitMax))
563 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
564 ACTION("Must be in the range %d-%d inclusive\n",
566 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
569 if (stmt->merge != MERGE_DEFAULT)
571 if (stmt->merge == MERGE_REPLACE)
572 merge = MERGE_OVERRIDE;
576 return AddKeyName(info, stmt->value, stmt->name, merge, info->file_id,
580 #define MIN_KEYCODE_DEF 0
581 #define MAX_KEYCODE_DEF 1
584 * Handle the minimum/maximum statement of the xkb file.
585 * Sets explicitMin/Max of the info struct.
587 * @return 1 on success, 0 otherwise.
590 HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
592 ExprResult tmp, field;
596 if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
597 return 0; /* internal error, already reported */
601 ERROR("Unknown element %s encountered\n", tmp.str);
602 ACTION("Default for field %s ignored\n", field.str);
605 if (strcasecmp(field.str, "minimum") == 0)
606 which = MIN_KEYCODE_DEF;
607 else if (strcasecmp(field.str, "maximum") == 0)
608 which = MAX_KEYCODE_DEF;
611 ERROR("Unknown field encountered\n");
612 ACTION("Assigment to field %s ignored\n", field.str);
615 if (arrayNdx != NULL)
617 ERROR("The %s setting is not an array\n", field.str);
618 ACTION("Illegal array reference ignored\n");
622 if (ExprResolveKeyCode(keymap->ctx, stmt->value, &tmp) == 0)
624 ACTION("Assignment to field %s ignored\n", field.str);
627 if (tmp.uval > XKB_KEYCODE_MAX)
630 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
631 tmp.uval, 0, XKB_KEYCODE_MAX);
632 ACTION("Value of \"%s\" not changed\n", field.str);
635 if (which == MIN_KEYCODE_DEF)
637 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
640 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
641 tmp.uval, info->explicitMax);
642 ACTION("Minimum key code value not changed\n");
645 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
648 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
649 tmp.uval, info->computedMin);
650 ACTION("Minimum key code value not changed\n");
653 info->explicitMin = tmp.uval;
655 if (which == MAX_KEYCODE_DEF)
657 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
659 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
660 tmp.uval, info->explicitMin);
661 ACTION("Maximum code value not changed\n");
664 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
667 ("Maximum code (%d) must be >= highest defined key (%d)\n",
668 tmp.uval, info->computedMax);
669 ACTION("Maximum code value not changed\n");
672 info->explicitMax = tmp.uval;
684 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
685 enum merge_mode merge, KeyNamesInfo *info)
687 IndicatorNameInfo ii;
690 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
693 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
697 InitIndicatorNameInfo(&ii, info);
699 if (!ExprResolveString(keymap->ctx, def->name, &tmp))
702 snprintf(buf, sizeof(buf), "%d", def->ndx);
704 return ReportBadType("indicator", "name", buf, "string");
706 ii.name = xkb_atom_intern(keymap->ctx, tmp.str);
708 ii.virtual = def->virtual;
709 if (!AddIndicatorName(info, keymap, merge, &ii))
715 * Handle the xkb_keycodes section of a xkb file.
716 * All information about parsed keys is stored in the info struct.
718 * Such a section may have include statements, in which case this function is
719 * semi-recursive (it calls HandleIncludeKeycodes, which may call
720 * HandleKeycodesFile again).
722 * @param file The input file (parsed xkb_keycodes section)
723 * @param xkb Necessary to pass down, may have flags changed.
724 * @param merge Merge strategy (MERGE_OVERRIDE, etc.)
725 * @param info Struct to contain the fully parsed key information.
728 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
729 enum merge_mode merge, KeyNamesInfo *info)
734 info->name = uDupString(file->name);
738 switch (stmt->stmtType)
740 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
741 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
744 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
745 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
748 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
749 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->file_id,
753 case StmtVarDef: /* e.g. minimum, maximum */
754 if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
757 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
758 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap,
764 ERROR("Keycode files may define key and indicator names only\n");
765 ACTION("Ignoring definition of %s\n",
767 StmtInterpDef) ? "a symbol interpretation" :
768 "virtual modifiers"));
772 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
777 if (info->errorCount > 10)
780 ERROR("Too many errors\n");
782 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
789 * Compile the xkb_keycodes section, parse it's output, return the results.
791 * @param file The parsed XKB file (may have include statements requiring
793 * @param result The effective keycodes, as gathered from the file.
794 * @param merge Merge strategy.
796 * @return true on success, false otherwise.
799 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
801 KeyNamesInfo info; /* contains all the info after parsing */
803 InitKeyNamesInfo(&info, file->id);
805 HandleKeycodesFile(file, keymap, merge, &info);
807 /* all the keys are now stored in info */
809 if (info.errorCount != 0)
812 if (info.explicitMin > 0) /* if "minimum" statement was present */
813 keymap->min_key_code = info.explicitMin;
815 keymap->min_key_code = info.computedMin;
817 if (info.explicitMax > 0) /* if "maximum" statement was present */
818 keymap->max_key_code = info.explicitMax;
820 keymap->max_key_code = info.computedMax;
822 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
825 for (i = info.computedMin; i <= info.computedMax; i++)
826 LongToKeyName(darray_item(info.names, i),
827 darray_item(keymap->names->keys, i).name);
829 keymap->names->keycodes = strdup(info.name);
831 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
836 IndicatorNameInfo *ii;
837 if (XkbcAllocIndicatorMaps(keymap) != Success) {
838 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
839 ACTION("Physical indicators not set\n");
842 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
843 free(keymap->names->indicators[ii->ndx - 1]);
844 keymap->names->indicators[ii->ndx - 1] =
845 xkb_atom_strdup(keymap->ctx, ii->name);
849 ApplyAliases(keymap, &info.aliases);
851 ClearKeyNamesInfo(&info);
855 ClearKeyNamesInfo(&info);