summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/rules-format.md3
-rw-r--r--doc/user-configuration.md2
-rw-r--r--meson.build5
-rw-r--r--meson_options.txt5
-rw-r--r--src/context.c11
-rw-r--r--src/context.h3
-rw-r--r--src/registry.c8
-rw-r--r--src/xkbcomp/rules.c7
-rwxr-xr-xtest/tool-option-parsing.py2
-rw-r--r--xkbcommon/xkbcommon.h5
10 files changed, 48 insertions, 3 deletions
diff --git a/doc/rules-format.md b/doc/rules-format.md
index 96acbbf..f9fe0d9 100644
--- a/doc/rules-format.md
+++ b/doc/rules-format.md
@@ -73,6 +73,9 @@ Notes:
%H:
The value of the HOME environment variable.
+ %E:
+ The extra lookup path for system-wide XKB data (usually /etc/xkb/rules).
+
%S:
The system-installed rules directory (usually /usr/share/X11/xkb/rules).
```
diff --git a/doc/user-configuration.md b/doc/user-configuration.md
index 17e7179..b8c4d30 100644
--- a/doc/user-configuration.md
+++ b/doc/user-configuration.md
@@ -11,6 +11,8 @@ libxkbcommon searches the following paths for XKB configuration files:
- `$XDG_CONFIG_HOME/xkb/`, or `$HOME/.config/xkb/` if the `$XDG_CONFIG_HOME`
environment variable is not defined
- `$HOME/.xkb/`
+- `$XKB_CONFIG_EXTRA_PATH` if set, otherswise `<sysconfdir>/xkb` (on most
+ distributions this is `/etc/xkb`)
- `$XKB_CONFIG_ROOT` if set, otherwise `<datadir>/X11/xkb/` (path defined by the
`xkeyboard-config` package, on most distributions this is
`/usr/share/X11/xkb`)
diff --git a/meson.build b/meson.build
index e7d75aa..c08b40b 100644
--- a/meson.build
+++ b/meson.build
@@ -47,6 +47,10 @@ if XKBCONFIGROOT == ''
endif
endif
+XKBCONFIGEXTRAPATH = get_option('xkb-config-extra-path')
+if XKBCONFIGEXTRAPATH == ''
+ XKBCONFIGEXTRAPATH = join_paths(get_option('prefix'), get_option('sysconfdir'), 'xkb')
+endif
# The X locale directory for compose.
XLOCALEDIR = get_option('x-locale-root')
@@ -70,6 +74,7 @@ endif
configh_data.set(system_extensions, 1)
system_ext_define = '#define ' + system_extensions
configh_data.set_quoted('DFLT_XKB_CONFIG_ROOT', XKBCONFIGROOT)
+configh_data.set_quoted('DFLT_XKB_CONFIG_EXTRA_PATH', XKBCONFIGEXTRAPATH)
configh_data.set_quoted('XLOCALEDIR', XLOCALEDIR)
configh_data.set_quoted('DEFAULT_XKB_RULES', get_option('default-rules'))
configh_data.set_quoted('DEFAULT_XKB_MODEL', get_option('default-model'))
diff --git a/meson_options.txt b/meson_options.txt
index 5eaa081..04982c6 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,6 +4,11 @@ option(
description: 'The XKB config root [default=xkeyboard-config install path]',
)
option(
+ 'xkb-config-extra-path',
+ type: 'string',
+ description: 'Extra lookup path for system-wide XKB data [default=$sysconfdir/xkb]',
+)
+option(
'x-locale-root',
type: 'string',
description: 'The X locale root [default=$datadir/X11/locale]',
diff --git a/src/context.c b/src/context.c
index ef9b774..2abaa9b 100644
--- a/src/context.c
+++ b/src/context.c
@@ -84,6 +84,13 @@ err:
}
const char *
+xkb_context_include_path_get_extra_path(struct xkb_context *ctx)
+{
+ const char *extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
+ return extra ? extra : DFLT_XKB_CONFIG_EXTRA_PATH;
+}
+
+const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx)
{
const char *root = secure_getenv("XKB_CONFIG_ROOT");
@@ -96,7 +103,7 @@ xkb_context_include_path_get_system_path(struct xkb_context *ctx)
XKB_EXPORT int
xkb_context_include_path_append_default(struct xkb_context *ctx)
{
- const char *home, *xdg, *root;
+ const char *home, *xdg, *root, *extra;
char *user_path;
int ret = 0;
@@ -126,6 +133,8 @@ xkb_context_include_path_append_default(struct xkb_context *ctx)
}
}
+ extra = xkb_context_include_path_get_extra_path(ctx);
+ ret |= xkb_context_include_path_append(ctx, extra);
root = xkb_context_include_path_get_system_path(ctx);
ret |= xkb_context_include_path_append(ctx, root);
diff --git a/src/context.h b/src/context.h
index 9584dbc..ead2508 100644
--- a/src/context.h
+++ b/src/context.h
@@ -60,6 +60,9 @@ xkb_context_failed_include_path_get(struct xkb_context *ctx,
unsigned int idx);
const char *
+xkb_context_include_path_get_extra_path(struct xkb_context *ctx);
+
+const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx);
/*
diff --git a/src/registry.c b/src/registry.c
index 956d850..d3d95f5 100644
--- a/src/registry.c
+++ b/src/registry.c
@@ -583,7 +583,7 @@ err:
XKB_EXPORT bool
rxkb_context_include_path_append_default(struct rxkb_context *ctx)
{
- const char *home, *xdg, *root;
+ const char *home, *xdg, *root, *extra;
char *user_path;
bool ret = false;
@@ -618,6 +618,12 @@ rxkb_context_include_path_append_default(struct rxkb_context *ctx)
}
}
+ extra = secure_getenv("XKB_CONFIG_EXTRA_PATH");
+ if (extra != NULL)
+ ret |= rxkb_context_include_path_append(ctx, extra);
+ else
+ ret |= rxkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_EXTRA_PATH);
+
root = secure_getenv("XKB_CONFIG_ROOT");
if (root != NULL)
ret |= rxkb_context_include_path_append(ctx, root);
diff --git a/src/xkbcomp/rules.c b/src/xkbcomp/rules.c
index 3359552..099500a 100644
--- a/src/xkbcomp/rules.c
+++ b/src/xkbcomp/rules.c
@@ -399,6 +399,13 @@ matcher_include(struct matcher *m, struct scanner *parent_scanner,
return;
}
}
+ else if (chr(&s, 'E')) {
+ const char *default_root = xkb_context_include_path_get_extra_path(m->ctx);
+ if (!buf_appends(&s, default_root) || !buf_appends(&s, "/rules")) {
+ scanner_err(&s, "include path after expanding %%E is too long");
+ return;
+ }
+ }
else {
scanner_err(&s, "unknown %% format (%c) in include statement", peek(&s));
return;
diff --git a/test/tool-option-parsing.py b/test/tool-option-parsing.py
index c503176..de638d1 100755
--- a/test/tool-option-parsing.py
+++ b/test/tool-option-parsing.py
@@ -306,5 +306,7 @@ if __name__ == '__main__':
# to override it with a known (empty) directory. Otherwise our test
# behavior depends on the system the test is run on.
os.environ['XDG_CONFIG_HOME'] = tmpdir
+ # This needs to be separated if we do specific extra path testing
+ os.environ['XKB_CONFIG_EXTRA_PATH'] = tmpdir
sys.exit(pytest.main(args=[__file__]))
diff --git a/xkbcommon/xkbcommon.h b/xkbcommon/xkbcommon.h
index c091e5d..5fabc34 100644
--- a/xkbcommon/xkbcommon.h
+++ b/xkbcommon/xkbcommon.h
@@ -553,7 +553,7 @@ xkb_keysym_to_lower(xkb_keysym_t ks);
*
* The user may set some environment variables which affect the library:
*
- * - `XKB_CONFIG_ROOT`, `XDG_CONFIG_DIR`, `HOME` - see @ref include-path.
+ * - `XKB_CONFIG_ROOT`, `XKB_EXTRA_PATH`, `XDG_CONFIG_DIR`, `HOME` - see @ref include-path.
* - `XKB_LOG_LEVEL` - see xkb_context_set_log_level().
* - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity().
* - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`,
@@ -644,6 +644,9 @@ xkb_context_get_user_data(struct xkb_context *context);
* fallback to `$HOME/.config/` if unset.
* - The path `$HOME/.xkb`, where $HOME is the value of the environment
* variable `HOME`.
+ * - The `XKB_EXTRA_PATH` environment variable, if defined, otherwise the
+ * system configuration directory, defined at library configuration time
+ * (usually `/etc/xkb`).
* - The `XKB_CONFIG_ROOT` environment variable, if defined, otherwise
* the system XKB root, defined at library configuration time.
*