]> source.dussan.org Git - tigervnc.git/commitdiff
Handle Windows scan code exceptions
authorPierre Ossman <ossman@cendio.se>
Mon, 13 Nov 2017 08:06:03 +0000 (09:06 +0100)
committerPierre Ossman <ossman@cendio.se>
Mon, 13 Nov 2017 14:55:51 +0000 (15:55 +0100)
Windows mostly follows the AT set 1 scan codes that we want, but
there are a few exceptions.

vncviewer/Viewport.cxx
win/rfb_win32/SInput.cxx

index 31d09a1e4521b40fc9b488f699e45174fc601a21..960a085cfd3d0e2a890b1143aafc32c477eb086a 100644 (file)
@@ -894,10 +894,24 @@ int Viewport::handleSystemEvent(void *event, void *data)
     if (isExtended)
       keyCode |= 0x80;
 
-    // VK_SNAPSHOT sends different scan codes depending on the state of
-    // Alt. This means that we can get different scan codes on press and
-    // release. Force it to be something standard.
-    if (vKey == VK_SNAPSHOT)
+
+    // Fortunately RFB and Windows use the same scan code set (mostly),
+    // so there is no conversion needed
+    // (as long as we encode the extended keys with the high bit)
+
+    // However Pause sends a code that conflicts with NumLock, so use
+    // the code most RFB implementations use (part of the sequence for
+    // Ctrl+Pause, i.e. Break)
+    if (keyCode == 0x45)
+      keyCode = 0xc6;
+
+    // And NumLock incorrectly has the extended bit set
+    if (keyCode == 0xc5)
+      keyCode = 0x45;
+
+    // And Alt+PrintScreen (i.e. SysRq) sends a different code than
+    // PrintScreen
+    if (keyCode == 0xb7)
       keyCode = 0x54;
 
     keySym = win32_vkey_to_keysym(vKey, isExtended);
@@ -908,10 +922,6 @@ int Viewport::handleSystemEvent(void *event, void *data)
         vlog.error(_("No symbol for virtual key 0x%02x"), (int)vKey);
     }
 
-    // Fortunately RFB and Windows use the same scan code set,
-    // so there is no conversion needed
-    // (as long as we encode the extended keys with the high bit)
-
     self->handleKeyPress(keyCode, keySym);
 
     return 1;
@@ -934,7 +944,11 @@ int Viewport::handleSystemEvent(void *event, void *data)
       keyCode = MapVirtualKey(vKey, MAPVK_VK_TO_VSC);
     if (isExtended)
       keyCode |= 0x80;
-    if (vKey == VK_SNAPSHOT)
+    if (keyCode == 0x45)
+      keyCode = 0xc6;
+    if (keyCode == 0xc5)
+      keyCode = 0x45;
+    if (keyCode == 0xb7)
       keyCode = 0x54;
 
     self->handleKeyRelease(keyCode);
index f6075c1663e609bca3daae267992ef0e591913db..e6da9b8498386baa4a9efae6cc8a4445d7edc4ee 100644 (file)
@@ -253,6 +253,16 @@ inline void doScanCodeEvent(BYTE scancode, bool down) {
   vlog.debug("SendInput ScanCode: 0x%x Flags: 0x%lx %s", scancode,
              evt.ki.dwFlags, down ? "Down" : "Up");
 
+  // Windows has some bug where it doesn't look up scan code 0x45
+  // properly, so we need to help it out
+  if (evt.ki.wScan == 0x45) {
+    evt.ki.dwFlags &= ~KEYEVENTF_SCANCODE;
+    if (evt.ki.dwFlags & KEYEVENTF_EXTENDEDKEY)
+      evt.ki.wVk = VK_NUMLOCK;
+    else
+      evt.ki.wVk = VK_PAUSE;
+  }
+
   if (SendInput(1, &evt, sizeof(evt)) != 1)
     vlog.error("SendInput %lu", GetLastError());
 }
@@ -354,6 +364,19 @@ void win32::SKeyboard::keyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
   // If scan code is available use that directly as windows uses
   // compatible scancodes
   if (keycode && rawKeyboard) {
+    // However NumLock incorrectly has the extended bit set
+    if (keycode == 0x45)
+      keycode = 0xc5;
+
+    // And Pause uses NumLock's proper code, except when Control is
+    // also pressed (i.e. when it is generating Break)
+    if ((keycode == 0xc6) && !(GetAsyncKeyState(VK_CONTROL) & 0x8000))
+      keycode = 0x45;
+
+    // And PrintScreen uses a different code than Alt+PrintScreen (SysRq)
+    if ((keycode == 0x54) && !(GetAsyncKeyState(VK_MENU) & 0x8000))
+      keycode = 0xb7;
+
     doScanCodeEvent(keycode, down);
     return;
   }