SDL: [Win32] Better keyboard button mapping to SDL scan codes

From acc5bb89f8b526e6d72c76cfdc78eff1a9acc505 Mon Sep 17 00:00:00 2001
From: Dimitriy Ryazantcev <[EMAIL REDACTED]>
Date: Tue, 21 Nov 2023 14:07:18 +0200
Subject: [PATCH] [Win32] Better keyboard button mapping to SDL scan codes

Using official mappings from the Microsoft docs:
https://learn.microsoft.com/windows/win32/inputdev/about-keyboard-input#scan-codes
---
 VisualC-GDK/SDL/SDL.vcxproj           |   1 -
 VisualC-GDK/SDL/SDL.vcxproj.filters   |   3 -
 VisualC/SDL/SDL.vcxproj               |   1 -
 VisualC/SDL/SDL.vcxproj.filters       |   3 -
 src/events/scancodes_windows.h        | 188 +++++++++++++++++++----
 src/video/windows/SDL_vkeys.h         |  74 ---------
 src/video/windows/SDL_windowsevents.c | 211 +++-----------------------
 7 files changed, 181 insertions(+), 300 deletions(-)
 delete mode 100644 src/video/windows/SDL_vkeys.h

diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 6cae7db9582c..2c5b186f8965 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -526,7 +526,6 @@
     <ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
     <ClInclude Include="..\..\src\video\SDL_yuv_c.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_msctf.h" />
-    <ClInclude Include="..\..\src\video\windows\SDL_vkeys.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsclipboard.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsevents.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsframebuffer.h" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 5b5c77da102e..c1f85c5a83df 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -627,9 +627,6 @@
     <ClInclude Include="..\..\src\video\yuv2rgb\yuv_rgb_std_func.h">
       <Filter>video\yuv2rgb</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\video\windows\SDL_vkeys.h">
-      <Filter>video\windows</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\video\windows\SDL_windowsclipboard.h">
       <Filter>video\windows</Filter>
     </ClInclude>
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index 528a3fba58ee..e547e4256ba9 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -454,7 +454,6 @@
     <ClInclude Include="..\..\src\video\SDL_vulkan_internal.h" />
     <ClInclude Include="..\..\src\video\SDL_yuv_c.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_msctf.h" />
-    <ClInclude Include="..\..\src\video\windows\SDL_vkeys.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsclipboard.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsevents.h" />
     <ClInclude Include="..\..\src\video\windows\SDL_windowsframebuffer.h" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 8a79f83f0ca7..5f1d2836f06d 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -621,9 +621,6 @@
     <ClInclude Include="..\..\src\video\yuv2rgb\yuv_rgb_std_func.h">
       <Filter>video\yuv2rgb</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\video\windows\SDL_vkeys.h">
-      <Filter>video\windows</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\video\windows\SDL_windowsclipboard.h">
       <Filter>video\windows</Filter>
     </ClInclude>
diff --git a/src/events/scancodes_windows.h b/src/events/scancodes_windows.h
index 3a65b8c16cdf..697d2f28ff25 100644
--- a/src/events/scancodes_windows.h
+++ b/src/events/scancodes_windows.h
@@ -20,12 +20,12 @@
 */
 #include "SDL_internal.h"
 
-/* Windows scancode to SDL scancode mapping table */
-/* derived from Microsoft scan code document, http://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc */
+/*
+ * Windows scancode to SDL scancode mapping table
+ * https://learn.microsoft.com/windows/win32/inputdev/about-keyboard-input#scan-codes */
 
 /* *INDENT-OFF* */ /* clang-format off */
