xserver: Branch 'mpx' - 9 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Sep 6 23:56:34 PDT 2007


 Xi/exevents.c                  |    3 
 Xi/extinit.c                   |   12 +++
 dix/devices.c                  |   22 ++++---
 dix/events.c                   |   93 ++++++++----------------------
 dix/getevents.c                |   56 ++++++++----------
 hw/xfree86/common/xf86Xinput.c |   13 +---
 include/xkbsrv.h               |   24 +++++++
 randr/rrpointer.c              |   37 +++++++-----
 xkb/xkbActions.c               |  125 ++++++++++++++++++-----------------------
 xkb/xkbEvents.c                |   43 +++++++++++---
 xkb/xkbPrKeyEv.c               |   67 +++++++++++++++------
 11 files changed, 265 insertions(+), 230 deletions(-)

New commits:
diff-tree 72b347e681f5667b68257822e7cec02ab4c9cb6d (from d627061b48ae06d27b37be209d67a3f4f2388dd3)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Fri Sep 7 14:31:19 2007 +0930

    dix: Enabling devices must not overwrite existing sprites/pairing.
    
    EnableDevices is (amongst others )called after a VT switch. We must not create
    a new sprite or re-pair the device, otherwise we lose the input device setup
    that we had before the VT switch.
    
    This requires the devices to be in exactly the same order as before
    the VT switch. Removing a device while on a different VT is probably a bad
    idea.

diff --git a/dix/devices.c b/dix/devices.c
index e606016..3ce045c 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -210,10 +210,13 @@ EnableDevice(DeviceIntPtr dev)
     /* Sprites pop up on the first root window, so we can supply it directly
      * here. 
      */
