xserver: Branch 'master' - 4 commits

Peter Hutterer whot at kemper.freedesktop.org
Thu Sep 3 20:16:13 PDT 2009


 Xi/exevents.c      |    3 
 dix/eventconvert.c |   35 +++++++++
 dix/events.c       |  165 ++++++++++++++++++++++++++++++----------------
 include/eventstr.h |    1 
 include/xkbsrv.h   |    4 -
 xkb/xkb.c          |   10 ++
 xkb/xkbAccessX.c   |   11 ---
 xkb/xkbEvents.c    |  190 ++++++++++++++++++++---------------------------------
 xkb/xkbPrKeyEv.c   |   67 ++++++------------
 9 files changed, 257 insertions(+), 229 deletions(-)

New commits:
commit 8af2793a90e8e644a6a598adce3f752c15b3e37a
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Thu Sep 3 11:30:48 2009 +1000

    xkb: xkbGetKbdByName on the lastSlave needs to change the master (#21859)
    
    If the layout is changed on a master's lastSlave, the master needs to change
    layout immediately. Otherwise, the master stays on the same layout until the
    lastSlave changes - which may not happen if only a single keyboard is
    available.
    
    X.Org Bug 21859 <http://bugs.freedesktop.org/show_bug.cgi?id=21859>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/xkb/xkb.c b/xkb/xkb.c
index b0d92b7..0b54a2e 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5867,6 +5867,16 @@ ProcXkbGetKbdByName(ClientPtr client)
 	if (geom_changed)
 	    nkn.changed|= XkbNKN_GeometryMask;
 	XkbSendNewKeyboardNotify(dev,&nkn);
+
+	if (!IsMaster(dev) && dev->u.master)
+	{
+	    DeviceIntPtr master = dev->u.master;
+	    if (master->u.lastSlave == dev)
+	    {
+		XkbCopyDeviceKeymap(dev->u.master, dev);
+		XkbSendNewKeyboardNotify(dev,&nkn);
+	    }
+	}
     }
     if ((new!=NULL)&&(new!=xkb)) {
 	XkbFreeKeyboard(new,XkbAllComponentsMask,True);
commit 219ae5b628f9ffe2be0876d5911cc04e52bef5f8
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Aug 21 16:38:53 2009 +1000

    dix: hide the sequenceNumber key repeat hack behind two functions.
    
    Just in case we figure out a better way to do it in the future.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 69d2f1f..21eed40 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -55,6 +55,35 @@ static int eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count);
 static int eventToDeviceChanged(DeviceChangedEvent *ev, xEvent **dcce);
 static int eventToDeviceEvent(DeviceEvent *ev, xEvent **xi);
 static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi);
