Skip to content

Commit

Permalink
locale: also save XKB settings to vconsole.conf
Browse files Browse the repository at this point in the history
Closes systemd#24228.
Replaces systemd#25412.
  • Loading branch information
yuwata committed Dec 23, 2022
1 parent 8ad5321 commit 8a90dd7
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 18 deletions.
43 changes: 41 additions & 2 deletions src/locale/localed-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,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) {
Expand All @@ -167,14 +168,18 @@ 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;

return NULL;
}

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) {
Expand Down Expand Up @@ -225,10 +230,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) {
Expand All @@ -240,6 +250,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, skipping to read 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)
Expand Down Expand Up @@ -337,6 +356,7 @@ 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);
Expand All @@ -353,6 +373,25 @@ int vconsole_write_data(Context *c) {
if (r < 0)
return r;

xc = context_get_x11_context(c);
if (xc) {
r = strv_env_assign(&l, "XKB_LAYOUT", empty_to_null(xc->layout));
if (r < 0)
return r;

r = strv_env_assign(&l, "XKB_MODEL", empty_to_null(xc->model));
if (r < 0)
return r;

r = strv_env_assign(&l, "XKB_VARIANT", empty_to_null(xc->variant));
if (r < 0)
return r;

r = strv_env_assign(&l, "XKB_OPTIONS", empty_to_null(xc->options));
if (r < 0)
return r;
}

if (strv_isempty(l)) {
if (unlink("/etc/vconsole.conf") < 0)
return errno == ENOENT ? 0 : -errno;
Expand Down
1 change: 1 addition & 0 deletions src/locale/localed-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
14 changes: 3 additions & 11 deletions src/locale/localed.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/locale/test-localed-util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
48 changes: 44 additions & 4 deletions test/units/testsuite-73.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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"
Expand Down

0 comments on commit 8a90dd7

Please sign in to comment.