LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File handle-disable_caplock-and-compose_table-and-kbd_rate.patch of Package systemd (Project Base:System)

Original-From: Frederic Crozat <fcrozat@suse.com>
Original-Date: Fri, 19 Aug 2011 15:29:49 +0000
Subject: handle disable_caplock and compose_table and kbd_rate
References: https://bugzilla.opensuse.org/746595
Last-Editor: Jan Engelhardt <jengelh@inai.de>
Date: Fri Jun 19 21:36:27 CEST 2015

---
 src/vconsole/vconsole-setup.c |  151 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 147 insertions(+), 4 deletions(-)

Index: systemd-221/src/vconsole/vconsole-setup.c
===================================================================
--- systemd-221.orig/src/vconsole/vconsole-setup.c
+++ systemd-221/src/vconsole/vconsole-setup.c
@@ -35,6 +35,8 @@
 #include "log.h"
 #include "virt.h"
 #include "fileio.h"
+#include "macro.h"
+#include "strv.h"
 #include "process-util.h"
 #include "terminal-util.h"
 #include "signal-util.h"
@@ -99,8 +101,10 @@ static int enable_utf8(int fd) {
         return r;
 }
 
-static int keyboard_load_and_wait(const char *vc, const char *map, const char *map_toggle, bool utf8) {
-        const char *args[8];
+static int keyboard_load_and_wait(const char *vc, const char *map,
+    const char *map_toggle, bool utf8, bool disable_capslock)
+{
+        const char *args[9];
         int i = 0, r;
         pid_t pid;
 
@@ -117,6 +121,8 @@ static int keyboard_load_and_wait(const
         args[i++] = map;
         if (map_toggle)
                 args[i++] = map_toggle;
+        if (disable_capslock)
+                args[i++] = "disable.capslock";
         args[i++] = NULL;
 
         pid = fork();
@@ -246,11 +252,117 @@ static void font_copy_to_all_vcs(int fd)
         }
 }
 
+#ifdef HAVE_SYSV_COMPAT
+static int compose_load_and_wait(const char *vc, const char *compose_table)
+{
+        const char *args[1024];
+        unsigned int i = 0, j = 0;
+        int ret;
+        pid_t pid;
+        char **strv_compose_table = NULL;
+        char *to_free[1024];
+
+        if (isempty(compose_table))
+                /* An empty map means no compose table */
+                return 1;
+
+        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 && compose_clear)
+                                args[i++] = "-c";
+                        asprintf(&arg, "compose.%s", *name);
+                        compose_loaded = true;
+                        args[i++] = to_free[j++] = arg;
+                        if (i >= ELEMENTSOF(args) - 1)
+                                break;
+                }
+                strv_free(strv_compose_table);
+        }
+        args[i++] = NULL;
+
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "Failed to fork: %m");
+        if (pid == 0) {
+                reset_all_signal_handlers();
+                reset_signal_mask();
+                execv(args[0], (char **) args);
+                _exit(EXIT_FAILURE);
+        }
+
+        ret = wait_for_terminate_and_warn(args[0], pid, true);
+        for (i = 0; i < j; ++i)
+                free(to_free[i]);
+        if (ret < 0)
+                return ret;
+        return ret == 0;
+}
+#endif
+
+static int kbdrate_set_and_wait(const char *vc, const char *kbd_rate,
+    const char *kbd_delay)
+{
+        const char *args[7];
+        int i = 0, ret;
+        pid_t pid;
+
+        if (isempty(kbd_rate) && isempty(kbd_delay))
+                return 1;
+
+        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;
+
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "Failed to fork: %m");
+        if (pid == 0) {
+                reset_all_signal_handlers();
+                reset_signal_mask();
+                execv(args[0], (char **) args);
+                _exit(EXIT_FAILURE);
+        }
+        ret = wait_for_terminate_and_warn(args[0], pid, true);
+        if (ret < 0)
+                return ret;
+        return ret == 0;
+}
+
 int main(int argc, char **argv) {
         const char *vc;
         _cleanup_free_ char
                 *vc_keymap = NULL, *vc_keymap_toggle = NULL,
                 *vc_font = NULL, *vc_font_map = NULL, *vc_font_unimap = NULL;
+#ifdef HAVE_SYSV_COMPAT
+        _cleanup_free_ char
+                *vc_kbd_delay = NULL, *vc_kbd_rate = NULL,
+                *vc_kbd_disable_caps_lock = NULL, *vc_compose_table = NULL;
+#endif
+        bool disable_capslock = false;
+        bool comp_ok, rate_ok;
         _cleanup_close_ int fd = -1;
         bool utf8, font_copy = false, font_ok, keyboard_ok;
         int r = EXIT_FAILURE;
@@ -281,6 +393,31 @@ int main(int argc, char **argv) {
 
         utf8 = is_locale_utf8();
 
+#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 /* HAVE_SYSV_COMPAT */
+
         r = parse_env_file("/etc/vconsole.conf", NEWLINE,
                            "KEYMAP", &vc_keymap,
                            "KEYMAP_TOGGLE", &vc_keymap_toggle,
@@ -312,11 +449,17 @@ int main(int argc, char **argv) {
                 (void) disable_utf8(fd);
 
         font_ok = font_load_and_wait(vc, vc_font, vc_font_map, vc_font_unimap) > 0;
-        keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle, utf8) > 0;
+        keyboard_ok = keyboard_load_and_wait(vc, vc_keymap, vc_keymap_toggle,
+                                             utf8, disable_capslock) > 0;
+#ifdef HAVE_SYSV_COMPAT
+        comp_ok = compose_load_and_wait(vc, vc_compose_table);
+        rate_ok = kbdrate_set_and_wait(vc, vc_kbd_rate, vc_kbd_delay);
+#endif
 
         /* Only copy the font when we executed setfont successfully */
         if (font_copy && font_ok)
                 (void) font_copy_to_all_vcs(fd);
 
-        return font_ok && keyboard_ok ? EXIT_SUCCESS : EXIT_FAILURE;
+        return font_ok && keyboard_ok && comp_ok && rate_ok ?
+               EXIT_SUCCESS : EXIT_FAILURE;
 }