xserver: Branch 'server-1.4-branch' - 16 commits

Daniel Stone daniels at kemper.freedesktop.org
Mon Nov 5 02:34:44 PST 2007


 Xi/exevents.c                        |   13 ++
 Xi/setbmap.c                         |    2 
 Xi/setmmap.c                         |    2 
 config/hal.c                         |    3 
 dix/devices.c                        |   25 +++--
 dix/events.c                         |   24 ++---
 hw/xfree86/common/xf86Events.c       |    2 
 hw/xfree86/common/xf86Xinput.c       |    5 +
 hw/xfree86/os-support/shared/sigio.c |    6 -
 include/exevents.h                   |    3 
 include/xkbsrv.h                     |   30 ++++++
 xkb/xkbAccessX.c                     |   23 ++++-
 xkb/xkbActions.c                     |  160 +++++++++++++++--------------------
 xkb/xkbEvents.c                      |   39 ++++++--
 xkb/xkbPrKeyEv.c                     |  110 +++++++++++++++++-------
 15 files changed, 284 insertions(+), 163 deletions(-)

New commits:
commit 846745c58108856e5fc1b6d94c91a245cbc4f16f
Author: Markku Vire <markku.vire at movial.fi>
Date:   Thu Nov 1 22:43:04 2007 +0200

    Config: HAL: Touchpads are pointers too
    
    Treat touchpads -- not just mice -- as pointer devices.
    (cherry picked from commit 3f1b6765aadf665ede8253464da19a5878f16e56)

diff --git a/config/hal.c b/config/hal.c
index d7835e6..6bb449d 100644
--- a/config/hal.c
+++ b/config/hal.c
@@ -177,7 +177,8 @@ device_added(LibHalContext *hal_ctx, const char *udi)
         if (strcmp(props[i], "input.keys") == 0 ||
             strcmp(props[i], "input.keyboard") == 0)
             type |= TYPE_KEYS;
-        if (strcmp(props[i], "input.mouse") == 0)
+        if (strcmp(props[i], "input.mouse") == 0 ||
+            strcmp(props[i], "input.touchpad") == 0)
             type |= TYPE_POINTER;
     }
     libhal_free_string_array(props);
commit ab80b27250bb583e3a40bf92cfe5edc117e4bd58
Author: Mark Vytlacil <mrv at wi.rr.com>
Date:   Thu Nov 1 21:05:43 2007 +0200

    XFree86: Input: Save/restore errno around SIGIO (bug #10683)
    
    Make sure errno is saved and restored from the SIGIO handler, so errors
    from system calls in input handlers don't break the interrupted code.
    (cherry picked from commit 41c3069f7cf28155f8e6cfe0c10a12a1f5f76c7d)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 91964c9..46fae08 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -510,12 +510,14 @@ static void
 xf86SigioReadInput(int fd,
 		   void *closure)
 {
+    int errno_save = errno;
     int sigstate = xf86BlockSIGIO();
     InputInfoPtr pInfo = (InputInfoPtr) closure;
 
     pInfo->read_input(pInfo);
 
     xf86UnblockSIGIO(sigstate);
+    errno = errno_save;
 }
 
 /*
commit ad05d5d035b32b05d304b2fc598f6fadeb077516
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sun Sep 23 17:17:03 2007 +0300

    Input: Generate XKB mapping changes for all core-sending devices (bug #12523)
    
    When we change the mapping on a core device, make sure we propagate this
    through to XKB for all extended devices as well.
    (cherry picked from commit 27ad5d74c20f01516a1bff73be283f8982fcf0fe)

diff --git a/Xi/exevents.c b/Xi/exevents.c
index fe297ab..377311e 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -73,6 +73,10 @@ SOFTWARE.
 #include "dixgrabs.h"	/* CreateGrab() */
 #include "scrnintstr.h"
 
+#ifdef XKB
+#include "xkbsrv.h"
+#endif
+
 #define WID(w) ((w) ? ((w)->drawable.id) : 0)
 #define AllModifiersMask ( \
 	ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
@@ -942,7 +946,7 @@ SetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen,
 }
 
 void
-SendDeviceMappingNotify(CARD8 request,
+SendDeviceMappingNotify(ClientPtr client, CARD8 request,
 			KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)
 {
     xEvent event;
@@ -957,6 +961,11 @@ SendDeviceMappingNotify(CARD8 request,
 	ev->count = count;
     }
 
+#ifdef XKB
+    if (request == MappingKeyboard || request == MappingModifier)
+        XkbApplyMappingChange(dev, request, firstKeyCode, count, client);
+#endif
+
     SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1);
 }
 