+
+/* Do not use, read comments below */
+BOOL EventIsKeyRepeat(xEvent *event);
+
+/**
+ * Hack to allow detectable autorepeat for core and XI1 events.
+ * The sequence number is unused until we send to the client and can be
+ * misused to store data. More or less, anyway.
+ *
+ * Do not use this. It may change any time without warning, eat your babies
+ * and piss on your cat.
+ */
+static void
+EventSetKeyRepeatFlag(xEvent *event, BOOL on)
+{
+    event->u.u.sequenceNumber = on;
+}
+
+/**
+ * Check if the event was marked as a repeat event before.
+ * NOTE: This is a nasty hack and should NOT be used by anyone else but
+ * TryClientEvents.
+ */
+BOOL
+EventIsKeyRepeat(xEvent *event)
+{
+    return !!event->u.u.sequenceNumber;
+}
+
 /**
  * Convert the given event to the respective core event.
  *
@@ -90,8 +119,7 @@ EventToCore(InternalEvent *event, xEvent *core)
                 core->u.keyButtonPointer.rootX = e->root_x;
                 core->u.keyButtonPointer.rootY = e->root_y;
                 core->u.keyButtonPointer.state = e->corestate;
-                if (e->type == ET_KeyPress && e->key_repeat)
-                    core->u.u.sequenceNumber = 1;
+                EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat));
             }
             break;
         case ET_ProximityIn:
@@ -239,8 +267,8 @@ eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
     kbp->root_y   = ev->root_y;
     kbp->deviceid = ev->deviceid;
     kbp->state    = ev->corestate;
-    if (ev->type == ET_KeyPress && ev->key_repeat)
-        kbp->sequenceNumber = 1;
+    EventSetKeyRepeatFlag((xEvent*)kbp,
+                          (ev->type == ET_KeyPress && ev->key_repeat));
 
     if (num_events > 1)
         kbp->deviceid |= MORE_EVENTS;
diff --git a/dix/events.c b/dix/events.c
index 62eb6c2..90a2675 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -226,6 +226,9 @@ static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin,
                                       DeviceEvent *event,
                                       BOOL checkCore);
 
+/** Key repeat hack. Do not use but in TryClientEvents */
+extern BOOL EventIsKeyRepeat(xEvent *event);
+
 /**
  * Main input device struct.
  *     inputInfo.pointer
@@ -1948,8 +1951,7 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
             return 1;
     } else if (type == KeyPress)
     {
-        /* sequenceNumber == 1 if autorepeat is set */
-        if (pEvents->u.u.sequenceNumber)
+        if (EventIsKeyRepeat(pEvents))
         {
             if (!_XkbWantsDetectableAutoRepeat(client))
             {
@@ -1970,7 +1972,7 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
 
     } else if (type == DeviceKeyPress)
     {
-        if (((deviceKeyButtonPointer *)pEvents)->sequenceNumber)
+        if (EventIsKeyRepeat(pEvents))
         {
             if (!_XkbWantsDetectableAutoRepeat(client))
             {
commit bfb219f532f3c78ba905424365ee7c5f7b5f21a2
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Fri Aug 21 16:03:36 2009 +1000

    input: allow for detectable autorepeat.
    
    For core and XI1 events, store the key_repeat flag in the sequence number
    until TryClientEvents. The sequenceNumber is unset until TryClientEvents.
    
    [Also thrown in, some random indentation changes. Thanks]
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/Xi/exevents.c b/Xi/exevents.c
index 7f77aa8..0211e72 100644
--- a/Xi/exevents.c
+++ b/Xi/exevents.c
@@ -814,7 +814,8 @@ UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
             return DONT_PROCESS;
 
 	kptr = &k->down[key >> 3];
-	if (*kptr & bit)	/* don't allow ddx to generate multiple downs */
+        /* don't allow ddx to generate multiple downs, but repeats are okay */
+	if ((*kptr & bit) && !event->key_repeat)
 	    return DONT_PROCESS;
 	if (device->valuator)
 	    device->valuator->motionHintWindow = NullWindow;
diff --git a/dix/eventconvert.c b/dix/eventconvert.c
index 07a8e5f..69d2f1f 100644
--- a/dix/eventconvert.c
+++ b/dix/eventconvert.c
@@ -90,6 +90,8 @@ EventToCore(InternalEvent *event, xEvent *core)
                 core->u.keyButtonPointer.rootX = e->root_x;
                 core->u.keyButtonPointer.rootY = e->root_y;
                 core->u.keyButtonPointer.state = e->corestate;
+                if (e->type == ET_KeyPress && e->key_repeat)
+                    core->u.u.sequenceNumber = 1;
             }
             break;
         case ET_ProximityIn:
@@ -237,6 +239,8 @@ eventToKeyButtonPointer(DeviceEvent *ev, xEvent **xi, int *count)
     kbp->root_y   = ev->root_y;
     kbp->deviceid = ev->deviceid;
     kbp->state    = ev->corestate;
+    if (ev->type == ET_KeyPress && ev->key_repeat)
+        kbp->sequenceNumber = 1;
 
     if (num_events > 1)
         kbp->deviceid |= MORE_EVENTS;
@@ -528,6 +532,9 @@ eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
     xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
     xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);
 
+    if (ev->key_repeat)
+        xde->flags      |= XIKeyRepeat;
+
     xde->mods.base_mods         = ev->mods.base;
     xde->mods.latched_mods      = ev->mods.latched;
     xde->mods.locked_mods       = ev->mods.locked;
diff --git a/dix/events.c b/dix/events.c
index acc1803..62eb6c2 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1941,12 +1941,53 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
             pEvents->u.u.detail = NotifyNormal;
         }
     }
