summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-09-04 17:44:51 +0930
committerDaniel Stone <daniel@fooishbar.org>2007-10-28 15:51:10 +0200
commit8b9481a113b56078191e2298bf590905978f6289 (patch)
tree1e01c0838e929e088f458585ff26187c1a499fd4
parent493b83bd097372ae0023da9919da83af39e3fc1c (diff)
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 bfe6b4d2d9952a80f8dbc63eec974ef894e5c226)
-rw-r--r--include/xkbsrv.h21
-rw-r--r--xkb/xkbActions.c85
2 files changed, 57 insertions, 49 deletions
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index e43e8fde4..bb2316de6 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -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)
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index 2e0c89fc2..ef67d64e8 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -72,7 +72,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;
@@ -236,22 +236,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,
@@ -1097,32 +1081,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
@@ -1131,9 +1115,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;
}
@@ -1161,6 +1146,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;
@@ -1197,62 +1184,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;
}
@@ -1352,7 +1339,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;
@@ -1372,7 +1359,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;