@@ -992,7 +1001,7 @@ ChangeKeyMapping(ClientPtr client,
     keysyms.map = map;
     if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
 	return BadAlloc;
-    SendDeviceMappingNotify(MappingKeyboard, firstKeyCode, keyCodes, dev);
+    SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev);
     return client->noClientException;
 }
 
diff --git a/Xi/setbmap.c b/Xi/setbmap.c
index bdfa513..1f5970d 100644
--- a/Xi/setbmap.c
+++ b/Xi/setbmap.c
@@ -134,7 +134,7 @@ ProcXSetDeviceButtonMapping(ClientPtr client)
     }
 
     if (ret != MappingBusy)
-	SendDeviceMappingNotify(MappingPointer, 0, 0, dev);
+	SendDeviceMappingNotify(client, MappingPointer, 0, 0, dev);
     return Success;
 }
 
diff --git a/Xi/setmmap.c b/Xi/setmmap.c
index 0078499..e30213e 100644
--- a/Xi/setmmap.c
+++ b/Xi/setmmap.c
@@ -122,7 +122,7 @@ ProcXSetDeviceModifierMapping(ClientPtr client)
     if (ret == MappingSuccess || ret == MappingBusy || ret == MappingFailed) {
 	rep.success = ret;
 	if (ret == MappingSuccess)
-	    SendDeviceMappingNotify(MappingModifier, 0, 0, dev);
+	    SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
 	WriteReplyToClient(client, sizeof(xSetDeviceModifierMappingReply),
 			   &rep);
     } else {
diff --git a/dix/devices.c b/dix/devices.c
index 9f3c576..e05444e 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -1208,10 +1208,9 @@ SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
     }
 #ifdef XKB
     if (!noXkbExtension &&
-	((request == MappingKeyboard) || (request == MappingModifier))) {
-	XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
-									client);
-    }
+	((request == MappingKeyboard) || (request == MappingModifier)))
+        XkbApplyMappingChange(inputInfo.keyboard, request, firstKeyCode, count,
+                              client);
 #endif
 
    /* 0 is the server client */
@@ -1359,6 +1358,7 @@ int
 ProcSetModifierMapping(ClientPtr client)
 {
     xSetModifierMappingReply rep;
+    DeviceIntPtr dev;
     REQUEST(xSetModifierMappingReq);
     
     REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
@@ -1374,8 +1374,10 @@ ProcSetModifierMapping(ClientPtr client)
     rep.success = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
                                        stuff->numKeyPerModifier);
 
-    /* FIXME: Send mapping notifies for all the extended devices as well. */
     SendMappingNotify(MappingModifier, 0, 0, client);
+    for (dev = inputInfo.devices; dev; dev = dev->next)
+        if (dev->key && dev->coreEvents)
+            SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev);
     WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
     return client->noClientException;
 }
@@ -1438,16 +1440,19 @@ ProcChangeKeyboardMapping(ClientPtr client)
     keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
     keysyms.mapWidth = stuff->keySymsPerKeyCode;
     keysyms.map = (KeySym *)&stuff[1];
-    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
-        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+        if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key)
             if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms))
                 return BadAlloc;
-        }
-    }
 
-    /* FIXME: Send mapping notifies for all the extended devices as well. */
     SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
                       client);
+    for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+        if (pDev->key && pDev->coreEvents)
+            SendDeviceMappingNotify(client, MappingKeyboard,
+                                    stuff->firstKeyCode, stuff->keyCodes,
+                                    pDev);
+
     return client->noClientException;
 }
 
diff --git a/include/exevents.h b/include/exevents.h
index 9f15f50..0892f4d 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -131,6 +131,7 @@ extern int SetModifierMapping(
 	KeyClassPtr *          /* k */);
 
 extern void SendDeviceMappingNotify(
+        ClientPtr              /* client, */,
 	CARD8                  /* request, */,
 	KeyCode                /* firstKeyCode */,
 	CARD8                  /* count */,
commit 84040b655e3ea9188a6c9d6dafea429ffc4690de
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.
    
    (cherry picked from commit d627061b48ae06d27b37be209d67a3f4f2388dd3)
    (cherry picked from commit 8ead41388e36e21eea6fa0408c847f174911eab0)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index e45d44c..b939fb7 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -165,6 +165,11 @@ xf86ActivateDevice(LocalDevicePtr local)
         dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
         RegisterOtherDevice(dev);
 
+#ifdef XKB
+        if (!noXkbExtension)
+            XkbSetExtension(dev, ProcessKeyboardEvent);
+#endif
+
         if (serverGeneration == 1) 
             xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
                     local->name, local->type_name);