-    else
+    else if (type == DeviceMotionNotify)
     {
-        if ((type == DeviceMotionNotify) &&
-                MaybeSendDeviceMotionNotifyHint
-                ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+        if (MaybeSendDeviceMotionNotifyHint((deviceKeyButtonPointer*)pEvents,
+                                            mask) != 0)
             return 1;
+    } else if (type == KeyPress)
+    {
+        /* sequenceNumber == 1 if autorepeat is set */
+        if (pEvents->u.u.sequenceNumber)
+        {
+            if (!_XkbWantsDetectableAutoRepeat(client))
+            {
+                xEvent release = *pEvents;
+                release.u.u.type = KeyRelease;
+                release.u.u.sequenceNumber = client->sequence;
+                WriteEventsToClient(client, 1, &release);
+#ifdef DEBUG_EVENTS
+                ErrorF(" (plus fake core release for repeat)");
+#endif
+            } else
+            {
+#ifdef DEBUG_EVENTS
+                ErrorF(" (detectable autorepeat for core)");
+#endif
+            }
+        }
+
+    } else if (type == DeviceKeyPress)
+    {
+        if (((deviceKeyButtonPointer *)pEvents)->sequenceNumber)
+        {
+            if (!_XkbWantsDetectableAutoRepeat(client))
+            {
+                deviceKeyButtonPointer release = *(deviceKeyButtonPointer *)pEvents;
+                release.type = DeviceKeyRelease;
+                release.sequenceNumber = client->sequence;
+#ifdef DEBUG_EVENTS
+                ErrorF(" (plus fake xi1 release for repeat)");
+#endif
+                WriteEventsToClient(client, 1, (xEvent *) &release);
+            }
+            else {
+#ifdef DEBUG_EVENTS
+                ErrorF(" (detectable autorepeat for core)");
+#endif
+            }
+        }
     }
 
     type &= 0177;
@@ -5622,8 +5663,8 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
     int       i,
               eventlength = sizeof(xEvent);
 
-    if (!XkbFilterEvents(pClient, count, events))
-	return;
+    /* Let XKB rewrite the state, as it depends on client preferences. */
+    XkbFilterEvents(pClient, count, events);
 
 #ifdef PANORAMIX
     if(!noPanoramiXExtension &&
diff --git a/include/eventstr.h b/include/eventstr.h
index 8dd98be..f082db3 100644
--- a/include/eventstr.h
+++ b/include/eventstr.h
@@ -117,6 +117,7 @@ struct _DeviceEvent
     } group;
     Window      root; /**< Root window of the event */
     int corestate;    /**< Core key/button state BEFORE the event */
+    int key_repeat;   /**< Internally-generated key repeat event */
 };
 
 
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index cdca8f1..2c7d86a 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -297,8 +297,6 @@ extern _X_EXPORT int	XkbKeyboardErrorCode;
 extern _X_EXPORT char *	XkbBaseDirectory;
 extern _X_EXPORT char *	XkbBinDirectory;
 
-extern _X_EXPORT pointer	XkbLastRepeatEvent;
-
 extern _X_EXPORT CARD32	xkbDebugFlags;
 
 #define	_XkbTypedAlloc(t)	((t *)xalloc(sizeof(t)))
@@ -942,7 +940,7 @@ extern Bool XkbCopyDeviceKeymap(
         DeviceIntPtr            /* dst */,
         DeviceIntPtr            /* src */);
 
