summaryrefslogtreecommitdiff
path: root/src/locale
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-12-21 03:09:58 +0900
committerLuca Boccassi <bluca@debian.org>2023-01-23 11:30:03 +0000
commit8589823f9d9187bde27ab41a157f07afd59deaad (patch)
tree79ef0be3cc5d6919b9a84d966e99b1bf0f766a7d /src/locale
parent50ec824570d31847a1abaa65fa03036cda2aa25a (diff)
downloadsystemd-8589823f9d9187bde27ab41a157f07afd59deaad.tar.gz
locale: also save XKB settings to vconsole.conf
Closes #24228. Replaces #25412.
Diffstat (limited to 'src/locale')
-rw-r--r--src/locale/localed-util.c51
-rw-r--r--src/locale/localed-util.h1
-rw-r--r--src/locale/localed.c14
-rw-r--r--src/locale/test-localed-util.c2
4 files changed, 54 insertions, 14 deletions
diff --git a/src/locale/localed-util.c b/src/locale/localed-util.c
index 99f76a14bc..003663054c 100644
--- a/src/locale/localed-util.c
+++ b/src/locale/localed-util.c
@@ -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)) {
diff --git a/src/locale/localed-util.h b/src/locale/localed-util.h
index 36c6d903f2..a3e763f850 100644
--- a/src/locale/localed-util.h
+++ b/src/locale/localed-util.h
@@ -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;
diff --git a/src/locale/localed.c b/src/locale/localed.c
index 0312963f3e..68c014fd47 100644
--- a/src/locale/localed.c
+++ b/src/locale/localed.c
@@ -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)
diff --git a/src/locale/test-localed-util.c b/src/locale/test-localed-util.c
index d99ccba748..3d96b3aa85 100644
--- a/src/locale/test-localed-util.c
+++ b/src/locale/test-localed-util.c
@@ -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);