Merge pull request #27355 from fbuihuu/kbd-improve-vc2x11-conversion

locale: improve vc -> x11 keyboard conversion
This commit is contained in:
Luca Boccassi
2023-04-26 23:37:53 +01:00
committed by GitHub
3 changed files with 94 additions and 16 deletions
+56 -8
View File
@@ -655,6 +655,7 @@ static int read_next_mapping(
int vconsole_convert_to_x11(const VCContext *vc, X11Context *ret) {
_cleanup_fclose_ FILE *f = NULL;
const char *map;
X11Context xc;
int r;
assert(vc);
@@ -672,15 +673,12 @@ int vconsole_convert_to_x11(const VCContext *vc, X11Context *ret) {
for (unsigned n = 0;;) {
_cleanup_strv_free_ char **a = NULL;
X11Context xc;
r = read_next_mapping(map, 5, UINT_MAX, f, &n, &a);
if (r < 0)
return r;
if (r == 0) {
*ret = (X11Context) {};
return 0;
}
if (r == 0)
break;
if (!streq(vc->keymap, a[0]))
continue;
@@ -697,6 +695,47 @@ int vconsole_convert_to_x11(const VCContext *vc, X11Context *ret) {
return x11_context_copy(ret, &xc);
}
/* No custom mapping has been found, see if the keymap is a converted one. In such case deducing the
* corresponding x11 layout is easy. */
_cleanup_free_ char *xlayout = NULL, *converted = NULL;
char *xvariant;
xlayout = strdup(vc->keymap);
if (!xlayout)
return -ENOMEM;
xvariant = strchr(xlayout, '-');
if (xvariant) {
xvariant[0] = '\0';
xvariant++;
}
/* Note: by default we use keyboard model "microsoftpro" which should be equivalent to "pc105" but
* with the internet/media key mapping added. */
xc = (X11Context) {
.layout = xlayout,
.model = (char*) "microsoftpro",
.variant = xvariant,
.options = (char*) "terminate:ctrl_alt_bksp",
};
/* This sanity check seems redundant with the verification of the X11 layout done on the next
* step. However xkbcommon is an optional dependency hence the verification might be a NOP. */
r = find_converted_keymap(&xc, &converted);
if (r == 0 && xc.variant) {
/* If we still haven't find a match, try with no variant, it's still better than nothing. */
xc.variant = NULL;
r = find_converted_keymap(&xc, &converted);
}
if (r < 0)
return r;
if (r == 0 || x11_context_verify(&xc) < 0) {
*ret = (X11Context) {};
return 0;
}
return x11_context_copy(ret, &xc);
}
int find_converted_keymap(const X11Context *xc, char **ret) {
@@ -817,12 +856,12 @@ int find_legacy_keymap(const X11Context *xc, char **ret) {
* matches just the first layout.
*/
l = strndup(xc->layout, strcspn(xc->layout, ","));
l = strdupcspn(xc->layout, ",");
if (!l)
return -ENOMEM;
if (!isempty(xc->variant)) {
v = strndup(xc->variant, strcspn(xc->variant, ","));
v = strdupcspn(xc->variant, ",");
if (!v)
return -ENOMEM;
}
@@ -856,8 +895,17 @@ int x11_convert_to_vconsole(const X11Context *xc, VCContext *ret) {
}
r = find_converted_keymap(xc, &keymap);
if (r == 0)
if (r == 0) {
r = find_legacy_keymap(xc, &keymap);
if (r == 0 && xc->variant)
/* If we still haven't find a match, try with no variant, it's still better than
* nothing. */
r = find_converted_keymap(
&(X11Context) {
.layout = xc->layout,
},
&keymap);
}
if (r < 0)
return r;
+30
View File
@@ -44,6 +44,7 @@ TEST(find_converted_keymap) {
assert_se(r == 1);
assert_se(streq(ans, "pl"));
ans = mfree(ans);
assert_se(find_converted_keymap(
&(X11Context) {
@@ -73,6 +74,7 @@ TEST(find_legacy_keymap) {
TEST(vconsole_convert_to_x11) {
_cleanup_(x11_context_clear) X11Context xc = {};
_cleanup_(vc_context_clear) VCContext vc = {};
int r;
log_info("/* test empty keymap */");
assert_se(vconsole_convert_to_x11(&vc, &xc) >= 0);
@@ -111,6 +113,34 @@ TEST(vconsole_convert_to_x11) {
assert_se(vconsole_convert_to_x11(&vc, &xc) >= 0);
assert_se(streq(xc.layout, "us"));
assert_se(xc.variant == NULL);
x11_context_clear(&xc);
/* "gh" has no mapping in kbd-model-map and kbd provides a converted keymap for this layout. */
log_info("/* test with a converted keymap (gh:) */");
assert_se(free_and_strdup(&vc.keymap, "gh") >= 0);
r = vconsole_convert_to_x11(&vc, &xc);
if (r == 0) {
log_info("Skipping rest of %s: keymaps are not installed", __func__);
return;
}
assert_se(r > 0);
assert_se(streq(xc.layout, "gh"));
assert_se(xc.variant == NULL);
x11_context_clear(&xc);
log_info("/* test with converted keymap and with a known variant (gh:ewe) */");
assert_se(free_and_strdup(&vc.keymap, "gh-ewe") >= 0);
assert_se(vconsole_convert_to_x11(&vc, &xc) > 0);
assert_se(streq(xc.layout, "gh"));
assert_se(streq(xc.variant, "ewe"));
x11_context_clear(&xc);
log_info("/* test with converted keymap and with an unknown variant (gh:ewe) */");
assert_se(free_and_strdup(&vc.keymap, "gh-foobar") > 0);
assert_se(vconsole_convert_to_x11(&vc, &xc) > 0);
assert_se(streq(xc.layout, "gh"));
assert_se(xc.variant == NULL);
x11_context_clear(&xc);
}
TEST(x11_convert_to_vconsole) {
+8 -8
View File
@@ -273,15 +273,15 @@ test_vc_keymap() {
assert_in "XKBVARIANT=intl" "$vc"
assert_in "XKBOPTIONS=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_in "X11 Layout: us" "$output"
assert_in "X11 Model: microsoftpro" "$output"
assert_in "X11 Variant:" "$output"
assert_in "X11 Options: terminate:ctrl_alt_bksp" "$output"
assert_not_in "XKBLAYOUT" "$vc"
assert_not_in "XKBMODEL" "$vc"
assert_not_in "XKBVARIANT" "$vc"
assert_not_in "XKBOPTIONS" "$vc"
assert_in "XKBLAYOUT=us" "$vc"
assert_in "XKBMODEL=microsoftpro" "$vc"
assert_in "XKBVARIANT=" "$vc"
assert_in "XKBOPTIONS=terminate:ctrl_alt_bksp" "$vc"
fi
done