summaryrefslogtreecommitdiff
path: root/xkb/xkbUtils.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@redhat.com>2008-12-02 13:31:58 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2008-12-23 09:02:28 +1000
commita157575eeeb523cd43197c5caeb00cb3d56f9988 (patch)
treec983498bd9ff533345545a2c957a81498a7c9cc3 /xkb/xkbUtils.c
parentb5736d237a21d5e65d839c4d213dd3bda5a11e9d (diff)
xkb: ensure enough symbols for core Group1 replication.
A single-group key on a multi-group keyboard has to be replicated across all three groups (see Section 12.4 of the XKB protocol spec). Ensure that there's enough symbols available to actually do that. e.g. a key ABCD on a 3 group keyboard needs to be replicated as ABABCDCDABCD, hence requiring space for 12 symbols, even if maxSymsPerKey is less than that. Signed-off-by: Peter Hutterer <peter.hutterer@redhat.com>
Diffstat (limited to 'xkb/xkbUtils.c')
-rw-r--r--xkb/xkbUtils.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6b5acd8c2..f13d292bd 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -361,17 +361,19 @@ void
XkbUpdateCoreDescription(DeviceIntPtr keybd,Bool resize)
{
register int key,tmp;
-int maxSymsPerKey,maxKeysPerMod;
+int maxSymsPerKey,maxKeysPerMod, maxGroup1Width;
int first,last,firstCommon,lastCommon;
XkbDescPtr xkb;
KeyClassPtr keyc;
CARD8 keysPerMod[XkbNumModifiers];
+int maxNumberOfGroups;
if (!keybd || !keybd->key || !keybd->key->xkbInfo)
return;
xkb= keybd->key->xkbInfo->desc;
keyc= keybd->key;
- maxSymsPerKey= maxKeysPerMod= 0;
+ maxSymsPerKey= maxKeysPerMod= maxGroup1Width= 0;
+ maxNumberOfGroups = 0;
bzero(keysPerMod,sizeof(keysPerMod));
memcpy(keyc->modifierMap,xkb->map->modmap,xkb->max_key_code+1);
if ((xkb->min_key_code==keyc->curKeySyms.minKeyCode)&&
@@ -419,6 +421,9 @@ CARD8 keysPerMod[XkbNumModifiers];
if ((w=XkbKeyGroupWidth(xkb,key,XkbGroup1Index))<=2)
tmp+= 2;
else tmp+= w + 2;
+ /* remember highest G1 width */
+ if (w > maxGroup1Width)
+ maxGroup1Width = w;
}
if (nGroups>1) {
if (tmp <= 2) {
@@ -436,6 +441,8 @@ CARD8 keysPerMod[XkbNumModifiers];
tmp+= XkbKeyGroupWidth(xkb,key,XkbGroup4Index);
if (tmp>maxSymsPerKey)
maxSymsPerKey= tmp;
+ if (nGroups > maxNumberOfGroups)
+ maxNumberOfGroups = nGroups;
}
if (_XkbCoreKeycodeInRange(keyc,key)) {
if (keyc->modifierMap[key]!=0) {
@@ -469,6 +476,14 @@ CARD8 keysPerMod[XkbNumModifiers];
keyc->maxKeysPerModifier= maxKeysPerMod;
if (maxSymsPerKey>0) {
+ /* See Section 12.4 of the XKB Protocol spec. Because of the
+ * single-group distribution for multi-group keyboards, we have to
+ * have enough symbols for the largest group 1 to replicate across the
+ * number of groups on the keyboard. e.g. a single-group key with 4
+ * symbols on a keyboard that has 3 groups -> 12 syms per key */
+ if (maxSymsPerKey < maxNumberOfGroups * maxGroup1Width)
+ maxSymsPerKey = maxNumberOfGroups * maxGroup1Width;
+
tmp= maxSymsPerKey*_XkbCoreNumKeys(keyc);
keyc->curKeySyms.map= _XkbTypedRealloc(keyc->curKeySyms.map,tmp,KeySym);
if (keyc->curKeySyms.map==NULL)