commit e26e93c54e54ab4010dfdede47c3e56e4418bcbd
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sat Oct 27 21:32:47 2007 +0300

    XKB: Cope with all events in XkbProcessKeyboardEvent
    
    Cope with Xi and pointer events in the (now increasingly misnamed)
    XkbProcessKeyboardEvent.  If it's the wrong type, call through the wrapping
    chain to get out; else, process it.
    (cherry picked from commit e717cf08e99746761d74289c426bbd84176f4435)

diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index ba3fcc0..3fec4f5 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -36,11 +36,11 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/keysym.h>
 #include "misc.h"
 #include "inputstr.h"
+#include "exevents.h"
 #include <xkbsrv.h>
 #include <ctype.h>
 #define EXTENSION_EVENT_BASE 64
 
-
 /***====================================================================***/
 
 void
@@ -115,12 +115,12 @@ int             xiEvent;
 		break;
 	    case XkbKB_Lock:
 		if ( xE->u.u.type == KeyRelease || 
-                        xE->u.u.type == DeviceKeyRelease)
+                        xE->u.u.type == DeviceKeyRelease) {
 		    return;
+                }
 		else {
 		    int	bit= 1<<(key&7);
-		    if ( keyc->down[key>>3]&bit )
-                    {
+		    if ( keyc->down[key>>3]&bit ) {
                         if (xiEvent)
                             xE->u.u.type = DeviceKeyRelease;
                         else
@@ -193,23 +193,42 @@ int             xiEvent;
 void
 ProcessKeyboardEvent(xEvent *xE,DeviceIntPtr keybd,int count)
 {
-KeyClassPtr	keyc = keybd->key;
-XkbSrvInfoPtr	xkbi;
 
-    xkbi= keyc->xkbInfo;
+    KeyClassPtr keyc = keybd->key;
+    XkbSrvInfoPtr xkbi = NULL;
+    ProcessInputProc backup_proc;
+    xkbDeviceInfoPtr xkb_priv = XKBDEVICEINFO(keybd);
+    int is_press = (xE->u.u.type == KeyPress || xE->u.u.type == DeviceKeyPress);
+    int is_release = (xE->u.u.type == KeyRelease ||
+                      xE->u.u.type == DeviceKeyRelease);
+
+    if (keyc)
+        xkbi = keyc->xkbInfo;
+
+    /* We're only interested in key events. */
+    if (!is_press && !is_release) {
+        UNWRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc);
+        keybd->public.processInputProc(xE, keybd, count);
+        COND_WRAP_PROCESS_INPUT_PROC(keybd, xkb_priv, backup_proc,
+                                     xkbUnwrapProc);
+        return;
+    }
 
-#ifdef DEBUG
-    if (xkbDebugFlags&0x8) {
-	int key= xE->u.u.detail;
-	ErrorF("PKE: Key %d %s\n",key,(xE->u.u.type==KeyPress?"down":"up"));
+    /* If AccessX filters are active, then pass it through to
+     * AccessXFilter{Press,Release}Event; else, punt to
+     * XkbProcessKeyboardEvent.
+     *
+     * If AXF[PK]E don't intercept anything (which they probably won't),
+     * they'll punt through XPKE anyway. */
+    if ((xkbi->desc->ctrls->enabled_ctrls & XkbAllFilteredEventsMask)) {
+        if (is_press)
+            AccessXFilterPressEvent(xE, keybd, count);
+        else if (is_release)
+            AccessXFilterReleaseEvent(xE, keybd, count);
     }
-#endif
-    if ((xkbi->desc->ctrls->enabled_ctrls&XkbAllFilteredEventsMask)==0)
-	XkbProcessKeyboardEvent(xE,keybd,count);
-    else if (xE->u.u.type==KeyPress || xE->u.u.type==DeviceKeyPress)
-	AccessXFilterPressEvent(xE,keybd,count);
-    else if (xE->u.u.type==KeyRelease || xE->u.u.type==DeviceKeyRelease)
-	AccessXFilterReleaseEvent(xE,keybd,count);
+    else {
+        XkbProcessKeyboardEvent(xE, keybd, count);
+    }
+    
     return;
 }
-
commit 37c690cfa4e9055209732ab5431fffb8886c7d67
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sat Oct 27 21:31:39 2007 +0300

    XKB: Don't update indicators on all devices, add missing include file
    
    Don't get XkbUpdateIndicators to update the indicators on all our devices: we
    already deal with that ourselves.
    Add exevents.h include to get more (proto)types.
    (cherry picked from commit 9db8846fa53d91193bbfe541b244e2326440011d)

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index e50dbfe..8ddbdba 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -36,6 +36,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <X11/keysym.h>
 #include "misc.h"
 #include "inputstr.h"
+#include "exevents.h"
 #include <xkbsrv.h>
 #include "xkb.h"
 #include <ctype.h>
@@ -80,8 +81,7 @@ XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
     xkbPrivPtr->unwrapProc = NULL;
 
     device->devPrivates[xkbDevicePrivateIndex].ptr = xkbPrivPtr;
-    WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
-			    proc,xkbUnwrapProc);
+    WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
 }
 
 extern	void	ProcessOtherEvent(
@@ -400,7 +400,6 @@ _XkbFilterLockState(	XkbSrvInfoPtr	xkbi,
 			unsigned	keycode,
 			XkbAction *	pAction)
 {
-
     if (pAction&&(pAction->type==XkbSA_LockGroup)) {
 	if (pAction->group.flags&XkbSA_GroupAbsolute)
 	     xkbi->state.locked_group= XkbSAGroup(&pAction->group);
@@ -1287,8 +1286,9 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
         if (keyEvent)
 	    keyc->modifierMap[key] = realMods;
     }
-    else if (keyEvent)
+    else if (keyEvent) {
 	FixKeyState(xE,dev);
+    }
 
     xkbi->prev_state= oldState;
     XkbComputeDerivedState(xkbi);
@@ -1310,7 +1310,7 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
     if (changed) {
 	XkbEventCauseRec	cause;
 	XkbSetCauseKey(&cause,key,xE->u.u.type);
-	XkbUpdateIndicators(dev,changed,True,NULL,&cause);
+	XkbUpdateIndicators(dev,changed,False,NULL,&cause);
     }
     return;
 }
commit 1dce9c20283279eac4d6e5cafc4f73a333548c07
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Wed Sep 26 18:04:59 2007 +0930

    xkb: Unwrap properly in ProcessPointerEvent.
    
    Instead of hardcoding CoreProcessPointerEvent, actually try to unwrap properly
    and then call the unwrapped processInputProc. Seems to be a better idea,
    especially since it makes stuff actually work...
    (cherry picked from commit 8f9bf927e1beecf9b9ec8877131ec12c765e4d84)
    (cherry picked from commit ee3aa948eb8ed181d037294ed87df6ceec81684e)

diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 2954a0c..4c6e3d4 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -692,6 +692,8 @@ ProcessPointerEvent(	register xEvent  *	xE,
 DeviceIntPtr	dev = (DeviceIntPtr)LookupKeyboardDevice();
 XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
 unsigned 	changed = 0;
+ProcessInputProc backupproc;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(mouse);
 
     xkbi->shiftKeyCount = 0;
     xkbi->lastPtrEventTime= xE->u.keyButtonPointer.time;
@@ -703,7 +705,26 @@ unsigned 	changed = 0;
 	xkbi->lockedPtrButtons&= ~(1<<(xE->u.u.detail&0x7));
 	changed |= XkbPointerButtonMask;
     }
-    CoreProcessPointerEvent(xE,mouse,count);
+
+    /* Guesswork. mostly. 
+     * xkb actuall goes through some effort to transparently wrap the
+     * processInputProcs (see XkbSetExtension). But we all love fun, so the
+     * previous XKB implementation just hardcoded the CPPE call here instead
+     * of unwrapping like anybody with any sense of decency would do. 
+     * I got no clue what the correct thing to do is, but my guess is that
+     * it's not hardcoding. I may be wrong. whatever it is, don't come whining
+     * to me. I just work here. 
+     *
+     * Anyway. here's the old call, if you don't like the wrapping, revert it.
+     *
+     * CoreProcessPointerEvent(xE,mouse,count);
+     *
+     *          see. it's still steaming. told you. (whot)
+     */
+    UNWRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr, backupproc);
+    mouse->public.processInputProc(xE, mouse, count);
+    COND_WRAP_PROCESS_INPUT_PROC(mouse, xkbPrivPtr,
+				     backupproc, xkbUnwrapProc);
 
     xkbi->state.ptr_buttons = mouse->button->state;
     
commit 940cce1f4856a3ffc6fdba9c807c8238ed1acf8b
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Sep 27 11:44:03 2007 +0930

    xkb: xkbHandleActions: let wrapping take care of event delivery.
    
    This is hopefully better than hardcodey calling CoreProcessPointerEvent.
    (cherry picked from commit 32d0440c7f6e604807cb14dd32349df6f22c903b)
    (cherry picked from commit d3588a0aee33fbd233082f881c0d37152c6d4d8b)

diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index c62910f..e50dbfe 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -1148,7 +1148,6 @@ XkbAction	act;
 XkbFilterPtr	filter;
 Bool		keyEvent;
 Bool		pressEvent;
-Bool		xiEvent;
 ProcessInputProc backupproc;
     
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
@@ -1173,9 +1172,6 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 		(xE->u.u.type==KeyRelease)||(xE->u.u.type==DeviceKeyRelease));
     pressEvent= (xE->u.u.type==KeyPress)||(xE->u.u.type==DeviceKeyPress)||
 		 (xE->u.u.type==ButtonPress)||(xE->u.u.type==DeviceButtonPress);
