Add /etc/xkb as extra lookup path for system data files

This completes the usual triplet of configuration locations available for most
processes:
- vendor-provided data files in /usr/share/X11/xkb
- system-specific data files in /etc/xkb
- user-specific data files in $XDG_CONFIG_HOME/xkb

The default lookup order user, system, vendor, just like everything else that
uses these conventions.

For include directives in rules files, the '%E' resolves to that path.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
master
Peter Hutterer 2020-07-10 08:50:02 +10:00 committed by Ran Benita
parent 05d6efc417
commit d7b39f6ffb
10 changed files with 48 additions and 3 deletions

View File

@ -73,6 +73,9 @@ Notes:
%H: %H:
The value of the HOME environment variable. The value of the HOME environment variable.
%E:
The extra lookup path for system-wide XKB data (usually /etc/xkb/rules).
%S: %S:
The system-installed rules directory (usually /usr/share/X11/xkb/rules). The system-installed rules directory (usually /usr/share/X11/xkb/rules).
``` ```

View File

@ -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` - `$XDG_CONFIG_HOME/xkb/`, or `$HOME/.config/xkb/` if the `$XDG_CONFIG_HOME`
environment variable is not defined environment variable is not defined
- `$HOME/.xkb/` - `$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 - `$XKB_CONFIG_ROOT` if set, otherwise `<datadir>/X11/xkb/` (path defined by the
`xkeyboard-config` package, on most distributions this is `xkeyboard-config` package, on most distributions this is
`/usr/share/X11/xkb`) `/usr/share/X11/xkb`)

View File

@ -47,6 +47,10 @@ if XKBCONFIGROOT == ''
endif endif
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. # The X locale directory for compose.
XLOCALEDIR = get_option('x-locale-root') XLOCALEDIR = get_option('x-locale-root')
@ -70,6 +74,7 @@ endif
configh_data.set(system_extensions, 1) configh_data.set(system_extensions, 1)
system_ext_define = '#define ' + system_extensions system_ext_define = '#define ' + system_extensions
configh_data.set_quoted('DFLT_XKB_CONFIG_ROOT', XKBCONFIGROOT) 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('XLOCALEDIR', XLOCALEDIR)
configh_data.set_quoted('DEFAULT_XKB_RULES', get_option('default-rules')) configh_data.set_quoted('DEFAULT_XKB_RULES', get_option('default-rules'))
configh_data.set_quoted('DEFAULT_XKB_MODEL', get_option('default-model')) configh_data.set_quoted('DEFAULT_XKB_MODEL', get_option('default-model'))

View File

@ -3,6 +3,11 @@ option(
type: 'string', type: 'string',
description: 'The XKB config root [default=xkeyboard-config install path]', 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( option(
'x-locale-root', 'x-locale-root',
type: 'string', type: 'string',

View File

@ -83,6 +83,13 @@ err:
return 0; return 0;
} }
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 * const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx) xkb_context_include_path_get_system_path(struct xkb_context *ctx)
{ {
@ -96,7 +103,7 @@ xkb_context_include_path_get_system_path(struct xkb_context *ctx)
XKB_EXPORT int XKB_EXPORT int
xkb_context_include_path_append_default(struct xkb_context *ctx) xkb_context_include_path_append_default(struct xkb_context *ctx)
{ {
const char *home, *xdg, *root; const char *home, *xdg, *root, *extra;
char *user_path; char *user_path;
int ret = 0; 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); root = xkb_context_include_path_get_system_path(ctx);
ret |= xkb_context_include_path_append(ctx, root); ret |= xkb_context_include_path_append(ctx, root);

View File

@ -59,6 +59,9 @@ const char *
xkb_context_failed_include_path_get(struct xkb_context *ctx, xkb_context_failed_include_path_get(struct xkb_context *ctx,
unsigned int idx); unsigned int idx);
const char *
xkb_context_include_path_get_extra_path(struct xkb_context *ctx);
const char * const char *
xkb_context_include_path_get_system_path(struct xkb_context *ctx); xkb_context_include_path_get_system_path(struct xkb_context *ctx);

View File

@ -583,7 +583,7 @@ err:
XKB_EXPORT bool XKB_EXPORT bool
rxkb_context_include_path_append_default(struct rxkb_context *ctx) rxkb_context_include_path_append_default(struct rxkb_context *ctx)
{ {
const char *home, *xdg, *root; const char *home, *xdg, *root, *extra;
char *user_path; char *user_path;
bool ret = false; 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"); root = secure_getenv("XKB_CONFIG_ROOT");
if (root != NULL) if (root != NULL)
ret |= rxkb_context_include_path_append(ctx, root); ret |= rxkb_context_include_path_append(ctx, root);

View File

@ -399,6 +399,13 @@ matcher_include(struct matcher *m, struct scanner *parent_scanner,
return; 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 { else {
scanner_err(&s, "unknown %% format (%c) in include statement", peek(&s)); scanner_err(&s, "unknown %% format (%c) in include statement", peek(&s));
return; return;

View File

@ -306,5 +306,7 @@ if __name__ == '__main__':
# to override it with a known (empty) directory. Otherwise our test # to override it with a known (empty) directory. Otherwise our test
# behavior depends on the system the test is run on. # behavior depends on the system the test is run on.
os.environ['XDG_CONFIG_HOME'] = tmpdir 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__])) sys.exit(pytest.main(args=[__file__]))

View File

@ -553,7 +553,7 @@ xkb_keysym_to_lower(xkb_keysym_t ks);
* *
* The user may set some environment variables which affect the library: * 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_LEVEL` - see xkb_context_set_log_level().
* - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity(). * - `XKB_LOG_VERBOSITY` - see xkb_context_set_log_verbosity().
* - `XKB_DEFAULT_RULES`, `XKB_DEFAULT_MODEL`, `XKB_DEFAULT_LAYOUT`, * - `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. * fallback to `$HOME/.config/` if unset.
* - The path `$HOME/.xkb`, where $HOME is the value of the environment * - The path `$HOME/.xkb`, where $HOME is the value of the environment
* variable `HOME`. * 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 `XKB_CONFIG_ROOT` environment variable, if defined, otherwise
* the system XKB root, defined at library configuration time. * the system XKB root, defined at library configuration time.
* *