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 ********************************************************/
37 longText(unsigned long val)
41 LongToKeyName(val, buf);
42 return XkbcKeyNameText(buf);
45 /***====================================================================***/
48 LongToKeyName(unsigned long val, char *name)
50 name[0] = ((val >> 24) & 0xff);
51 name[1] = ((val >> 16) & 0xff);
52 name[2] = ((val >> 8) & 0xff);
53 name[3] = (val & 0xff);
57 /***====================================================================***/
59 typedef struct _IndicatorNameInfo
67 typedef struct _KeyNamesInfo
69 char *name; /* e.g. evdev+aliases(qwerty) */
73 xkb_keycode_t computedMin; /* lowest keycode stored */
74 xkb_keycode_t computedMax; /* highest keycode stored */
75 xkb_keycode_t explicitMin;
76 xkb_keycode_t explicitMax;
77 xkb_keycode_t arraySize;
80 unsigned char *has_alt_forms;
81 IndicatorNameInfo *leds;
85 static void HandleKeycodesFile(XkbFile * file,
86 struct xkb_desc * xkb,
91 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
96 tmp = _XkbTypedRealloc(info->names, newMax + 1, unsigned long);
99 ("Couldn't reallocate for larger maximum keycode (%d)\n",
101 ACTION("Maximum key value not changed\n");
105 for (i = info->arraySize + 1; i <= newMax; i++)
108 tmp = _XkbTypedRealloc(info->files, newMax + 1, unsigned);
111 ("Couldn't reallocate for larger maximum keycode (%d)\n",
113 ACTION("Maximum key value not changed\n");
117 for (i = info->arraySize + 1; i <= newMax; i++)
120 tmp = _XkbTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
123 ("Couldn't reallocate for larger maximum keycode (%d)\n",
125 ACTION("Maximum key value not changed\n");
128 info->has_alt_forms = tmp;
129 for (i = info->arraySize + 1; i <= newMax; i++)
130 info->has_alt_forms[i] = 0;
132 info->arraySize = newMax;
138 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
140 ii->defs.defined = 0;
141 ii->defs.merge = info->merge;
142 ii->defs.fileID = info->fileID;
143 ii->defs.next = NULL;
151 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
153 if (ii == info->leds)
155 ClearCommonInfo(&ii->defs);
161 static IndicatorNameInfo *
162 NextIndicatorName(KeyNamesInfo * info)
164 IndicatorNameInfo *ii;
166 ii = uTypedAlloc(IndicatorNameInfo);
169 InitIndicatorNameInfo(ii, info);
170 info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
176 static IndicatorNameInfo *
177 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
179 IndicatorNameInfo *old;
181 for (old = info->leds; old != NULL;
182 old = (IndicatorNameInfo *) old->defs.next)
190 static IndicatorNameInfo *
191 FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
193 IndicatorNameInfo *old;
195 for (old = info->leds; old != NULL;
196 old = (IndicatorNameInfo *) old->defs.next)
198 if (old->name == name)
205 AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
207 IndicatorNameInfo *old;
210 replace = (new->defs.merge == MergeReplace) ||
211 (new->defs.merge == MergeOverride);
212 old = FindIndicatorByName(info, new->name);
215 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
216 || (warningLevel > 9))
218 WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
219 if (old->ndx == new->ndx)
221 if (old->virtual != new->virtual)
224 old->virtual = new->virtual;
225 ACTION("Using %s instead of %s\n",
226 (old->virtual ? "virtual" : "real"),
227 (old->virtual ? "real" : "virtual"));
231 ACTION("Identical definitions ignored\n");
238 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
240 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
244 if (info->leds == old)
245 info->leds = (IndicatorNameInfo *) old->defs.next;
248 IndicatorNameInfo *tmp;
251 tmp = (IndicatorNameInfo *) tmp->defs.next)
253 if (tmp->defs.next == (CommonInfo *) old)
255 tmp->defs.next = old->defs.next;
264 old = FindIndicatorByIndex(info, new->ndx);
267 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
268 || (warningLevel > 9))
270 WARN("Multiple names for indicator %d\n", new->ndx);
271 if ((old->name == new->name) && (old->virtual == new->virtual))
272 ACTION("Identical definitions ignored\n");
275 const char *oldType, *newType;
276 uint32_t using, ignoring;
278 oldType = "virtual indicator";
280 oldType = "real indicator";
282 newType = "virtual indicator";
284 newType = "real indicator";
288 ignoring = old->name;
293 ignoring = new->name;
295 ACTION("Using %s %s, ignoring %s %s\n",
296 oldType, XkbcAtomText(using),
297 newType, XkbcAtomText(ignoring));
302 old->name = new->name;
303 old->virtual = new->virtual;
308 new = NextIndicatorName(info);
311 WSGO("Couldn't allocate name for indicator %d\n", new->ndx);
315 new->name = old->name;
317 new->virtual = old->virtual;
322 ClearKeyNamesInfo(KeyNamesInfo * info)
324 if (info->name != NULL)
327 info->computedMax = info->explicitMax = info->explicitMin = 0;
328 info->computedMin = XKB_KEYCODE_MAX;
334 free(info->has_alt_forms);
335 info->has_alt_forms = NULL;
337 ClearIndicatorNameInfo(info->leds, info);
339 ClearAliases(&info->aliases);
344 InitKeyNamesInfo(KeyNamesInfo * info)
348 info->aliases = NULL;
351 info->has_alt_forms = NULL;
352 ClearKeyNamesInfo(info);
353 info->errorCount = 0;
358 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
362 for (i = info->computedMin; i <= info->computedMax; i++)
364 if (info->names[i] == name)
371 * Store the name of the key as a long in the info struct under the given
372 * keycode. If the same keys is referred to twice, print a warning.
373 * Note that the key's name is stored as a long, the keycode is the index.
376 AddKeyName(KeyNamesInfo * info,
378 char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
383 if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
384 ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
385 ACTION("Ignoring key %d\n", kc);
388 if (kc < info->computedMin)
389 info->computedMin = kc;
390 if (kc > info->computedMax)
391 info->computedMax = kc;
392 lval = KeyNameToLong(name);
394 if (reportCollisions)
396 reportCollisions = ((warningLevel > 7) ||
398 && (fileID == info->files[kc])));
401 if (info->names[kc] != 0)
405 LongToKeyName(info->names[kc], buf);
407 if (info->names[kc] == lval)
409 if (info->has_alt_forms[kc] || (merge == MergeAltForm))
411 info->has_alt_forms[kc] = True;
413 else if (reportCollisions)
415 WARN("Multiple identical key name definitions\n");
416 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
421 if (merge == MergeAugment)
423 if (reportCollisions)
425 WARN("Multiple names for keycode %d\n", kc);
426 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
432 if (reportCollisions)
434 WARN("Multiple names for keycode %d\n", kc);
435 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
441 old = FindKeyByLong(info, lval);
442 if ((old != 0) && (old != kc))
444 if (merge == MergeOverride)
446 info->names[old] = 0;
447 info->files[old] = 0;
448 info->has_alt_forms[old] = True;
449 if (reportCollisions)
451 WARN("Key name <%s> assigned to multiple keys\n", name);
452 ACTION("Using %d, ignoring %d\n", kc, old);
455 else if (merge != MergeAltForm)
457 if ((reportCollisions) && (warningLevel > 3))
459 WARN("Key name <%s> assigned to multiple keys\n", name);
460 ACTION("Using %d, ignoring %d\n", old, kc);
462 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
468 info->has_alt_forms[old] = True;
471 info->names[kc] = lval;
472 info->files[kc] = fileID;
473 info->has_alt_forms[kc] = (merge == MergeAltForm);
477 /***====================================================================***/
480 MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
486 if (from->errorCount > 0)
488 into->errorCount += from->errorCount;
491 if (into->name == NULL)
493 into->name = from->name;
496 if (from->computedMax > into->arraySize &&
497 !ResizeKeyNameArrays(into, from->computedMax)) {
498 ERROR("Couldn't resize KeyNames arrays for key %d\n",
500 ACTION("Ignoring include file %s\n", from->name);
501 into->errorCount += 10;
504 for (i = from->computedMin; i <= from->computedMax; i++)
507 if (from->names[i] == 0)
509 LongToKeyName(from->names[i], buf);
511 if (from->has_alt_forms[i])
512 thisMerge = MergeAltForm;
515 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
520 IndicatorNameInfo *led, *next;
521 for (led = from->leds; led != NULL; led = next)
523 if (merge != MergeDefault)
524 led->defs.merge = merge;
525 if (!AddIndicatorName(into, led))
527 next = (IndicatorNameInfo *) led->defs.next;
530 if (!MergeAliases(&into->aliases, &from->aliases, merge))
532 if (from->explicitMin != 0)
534 if ((into->explicitMin < 0)
535 || (into->explicitMin > from->explicitMin))
536 into->explicitMin = from->explicitMin;
538 if (from->explicitMax > 0)
540 if ((into->explicitMax < 0)
541 || (into->explicitMax < from->explicitMax))
542 into->explicitMax = from->explicitMax;
548 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
550 * @param stmt The include statement from the keymap file.
551 * @param xkb Unused for all but the xkb->flags.
552 * @param info Struct to store the key info in.
555 HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo * info)
559 KeyNamesInfo included = {NULL};
563 if ((stmt->file == NULL) && (stmt->map == NULL))
567 bzero(info, sizeof(KeyNamesInfo));
569 else if (strcmp(stmt->file, "computed") == 0)
571 xkb->flags |= AutoKeyNames;
572 info->explicitMin = 0;
573 info->explicitMax = XKB_KEYCODE_MAX;
574 return (info->errorCount == 0);
575 } /* parse file, store returned info in the xkb struct */
576 else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
578 InitKeyNamesInfo(&included);
579 HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
580 if (stmt->stmt != NULL)
582 if (included.name != NULL)
584 included.name = stmt->stmt;
590 info->errorCount += 10; /* XXX: why 10?? */
593 /* Do we have more than one include statement? */
594 if ((stmt->next != NULL) && (included.errorCount < 1))
598 KeyNamesInfo next_incl;
600 for (next = stmt->next; next != NULL; next = next->next)
602 if ((next->file == NULL) && (next->map == NULL))
605 MergeIncludedKeycodes(&included, info, next->merge);
606 ClearKeyNamesInfo(info);
608 else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
610 InitKeyNamesInfo(&next_incl);
611 HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
612 MergeIncludedKeycodes(&included, &next_incl, op);
613 ClearKeyNamesInfo(&next_incl);
617 info->errorCount += 10; /* XXX: Why 10?? */
618 ClearKeyNamesInfo(&included);
627 MergeIncludedKeycodes(info, &included, newMerge);
628 ClearKeyNamesInfo(&included);
630 return (info->errorCount == 0);
634 * Parse the given statement and store the output in the info struct.
638 HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
640 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
641 (info->explicitMax != 0 && stmt->value > info->explicitMax))
643 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
644 ACTION("Must be in the range %d-%d inclusive\n",
646 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
649 if (stmt->merge != MergeDefault)
651 if (stmt->merge == MergeReplace)
652 merge = MergeOverride;
656 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
660 #define MIN_KEYCODE_DEF 0
661 #define MAX_KEYCODE_DEF 1
664 * Handle the minimum/maximum statement of the xkb file.
665 * Sets explicitMin/Max of the info struct.
667 * @return 1 on success, 0 otherwise.
670 HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
672 ExprResult tmp, field;
676 if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
677 return 0; /* internal error, already reported */
681 ERROR("Unknown element %s encountered\n", tmp.str);
682 ACTION("Default for field %s ignored\n", field.str);
685 if (uStrCaseCmp(field.str, "minimum") == 0)
686 which = MIN_KEYCODE_DEF;
687 else if (uStrCaseCmp(field.str, "maximum") == 0)
688 which = MAX_KEYCODE_DEF;
691 ERROR("Unknown field encountered\n");
692 ACTION("Assigment to field %s ignored\n", field.str);
695 if (arrayNdx != NULL)
697 ERROR("The %s setting is not an array\n", field.str);
698 ACTION("Illegal array reference ignored\n");
702 if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
704 ACTION("Assignment to field %s ignored\n", field.str);
707 if (tmp.uval > XKB_KEYCODE_MAX)
710 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
711 tmp.uval, 0, XKB_KEYCODE_MAX);
712 ACTION("Value of \"%s\" not changed\n", field.str);
715 if (which == MIN_KEYCODE_DEF)
717 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
720 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
721 tmp.uval, info->explicitMax);
722 ACTION("Minimum key code value not changed\n");
725 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
728 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
729 tmp.uval, info->computedMin);
730 ACTION("Minimum key code value not changed\n");
733 info->explicitMin = tmp.uval;
735 if (which == MAX_KEYCODE_DEF)
737 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
739 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
740 tmp.uval, info->explicitMin);
741 ACTION("Maximum code value not changed\n");
744 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
747 ("Maximum code (%d) must be >= highest defined key (%d)\n",
748 tmp.uval, info->computedMax);
749 ACTION("Maximum code value not changed\n");
752 info->explicitMax = tmp.uval;
758 HandleIndicatorNameDef(IndicatorNameDef * def,
759 unsigned merge, KeyNamesInfo * info)
761 IndicatorNameInfo ii;
764 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
767 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
771 InitIndicatorNameInfo(&ii, info);
773 if (!ExprResolveString(def->name, &tmp, NULL, NULL))
776 snprintf(buf, sizeof(buf), "%d", def->ndx);
778 return ReportBadType("indicator", "name", buf, "string");
780 ii.name = xkb_intern_atom(tmp.str);
782 ii.virtual = def->virtual;
783 if (!AddIndicatorName(info, &ii))
789 * Handle the xkb_keycodes section of a xkb file.
790 * All information about parsed keys is stored in the info struct.
792 * Such a section may have include statements, in which case this function is
793 * semi-recursive (it calls HandleIncludeKeycodes, which may call
794 * HandleKeycodesFile again).
796 * @param file The input file (parsed xkb_keycodes section)
797 * @param xkb Necessary to pass down, may have flags changed.
798 * @param merge Merge strategy (MergeOverride, etc.)
799 * @param info Struct to contain the fully parsed key information.
802 HandleKeycodesFile(XkbFile * file,
803 struct xkb_desc * xkb, unsigned merge, KeyNamesInfo * info)
807 info->name = _XkbDupString(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,
839 ERROR("Keycode files may define key and indicator names only\n");
840 ACTION("Ignoring definition of %s\n",
842 StmtInterpDef) ? "a symbol interpretation" :
843 "virtual modifiers"));
847 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
852 if (info->errorCount > 10)
855 ERROR("Too many errors\n");
857 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
865 * Compile the xkb_keycodes section, parse it's output, return the results.
867 * @param file The parsed XKB file (may have include statements requiring
869 * @param result The effective keycodes, as gathered from the file.
870 * @param merge Merge strategy.
872 * @return True on success, False otherwise.
875 CompileKeycodes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
877 KeyNamesInfo info; /* contains all the info after parsing */
879 InitKeyNamesInfo(&info);
880 HandleKeycodesFile(file, xkb, merge, &info);
882 /* all the keys are now stored in info */
884 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;
890 if (info.explicitMax > 0) /* if "maximum" statement was present */
891 xkb->max_key_code = info.explicitMax;
893 xkb->max_key_code = info.computedMax;
894 if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0)
898 xkb->names->keycodes = xkb_intern_atom(info.name);
899 for (i = info.computedMin; i <= info.computedMax; i++)
901 LongToKeyName(info.names[i], xkb->names->keys[i].name);
906 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
911 IndicatorNameInfo *ii;
912 if (XkbcAllocIndicatorMaps(xkb) != Success)
914 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
915 ACTION("Physical indicators not set\n");
917 for (ii = info.leds; ii != NULL;
918 ii = (IndicatorNameInfo *) ii->defs.next)
920 xkb->names->indicators[ii->ndx - 1] = ii->name;
921 if (xkb->indicators != NULL)
923 register unsigned bit;
924 bit = 1 << (ii->ndx - 1);
926 xkb->indicators->phys_indicators &= ~bit;
928 xkb->indicators->phys_indicators |= bit;
933 ApplyAliases(xkb, False, &info.aliases);
936 ClearKeyNamesInfo(&info);