[PATCH] xkb: ensure enough symbols for core Group1 replication.

Peter Hutterer peter.hutterer at who-t.net
Mon Dec 1 22:45:21 PST 2008


From: Peter Hutterer <peter.hutterer at redhat.com>

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 at redhat.com>
---
 xkb/xkbUtils.c |   19 +++++++++++++++++--
 1 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c
index 6c90756..313d418 100644
--- a/xkb/xkbUtils.c
+++ b/xkb/xkbUtils.c
@@ -361,17 +361,19 @@ _X_EXPORT 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)
-- 
1.6.0.4




More information about the xorg mailing list