-    xiEvent= (xE->u.u.type==DeviceKeyPress)||(xE->u.u.type==DeviceKeyRelease)||
-	     (xE->u.u.type==DeviceButtonPress)||
-	     (xE->u.u.type==DeviceButtonRelease);
 
     if (pressEvent) {
 	if (keyEvent)	
@@ -1282,20 +1278,14 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 	if (keyEvent) {
 	    realMods = keyc->modifierMap[key];
 	    keyc->modifierMap[key] = 0;
-	    UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr, backupproc);
-	    dev->public.processInputProc(xE,dev,count);
-	    COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr,
-					 backupproc,xkbUnwrapProc);
-	    keyc->modifierMap[key] = realMods;
-	}
-	else 
-        {
-            if (xE->u.u.type & EXTENSION_EVENT_BASE)
-                ProcessOtherEvent(xE, dev, count);
-            else
-                CoreProcessPointerEvent(xE,dev,count);
-            
         }
+
+        UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr, backupproc);
+        dev->public.processInputProc(xE,dev,count);
+        COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr,
+                                     backupproc,xkbUnwrapProc);
+        if (keyEvent)
+	    keyc->modifierMap[key] = realMods;
     }
     else if (keyEvent)
 	FixKeyState(xE,dev);
commit 5909fb3c406356505440af8d53785d9ee06ab9be
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Wed Sep 12 17:40:11 2007 +0930

    dix: don't compress motion events from different devices (EventEnqueue)
    
    (cherry picked from commit 8840829ab93c4eb62eb58753c015da5307133fe5)
    (cherry picked from commit 352c5a311200bf491153fe9ef16126c5877a57bb)

