summaryrefslogtreecommitdiff
path: root/xkb/xkbUtils.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@redhat.com>2008-09-19 18:27:24 +0930
committerPeter Hutterer <peter.hutterer@redhat.com>2008-09-26 09:33:39 +0930
commitae986d1c73d2f720bd0309d8c33328d14e8eed25 (patch)
tree22b4a92b6c3795baea8bb2d1e33d5ef252d24db1 /xkb/xkbUtils.c
parent5bf3f0fd4e00f96cfebd14b58580c3c8733626fb (diff)
xkb: fix core keyboard map generation. #14373
According to Section 12.4 of the XKB Protocol Spec, if a key only has a single group but the keyboard has multiple groups defined, the core description of the key is a duplication of the single group across all symbols. i.e. G1L1 G1L2 G1L1 G1L2 G1L3 G1L4 G1L3 G1L4 The previous code generated G1L1 G1L2 G1L3 G1L4 G1L3 G1L4, leading to "invented" groups when the process is reversed. Note that this creates wrong key types on reconstruction from core to xkb, i.e. any single-group key with a key type that is not one of the canonical four (Sec 12.2.3), will get the assigned type on group 1, and a canonical type for the other gruops. X.Org Bug 14373 <http://bugs.freedesktop.org/show_bug.cgi?id=14373>
Diffstat (limited to 'xkb/xkbUtils.c')
-rw-r--r--xkb/xkbUtils.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 486446ac7..7e9f8d0e8 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -504,6 +504,40 @@ CARD8 keysPerMod[XkbNumModifiers];
if (groupWidth>2)
nOut= groupWidth;
}
+
+ /* See XKB Protocol Sec, Section 12.4.
+ A 1-group key with ABCDE on a 2 group keyboard must be
+ duplicated across all groups as ABABCDECDE.
+ */
+ if (nGroups == 1)
+ {
+ int idx;
+
+ groupWidth = XkbKeyGroupWidth(xkb, key, XkbGroup1Index);
+
+ /* AB..CDE... -> ABABCDE... */
+ if (groupWidth > 0 && maxSymsPerKey >= 3)
+ pCore[2] = pCore[0];
+ if (groupWidth > 1 && maxSymsPerKey >= 4)
+ pCore[3] = pCore[1];
+
+ /* ABABCDE... -> ABABCDECDE */
+ idx = 2 + groupWidth;
+ while (groupWidth > 2 &&
+ idx < maxSymsPerKey &&
+ idx < groupWidth * 2)
+ {
+ pCore[idx] = pCore[idx - groupWidth + 2];
+ idx++;
+ }
+ idx = 2 * groupWidth;
+ if (idx < 4)
+ idx = 4;
+ /* 3 or more groups: ABABCDECDEABCDEABCDE */
+ for (n = 0; n < groupWidth && idx < maxSymsPerKey; n++)
+ pCore[idx++] = pXKB[n];
+ }
+
pXKB+= XkbKeyGroupsWidth(xkb,key);
nOut+= 2;
if (nGroups>1) {
@@ -525,11 +559,6 @@ CARD8 keysPerMod[XkbNumModifiers];
}
pXKB+= XkbKeyGroupsWidth(xkb,key);
}
- if (!pCore[2] && !pCore[3] && maxSymsPerKey >= 6 &&
- (pCore[4] || pCore[5])) {
- pCore[2] = pCore[4];
- pCore[3] = pCore[5];
- }
}
if (keyc->modifierMap[key]!=0) {
register unsigned bit,i,mask;