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