From: Frederic Crozat Date: Fri, 19 Aug 2011 15:29:49 +0000 Subject: handle disable_caplock and compose_table and kbd_rate (bnc#746595) --- src/vconsole/vconsole-setup.c | 156 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 153 insertions(+), 3 deletions(-) diff --git a/src/vconsole/vconsole-setup.c b/src/vconsole/vconsole-setup.c index c1f662b..5f3354e 100644 --- a/src/vconsole/vconsole-setup.c +++ b/src/vconsole/vconsole-setup.c @@ -40,6 +40,7 @@ #include "macro.h" #include "virt.h" #include "fileio.h" +#include "strv.h" static bool is_vconsole(int fd) { unsigned char data[1]; @@ -99,8 +100,8 @@ static int enable_utf8(int fd) { return r; } -static int keymap_load(const char *vc, const char *map, const char *map_toggle, bool utf8, pid_t *_pid) { - const char *args[8]; +static int keymap_load(const char *vc, const char *map, const char *map_toggle, bool utf8, bool disable_capslock, pid_t *_pid) { + const char *args[9]; int i = 0; pid_t pid; @@ -119,6 +120,8 @@ static int keymap_load(const char *vc, const char *map, const char *map_toggle, args[i++] = map; if (map_toggle) args[i++] = map_toggle; + if (disable_capslock) + args[i++] = "disable.capslock"; args[i++] = NULL; pid = fork(); @@ -217,6 +220,101 @@ static void font_copy_to_all_vcs(int fd) { } } +#ifdef HAVE_SYSV_COMPAT +static int load_compose_table(const char *vc, const char *compose_table, pid_t *_pid) { + const char *args[1024]; + int i = 0, j = 0; + pid_t pid; + char **strv_compose_table = NULL; + char *to_free[1024]; + + if (isempty(compose_table)) { + /* An empty map means no compose table*/ + *_pid = 0; + return 0; + } + + args[i++] = KBD_LOADKEYS; + args[i++] = "-q"; + args[i++] = "-C"; + args[i++] = vc; + + strv_compose_table = strv_split(compose_table, WHITESPACE); + if (strv_compose_table) { + bool compose_loaded = false; + bool compose_clear = false; + char **name; + char *arg; + + STRV_FOREACH (name, strv_compose_table) { + if (streq(*name,"-c") || streq(*name,"clear")) { + compose_clear = true; + continue; + } + if (!compose_loaded) { + if (compose_clear) + args[i++] = "-c"; + } + asprintf(&arg, "compose.%s",*name); + compose_loaded = true; + args[i++] = to_free[j++] = arg; + + } + strv_free(strv_compose_table); + } + args[i++] = NULL; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + + for (i=0 ; i < j ; i++) + free (to_free[i]); + + return 0; +} +#endif + +static int set_kbd_rate(const char *vc, const char *kbd_rate, const char *kbd_delay, pid_t *_pid) { + const char *args[7]; + int i = 0; + pid_t pid; + + if (isempty(kbd_rate) && isempty(kbd_delay)) { + *_pid = 0; + return 0; + } + + args[i++] = "/bin/kbdrate"; + if (!isempty(kbd_rate)) { + args[i++] = "-r"; + args[i++] = kbd_rate; + } + if (!isempty(kbd_delay)) { + args[i++] = "-d"; + args[i++] = kbd_delay; + } + args[i++] = "-s"; + args[i++] = NULL; + + if ((pid = fork()) < 0) { + log_error("Failed to fork: %m"); + return -errno; + } else if (pid == 0) { + execv(args[0], (char **) args); + _exit(EXIT_FAILURE); + } + + *_pid = pid; + return 0; +} + int main(int argc, char **argv) { const char *vc; char *vc_keymap = NULL; @@ -224,8 +322,16 @@ int main(int argc, char **argv) { char *vc_font = NULL; char *vc_font_map = NULL; char *vc_font_unimap = NULL; +#ifdef HAVE_SYSV_COMPAT + char *vc_kbd_delay = NULL; + char *vc_kbd_rate = NULL; + char *vc_kbd_disable_caps_lock = NULL; + char *vc_compose_table = NULL; + pid_t kbd_rate_pid = 0, compose_table_pid = 0; +#endif int fd = -1; bool utf8; + bool disable_capslock = false; pid_t font_pid = 0, keymap_pid = 0; bool font_copy = false; int r = EXIT_FAILURE; @@ -286,13 +392,43 @@ int main(int argc, char **argv) { log_warning("Failed to read /etc/vconsole.conf: %s", strerror(-r)); } + if (r <= 0) { +#ifdef HAVE_SYSV_COMPAT + r = parse_env_file("/etc/sysconfig/keyboard", NEWLINE, + "KEYTABLE", &vc_keymap, + "KBD_DELAY", &vc_kbd_delay, + "KBD_RATE", &vc_kbd_rate, + "KBD_DISABLE_CAPS_LOCK", &vc_kbd_disable_caps_lock, + "COMPOSETABLE", &vc_compose_table, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/keyboard: %s", strerror(-r)); + + r = parse_env_file("/etc/sysconfig/console", NEWLINE, + "CONSOLE_FONT", &vc_font, + "CONSOLE_SCREENMAP", &vc_font_map, + "CONSOLE_UNICODEMAP", &vc_font_unimap, + NULL); + if (r < 0 && r != -ENOENT) + log_warning("Failed to read /etc/sysconfig/console: %s", strerror(-r)); + + disable_capslock = vc_kbd_disable_caps_lock && strcasecmp(vc_kbd_disable_caps_lock, "YES") == 0; + +#endif + } + if (utf8) enable_utf8(fd); else disable_utf8(fd); r = EXIT_FAILURE; - if (keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, &keymap_pid) >= 0 && + + if (keymap_load(vc, vc_keymap, vc_keymap_toggle, utf8, disable_capslock, &keymap_pid) >= 0 && +#ifdef HAVE_SYSV_COMPAT + load_compose_table(vc, vc_compose_table, &compose_table_pid) >= 0 && + set_kbd_rate(vc, vc_kbd_rate, vc_kbd_delay, &kbd_rate_pid) >= 0 && +#endif font_load(vc, vc_font, vc_font_map, vc_font_unimap, &font_pid) >= 0) r = EXIT_SUCCESS; @@ -300,6 +436,14 @@ finish: if (keymap_pid > 0) wait_for_terminate_and_warn(KBD_LOADKEYS, keymap_pid); +#ifdef HAVE_SYSV_COMPAT + if (compose_table_pid > 0) + wait_for_terminate_and_warn(KBD_LOADKEYS, compose_table_pid); + + if (kbd_rate_pid > 0) + wait_for_terminate_and_warn("/bin/kbdrate", kbd_rate_pid); +#endif + if (font_pid > 0) { wait_for_terminate_and_warn(KBD_SETFONT, font_pid); if (font_copy) @@ -310,6 +454,12 @@ finish: free(vc_font); free(vc_font_map); free(vc_font_unimap); +#ifdef HAVE_SYSV_COMPAT + free(vc_kbd_delay); + free(vc_kbd_rate); + free(vc_kbd_disable_caps_lock); + free(vc_compose_table); +#endif if (fd >= 0) close_nointr_nofail(fd);