summaryrefslogtreecommitdiff
path: root/app/setxkbmap/setxkbmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/setxkbmap/setxkbmap.c')
-rw-r--r--app/setxkbmap/setxkbmap.c668
1 files changed, 350 insertions, 318 deletions
diff --git a/app/setxkbmap/setxkbmap.c b/app/setxkbmap/setxkbmap.c
index 13875b081..cde779cc9 100644
--- a/app/setxkbmap/setxkbmap.c
+++ b/app/setxkbmap/setxkbmap.c
@@ -6,19 +6,19 @@
fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright
notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
+ documentation, and that the name of Silicon Graphics not be
+ used in advertising or publicity pertaining to distribution
of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
+ Silicon Graphics makes no representation about the suitability
of this software for any purpose. It is provided "as is"
without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+
+ SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -45,43 +45,29 @@
#endif
#ifndef DFLT_XKB_CONFIG_ROOT
-#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
+#define DFLT_XKB_CONFIG_ROOT "/usr/share/X11/xkb"
#endif
#ifndef DFLT_XKB_RULES_FILE
-#define DFLT_XKB_RULES_FILE "xorg"
+#define DFLT_XKB_RULES_FILE "base"
#endif
#ifndef DFLT_XKB_LAYOUT
-#define DFLT_XKB_LAYOUT "us"
+#define DFLT_XKB_LAYOUT "us"
#endif
#ifndef DFLT_XKB_MODEL
-#define DFLT_XKB_MODEL "pc105"
+#define DFLT_XKB_MODEL "pc105"
#endif
-/* Values used in svSrc to state how a value was obtained. The order of these
+/* Constants to state how a value was obtained. The order of these
* is important, the bigger the higher the priority.
* e.g. FROM_CONFIG overrides FROM_SERVER */
-#define UNDEFINED 0
-#define FROM_SERVER 1 /* retrieved from server at runtime */
-#define FROM_RULES 2 /* xkb rules file */
-#define FROM_CONFIG 3 /* command-line specified config file */
-#define FROM_CMD_LINE 4 /* specified at the cmdline */
-#define NUM_SOURCES 5
-
-/* Indices used into svSrc, svNValue */
-#define RULES_NDX 0 /* rules file */
-#define CONFIG_NDX 1 /* config file (if used) */
-#define DISPLAY_NDX 2 /* X display name */
-#define LOCALE_NDX 3 /* machine's locale */
-#define MODEL_NDX 4
-#define LAYOUT_NDX 5
-#define VARIANT_NDX 6
-#define KEYCODES_NDX 7
-#define TYPES_NDX 8
-#define COMPAT_NDX 9
-#define SYMBOLS_NDX 10
-#define GEOMETRY_NDX 11
-#define KEYMAP_NDX 12
-#define NUM_STRING_VALS 13
+enum source {
+ UNDEFINED = 0,
+ FROM_SERVER, /* Retrieved from server at runtime. */
+ FROM_RULES, /* Xkb rules file. */
+ FROM_CONFIG, /* Command-line specified config file. */
+ FROM_CMD_LINE, /* Specified at the cmdline. */
+ NUM_SOURCES
+};
/***====================================================================***/
static Bool print = False;
@@ -95,30 +81,51 @@ static Display *dpy;
* human-readable versions of FROM_CONFIG, FROM_SERVER, etc. Used for error
* reporting.
*/
-static char *srcName[NUM_SOURCES] = {
+static const char *srcName[NUM_SOURCES] = {
"undefined", "X server", "rules file", "config file", "command line"
};
-/**
- * human-readable versions for RULES_NDX, CONFIG_NDX, etc. Used for error
- * reporting.
- */
-static char *svName[NUM_STRING_VALS] = {
- "rules file", "config file", "X display", "locale",
- "keyboard model", "keyboard layout", "layout variant",
- "keycodes", "types", "compatibility map", "symbols", "geometry",
- "keymap"
+struct setting {
+ char const *name; /* Human-readable setting name. Used for error reporting. */
+ char *value; /* Holds the value. */
+ enum source src; /* Holds the source. */
+};
+
+typedef struct setting setting_t;
+
+struct settings {
+ setting_t rules; /* Rules file */
+ setting_t config; /* Config file (if used) */
+ setting_t display; /* X display name */
+ setting_t locale; /* Machine's locale */
+ setting_t model;
+ setting_t layout;
+ setting_t variant;
+ setting_t keycodes;
+ setting_t types;
+ setting_t compat;
+ setting_t symbols;
+ setting_t geometry;
+ setting_t keymap;
+};
+
+typedef struct settings settings_t;
+
+static settings_t settings = {
+ { "rules file", NULL, UNDEFINED },
+ { "config file", NULL, UNDEFINED },
+ { "X display", NULL, UNDEFINED },
+ { "locale", NULL, UNDEFINED },
+ { "keyboard model", NULL, UNDEFINED },
+ { "keyboard layout", NULL, UNDEFINED },
+ { "layout variant", NULL, UNDEFINED },
+ { "keycodes", NULL, UNDEFINED },
+ { "types", NULL, UNDEFINED },
+ { "compatibility map", NULL, UNDEFINED },
+ { "symbols", NULL, UNDEFINED },
+ { "geometry", NULL, UNDEFINED },
+ { "keymap", NULL, UNDEFINED }
};
-/**
- * Holds the source for each of RULES, CONFIG, DISPLAY, etc.
- * i.e. if svSrc[LAYOUT_NDX] == FROM_SERVER, then the layout has been fetched
- * from the server.
- */
-static int svSrc[NUM_STRING_VALS];
-/**
- * Holds the value for each of RULES, CONFIG, DISPLAY, etc.
- */
-static char *svValue[NUM_STRING_VALS];
static XkbConfigRtrnRec cfgResult;
@@ -126,13 +133,18 @@ static XkbRF_RulesPtr rules = NULL;
static XkbRF_VarDefsRec rdefs;
static Bool clearOptions = False;
-static int szOptions = 0;
-static int numOptions = 0;
-static char **options = NULL;
-static int szInclPath = 0;
-static int numInclPath = 0;
-static char **inclPath = NULL;
+struct list {
+ char **item; /* Array of items. */
+ int sz; /* Size of array. */
+ int num; /* Number of used elements. */
+};
+
+typedef struct list list_t;
+
+static list_t options = { NULL, 0, 0 };
+
+static list_t inclPath = { NULL, 0, 0 };
static XkbDescPtr xkb = NULL;
@@ -140,83 +152,83 @@ static int deviceSpec = XkbUseCoreKbd;
/***====================================================================***/
-#define streq(s1,s2) (strcmp(s1,s2)==0)
-#define strpfx(s1,s2) (strncmp(s1,s2,strlen(s2))==0)
+#define streq(s1,s2) (strcmp(s1,s2)==0)
+#define strpfx(s1,s2) (strncmp(s1,s2,strlen(s2))==0)
+
+#define MSG(s) printf(s)
+#define MSG1(s,a) printf(s,a)
+#define MSG2(s,a,b) printf(s,a,b)
+#define MSG3(s,a,b,c) printf(s,a,b,c)
-#define MSG(s) printf(s)
-#define MSG1(s,a) printf(s,a)
-#define MSG2(s,a,b) printf(s,a,b)
-#define MSG3(s,a,b,c) printf(s,a,b,c)
+#define VMSG(l,s) if (verbose>(l)) printf(s)
+#define VMSG1(l,s,a) if (verbose>(l)) printf(s,a)
+#define VMSG2(l,s,a,b) if (verbose>(l)) printf(s,a,b)
+#define VMSG3(l,s,a,b,c) if (verbose>(l)) printf(s,a,b,c)
-#define VMSG(l,s) if (verbose>(l)) printf(s)
-#define VMSG1(l,s,a) if (verbose>(l)) printf(s,a)
-#define VMSG2(l,s,a,b) if (verbose>(l)) printf(s,a,b)
-#define VMSG3(l,s,a,b,c) if (verbose>(l)) printf(s,a,b,c)
+#define ERR(s) fprintf(stderr,s)
+#define ERR1(s,a) fprintf(stderr,s,a)
+#define ERR2(s,a,b) fprintf(stderr,s,a,b)
+#define ERR3(s,a,b,c) fprintf(stderr,s,a,b,c)
-#define ERR(s) fprintf(stderr,s)
-#define ERR1(s,a) fprintf(stderr,s,a)
-#define ERR2(s,a,b) fprintf(stderr,s,a,b)
-#define ERR3(s,a,b,c) fprintf(stderr,s,a,b,c)
+#define OOM(ptr) do { if ((ptr) == NULL) { ERR("Out of memory.\n"); exit(-1); } } while (0)
/***====================================================================***/
-Bool addToList(int *sz, int *num, char ***listIn, char *newVal);
+Bool addToList(list_t *list, const char *newVal);
void usage(int argc, char **argv);
void dumpNames(Bool wantRules, Bool wantCNames);
-void trySetString(int which, char *newVal, int src);
-Bool setOptString(int *arg, int argc, char **argv, int which, int src);
+void trySetString(setting_t * setting, char *newVal, enum source src);
+Bool setOptString(int *arg, int argc, char **argv, setting_t *setting, enum source src);
int parseArgs(int argc, char **argv);
Bool getDisplay(int argc, char **argv);
Bool getServerValues(void);
-FILE *findFileInPath(char *name, char *subdir);
-Bool addStringToOptions(char *opt_str, int *sz_opts, int *num_opts,
- char ***opts);
-char *stringFromOptions(char *orig, int numNew, char **newOpts);
+FILE *findFileInPath(char *name);
+Bool addStringToOptions(char *opt_str, list_t *opts);
+char *stringFromOptions(char *orig, list_t *newOpts);
Bool applyConfig(char *name);
+XkbRF_RulesPtr tryLoadRules(char *name, char *locale, Bool wantDesc, Bool wantRules);
Bool applyRules(void);
Bool applyComponentNames(void);
void printKeymap(void);
/***====================================================================***/
+/*
+ If newVal is NULL or empty string, the list is cleared.
+ Otherwise newVal is added to the end of the list (if it is not present in the list yet).
+*/
+
Bool
-addToList(int *sz, int *num, char ***listIn, char *newVal)
+addToList(list_t *list, const char *newVal)
{
register int i;
- char **list;
if ((!newVal) || (!newVal[0]))
{
- *num = 0;
+ list->num = 0;
return True;
}
- list = *listIn;
- for (i = 0; i < *num; i++)
+ for (i = 0; i < list->num; i++)
{
- if (streq(list[i], newVal))
+ if (streq(list->item[i], newVal))
return True;
}
- if ((list == NULL) || (*sz < 1))
+ if ((list->item == NULL) || (list->sz < 1))
{
- *num = 0;
- *sz = 4;
- list = (char **) calloc(*sz, sizeof(char *));
- *listIn = list;
+ list->num = 0;
+ list->sz = 4;
+ list->item = (char **) calloc(list->sz, sizeof(char *));
+ OOM(list->item);
}
- else if (*num >= *sz)
+ else if (list->num >= list->sz)
{
- *sz *= 2;
- list = (char **) realloc(list, (*sz) * sizeof(char *));
- *listIn = list;
+ list->sz *= 2;
+ list->item = (char **) realloc(list->item, (list->sz) * sizeof(char *));
+ OOM(list->item);
}
- if (!list)
- {
- ERR("Internal Error! Allocation failure in add to list!\n");
- ERR(" Exiting.\n");
- exit(-1);
- }
- list[*num] = strdup(newVal);
- (*num) = (*num) + 1;
+ list->item[list->num] = strdup(newVal);
+ OOM(list->item[list->num]);
+ list->num += 1;
return True;
}
@@ -225,30 +237,32 @@ addToList(int *sz, int *num, char ***listIn, char *newVal)
void
usage(int argc, char **argv)
{
- MSG1("Usage: %s [args] [<layout> [<variant> [<option> ... ]]]\n",
- argv[0]);
- MSG("Where legal args are:\n");
- MSG("-?,-help Print this message\n");
- MSG("-compat <name> Specifies compatibility map component name\n");
- MSG("-config <file> Specifies configuration file to use\n");
- MSG("-device <deviceid> Specifies the device ID to use\n");
- MSG("-display <dpy> Specifies display to use\n");
- MSG("-geometry <name> Specifies geometry component name\n");
- MSG("-I[<dir>] Add <dir> to list of directories to be used\n");
- MSG("-keycodes <name> Specifies keycodes component name\n");
- MSG("-keymap <name> Specifies name of keymap to load\n");
- MSG("-layout <name> Specifies layout used to choose component names\n");
- MSG("-model <name> Specifies model used to choose component names\n");
- MSG("-option <name> Adds an option used to choose component names\n");
- MSG("-print Print a complete xkb_keymap description and exit\n");
- MSG("-query Print the current layout settings and exit\n");
- MSG("-rules <name> Name of rules file to use\n");
- MSG("-symbols <name> Specifies symbols component name\n");
- MSG("-synch Synchronize request w/X server\n");
- MSG("-types <name> Specifies types component name\n");
- MSG("-v[erbose] [<lvl>] Sets verbosity (1..10). Higher values yield\n");
- MSG(" more messages\n");
- MSG("-variant <name> Specifies layout variant used to choose component names\n");
+ MSG1(
+ "Usage: %s [options] [<layout> [<variant> [<option> ... ]]]\n"
+ "Options:\n"
+ " -?, -help Print this message\n"
+ " -compat <name> Specifies compatibility map component name\n"
+ " -config <file> Specifies configuration file to use\n"
+ " -device <deviceid> Specifies the device ID to use\n"
+ " -display <dpy> Specifies display to use\n"
+ " -geometry <name> Specifies geometry component name\n"
+ " -I<dir> Add <dir> to list of directories to be used\n"
+ " -keycodes <name> Specifies keycodes component name\n"
+ " -keymap <name> Specifies name of keymap to load\n"
+ " -layout <name> Specifies layout used to choose component names\n"
+ " -model <name> Specifies model used to choose component names\n"
+ " -option <name> Adds an option used to choose component names\n"
+ " -print Print a complete xkb_keymap description and exit\n"
+ " -query Print the current layout settings and exit\n"
+ " -rules <name> Name of rules file to use\n"
+ " -symbols <name> Specifies symbols component name\n"
+ " -synch Synchronize request with X server\n"
+ " -types <name> Specifies types component name\n"
+ " -v[erbose] [<lvl>] Sets verbosity (1..10). Higher values yield\n"
+ " more messages\n"
+ " -variant <name> Specifies layout variant used to choose component names\n",
+ argv[0]
+ );
}
void
@@ -256,35 +270,35 @@ dumpNames(Bool wantRules, Bool wantCNames)
{
if (wantRules)
{
- if (svValue[RULES_NDX])
- MSG1("rules: %s\n", svValue[RULES_NDX]);
- if (svValue[MODEL_NDX])
- MSG1("model: %s\n", svValue[MODEL_NDX]);
- if (svValue[LAYOUT_NDX])
- MSG1("layout: %s\n", svValue[LAYOUT_NDX]);
- if (svValue[VARIANT_NDX])
- MSG1("variant: %s\n", svValue[VARIANT_NDX]);
- if (options)
+ if (settings.rules.value)
+ MSG1("rules: %s\n", settings.rules.value);
+ if (settings.model.value)
+ MSG1("model: %s\n", settings.model.value);
+ if (settings.layout.value)
+ MSG1("layout: %s\n", settings.layout.value);
+ if (settings.variant.value)
+ MSG1("variant: %s\n", settings.variant.value);
+ if (options.item)
{
- char *opt_str = stringFromOptions(NULL, numOptions, options);
+ char *opt_str = stringFromOptions(NULL, &options);
MSG1("options: %s\n", opt_str);
free(opt_str);
}
}
if (wantCNames)
{
- if (svValue[KEYMAP_NDX])
- MSG1("keymap: %s\n", svValue[KEYMAP_NDX]);
- if (svValue[KEYCODES_NDX])
- MSG1("keycodes: %s\n", svValue[KEYCODES_NDX]);
- if (svValue[TYPES_NDX])
- MSG1("types: %s\n", svValue[TYPES_NDX]);
- if (svValue[COMPAT_NDX])
- MSG1("compat: %s\n", svValue[COMPAT_NDX]);
- if (svValue[SYMBOLS_NDX])
- MSG1("symbols: %s\n", svValue[SYMBOLS_NDX]);
- if (svValue[GEOMETRY_NDX])
- MSG1("geometry: %s\n", svValue[GEOMETRY_NDX]);
+ if (settings.keymap.value)
+ MSG1("keymap: %s\n", settings.keymap.value);
+ if (settings.keycodes.value)
+ MSG1("keycodes: %s\n", settings.keycodes.value);
+ if (settings.types.value)
+ MSG1("types: %s\n", settings.types.value);
+ if (settings.compat.value)
+ MSG1("compat: %s\n", settings.compat.value);
+ if (settings.symbols.value)
+ MSG1("symbols: %s\n", settings.symbols.value);
+ if (settings.geometry.value)
+ MSG1("geometry: %s\n", settings.geometry.value);
}
return;
}
@@ -299,33 +313,33 @@ dumpNames(Bool wantRules, Bool wantCNames)
* @param which What value is it (one of RULES_NDX, CONFIG_NDX, ...)
*/
void
-trySetString(int which, char *newVal, int src)
+trySetString(setting_t *setting, char *newVal, enum source src)
{
- if (svValue[which] != NULL)
+ if (setting->value != NULL)
{
- if (svSrc[which] == src)
+ if (setting->src == src)
{
VMSG2(0, "Warning! More than one %s from %s\n",
- svName[which], srcName[src]);
+ setting->name, srcName[src]);
VMSG2(0, " Using \"%s\", ignoring \"%s\"\n",
- svValue[which], newVal);
+ setting->value, newVal);
return;
}
- else if (svSrc[which] > src)
+ else if (setting->src > src)
{
- VMSG1(5, "Warning! Multiple definitions of %s\n", svName[which]);
+ VMSG1(5, "Warning! Multiple definitions of %s\n", setting->name);
VMSG2(5, " Using %s, ignoring %s\n",
- srcName[svSrc[which]], srcName[src]);
+ srcName[setting->src], srcName[src]);
return;
}
}
- svSrc[which] = src;
- svValue[which] = newVal;
+ setting->src = src;
+ setting->value = newVal;
return;
}
Bool
-setOptString(int *arg, int argc, char **argv, int which, int src)
+setOptString(int *arg, int argc, char **argv, setting_t *setting, enum source src)
{
int ndx;
char *opt;
@@ -334,31 +348,31 @@ setOptString(int *arg, int argc, char **argv, int which, int src)
opt = argv[ndx];
if (ndx >= argc - 1)
{
- VMSG1(0, "No %s specified on the command line\n", svName[which]);
+ VMSG1(0, "No %s specified on the command line\n", setting->name);
VMSG1(0, "Trailing %s option ignored\n", opt);
return True;
}
ndx++;
*arg = ndx;
- if (svValue[which] != NULL)
+ if (setting->value != NULL)
{
- if (svSrc[which] == src)
+ if (setting->src == src)
{
- VMSG2(0, "More than one %s on %s\n", svName[which], srcName[src]);
- VMSG2(0, "Using \"%s\", ignoring \"%s\"\n", svValue[which],
+ VMSG2(0, "More than one %s on %s\n", setting->name, srcName[src]);
+ VMSG2(0, "Using \"%s\", ignoring \"%s\"\n", setting->value,
argv[ndx]);
return True;
}
- else if (svSrc[which] > src)
+ else if (setting->src > src)
{
- VMSG1(5, "Multiple definitions of %s\n", svName[which]);
- VMSG2(5, "Using %s, ignoring %s\n", srcName[svSrc[which]],
+ VMSG1(5, "Multiple definitions of %s\n", setting->name);
+ VMSG2(5, "Using %s, ignoring %s\n", srcName[setting->src],
srcName[src]);
return True;
}
}
- svSrc[which] = src;
- svValue[which] = argv[ndx];
+ setting->src = src;
+ setting->value = argv[ndx];
return True;
}
@@ -377,59 +391,74 @@ parseArgs(int argc, char **argv)
unsigned present;
ok = True;
- addToList(&szInclPath, &numInclPath, &inclPath, ".");
- addToList(&szInclPath, &numInclPath, &inclPath, DFLT_XKB_CONFIG_ROOT);
+ addToList(&inclPath, ".");
+ addToList(&inclPath, DFLT_XKB_CONFIG_ROOT);
for (i = 1; (i < argc) && ok; i++)
{
if (argv[i][0] != '-')
{
/* Allow a call like "setxkbmap us" to work. Layout is default,
if -layout is given, then try parsing variant, then options */
- if (!svSrc[LAYOUT_NDX])
- trySetString(LAYOUT_NDX, argv[i], FROM_CMD_LINE);
- else if (!svSrc[VARIANT_NDX])
- trySetString(VARIANT_NDX, argv[i], FROM_CMD_LINE);
+ if (!settings.layout.src)
+ trySetString(&settings.layout, argv[i], FROM_CMD_LINE);
+ else if (!settings.variant.src)
+ trySetString(&settings.variant, argv[i], FROM_CMD_LINE);
else
- ok = addToList(&szOptions, &numOptions, &options, argv[i]);
+ ok = addToList(&options, argv[i]);
}
else if (streq(argv[i], "-compat"))
- ok = setOptString(&i, argc, argv, COMPAT_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.compat, FROM_CMD_LINE);
else if (streq(argv[i], "-config"))
- ok = setOptString(&i, argc, argv, CONFIG_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.config, FROM_CMD_LINE);
else if (streq(argv[i], "-device"))
- deviceSpec = atoi(argv[++i]); /* only allow device IDs, not names */
+ {
+ if ( ++i < argc ) {
+ deviceSpec = atoi(argv[i]); /* only allow device IDs, not names */
+ } else {
+ usage(argc, argv);
+ exit(-1);
+ }
+ }
else if (streq(argv[i], "-display"))
- ok = setOptString(&i, argc, argv, DISPLAY_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.display, FROM_CMD_LINE);
else if (streq(argv[i], "-geometry"))
- ok = setOptString(&i, argc, argv, GEOMETRY_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.geometry, FROM_CMD_LINE);
else if (streq(argv[i], "-help") || streq(argv[i], "-?"))
{
usage(argc, argv);
exit(0);
}
- else if (strpfx(argv[i], "-I"))
- ok = addToList(&szInclPath, &numInclPath, &inclPath, &argv[i][2]);
+ else if (streq(argv[i], "-I")) /* space between -I and path */
+ {
+ if ( ++i < argc )
+ ok = addToList(&inclPath, argv[i]);
+ else
+ VMSG(0, "No directory specified on the command line\n"
+ "Trailing -I option ignored\n");
+ }
+ else if (strpfx(argv[i], "-I")) /* no space between -I and path */
+ ok = addToList(&inclPath, &argv[i][2]);
else if (streq(argv[i], "-keycodes"))
- ok = setOptString(&i, argc, argv, KEYCODES_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.keycodes, FROM_CMD_LINE);
else if (streq(argv[i], "-keymap"))
- ok = setOptString(&i, argc, argv, KEYMAP_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.keymap, FROM_CMD_LINE);
else if (streq(argv[i], "-layout"))
- ok = setOptString(&i, argc, argv, LAYOUT_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.layout, FROM_CMD_LINE);
else if (streq(argv[i], "-model"))
- ok = setOptString(&i, argc, argv, MODEL_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.model, FROM_CMD_LINE);
else if (streq(argv[i], "-option"))
{
if ((i == argc - 1) || (argv[i + 1][0] == '\0')
|| (argv[i + 1][0] == '-'))
{
clearOptions = True;
- ok = addToList(&szOptions, &numOptions, &options, "");
+ ok = addToList(&options, "");
if (i < argc - 1 && argv[i + 1][0] == '\0')
i++;
}
else
{
- ok = addToList(&szOptions, &numOptions, &options, argv[++i]);
+ ok = addToList(&options, argv[++i]);
}
}
else if (streq(argv[i], "-print"))
@@ -437,13 +466,13 @@ parseArgs(int argc, char **argv)
else if (streq(argv[i], "-query"))
query = True;
else if (streq(argv[i], "-rules"))
- ok = setOptString(&i, argc, argv, RULES_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.rules, FROM_CMD_LINE);
else if (streq(argv[i], "-symbols"))
- ok = setOptString(&i, argc, argv, SYMBOLS_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.symbols, FROM_CMD_LINE);
else if (streq(argv[i], "-synch"))
synch = True;
else if (streq(argv[i], "-types"))
- ok = setOptString(&i, argc, argv, TYPES_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.types, FROM_CMD_LINE);
else if (streq(argv[i], "-verbose") || (streq(argv[i], "-v")))
{
if ((i < argc - 1) && (isdigit(argv[i + 1][0])))
@@ -463,7 +492,7 @@ parseArgs(int argc, char **argv)
VMSG1(7, "Setting verbose level to %d\n", verbose);
}
else if (streq(argv[i], "-variant"))
- ok = setOptString(&i, argc, argv, VARIANT_NDX, FROM_CMD_LINE);
+ ok = setOptString(&i, argc, argv, &settings.variant, FROM_CMD_LINE);
else
{
ERR1("Error! Option \"%s\" not recognized\n", argv[i]);
@@ -472,25 +501,25 @@ parseArgs(int argc, char **argv)
}
present = 0;
- if (svValue[TYPES_NDX])
+ if (settings.types.value)
present++;
- if (svValue[COMPAT_NDX])
+ if (settings.compat.value)
present++;
- if (svValue[SYMBOLS_NDX])
+ if (settings.symbols.value)
present++;
- if (svValue[KEYCODES_NDX])
+ if (settings.keycodes.value)
present++;
- if (svValue[GEOMETRY_NDX])
+ if (settings.geometry.value)
present++;
- if (svValue[CONFIG_NDX])
+ if (settings.config.value)
present++;
- if (svValue[MODEL_NDX])
+ if (settings.model.value)
present++;
- if (svValue[LAYOUT_NDX])
+ if (settings.layout.value)
present++;
- if (svValue[VARIANT_NDX])
+ if (settings.variant.value)
present++;
- if (svValue[KEYMAP_NDX] && present)
+ if (settings.keymap.value && present)
{
ERR("No other components can be specified when a keymap is present\n");
return False;
@@ -511,14 +540,14 @@ getDisplay(int argc, char **argv)
major = XkbMajorVersion;
minor = XkbMinorVersion;
dpy =
- XkbOpenDisplay(svValue[DISPLAY_NDX], NULL, NULL, &major, &minor,
+ XkbOpenDisplay(settings.display.value, NULL, NULL, &major, &minor,
&why);
if (!dpy)
{
- if (svValue[DISPLAY_NDX] == NULL)
- svValue[DISPLAY_NDX] = getenv("DISPLAY");
- if (svValue[DISPLAY_NDX] == NULL)
- svValue[DISPLAY_NDX] = "default display";
+ if (settings.display.value == NULL)
+ settings.display.value = getenv("DISPLAY");
+ if (settings.display.value == NULL)
+ settings.display.value = "default display";
switch (why)
{
case XkbOD_BadLibraryVersion:
@@ -528,16 +557,16 @@ getDisplay(int argc, char **argv)
major, minor);
break;
case XkbOD_ConnectionRefused:
- ERR1("Cannot open display \"%s\"\n", svValue[DISPLAY_NDX]);
+ ERR1("Cannot open display \"%s\"\n", settings.display.value);
break;
case XkbOD_NonXkbServer:
- ERR1("XKB extension not present on %s\n", svValue[DISPLAY_NDX]);
+ ERR1("XKB extension not present on %s\n", settings.display.value);
break;
case XkbOD_BadServerVersion:
ERR3("%s was compiled with XKB version %d.%02d\n", argv[0],
XkbMajorVersion, XkbMinorVersion);
ERR3("Server %s uses incompatible version %d.%02d\n",
- svValue[DISPLAY_NDX], major, minor);
+ settings.display.value, major, minor);
break;
default:
ERR1("Unknown error %d from XkbOpenDisplay\n", why);
@@ -577,16 +606,16 @@ getServerValues(void)
tmp, vd.model, vd.layout);
}
if (tmp)
- trySetString(RULES_NDX, tmp, FROM_SERVER);
+ trySetString(&settings.rules, tmp, FROM_SERVER);
if (vd.model)
- trySetString(MODEL_NDX, vd.model, FROM_SERVER);
+ trySetString(&settings.model, vd.model, FROM_SERVER);
if (vd.layout)
- trySetString(LAYOUT_NDX, vd.layout, FROM_SERVER);
+ trySetString(&settings.layout, vd.layout, FROM_SERVER);
if (vd.variant)
- trySetString(VARIANT_NDX, vd.variant, FROM_SERVER);
+ trySetString(&settings.variant, vd.variant, FROM_SERVER);
if ((vd.options) && (!clearOptions))
{
- addStringToOptions(vd.options, &szOptions, &numOptions, &options);
+ addStringToOptions(vd.options, &options);
XFree(vd.options);
}
return True;
@@ -595,7 +624,7 @@ getServerValues(void)
/***====================================================================***/
FILE *
-findFileInPath(char *name, char *subdir)
+findFileInPath(char *name)
{
register int i;
char buf[PATH_MAX];
@@ -608,17 +637,16 @@ findFileInPath(char *name, char *subdir)
MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), name);
return fp;
}
- for (i = 0; (i < numInclPath); i++)
+ for (i = 0; (i < inclPath.num); i++)
{
- if ((strlen(inclPath[i]) + strlen(subdir) + strlen(name) + 2) >
+ if (snprintf(buf, PATH_MAX, "%s/%s", inclPath.item[i], name) >=
PATH_MAX)
{
- VMSG3(0, "Path too long (%s/%s%s). Ignored.\n", inclPath[i],
- subdir, name);
+ VMSG2(0, "Path too long (%s/%s). Ignored.\n", inclPath.item[i],
+ name);
continue;
}
- sprintf(buf, "%s/%s%s", inclPath[i], subdir, name);
- fp = fopen(name, "r");
+ fp = fopen(buf, "r");
if ((verbose > 7) || ((!fp) && (verbose > 5)))
MSG2("%s file %s\n", (fp ? "Found" : "Didn't find"), buf);
if (fp != NULL)
@@ -630,14 +658,14 @@ findFileInPath(char *name, char *subdir)
/***====================================================================***/
Bool
-addStringToOptions(char *opt_str, int *sz_opts, int *num_opts, char ***opts)
+addStringToOptions(char *opt_str, list_t *opts)
{
char *tmp, *str, *next;
Bool ok = True;
- if ((str = strdup(opt_str)) == NULL)
- return False;
- for (tmp = str, next = NULL; (tmp && *tmp != '\0') && ok; tmp = next)
+ str = strdup(opt_str);
+ OOM(str);
+ for (tmp = str; (tmp && *tmp != '\0') && ok; tmp = next)
{
next = strchr(str, ',');
if (next)
@@ -645,7 +673,7 @@ addStringToOptions(char *opt_str, int *sz_opts, int *num_opts, char ***opts)
*next = '\0';
next++;
}
- ok = addToList(sz_opts, num_opts, opts, tmp) && ok;
+ ok = addToList(opts, tmp) && ok;
}
free(str);
return ok;
@@ -654,7 +682,7 @@ addStringToOptions(char *opt_str, int *sz_opts, int *num_opts, char ***opts)
/***====================================================================***/
char *
-stringFromOptions(char *orig, int numNew, char **newOpts)
+stringFromOptions(char *orig, list_t *newOpts)
{
int len, i, nOut;
@@ -662,44 +690,36 @@ stringFromOptions(char *orig, int numNew, char **newOpts)
len = strlen(orig) + 1;
else
len = 0;
- for (i = 0; i < numNew; i++)
+ for (i = 0; i < newOpts->num; i++)
{
- if (newOpts[i])
- len += strlen(newOpts[i]) + 1;
+ if (newOpts->item[i])
+ len += strlen(newOpts->item[i]) + 1;
}
if (len < 1)
return NULL;
if (orig)
{
orig = (char *) realloc(orig, len);
- if (!orig)
- {
- ERR("OOM in stringFromOptions\n");
- return NULL;
- }
+ OOM(orig);
nOut = 1;
}
else
{
orig = (char *) calloc(len, 1);
- if (!orig)
- {
- ERR("OOM in stringFromOptions\n");
- return NULL;
- }
+ OOM(orig);
nOut = 0;
}
- for (i = 0; i < numNew; i++)
+ for (i = 0; i < newOpts->num; i++)
{
- if (!newOpts[i])
+ if (!newOpts->item[i])
continue;
if (nOut > 0)
{
strcat(orig, ",");
- strcat(orig, newOpts[i]);
+ strcat(orig, newOpts->item[i]);
}
else
- strcpy(orig, newOpts[i]);
+ strcpy(orig, newOpts->item[i]);
nOut++;
}
return orig;
@@ -713,7 +733,7 @@ applyConfig(char *name)
FILE *fp;
Bool ok;
- if ((fp = findFileInPath(name, "")) == NULL)
+ if ((fp = findFileInPath(name)) == NULL)
return False;
ok = XkbCFParse(fp, XkbCFDflts, NULL, &cfgResult);
fclose(fp);
@@ -724,58 +744,57 @@ applyConfig(char *name)
}
if (cfgResult.rules_file)
{
- trySetString(RULES_NDX, cfgResult.rules_file, FROM_CONFIG);
+ trySetString(&settings.rules, cfgResult.rules_file, FROM_CONFIG);
cfgResult.rules_file = NULL;
}
if (cfgResult.model)
{
- trySetString(MODEL_NDX, cfgResult.model, FROM_CONFIG);
+ trySetString(&settings.model, cfgResult.model, FROM_CONFIG);
cfgResult.model = NULL;
}
if (cfgResult.layout)
{
- trySetString(LAYOUT_NDX, cfgResult.layout, FROM_CONFIG);
+ trySetString(&settings.layout, cfgResult.layout, FROM_CONFIG);
cfgResult.layout = NULL;
}
if (cfgResult.variant)
{
- trySetString(VARIANT_NDX, cfgResult.variant, FROM_CONFIG);
+ trySetString(&settings.variant, cfgResult.variant, FROM_CONFIG);
cfgResult.variant = NULL;
}
if (cfgResult.options)
{
- addStringToOptions(cfgResult.options, &szOptions, &numOptions,
- &options);
+ addStringToOptions(cfgResult.options, &options);
cfgResult.options = NULL;
}
if (cfgResult.keymap)
{
- trySetString(KEYMAP_NDX, cfgResult.keymap, FROM_CONFIG);
+ trySetString(&settings.keymap, cfgResult.keymap, FROM_CONFIG);
cfgResult.keymap = NULL;
}
if (cfgResult.keycodes)
{
- trySetString(KEYCODES_NDX, cfgResult.keycodes, FROM_CONFIG);
+ trySetString(&settings.keycodes, cfgResult.keycodes, FROM_CONFIG);
cfgResult.keycodes = NULL;
}
if (cfgResult.geometry)
{
- trySetString(GEOMETRY_NDX, cfgResult.geometry, FROM_CONFIG);
+ trySetString(&settings.geometry, cfgResult.geometry, FROM_CONFIG);
cfgResult.geometry = NULL;
}
if (cfgResult.symbols)
{
- trySetString(SYMBOLS_NDX, cfgResult.symbols, FROM_CONFIG);
+ trySetString(&settings.symbols, cfgResult.symbols, FROM_CONFIG);
cfgResult.symbols = NULL;
}
if (cfgResult.types)
{
- trySetString(TYPES_NDX, cfgResult.types, FROM_CONFIG);
+ trySetString(&settings.types, cfgResult.types, FROM_CONFIG);
cfgResult.types = NULL;
}
if (cfgResult.compat)
{
- trySetString(COMPAT_NDX, cfgResult.compat, FROM_CONFIG);
+ trySetString(&settings.compat, cfgResult.compat, FROM_CONFIG);
cfgResult.compat = NULL;
}
if (verbose > 5)
@@ -786,6 +805,19 @@ applyConfig(char *name)
return True;
}
+XkbRF_RulesPtr
+tryLoadRules(char *name, char *locale, Bool wantDesc, Bool wantRules)
+{
+ XkbRF_RulesPtr rules = NULL;
+ VMSG1(7, "Trying to load rules file %s...\n", name);
+ rules = XkbRF_Load(name, locale, wantDesc, wantRules);
+ if (rules)
+ {
+ VMSG(7, "Success.\n");
+ }
+ return rules;
+}
+
/**
* If any of model, layout, variant or options is specified, then compile the
* options into the
@@ -798,50 +830,50 @@ applyRules(void)
int i;
char *rfName;
- if (svSrc[MODEL_NDX] || svSrc[LAYOUT_NDX] || svSrc[VARIANT_NDX]
- || options)
+ if (settings.model.src || settings.layout.src || settings.variant.src
+ || options.item)
{
char buf[PATH_MAX];
XkbComponentNamesRec rnames;
- if (svSrc[VARIANT_NDX] < svSrc[LAYOUT_NDX])
- svValue[VARIANT_NDX] = NULL;
+ if (settings.variant.src < settings.layout.src)
+ settings.variant.value = NULL;
- rdefs.model = svValue[MODEL_NDX];
- rdefs.layout = svValue[LAYOUT_NDX];
- rdefs.variant = svValue[VARIANT_NDX];
- if (options)
+ rdefs.model = settings.model.value;
+ rdefs.layout = settings.layout.value;
+ rdefs.variant = settings.variant.value;
+ if (options.item)
rdefs.options =
- stringFromOptions(rdefs.options, numOptions, options);
+ stringFromOptions(rdefs.options, &options);
- if (svSrc[RULES_NDX])
- rfName = svValue[RULES_NDX];
+ if (settings.rules.src)
+ rfName = settings.rules.value;
else
rfName = DFLT_XKB_RULES_FILE;
if (rfName[0] == '/')
{
- rules = XkbRF_Load(rfName, svValue[LOCALE_NDX], True, True);
+ rules = tryLoadRules(rfName, settings.locale.value, True, True);
}
else
{
/* try to load rules files from all include paths until the first
* we succeed with */
- for (i = 0; (i < numInclPath) && (!rules); i++)
+ for (i = 0; (i < inclPath.num) && (!rules); i++)
{
- if ((strlen(inclPath[i]) + strlen(rfName) + 8) > PATH_MAX)
+ if (snprintf(buf, PATH_MAX, "%s/rules/%s",
+ inclPath.item[i], rfName) >= PATH_MAX)
{
VMSG2(0, "Path too long (%s/rules/%s). Ignored.\n",
- inclPath[i], rfName);
+ inclPath.item[i], rfName);
continue;
}
- sprintf(buf, "%s/rules/%s", inclPath[i], svValue[RULES_NDX]);
- rules = XkbRF_Load(buf, svValue[LOCALE_NDX], True, True);
+ rules = tryLoadRules(buf, settings.locale.value, True, True);
}
}
if (!rules)
{
- ERR1("Couldn't find rules file (%s) \n", svValue[RULES_NDX]);
+ ERR1("Couldn't find rules file (%s) \n", rfName);
return False;
}
/* Let the rules file to the magic, then update the svValues with
@@ -849,37 +881,37 @@ applyRules(void)
XkbRF_GetComponents(rules, &rdefs, &rnames);
if (rnames.keycodes)
{
- trySetString(KEYCODES_NDX, rnames.keycodes, FROM_RULES);
+ trySetString(&settings.keycodes, rnames.keycodes, FROM_RULES);
rnames.keycodes = NULL;
}
if (rnames.symbols)
{
- trySetString(SYMBOLS_NDX, rnames.symbols, FROM_RULES);
+ trySetString(&settings.symbols, rnames.symbols, FROM_RULES);
rnames.symbols = NULL;
}
if (rnames.types)
{
- trySetString(TYPES_NDX, rnames.types, FROM_RULES);
+ trySetString(&settings.types, rnames.types, FROM_RULES);
rnames.types = NULL;
}
if (rnames.compat)
{
- trySetString(COMPAT_NDX, rnames.compat, FROM_RULES);
+ trySetString(&settings.compat, rnames.compat, FROM_RULES);
rnames.compat = NULL;
}
if (rnames.geometry)
{
- trySetString(GEOMETRY_NDX, rnames.geometry, FROM_RULES);
+ trySetString(&settings.geometry, rnames.geometry, FROM_RULES);
rnames.geometry = NULL;
}
if (rnames.keymap)
{
- trySetString(KEYMAP_NDX, rnames.keymap, FROM_RULES);
+ trySetString(&settings.keymap, rnames.keymap, FROM_RULES);
rnames.keymap = NULL;
}
if (verbose > 6)
{
- MSG1("Applied rules from %s:\n", svValue[RULES_NDX]);
+ MSG1("Applied rules from %s:\n", rfName);
dumpNames(True, False);
}
}
@@ -893,7 +925,7 @@ applyRules(void)
/* Primitive sanity check - filter out 'map names' (inside parenthesis) */
/* that can confuse xkbcomp parser */
static Bool
-checkName(char *name, char *string)
+checkName(char *name, const char *string)
{
char *i = name, *opar = NULL;
Bool ret = True;
@@ -948,33 +980,33 @@ void
printKeymap(void)
{
MSG("xkb_keymap {\n");
- if (svValue[KEYCODES_NDX])
- MSG1("\txkb_keycodes { include \"%s\"\t};\n", svValue[KEYCODES_NDX]);
- if (svValue[TYPES_NDX])
- MSG1("\txkb_types { include \"%s\"\t};\n", svValue[TYPES_NDX]);
- if (svValue[COMPAT_NDX])
- MSG1("\txkb_compat { include \"%s\"\t};\n", svValue[COMPAT_NDX]);
- if (svValue[SYMBOLS_NDX])
- MSG1("\txkb_symbols { include \"%s\"\t};\n", svValue[SYMBOLS_NDX]);
- if (svValue[GEOMETRY_NDX])
- MSG1("\txkb_geometry { include \"%s\"\t};\n", svValue[GEOMETRY_NDX]);
+ if (settings.keycodes.value)
+ MSG1("\txkb_keycodes { include \"%s\"\t};\n", settings.keycodes.value);
+ if (settings.types.value)
+ MSG1("\txkb_types { include \"%s\"\t};\n", settings.types.value);
+ if (settings.compat.value)
+ MSG1("\txkb_compat { include \"%s\"\t};\n", settings.compat.value);
+ if (settings.symbols.value)
+ MSG1("\txkb_symbols { include \"%s\"\t};\n", settings.symbols.value);
+ if (settings.geometry.value)
+ MSG1("\txkb_geometry { include \"%s\"\t};\n", settings.geometry.value);
MSG("};\n");
}
Bool
applyComponentNames(void)
{
- if (!checkName(svValue[TYPES_NDX], "types"))
+ if (!checkName(settings.types.value, "types"))
return False;
- if (!checkName(svValue[COMPAT_NDX], "compat"))
+ if (!checkName(settings.compat.value, "compat"))
return False;
- if (!checkName(svValue[SYMBOLS_NDX], "symbols"))
+ if (!checkName(settings.symbols.value, "symbols"))
return False;
- if (!checkName(svValue[KEYCODES_NDX], "keycodes"))
+ if (!checkName(settings.keycodes.value, "keycodes"))
return False;
- if (!checkName(svValue[GEOMETRY_NDX], "geometry"))
+ if (!checkName(settings.geometry.value, "geometry"))
return False;
- if (!checkName(svValue[KEYMAP_NDX], "keymap"))
+ if (!checkName(settings.keymap.value, "keymap"))
return False;
if (verbose > 5)
@@ -986,12 +1018,12 @@ applyComponentNames(void)
if (dpy && !print && !query)
{
XkbComponentNamesRec cmdNames;
- cmdNames.types = svValue[TYPES_NDX];
- cmdNames.compat = svValue[COMPAT_NDX];
- cmdNames.symbols = svValue[SYMBOLS_NDX];
- cmdNames.keycodes = svValue[KEYCODES_NDX];
- cmdNames.geometry = svValue[GEOMETRY_NDX];
- cmdNames.keymap = svValue[KEYMAP_NDX];
+ cmdNames.types = settings.types.value;
+ cmdNames.compat = settings.compat.value;
+ cmdNames.symbols = settings.symbols.value;
+ cmdNames.keycodes = settings.keycodes.value;
+ cmdNames.geometry = settings.geometry.value;
+ cmdNames.keymap = settings.keymap.value;
xkb = XkbGetKeyboardByName(dpy, deviceSpec, &cmdNames,
XkbGBN_AllComponentsMask,
XkbGBN_AllComponentsMask &
@@ -1002,9 +1034,9 @@ applyComponentNames(void)
return False;
}
/* update the XKB root property */
- if (svValue[RULES_NDX] && (rdefs.model || rdefs.layout))
+ if (settings.rules.value && (rdefs.model || rdefs.layout))
{
- if (!XkbRF_SetNamesProp(dpy, svValue[RULES_NDX], &rdefs))
+ if (!XkbRF_SetNamesProp(dpy, settings.rules.value, &rdefs))
{
VMSG(0, "Error updating the XKB names property\n");
}
@@ -1016,7 +1048,7 @@ applyComponentNames(void)
}
if (query)
{
- dumpNames(True, False);
+ dumpNames(True, False);
}
return True;
}
@@ -1027,12 +1059,12 @@ main(int argc, char **argv)
{
if ((!parseArgs(argc, argv)) || (!getDisplay(argc, argv)))
exit(-1);
- svValue[LOCALE_NDX] = setlocale(LC_ALL, svValue[LOCALE_NDX]);
- svSrc[LOCALE_NDX] = FROM_SERVER;
- VMSG1(7, "locale is %s\n", svValue[LOCALE_NDX]);
+ settings.locale.value = setlocale(LC_ALL, settings.locale.value);
+ settings.locale.src = FROM_SERVER;
+ VMSG1(7, "locale is %s\n", settings.locale.value);
if (dpy)
getServerValues();
- if (svValue[CONFIG_NDX] && (!applyConfig(svValue[CONFIG_NDX])))
+ if (settings.config.value && (!applyConfig(settings.config.value)))
exit(-3);
if (!applyRules())
exit(-4);