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.
(cherry picked from commit bfe6b4d2d9
)
This commit is contained in:
parent
493b83bd09
commit
8b9481a113
|
@ -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)
|
||||||
|
|
|
@ -72,7 +72,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;
|
||||||
|
@ -236,22 +236,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,
|
||||||
|
@ -1097,32 +1081,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
|
||||||
|
@ -1131,9 +1115,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;
|
||||||
}
|
}
|
||||||
|
@ -1161,6 +1146,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;
|
||||||
|
@ -1197,62 +1184,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;
|
||||||
}
|
}
|
||||||
|
@ -1352,7 +1339,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;
|
||||||
|
@ -1372,7 +1359,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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user