-static const SDL_Scancode windows_scancode_table[] =
-{
+static const SDL_Scancode windows_scancode_table[] = {
     /*0x00*/ SDL_SCANCODE_UNKNOWN,
     /*0x01*/ SDL_SCANCODE_ESCAPE,
     /*0x02*/ SDL_SCANCODE_1,
@@ -81,7 +81,7 @@ static const SDL_Scancode windows_scancode_table[] =
     /*0x34*/ SDL_SCANCODE_PERIOD,
     /*0x35*/ SDL_SCANCODE_SLASH,
     /*0x36*/ SDL_SCANCODE_RSHIFT,
-    /*0x37*/ SDL_SCANCODE_PRINTSCREEN,
+    /*0x37*/ SDL_SCANCODE_KP_MULTIPLY,
     /*0x38*/ SDL_SCANCODE_LALT,
     /*0x39*/ SDL_SCANCODE_SPACE,
     /*0x3a*/ SDL_SCANCODE_CAPSLOCK,
@@ -97,29 +97,29 @@ static const SDL_Scancode windows_scancode_table[] =
     /*0x44*/ SDL_SCANCODE_F10,
     /*0x45*/ SDL_SCANCODE_NUMLOCKCLEAR,
     /*0x46*/ SDL_SCANCODE_SCROLLLOCK,
-    /*0x47*/ SDL_SCANCODE_HOME,
-    /*0x48*/ SDL_SCANCODE_UP,
-    /*0x49*/ SDL_SCANCODE_PAGEUP,
+    /*0x47*/ SDL_SCANCODE_KP_7,
+    /*0x48*/ SDL_SCANCODE_KP_8,
+    /*0x49*/ SDL_SCANCODE_KP_9,
     /*0x4a*/ SDL_SCANCODE_KP_MINUS,
-    /*0x4b*/ SDL_SCANCODE_LEFT,
+    /*0x4b*/ SDL_SCANCODE_KP_4,
     /*0x4c*/ SDL_SCANCODE_KP_5,
-    /*0x4d*/ SDL_SCANCODE_RIGHT,
+    /*0x4d*/ SDL_SCANCODE_KP_6,
     /*0x4e*/ SDL_SCANCODE_KP_PLUS,
-    /*0x4f*/ SDL_SCANCODE_END,
-    /*0x50*/ SDL_SCANCODE_DOWN,
-    /*0x51*/ SDL_SCANCODE_PAGEDOWN,
-    /*0x52*/ SDL_SCANCODE_INSERT,
-    /*0x53*/ SDL_SCANCODE_DELETE,
+    /*0x4f*/ SDL_SCANCODE_KP_1,
+    /*0x50*/ SDL_SCANCODE_KP_2,
+    /*0x51*/ SDL_SCANCODE_KP_3,
+    /*0x52*/ SDL_SCANCODE_KP_0,
+    /*0x53*/ SDL_SCANCODE_KP_PERIOD,
     /*0x54*/ SDL_SCANCODE_UNKNOWN,
     /*0x55*/ SDL_SCANCODE_UNKNOWN,
     /*0x56*/ SDL_SCANCODE_NONUSBACKSLASH,
     /*0x57*/ SDL_SCANCODE_F11,
     /*0x58*/ SDL_SCANCODE_F12,
-    /*0x59*/ SDL_SCANCODE_PAUSE,
+    /*0x59*/ SDL_SCANCODE_KP_EQUALS,
     /*0x5a*/ SDL_SCANCODE_UNKNOWN,
-    /*0x5b*/ SDL_SCANCODE_LGUI,
-    /*0x5c*/ SDL_SCANCODE_RGUI,
-    /*0x5d*/ SDL_SCANCODE_APPLICATION,
+    /*0x5b*/ SDL_SCANCODE_UNKNOWN,
+    /*0x5c*/ SDL_SCANCODE_INTERNATIONAL6,
+    /*0x5d*/ SDL_SCANCODE_UNKNOWN,
     /*0x5e*/ SDL_SCANCODE_UNKNOWN,
     /*0x5f*/ SDL_SCANCODE_UNKNOWN,
     /*0x60*/ SDL_SCANCODE_UNKNOWN,
@@ -133,26 +133,154 @@ static const SDL_Scancode windows_scancode_table[] =
     /*0x68*/ SDL_SCANCODE_F17,
     /*0x69*/ SDL_SCANCODE_F18,
     /*0x6a*/ SDL_SCANCODE_F19,
-    /*0x6b*/ SDL_SCANCODE_UNKNOWN,
-    /*0x6c*/ SDL_SCANCODE_UNKNOWN,
-    /*0x6d*/ SDL_SCANCODE_UNKNOWN,
-    /*0x6e*/ SDL_SCANCODE_UNKNOWN,
+    /*0x6b*/ SDL_SCANCODE_F20,
+    /*0x6c*/ SDL_SCANCODE_F21,
+    /*0x6d*/ SDL_SCANCODE_F22,
+    /*0x6e*/ SDL_SCANCODE_F23,
     /*0x6f*/ SDL_SCANCODE_UNKNOWN,
     /*0x70*/ SDL_SCANCODE_INTERNATIONAL2,
-    /*0x71*/ SDL_SCANCODE_UNKNOWN,
-    /*0x72*/ SDL_SCANCODE_UNKNOWN,
+    /*0x71*/ SDL_SCANCODE_LANG2,
+    /*0x72*/ SDL_SCANCODE_LANG1,
     /*0x73*/ SDL_SCANCODE_INTERNATIONAL1,
     /*0x74*/ SDL_SCANCODE_UNKNOWN,
     /*0x75*/ SDL_SCANCODE_UNKNOWN,
-    /*0x76*/ SDL_SCANCODE_UNKNOWN,
-    /*0x77*/ SDL_SCANCODE_UNKNOWN,
-    /*0x78*/ SDL_SCANCODE_UNKNOWN,
+    /*0x76*/ SDL_SCANCODE_F24,
+    /*0x77*/ SDL_SCANCODE_LANG4,
+    /*0x78*/ SDL_SCANCODE_LANG3,
     /*0x79*/ SDL_SCANCODE_INTERNATIONAL4,
     /*0x7a*/ SDL_SCANCODE_UNKNOWN,
     /*0x7b*/ SDL_SCANCODE_INTERNATIONAL5,
     /*0x7c*/ SDL_SCANCODE_UNKNOWN,
     /*0x7d*/ SDL_SCANCODE_INTERNATIONAL3,
-    /*0x7e*/ SDL_SCANCODE_UNKNOWN,
-    /*0x7f*/ SDL_SCANCODE_UNKNOWN
+    /*0x7e*/ SDL_SCANCODE_KP_COMMA,
+    /*0x7f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe000*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe001*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe002*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe003*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe004*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe005*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe006*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe007*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe008*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe009*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00c*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00d*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe00f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe010*/ SDL_SCANCODE_AUDIOPREV,
+    /*0xe011*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe012*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe013*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe014*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe015*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe016*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe017*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe018*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe019*/ SDL_SCANCODE_AUDIONEXT,
+    /*0xe01a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe01b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe01c*/ SDL_SCANCODE_KP_ENTER,
+    /*0xe01d*/ SDL_SCANCODE_RCTRL,
+    /*0xe01e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe01f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe020*/ SDL_SCANCODE_MUTE,
+    /*0xe021*/ SDL_SCANCODE_CALCULATOR,
+    /*0xe022*/ SDL_SCANCODE_AUDIOPLAY,
+    /*0xe023*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe024*/ SDL_SCANCODE_AUDIOSTOP,
+    /*0xe025*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe026*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe027*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe028*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe029*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe02a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe02b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe02c*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe02d*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe02e*/ SDL_SCANCODE_VOLUMEDOWN,
+    /*0xe02f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe030*/ SDL_SCANCODE_VOLUMEUP,
+    /*0xe031*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe032*/ SDL_SCANCODE_AC_HOME,
+    /*0xe033*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe034*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe035*/ SDL_SCANCODE_KP_DIVIDE,
+    /*0xe036*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe037*/ SDL_SCANCODE_PRINTSCREEN,
+    /*0xe038*/ SDL_SCANCODE_RALT,
+    /*0xe039*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03c*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03d*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe03f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe040*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe041*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe042*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe043*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe044*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe045*/ SDL_SCANCODE_NUMLOCKCLEAR,
+    /*0xe046*/ SDL_SCANCODE_PAUSE,
+    /*0xe047*/ SDL_SCANCODE_HOME,
+    /*0xe048*/ SDL_SCANCODE_UP,
+    /*0xe049*/ SDL_SCANCODE_PAGEUP,
+    /*0xe04a*/ SDL_SCANCODE_LEFT,
+    /*0xe04b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe04c*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe04d*/ SDL_SCANCODE_RIGHT,
+    /*0xe04e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe04f*/ SDL_SCANCODE_END,
+    /*0xe050*/ SDL_SCANCODE_DOWN,
+    /*0xe051*/ SDL_SCANCODE_PAGEDOWN,
+    /*0xe052*/ SDL_SCANCODE_INSERT,
+    /*0xe053*/ SDL_SCANCODE_DELETE,
+    /*0xe054*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe055*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe056*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe057*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe058*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe059*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe05a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe05b*/ SDL_SCANCODE_LGUI,
+    /*0xe05c*/ SDL_SCANCODE_RGUI,
+    /*0xe05d*/ SDL_SCANCODE_APPLICATION,
+    /*0xe05e*/ SDL_SCANCODE_POWER,
+    /*0xe05f*/ SDL_SCANCODE_SLEEP,
+    /*0xe060*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe061*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe062*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe063*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe064*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe065*/ SDL_SCANCODE_AC_SEARCH,
+    /*0xe066*/ SDL_SCANCODE_AC_BOOKMARKS,
+    /*0xe067*/ SDL_SCANCODE_AC_REFRESH,
+    /*0xe068*/ SDL_SCANCODE_AC_STOP,
+    /*0xe069*/ SDL_SCANCODE_AC_FORWARD,
+    /*0xe06a*/ SDL_SCANCODE_AC_BACK,
+    /*0xe06b*/ SDL_SCANCODE_COMPUTER,
+    /*0xe06c*/ SDL_SCANCODE_MAIL,
+    /*0xe06d*/ SDL_SCANCODE_MEDIASELECT,
+    /*0xe06e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe06f*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe070*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe071*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe072*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe073*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe074*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe075*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe076*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe077*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe078*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe079*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07a*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07b*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07c*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07d*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07e*/ SDL_SCANCODE_UNKNOWN,
+    /*0xe07f*/ SDL_SCANCODE_UNKNOWN
 };
 /* *INDENT-ON* */ /* clang-format on */
diff --git a/src/video/windows/SDL_vkeys.h b/src/video/windows/SDL_vkeys.h
deleted file mode 100644
index b15a39f09428..000000000000
--- a/src/video/windows/SDL_vkeys.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-  Simple DirectMedia Layer
-  Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-*/
-
-#ifndef VK_0
-#define VK_0 '0'
-#define VK_1 '1'
-#define VK_2 '2'
-#define VK_3 '3'
-#define VK_4 '4'
-#define VK_5 '5'
-#define VK_6 '6'
-#define VK_7 '7'
-#define VK_8 '8'
-#define VK_9 '9'
-#define VK_A 'A'
-#define VK_B 'B'
-#define VK_C 'C'
-#define VK_D 'D'
-#define VK_E 'E'
-#define VK_F 'F'
-#define VK_G 'G'
-#define VK_H 'H'
-#define VK_I 'I'
-#define VK_J 'J'
-#define VK_K 'K'
-#define VK_L 'L'
-#define VK_M 'M'
-#define VK_N 'N'
-#define VK_O 'O'
-#define VK_P 'P'
-#define VK_Q 'Q'
-#define VK_R 'R'
-#define VK_S 'S'
-#define VK_T 'T'
-#define VK_U 'U'
-#define VK_V 'V'
-#define VK_W 'W'
-#define VK_X 'X'
-#define VK_Y 'Y'
-#define VK_Z 'Z'
-#endif /* VK_0 */
-
-/* These keys haven't been defined, but were experimentally determined */
-#define VK_SEMICOLON  0xBA
-#define VK_EQUALS     0xBB
-#define VK_COMMA      0xBC
-#define VK_MINUS      0xBD
-#define VK_PERIOD     0xBE
-#define VK_SLASH      0xBF
-#define VK_GRAVE      0xC0
-#define VK_LBRACKET   0xDB
-#define VK_BACKSLASH  0xDC
-#define VK_RBRACKET   0xDD
-#define VK_APOSTROPHE 0xDE
-#define VK_BACKTICK   0xDF
-#define VK_OEM_102    0xE2
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 5202955bf054..d5381dd77cf0 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -23,7 +23,6 @@
 #ifdef SDL_VIDEO_DRIVER_WINDOWS
 
 #include "SDL_windowsvideo.h"
-#include "SDL_vkeys.h"
 #include "../../events/SDL_events_c.h"
 #include "../../events/SDL_touch_c.h"
 #include "../../events/scancodes_windows.h"
@@ -152,202 +151,38 @@ static Uint64 WIN_GetEventTimestamp()
     return timestamp;
 }
 
