Re[2]: Multikey autorepetition

Anton E aeforeve at mail.ru
Wed Sep 15 04:35:20 PDT 2010


> right, the problem here though wasn't whether it's possible in
> hardware but
> whether doing so would break applications.
> I checked the XKB spec, autorepeat is discussed in section 4.1.2 and as I
> read this, this allows for multiple keys to autorepeat. Having said that, it
> remains to be seen if some clients implicitly rely on the current behaviour.
> Антон, can you please resend your patch as a git-formatted patch to the
> list?

> Please CC me and Daniel on it, just in case.


diff --git a/xorg-server-1.9.0/include/xkbsrv.h b/xorg-server-1.9.0.mkr/include/xkbsrv.h
index 9f1507e..67d93e0 100644
--- a/xorg-server-1.9.0/include/xkbsrv.h
+++ b/xorg-server-1.9.0.mkr/include/xkbsrv.h
@@ -171,7 +171,8 @@ typedef struct _XkbSrvInfo {
 	KeyCode		 mouseKey;
 	KeyCode		 inactiveKey;
 	KeyCode		 slowKey;
-	KeyCode		 repeatKey;
+#define	XkbMkrMax	6
+	KeyCode		 repeatKey[XkbMkrMax];
 	CARD8		 krgTimerActive;
 	CARD8		 beepType;
 	CARD8		 beepCount;
@@ -183,7 +184,7 @@ typedef struct _XkbSrvInfo {
 	OsTimerPtr	 mouseKeyTimer;
 	OsTimerPtr	 slowKeysTimer;
 	OsTimerPtr	 bounceKeysTimer;
-	OsTimerPtr	 repeatKeyTimer;
+	OsTimerPtr	 repeatKeyTimer[XkbMkrMax];
 	OsTimerPtr	 krgTimer;
 
 	int		 szFilters;
diff --git a/xorg-server-1.9.0/xkb/xkbAccessX.c b/xorg-server-1.9.0.mkr/xkb/xkbAccessX.c
index 10c38ca..1816e37 100644
--- a/xorg-server-1.9.0/xkb/xkbAccessX.c
+++ b/xorg-server-1.9.0.mkr/xkb/xkbAccessX.c
@@ -70,19 +70,24 @@ AccessXInit(DeviceIntPtr keybd)
 {
 XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
 XkbControlsPtr	ctrls = xkbi->desc->ctrls;
+unsigned	i;
 
     xkbi->shiftKeyCount= 0;
     xkbi->mouseKeysCounter= 0;
     xkbi->inactiveKey= 0;
     xkbi->slowKey= 0;
-    xkbi->repeatKey= 0;
     xkbi->krgTimerActive= _OFF_TIMER;
     xkbi->beepType= _BEEP_NONE;
     xkbi->beepCount= 0;
     xkbi->mouseKeyTimer= NULL;
     xkbi->slowKeysTimer= NULL;
     xkbi->bounceKeysTimer= NULL;
-    xkbi->repeatKeyTimer= NULL;
+
+    for(i=0;i<XkbMkrMax;i++){
+   xkbi->repeatKey[i]= 0;
+   xkbi->repeatKeyTimer[i]= NULL;
+	 }
+
     xkbi->krgTimer= NULL;
     xkbi->beepTimer= NULL;
     ctrls->repeat_delay = XkbDfltRepeatDelay;
@@ -302,16 +307,21 @@ xkbControlsNotify	cn;
     return 0;
 }
 
+
 static CARD32
 AccessXRepeatKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
 {
 DeviceIntPtr    dev = (DeviceIntPtr) arg;
 XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
+unsigned i;
 
-    if (xkbi->repeatKey == 0)
-	return 0;
-
-    AccessXKeyboardEvent(dev, ET_KeyPress, xkbi->repeatKey, TRUE);
+   for(i=0;i<XkbMkrMax;i++)
+	if(xkbi->repeatKeyTimer[i] == timer){
+      	   if (xkbi->repeatKey[i] == 0)
+	      return 0;
+	   AccessXKeyboardEvent(dev, ET_KeyPress, xkbi->repeatKey[i], TRUE);
+	   break;
+	   }
 
     return xkbi->desc->ctrls->repeat_interval;
 }
@@ -319,8 +329,10 @@ XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
 void
 AccessXCancelRepeatKey(XkbSrvInfoPtr xkbi,KeyCode key)
 {
-    if (xkbi->repeatKey==key)
-	xkbi->repeatKey= 0;
+unsigned i;
+   for(i=0;i<XkbMkrMax;i++)
+    if (xkbi->repeatKey[i]==key)
+	xkbi->repeatKey[i]= 0;
     return;
 }
 
@@ -331,6 +343,7 @@ DeviceIntPtr	keybd;
 XkbSrvInfoPtr	xkbi;
 XkbDescPtr	xkb;
 XkbControlsPtr	ctrls;
+unsigned i;
 
     keybd= 	(DeviceIntPtr)arg;
     xkbi= 	keybd->key->xkbInfo;
@@ -359,10 +372,14 @@ XkbControlsPtr	ctrls;
 	    ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) &&
 	     (ctrls->enabled_ctrls&XkbRepeatKeysMask)) {
 	    if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey)) {
-		xkbi->repeatKey = xkbi->slowKey;
-		xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
-					0, ctrls->repeat_delay,
-					AccessXRepeatKeyExpire, (pointer)keybd);
+		for(i=0;i<(XkbMkrMax-1);i++)
+		   if(xkbi->repeatKey[i] == 0)
+		      break;
+		xkbi->repeatKey[i] = xkbi->slowKey;
+		xkbi->repeatKeyTimer[i]= TimerSet(xkbi->repeatKeyTimer[i],0, ctrls->repeat_delay,AccessXRepeatKeyExpire, (pointer)keybd);
+		}
+
+
 	    }
 	}
     }
