diff options
author | Peter Hutterer <peter.hutterer@redhat.com> | 2008-12-02 13:31:58 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2008-12-23 09:02:28 +1000 |
commit | a157575eeeb523cd43197c5caeb00cb3d56f9988 (patch) | |
tree | c983498bd9ff533345545a2c957a81498a7c9cc3 /xkb/xkbUtils.c | |
parent | b5736d237a21d5e65d839c4d213dd3bda5a11e9d (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.c | 19 |
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) |