diff --git a/dix/events.c b/dix/events.c
index d2591de..5bd67e3 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1098,9 +1098,10 @@ EnqueueEvent(xEvent *xE, DeviceIntPtr device, int count)
 #endif
 	sprite.hotPhys.x = XE_KBPTR.rootX;
 	sprite.hotPhys.y = XE_KBPTR.rootY;
-	/* do motion compression */
+	/* do motion compression, but not if from different devices */
 	if (tail &&
 	    (tail->event->u.u.type == MotionNotify) &&
+            (tail->device == device) &&
 	    (tail->pScreen == sprite.hotPhys.pScreen))
 	{
 	    tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
commit 600752bece350592f374470dd54b9e1cd2900d0b
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.
    (cherry picked from commit 5ee409794ee604fcf84886f70429fc2d6b1ff4f1)
    (cherry picked from commit 8d3d027062c105b50863dce43b8070ec560bc12e)

diff --git a/dix/events.c b/dix/events.c
index 7b4cab0..d2591de 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -3095,7 +3095,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)
@@ -3108,22 +3108,19 @@ FixKeyState (xEvent *xE, DeviceIntPtr keybd)
     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
 
commit 15117d47bf883f3eefc57404f1dfc0c933ab054a
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.
    
    (cherry picked from commit 6334d4e7be18de5f237c12a6dc20f75aa23477d0 with some
     additional compile fixes and non-MPX adaptations)
    (cherry picked from commit 99e826e867c1c5520153c539ba07a884aec88d0c)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index d78a68a..167dbec 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -314,8 +314,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 2c7c2cd..c62910f 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -39,11 +39,12 @@ 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;
