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 ********************************************************/
36 longText(unsigned long val)
40 LongToKeyName(val, buf);
41 return XkbcKeyNameText(buf);
44 /***====================================================================***/
47 LongToKeyName(unsigned long val, char *name)
49 name[0] = ((val >> 24) & 0xff);
50 name[1] = ((val >> 16) & 0xff);
51 name[2] = ((val >> 8) & 0xff);
52 name[3] = (val & 0xff);
55 /***====================================================================***/
57 typedef struct _IndicatorNameInfo
65 typedef struct _KeyNamesInfo
67 char *name; /* e.g. evdev+aliases(qwerty) */
71 xkb_keycode_t computedMin; /* lowest keycode stored */
72 xkb_keycode_t computedMax; /* highest keycode stored */
73 xkb_keycode_t explicitMin;
74 xkb_keycode_t explicitMax;
75 xkb_keycode_t arraySize;
78 unsigned char *has_alt_forms;
79 IndicatorNameInfo *leds;
83 static void HandleKeycodesFile(XkbFile * file,
84 struct xkb_desc * xkb,
89 ResizeKeyNameArrays(KeyNamesInfo *info, int newMax)
94 tmp = _XkbTypedRealloc(info->names, newMax + 1, unsigned long);
97 ("Couldn't reallocate for larger maximum keycode (%d)\n",
99 ACTION("Maximum key value not changed\n");
103 for (i = info->arraySize + 1; i <= newMax; i++)
106 tmp = _XkbTypedRealloc(info->files, newMax + 1, unsigned);
109 ("Couldn't reallocate for larger maximum keycode (%d)\n",
111 ACTION("Maximum key value not changed\n");
115 for (i = info->arraySize + 1; i <= newMax; i++)
118 tmp = _XkbTypedRealloc(info->has_alt_forms, newMax + 1, unsigned char);
121 ("Couldn't reallocate for larger maximum keycode (%d)\n",
123 ACTION("Maximum key value not changed\n");
126 info->has_alt_forms = tmp;
127 for (i = info->arraySize + 1; i <= newMax; i++)
128 info->has_alt_forms[i] = 0;
130 info->arraySize = newMax;
136 InitIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
138 ii->defs.defined = 0;
139 ii->defs.merge = info->merge;
140 ii->defs.fileID = info->fileID;
141 ii->defs.next = NULL;
148 ClearIndicatorNameInfo(IndicatorNameInfo * ii, KeyNamesInfo * info)
150 if (ii == info->leds)
152 ClearCommonInfo(&ii->defs);
157 static IndicatorNameInfo *
158 NextIndicatorName(KeyNamesInfo * info)
160 IndicatorNameInfo *ii;
162 ii = uTypedAlloc(IndicatorNameInfo);
165 InitIndicatorNameInfo(ii, info);
166 info->leds = (IndicatorNameInfo *) AddCommonInfo(&info->leds->defs,
172 static IndicatorNameInfo *
173 FindIndicatorByIndex(KeyNamesInfo * info, int ndx)
175 IndicatorNameInfo *old;
177 for (old = info->leds; old != NULL;
178 old = (IndicatorNameInfo *) old->defs.next)
186 static IndicatorNameInfo *
187 FindIndicatorByName(KeyNamesInfo * info, uint32_t name)
189 IndicatorNameInfo *old;
191 for (old = info->leds; old != NULL;
192 old = (IndicatorNameInfo *) old->defs.next)
194 if (old->name == name)
201 AddIndicatorName(KeyNamesInfo * info, IndicatorNameInfo * new)
203 IndicatorNameInfo *old;
206 replace = (new->defs.merge == MergeReplace) ||
207 (new->defs.merge == MergeOverride);
208 old = FindIndicatorByName(info, new->name);
211 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
212 || (warningLevel > 9))
214 WARN("Multiple indicators named %s\n", XkbcAtomText(new->name));
215 if (old->ndx == new->ndx)
217 if (old->virtual != new->virtual)
220 old->virtual = new->virtual;
221 ACTION("Using %s instead of %s\n",
222 (old->virtual ? "virtual" : "real"),
223 (old->virtual ? "real" : "virtual"));
227 ACTION("Identical definitions ignored\n");
234 ACTION("Ignoring %d, using %d\n", old->ndx, new->ndx);
236 ACTION("Using %d, ignoring %d\n", old->ndx, new->ndx);
240 if (info->leds == old)
241 info->leds = (IndicatorNameInfo *) old->defs.next;
244 IndicatorNameInfo *tmp;
247 tmp = (IndicatorNameInfo *) tmp->defs.next)
249 if (tmp->defs.next == (CommonInfo *) old)
251 tmp->defs.next = old->defs.next;
260 old = FindIndicatorByIndex(info, new->ndx);
263 if (((old->defs.fileID == new->defs.fileID) && (warningLevel > 0))
264 || (warningLevel > 9))
266 WARN("Multiple names for indicator %d\n", new->ndx);
267 if ((old->name == new->name) && (old->virtual == new->virtual))
268 ACTION("Identical definitions ignored\n");
271 const char *oldType, *newType;
272 uint32_t using, ignoring;
274 oldType = "virtual indicator";
276 oldType = "real indicator";
278 newType = "virtual indicator";
280 newType = "real indicator";
284 ignoring = old->name;
289 ignoring = new->name;
291 ACTION("Using %s %s, ignoring %s %s\n",
292 oldType, XkbcAtomText(using),
293 newType, XkbcAtomText(ignoring));
298 old->name = new->name;
299 old->virtual = new->virtual;
304 new = NextIndicatorName(info);
307 WSGO("Couldn't allocate name for indicator %d\n", old->ndx);
311 new->name = old->name;
313 new->virtual = old->virtual;
318 ClearKeyNamesInfo(KeyNamesInfo * info)
322 info->computedMax = info->explicitMax = info->explicitMin = 0;
323 info->computedMin = XKB_KEYCODE_MAX;
329 free(info->has_alt_forms);
330 info->has_alt_forms = NULL;
332 ClearIndicatorNameInfo(info->leds, info);
334 ClearAliases(&info->aliases);
338 InitKeyNamesInfo(KeyNamesInfo * info)
342 info->aliases = NULL;
345 info->has_alt_forms = NULL;
346 ClearKeyNamesInfo(info);
347 info->errorCount = 0;
351 FindKeyByLong(KeyNamesInfo * info, unsigned long name)
355 for (i = info->computedMin; i <= info->computedMax; i++)
357 if (info->names[i] == name)
364 * Store the name of the key as a long in the info struct under the given
365 * keycode. If the same keys is referred to twice, print a warning.
366 * Note that the key's name is stored as a long, the keycode is the index.
369 AddKeyName(KeyNamesInfo * info,
371 char *name, unsigned merge, unsigned fileID, Bool reportCollisions)
376 if (kc > info->arraySize && !ResizeKeyNameArrays(info, kc)) {
377 ERROR("Couldn't resize KeyNames arrays for keycode %d\n", kc);
378 ACTION("Ignoring key %d\n", kc);
381 if (kc < info->computedMin)
382 info->computedMin = kc;
383 if (kc > info->computedMax)
384 info->computedMax = kc;
385 lval = KeyNameToLong(name);
387 if (reportCollisions)
389 reportCollisions = ((warningLevel > 7) ||
391 && (fileID == info->files[kc])));
394 if (info->names[kc] != 0)
398 LongToKeyName(info->names[kc], buf);
400 if (info->names[kc] == lval)
402 if (info->has_alt_forms[kc] || (merge == MergeAltForm))
404 info->has_alt_forms[kc] = True;
406 else if (reportCollisions)
408 WARN("Multiple identical key name definitions\n");
409 ACTION("Later occurences of \"<%s> = %d\" ignored\n",
414 if (merge == MergeAugment)
416 if (reportCollisions)
418 WARN("Multiple names for keycode %d\n", kc);
419 ACTION("Using <%s>, ignoring <%s>\n", buf, name);
425 if (reportCollisions)
427 WARN("Multiple names for keycode %d\n", kc);
428 ACTION("Using <%s>, ignoring <%s>\n", name, buf);
434 old = FindKeyByLong(info, lval);
435 if ((old != 0) && (old != kc))
437 if (merge == MergeOverride)
439 info->names[old] = 0;
440 info->files[old] = 0;
441 info->has_alt_forms[old] = True;
442 if (reportCollisions)
444 WARN("Key name <%s> assigned to multiple keys\n", name);
445 ACTION("Using %d, ignoring %d\n", kc, old);
448 else if (merge != MergeAltForm)
450 if ((reportCollisions) && (warningLevel > 3))
452 WARN("Key name <%s> assigned to multiple keys\n", name);
453 ACTION("Using %d, ignoring %d\n", old, kc);
455 ("Use 'alternate' keyword to assign the same name to multiple keys\n");
461 info->has_alt_forms[old] = True;
464 info->names[kc] = lval;
465 info->files[kc] = fileID;
466 info->has_alt_forms[kc] = (merge == MergeAltForm);
470 /***====================================================================***/
473 MergeIncludedKeycodes(KeyNamesInfo * into, KeyNamesInfo * from,
479 if (from->errorCount > 0)
481 into->errorCount += from->errorCount;
484 if (into->name == NULL)
486 into->name = from->name;
489 if (from->computedMax > into->arraySize &&
490 !ResizeKeyNameArrays(into, from->computedMax)) {
491 ERROR("Couldn't resize KeyNames arrays for key %d\n",
493 ACTION("Ignoring include file %s\n", from->name);
494 into->errorCount += 10;
497 for (i = from->computedMin; i <= from->computedMax; i++)
500 if (from->names[i] == 0)
502 LongToKeyName(from->names[i], buf);
504 if (from->has_alt_forms[i])
505 thisMerge = MergeAltForm;
508 if (!AddKeyName(into, i, buf, thisMerge, from->fileID, False))
513 IndicatorNameInfo *led, *next;
514 for (led = from->leds; led != NULL; led = next)
516 if (merge != MergeDefault)
517 led->defs.merge = merge;
518 if (!AddIndicatorName(into, led))
520 next = (IndicatorNameInfo *) led->defs.next;
523 if (!MergeAliases(&into->aliases, &from->aliases, merge))
525 if (from->explicitMin != 0)
527 if ((into->explicitMin == 0)
528 || (into->explicitMin > from->explicitMin))
529 into->explicitMin = from->explicitMin;
531 if (from->explicitMax > 0)
533 if ((into->explicitMax == 0)
534 || (into->explicitMax < from->explicitMax))
535 into->explicitMax = from->explicitMax;
540 * Handle the given include statement (e.g. "include "evdev+aliases(qwerty)").
542 * @param stmt The include statement from the keymap file.
543 * @param xkb Unused for all but the xkb->flags.
544 * @param info Struct to store the key info in.
547 HandleIncludeKeycodes(IncludeStmt * stmt, struct xkb_desc * xkb, KeyNamesInfo * info)
551 KeyNamesInfo included = {NULL};
555 if ((stmt->file == NULL) && (stmt->map == NULL))
559 bzero(info, sizeof(KeyNamesInfo));
561 else if (stmt->file && strcmp(stmt->file, "computed") == 0)
563 xkb->flags |= AutoKeyNames;
564 info->explicitMin = 0;
565 info->explicitMax = XKB_KEYCODE_MAX;
566 return (info->errorCount == 0);
567 } /* parse file, store returned info in the xkb struct */
568 else if (ProcessIncludeFile(stmt, XkmKeyNamesIndex, &rtrn, &newMerge))
570 InitKeyNamesInfo(&included);
571 HandleKeycodesFile(rtrn, xkb, MergeOverride, &included);
572 if (stmt->stmt != NULL)
575 included.name = stmt->stmt;
581 info->errorCount += 10; /* XXX: why 10?? */
584 /* Do we have more than one include statement? */
585 if ((stmt->next != NULL) && (included.errorCount < 1))
589 KeyNamesInfo next_incl;
591 for (next = stmt->next; next != NULL; next = next->next)
593 if ((next->file == NULL) && (next->map == NULL))
596 MergeIncludedKeycodes(&included, info, next->merge);
597 ClearKeyNamesInfo(info);
599 else if (ProcessIncludeFile(next, XkmKeyNamesIndex, &rtrn, &op))
601 InitKeyNamesInfo(&next_incl);
602 HandleKeycodesFile(rtrn, xkb, MergeOverride, &next_incl);
603 MergeIncludedKeycodes(&included, &next_incl, op);
604 ClearKeyNamesInfo(&next_incl);
608 info->errorCount += 10; /* XXX: Why 10?? */
609 ClearKeyNamesInfo(&included);
618 MergeIncludedKeycodes(info, &included, newMerge);
619 ClearKeyNamesInfo(&included);
621 return (info->errorCount == 0);
625 * Parse the given statement and store the output in the info struct.
629 HandleKeycodeDef(KeycodeDef * stmt, unsigned merge, KeyNamesInfo * info)
631 if ((info->explicitMin != 0 && stmt->value < info->explicitMin) ||
632 (info->explicitMax != 0 && stmt->value > info->explicitMax))
634 ERROR("Illegal keycode %lu for name <%s>\n", stmt->value, stmt->name);
635 ACTION("Must be in the range %d-%d inclusive\n",
637 info->explicitMax ? info->explicitMax : XKB_KEYCODE_MAX);
640 if (stmt->merge != MergeDefault)
642 if (stmt->merge == MergeReplace)
643 merge = MergeOverride;
647 return AddKeyName(info, stmt->value, stmt->name, merge, info->fileID,
651 #define MIN_KEYCODE_DEF 0
652 #define MAX_KEYCODE_DEF 1
655 * Handle the minimum/maximum statement of the xkb file.
656 * Sets explicitMin/Max of the info struct.
658 * @return 1 on success, 0 otherwise.
661 HandleKeyNameVar(VarDef * stmt, KeyNamesInfo * info)
663 ExprResult tmp, field;
667 if (ExprResolveLhs(stmt->name, &tmp, &field, &arrayNdx) == 0)
668 return 0; /* internal error, already reported */
672 ERROR("Unknown element %s encountered\n", tmp.str);
673 ACTION("Default for field %s ignored\n", field.str);
676 if (uStrCaseCmp(field.str, "minimum") == 0)
677 which = MIN_KEYCODE_DEF;
678 else if (uStrCaseCmp(field.str, "maximum") == 0)
679 which = MAX_KEYCODE_DEF;
682 ERROR("Unknown field encountered\n");
683 ACTION("Assigment to field %s ignored\n", field.str);
686 if (arrayNdx != NULL)
688 ERROR("The %s setting is not an array\n", field.str);
689 ACTION("Illegal array reference ignored\n");
693 if (ExprResolveKeyCode(stmt->value, &tmp) == 0)
695 ACTION("Assignment to field %s ignored\n", field.str);
698 if (tmp.uval > XKB_KEYCODE_MAX)
701 ("Illegal keycode %d (must be in the range %d-%d inclusive)\n",
702 tmp.uval, 0, XKB_KEYCODE_MAX);
703 ACTION("Value of \"%s\" not changed\n", field.str);
706 if (which == MIN_KEYCODE_DEF)
708 if ((info->explicitMax > 0) && (info->explicitMax < tmp.uval))
711 ("Minimum key code (%d) must be <= maximum key code (%d)\n",
712 tmp.uval, info->explicitMax);
713 ACTION("Minimum key code value not changed\n");
716 if ((info->computedMax > 0) && (info->computedMin < tmp.uval))
719 ("Minimum key code (%d) must be <= lowest defined key (%d)\n",
720 tmp.uval, info->computedMin);
721 ACTION("Minimum key code value not changed\n");
724 info->explicitMin = tmp.uval;
726 if (which == MAX_KEYCODE_DEF)
728 if ((info->explicitMin > 0) && (info->explicitMin > tmp.uval))
730 ERROR("Maximum code (%d) must be >= minimum key code (%d)\n",
731 tmp.uval, info->explicitMin);
732 ACTION("Maximum code value not changed\n");
735 if ((info->computedMax > 0) && (info->computedMax > tmp.uval))
738 ("Maximum code (%d) must be >= highest defined key (%d)\n",
739 tmp.uval, info->computedMax);
740 ACTION("Maximum code value not changed\n");
743 info->explicitMax = tmp.uval;
749 HandleIndicatorNameDef(IndicatorNameDef * def,
750 unsigned merge, KeyNamesInfo * info)
752 IndicatorNameInfo ii;
755 if ((def->ndx < 1) || (def->ndx > XkbNumIndicators))
758 ERROR("Name specified for illegal indicator index %d\n", def->ndx);
762 InitIndicatorNameInfo(&ii, info);
764 if (!ExprResolveString(def->name, &tmp))
767 snprintf(buf, sizeof(buf), "%d", def->ndx);
769 return ReportBadType("indicator", "name", buf, "string");
771 ii.name = xkb_intern_atom(tmp.str);
773 ii.virtual = def->virtual;
774 if (!AddIndicatorName(info, &ii))
780 * Handle the xkb_keycodes section of a xkb file.
781 * All information about parsed keys is stored in the info struct.
783 * Such a section may have include statements, in which case this function is
784 * semi-recursive (it calls HandleIncludeKeycodes, which may call
785 * HandleKeycodesFile again).
787 * @param file The input file (parsed xkb_keycodes section)
788 * @param xkb Necessary to pass down, may have flags changed.
789 * @param merge Merge strategy (MergeOverride, etc.)
790 * @param info Struct to contain the fully parsed key information.
793 HandleKeycodesFile(XkbFile * file,
794 struct xkb_desc * xkb, unsigned merge, KeyNamesInfo * info)
798 info->name = _XkbDupString(file->name);
802 switch (stmt->stmtType)
804 case StmtInclude: /* e.g. include "evdev+aliases(qwerty)" */
805 if (!HandleIncludeKeycodes((IncludeStmt *) stmt, xkb, info))
808 case StmtKeycodeDef: /* e.g. <ESC> = 9; */
809 if (!HandleKeycodeDef((KeycodeDef *) stmt, merge, info))
812 case StmtKeyAliasDef: /* e.g. alias <MENU> = <COMP>; */
813 if (!HandleAliasDef((KeyAliasDef *) stmt,
814 merge, info->fileID, &info->aliases))
817 case StmtVarDef: /* e.g. minimum, maximum */
818 if (!HandleKeyNameVar((VarDef *) stmt, info))
821 case StmtIndicatorNameDef: /* e.g. indicator 1 = "Caps Lock"; */
822 if (!HandleIndicatorNameDef((IndicatorNameDef *) stmt,
830 ERROR("Keycode files may define key and indicator names only\n");
831 ACTION("Ignoring definition of %s\n",
833 StmtInterpDef) ? "a symbol interpretation" :
834 "virtual modifiers"));
838 WSGO("Unexpected statement type %d in HandleKeycodesFile\n",
843 if (info->errorCount > 10)
846 ERROR("Too many errors\n");
848 ACTION("Abandoning keycodes file \"%s\"\n", file->topName);
855 * Compile the xkb_keycodes section, parse it's output, return the results.
857 * @param file The parsed XKB file (may have include statements requiring
859 * @param result The effective keycodes, as gathered from the file.
860 * @param merge Merge strategy.
862 * @return True on success, False otherwise.
865 CompileKeycodes(XkbFile *file, struct xkb_desc * xkb, unsigned merge)
867 KeyNamesInfo info; /* contains all the info after parsing */
869 InitKeyNamesInfo(&info);
870 HandleKeycodesFile(file, xkb, merge, &info);
872 /* all the keys are now stored in info */
874 if (info.errorCount == 0)
876 if (info.explicitMin > 0) /* if "minimum" statement was present */
877 xkb->min_key_code = info.explicitMin;
879 xkb->min_key_code = info.computedMin;
880 if (info.explicitMax > 0) /* if "maximum" statement was present */
881 xkb->max_key_code = info.explicitMax;
883 xkb->max_key_code = info.computedMax;
884 if (XkbcAllocNames(xkb, XkbKeyNamesMask | XkbIndicatorNamesMask, 0, 0)
888 xkb->names->keycodes = xkb_intern_atom(info.name);
889 for (i = info.computedMin; i <= info.computedMax; i++)
891 LongToKeyName(info.names[i], xkb->names->keys[i].name);
896 WSGO("Cannot create struct xkb_names in CompileKeycodes\n");
901 IndicatorNameInfo *ii;
902 if (XkbcAllocIndicatorMaps(xkb) != Success)
904 WSGO("Couldn't allocate IndicatorRec in CompileKeycodes\n");
905 ACTION("Physical indicators not set\n");
907 for (ii = info.leds; ii != NULL;
908 ii = (IndicatorNameInfo *) ii->defs.next)
910 xkb->names->indicators[ii->ndx - 1] = ii->name;
911 if (xkb->indicators != NULL)
914 bit = 1 << (ii->ndx - 1);
916 xkb->indicators->phys_indicators &= ~bit;
918 xkb->indicators->phys_indicators |= bit;
923 ApplyAliases(xkb, False, &info.aliases);
926 ClearKeyNamesInfo(&info);