-extern Bool XkbFilterEvents(
+extern void XkbFilterEvents(
         ClientPtr               /* pClient */,
         int                     /* nEvents */,
         xEvent*                 /* xE */);
diff --git a/xkb/xkbAccessX.c b/xkb/xkbAccessX.c
index 7df8e06..47023c0 100644
--- a/xkb/xkbAccessX.c
+++ b/xkb/xkbAccessX.c
@@ -44,7 +44,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 int	XkbDfltRepeatDelay=	660;
 int	XkbDfltRepeatInterval=	40;
-pointer XkbLastRepeatEvent=	NULL;
 
 #define	DFLT_TIMEOUT_CTRLS (XkbAX_KRGMask|XkbStickyKeysMask|XkbMouseKeysMask)
 #define	DFLT_TIMEOUT_OPTS  (XkbAX_IndicatorFBMask)
@@ -131,18 +130,15 @@ AccessXKeyboardEvent(DeviceIntPtr	keybd,
     event.detail.key = keyCode;
     event.time = GetTimeInMillis();
     event.length = sizeof(DeviceEvent);
+    event.key_repeat = isRepeat;
 
     if (xkbDebugFlags&0x8) {
 	DebugF("[xkb] AXKE: Key %d %s\n", keyCode,
                (event.type == ET_KeyPress ? "down" : "up"));
     }
 
-    if (!_XkbIsPressEvent(type) && isRepeat)
-	XkbLastRepeatEvent=	(pointer)&event;
     XkbProcessKeyboardEvent(&event, keybd);
-    XkbLastRepeatEvent= NULL;
     return;
-    
 } /* AccessXKeyboardEvent */
 
 /************************************************************************/
@@ -309,14 +305,11 @@ AccessXRepeatKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg)
 {
 DeviceIntPtr    dev = (DeviceIntPtr) arg;
 XkbSrvInfoPtr	xkbi = dev->key->xkbInfo;
-KeyCode		key;
 
     if (xkbi->repeatKey == 0)
 	return 0;
 
-    key = xkbi->repeatKey;
-    AccessXKeyboardEvent(dev, ET_KeyRelease, key, True);
-    AccessXKeyboardEvent(dev, ET_KeyPress, key, True);
+    AccessXKeyboardEvent(dev, ET_KeyPress, xkbi->repeatKey, True);
 
     return xkbi->desc->ctrls->repeat_interval;
 }
diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c
index e56694d..8fb49c1 100644
--- a/xkb/xkbEvents.c
+++ b/xkb/xkbEvents.c
@@ -914,145 +914,99 @@ XkbSrvLedInfoPtr	sli;
 
 /***====================================================================***/
 
