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_free(info->files);
285 darray_free(info->has_alt_forms);
287 ClearIndicatorNameInfo(info->leds, info);
289 ClearAliases(&info->aliases);
293 InitKeyNamesInfo(KeyNamesInfo * info)
297 info->aliases = NULL;
298 darray_init(info->names);
299 darray_init(info->files);
300 darray_init(info->has_alt_forms);
301 ClearKeyNamesInfo(info);
302 info->errorCount = 0;
306 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
310 for (i = info->computedMin; i <= info->computedMax; i++)
311 if (darray_item(info->names, i) == name)
318 * Store the name of the key as a long in the info struct under the given
319 * keycode. If the same keys is referred to twice, print a warning.
320 * Note that the key's name is stored as a long, the keycode is the index.
323 AddKeyName(KeyNamesInfo * info,
325 char *name, unsigned merge, unsigned fileID, bool reportCollisions)
330 ResizeKeyNameArrays(info, kc);
332 if (kc < info->computedMin)
333 info->computedMin = kc;
334 if (kc > info->computedMax)
335 info->computedMax = kc;
336 lval = KeyNameToLong(name);
338 if (reportCollisions)
340 reportCollisions = (warningLevel > 7 ||
342 fileID == darray_item(info->files, kc)));
345 if (darray_item(info->names, kc) != 0)
349 LongToKeyName(darray_item(info->names, kc), buf);
351 if (darray_item(info->names, kc) == lval)
353 if (darray_item(info->has_alt_forms, kc) || (merge == MergeAltForm)) {
354 darray_item(info->has_alt_forms, kc) = true;
356 else if (reportCollisions) {
357 WARN("Multiple identical key name definitions\n");
358 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
363 if (merge == MergeAugment)
365 if (reportCollisions)
367 WARN("Multiple names for keycode %d\n", kc);
368 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
374 if (reportCollisions)
376 WARN("Multiple names for keycode %d\n", kc);
377 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
379 darray_item(info->names, kc) = 0;
380 darray_item(info->files, kc) = 0;
383 old = FindKeyByLong(info, lval);
384 if ((old != 0) && (old != kc))
386 if (merge == MergeOverride)
388 darray_item(info->names, old) = 0;
389 darray_item(info->files, old) = 0;
390 darray_item(info->has_alt_forms, old) = true;
391 if (reportCollisions)
393 WARN("Key name <%s> assigned to multiple keys\n", name);
394 ACTION("Using %d, ignoring %d\n", kc, old);
397 else if (merge != MergeAltForm)
399 if ((reportCollisions) && (warningLevel > 3))
401 WARN("Key name <%s> assigned to multiple keys\n", name);
402 ACTION("Using %d, ignoring %d\n", old, kc);
404 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
410 darray_item(info->has_alt_forms, old) = true;
413 darray_item(info->names, kc) = lval;
414 darray_item(info->files, kc) = fileID;
415 darray_item(info->has_alt_forms, kc) = (merge == MergeAltForm);
419 /***====================================================================***/
422 MergeIncludedKeycodes(KeyNamesInfo *into, struct xkb_keymap *keymap,
423 KeyNamesInfo *from, unsigned merge)
428 if (from->errorCount > 0)
430 into->errorCount += from->errorCount;
433 if (into->name == NULL)
435 into->name = from->name;
439 ResizeKeyNameArrays(into, from->computedMax);
441 for (i = from->computedMin; i <= from->computedMax; i++)
444 if (darray_item(from->names, i) == 0)
446 LongToKeyName(darray_item(from->names, i), buf);
448 if (darray_item(from->has_alt_forms, i))
449 thisMerge = MergeAltForm;
452 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, false))
457 IndicatorNameInfo *led, *next;
458 for (led = from->leds; led != NULL; led = next)
460 if (merge != MergeDefault)
461 led->defs.merge = merge;
462 if (!AddIndicatorName(into, keymap, led->defs.merge, led))
464 next = (IndicatorNameInfo *) led->defs.next;
467 if (!MergeAliases(&into->aliases, &from->aliases, merge))
469 if (from->explicitMin != 0)
471 if ((into->explicitMin == 0)
472 || (into->explicitMin > from->explicitMin))
473 into->explicitMin = from->explicitMin;
475 if (from->explicitMax > 0)
477 if ((into->explicitMax == 0)
478 || (into->explicitMax < from->explicitMax))
479 into->explicitMax = from->explicitMax;
484 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
486 * @param stmt The include statement from the keymap file.
487 * @param keymap Unused for all but the keymap->flags.
488 * @param info Struct to store the key info in.
491 HandleIncludeKeycodes(IncludeStmt *stmt, struct xkb_keymap *keymap,
496 KeyNamesInfo included;
499 memset(&included, 0, sizeof(included));
502 if ((stmt->file == NULL) && (stmt->map == NULL))
506 memset(info, 0, sizeof(KeyNamesInfo));
508 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
510 keymap->flags |= AutoKeyNames;
511 info->explicitMin = 0;
512 info->explicitMax = XKB_KEYCODE_MAX;
513 return (info->errorCount == 0);
514 } /* parse file, store returned info in the xkb struct */
515 else if (ProcessIncludeFile(keymap->ctx, stmt, XkmKeyNamesIndex, &rtrn,
518 InitKeyNamesInfo(&included);
519 HandleKeycodesFile(rtrn, keymap, MergeOverride, &included);
520 if (stmt->stmt != NULL)
523 included.name = stmt->stmt;
530 info->errorCount += 10; /* XXX: why 10?? */
533 /* Do we have more than one include statement? */
534 if ((stmt->next != NULL) && (included.errorCount < 1))
538 KeyNamesInfo next_incl;
540 for (next = stmt->next; next != NULL; next = next->next)
542 if ((next->file == NULL) && (next->map == NULL))
545 MergeIncludedKeycodes(&included, keymap, info, next->merge);
546 ClearKeyNamesInfo(info);
548 else if (ProcessIncludeFile(keymap->ctx, next, XkmKeyNamesIndex,
551 InitKeyNamesInfo(&next_incl);
552 HandleKeycodesFile(rtrn, keymap, MergeOverride, &next_incl);
553 MergeIncludedKeycodes(&included, keymap, &next_incl, op);
554 ClearKeyNamesInfo(&next_incl);
559 info->errorCount += 10; /* XXX: Why 10?? */
560 ClearKeyNamesInfo(&included);
569 MergeIncludedKeycodes(info, keymap, &included, newMerge);
570 ClearKeyNamesInfo(&included);
572 return (info->errorCount == 0);
576 * Parse the given statement and store the output in the info struct.
580 HandleKeycodeDef(KeycodeDef *stmt, unsigned merge, KeyNamesInfo *info)
582 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
583 (info->explicitMax != 0 && stmt->value > info->explicitMax))
585 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
586 ACTION("Must be in the range %d-%d inclusive\n",
588 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
591 if (stmt->merge != MergeDefault)
593 if (stmt->merge == MergeReplace)
594 merge = MergeOverride;
598 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
602 #define MIN_KEYCODE_DEF 0
603 #define MAX_KEYCODE_DEF 1
606 * Handle the minimum/maximum statement of the xkb file.
607 * Sets explicitMin/Max of the info struct.
609 * @return 1 on success, 0 otherwise.
612 HandleKeyNameVar(VarDef *stmt, struct xkb_keymap *keymap, KeyNamesInfo *info)
614 ExprResult tmp, field;
618 if (ExprResolveLhs(keymap, stmt->name, &tmp, &field, &arrayNdx) == 0)
619 return 0; /* internal error, already reported */
623 ERROR("Unknown element %s encountered\n", tmp.str);
624 ACTION("Default for field %s ignored\n", field.str);
627 if (strcasecmp(field.str, "minimum") == 0)
628 which = MIN_KEYCODE_DEF;
629 else if (strcasecmp(field.str, "maximum") == 0)
630 which = MAX_KEYCODE_DEF;
633 ERROR("Unknown field encountered\n");
634 ACTION("Assigment to field %s ignored\n", field.str);
637 if (arrayNdx != NULL)
639 ERROR("The %s setting is not an array\n", field.str);
640 ACTION("Illegal array reference ignored\n");
644 if (ExprResolveKeyCode(keymap->ctx, stmt->value, &tmp) == 0)
646 ACTION("Assignment to field %s ignored\n", field.str);
649 if (tmp.uval > XKB_KEYCODE_MAX)
652 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
653 tmp.uval, 0, XKB_KEYCODE_MAX);
654 ACTION("Value of \"%s\" not changed\n", field.str);
657 if (which == MIN_KEYCODE_DEF)
659 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
662 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
663 tmp.uval, info->explicitMax);
664 ACTION("Minimum key code value not changed\n");
667 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
670 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
671 tmp.uval, info->computedMin);
672 ACTION("Minimum key code value not changed\n");
675 info->explicitMin = tmp.uval;
677 if (which == MAX_KEYCODE_DEF)
679 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
681 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
682 tmp.uval, info->explicitMin);
683 ACTION("Maximum code value not changed\n");
686 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
689 ("Maximum code (%d) must be >= highest defined key (%d)\n",
690 tmp.uval, info->computedMax);
691 ACTION("Maximum code value not changed\n");
694 info->explicitMax = tmp.uval;
706 HandleIndicatorNameDef(IndicatorNameDef *def, struct xkb_keymap *keymap,
707 unsigned merge, KeyNamesInfo *info)
709 IndicatorNameInfo ii;
712 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
715 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
719 InitIndicatorNameInfo(&ii, info);
721 if (!ExprResolveString(keymap->ctx, def->name, &tmp))
724 snprintf(buf, sizeof(buf), "%d", def->ndx);
726 return ReportBadType("indicator", "name", buf, "string");
728 ii.name = xkb_atom_intern(keymap->ctx, tmp.str);
730 ii.virtual = def->virtual;
731 if (!AddIndicatorName(info, keymap, merge, &ii))
737 * Handle the xkb_keycodes section of a xkb file.
738 * All information about parsed keys is stored in the info struct.
740 * Such a section may have include statements, in which case this function is
741 * semi-recursive (it calls HandleIncludeKeycodes, which may call
742 * HandleKeycodesFile again).
744 * @param file The input file (parsed xkb_keycodes section)
745 * @param xkb Necessary to pass down, may have flags changed.
746 * @param merge Merge strategy (MergeOverride, etc.)
747 * @param info Struct to contain the fully parsed key information.
750 HandleKeycodesFile(XkbFile *file, struct xkb_keymap *keymap,
751 unsigned merge, KeyNamesInfo *info)
756 info->name = uDupString(file->name);
760 switch (stmt->stmtType)
762 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
763 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, keymap, info))
766 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
767 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
770 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
771 if (!HandleAliasDef((KeyAliasDef *) stmt, merge, info->fileID,
775 case StmtVarDef: /* e.g. minimum, maximum */
776 if (!HandleKeyNameVar((VarDef *) stmt, keymap, info))
779 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
780 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt, keymap,
786 ERROR("Keycode files may define key and indicator names only\n");
787 ACTION("Ignoring definition of %s\n",
789 StmtInterpDef) ? "a symbol interpretation" :
790 "virtual modifiers"));
794 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
799 if (info->errorCount > 10)
802 ERROR("Too many errors\n");
804 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
811 * Compile the xkb_keycodes section, parse it's output, return the results.
813 * @param file The parsed XKB file (may have include statements requiring
815 * @param result The effective keycodes, as gathered from the file.
816 * @param merge Merge strategy.
818 * @return true on success, false otherwise.
821 CompileKeycodes(XkbFile *file, struct xkb_keymap *keymap, unsigned merge)
823 KeyNamesInfo info; /* contains all the info after parsing */
825 InitKeyNamesInfo(&info);
827 HandleKeycodesFile(file, keymap, merge, &info);
829 /* all the keys are now stored in info */
831 if (info.errorCount != 0)
834 if (info.explicitMin > 0) /* if "minimum" statement was present */
835 keymap->min_key_code = info.explicitMin;
837 keymap->min_key_code = info.computedMin;
839 if (info.explicitMax > 0) /* if "maximum" statement was present */
840 keymap->max_key_code = info.explicitMax;
842 keymap->max_key_code = info.computedMax;
844 if (XkbcAllocNames(keymap, XkbKeyNamesMask | XkbIndicatorNamesMask, 0)
847 for (i = info.computedMin; i <= info.computedMax; i++)
848 LongToKeyName(darray_item(info.names, i),
849 darray_item(keymap->names->keys, i).name);
851 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
856 IndicatorNameInfo *ii;
857 if (XkbcAllocIndicatorMaps(keymap) != Success) {
858 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
859 ACTION("Physical indicators not set\n");
862 for (ii = info.leds; ii; ii = (IndicatorNameInfo *)ii->defs.next) {
863 free(keymap->names->indicators[ii->ndx - 1]);
864 keymap->names->indicators[ii->ndx - 1] =
865 xkb_atom_strdup(keymap->ctx, ii->name);
869 ApplyAliases(keymap, &info.aliases);
871 ClearKeyNamesInfo(&info);
875 ClearKeyNamesInfo(&info);