diff options
author | Peter Hutterer <peter.hutterer@redhat.com> | 2008-12-02 14:54:50 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2008-12-23 09:02:28 +1000 |
commit | f141c1b4bb9482f188783dd6f161d3c7960a3329 (patch) | |
tree | 35f9b145c7e095c57c6bba39ed1c34bb6a02e8e2 | |
parent | 70a977c021e107c4fabe46ec2f619be9fb55abeb (diff) |
xkb: explicitly check for group replication in the core representation.
Single-group keys may get replicated amongst all groups. Check explicitly for
this case and squash it down to one group.
Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
-rw-r--r-- | xkb/XKBMisc.c | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/xkb/XKBMisc.c b/xkb/XKBMisc.c index 39bbec651..f32410351 100644 --- a/xkb/XKBMisc.c +++ b/xkb/XKBMisc.c @@ -56,6 +56,7 @@ register int i; unsigned int empty; int nSyms[XkbNumKbdGroups]; int nGroups,tmp,groupsWidth; +BOOL replicated = FALSE; /* Section 12.2 of the protocol describes this process in more detail */ /* Step 1: find the # of symbols in the core mapping per group */ @@ -89,27 +90,70 @@ int nGroups,tmp,groupsWidth; for (i=2;i<nSyms[XkbGroup2Index];i++) { xkb_syms_rtrn[XKB_OFFSET(XkbGroup2Index,i)]= CORE_SYM(tmp+i); } - tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index]; - if ((tmp>=map_width)&& - ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { + + /* Special case: if only the first group is explicit, and the symbols + * replicate across all groups, then we have a Section 12.4 replication */ + if ((protected & ~XkbExplicitKeyType1Mask) == 0) + { + int j, width = nSyms[XkbGroup1Index]; + + replicated = TRUE; + + /* Check ABAB in ABABCDECDEABCDE */ + if ((width > 0 && CORE_SYM(0) != CORE_SYM(2)) || + (width > 1 && CORE_SYM(1) != CORE_SYM(3))) + replicated = FALSE; + + /* Check CDECDE in ABABCDECDEABCDE */ + for (i = 2; i < width && replicated; i++) + { + if (CORE_SYM(2 + i) != CORE_SYM(i + width)) + replicated = FALSE; + } + + /* Check ABCDE in ABABCDECDEABCDE */ + for (j = 2; replicated && + j < XkbNumKbdGroups && + map_width >= width * (j + 1); j++) + { + for (i = 0; i < width && replicated; i++) + { + if (CORE_SYM(((i < 2) ? i : 2 + i)) != CORE_SYM(i + width * j)) + replicated = FALSE; + } + } + } + + if (replicated) + { + nSyms[XkbGroup2Index]= 0; nSyms[XkbGroup3Index]= 0; nSyms[XkbGroup4Index]= 0; - nGroups= 2; - } - else { - nGroups= 3; - for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) { - xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp); - } - if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) { - nGroups= 4; - for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) { - xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp); - } - } - else { - nSyms[XkbGroup4Index]= 0; - } + nGroups= 1; + } else + { + tmp= nSyms[XkbGroup1Index]+nSyms[XkbGroup2Index]; + if ((tmp>=map_width)&& + ((protected&(XkbExplicitKeyType3Mask|XkbExplicitKeyType4Mask))==0)) { + nSyms[XkbGroup3Index]= 0; + nSyms[XkbGroup4Index]= 0; + nGroups= 2; + } else + { + nGroups= 3; + for (i=0;i<nSyms[XkbGroup3Index];i++,tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup3Index,i)]= CORE_SYM(tmp); + } + if ((tmp<map_width)||(protected&XkbExplicitKeyType4Mask)) { + nGroups= 4; + for (i=0;i<nSyms[XkbGroup4Index];i++,tmp++) { + xkb_syms_rtrn[XKB_OFFSET(XkbGroup4Index,i)]= CORE_SYM(tmp); + } + } + else { + nSyms[XkbGroup4Index]= 0; + } + } } /* steps 3&4: alphanumeric expansion, assign canonical types */ empty= 0; |