From 50cfc579280fb42569488079bd2e249e32a27df2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 5 Apr 2013 00:23:23 +0200 Subject: [PATCH 1/1] localectl: add support for listing X11 keymap information --- man/localectl.xml | 17 +++++ src/locale/localectl.c | 148 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 147 insertions(+), 18 deletions(-) diff --git a/man/localectl.xml b/man/localectl.xml index 5e7886c10..0b13c111a 100644 --- a/man/localectl.xml +++ b/man/localectl.xml @@ -215,6 +215,23 @@ mapping. + + list-x11-keymap-models + list-x11-keymap-layouts + list-x11-keymap-variants [LAYOUT] + list-x11-keymap-options + + List available X11 + keymap models, layouts, variants and + options, useful for configuration with + set-keymap. The + command + list-x11-keymap-variants + optionally takes a layout parameter to + limit the output to the variants + suitable for the specific + layout. + diff --git a/src/locale/localectl.c b/src/locale/localectl.c index fc312894c..5739a1dcd 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -606,24 +606,132 @@ static int set_x11_keymap(DBusConnection *bus, char **args, unsigned n) { DBUS_TYPE_INVALID); } +static int list_x11_keymaps(DBusConnection *bus, char **args, unsigned n) { + _cleanup_fclose_ FILE *f = NULL; + char _cleanup_strv_free_ **list = NULL; + char line[LINE_MAX]; + enum { + NONE, + MODELS, + LAYOUTS, + VARIANTS, + OPTIONS + } state = NONE, look_for; + int r; + + if (n > 2) { + log_error("Too many arguments."); + return -EINVAL; + } + + f = fopen("/usr/share/X11/xkb/rules/xorg.lst", "re"); + if (!f) { + log_error("Failed to open keyboard mapping list. %m"); + return -errno; + } + + if (streq(args[0], "list-x11-keymap-models")) + look_for = MODELS; + else if (streq(args[0], "list-x11-keymap-layouts")) + look_for = LAYOUTS; + else if (streq(args[0], "list-x11-keymap-variants")) + look_for = VARIANTS; + else if (streq(args[0], "list-x11-keymap-options")) + look_for = OPTIONS; + else + assert_not_reached("Wrong parameter"); + + FOREACH_LINE(line, f, break) { + char *l, *w; + + l = strstrip(line); + + if (isempty(l)) + continue; + + if (l[0] == '!') { + if (startswith(l, "! model")) + state = MODELS; + else if (startswith(l, "! layout")) + state = LAYOUTS; + else if (startswith(l, "! variant")) + state = VARIANTS; + else if (startswith(l, "! option")) + state = OPTIONS; + else + state = NONE; + + continue; + } + + if (state != look_for) + continue; + + w = l + strcspn(l, WHITESPACE); + + if (n > 1) { + char *e; + + if (*w == 0) + continue; + + *w = 0; + w++; + w += strspn(w, WHITESPACE); + + e = strchr(w, ':'); + if (!e) + continue; + + *e = 0; + + if (!streq(w, args[1])) + continue; + } else + *w = 0; + + r = strv_extend(&list, l); + if (r < 0) + return log_oom(); + } + + if (strv_isempty(list)) { + log_error("Couldn't find any entries."); + return -ENOENT; + } + + strv_sort(list); + strv_uniq(list); + + pager_open_if_enabled(); + + strv_print(list); + return 0; +} + static int help(void) { printf("%s [OPTIONS...] COMMAND ...\n\n" "Query or change system locale and keyboard settings.\n\n" - " -h --help Show this help\n" - " --version Show package version\n" - " --no-convert Don't convert keyboard mappings\n" - " --no-pager Do not pipe output into a pager\n" - " --no-ask-password Do not prompt for password\n" - " -H --host=[USER@]HOST Operate on remote host\n\n" + " -h --help Show this help\n" + " --version Show package version\n" + " --no-convert Don't convert keyboard mappings\n" + " --no-pager Do not pipe output into a pager\n" + " --no-ask-password Do not prompt for password\n" + " -H --host=[USER@]HOST Operate on remote host\n\n" "Commands:\n" - " status Show current locale settings\n" - " set-locale LOCALE... Set system locale\n" - " list-locales Show known locales\n" - " set-keymap MAP [MAP] Set virtual console keyboard mapping\n" - " list-keymaps Show known virtual console keyboard mappings\n" + " status Show current locale settings\n" + " set-locale LOCALE... Set system locale\n" + " list-locales Show known locales\n" + " set-keymap MAP [MAP] Set virtual console keyboard mapping\n" + " list-keymaps Show known virtual console keyboard mappings\n" " set-x11-keymap LAYOUT [MODEL] [VARIANT] [OPTIONS]\n" - " Set X11 keyboard mapping\n", + " Set X11 keyboard mapping\n" + " list-x11-keymap-models Show known X11 keyboard mapping models\n" + " list-x11-keymap-layouts Show known X11 keyboard mapping layouts\n" + " list-x11-keymap-variants [LAYOUT]\n" + " Show known X11 keyboard mapping variants\n" + " list-x11-keymap-options Show known X11 keyboard mapping options\n", program_invocation_short_name); return 0; @@ -708,12 +816,16 @@ static int localectl_main(DBusConnection *bus, int argc, char *argv[], DBusError const int argc; int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); } verbs[] = { - { "status", LESS, 1, show_status }, - { "set-locale", MORE, 2, set_locale }, - { "list-locales", EQUAL, 1, list_locales }, - { "set-keymap", MORE, 2, set_vconsole_keymap }, - { "list-keymaps", EQUAL, 1, list_vconsole_keymaps }, - { "set-x11-keymap", MORE, 2, set_x11_keymap }, + { "status", LESS, 1, show_status }, + { "set-locale", MORE, 2, set_locale }, + { "list-locales", EQUAL, 1, list_locales }, + { "set-keymap", MORE, 2, set_vconsole_keymap }, + { "list-keymaps", EQUAL, 1, list_vconsole_keymaps }, + { "set-x11-keymap", MORE, 2, set_x11_keymap }, + { "list-x11-keymap-models", EQUAL, 1, list_x11_keymaps }, + { "list-x11-keymap-layouts", EQUAL, 1, list_x11_keymaps }, + { "list-x11-keymap-variants", LESS, 2, list_x11_keymaps }, + { "list-x11-keymap-options", EQUAL, 1, list_x11_keymaps }, }; int left; -- 2.30.2