xkb: Store the action filters per device in the XkbSrvInfoRec.

Using a global array for action filters is bad. If two keyboard hit a modifier
at the same time, releaseing the first one will deactivate the filter and
thus the second keyboard can never release the modifier again.
This commit is contained in:
Peter Hutterer 2007-09-04 17:44:51 +09:30
parent cc5c926267
commit bfe6b4d2d9
2 changed files with 57 additions and 49 deletions

View File

@ -126,6 +126,24 @@ typedef struct _XkbEventCause {
#define _BEEP_LED_CHANGE 14 #define _BEEP_LED_CHANGE 14
#define _BEEP_BOUNCE_REJECT 15 #define _BEEP_BOUNCE_REJECT 15
struct _XkbSrvInfo; /* definition see below */
typedef struct _XkbFilter {
CARD16 keycode;
CARD8 what;
CARD8 active;
CARD8 filterOthers;
CARD32 priv;
XkbAction upAction;
int (*filter)(
struct _XkbSrvInfo* /* xkbi */,
struct _XkbFilter * /* filter */,
unsigned /* keycode */,
XkbAction * /* action */
);
struct _XkbFilter *next;
} XkbFilterRec,*XkbFilterPtr;
typedef struct _XkbSrvInfo { typedef struct _XkbSrvInfo {
XkbStateRec prev_state; XkbStateRec prev_state;
XkbStateRec state; XkbStateRec state;
@ -169,6 +187,9 @@ typedef struct _XkbSrvInfo {
OsTimerPtr bounceKeysTimer; OsTimerPtr bounceKeysTimer;
OsTimerPtr repeatKeyTimer; OsTimerPtr repeatKeyTimer;
OsTimerPtr krgTimer; OsTimerPtr krgTimer;
int szFilters;
XkbFilterPtr filters;
} XkbSrvInfoRec, *XkbSrvInfoPtr; } XkbSrvInfoRec, *XkbSrvInfoPtr;
#define XkbSLI_IsDefault (1L<<0) #define XkbSLI_IsDefault (1L<<0)

View File

@ -73,7 +73,7 @@ XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
if (!AllocateDevicePrivate(device, xkbDevicePrivateIndex)) if (!AllocateDevicePrivate(device, xkbDevicePrivateIndex))
return; return;
xkbPrivPtr = (xkbDeviceInfoPtr) xalloc(sizeof(xkbDeviceInfoRec)); xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec));
if (!xkbPrivPtr) if (!xkbPrivPtr)
return; return;
xkbPrivPtr->unwrapProc = NULL; xkbPrivPtr->unwrapProc = NULL;
@ -237,22 +237,6 @@ XkbAction fake;
#define SYNTHETIC_KEYCODE 1 #define SYNTHETIC_KEYCODE 1
#define BTN_ACT_FLAG 0x100 #define BTN_ACT_FLAG 0x100
typedef struct _XkbFilter {
CARD16 keycode;
CARD8 what;
CARD8 active;
CARD8 filterOthers;
CARD32 priv;
XkbAction upAction;
int (*filter)(
XkbSrvInfoPtr /* xkbi */,
struct _XkbFilter * /* filter */,
unsigned /* keycode */,
XkbAction * /* action */
);
struct _XkbFilter *next;
} XkbFilterRec,*XkbFilterPtr;
static int static int
_XkbFilterSetState( XkbSrvInfoPtr xkbi, _XkbFilterSetState( XkbSrvInfoPtr xkbi,
XkbFilterPtr filter, XkbFilterPtr filter,
@ -1099,32 +1083,32 @@ int button;
} }
#endif #endif
static int szFilters = 0;
static XkbFilterPtr filters = NULL;
static XkbFilterPtr static XkbFilterPtr
_XkbNextFreeFilter( _XkbNextFreeFilter(
void XkbSrvInfoPtr xkbi
) )
{ {
register int i; register int i;
if (szFilters==0) { if (xkbi->szFilters==0) {
szFilters = 4; xkbi->szFilters = 4;
filters = _XkbTypedCalloc(szFilters,XkbFilterRec); xkbi->filters = _XkbTypedCalloc(xkbi->szFilters,XkbFilterRec);
/* 6/21/93 (ef) -- XXX! deal with allocation failure */ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
} }
for (i=0;i<szFilters;i++) { for (i=0;i<xkbi->szFilters;i++) {
if (!filters[i].active) { if (!xkbi->filters[i].active) {
filters[i].keycode = 0; xkbi->filters[i].keycode = 0;
return &filters[i]; return &xkbi->filters[i];
} }
} }
szFilters*=2; xkbi->szFilters*=2;
filters= _XkbTypedRealloc(filters,szFilters,XkbFilterRec); xkbi->filters= _XkbTypedRealloc(xkbi->filters,
xkbi->szFilters,
XkbFilterRec);
/* 6/21/93 (ef) -- XXX! deal with allocation failure */ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
bzero(&filters[szFilters/2],(szFilters/2)*sizeof(XkbFilterRec)); bzero(&xkbi->filters[xkbi->szFilters/2],
return &filters[szFilters/2]; (xkbi->szFilters/2)*sizeof(XkbFilterRec));
return &xkbi->filters[xkbi->szFilters/2];
} }
static int static int
@ -1133,9 +1117,10 @@ _XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
register int i,send; register int i,send;
send= 1; send= 1;
for (i=0;i<szFilters;i++) { for (i=0;i<xkbi->szFilters;i++) {
if ((filters[i].active)&&(filters[i].filter)) if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
send= ((*filters[i].filter)(xkbi,&filters[i],kc,pAction)&&send); send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction)
&& send);
} }
return send; return send;
} }
@ -1164,6 +1149,8 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
keyc= kbd->key; keyc= kbd->key;
xkbi= keyc->xkbInfo; xkbi= keyc->xkbInfo;
key= xE->u.u.detail; key= xE->u.u.detail;
/* The state may change, so if we're not in the middle of sending a state
* notify, prepare for it */
if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
oldState= xkbi->state; oldState= xkbi->state;
xkbi->flags|= _XkbStateNotifyInProgress; xkbi->flags|= _XkbStateNotifyInProgress;
@ -1200,62 +1187,62 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
switch (act.type) { switch (act.type) {
case XkbSA_SetMods: case XkbSA_SetMods:
case XkbSA_SetGroup: case XkbSA_SetGroup:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
break; break;
case XkbSA_LatchMods: case XkbSA_LatchMods:
case XkbSA_LatchGroup: case XkbSA_LatchGroup:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
break; break;
case XkbSA_LockMods: case XkbSA_LockMods:
case XkbSA_LockGroup: case XkbSA_LockGroup:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
break; break;
case XkbSA_ISOLock: case XkbSA_ISOLock:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
break; break;
case XkbSA_MovePtr: case XkbSA_MovePtr:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
break; break;
case XkbSA_PtrBtn: case XkbSA_PtrBtn:
case XkbSA_LockPtrBtn: case XkbSA_LockPtrBtn:
case XkbSA_SetPtrDflt: case XkbSA_SetPtrDflt:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
break; break;
case XkbSA_Terminate: case XkbSA_Terminate:
sendEvent= XkbDDXTerminateServer(dev,key,&act); sendEvent= XkbDDXTerminateServer(dev,key,&act);
break; break;
case XkbSA_SwitchScreen: case XkbSA_SwitchScreen:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
break; break;
case XkbSA_SetControls: case XkbSA_SetControls:
case XkbSA_LockControls: case XkbSA_LockControls:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterControls(xkbi,filter,key,&act); sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
break; break;
case XkbSA_ActionMessage: case XkbSA_ActionMessage:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
break; break;
case XkbSA_RedirectKey: case XkbSA_RedirectKey:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
break; break;
#ifdef XINPUT #ifdef XINPUT
case XkbSA_DeviceBtn: case XkbSA_DeviceBtn:
case XkbSA_LockDeviceBtn: case XkbSA_LockDeviceBtn:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
break; break;
#endif #endif
case XkbSA_XFree86Private: case XkbSA_XFree86Private:
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
break; break;
} }
@ -1355,7 +1342,7 @@ unsigned clear;
act.type = XkbSA_LatchMods; act.type = XkbSA_LatchMods;
act.mods.flags = 0; act.mods.flags = 0;
act.mods.mask = mask&latches; act.mods.mask = mask&latches;
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
return Success; return Success;
@ -1375,7 +1362,7 @@ XkbAction act;
act.type = XkbSA_LatchGroup; act.type = XkbSA_LatchGroup;
act.group.flags = 0; act.group.flags = 0;
XkbSASetGroup(&act.group,group); XkbSASetGroup(&act.group,group);
filter = _XkbNextFreeFilter(); filter = _XkbNextFreeFilter(xkbi);
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
_XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
return Success; return Success;