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

Eric Anholt anholt at kemper.freedesktop.org
Thu Sep 6 00:39:44 PDT 2007


 dix/devices.c                  |    1 +
 dix/getevents.c                |   37 ++++++++++++++++++++++++++++++-------
 hw/xfree86/common/atKeynames.h |    2 +-
 hw/xfree86/common/xf86Events.c |    4 +++-
 include/inputstr.h             |    1 +
 5 files changed, 36 insertions(+), 9 deletions(-)

New commits:
diff-tree f73fd98a8636c0df3133a8b9428f3f23ecc788b4 (from 3c5fe1ec377688ab2edc6137b74a7c04b3bc2e7e)
Author: Daniel Stone <daniel at fooishbar.org>
Date:   Wed Sep 5 17:46:23 2007 -0700

    Fix key repeats during VT switch.
    
    Add keyc->postdown, which represents the key state as of the last mieqEnqueue
    call, and use it when we need to know the posted state, instead of the
    processed state (keyc->down).  Add small functions to getevents.c to query and
    modify key state in postdown and use them all through, eliminating previously
    broken uses.
    (cherry picked from commit 81c28ffd2b13a83770eadcfd7829d35d319d637f)

diff --git a/dix/devices.c b/dix/devices.c
index 923bc0d..9f3c576 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -868,6 +868,7 @@ InitKeyClassDeviceStruct(DeviceIntPtr de
     else
 	bzero((char *)keyc->modifierMap, MAP_LENGTH);
     bzero((char *)keyc->down, DOWN_LENGTH);
+    bzero((char *)keyc->postdown, DOWN_LENGTH);
     for (i = 0; i < 8; i++)
 	keyc->modifierKeyCount[i] = 0;
     if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
diff --git a/dix/getevents.c b/dix/getevents.c
index 162fa45..f92a021 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -80,6 +80,23 @@ GetMotionHistorySize(void)
     return MOTION_HISTORY_SIZE;
 }
 
+static void
+set_key_down(DeviceIntPtr pDev, int key_code)
+{
+    pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
+}
+
+static void
+set_key_up(DeviceIntPtr pDev, int key_code)
+{
+    pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
+}
+
+static Bool
+key_is_down(DeviceIntPtr pDev, int key_code)
+{
+    return pDev->key->postdown[key_code >> 3] >> (key_code & 7);
+}
 
 /**
  * Allocate the motion history buffer.
@@ -414,17 +431,15 @@ GetKeyboardValuatorEvents(xEvent *events
             case XK_Shift_Lock:
                 if (type == KeyRelease)
                     return 0;
-                else if (type == KeyPress &&
-                         (pDev->key->down[key_code >> 3] & (key_code & 7)) & 1)
-                        type = KeyRelease;
+                else if (type == KeyPress && key_is_down(pDev, key_code))
+                    type = KeyRelease;
         }
     }
 
     /* Handle core repeating, via press/release/press/release.
      * FIXME: In theory, if you're repeating with two keyboards in non-XKB,
      *        you could get unbalanced events here. */
-    if (type == KeyPress &&
-        (((pDev->key->down[key_code >> 3] & (key_code & 7))) & 1)) {
+    if (type == KeyPress && key_is_down(pDev, key_code)) {
         if (!pDev->kbdfeed->ctrl.autoRepeat ||
             pDev->key->modifierMap[key_code] ||
             !(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3]
@@ -449,6 +464,10 @@ GetKeyboardValuatorEvents(xEvent *events
         events->u.keyButtonPointer.time = ms;
         events->u.u.type = type;
         events->u.u.detail = key_code;
+        if (type == KeyPress)
+	    set_key_down(inputInfo.keyboard, key_code);
+        else if (type == KeyRelease)
+	    set_key_up(inputInfo.keyboard, key_code);
         events++;
     }
 
@@ -456,10 +475,14 @@ GetKeyboardValuatorEvents(xEvent *events
     kbp->time = ms;
     kbp->deviceid = pDev->id;
     kbp->detail = key_code;
-    if (type == KeyPress)
+    if (type == KeyPress) {
         kbp->type = DeviceKeyPress;
-    else if (type == KeyRelease)
+	set_key_down(pDev, key_code);
+    }
+    else if (type == KeyRelease) {
         kbp->type = DeviceKeyRelease;
+	set_key_up(pDev, key_code);
+    }
 
     events++;
     if (num_valuators) {
diff --git a/hw/xfree86/common/atKeynames.h b/hw/xfree86/common/atKeynames.h
index f31f533..85f13ac 100644
--- a/hw/xfree86/common/atKeynames.h
+++ b/hw/xfree86/common/atKeynames.h
@@ -66,7 +66,7 @@
 #define KanaMask	Mod4Mask
 #define ScrollLockMask	Mod5Mask
 
-#define KeyPressed(k) (keyc->down[k >> 3] & (1 << (k & 7)))
+#define KeyPressed(k) (keyc->postdown[k >> 3] & (1 << (k & 7)))
 #define ModifierDown(k) ((keyc->state & (k)) == (k))
 
 /*
diff --git a/include/inputstr.h b/include/inputstr.h
index 3398949..d0cc858 100644
--- a/include/inputstr.h
+++ b/include/inputstr.h
@@ -122,6 +122,7 @@ typedef struct _GrabRec {
 
 typedef struct _KeyClassRec {
     CARD8		down[DOWN_LENGTH];
+    CARD8		postdown[DOWN_LENGTH];
     KeyCode 		*modifierKeyMap;
     KeySymsRec		curKeySyms;
     int			modifierKeyCount[8];
diff-tree 3c5fe1ec377688ab2edc6137b74a7c04b3bc2e7e (from 70ed110538413e96cefbf0a1c276b52dc62c5aae)
Author: Keith Packard <keithp at koto.keithp.com>
Date:   Wed Sep 5 14:19:19 2007 -0700

    Deliver correct event when releasing keys on VT switch.
    
    In commit 41bb9fce47f6366cc3f7d45790f7883f74289b5a, the event delivery loop
    for Xinput enabled keyboards was changed and accidentally used the wrong
    index variable, causing random events to be delivered when returning from VT
    switch.
    
    In addition, in commit aeba855b07832354f59678e20cc29a085e42bd99,
    SIGIO was blocked during delivery of these events, but not for the entire
    period the xf86Events array was being used. Block SIGIO for the whole loop
    to avoid other event delivery from trashing the key release events.
    (cherry picked from commit aa7ed1f5f35cd043bc38d985500aa0a32e857e84)
    (cherry picked from commit accd71bda6f958ea6892ad3a10879232d345774c)

diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index dd9c34e..91964c9 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -811,9 +811,11 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
                     (*pDev->public.processInputProc) (&ke, pDev, 1);
                 }
                 else {
+		    int sigstate = xf86BlockSIGIO ();
                     nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i);
                     for (j = 0; j < nevents; j++)
-                        EqEnqueue(pDev, xf86Events + i);
+                        mieqEnqueue(pDev, xf86Events + j);
+		    xf86UnblockSIGIO(sigstate);
                 }
                 break;
             }


More information about the xorg-commit mailing list