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_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 {
XkbStateRec prev_state;
XkbStateRec state;
@ -169,6 +187,9 @@ typedef struct _XkbSrvInfo {
OsTimerPtr bounceKeysTimer;
OsTimerPtr repeatKeyTimer;
OsTimerPtr krgTimer;
int szFilters;
XkbFilterPtr filters;
} XkbSrvInfoRec, *XkbSrvInfoPtr;
#define XkbSLI_IsDefault (1L<<0)

View File

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