]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
locale: also save XKB settings to vconsole.conf 25805/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Dec 2022 18:09:58 +0000 (03:09 +0900)
committerLuca Boccassi <bluca@debian.org>
Mon, 23 Jan 2023 11:30:03 +0000 (11:30 +0000)
Closes #24228.
Replaces #25412.

src/locale/localed-util.c
src/locale/localed-util.h
src/locale/localed.c
src/locale/test-localed-util.c
test/units/testsuite-73.sh

index 99f76a14bcc5bad023996767194ba34de8ecd785..003663054c9e21cf560c0a5ff8d88325e11bccb6 100644 (file)
@@ -149,6 +149,7 @@ static void context_clear_x11(Context *c) {
         assert(c);
 
         x11_context_clear(&c->x11_from_xorg);
+        x11_context_clear(&c->x11_from_vc);
 }
 
 static void context_clear_vconsole(Context *c) {
@@ -175,6 +176,9 @@ void context_clear(Context *c) {
 static X11Context *context_get_x11_context(Context *c) {
         assert(c);
 
+        if (!x11_context_isempty(&c->x11_from_vc))
+                return &c->x11_from_vc;
+
         if (!x11_context_isempty(&c->x11_from_xorg))
                 return &c->x11_from_xorg;
 
@@ -182,7 +186,8 @@ static X11Context *context_get_x11_context(Context *c) {
 }
 
 X11Context *context_get_x11_context_safe(Context *c) {
-        return &ASSERT_PTR(c)->x11_from_xorg;
+        assert(c);
+        return context_get_x11_context(c) ?: &c->x11_from_vc;
 }
 
 int locale_read_data(Context *c, sd_bus_message *m) {
@@ -233,10 +238,15 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
 
         c->vc_stat = st;
         context_clear_vconsole(c);
+        x11_context_clear(&c->x11_from_vc);
 
         return parse_env_file_fd(fd, "/etc/vconsole.conf",
                                  "KEYMAP",        &c->vc_keymap,
-                                 "KEYMAP_TOGGLE", &c->vc_keymap_toggle);
+                                 "KEYMAP_TOGGLE", &c->vc_keymap_toggle,
+                                 "XKB_LAYOUT",    &c->x11_from_vc.layout,
+                                 "XKB_MODEL",     &c->x11_from_vc.model,
+                                 "XKB_VARIANT",   &c->x11_from_vc.variant,
+                                 "XKB_OPTIONS",   &c->x11_from_vc.options);
 }
 
 int x11_read_data(Context *c, sd_bus_message *m) {
@@ -248,6 +258,15 @@ int x11_read_data(Context *c, sd_bus_message *m) {
 
         assert(c);
 
+        r = vconsole_read_data(c, m);
+        if (r < 0)
+                return r;
+
+        if (!x11_context_isempty(&c->x11_from_vc)) {
+                log_debug("XKB settings loaded from vconsole.conf, not reading xorg.conf.d/00-keyboard.conf.");
+                return 0;
+        }
+
         /* Do not try to re-read the file within single bus operation. */
         if (m) {
                 if (m == c->x11_cache)
@@ -345,10 +364,18 @@ int x11_read_data(Context *c, sd_bus_message *m) {
 
 int vconsole_write_data(Context *c) {
         _cleanup_strv_free_ char **l = NULL;
+        const X11Context *xc;
         int r;
 
         assert(c);
 
+        xc = context_get_x11_context(c);
+
+        /* If the X11 context is from xorg.conf, then sync one from vconsole.conf with it. */
+        r = x11_context_copy(&c->x11_from_vc, xc);
+        if (r < 0)
+                return r;
+
         r = load_env_file(NULL, "/etc/vconsole.conf", &l);
         if (r < 0 && r != -ENOENT)
                 return r;
@@ -361,6 +388,22 @@ int vconsole_write_data(Context *c) {
         if (r < 0)
                 return r;
 
+        r = strv_env_assign(&l, "XKB_LAYOUT", xc ? empty_to_null(xc->layout) : NULL);
+        if (r < 0)
+                return r;
+
+        r = strv_env_assign(&l, "XKB_MODEL", xc ? empty_to_null(xc->model) : NULL);
+        if (r < 0)
+                return r;
+
+        r = strv_env_assign(&l, "XKB_VARIANT", xc ? empty_to_null(xc->variant) : NULL);
+        if (r < 0)
+                return r;
+
+        r = strv_env_assign(&l, "XKB_OPTIONS", xc ? empty_to_null(xc->options) : NULL);
+        if (r < 0)
+                return r;
+
         if (strv_isempty(l)) {
                 if (unlink("/etc/vconsole.conf") < 0)
                         return errno == ENOENT ? 0 : -errno;
@@ -493,6 +536,10 @@ int vconsole_convert_to_x11(Context *c) {
 
         assert(c);
 
+        /* If Context.x11_from_vc is empty, then here we update Context.x11_from_xorg, as the caller may
+         * already have been called context_get_x11_context() or _safe(), and otherwise the caller's
+         * X11Context may be outdated. The updated context will be copied to Context.x11_from_vc in
+         * vconsole_write_data() if necessary. */
         xc = context_get_x11_context_safe(c);
 
         if (isempty(c->vc_keymap)) {
index 36c6d903f29e9b54ae94c248ac0b3e1722700e43..a3e763f8505a6e44899fc9762ccac6082c895368 100644 (file)
@@ -22,6 +22,7 @@ typedef struct Context {
         sd_bus_message *x11_cache;
         struct stat x11_stat;
         X11Context x11_from_xorg;
+        X11Context x11_from_vc;
 
         sd_bus_message *vc_cache;
         struct stat vc_stat;
index 0312963f3ebd68c17fbcdc79e56d49e8b0ac57ff..68c014fd47b47297ecc8084a834728c0152a3a28 100644 (file)
@@ -621,12 +621,6 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
                 return log_oom();
 
         if (convert) {
-                r = vconsole_read_data(c, m);
-                if (r < 0) {
-                        log_error_errno(r, "Failed to read virtual console keymap data: %m");
-                        return sd_bus_error_set_errnof(error, r, "Failed to read virtual console keymap data: %m");
-                }
-
                 r = x11_convert_to_vconsole(c);
                 if (r < 0) {
                         log_error_errno(r, "Failed to convert keymap data: %m");
@@ -637,11 +631,9 @@ static int method_set_x11_keyboard(sd_bus_message *m, void *userdata, sd_bus_err
                 convert = r > 0;
         }
 
-        if (convert) {
-                r = vconsole_write_data(c);
-                if (r < 0)
-                        log_warning_errno(r, "Failed to update vconsole.conf, ignoring: %m");
-        }
+        r = vconsole_write_data(c);
+        if (r < 0)
+                log_warning_errno(r, "Failed to update vconsole.conf, ignoring: %m");
 
         r = x11_write_data(c);
         if (r < 0)
index d99ccba7486c6e24b3f842f38696a3195731cef5..3d96b3aa85bd3b1cc93ace5b7462bd8ed15fd6cf 100644 (file)
@@ -72,7 +72,7 @@ TEST(find_legacy_keymap) {
 
 TEST(vconsole_convert_to_x11) {
         _cleanup_(context_clear) Context c = {};
-        X11Context *xc = &c.x11_from_xorg;
+        X11Context *xc = &c.x11_from_vc;
 
         log_info("/* test emptying first (:) */");
         assert_se(free_and_strdup(&xc->layout, "foo") >= 0);
index a4fda36da06d0e03015037ab7f20d00cfab81e73..9ab0d55dd853e4e3fc6ff3654e3793f8bf790e12 100755 (executable)
@@ -225,7 +225,7 @@ wait_vconsole_setup() {
 }
 
 test_vc_keymap() {
-    local i output
+    local i output vc
 
     if [[ -z "$(localectl list-keymaps)" ]]; then
         echo "No vconsole keymap installed, skipping test."
@@ -242,14 +242,15 @@ test_vc_keymap() {
         # clear previous conversion from VC -> X11 keymap
         systemctl stop systemd-localed.service
         wait_vconsole_setup
-        rm -f /etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard
+        rm -f /etc/vconsole.conf /etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard
 
         # set VC keymap
         assert_rc 0 localectl set-keymap "$i"
         output=$(localectl)
 
         # check VC keymap
-        assert_in "KEYMAP=$i" "$(cat /etc/vconsole.conf)"
+        vc=$(cat /etc/vconsole.conf)
+        assert_in "KEYMAP=$i" "$vc"
         assert_in "VC Keymap: $i" "$output"
 
         # check VC -> X11 keymap conversion
@@ -258,16 +259,31 @@ test_vc_keymap() {
             assert_in "X11 Model: pc105\+inet" "$output"
             assert_not_in "X11 Variant:" "$output"
             assert_in "X11 Options: terminate:ctrl_alt_bksp" "$output"
+
+            assert_in "XKB_LAYOUT=us" "$vc"
+            assert_in "XKB_MODEL=pc105\+inet" "$vc"
+            assert_not_in "XKB_VARIANT" "$vc"
+            assert_in "XKB_OPTIONS=terminate:ctrl_alt_bksp" "$vc"
         elif [[ "$i" == "us-acentos" ]]; then
             assert_in "X11 Layout: us" "$output"
             assert_in 'X11 Model: pc105$' "$output"
             assert_in "X11 Variant: intl" "$output"
             assert_in "X11 Options: terminate:ctrl_alt_bksp" "$output"
+
+            assert_in "XKB_LAYOUT=us" "$vc"
+            assert_in "XKB_MODEL=pc105$" "$vc"
+            assert_in "XKB_VARIANT=intl" "$vc"
+            assert_in "XKB_OPTIONS=terminate:ctrl_alt_bksp" "$vc"
         elif [[ "$i" =~ ^us-.* ]]; then
             assert_in "X11 Layout: .unset." "$output"
             assert_not_in "X11 Model:" "$output"
             assert_not_in "X11 Variant:" "$output"
             assert_not_in "X11 Options:" "$output"
+
+            assert_not_in "XKB_LAYOUT" "$vc"
+            assert_not_in "XKB_MODEL" "$vc"
+            assert_not_in "XKB_VARIANT" "$vc"
+            assert_not_in "XKB_OPTIONS" "$vc"
         fi
     done
 
@@ -306,6 +322,12 @@ XKBOPTIONS=terminate:ctrl_alt_bksp"
         assert_in 'Option "XkbModel" "pc105\+inet"' "$output"
         assert_in 'Option "XkbVariant" "intl"' "$output"
         assert_in 'Option "XkbOptions" "terminate:ctrl_alt_bksp"' "$output"
+
+        output=$(cat /etc/vconsole.conf)
+        assert_in 'XKB_LAYOUT=us' "$output"
+        assert_in 'XKB_MODEL=pc105\+inet' "$output"
+        assert_in 'XKB_VARIANT=intl' "$output"
+        assert_in 'XKB_OPTIONS=terminate:ctrl_alt_bksp' "$output"
     fi
 
     output=$(localectl)
@@ -330,6 +352,12 @@ XKBVARIANT=intl"
         assert_in 'Option "XkbModel" "pc105\+inet"' "$output"
         assert_in 'Option "XkbVariant" "intl"' "$output"
         assert_not_in 'Option "XkbOptions"' "$output"
+
+        output=$(cat /etc/vconsole.conf)
+        assert_in 'XKB_LAYOUT=us' "$output"
+        assert_in 'XKB_MODEL=pc105\+inet' "$output"
+        assert_in 'XKB_VARIANT=intl' "$output"
+        assert_not_in 'XKB_OPTIONS' "$output"
     fi
 
     output=$(localectl)
@@ -353,6 +381,12 @@ XKBMODEL=pc105+inet"
         assert_in 'Option "XkbModel" "pc105\+inet"' "$output"
         assert_not_in 'Option "XkbVariant"' "$output"
         assert_not_in 'Option "XkbOptions"' "$output"
+
+        output=$(cat /etc/vconsole.conf)
+        assert_in 'XKB_LAYOUT=us' "$output"
+        assert_in 'XKB_MODEL=pc105\+inet' "$output"
+        assert_not_in 'XKB_VARIANT' "$output"
+        assert_not_in 'XKB_OPTIONS' "$output"
     fi
 
     output=$(localectl)
@@ -375,6 +409,12 @@ XKBMODEL=pc105+inet"
         assert_not_in 'Option "XkbModel"' "$output"
         assert_not_in 'Option "XkbVariant"' "$output"
         assert_not_in 'Option "XkbOptions"' "$output"
+
+        output=$(cat /etc/vconsole.conf)
+        assert_in 'XKB_LAYOUT=us' "$output"
+        assert_not_in 'XKB_MODEL' "$output"
+        assert_not_in 'XKB_VARIANT' "$output"
+        assert_not_in 'XKB_OPTIONS' "$output"
     fi
 
     output=$(localectl)
@@ -385,7 +425,7 @@ XKBMODEL=pc105+inet"
 
     # gets along without config file
     systemctl stop systemd-localed.service
-    rm -f /etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard
+    rm -f /etc/vconsole.conf /etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard
     output=$(localectl)
     assert_in "X11 Layout: .unset." "$output"
     assert_not_in "X11 Model:" "$output"