1 /************************************************************
2 Copyright (c) 1996 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 ********************************************************/
34 #include <X11/XKBlib.h>
35 #include <X11/extensions/XKBfile.h>
36 #include <X11/extensions/XKBconfig.h>
37 #include <X11/extensions/XKBrules.h>
41 #define PATH_MAX MAXPATHLEN
47 #ifndef DFLT_XKB_CONFIG_ROOT
48 #define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
50 #ifndef DFLT_XKB_RULES_FILE
51 #define DFLT_XKB_RULES_FILE "base"
53 #ifndef DFLT_XKB_LAYOUT
54 #define DFLT_XKB_LAYOUT "us"
56 #ifndef DFLT_XKB_MODEL
57 #define DFLT_XKB_MODEL "pc105"
60 /* Values used in svSrc to state how a value was obtained. The order of these
61 * is important, the bigger the higher the priority.
62 * e.g. FROM_CONFIG overrides FROM_SERVER */
64 #define FROM_SERVER 1 /* retrieved from server at runtime */
65 #define FROM_RULES 2 /* xkb rules file */
66 #define FROM_CONFIG 3 /* command-line specified config file */
67 #define FROM_CMD_LINE 4 /* specified at the cmdline */
70 /* Indices used into svSrc, svNValue */
71 #define RULES_NDX 0 /* rules file */
72 #define CONFIG_NDX 1 /* config file (if used) */
73 #define DISPLAY_NDX 2 /* X display name */
74 #define LOCALE_NDX 3 /* machine's locale */
78 #define KEYCODES_NDX 7
81 #define SYMBOLS_NDX 10
82 #define GEOMETRY_NDX 11
84 #define NUM_STRING_VALS 13
86 /***====================================================================***/
87 static Bool print = False;
88 static Bool query = False;
89 static Bool synch = False;
90 static int verbose = 5;
95 * human-readable versions of FROM_CONFIG, FROM_SERVER, etc. Used for error
98 static char *srcName[NUM_SOURCES] = {
99 "undefined", "X server", "rules file", "config file", "command line"
103 * human-readable versions for RULES_NDX, CONFIG_NDX, etc. Used for error
106 static char *svName[NUM_STRING_VALS] = {
107 "rules file", "config file", "X display", "locale",
108 "keyboard model", "keyboard layout", "layout variant",
109 "keycodes", "types", "compatibility map", "symbols", "geometry",
113 * Holds the source for each of RULES, CONFIG, DISPLAY, etc.
114 * i.e. if svSrc[LAYOUT_NDX] == FROM_SERVER, then the layout has been fetched
117 static int svSrc[NUM_STRING_VALS];
119 * Holds the value for each of RULES, CONFIG, DISPLAY, etc.
121 static char *svValue[NUM_STRING_VALS];
123 static XkbConfigRtrnRec cfgResult;
125 static XkbRF_RulesPtr rules = NULL;
126 static XkbRF_VarDefsRec rdefs;
128 static Bool clearOptions = False;
129 static int szOptions = 0;
130 static int numOptions = 0;
131 static char **options = NULL;
133 static int szInclPath = 0;
134 static int numInclPath = 0;
135 static char **inclPath = NULL;
137 static XkbDescPtr xkb = NULL;
139 static int deviceSpec = XkbUseCoreKbd;
141 /***====================================================================***/
143 #define streq(s1,s2) (strcmp(s1,s2)==0)
144 #define strpfx(s1,s2) (strncmp(s1,s2,strlen(s2))==0)
146 #define MSG(s) printf(s)
147 #define MSG1(s,a) printf(s,a)
148 #define MSG2(s,a,b) printf(s,a,b)
149 #define MSG3(s,a,b,c) printf(s,a,b,c)
151 #define VMSG(l,s) if (verbose>(l)) printf(s)
152 #define VMSG1(l,s,a) if (verbose>(l)) printf(s,a)
153 #define VMSG2(l,s,a,b) if (verbose>(l)) printf(s,a,b)
154 #define VMSG3(l,s,a,b,c) if (verbose>(l)) printf(s,a,b,c)
156 #define ERR(s) fprintf(stderr,s)
157 #define ERR1(s,a) fprintf(stderr,s,a)
158 #define ERR2(s,a,b) fprintf(stderr,s,a,b)
159 #define ERR3(s,a,b,c) fprintf(stderr,s,a,b,c)
161 /***====================================================================***/
163 Bool addToList(int *sz, int *num, char ***listIn, char *newVal);
164 void usage(int argc, char **argv);
165 void dumpNames(Bool wantRules, Bool wantCNames);
166 void trySetString(int which, char *newVal, int src);
167 Bool setOptString(int *arg, int argc, char **argv, int which, int src);
168 int parseArgs(int argc, char **argv);
169 Bool getDisplay(int argc, char **argv);
170 Bool getServerValues(void);
171 FILE *findFileInPath(char *name, char *subdir);
172 Bool addStringToOptions(char *opt_str, int *sz_opts, int *num_opts,
174 char *stringFromOptions(char *orig, int numNew, char **newOpts);
175 Bool applyConfig(char *name);
176 Bool applyRules(void);
177 Bool applyComponentNames(void);
178 void printKeymap(void);
180 /***====================================================================***/
183 addToList(int *sz, int *num, char ***listIn, char *newVal)
188 if ((!newVal) || (!newVal[0]))
194 for (i = 0; i < *num; i++)
196 if (streq(list[i], newVal))
199 if ((list == NULL) || (*sz < 1))
203 list = (char **) calloc(*sz, sizeof(char *));
206 else if (*num >= *sz)
209 list = (char **) realloc(list, (*sz) * sizeof(char *));
214 ERR("Internal Error! Allocation failure in add to list!\n");
218 list[*num] = strdup(newVal);
223 /***====================================================================***/
226 usage(int argc, char **argv)
228 MSG1("Usage: %s [args] [<layout> [<variant> [<option> ... ]]]\n",
230 MSG("Where legal args are:\n");
231 MSG("-?,-help Print this message\n");
232 MSG("-compat <name> Specifies compatibility map component name\n");
233 MSG("-config <file> Specifies configuration file to use\n");
234 MSG("-device <deviceid> Specifies the device ID to use\n");
235 MSG("-display <dpy> Specifies display to use\n");
236 MSG("-geometry <name> Specifies geometry component name\n");
237 MSG("-I[<dir>] Add <dir> to list of directories to be used\n");
238 MSG("-keycodes <name> Specifies keycodes component name\n");
239 MSG("-keymap <name> Specifies name of keymap to load\n");
240 MSG("-layout <name> Specifies layout used to choose component names\n");
241 MSG("-model <name> Specifies model used to choose component names\n");
242 MSG("-option <name> Adds an option used to choose component names\n");
243 MSG("-print Print a complete xkb_keymap description and exit\n");
244 MSG("-query Print the current layout settings and exit\n");
245 MSG("-rules <name> Name of rules file to use\n");
246 MSG("-symbols <name> Specifies symbols component name\n");
247 MSG("-synch Synchronize request w/X server\n");
248 MSG("-types <name> Specifies types component name\n");
249 MSG("-v[erbose] [<lvl>] Sets verbosity (1..10). Higher values yield\n");
250 MSG(" more messages\n");
251 MSG("-variant <name> Specifies layout variant used to choose component names\n");
255 dumpNames(Bool wantRules, Bool wantCNames)
259 if (svValue[RULES_NDX])
260 MSG1("rules: %s\n", svValue[RULES_NDX]);
261 if (svValue[MODEL_NDX])
262 MSG1("model: %s\n", svValue[MODEL_NDX]);
263 if (svValue[LAYOUT_NDX])
264 MSG1("layout: %s\n", svValue[LAYOUT_NDX]);
265 if (svValue[VARIANT_NDX])
266 MSG1("variant: %s\n", svValue[VARIANT_NDX]);
269 char *opt_str = stringFromOptions(NULL, numOptions, options);
270 MSG1("options: %s\n", opt_str);
276 if (svValue[KEYMAP_NDX])
277 MSG1("keymap: %s\n", svValue[KEYMAP_NDX]);
278 if (svValue[KEYCODES_NDX])
279 MSG1("keycodes: %s\n", svValue[KEYCODES_NDX]);
280 if (svValue[TYPES_NDX])
281 MSG1("types: %s\n", svValue[TYPES_NDX]);
282 if (svValue[COMPAT_NDX])
283 MSG1("compat: %s\n", svValue[COMPAT_NDX]);
284 if (svValue[SYMBOLS_NDX])
285 MSG1("symbols: %s\n", svValue[SYMBOLS_NDX]);
286 if (svValue[GEOMETRY_NDX])
287 MSG1("geometry: %s\n", svValue[GEOMETRY_NDX]);
292 /***====================================================================***/
295 * Set the given string (obtained from src) in the svValue/svSrc globals.
296 * If the given item is already set, it is overridden if the original source
297 * is less significant than the given one.
299 * @param which What value is it (one of RULES_NDX, CONFIG_NDX, ...)
302 trySetString(int which, char *newVal, int src)
304 if (svValue[which] != NULL)
306 if (svSrc[which] == src)
308 VMSG2(0, "Warning! More than one %s from %s\n",
309 svName[which], srcName[src]);
310 VMSG2(0, " Using \"%s\", ignoring \"%s\"\n",
311 svValue[which], newVal);
314 else if (svSrc[which] > src)
316 VMSG1(5, "Warning! Multiple definitions of %s\n", svName[which]);
317 VMSG2(5, " Using %s, ignoring %s\n",
318 srcName[svSrc[which]], srcName[src]);
323 svValue[which] = newVal;
328 setOptString(int *arg, int argc, char **argv, int which, int src)
337 VMSG1(0, "No %s specified on the command line\n", svName[which]);
338 VMSG1(0, "Trailing %s option ignored\n", opt);
343 if (svValue[which] != NULL)
345 if (svSrc[which] == src)
347 VMSG2(0, "More than one %s on %s\n", svName[which], srcName[src]);
348 VMSG2(0, "Using \"%s\", ignoring \"%s\"\n", svValue[which],
352 else if (svSrc[which] > src)
354 VMSG1(5, "Multiple definitions of %s\n", svName[which]);
355 VMSG2(5, "Using %s, ignoring %s\n", srcName[svSrc[which]],
361 svValue[which] = argv[ndx];
365 /***====================================================================***/
368 * Parse commandline arguments.
369 * Return True on success or False if an unrecognized option has been
373 parseArgs(int argc, char **argv)
380 addToList(&szInclPath, &numInclPath, &inclPath, ".");
381 addToList(&szInclPath, &numInclPath, &inclPath, DFLT_XKB_CONFIG_ROOT);
382 for (i = 1; (i < argc) && ok; i++)
384 if (argv[i][0] != '-')
386 /* Allow a call like "setxkbmap us" to work. Layout is default,
387 if -layout is given, then try parsing variant, then options */
388 if (!svSrc[LAYOUT_NDX])
389 trySetString(LAYOUT_NDX, argv[i], FROM_CMD_LINE);
390 else if (!svSrc[VARIANT_NDX])
391 trySetString(VARIANT_NDX, argv[i], FROM_CMD_LINE);
393 ok = addToList(&szOptions, &numOptions, &options, argv[i]);
395 else if (streq(argv[i], "-compat"))
396 ok = setOptString(&i, argc, argv, COMPAT_NDX, FROM_CMD_LINE);
397 else if (streq(argv[i], "-config"))
398 ok = setOptString(&i, argc, argv, CONFIG_NDX, FROM_CMD_LINE);
399 else if (streq(argv[i], "-device"))
400 deviceSpec = atoi(argv[++i]); /* only allow device IDs, not names */
401 else if (streq(argv[i], "-display"))
402 ok = setOptString(&i, argc, argv, DISPLAY_NDX, FROM_CMD_LINE);
403 else if (streq(argv[i], "-geometry"))
404 ok = setOptString(&i, argc, argv, GEOMETRY_NDX, FROM_CMD_LINE);
405 else if (streq(argv[i], "-help") || streq(argv[i], "-?"))
410 else if (strpfx(argv[i], "-I"))
411 ok = addToList(&szInclPath, &numInclPath, &inclPath, &argv[i][2]);
412 else if (streq(argv[i], "-keycodes"))
413 ok = setOptString(&i, argc, argv, KEYCODES_NDX, FROM_CMD_LINE);
414 else if (streq(argv[i], "-keymap"))
415 ok = setOptString(&i, argc, argv, KEYMAP_NDX, FROM_CMD_LINE);
416 else if (streq(argv[i], "-layout"))
417 ok = setOptString(&i, argc, argv, LAYOUT_NDX, FROM_CMD_LINE);
418 else if (streq(argv[i], "-model"))
419 ok = setOptString(&i, argc, argv, MODEL_NDX, FROM_CMD_LINE);
420 else if (streq(argv[i], "-option"))
422 if ((i == argc - 1) || (argv[i + 1][0] == '\0')
423 || (argv[i + 1][0] == '-'))
426 ok = addToList(&szOptions, &numOptions, &options, "");
427 if (i < argc - 1 && argv[i + 1][0] == '\0')
432 ok = addToList(&szOptions, &numOptions, &options, argv[++i]);
435 else if (streq(argv[i], "-print"))
437 else if (streq(argv[i], "-query"))
439 else if (streq(argv[i], "-rules"))
440 ok = setOptString(&i, argc, argv, RULES_NDX, FROM_CMD_LINE);
441 else if (streq(argv[i], "-symbols"))
442 ok = setOptString(&i, argc, argv, SYMBOLS_NDX, FROM_CMD_LINE);
443 else if (streq(argv[i], "-synch"))
445 else if (streq(argv[i], "-types"))
446 ok = setOptString(&i, argc, argv, TYPES_NDX, FROM_CMD_LINE);
447 else if (streq(argv[i], "-verbose") || (streq(argv[i], "-v")))
449 if ((i < argc - 1) && (isdigit(argv[i + 1][0])))
450 verbose = atoi(argv[++i]);
455 ERR1("Illegal verbose level %d. Reset to 0\n", verbose);
458 else if (verbose > 10)
460 ERR1("Illegal verbose level %d. Reset to 10\n", verbose);
463 VMSG1(7, "Setting verbose level to %d\n", verbose);
465 else if (streq(argv[i], "-variant"))
466 ok = setOptString(&i, argc, argv, VARIANT_NDX, FROM_CMD_LINE);
469 ERR1("Error! Option \"%s\" not recognized\n", argv[i]);
475 if (svValue[TYPES_NDX])
477 if (svValue[COMPAT_NDX])
479 if (svValue[SYMBOLS_NDX])
481 if (svValue[KEYCODES_NDX])
483 if (svValue[GEOMETRY_NDX])
485 if (svValue[CONFIG_NDX])
487 if (svValue[MODEL_NDX])
489 if (svValue[LAYOUT_NDX])
491 if (svValue[VARIANT_NDX])
493 if (svValue[KEYMAP_NDX] && present)
495 ERR("No other components can be specified when a keymap is present\n");
502 * Open a connection to the display and print error if it fails.
504 * @return True on success or False otherwise.
507 getDisplay(int argc, char **argv)
509 int major, minor, why;
511 major = XkbMajorVersion;
512 minor = XkbMinorVersion;
514 XkbOpenDisplay(svValue[DISPLAY_NDX], NULL, NULL, &major, &minor,
518 if (svValue[DISPLAY_NDX] == NULL)
519 svValue[DISPLAY_NDX] = getenv("DISPLAY");
520 if (svValue[DISPLAY_NDX] == NULL)
521 svValue[DISPLAY_NDX] = "default display";
524 case XkbOD_BadLibraryVersion:
525 ERR3("%s was compiled with XKB version %d.%02d\n", argv[0],
526 XkbMajorVersion, XkbMinorVersion);
527 ERR2("Xlib supports incompatible version %d.%02d\n",
530 case XkbOD_ConnectionRefused:
531 ERR1("Cannot open display \"%s\"\n", svValue[DISPLAY_NDX]);
533 case XkbOD_NonXkbServer:
534 ERR1("XKB extension not present on %s\n", svValue[DISPLAY_NDX]);
536 case XkbOD_BadServerVersion:
537 ERR3("%s was compiled with XKB version %d.%02d\n", argv[0],
538 XkbMajorVersion, XkbMinorVersion);
539 ERR3("Server %s uses incompatible version %d.%02d\n",
540 svValue[DISPLAY_NDX], major, minor);
543 ERR1("Unknown error %d from XkbOpenDisplay\n", why);
549 XSynchronize(dpy, True);
553 /***====================================================================***/
556 * Retrieve xkb values from the XKB_RULES_NAMES property and store their
557 * contents in svValues.
558 * If the property cannot be read, the built-in defaults are used.
563 getServerValues(void)
568 if (!XkbRF_GetNamesProp(dpy, &tmp, &vd) || !tmp)
570 VMSG1(3, "Couldn't interpret %s property\n", _XKB_RF_NAMES_PROP_ATOM);
571 tmp = DFLT_XKB_RULES_FILE;
572 vd.model = DFLT_XKB_MODEL;
573 vd.layout = DFLT_XKB_LAYOUT;
576 VMSG3(3, "Use defaults: rules - '%s' model - '%s' layout - '%s'\n",
577 tmp, vd.model, vd.layout);
580 trySetString(RULES_NDX, tmp, FROM_SERVER);
582 trySetString(MODEL_NDX, vd.model, FROM_SERVER);
584 trySetString(LAYOUT_NDX, vd.layout, FROM_SERVER);
586 trySetString(VARIANT_NDX, vd.variant, FROM_SERVER);
587 if ((vd.options) && (!clearOptions))
589 addStringToOptions(vd.options, &szOptions, &numOptions, &options);
595 /***====================================================================***/
598 findFileInPath(char *name, char *subdir)
606 fp = fopen(name, "r");
607 if ((verbose > 7) || ((!fp) && (verbose > 0)))
608 MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), name);
611 for (i = 0; (i < numInclPath); i++)
613 if ((strlen(inclPath[i]) + strlen(subdir) + strlen(name) + 2) >
616 VMSG3(0, "Path too long (%s/%s%s). Ignored.\n", inclPath[i],
620 sprintf(buf, "%s/%s%s", inclPath[i], subdir, name);
621 fp = fopen(name, "r");
622 if ((verbose > 7) || ((!fp) && (verbose > 5)))
623 MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), buf);
630 /***====================================================================***/
633 addStringToOptions(char *opt_str, int *sz_opts, int *num_opts, char ***opts)
635 char *tmp, *str, *next;
638 if ((str = strdup(opt_str)) == NULL)
640 for (tmp = str, next = NULL; (tmp && *tmp != '\0') && ok; tmp = next)
642 next = strchr(str, ',');
648 ok = addToList(sz_opts, num_opts, opts, tmp) && ok;
654 /***====================================================================***/
657 stringFromOptions(char *orig, int numNew, char **newOpts)
662 len = strlen(orig) + 1;
665 for (i = 0; i < numNew; i++)
668 len += strlen(newOpts[i]) + 1;
674 orig = (char *) realloc(orig, len);
677 ERR("OOM in stringFromOptions\n");
684 orig = (char *) calloc(len, 1);
687 ERR("OOM in stringFromOptions\n");
692 for (i = 0; i < numNew; i++)
699 strcat(orig, newOpts[i]);
702 strcpy(orig, newOpts[i]);
708 /***====================================================================***/
711 applyConfig(char *name)
716 if ((fp = findFileInPath(name, "")) == NULL)
718 ok = XkbCFParse(fp, XkbCFDflts, NULL, &cfgResult);
722 ERR1("Couldn't find configuration file \"%s\"\n", name);
725 if (cfgResult.rules_file)
727 trySetString(RULES_NDX, cfgResult.rules_file, FROM_CONFIG);
728 cfgResult.rules_file = NULL;
732 trySetString(MODEL_NDX, cfgResult.model, FROM_CONFIG);
733 cfgResult.model = NULL;
735 if (cfgResult.layout)
737 trySetString(LAYOUT_NDX, cfgResult.layout, FROM_CONFIG);
738 cfgResult.layout = NULL;
740 if (cfgResult.variant)
742 trySetString(VARIANT_NDX, cfgResult.variant, FROM_CONFIG);
743 cfgResult.variant = NULL;
745 if (cfgResult.options)
747 addStringToOptions(cfgResult.options, &szOptions, &numOptions,
749 cfgResult.options = NULL;
751 if (cfgResult.keymap)
753 trySetString(KEYMAP_NDX, cfgResult.keymap, FROM_CONFIG);
754 cfgResult.keymap = NULL;
756 if (cfgResult.keycodes)
758 trySetString(KEYCODES_NDX, cfgResult.keycodes, FROM_CONFIG);
759 cfgResult.keycodes = NULL;
761 if (cfgResult.geometry)
763 trySetString(GEOMETRY_NDX, cfgResult.geometry, FROM_CONFIG);
764 cfgResult.geometry = NULL;
766 if (cfgResult.symbols)
768 trySetString(SYMBOLS_NDX, cfgResult.symbols, FROM_CONFIG);
769 cfgResult.symbols = NULL;
773 trySetString(TYPES_NDX, cfgResult.types, FROM_CONFIG);
774 cfgResult.types = NULL;
776 if (cfgResult.compat)
778 trySetString(COMPAT_NDX, cfgResult.compat, FROM_CONFIG);
779 cfgResult.compat = NULL;
783 MSG("After config file:\n");
784 dumpNames(True, True);
790 * If any of model, layout, variant or options is specified, then compile the
793 * @return True on success or false otherwise.
801 if (svSrc[MODEL_NDX] || svSrc[LAYOUT_NDX] || svSrc[VARIANT_NDX]
805 XkbComponentNamesRec rnames;
807 if (svSrc[VARIANT_NDX] < svSrc[LAYOUT_NDX])
808 svValue[VARIANT_NDX] = NULL;
810 rdefs.model = svValue[MODEL_NDX];
811 rdefs.layout = svValue[LAYOUT_NDX];
812 rdefs.variant = svValue[VARIANT_NDX];
815 stringFromOptions(rdefs.options, numOptions, options);
817 if (svSrc[RULES_NDX])
818 rfName = svValue[RULES_NDX];
820 rfName = DFLT_XKB_RULES_FILE;
822 if (rfName[0] == '/')
824 rules = XkbRF_Load(rfName, svValue[LOCALE_NDX], True, True);
828 /* try to load rules files from all include paths until the first
830 for (i = 0; (i < numInclPath) && (!rules); i++)
832 if ((strlen(inclPath[i]) + strlen(rfName) + 8) > PATH_MAX)
834 VMSG2(0, "Path too long (%s/rules/%s). Ignored.\n",
835 inclPath[i], rfName);
838 sprintf(buf, "%s/rules/%s", inclPath[i], svValue[RULES_NDX]);
839 rules = XkbRF_Load(buf, svValue[LOCALE_NDX], True, True);
844 ERR1("Couldn't find rules file (%s) \n", svValue[RULES_NDX]);
847 /* Let the rules file to the magic, then update the svValues with
848 * those returned after processing the rules */
849 XkbRF_GetComponents(rules, &rdefs, &rnames);
852 trySetString(KEYCODES_NDX, rnames.keycodes, FROM_RULES);
853 rnames.keycodes = NULL;
857 trySetString(SYMBOLS_NDX, rnames.symbols, FROM_RULES);
858 rnames.symbols = NULL;
862 trySetString(TYPES_NDX, rnames.types, FROM_RULES);
867 trySetString(COMPAT_NDX, rnames.compat, FROM_RULES);
868 rnames.compat = NULL;
872 trySetString(GEOMETRY_NDX, rnames.geometry, FROM_RULES);
873 rnames.geometry = NULL;
877 trySetString(KEYMAP_NDX, rnames.keymap, FROM_RULES);
878 rnames.keymap = NULL;
882 MSG1("Applied rules from %s:\n", svValue[RULES_NDX]);
883 dumpNames(True, False);
886 else if (verbose > 6)
888 MSG("No rules variables specified. Rules file ignored\n");
893 /* Primitive sanity check - filter out 'map names' (inside parenthesis) */
894 /* that can confuse xkbcomp parser */
896 checkName(char *name, char *string)
898 char *i = name, *opar = NULL;
913 if ((*i == '(') || (*i == '|') || (*i == '+'))
929 for (i = opar + 1; *i && n; i++)
940 ERR1("Illegal map name '%s' ", opar);
942 ERR2("in %s name '%s'\n", string, name);
950 MSG("xkb_keymap {\n");
951 if (svValue[KEYCODES_NDX])
952 MSG1("\txkb_keycodes { include \"%s\"\t};\n", svValue[KEYCODES_NDX]);
953 if (svValue[TYPES_NDX])
954 MSG1("\txkb_types { include \"%s\"\t};\n", svValue[TYPES_NDX]);
955 if (svValue[COMPAT_NDX])
956 MSG1("\txkb_compat { include \"%s\"\t};\n", svValue[COMPAT_NDX]);
957 if (svValue[SYMBOLS_NDX])
958 MSG1("\txkb_symbols { include \"%s\"\t};\n", svValue[SYMBOLS_NDX]);
959 if (svValue[GEOMETRY_NDX])
960 MSG1("\txkb_geometry { include \"%s\"\t};\n", svValue[GEOMETRY_NDX]);
965 applyComponentNames(void)
967 if (!checkName(svValue[TYPES_NDX], "types"))
969 if (!checkName(svValue[COMPAT_NDX], "compat"))
971 if (!checkName(svValue[SYMBOLS_NDX], "symbols"))
973 if (!checkName(svValue[KEYCODES_NDX], "keycodes"))
975 if (!checkName(svValue[GEOMETRY_NDX], "geometry"))
977 if (!checkName(svValue[KEYMAP_NDX], "keymap"))
982 MSG("Trying to build keymap using the following components:\n");
983 dumpNames(False, True);
985 /* Upload the new description to the server. */
986 if (dpy && !print && !query)
988 XkbComponentNamesRec cmdNames;
989 cmdNames.types = svValue[TYPES_NDX];
990 cmdNames.compat = svValue[COMPAT_NDX];
991 cmdNames.symbols = svValue[SYMBOLS_NDX];
992 cmdNames.keycodes = svValue[KEYCODES_NDX];
993 cmdNames.geometry = svValue[GEOMETRY_NDX];
994 cmdNames.keymap = svValue[KEYMAP_NDX];
995 xkb = XkbGetKeyboardByName(dpy, deviceSpec, &cmdNames,
996 XkbGBN_AllComponentsMask,
997 XkbGBN_AllComponentsMask &
998 (~XkbGBN_GeometryMask), True);
1001 ERR("Error loading new keyboard description\n");
1004 /* update the XKB root property */
1005 if (svValue[RULES_NDX] && (rdefs.model || rdefs.layout))
1007 if (!XkbRF_SetNamesProp(dpy, svValue[RULES_NDX], &rdefs))
1009 VMSG(0, "Error updating the XKB names property\n");
1019 dumpNames(True, False);
1026 main(int argc, char **argv)
1028 if ((!parseArgs(argc, argv)) || (!getDisplay(argc, argv)))
1030 svValue[LOCALE_NDX] = setlocale(LC_ALL, svValue[LOCALE_NDX]);
1031 svSrc[LOCALE_NDX] = FROM_SERVER;
1032 VMSG1(7, "locale is %s\n", svValue[LOCALE_NDX]);
1035 if (svValue[CONFIG_NDX] && (!applyConfig(svValue[CONFIG_NDX])))
1039 if (!applyComponentNames())