Vitaliy Margolen : winex11: Properly report state of the caps-lock and num-lock and scroll-lock keys.

Alexandre Julliard julliard at winehq.org
Mon Apr 7 06:51:04 CDT 2008


Module: wine
Branch: master
Commit: bc325ac268ab0b99e1ce6d5012dd329cacb2357c
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bc325ac268ab0b99e1ce6d5012dd329cacb2357c

Author: Vitaliy Margolen <wine-patches at kievinfo.com>
Date:   Sat Apr  5 23:36:55 2008 -0600

winex11: Properly report state of the caps-lock and num-lock and scroll-lock keys.

---

 dlls/winex11.drv/keyboard.c |  134 +++++++++++++++----------------------------
 1 files changed, 46 insertions(+), 88 deletions(-)

diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index f11a9ee..4be6336 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1139,8 +1139,6 @@ static WORD EVENT_event_to_vkey( XIC xic, XKeyEvent *e)
     return keyc2vkey[e->keycode];
 }
 
-static BOOL NumState=FALSE, CapsState=FALSE;
-
 
 /***********************************************************************
  *           X11DRV_send_keyboard_input
@@ -1265,53 +1263,6 @@ void X11DRV_send_keyboard_input( WORD wVk, WORD wScan, DWORD dwFlags, DWORD time
 }
 
 
-/**********************************************************************
- *		KEYBOARD_GenerateMsg
- *
- * Generate Down+Up messages when NumLock or CapsLock is pressed.
- *
- * Convention : called with vkey only VK_NUMLOCK or VK_CAPITAL
- *
- */
-static void KEYBOARD_GenerateMsg( WORD vkey, WORD scan, int Evtype, DWORD event_time )
-{
-  BOOL * State = (vkey==VK_NUMLOCK? &NumState : &CapsState);
-  DWORD up, down;
-
-  if (*State) {
-    /* The INTERMEDIARY state means : just after a 'press' event, if a 'release' event comes,
-       don't treat it. It's from the same key press. Then the state goes to ON.
-       And from there, a 'release' event will switch off the toggle key. */
-    *State=FALSE;
-    TRACE("INTERM : don't treat release of toggle key. key_state_table[%#x] = %#x\n",
-          vkey,key_state_table[vkey]);
-  } else
-    {
-        down = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0);
-        up = (vkey==VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0) | KEYEVENTF_KEYUP;
-	if ( key_state_table[vkey] & 0x1 ) /* it was ON */
-	  {
-	    if (Evtype!=KeyPress)
-	      {
-		TRACE("ON + KeyRelease => generating DOWN and UP messages.\n");
-	        X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 );
-	        X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 );
-		*State=FALSE;
-		key_state_table[vkey] &= ~0x01; /* Toggle state to off. */
-	      }
-	  }
-	else /* it was OFF */
-	  if (Evtype==KeyPress)
-	    {
-	      TRACE("OFF + Keypress => generating DOWN and UP messages.\n");
-	      X11DRV_send_keyboard_input( vkey, scan, down, event_time, 0, 0 );
-	      X11DRV_send_keyboard_input( vkey, scan, up, event_time, 0, 0 );
-	      *State=TRUE; /* Goes to intermediary state before going to ON */
-	      key_state_table[vkey] |= 0x01; /* Toggle state to on. */
-	    }
-    }
-}
-
 /***********************************************************************
  *           KEYBOARD_UpdateOneState
  *
@@ -1370,6 +1321,16 @@ void X11DRV_KeymapNotify( HWND hwnd, XEvent *event )
     KEYBOARD_UpdateOneState( VK_SHIFT, shift, time );
 }
 
+static void update_lock_state(BYTE vkey, WORD scan, DWORD time)
+{
+    DWORD flags = vkey == VK_NUMLOCK ? KEYEVENTF_EXTENDEDKEY : 0;
+
+    if (key_state_table[vkey] & 0x80) flags ^= KEYEVENTF_KEYUP;
+
+    X11DRV_send_keyboard_input( vkey, scan, flags, time, 0, 0 );
+    X11DRV_send_keyboard_input( vkey, scan, flags ^ KEYEVENTF_KEYUP, time, 0, 0 );
+}
+
 /***********************************************************************
  *           X11DRV_KeyEvent
  *
@@ -1443,47 +1404,44 @@ void X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
     TRACE_(key)("keycode 0x%x converted to vkey 0x%x\n",
                 event->keycode, vkey);
 
-   if (vkey)
-   {
-    switch (vkey & 0xff)
-    {
-    case VK_NUMLOCK:
-      KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, event->type, event_time );
-      break;
-    case VK_CAPITAL:
-      TRACE("Caps Lock event. (type %d). State before : %#.2x\n",event->type,key_state_table[vkey]);
-      KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, event->type, event_time );
-      TRACE("State after : %#.2x\n",key_state_table[vkey]);
-      break;
-    default:
-        /* Adjust the NUMLOCK state if it has been changed outside wine */
-	if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask))
-	  {
-	    TRACE("Adjusting NumLock state.\n");
-	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyPress, event_time );
-	    KEYBOARD_GenerateMsg( VK_NUMLOCK, 0x45, KeyRelease, event_time );
-	  }
-        /* Adjust the CAPSLOCK state if it has been changed outside wine */
-	if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask))
-	  {
-              TRACE("Adjusting Caps Lock state.\n");
-	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyPress, event_time );
-	    KEYBOARD_GenerateMsg( VK_CAPITAL, 0x3A, KeyRelease, event_time );
-	  }
-	/* Not Num nor Caps : end of intermediary states for both. */
-	NumState = FALSE;
-	CapsState = FALSE;
+    if (!vkey) return;
+
+    dwFlags = 0;
+    if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
+    if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
+
 
