From 6334d4e7be18de5f237c12a6dc20f75aa23477d0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 6 Sep 2007 18:49:57 +0930 Subject: [PATCH] xkb: enable XI event processing for xkb. XI events can now take the same processing paths as core events, and should do the correct state changes etc. There's some cases where XKB will use KeyPress as type for an event to be delivered to the client. Stuck warnings in, not sure what the correct solution is yet. --- include/xkbsrv.h | 3 ++- xkb/xkbActions.c | 40 +++++++++++++++-------------- xkb/xkbEvents.c | 43 +++++++++++++++++++++++++------ xkb/xkbPrKeyEv.c | 67 +++++++++++++++++++++++++++++++++--------------- 4 files changed, 104 insertions(+), 49 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index be2cff67f..e220f0ac9 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -311,8 +311,9 @@ extern CARD32 xkbDebugFlags; #define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c)) #define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d))) -extern int DeviceKeyPress,DeviceKeyRelease; +extern int DeviceKeyPress,DeviceKeyRelease,DeviceMotionNotify; extern int DeviceButtonPress,DeviceButtonRelease; +extern int DeviceEnterNotify,DeviceLeaveNotify; #ifdef XINPUT #define _XkbIsPressEvent(t) (((t)==KeyPress)||((t)==DeviceKeyPress)) diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 762b6e586..e51b0cca9 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -39,6 +39,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include "xkb.h" #include +#define EXTENSION_EVENT_BASE 64 static unsigned int _xkbServerGeneration; static int xkbDevicePrivateIndex = -1; @@ -83,13 +84,11 @@ XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) proc,xkbUnwrapProc); } -#ifdef XINPUT extern void ProcessOtherEvent( xEvent * /* xE */, DeviceIntPtr /* dev */, int /* count */ ); -#endif /***====================================================================***/ @@ -673,6 +672,7 @@ _XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, &old,xkbi->desc->ctrls, &cn,False)) { cn.keycode = keycode; + /* XXX: what about DeviceKeyPress? */ cn.eventType = KeyPress; cn.requestMajor = 0; cn.requestMinor = 0; @@ -737,6 +737,7 @@ XkbEventCauseRec cause; ctrls->enabled_ctrls|= change; if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,False)) { cn.keycode = keycode; + /* XXX: what about DeviceKeyPress? */ cn.eventType = KeyPress; cn.requestMajor = 0; cn.requestMinor = 0; @@ -878,6 +879,7 @@ ProcessInputProc backupproc; filter->filter = _XkbFilterRedirectKey; filter->upAction = *pAction; + /* XXX: what about DeviceKeyPress */ ev.u.u.type = KeyPress; ev.u.u.detail = pAction->redirect.new_key; @@ -905,6 +907,10 @@ ProcessInputProc backupproc; realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; xkbi->device->key->modifierMap[ev.u.u.detail] = 0; + /* XXX: Bad! Since the switch to XI devices xkbi->device will be the + * XI device. Sending a core event through ProcessOtherEvent will + * cause trouble. Somebody should fix this. + */ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); xkbi->device->public.processInputProc(&ev,xkbi->device,1); COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, @@ -919,6 +925,7 @@ ProcessInputProc backupproc; } else if (filter->keycode==keycode) { + /* XXX: what about DeviceKeyRelease */ ev.u.u.type = KeyRelease; ev.u.u.detail = filter->upAction.redirect.new_key; @@ -946,6 +953,10 @@ ProcessInputProc backupproc; realMods = xkbi->device->key->modifierMap[ev.u.u.detail]; xkbi->device->key->modifierMap[ev.u.u.detail] = 0; + /* XXX: Bad! Since the switch to XI devices xkbi->device will be the + * XI device. Sending a core event through ProcessOtherEvent will + * cause trouble. Somebody should fix this. + */ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); xkbi->device->public.processInputProc(&ev,xkbi->device,1); COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, @@ -1009,7 +1020,6 @@ _XkbFilterXF86Private( XkbSrvInfoPtr xkbi, return 1; } -#ifdef XINPUT static int _XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, @@ -1081,7 +1091,6 @@ int button; } return 0; } -#endif static XkbFilterPtr _XkbNextFreeFilter( @@ -1139,9 +1148,7 @@ XkbAction act; XkbFilterPtr filter; Bool keyEvent; Bool pressEvent; -#ifdef XINPUT Bool xiEvent; -#endif ProcessInputProc backupproc; xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); @@ -1162,7 +1169,6 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); xkbi->groupChange = 0; sendEvent = 1; -#ifdef XINPUT keyEvent= ((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| (xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease)); pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)|| @@ -1170,10 +1176,6 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)|| (xE->u.u.type==DeviceButtonPress)|| (xE->u.u.type==DeviceButtonRelease); -#else - keyEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease); - pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==ButtonPress); -#endif if (pressEvent) { if (keyEvent) @@ -1234,13 +1236,11 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); filter = _XkbNextFreeFilter(xkbi); sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); break; -#ifdef XINPUT case XkbSA_DeviceBtn: case XkbSA_LockDeviceBtn: filter = _XkbNextFreeFilter(xkbi); sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); break; -#endif case XkbSA_XFree86Private: filter = _XkbNextFreeFilter(xkbi); sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); @@ -1279,11 +1279,6 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); } if (sendEvent) { -#ifdef XINPUT - if (xiEvent) - ProcessOtherEvent(xE,dev,count); - else -#endif if (keyEvent) { realMods = keyc->modifierMap[key]; keyc->modifierMap[key] = 0; @@ -1293,7 +1288,14 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); backupproc,xkbUnwrapProc); keyc->modifierMap[key] = realMods; } - else CoreProcessPointerEvent(xE,dev,count); + else + { + if (xE->u.u.type & EXTENSION_EVENT_BASE) + ProcessOtherEvent(xE, dev, count); + else + CoreProcessPointerEvent(xE,dev,count); + + } } else if (keyEvent) FixKeyState(xE,dev); diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c index 973e1ad1d..22ca2d6e9 100644 --- a/xkb/xkbEvents.c +++ b/xkb/xkbEvents.c @@ -34,6 +34,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include "inputstr.h" #include "windowstr.h" #include @@ -814,7 +815,9 @@ GrabInfoPtr grabinfo; if ( pClient->xkbClientFlags & _XkbClientInitialized ) { #ifdef DEBUG if ((xkbDebugFlags&0x10)&& - ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease)|| + (xE[0].u.u.type==DeviceKeyPress)|| + (xE[0].u.u.type == DeviceKeyRelease))) { ErrorF("XKbFilterWriteEvents:\n"); ErrorF(" Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state); ErrorF(" XkbLastRepeatEvent!=xE (0x%p!=0x%p) %s\n", @@ -834,7 +837,9 @@ GrabInfoPtr grabinfo; } if ((pXDev->deviceGrab.grab != NullGrab) && pXDev->deviceGrab.fromPassiveGrab && - ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease)|| + (xE[0].u.u.type==DeviceKeyPress)|| + (xE[0].u.u.type == DeviceKeyRelease))) { register unsigned state,flags; flags= pClient->xkbClientFlags; @@ -879,10 +884,12 @@ GrabInfoPtr grabinfo; type= xE[i].u.u.type; #ifdef DEBUG if ((xkbDebugFlags&0x4)&& - ((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease))) { + ((xE[i].u.u.type==KeyPress)||(xE[i].u.u.type==KeyRelease)|| + (xE[i].u.u.type==DeviceKeyPress)|| + (xE[i].u.u.type == DeviceKeyRelease))) { XkbStatePtr s= &xkbi->state; ErrorF("XKbFilterWriteEvents (non-XKB):\n"); - ErrorF("event= 0x%04x\n",xE[0].u.keyButtonPointer.state); + ErrorF("event= 0x%04x\n",xE[i].u.keyButtonPointer.state); ErrorF("lookup= 0x%02x, grab= 0x%02x\n",s->lookup_mods, s->grab_mods); ErrorF("compat lookup= 0x%02x, grab= 0x%02x\n", @@ -902,9 +909,22 @@ GrabInfoPtr grabinfo; xE[i].u.keyButtonPointer.state= new; } else if ((type==EnterNotify)||(type==LeaveNotify)) { - xE->u.enterLeave.state&= 0x1F00; - xE->u.enterLeave.state|= xkbi->state.compat_grab_mods; - } + xE[i].u.enterLeave.state&= 0x1F00; + xE[i].u.enterLeave.state|= xkbi->state.compat_grab_mods; + } else if ((type>=DeviceKeyPress)&&(type<=DeviceMotionNotify)) { + CARD16 old, new; + deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*)&xE[i]; + old= kbp->state&(~0x1F00); + new= kbp->state&0x1F00; + if (old==XkbStateFieldFromRec(&xkbi->state)) + new|= xkbi->state.compat_lookup_mods; + else new|= xkbi->state.compat_grab_mods; + kbp->state= new; + } else if ((type==DeviceEnterNotify)||(type==DeviceLeaveNotify)) { + deviceEnterNotify *del = (deviceEnterNotify*)&xE[i]; + del->state&=0x1F00; + del->state|= xkbi->state.compat_grab_mods; + } button_mask = 1 << xE[i].u.u.detail; if (type == ButtonPress && ((xE[i].u.keyButtonPointer.state >> 7) & button_mask) == button_mask && @@ -913,7 +933,14 @@ GrabInfoPtr grabinfo; ErrorF("Faking release of button %d\n", xE[i].u.u.detail); #endif XkbDDXFakePointerButton(ButtonRelease, xE[i].u.u.detail); - } + } else if (type == DeviceButtonPress && + ((((deviceKeyButtonPointer*)&xE[i])->state >> 7) & button_mask) == button_mask && + (xkbi->lockedPtrButtons & button_mask) == button_mask) { +#ifdef DEBUG + ErrorF("Faking release of button %d\n", ((deviceKeyButtonPointer*)&xE[i])->state) +#endif + XkbDDXFakePointerButton(DeviceButtonRelease, ((deviceKeyButtonPointer*)&xE[i])->state); + } } } return True; diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c index 02f3c35fe..ba3fcc06c 100644 --- a/xkb/xkbPrKeyEv.c +++ b/xkb/xkbPrKeyEv.c @@ -38,6 +38,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "inputstr.h" #include #include +#define EXTENSION_EVENT_BASE 64 /***====================================================================***/ @@ -50,9 +51,11 @@ XkbSrvInfoPtr xkbi; int key; XkbBehavior behavior; unsigned ndx; +int xiEvent; xkbi= keyc->xkbInfo; key= xE->u.u.detail; + xiEvent= (xE->u.u.type & EXTENSION_EVENT_BASE); #ifdef DEBUG if (xkbDebugFlags&0x8) { ErrorF("XkbPKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up")); @@ -70,51 +73,68 @@ unsigned ndx; /* do anything to implement the behavior, but it *does* report that */ /* key is hardwired */ - /* FIXME: this is bad. The down mask is set during ProcessOtherEvent. When - * we start processing the core event (and eventually arrive here), the - * down mask is already set and Xkb thinks it's a repeat event. We just - * silently ignore it for now. - */ -#if 0 if ((behavior.type&XkbKB_Permanent)==0) { switch (behavior.type) { case XkbKB_Default: - if (( xE->u.u.type == KeyPress ) && + if (( xE->u.u.type == KeyPress || + xE->u.u.type == DeviceKeyPress) && (keyc->down[key>>3] & (1<<(key&7)))) { XkbLastRepeatEvent= (pointer)xE; - xE->u.u.type = KeyRelease; + + if (xiEvent) + xE->u.u.type = DeviceKeyRelease; + else + xE->u.u.type = KeyRelease; XkbHandleActions(keybd,keybd,xE,count); - xE->u.u.type = KeyPress; + + if (xiEvent) + xE->u.u.type = DeviceKeyPress; + else + xE->u.u.type = KeyPress; XkbHandleActions(keybd,keybd,xE,count); XkbLastRepeatEvent= NULL; return; } - else if ((xE->u.u.type==KeyRelease) && + else if ((xE->u.u.type==KeyRelease || + xE->u.u.type == DeviceKeyRelease) && (!(keyc->down[key>>3]&(1<<(key&7))))) { XkbLastRepeatEvent= (pointer)&xE; - xE->u.u.type = KeyPress; + if (xiEvent) + xE->u.u.type = DeviceKeyPress; + else + xE->u.u.type = KeyPress; XkbHandleActions(keybd,keybd,xE,count); - xE->u.u.type = KeyRelease; + if (xiEvent) + xE->u.u.type = DeviceKeyRelease; + else + xE->u.u.type = KeyRelease; XkbHandleActions(keybd,keybd,xE,count); XkbLastRepeatEvent= NULL; return; } break; case XkbKB_Lock: - if ( xE->u.u.type == KeyRelease ) + if ( xE->u.u.type == KeyRelease || + xE->u.u.type == DeviceKeyRelease) return; else { int bit= 1<<(key&7); if ( keyc->down[key>>3]&bit ) - xE->u.u.type= KeyRelease; - } + { + if (xiEvent) + xE->u.u.type = DeviceKeyRelease; + else + xE->u.u.type= KeyRelease; + } + } break; case XkbKB_RadioGroup: ndx= (behavior.data&(~XkbKB_RGAllowNone)); if ( ndxnRadioGroups ) { XkbRadioGroupPtr rg; - if ( xE->u.u.type == KeyRelease ) + if ( xE->u.u.type == KeyRelease || + xE->u.u.type == DeviceKeyRelease) return; rg = &xkbi->radioGroups[ndx]; @@ -128,10 +148,16 @@ unsigned ndx; } if ( rg->currentDown!=0 ) { int key = xE->u.u.detail; - xE->u.u.type= KeyRelease; + if (xiEvent) + xE->u.u.type = DeviceKeyRelease; + else + xE->u.u.type= KeyRelease; xE->u.u.detail= rg->currentDown; XkbHandleActions(keybd,keybd,xE,count); - xE->u.u.type= KeyPress; + if (xiEvent) + xE->u.u.type = DeviceKeyPress; + else + xE->u.u.type= KeyPress; xE->u.u.detail= key; } rg->currentDown= key; @@ -160,7 +186,6 @@ unsigned ndx; break; } } -#endif XkbHandleActions(keybd,keybd,xE,count); return; } @@ -181,9 +206,9 @@ XkbSrvInfoPtr xkbi; #endif if ((xkbi->desc->ctrls->enabled_ctrls&XkbAllFilteredEventsMask)==0) XkbProcessKeyboardEvent(xE,keybd,count); - else if (xE->u.u.type==KeyPress) + else if (xE->u.u.type==KeyPress || xE->u.u.type==DeviceKeyPress) AccessXFilterPressEvent(xE,keybd,count); - else if (xE->u.u.type==KeyRelease) + else if (xE->u.u.type==KeyRelease || xE->u.u.type==DeviceKeyRelease) AccessXFilterReleaseEvent(xE,keybd,count); return; }