+int xkbDevicePrivateIndex = -1;
 
-static void
+void
 xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
                    pointer data)
 {
@@ -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 11dc17a..e11b609 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>
@@ -813,7 +814,9 @@ XkbSrvInfoPtr	xkbi;
     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",
@@ -832,7 +835,9 @@ XkbSrvInfoPtr	xkbi;
 	    return False;
 	}
 	if ((pXDev->grab != NullGrab) && pXDev->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;
@@ -877,10 +882,12 @@ XkbSrvInfoPtr	xkbi;
 	    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",
@@ -900,9 +907,18 @@ XkbSrvInfoPtr	xkbi;
 		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;
+            }
 	    button_mask = 1 << xE[i].u.u.detail;
 	    if (type == ButtonPress &&
 		((xE[i].u.keyButtonPointer.state >> 7) & button_mask) == button_mask &&
@@ -911,7 +927,14 @@ XkbSrvInfoPtr	xkbi;
 		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 81124bc..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"));
@@ -69,45 +72,69 @@ unsigned        ndx;
     /* below XKB, such as a key that physically locks.   XKB does not   */
     /* do anything to implement the behavior, but it *does* report that */
     /* key is hardwired */
+
     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];
@@ -121,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;
@@ -173,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;
 }
commit 83e76fb3f7a89a237893c2b7df450d4f90eab52d
Author: Peter Hutterer <peter at cs.unisa.edu.au>
Date:   Thu Jun 21 18:24:30 2007 +0930

    Save processInputProc before wrapping it and restore it later, instead of
    using a hardcoded ProcessKeyboardEvent. Otherwise we lose the ability to
    process DeviceKeyEvents after the first key press.
    
    This should be the correct fix now.
    (cherry picked from commit 4d5df14f2c4a3108a8c8adfcf4766c0d1a9daad2)
    (cherry picked from commit 91077bfc50d54be37c217e377c55b6bf886a2fab)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index bb2316d..d78a68a 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -262,7 +262,8 @@ typedef struct
 	oldprocs->unwrapProc = device->unwrapProc; \
 	device->unwrapProc = unwrapproc;
 
-#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs) \
+#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \
+        backupproc = device->public.processInputProc; \
 	device->public.processInputProc = oldprocs->processInputProc; \
 	device->public.realInputProc = oldprocs->realInputProc; \
 	device->unwrapProc = oldprocs->unwrapProc;
diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c
index ef67d64..2c7c2cd 100644
--- a/xkb/xkbActions.c
+++ b/xkb/xkbActions.c
@@ -49,10 +49,11 @@ xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
 {
     xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
     ProcessInputProc tmp = device->public.processInputProc;
+    ProcessInputProc dummy; /* unused, but neede for macro */
     if(xkbPrivPtr->unwrapProc)
 	xkbPrivPtr->unwrapProc = NULL;
 
-    UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr);
+    UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, dummy);
     proc(device,data);
     WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
 			    tmp,xkbUnwrapProc);
@@ -851,6 +852,7 @@ int		x,y;
 XkbStateRec	old;
 unsigned	mods,mask,oldCoreState = 0,oldCorePrevState = 0;
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
+ProcessInputProc backupproc;
 
     /* never actually used uninitialised, but gcc isn't smart enough
      * to work that out. */
@@ -903,10 +905,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
 
 	realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
 	xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
-	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
 	xkbi->device->public.processInputProc(&ev,xkbi->device,1);
 	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
-				     ProcessKeyboardEvent,xkbUnwrapProc);
+				     backupproc,xkbUnwrapProc);
 	xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
 	
 	if ( mask || mods ) {
@@ -944,10 +946,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
 
 	realMods = xkbi->device->key->modifierMap[ev.u.u.detail];
 	xkbi->device->key->modifierMap[ev.u.u.detail] = 0;
-	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr);
+	UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
 	xkbi->device->public.processInputProc(&ev,xkbi->device,1);
 	COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