-	bScan = keyc2scan[event->keycode] & 0xFF;
-	TRACE_(key)("bScan = 0x%02x.\n", bScan);
+    /* Note: X sets the below states on key down and clears them on key up.
+       Windows triggers them on key down. */
 
-	dwFlags = 0;
-	if ( event->type == KeyRelease ) dwFlags |= KEYEVENTF_KEYUP;
-	if ( vkey & 0x100 )              dwFlags |= KEYEVENTF_EXTENDEDKEY;
+    /* Adjust the CAPSLOCK state if it has been changed outside wine */
+    if (!(key_state_table[VK_CAPITAL] & 0x01) != !(event->state & LockMask) &&
+        vkey != VK_CAPITAL)
+    {
+        TRACE("Adjusting CapsLock state (%#.2x)\n", key_state_table[VK_CAPITAL]);
+        update_lock_state(VK_CAPITAL, 0x3A, event_time);
+    }
+
+    /* Adjust the NUMLOCK state if it has been changed outside wine */
+    if (!(key_state_table[VK_NUMLOCK] & 0x01) != !(event->state & NumLockMask) &&
+        (vkey & 0xff) != VK_NUMLOCK)
+    {
+        TRACE("Adjusting NumLock state (%#.2x)\n", key_state_table[VK_NUMLOCK]);
+        update_lock_state(VK_NUMLOCK, 0x45, event_time);
+    }
 
-        X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 );
+    /* Adjust the SCROLLLOCK state if it has been changed outside wine */
+    if (!(key_state_table[VK_SCROLL] & 0x01) != !(event->state & ScrollLockMask) &&
+        vkey != VK_SCROLL)
+    {
+        TRACE("Adjusting ScrLock state (%#.2x)\n", key_state_table[VK_SCROLL]);
+        update_lock_state(VK_SCROLL, 0x46, event_time);
     }
-   }
+
+    bScan = keyc2scan[event->keycode] & 0xFF;
+    TRACE_(key)("bScan = 0x%02x.\n", bScan);
+
+    X11DRV_send_keyboard_input( vkey & 0xff, bScan, dwFlags, event_time, 0, 0 );
 }
 
 /**********************************************************************




More information about the wine-cvs mailing list