@@ -450,6 +467,7 @@ XkbControlsPtr	ctrls = xkbi->desc->ctrls;
 Bool		ignoreKeyEvent = FALSE;
 KeyCode		key = event->detail.key;
 KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);
+unsigned i;
 
     if (ctrls->enabled_ctrls&XkbAccessXKeysMask) {
 	/* check for magic sequences */
@@ -526,14 +544,22 @@ KeySym *	sym = XkbKeySymsPtr(xkbi->desc,key);
 	    if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key)) {
 		if (xkbDebugFlags&0x10)
 		    DebugF("Starting software autorepeat...\n");
-		if (xkbi->repeatKey == key)
-		    ignoreKeyEvent = TRUE;
-		else {
-		    xkbi->repeatKey = key;
-		    xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer,
-			    0, ctrls->repeat_delay,
-			    AccessXRepeatKeyExpire, (pointer)keybd);
-		}
+
+   for(i=0;i<XkbMkrMax;i++)
+	if (xkbi->repeatKey[i] == key){
+	   ignoreKeyEvent = TRUE;
+	   break;
+	   }
+   if(i==XkbMkrMax)
+      for(i=0;i<XkbMkrMax;i++){
+	if(xkbi->repeatKey[i] == 0){
+	   xkbi->repeatKey[i] = key;
+	   xkbi->repeatKeyTimer[i]= TimerSet(xkbi->repeatKeyTimer[i],0, ctrls->repeat_delay,AccessXRepeatKeyExpire, (pointer)keybd);
+	   break;
+	   }
+	}
+
+
 	    }
 	}
     }
@@ -582,7 +608,7 @@ XkbSrvInfoPtr	xkbi = keybd->key->xkbInfo;
 XkbControlsPtr	ctrls = xkbi->desc->ctrls;
 KeyCode		key = event->detail.key;
 Bool		ignoreKeyEvent = FALSE;
-    
+int i;
     /* Don't transmit the KeyRelease if BounceKeys is on and
      * this is the release of a key that was ignored due to 
      * BounceKeys.
@@ -626,8 +652,10 @@ Bool		ignoreKeyEvent = FALSE;
     /* Stop Repeating if the user releases the key that is currently
      * repeating.
      */
-    if (xkbi->repeatKey==key) {
-	xkbi->repeatKey= 0;
+   for(i=0;i<XkbMkrMax;i++)
+    if (xkbi->repeatKey[i]==key){
+	xkbi->repeatKey[i]= 0;
+	break;
     }
 
     if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) {
diff --git a/xorg-server-1.9.0/xkb/xkbInit.c b/xorg-server-1.9.0.mkr/xkb/xkbInit.c
index fbf8f14..168b2ce 100644
--- a/xorg-server-1.9.0/xkb/xkbInit.c
+++ b/xorg-server-1.9.0.mkr/xkb/xkbInit.c
@@ -635,6 +635,7 @@ unwind_key:
 void
 XkbFreeInfo(XkbSrvInfoPtr xkbi)
 {
+int i;
     free(xkbi->radioGroups);
     xkbi->radioGroups = NULL;
     if (xkbi->mouseKeyTimer) {
@@ -649,10 +650,11 @@ XkbFreeInfo(XkbSrvInfoPtr xkbi)
 	TimerFree(xkbi->bounceKeysTimer);
 	xkbi->bounceKeysTimer= NULL;
     }
-    if (xkbi->repeatKeyTimer) {
-	TimerFree(xkbi->repeatKeyTimer);
-	xkbi->repeatKeyTimer= NULL;
-    }
+	for(i=0;i<XkbMkrMax;i++)
+    	if (xkbi->repeatKeyTimer[i]) {
+			TimerFree(xkbi->repeatKeyTimer[i]);
+			xkbi->repeatKeyTimer[i]= NULL;
+	}
     if (xkbi->krgTimer) {
 	TimerFree(xkbi->krgTimer);
 	xkbi->krgTimer= NULL;


More information about the xorg-devel mailing list