Add environment overrides for default RMLVO

You can now set default values in the environment, as well as a context
option to ignore the environment, e.g. for tests.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
master
Daniel Stone 2013-02-28 10:48:40 -08:00
parent d4c22ecc8a
commit fbe5e6751e
6 changed files with 126 additions and 13 deletions

View File

@ -114,6 +114,26 @@ AC_ARG_WITH([default_layout],
AC_DEFINE_UNQUOTED([DEFAULT_XKB_LAYOUT], ["$DEFAULT_XKB_LAYOUT"],
[Default XKB layout])
AC_ARG_WITH([default_variant],
[AS_HELP_STRING([--with-default-variant=<path>],
[Default XKB variant (default: (none))])],
[DEFAULT_XKB_VARIANT="$withval"],
[DEFAULT_XKB_VARAINT=])
if ! test "x$DEFAULT_XKB_VARIANT" = x; then
AC_DEFINE_UNQUOTED([DEFAULT_XKB_VARIANT], ["$DEFAULT_XKB_VARIANT"],
[Default XKB variant])
fi
AC_ARG_WITH([default_options],
[AS_HELP_STRING([--with-default-options=<path>],
[Default XKB options (default: (none))])],
[DEFAULT_XKB_OPTIONS="$withval"],
[DEFAULT_XKB_OPTIONS=])
if ! test "x$DEFAULT_XKB_OPTIONS" = x; then
AC_DEFINE_UNQUOTED([DEFAULT_XKB_OPTIONS], ["$DEFAULT_XKB_OPTIONS"],
[Default XKB options])
fi
AC_CONFIG_FILES([
Makefile
xkbcommon-uninstalled.pc

View File

@ -44,6 +44,8 @@ struct xkb_context {
int log_verbosity;
void *user_data;
struct xkb_rule_names names_dflt;
darray(char *) includes;
darray(char *) failed_includes;
@ -52,6 +54,8 @@ struct xkb_context {
/* Buffer for the *Text() functions. */
char text_buffer[2048];
size_t text_next;
unsigned int use_environment_names : 1;
};
/**
@ -271,6 +275,14 @@ log_verbosity(const char *verbosity) {
return 0;
}
#ifndef DEFAULT_XKB_VARIANT
#define DEFAULT_XKB_VARIANT NULL
#endif
#ifndef DEFAULT_XKB_OPTIONS
#define DEFAULT_XKB_OPTIONS NULL
#endif
/**
* Create a new context.
*/
@ -305,6 +317,8 @@ xkb_context_new(enum xkb_context_flags flags)
return NULL;
}
ctx->use_environment_names = !(flags & XKB_CONTEXT_NO_ENVIRONMENT_NAMES);
ctx->atom_table = atom_table_new();
if (!ctx->atom_table) {
xkb_context_unref(ctx);
@ -418,3 +432,61 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
return rtrn;
}
const char *
xkb_context_get_default_rules(struct xkb_context *ctx)
{
const char *env = NULL;
if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_RULES");
return env ? env : DEFAULT_XKB_RULES;
}
const char *
xkb_context_get_default_model(struct xkb_context *ctx)
{
const char *env = NULL;
if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_MODEL");
return env ? env : DEFAULT_XKB_MODEL;
}
const char *
xkb_context_get_default_layout(struct xkb_context *ctx)
{
const char *env = NULL;
if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_LAYOUT");
return env ? env : DEFAULT_XKB_LAYOUT;
}
const char *
xkb_context_get_default_variant(struct xkb_context *ctx)
{
const char *env = NULL;
const char *layout = getenv("XKB_DEFAULT_VARIANT");
/* We don't want to inherit the variant if they haven't also set a
* layout, since they're so closely paired. */
if (layout && ctx->use_environment_names)
env = getenv("XKB_DEFAULT_VARIANT");
return env ? env : DEFAULT_XKB_VARIANT;
}
const char *
xkb_context_get_default_options(struct xkb_context *ctx)
{
const char *env = NULL;
if (ctx->use_environment_names)
env = getenv("XKB_DEFAULT_OPTIONS");
return env ? env : DEFAULT_XKB_OPTIONS;
}

View File

@ -77,6 +77,21 @@ xkb_log(struct xkb_context *ctx, enum xkb_log_level level,
xkb_log_cond_level((ctx), (level), __VA_ARGS__); \
} while (0)
const char *
xkb_context_get_default_rules(struct xkb_context *ctx);
const char *
xkb_context_get_default_model(struct xkb_context *ctx);
const char *
xkb_context_get_default_layout(struct xkb_context *ctx);
const char *
xkb_context_get_default_variant(struct xkb_context *ctx);
const char *
xkb_context_get_default_options(struct xkb_context *ctx);
/*
* The format is not part of the argument list in order to avoid the
* "ISO C99 requires rest arguments to be used" warning when only the

View File

@ -153,13 +153,24 @@ xkb_keymap_new_from_names(struct xkb_context *ctx,
return NULL;
}
rmlvo = *rmlvo_in;
if (rmlvo_in)
rmlvo = *rmlvo_in;
else
memset(&rmlvo, 0, sizeof(rmlvo));
if (isempty(rmlvo.rules))
rmlvo.rules = DEFAULT_XKB_RULES;
rmlvo.rules = xkb_context_get_default_rules(ctx);
if (isempty(rmlvo.model))
rmlvo.model = DEFAULT_XKB_MODEL;
if (isempty(rmlvo.layout))
rmlvo.layout = DEFAULT_XKB_LAYOUT;
rmlvo.model = xkb_context_get_default_model(ctx);
/* Layout and variant are tied together, so don't try to use one from
* the caller and one from the environment. */
if (isempty(rmlvo.layout)) {
rmlvo.layout = xkb_context_get_default_layout(ctx);
rmlvo.variant = xkb_context_get_default_variant(ctx);
}
/* Options can be empty, so respect that if passed in. */
if (rmlvo.options == NULL)
rmlvo.options = xkb_context_get_default_options(ctx);
keymap = xkb_keymap_new(ctx, format, flags);
if (!keymap)

View File

@ -61,13 +61,6 @@ main(int argc, char *argv[])
}
}
if (isempty(rmlvo.rules))
rmlvo.rules = DEFAULT_XKB_RULES;
if (isempty(rmlvo.model))
rmlvo.model = DEFAULT_XKB_MODEL;
if (isempty(rmlvo.layout))
rmlvo.layout = DEFAULT_XKB_LAYOUT;
ctx = test_get_context(0);
if (!ctx) {
fprintf(stderr, "Failed to get xkb context\n");

View File

@ -417,7 +417,9 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym);
/** Flags for context creation. */
enum xkb_context_flags {
/** Create this context with an empty include path. */
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0)
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
/** Don't take RMLVO names from the environment. */
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
};
/**