-Bool
-XkbFilterEvents(ClientPtr pClient,int nEvents,xEvent *xE)
+void
+XkbFilterEvents(ClientPtr client,int nEvents,xEvent *xE)
 {
-int	i, button_mask;
-DeviceIntPtr pXDev = NULL;
-XkbSrvInfoPtr	xkbi;
+    DeviceIntPtr dev = NULL;
+    XkbSrvInfoPtr xkbi;
+    CARD8 type = xE[0].u.u.type;
 
     if (xE->u.u.type & EXTENSION_EVENT_BASE)
-        pXDev = XIGetDevice(xE);
-
-    if (!pXDev)
-        pXDev = PickKeyboard(pClient);
+        dev = XIGetDevice(xE);
 
-    xkbi= (pXDev->key) ? pXDev->key->xkbInfo : NULL;
+    if (!dev)
+        dev = PickKeyboard(client);
 
-    if ( pClient->xkbClientFlags & _XkbClientInitialized ) {
-	if ((xkbDebugFlags&0x10)&&
-		((xE[0].u.u.type==KeyPress)||(xE[0].u.u.type==KeyRelease)||
-                 (xE[0].u.u.type==DeviceKeyPress)||
-                 (xE[0].u.u.type == DeviceKeyRelease))) {
-	    DebugF("[xkb] XKbFilterWriteEvents:\n");
-	    DebugF("[xkb]    Event state= 0x%04x\n",xE[0].u.keyButtonPointer.state);
-	    DebugF("[xkb]    XkbLastRepeatEvent!=xE (0x%p!=0x%p) %s\n",
-			XkbLastRepeatEvent,xE,
-			((XkbLastRepeatEvent!=(pointer)xE)?"True":"False"));
-	    DebugF("[xkb]   (xkbClientEventsFlags&XWDA)==0 (0x%x) %s\n",
-		pClient->xkbClientFlags,
-		(_XkbWantsDetectableAutoRepeat(pClient)?"True":"False"));
-	    DebugF("[xkb]   !IsRelease(%d) %s\n",xE[0].u.u.type,
-			(!_XkbIsReleaseEvent(xE[0].u.u.type))?"True":"False");
-	}
-	if (	(XkbLastRepeatEvent==(pointer)xE) &&
-	     	(_XkbWantsDetectableAutoRepeat(pClient)) &&
-	     	(_XkbIsReleaseEvent(xE[0].u.u.type)) ) {
-	    return False;
-	}
-
-        if (!xkbi)
-            return True;
+    if (!dev->key)
+        return;
 
-	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==DeviceKeyPress)||
-             (xE[0].u.u.type == DeviceKeyRelease))) {
-	    register unsigned state,flags;
+    xkbi = dev->key->xkbInfo;
 
-	    flags= pClient->xkbClientFlags;
-	    state= xkbi->state.compat_grab_mods;
+    if (client->xkbClientFlags & _XkbClientInitialized) {
+	if ((xkbDebugFlags&0x10)&&
+            (type == KeyPress || type == KeyRelease ||
+             type == DeviceKeyPress || type == DeviceKeyRelease))
+	    DebugF("[xkb] XkbFilterWriteEvents (XKB client): state 0x%04x\n",
+                   xE[0].u.keyButtonPointer.state);
+
+	if (dev->deviceGrab.grab != NullGrab && dev->deviceGrab.fromPassiveGrab &&
+	    (type == KeyPress || type == KeyRelease ||
+             type == DeviceKeyPress || type == DeviceKeyRelease)) {
+	    unsigned int state, flags;
+
+	    flags = client->xkbClientFlags;
+	    state = xkbi->state.compat_grab_mods;
 	    if (flags & XkbPCF_GrabsUseXKBStateMask) {
 		int group;
-		if (flags&XkbPCF_LookupStateWhenGrabbed) {
-		     group= xkbi->state.group;
-		     state= xkbi->state.lookup_mods;
+		if (flags & XkbPCF_LookupStateWhenGrabbed) {
+		     group = xkbi->state.group;
+		     state = xkbi->state.lookup_mods;
 		}
 		else {
-		    state= xkbi->state.grab_mods;
-		    group= xkbi->state.base_group+xkbi->state.latched_group;
-		    if ((group<0)||(group>=xkbi->desc->ctrls->num_groups)) {
-			group= XkbAdjustGroup(group,xkbi->desc->ctrls);
-		    }
+		    state = xkbi->state.grab_mods;
+		    group = xkbi->state.base_group + xkbi->state.latched_group;
+		    if (group < 0 || group >= xkbi->desc->ctrls->num_groups)
+			group = XkbAdjustGroup(group, xkbi->desc->ctrls);
 		}
 		state = XkbBuildCoreState(state, group);
 	    }
-	    else if (flags&XkbPCF_LookupStateWhenGrabbed)
-		state= xkbi->state.compat_lookup_mods;
-	    xE[0].u.keyButtonPointer.state= state;
+	    else if (flags & XkbPCF_LookupStateWhenGrabbed) {
+		state = xkbi->state.compat_lookup_mods;
+            }
+	    xE[0].u.keyButtonPointer.state = state;
 	}
-	button_mask = 1 << xE[0].u.u.detail;
-	if (xE[0].u.u.type == ButtonPress &&
-	    ((xE[0].u.keyButtonPointer.state >> 7) & button_mask) == button_mask &&
-	    (xkbi->lockedPtrButtons & button_mask) == button_mask) {
-	    /* If the MouseKeys is pressed, and the "real" mouse is also pressed
-	     * when the mouse is released, the server does not behave properly.
-	     * Faking a release of the button here solves the problem.
-	     */
-	    DebugF("[xkb] Faking release of button %d\n", xE[0].u.u.detail);
-	    XkbDDXFakeDeviceButton(xkbi->device, 0, xE[0].u.u.detail);
-        }
     }
     else {
-	register CARD8 	type;
-
-        if (!xkbi)
-            return True;
-
-	for (i=0;i<nEvents;i++) {
-	    type= xE[i].u.u.type;
-	    if ((xkbDebugFlags&0x4)&&
-		((xE[i].u.u.type==KeyPress)||(xE[i].u.u.type==KeyRelease)||
-                 (xE[i].u.u.type==DeviceKeyPress)||
-                 (xE[i].u.u.type == DeviceKeyRelease))) {
-		DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n");
-		DebugF("[xkb] event= 0x%04x\n",xE[i].u.keyButtonPointer.state);
-		DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n",xkbi->state.lookup_mods,
-							xkbi->state.grab_mods);
-		DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n",
-							xkbi->state.compat_lookup_mods,
-							xkbi->state.compat_grab_mods);
-	    }
-	    if ( (type>=KeyPress)&&(type<=MotionNotify) ) {
-		CARD16	old,new;
+        if ((xkbDebugFlags & 0x4) &&
+	    (xE[0].u.u.type == KeyPress || xE[0].u.u.type==KeyRelease ||
+             xE[0].u.u.type == DeviceKeyPress ||
+             xE[0].u.u.type == DeviceKeyRelease)) {
+	    DebugF("[xkb] XKbFilterWriteEvents (non-XKB):\n");
+	    DebugF("[xkb] event= 0x%04x\n",xE[0].u.keyButtonPointer.state);
+	    DebugF("[xkb] lookup= 0x%02x, grab= 0x%02x\n",
+                   xkbi->state.lookup_mods, xkbi->state.grab_mods);
+	    DebugF("[xkb] compat lookup= 0x%02x, grab= 0x%02x\n",
+		   xkbi->state.compat_lookup_mods, xkbi->state.compat_grab_mods);
+	}
+	if (type >= KeyPress && type <= MotionNotify) {
+	    CARD16 old, new;
 
-		old= xE[i].u.keyButtonPointer.state&(~0x1f00);
-		new= xE[i].u.keyButtonPointer.state&0x1F00;
+	    old = xE[0].u.keyButtonPointer.state & ~0x1f00;
+	    new = xE[0].u.keyButtonPointer.state & 0x1F00;
 
-		if (old==XkbStateFieldFromRec(&xkbi->state))
-		     new|= xkbi->state.compat_lookup_mods;
-		else new|= xkbi->state.compat_grab_mods;
-		xE[i].u.keyButtonPointer.state= new;
-	    }
-	    else if ((type==EnterNotify)||(type==LeaveNotify)) {
-		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 &&
-		(xkbi->lockedPtrButtons & button_mask) == button_mask) {
-		DebugF("[xkb] Faking release of button %d\n", xE[i].u.u.detail);
-		XkbDDXFakeDeviceButton(xkbi->device, 0, xE[i].u.u.detail);
-	    } else if (type == DeviceButtonPress &&
-                    ((((deviceKeyButtonPointer*)&xE[i])->state >> 7) & button_mask) == button_mask &&
-                    (xkbi->lockedPtrButtons & button_mask) == button_mask) {
-		DebugF("[xkb] Faking release of button %d\n", ((deviceKeyButtonPointer*)&xE[i])->state);
-		XkbDDXFakeDeviceButton(xkbi->device, 0, ((deviceKeyButtonPointer*)&xE[i])->state);
-            }
+	    if (old == XkbStateFieldFromRec(&xkbi->state))
+		new |= xkbi->state.compat_lookup_mods;
+	    else
+                new |= xkbi->state.compat_grab_mods;
+	    xE[0].u.keyButtonPointer.state = new;
 	}
+	else if (type == EnterNotify || type == LeaveNotify) {
+	    xE[0].u.enterLeave.state &= 0x1F00;
+	    xE[0].u.enterLeave.state |= xkbi->state.compat_grab_mods;
+	}
+        else if (type >= DeviceKeyPress && type <= DeviceMotionNotify) {
+            CARD16 old, new;
+            deviceKeyButtonPointer *kbp = (deviceKeyButtonPointer*) &xE[0];
+
+            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;
+        }
     }
-    return True;
 }
 
 /***====================================================================***/
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index e01282d..8f6705f 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -52,59 +52,38 @@ int		key;
 XkbBehavior	behavior;
 unsigned        ndx;
 