-				     ProcessKeyboardEvent,xkbUnwrapProc);
+				     backupproc,xkbUnwrapProc);
 	xkbi->device->key->modifierMap[ev.u.u.detail] = realMods;
 
 	if ( mask || mods ) {
@@ -1140,6 +1142,7 @@ Bool		pressEvent;
 #ifdef XINPUT
 Bool		xiEvent;
 #endif
+ProcessInputProc backupproc;
     
 xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 
@@ -1284,10 +1287,10 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
 	if (keyEvent) {
 	    realMods = keyc->modifierMap[key];
 	    keyc->modifierMap[key] = 0;
-	    UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr);
+	    UNWRAP_PROCESS_INPUT_PROC(dev,xkbPrivPtr, backupproc);
 	    dev->public.processInputProc(xE,dev,count);
 	    COND_WRAP_PROCESS_INPUT_PROC(dev, xkbPrivPtr,
-					 ProcessKeyboardEvent,xkbUnwrapProc);
+					 backupproc,xkbUnwrapProc);
 	    keyc->modifierMap[key] = realMods;
 	}
 	else CoreProcessPointerEvent(xE,dev,count);
commit a53172827c69a88155a088843c9a3e8a7a7a0463
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.
    (cherry picked from commit bfe6b4d2d9952a80f8dbc63eec974ef894e5c226)
    (cherry picked from commit 8b9481a113b56078191e2298bf590905978f6289)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index e43e8fd..bb2316d 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 2e0c89f..ef67d64 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;
commit b76b1d51fe3053fa2a60b64de9ac93f50ef252f5
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sat Oct 27 21:33:52 2007 +0300

    XFree86: Remove ridiculous SIGIO debugging
    
    YOU PRESSED A KEY
    AND AGAIN
    YOU RELEASED A KEY
    AND AGAIN
    YOU PRESSED A KEY
    AND AGAIN
    
    ... not so much.
    (cherry picked from commit 493b83bd097372ae0023da9919da83af39e3fc1c)

diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c
index f6c15c2..c97f503 100644
--- a/hw/xfree86/os-support/shared/sigio.c
+++ b/hw/xfree86/os-support/shared/sigio.c
@@ -243,9 +243,6 @@ xf86BlockSIGIO (void)
     sigaddset (&set, SIGIO);
     sigprocmask (SIG_BLOCK, &set, &old);
     ret = sigismember (&old, SIGIO);
-#ifdef DEBUG
-    ErrorF("%i = xf86BlockSIGIO()\n",ret);
-#endif
     return ret; 
 }
 
@@ -253,9 +250,6 @@ _X_EXPORT void
 xf86UnblockSIGIO (int wasset)
 {
     sigset_t	set;
-#ifdef DEBUG
-    ErrorF("xf86UnblockSIGIO(%i)\n",wasset);
-#endif
 
     if (!wasset)
     {
commit b600e7c123ce637359a75c43bf67b3462eadb37e
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sat Oct 27 21:35:31 2007 +0300

    XKB: Add more bits to xkbsrv.h
    
    Add the device private index, given we use that in a macro here, and also the
    prototype for xkbUnwrapProc, since that's also useful.
    (cherry picked from commit a3d48de5f2b7eacf3193c60f0fb461912201210b)

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 5edee53..e43e8fd 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -246,8 +246,11 @@ typedef struct
 	device->public.realInputProc = oldprocs->realInputProc; \
 	device->unwrapProc = oldprocs->unwrapProc;
 
+extern int xkbDevicePrivateIndex;
 #define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr) (dev)->devPrivates[xkbDevicePrivateIndex].ptr)
 
+extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, pointer);
+
 /***====================================================================***/
 
 
commit 63c6d9d622a10303f594a07bd86dda8e5f894ca7
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Sat Oct 27 21:34:22 2007 +0300

    Xi: Include XI protocol header in exevents.h
    
    Make sure we have all the types we need to use this header.
    (cherry picked from commit e29e69960d67aa4b7a4d1551af509dbac193f438)

diff --git a/include/exevents.h b/include/exevents.h
index 69d4abc..9f15f50 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -30,6 +30,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifndef EXEVENTS_H
 #define EXEVENTS_H
 
+#include <X11/extensions/XIproto.h>
+
 extern void RegisterOtherDevice (
 	DeviceIntPtr           /* device */);
 


More information about the xorg-commit mailing list