-static SDL_Scancode VKeytoScancodeFallback(WPARAM vkey)
-{
-    switch (vkey) {
-    case VK_LEFT:
-        return SDL_SCANCODE_LEFT;
-    case VK_UP:
-        return SDL_SCANCODE_UP;
-    case VK_RIGHT:
-        return SDL_SCANCODE_RIGHT;
-    case VK_DOWN:
-        return SDL_SCANCODE_DOWN;
-
-    default:
-        return SDL_SCANCODE_UNKNOWN;
-    }
-}
-
-static SDL_Scancode VKeytoScancode(WPARAM vkey)
-{
-    switch (vkey) {
-    case VK_MODECHANGE:
-        return SDL_SCANCODE_MODE;
-    case VK_SELECT:
-        return SDL_SCANCODE_SELECT;
-    case VK_EXECUTE:
-        return SDL_SCANCODE_EXECUTE;
-    case VK_HELP:
-        return SDL_SCANCODE_HELP;
-    case VK_PAUSE:
-        return SDL_SCANCODE_PAUSE;
-    case VK_NUMLOCK:
-        return SDL_SCANCODE_NUMLOCKCLEAR;
-
-    case VK_F13:
-        return SDL_SCANCODE_F13;
-    case VK_F14:
-        return SDL_SCANCODE_F14;
-    case VK_F15:
-        return SDL_SCANCODE_F15;
-    case VK_F16:
-        return SDL_SCANCODE_F16;
-    case VK_F17:
-        return SDL_SCANCODE_F17;
-    case VK_F18:
-        return SDL_SCANCODE_F18;
-    case VK_F19:
-        return SDL_SCANCODE_F19;
-    case VK_F20:
-        return SDL_SCANCODE_F20;
-    case VK_F21:
-        return SDL_SCANCODE_F21;
-    case VK_F22:
-        return SDL_SCANCODE_F22;
-    case VK_F23:
-        return SDL_SCANCODE_F23;
-    case VK_F24:
-        return SDL_SCANCODE_F24;
-
-    case VK_OEM_NEC_EQUAL:
-        return SDL_SCANCODE_KP_EQUALS;
-    case VK_BROWSER_BACK:
-        return SDL_SCANCODE_AC_BACK;
-    case VK_BROWSER_FORWARD:
-        return SDL_SCANCODE_AC_FORWARD;
-    case VK_BROWSER_REFRESH:
-        return SDL_SCANCODE_AC_REFRESH;
-    case VK_BROWSER_STOP:
-        return SDL_SCANCODE_AC_STOP;
-    case VK_BROWSER_SEARCH:
-        return SDL_SCANCODE_AC_SEARCH;
-    case VK_BROWSER_FAVORITES:
-        return SDL_SCANCODE_AC_BOOKMARKS;
-    case VK_BROWSER_HOME:
-        return SDL_SCANCODE_AC_HOME;
-    case VK_VOLUME_MUTE:
-        return SDL_SCANCODE_MUTE;
-    case VK_VOLUME_DOWN:
-        return SDL_SCANCODE_VOLUMEDOWN;
-    case VK_VOLUME_UP:
-        return SDL_SCANCODE_VOLUMEUP;
-
-    case VK_MEDIA_NEXT_TRACK:
-        return SDL_SCANCODE_AUDIONEXT;
-    case VK_MEDIA_PREV_TRACK:
-        return SDL_SCANCODE_AUDIOPREV;
-    case VK_MEDIA_STOP:
-        return SDL_SCANCODE_AUDIOSTOP;
-    case VK_MEDIA_PLAY_PAUSE:
-        return SDL_SCANCODE_AUDIOPLAY;
-    case VK_LAUNCH_MAIL:
-        return SDL_SCANCODE_MAIL;
-    case VK_LAUNCH_MEDIA_SELECT:
-        return SDL_SCANCODE_MEDIASELECT;
-
-    case VK_OEM_102:
-        return SDL_SCANCODE_NONUSBACKSLASH;
-
-    case VK_ATTN:
-        return SDL_SCANCODE_SYSREQ;
-    case VK_CRSEL:
-        return SDL_SCANCODE_CRSEL;
-    case VK_EXSEL:
-        return SDL_SCANCODE_EXSEL;
-    case VK_OEM_CLEAR:
-        return SDL_SCANCODE_CLEAR;
-
-    case VK_LAUNCH_APP1:
-        return SDL_SCANCODE_APP1;
-    case VK_LAUNCH_APP2:
-        return SDL_SCANCODE_APP2;
-
-    default:
-        return SDL_SCANCODE_UNKNOWN;
-    }
-}
-
 static SDL_Scancode WindowsScanCodeToSDLScanCode(LPARAM lParam, WPARAM wParam)
 {
     SDL_Scancode code;
-    int nScanCode = (lParam >> 16) & 0xFF;
-    SDL_bool bIsExtended = (lParam & (1 << 24)) != 0;
+    Uint8 index;
+    Uint16 keyFlags = HIWORD(lParam);
+    Uint16 scanCode = LOBYTE(keyFlags);
 
-    code = VKeytoScancode(wParam);
+    /* On-Screen Keyboard can send wrong scan codes with high-order bit set (key break code).
+     * Strip high-order bit. */
+    scanCode &= ~0x80;
 
-    if (code == SDL_SCANCODE_UNKNOWN && nScanCode <= 127) {
-        code = windows_scancode_table[nScanCode];
+    if (scanCode != 0) {
+        if ((keyFlags & KF_EXTENDED) == KF_EXTENDED) {
+            scanCode = MAKEWORD(scanCode, 0xe0);
+        }
+    } else {
+        Uint16 vkCode = LOWORD(wParam);
 
-        if (bIsExtended) {
-            switch (code) {
-            case SDL_SCANCODE_RETURN:
-                code = SDL_SCANCODE_KP_ENTER;
-                break;
-            case SDL_SCANCODE_LALT:
-                code = SDL_SCANCODE_RALT;
-                break;
-            case SDL_SCANCODE_LCTRL:
-                code = SDL_SCANCODE_RCTRL;
-                break;
-            case SDL_SCANCODE_SLASH:
-                code = SDL_SCANCODE_KP_DIVIDE;
-                break;
-            case SDL_SCANCODE_CAPSLOCK:
-                code = SDL_SCANCODE_KP_PLUS;
-                break;
-            default:
-                break;
-            }
-        } else {
-            switch (code) {
-            case SDL_SCANCODE_HOME:
-                code = SDL_SCANCODE_KP_7;
-                break;
-            case SDL_SCANCODE_UP:
-                code = SDL_SCANCODE_KP_8;
-                break;
-            case SDL_SCANCODE_PAGEUP:
-                code = SDL_SCANCODE_KP_9;
-                break;
-            case SDL_SCANCODE_LEFT:
-                code = SDL_SCANCODE_KP_4;
-                break;
-            case SDL_SCANCODE_RIGHT:
-                code = SDL_SCANCODE_KP_6;
-                break;
-            case SDL_SCANCODE_END:
-                code = SDL_SCANCODE_KP_1;
-                break;
-            case SDL_SCANCODE_DOWN:
-                code = SDL_SCANCODE_KP_2;
-                break;
-            case SDL_SCANCODE_PAGEDOWN:
-                code = SDL_SCANCODE_KP_3;
-                break;
-            case SDL_SCANCODE_INSERT:
-                code = SDL_SCANCODE_KP_0;
-                break;
-            case SDL_SCANCODE_DELETE:
-                code = SDL_SCANCODE_KP_PERIOD;
-                break;
-            case SDL_SCANCODE_PRINTSCREEN:
-                code = SDL_SCANCODE_KP_MULTIPLY;
-                break;
-            default:
-                break;
-            }
+        /* Windows may not report scan codes for some buttons (multimedia buttons etc).
+         * Get scan code from the VK code.*/
+        scanCode = LOWORD(MapVirtualKey(vkCode, MAPVK_VK_TO_VSC_EX));
+
+        /* Pause/Break key have a special scan code with 0xe1 prefix.
+         * Use Pause scan code that is used in Win32. */
+        if (scanCode == 0xe11d) {
+            scanCode = 0xe046;
         }
     }
 
-    /* The on-screen keyboard can generate VK_LEFT and VK_RIGHT events without a scancode
-     * value set, however we cannot simply map these in VKeytoScancode() or we will be
-     * incorrectly handling the arrow keys on the number pad when NumLock is disabled
-     * (which also generate VK_LEFT, VK_RIGHT, etc in that scenario). Instead, we'll only
-     * map them if none of the above special number pad mappings applied. */
-    if (code == SDL_SCANCODE_UNKNOWN) {
-        code = VKeytoScancodeFallback(wParam);
-    }
+    /* Pack scan code into one byte to make the index. */
+    index = LOBYTE(scanCode) | (HIBYTE(scanCode) ? 0x80 : 0x00);
+    code = windows_scancode_table[index];
 
     return code;
 }