-    xkbi= keyc->xkbInfo;
-    key= event->detail.key;
-    if (xkbDebugFlags&0x8) {
+    xkbi = keyc->xkbInfo;
+    key = event->detail.key;
+    if (xkbDebugFlags & 0x8)
 	DebugF("[xkb] XkbPKE: Key %d %s\n",key,(event->type == ET_KeyPress?"down":"up"));
-    }
 
-    if ( (xkbi->repeatKey==key) && (event->type== ET_KeyRelease) &&
-	 ((xkbi->desc->ctrls->enabled_ctrls&XkbRepeatKeysMask)==0) ) {
-	AccessXCancelRepeatKey(xkbi,key);
-    }
+    if (xkbi->repeatKey == key && event->type== ET_KeyRelease &&
+        !(xkbi->desc->ctrls->enabled_ctrls & XkbRepeatKeysMask))
+	AccessXCancelRepeatKey(xkbi, key);
 
-    behavior= xkbi->desc->server->behaviors[key];
+    behavior = xkbi->desc->server->behaviors[key];
     /* The "permanent" flag indicates a hard-wired behavior that occurs */
     /* 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) {
+    if (!(behavior.type & XkbKB_Permanent)) {
 	switch (behavior.type) {
 	    case XkbKB_Default:
-		if (event->type == ET_KeyPress &&
-		    (keyc->down[key>>3] & (1<<(key&7)))) {
-		    XkbLastRepeatEvent=	(pointer)event;
-
-		    event->type = ET_KeyRelease;
-		    XkbHandleActions(keybd, keybd, event);
-
-		    event->type = ET_KeyPress;
-		    XkbHandleActions(keybd, keybd, event);
-		    XkbLastRepeatEvent= NULL;
-		    return;
-		}
+                /* Neither of these should happen in practice, but ignore them
+                   anyway. */
+		if (event->type == ET_KeyPress && !event->key_repeat &&
+                    key_is_down(keybd, key, KEY_PROCESSED))
+                    return;
 		else if (event->type == ET_KeyRelease &&
-			(!(keyc->down[key>>3]&(1<<(key&7))))) {
-		    XkbLastRepeatEvent=	(pointer)event;
-		    event->type = ET_KeyPress;
-		    XkbHandleActions(keybd, keybd, event);
-		    event->type = ET_KeyRelease;
-		    XkbHandleActions(keybd, keybd, event);
-		    XkbLastRepeatEvent= NULL;
-		    return;
-		}
+                         !key_is_down(keybd, key, KEY_PROCESSED))
+                    return;
 		break;
 	    case XkbKB_Lock:
-		if (event->type == ET_KeyRelease) {
+		if (event->type == ET_KeyRelease)
 		    return;
-                }
-		else {
-		    int	bit= 1<<(key&7);
-		    if ( keyc->down[key>>3]&bit ) {
-			event->type = ET_KeyRelease;
-                    }
-                }
+		else if (key_is_down(keybd, key, KEY_PROCESSED))
+                    event->type = ET_KeyRelease;
 		break;
 	    case XkbKB_RadioGroup:
 		ndx= (behavior.data&(~XkbKB_RGAllowNone));
@@ -173,9 +152,6 @@ ProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd)
     int is_press = (event->type == ET_KeyPress);
     int is_release = (event->type == ET_KeyRelease);
 
-    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);
@@ -185,6 +161,8 @@ ProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd)
         return;
     }
 
+    xkbi = keyc->xkbInfo;
+
     /* If AccessX filters are active, then pass it through to
      * AccessXFilter{Press,Release}Event; else, punt to
      * XkbProcessKeyboardEvent.
@@ -196,8 +174,9 @@ ProcessKeyboardEvent(InternalEvent *ev, DeviceIntPtr keybd)
             AccessXFilterPressEvent(event, keybd);
         else if (is_release)
             AccessXFilterReleaseEvent(event, keybd);
-
-    } else {
+        return;
+    }
+    else {
         XkbProcessKeyboardEvent(event, keybd);
     }
 
commit 3d988e01e41e98fc5160f825a250522ba274d09f
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Fri Aug 21 15:15:41 2009 +1000

    dix: improve code flow in TryClientEvents, better debugging messages.
    
    Instead of a massive if (blah && blah), return early where possible.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/events.c b/dix/events.c
index de96de3..acc1803 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -1891,70 +1891,84 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
     int type;
 
 #ifdef DEBUG_EVENTS
-    ErrorF("[dix] Event([%d, %d], mask=0x%x), client=%d",
-	pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
+    ErrorF("[dix] Event([%d, %d], mask=0x%lx), client=%d%s",
+           pEvents->u.u.type, pEvents->u.u.detail, mask,
+           client ? client->index : -1,
+           (client && client->clientGone) ? " (gone)" : "");
 #endif
-    if ((client) && (client != serverClient) && (!client->clientGone) &&
-	((filter == CantBeFiltered) || (mask & filter)))
-    {
-	if (grab && !SameClient(grab, client))
-	    return -1; /* don't send, but notify caller */
-	type = pEvents->u.u.type;
-	if (type == MotionNotify)
-	{
-	    if (mask & PointerMotionHintMask)
-	    {
-		if (WID(dev->valuator->motionHintWindow) ==
-		    pEvents->u.keyButtonPointer.event)
-		{
+
+    if (!client || client == serverClient || client->clientGone) {
 #ifdef DEBUG_EVENTS
-		    ErrorF("[dix] \n");
-	    ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n");
+        ErrorF(" not delivered to fake/dead client\n");
 #endif
-		    return 1; /* don't send, but pretend we did */
-		}
-		pEvents->u.u.detail = NotifyHint;
-	    }
-	    else
-	    {
-		pEvents->u.u.detail = NotifyNormal;
-	    }
-	}
-	else
-	{
-	    if ((type == DeviceMotionNotify) &&
-		MaybeSendDeviceMotionNotifyHint
-			((deviceKeyButtonPointer*)pEvents, mask) != 0)
-		return 1;
-	}
-	type &= 0177;
-	if (type != KeymapNotify)
-	{
-	    /* all extension events must have a sequence number */
-	    for (i = 0; i < count; i++)
-		pEvents[i].u.u.sequenceNumber = client->sequence;
-	}
+        return 0;
+    }
 