-    if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
-        InitializeSprite(dev, WindowTable[0]);
-    else
-        PairDevices(NULL, inputInfo.pointer, dev);
+    if (!dev->spriteInfo->sprite)
+    {
+        if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
+            InitializeSprite(dev, WindowTable[0]);
+        else
+            PairDevices(NULL, inputInfo.pointer, dev);
+    }
 
     if ((*prev != dev) || !dev->inited ||
 	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
diff-tree d627061b48ae06d27b37be209d67a3f4f2388dd3 (from 5ee409794ee604fcf84886f70429fc2d6b1ff4f1)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 6 18:57:00 2007 +0930

    xfree86: wrap keyboard devices for XKB.
    
    Call ProcessOtherEvents first, then for all keyboard devices let them be
    wrapped by XKB. This way all XI events will go through XKB.
    
    Note that the VCK is still not wrapped, so core events will bypass XKB.

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 4c9de1f..2436231 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -179,20 +179,15 @@ xf86ActivateDevice(LocalDevicePtr local)
         dev->coreEvents = local->flags & XI86_ALWAYS_CORE; 
         dev->spriteInfo->spriteOwner = !(local->flags & XI86_SHARED_POINTER);
 
+        RegisterOtherDevice(dev);
+
 #ifdef XKB
-        if (!DeviceIsPointerType(dev))
+        if (!DeviceIsPointerType(dev) && !noXkbExtension)
         {
-        /* FIXME: that's not the nice way to do it. XKB wraps the previously
-         * set procs, so if we don't have them here, our event will disappear
-         * in a black hole.*/
-            dev->public.processInputProc = CoreProcessKeyboardEvent;
-            dev->public.realInputProc = CoreProcessKeyboardEvent;
-            if (!noXkbExtension)
-                XkbSetExtension(dev, ProcessKeyboardEvent);
+            XkbSetExtension(dev, ProcessKeyboardEvent);
         }
 #endif
 
-        RegisterOtherDevice(dev);
 
         if (serverGeneration == 1) 
             xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
diff-tree 5ee409794ee604fcf84886f70429fc2d6b1ff4f1 (from 6334d4e7be18de5f237c12a6dc20f75aa23477d0)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 6 18:52:02 2007 +0930

    dix: add XI event support to FixKeyState.
    
    FixKeyState needs to be able to handle XI events, otherwise we get "impossible
    keyboard events" on server zaps and other special key combos.

diff --git a/dix/events.c b/dix/events.c
index 07a191f..ad9ec1c 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3584,7 +3584,7 @@ drawable.id:0;
 #ifdef XKB
 /* This function is used to set the key pressed or key released state -
    this is only used when the pressing of keys does not cause 
-   CoreProcessKeyEvent to be called, as in for example Mouse Keys.
+   the device's processInputProc to be called, as in for example Mouse Keys.
 */
 void
 FixKeyState (xEvent *xE, DeviceIntPtr keybd)
@@ -3597,22 +3597,19 @@ FixKeyState (xEvent *xE, DeviceIntPtr ke
     kptr = &keyc->down[key >> 3];
     bit = 1 << (key & 7);
 
-    if (((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
+    if (((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease)||
+         (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease))
+            ) {
 	DebugF("FixKeyState: Key %d %s\n",key,
-			(xE->u.u.type==KeyPress?"down":"up"));
+               (((xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress))?"down":"up"));
     }
 
-    switch (xE->u.u.type)
-    {
-	case KeyPress: 
+    if (xE->u.u.type == KeyPress || xE->u.u.type == DeviceKeyPress)
 	    *kptr |= bit;
-	    break;
-	case KeyRelease: 
+    else if (xE->u.u.type == KeyRelease || xE->u.u.type == DeviceKeyRelease)
 	    *kptr &= ~bit;
-	    break;
-	default: 
-	    FatalError("Impossible keyboard event");
-    }
+    else
+        FatalError("Impossible keyboard event");
 }
 #endif
 
diff-tree 6334d4e7be18de5f237c12a6dc20f75aa23477d0 (from 49dbe9a757a3d7a0b9ab318242c6cc0cbd4dd1f0)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 6 18:49:57 2007 +0930

    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.

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index be2cff6..e220f0a 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 762b6e5..e51b0cc 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -39,6 +39,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <xkbsrv.h>
 #include "xkb.h"
 #include <ctype.h>
+#define EXTENSION_EVENT_BASE 64
 
 static unsigned int _xkbServerGeneration;
 static int xkbDevicePrivateIndex = -1;
@@ -83,13 +84,11 @@ XkbSetExtension(DeviceIntPtr device, Pro
 			    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	xkb
     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 = XKBDEVICEI
     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 = XKBDEVICEI
     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 = XKBDEVICEI
 		    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 = XKBDEVICEI
     }
 
     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 = XKBDEVICEI
 					 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 973e1ad..22ca2d6 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -34,6 +34,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/Xproto.h>
 #include <X11/keysym.h>
 #include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
 #include "inputstr.h"
 #include "windowstr.h"
 #include <xkbsrv.h>
@@ -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 02f3c35..ba3fcc0 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -38,6 +38,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "inputstr.h"
 #include <xkbsrv.h>
 #include <ctype.h>
+#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 ( ndx<xkbi->nRadioGroups ) {
 		    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;
 }
diff-tree 49dbe9a757a3d7a0b9ab318242c6cc0cbd4dd1f0 (from 03680a384aa423ece75b658f00b96db2628c39fa)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 6 17:27:28 2007 +0930

    dix: close virtual core devices after other devices.
    
    If a device is paired with the VCP, deleting the VCP before the device will
    segfault the server when the sprite should get updated.

diff --git a/dix/devices.c b/dix/devices.c
index fbb6cba..e606016 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -712,9 +712,6 @@ CloseDownDevices(void)
 {
     DeviceIntPtr dev, next;
 
-    CloseDevice(inputInfo.keyboard);
-    CloseDevice(inputInfo.pointer);
-
     for (dev = inputInfo.devices; dev; dev = next)
     {
 	next = dev->next;
@@ -725,6 +722,10 @@ CloseDownDevices(void)
 	next = dev->next;
 	CloseDevice(dev);
     }
+
+    CloseDevice(inputInfo.keyboard);
+    CloseDevice(inputInfo.pointer);
+
     inputInfo.devices = NULL;
     inputInfo.off_devices = NULL;
     inputInfo.keyboard = NULL;
diff-tree 03680a384aa423ece75b658f00b96db2628c39fa (from c4fff050836feeef8390b7197f1de39af2997811)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 6 15:43:47 2007 +0930

    dix: don't change the device struct while processing core events.
    
    The device state needs to be changed while processing the XI event. Core
    events are always processed after XI, so by then the device is already set up
    properly. However, we now rely on DeviceButtonMotionMask to be equal to
    ButtonMotionMask. It already is, but stick a big fat warning in so nobody
    attempts to change it.
    
    This commit disables XKB for the VCK, thus essentially for all devices.
    Temporarily anyway.

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 8f60561..aa2b4c9 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -126,9 +126,6 @@ ProcessOtherEvent(xEventPtr xE, DeviceIn
     ValuatorClassPtr v = device->valuator;
     deviceValuator *xV = (deviceValuator *) xE;
 
-    if (grab && grab->coreGrab && !device->deviceGrab.fromPassiveGrab)
-        return;
-
     CheckMotion(xE, device);
 
     if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 70253fe..1d23809 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -879,8 +879,20 @@ FixExtensionEvents(ExtensionEntry * extE
     SetEventInfo(GetNextExtEventMask(), _deviceButton3Motion);
     SetEventInfo(GetNextExtEventMask(), _deviceButton4Motion);
     SetEventInfo(GetNextExtEventMask(), _deviceButton5Motion);
+
+    /* If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
+     * breaks down. The device needs the dev->button->motionMask. If DBMM is
+     * the same as BMM, we can ensure that both core and device events can be
+     * delivered, without the need for extra structures in the DeviceIntRec.
+     */
     DeviceButtonMotionMask = GetNextExtEventMask();
     SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
+    if (DeviceButtonMotionMask != ButtonMotionMask)
+    {
+        /* This should never happen, but if it does, hide under the
+         * bed and cry for help. */
+        ErrorF("DeviceButtonMotionMask != ButtonMotionMask. Trouble!\n");
+    }
 
     DeviceFocusChangeMask = GetNextExtEventMask();
     SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
diff --git a/dix/devices.c b/dix/devices.c
index 60825c1..fbb6cba 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -458,8 +458,8 @@ InitCoreDevices(void)
 #ifdef XKB
         dev->public.processInputProc = CoreProcessKeyboardEvent;
         dev->public.realInputProc = CoreProcessKeyboardEvent;
-        if (!noXkbExtension)
-           XkbSetExtension(dev, ProcessKeyboardEvent);
+        /*if (!noXkbExtension)*/
+        /*XkbSetExtension(dev, ProcessKeyboardEvent);*/
 #else
         dev->public.processInputProc = ProcessKeyboardEvent;
         dev->public.realInputProc = ProcessKeyboardEvent;
diff --git a/dix/events.c b/dix/events.c
index 0f413a6..07a191f 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3524,7 +3524,9 @@ drawable.id:0;
 #endif
     )))
 #endif
-    XE_KBPTR.state = (keyc->state | GetPairedPointer(keybd)->button->state);
+    /* ProcessOtherEvent already updated the keyboard's state, so we need to
+     * access prev_state here! */
+    XE_KBPTR.state = (keyc->prev_state | GetPairedPointer(keybd)->button->state);
     XE_KBPTR.rootX = keybd->spriteInfo->sprite->hot.x;
     XE_KBPTR.rootY = keybd->spriteInfo->sprite->hot.y;
     key = xE->u.u.detail;
@@ -3545,31 +3547,14 @@ drawable.id:0;
     switch (xE->u.u.type)
     {
 	case KeyPress: 
-	    if (*kptr & bit) /* allow ddx to generate multiple downs */
-	    {   
-		if (!modifiers)
-		{
-		    xE->u.u.type = KeyRelease;
-		    (*keybd->public.processInputProc)(xE, keybd, count);
-		    xE->u.u.type = KeyPress;
-		    /* release can have side effects, don't fall through */
-		    (*keybd->public.processInputProc)(xE, keybd, count);
-		}
-		return;
-	    }
-	    GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow;
-	    *kptr |= bit;
-	    keyc->prev_state = keyc->state;
-	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
-	    {
-		if (mask & modifiers)
-		{
-		    /* This key affects modifier "i" */
-		    keyc->modifierKeyCount[i]++;
-		    keyc->state |= mask;
-		    modifiers &= ~mask;
-		}
-	    }
+            /* We MUST NOT change the device itself here.  All device state
+             * changes must be performed in ProcessOtherEvents. We're dealing
+             * with the same device struct, so if we change it in POE and
+             * here, we've just screwed up the state by setting it twice. 
+             *
+             * Devices may not send core events but always send XI events, so
+             * the state must be changed in POE, not here.
+             */
 	    if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
 	    {
 		grabinfo->activatingKey = key;
@@ -3579,20 +3564,7 @@ drawable.id:0;
 	case KeyRelease: 
 	    if (!(*kptr & bit)) /* guard against duplicates */
 		return;
-	    GetPairedPointer(keybd)->valuator->motionHintWindow = NullWindow;
-	    *kptr &= ~bit;
-	    keyc->prev_state = keyc->state;
-	    for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
-	    {
-		if (mask & modifiers) {
-		    /* This key affects modifier "i" */
-		    if (--keyc->modifierKeyCount[i] <= 0) {
-			keyc->state &= ~mask;
-			keyc->modifierKeyCount[i] = 0;
-		    }
-		    modifiers &= ~mask;
-		}
-	    }
+            /* No device state changes, see comment for KeyPress */
 	    if (grabinfo->fromPassiveGrab && (key == grabinfo->activatingKey))
 		deactivateGrab = TRUE;
 	    break;
@@ -3729,31 +3701,21 @@ ProcessPointerEvent (xEvent *xE, DeviceI
 	switch (xE->u.u.type)
 	{
 	case ButtonPress: 
-	    mouse->valuator->motionHintWindow = NullWindow;
-	    if (!(*kptr & bit))
-		butc->buttonsDown++;
-	    butc->motionMask = ButtonMotionMask;
-	    *kptr |= bit;
+            /*
+             * We rely on the fact that ButtonMotionMask is the same as
+             * DeviceButtonMotionMask, so setting the motionMask
+             * to this value ensures correctness for both XI and core events.
+             */
 	    if (xE->u.u.detail == 0)
 		return;
-	    if (xE->u.u.detail <= 5)
-		butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!grab)
 		if (CheckDeviceGrabs(mouse, xE, 0, count))
 		    return;
 	    break;
 	case ButtonRelease: 
-	    mouse->valuator->motionHintWindow = NullWindow;
-	    if (*kptr & bit)
-		--butc->buttonsDown;
-	    if (!butc->buttonsDown)
-		butc->motionMask = 0;
-	    *kptr &= ~bit;
 	    if (xE->u.u.detail == 0)
 		return;
-	    if (xE->u.u.detail <= 5)
-		butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 	    filters[MotionNotify] = Motion_Filter(butc);
 	    if (!butc->state && mouse->deviceGrab.fromPassiveGrab)
 		deactivateGrab = TRUE;
diff-tree c4fff050836feeef8390b7197f1de39af2997811 (from bfe6b4d2d9952a80f8dbc63eec974ef894e5c226)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Wed Sep 5 16:19:45 2007 +0930

    Revert "Input: Fix stuck modifiers (bug #11683)"
    
    This reverts commit 6b055e5d9751e3679ff98065e43225ec8a960053.
    
    MPX relies on the XI event being delivered before the core event. Device grabs
    break, amongst other things. I guess stuck modifiers need to be fixed some
    other way.
    
    Conflicts:
    
            dix/getevents.c

diff --git a/dix/getevents.c b/dix/getevents.c
index bcbc00b..e88c56c 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -451,14 +451,6 @@ GetKeyboardValuatorEvents(EventList *eve
 
     ms = GetTimeInMillis();
 
-    if (pDev->coreEvents) {
-        xEvent* evt = events->event;
-        evt->u.keyButtonPointer.time = ms;
-        evt->u.u.type = type;
-        evt->u.u.detail = key_code;
-        events++;
-    }
-
     kbp = (deviceKeyButtonPointer *) events->event;
     kbp->time = ms;
     kbp->deviceid = pDev->id;
@@ -476,6 +468,12 @@ GetKeyboardValuatorEvents(EventList *eve
                                    num_valuators, valuators);
     }
 
+    if (pDev->coreEvents) {
+        events->event->u.keyButtonPointer.time = ms;
+        events->event->u.u.type = type;
+        events->event->u.u.detail = key_code;
+    }
+
     return numEvents;
 }
 
@@ -677,28 +675,8 @@ GetPointerEvents(EventList *events, Devi
     pDev->valuator->lastx = x;
     pDev->valuator->lasty = y;
 
-    /* for some reason inputInfo.pointer does not have coreEvents set */
-    if (coreOnly || pDev->coreEvents) {
-        xEvent* evt = events->event;
-        evt->u.u.type = type;
-        evt->u.keyButtonPointer.time = ms;
-        evt->u.keyButtonPointer.rootX = x;
-        evt->u.keyButtonPointer.rootY = y;
-
-        if (type == ButtonPress || type == ButtonRelease) {
-            /* We hijack SetPointerMapping to work on all core-sending
-             * devices, so we use the device-specific map here instead of
-             * the core one. */
-            evt->u.u.detail = pDev->button->map[buttons];
-        }
-        else {
-            evt->u.u.detail = 0;
-        }
-
-        events++;
-    }
-
-    if (!coreOnly) {
+    if (!coreOnly)
+    {
         kbp = (deviceKeyButtonPointer *) events->event;
         kbp->time = ms;
         kbp->deviceid = pDev->id;
@@ -726,6 +704,24 @@ GetPointerEvents(EventList *events, Devi
         }
     }
 
+    /* for some reason inputInfo.pointer does not have coreEvents set */
+    if (coreOnly || pDev->coreEvents) {
+        events->event->u.u.type = type;
+        events->event->u.keyButtonPointer.time = ms;
+        events->event->u.keyButtonPointer.rootX = x;
+        events->event->u.keyButtonPointer.rootY = y;
+
+        if (type == ButtonPress || type == ButtonRelease) {
+            /* We hijack SetPointerMapping to work on all core-sending
+             * devices, so we use the device-specific map here instead of
+             * the core one. */
+            events->event->u.u.detail = pDev->button->map[buttons];
+        }
+        else {
+            events->event->u.u.detail = 0;
+        }
+    }
+
     return num_events;
 }
 
diff-tree bfe6b4d2d9952a80f8dbc63eec974ef894e5c226 (from cc5c926267be099d793e6dfec17916f21c73c64d)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Tue Sep 4 17:44:51 2007 +0930

    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.

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index e018749..be2cff6 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 252c653..762b6e5 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -73,7 +73,7 @@ XkbSetExtension(DeviceIntPtr device, Pro
     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,unsi
 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 = XKBDEVICEI
     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 = XKBDEVICEI
 	    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;
diff-tree cc5c926267be099d793e6dfec17916f21c73c64d (from 88a9828ef906bba973debc191e35ea669b7ec271)
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Aug 30 15:51:22 2007 +0930

    randr: RRPointerScreenConfigured needs to move all pointers.
    
    Previous version only moved the VCP, causing "bogus pointer events" lateron.
    Now we run through the device list, updating each pointer separately if
    necessary.
    
    Also stick a big warning into RRPointerMoved, not sure what device we need to
    work on here.

diff --git a/randr/rrpointer.c b/randr/rrpointer.c
index 722b22c..e3b8b03 100644
--- a/randr/rrpointer.c
+++ b/randr/rrpointer.c
@@ -52,7 +52,7 @@ RRCrtcContainsPosition (RRCrtcPtr crtc, 
  * Find the CRTC nearest the specified position, ignoring 'skip'
  */
 static void
-RRPointerToNearestCrtc (ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
+RRPointerToNearestCrtc (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y, RRCrtcPtr skip)
 {
     rrScrPriv (pScreen);
     int		c;
@@ -96,7 +96,7 @@ RRPointerToNearestCrtc (ScreenPtr pScree
 	}
     }
     if (best_dx || best_dy)
-	(*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, x + best_dx, y + best_dy, TRUE);
+	(*pScreen->SetCursorPosition) (pDev, pScreen, x + best_dx, y + best_dy, TRUE);
     pScrPriv->pointerCrtc = nearest;
 }
 
@@ -125,28 +125,37 @@ RRPointerMoved (ScreenPtr pScreen, int x
     }
 
     /* None contain pointer, find nearest */
-    RRPointerToNearestCrtc (pScreen, x, y, pointerCrtc);
+    ErrorF("RRPointerMoved: Untested, may cause \"bogus pointer event\"\n");
+    RRPointerToNearestCrtc (inputInfo.pointer, pScreen, x, y, pointerCrtc);
 }
 
 /*
- * When the screen is reconfigured, move the pointer to the nearest
+ * When the screen is reconfigured, move all pointers to the nearest
  * CRTC
  */
 void
 RRPointerScreenConfigured (ScreenPtr pScreen)
 {
-    WindowPtr	pRoot = GetCurrentRootWindow (inputInfo.pointer);
-    ScreenPtr	pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+    WindowPtr	pRoot; 
+    ScreenPtr	pCurrentScreen;
     int		x, y;
-
-    /* XXX: GetCurrentRootWindow revices an argument, It is inputInfo.pointer,
-     * but I really think this is wrong...  What do we do here? This was made so
-     * that it can compile, but I don't think randr should assume there is just
-     * one pointer. There might be more than one pointer on the screen! So, what
-     * to do? What happens? */
+    DeviceIntPtr pDev;
 
     if (pScreen != pCurrentScreen)
 	return;
-    GetSpritePosition(inputInfo.pointer, &x, &y);
-    RRPointerToNearestCrtc (pScreen, x, y, NULL);
+
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+    {
+        if (IsPointerDevice(pDev))
+        {
+            pRoot = GetCurrentRootWindow(pDev);
+            pCurrentScreen = pRoot ? pRoot->drawable.pScreen : NULL;
+
+            if (pScreen == pCurrentScreen)
+            {
+                GetSpritePosition(pDev, &x, &y);
+                RRPointerToNearestCrtc (pDev, pScreen, x, y, NULL);
+            }
+        }
+    }
 }


More information about the xorg-commit mailing list