-	if (BitIsOn(criticalEvents, type))
-	{
-	    if (client->smart_priority < SMART_MAX_PRIORITY)
-		client->smart_priority++;
-	    SetCriticalOutputPending();
-	}
+    if (filter != CantBeFiltered && !(mask & filter))
+    {
+ #ifdef DEBUG_EVENTS
+        ErrorF(" filtered\n");
+ #endif
+        return 0;
+    }
 
-	WriteEventsToClient(client, count, pEvents);
+    if (grab && !SameClient(grab, client))
+    {
 #ifdef DEBUG_EVENTS
-	ErrorF("[dix]  delivered\n");
+        ErrorF(" not delivered due to grab\n");
 #endif
-	return 1;
+        return -1; /* don't send, but notify caller */
     }
-    else
+
+    type = pEvents->u.u.type;
+    if (type == MotionNotify)
     {
+        if (mask & PointerMotionHintMask)
+        {
+            if (WID(dev->valuator->motionHintWindow) ==
+                    pEvents->u.keyButtonPointer.event)
+            {
 #ifdef DEBUG_EVENTS
-	ErrorF("[dix] \n");
+                ErrorF("[dix] \n");
+                ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n");
 #endif
-	return 0;
+                return 1; /* don't send, but pretend we did */
+            }
+            pEvents->u.u.detail = NotifyHint;
+        }
+        else
+        {
+            pEvents->u.u.detail = NotifyNormal;
+        }
     }
+    else
+    {
+        if ((type == DeviceMotionNotify) &&
+                MaybeSendDeviceMotionNotifyHint
+                ((deviceKeyButtonPointer*)pEvents, mask) != 0)
+            return 1;
+    }
+
+    type &= 0177;
+    if (type != KeymapNotify)
+    {
+        /* all extension events must have a sequence number */
+        for (i = 0; i < count; i++)
+            pEvents[i].u.u.sequenceNumber = client->sequence;
+    }
+
+    if (BitIsOn(criticalEvents, type))
+    {
+        if (client->smart_priority < SMART_MAX_PRIORITY)
+            client->smart_priority++;
+        SetCriticalOutputPending();
+    }
+
+    WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG_EVENTS
+    ErrorF("[dix]  delivered\n");
+#endif
+    return 1;
 }
 
 /**


More information about the xorg-commit mailing list