diff --git a/src/BizHawk.Bizware.Input/DirectX/DKeyInput.cs b/src/BizHawk.Bizware.Input/DirectX/DKeyInput.cs index c2ec4c9ea1..9c0ce9c8b3 100644 --- a/src/BizHawk.Bizware.Input/DirectX/DKeyInput.cs +++ b/src/BizHawk.Bizware.Input/DirectX/DKeyInput.cs @@ -9,7 +9,7 @@ using BizHawk.Common.CollectionExtensions; using Vortice.DirectInput; -using static BizHawk.Common.Win32Imports; +using static BizHawk.Common.RawInputImports; using DInputKey = Vortice.DirectInput.Key; @@ -86,7 +86,7 @@ namespace BizHawk.Bizware.Input } } - /*private*/ internal static DInputKey MapToRealKeyViaScanCode(DInputKey key) + private static DInputKey MapToRealKeyViaScanCode(DInputKey key) { const uint MAPVK_VSC_TO_VK_EX = 0x03; // DInputKey is a scancode with bit 7 indicating an E0 prefix @@ -109,8 +109,7 @@ namespace BizHawk.Bizware.Input return VKeyToDKeyMap.GetValueOrDefault(virtualKey, DInputKey.Unknown); } - // DInputKey is just a scancode so it's used with RawKeyInput - /*private*/ internal static readonly IReadOnlyDictionary KeyEnumMap = new Dictionary + private static readonly IReadOnlyDictionary KeyEnumMap = new Dictionary { [DInputKey.D0] = DistinctKey.D0, [DInputKey.D1] = DistinctKey.D1, diff --git a/src/BizHawk.Bizware.Input/KeyInput/RawKeyInput.cs b/src/BizHawk.Bizware.Input/KeyInput/RawKeyInput.cs index 886eaa1174..821028ebb2 100644 --- a/src/BizHawk.Bizware.Input/KeyInput/RawKeyInput.cs +++ b/src/BizHawk.Bizware.Input/KeyInput/RawKeyInput.cs @@ -6,12 +6,11 @@ using System.Runtime.InteropServices; using BizHawk.Client.Common; using BizHawk.Common; +using BizHawk.Common.CollectionExtensions; using static BizHawk.Common.RawInputImports; using static BizHawk.Common.WmImports; -using RawKey = Vortice.DirectInput.Key; - namespace BizHawk.Bizware.Input { /// @@ -94,7 +93,6 @@ namespace BizHawk.Bizware.Input lock (rawKeyInput.LockObj) { - // TODO: Make a separate enum map for RAWINPUT / VKeys and don't rely on DKeyInput's maps var rawKey = (RawKey)(input->data.keyboard.MakeCode | ((input->data.keyboard.Flags & RAWKEYBOARD.RI_KEY.E0) != 0 ? 0x80 : 0)); @@ -102,17 +100,17 @@ namespace BizHawk.Bizware.Input // keyboards would send scancode 0x1D with an E1 prefix, followed by 0x45 (which is NumLock!) // this "NumLock" press will set the VKey to 255 (invalid VKey), so we can use that to know if this is actually a Pause press // (note that DIK_PAUSE is just 0x45 with an E0 prefix, although this is likely just a conversion DirectInput does internally) - if (rawKey == RawKey.NumberLock && input->data.keyboard.VKey == 0xFF) + if (rawKey == RawKey.NUMLOCK && input->data.keyboard.VKey == VirtualKey.VK_NONE) { - rawKey = RawKey.Pause; + rawKey = RawKey.PAUSE; } if (rawKeyInput.HandleAltKbLayouts) { - rawKey = DKeyInput.MapToRealKeyViaScanCode(rawKey); + rawKey = MapToRealKeyViaScanCode(rawKey); } - if (DKeyInput.KeyEnumMap.TryGetValue(rawKey, out var key) && key != DistinctKey.Unknown) + if (KeyEnumMap.TryGetValue(rawKey, out var key)) { rawKeyInput.KeyEvents.Add(new(key, (input->data.keyboard.Flags & RAWKEYBOARD.RI_KEY.BREAK) == RAWKEYBOARD.RI_KEY.MAKE)); } @@ -210,5 +208,325 @@ namespace BizHawk.Bizware.Input return ret; } } + + private static RawKey MapToRealKeyViaScanCode(RawKey key) + { + // Numpad Enter just gets mapped to the virtual Enter key + // Pause is special as it uses 0xE11D technically + if (key is RawKey.NUMPADENTER or RawKey.PAUSE) + { + return key; + } + + var scanCode = (uint)key; + if ((scanCode & 0x80) != 0) + { + scanCode &= 0x7F; + scanCode |= 0xE000; + } + + const uint MAPVK_VSC_TO_VK_EX = 0x03; + var virtualKey = (VirtualKey)MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX); + return VKeyToRawKeyMap.GetValueOrDefault(virtualKey); + } + + private static readonly IReadOnlyDictionary KeyEnumMap = new Dictionary + { + [RawKey.ESCAPE] = DistinctKey.Escape, + [RawKey._1] = DistinctKey.D1, + [RawKey._2] = DistinctKey.D2, + [RawKey._3] = DistinctKey.D3, + [RawKey._4] = DistinctKey.D4, + [RawKey._5] = DistinctKey.D5, + [RawKey._6] = DistinctKey.D6, + [RawKey._7] = DistinctKey.D7, + [RawKey._8] = DistinctKey.D8, + [RawKey._9] = DistinctKey.D9, + [RawKey._0] = DistinctKey.D0, + [RawKey.MINUS] = DistinctKey.OemMinus, + [RawKey.EQUALS] = DistinctKey.OemPlus, + [RawKey.BACKSPACE] = DistinctKey.Back, + [RawKey.TAB] = DistinctKey.Tab, + [RawKey.Q] = DistinctKey.Q, + [RawKey.W] = DistinctKey.W, + [RawKey.E] = DistinctKey.E, + [RawKey.R] = DistinctKey.R, + [RawKey.T] = DistinctKey.T, + [RawKey.Y] = DistinctKey.Y, + [RawKey.U] = DistinctKey.U, + [RawKey.I] = DistinctKey.I, + [RawKey.O] = DistinctKey.O, + [RawKey.P] = DistinctKey.P, + [RawKey.LEFTBRACKET] = DistinctKey.OemOpenBrackets, + [RawKey.RIGHTBRACKET] = DistinctKey.OemCloseBrackets, + [RawKey.ENTER] = DistinctKey.Enter, + [RawKey.LEFTCONTROL] = DistinctKey.LeftCtrl, + [RawKey.A] = DistinctKey.A, + [RawKey.S] = DistinctKey.S, + [RawKey.D] = DistinctKey.D, + [RawKey.F] = DistinctKey.F, + [RawKey.G] = DistinctKey.G, + [RawKey.H] = DistinctKey.H, + [RawKey.J] = DistinctKey.J, + [RawKey.K] = DistinctKey.K, + [RawKey.L] = DistinctKey.L, + [RawKey.SEMICOLON] = DistinctKey.OemSemicolon, + [RawKey.APOSTROPHE] = DistinctKey.OemQuotes, + [RawKey.GRAVE] = DistinctKey.OemTilde, + [RawKey.LEFTSHIFT] = DistinctKey.LeftShift, + [RawKey.BACKSLASH] = DistinctKey.OemPipe, + [RawKey.Z] = DistinctKey.Z, + [RawKey.X] = DistinctKey.X, + [RawKey.C] = DistinctKey.C, + [RawKey.V] = DistinctKey.V, + [RawKey.B] = DistinctKey.B, + [RawKey.N] = DistinctKey.N, + [RawKey.M] = DistinctKey.M, + [RawKey.COMMA] = DistinctKey.OemComma, + [RawKey.PERIOD] = DistinctKey.OemPeriod, + [RawKey.SLASH] = DistinctKey.OemQuestion, + [RawKey.RIGHTSHIFT] = DistinctKey.RightShift, + [RawKey.MULTIPLY] = DistinctKey.Multiply, + [RawKey.LEFTALT] = DistinctKey.LeftAlt, + [RawKey.SPACEBAR] = DistinctKey.Space, + [RawKey.CAPSLOCK] = DistinctKey.CapsLock, + [RawKey.F1] = DistinctKey.F1, + [RawKey.F2] = DistinctKey.F2, + [RawKey.F3] = DistinctKey.F3, + [RawKey.F4] = DistinctKey.F4, + [RawKey.F5] = DistinctKey.F5, + [RawKey.F6] = DistinctKey.F6, + [RawKey.F7] = DistinctKey.F7, + [RawKey.F8] = DistinctKey.F8, + [RawKey.F9] = DistinctKey.F9, + [RawKey.F10] = DistinctKey.F10, + [RawKey.NUMLOCK] = DistinctKey.NumLock, + [RawKey.SCROLLLOCK] = DistinctKey.Scroll, + [RawKey.NUMPAD7] = DistinctKey.NumPad7, + [RawKey.NUMPAD8] = DistinctKey.NumPad8, + [RawKey.NUMPAD9] = DistinctKey.NumPad9, + [RawKey.SUBSTRACT] = DistinctKey.Subtract, + [RawKey.NUMPAD4] = DistinctKey.NumPad4, + [RawKey.NUMPAD5] = DistinctKey.NumPad5, + [RawKey.NUMPAD6] = DistinctKey.NumPad6, + [RawKey.ADD] = DistinctKey.Add, + [RawKey.NUMPAD1] = DistinctKey.NumPad1, + [RawKey.NUMPAD2] = DistinctKey.NumPad2, + [RawKey.NUMPAD3] = DistinctKey.NumPad3, + [RawKey.NUMPAD0] = DistinctKey.NumPad0, + [RawKey.DECIMAL] = DistinctKey.Decimal, + [RawKey.EUROPE2] = DistinctKey.Oem102, + [RawKey.F11] = DistinctKey.F11, + [RawKey.F12] = DistinctKey.F12, + [RawKey.NUMPADEQUALS] = DistinctKey.OemPlus, + [RawKey.INTL6] = DistinctKey.Separator, + [RawKey.F13] = DistinctKey.F13, + [RawKey.F14] = DistinctKey.F14, + [RawKey.F15] = DistinctKey.F15, + [RawKey.F16] = DistinctKey.F16, + [RawKey.F17] = DistinctKey.F17, + [RawKey.F18] = DistinctKey.F18, + [RawKey.F19] = DistinctKey.F19, + [RawKey.F20] = DistinctKey.F20, + [RawKey.F21] = DistinctKey.F21, + [RawKey.F22] = DistinctKey.F22, + [RawKey.F23] = DistinctKey.F23, + [RawKey.INTL2] = DistinctKey.HanjaMode, + [RawKey.INTL1] = DistinctKey.HangulMode, + [RawKey.F24] = DistinctKey.F24, + [RawKey.LANG4] = DistinctKey.DbeHiragana, + [RawKey.LANG3] = DistinctKey.DbeKatakana, + [RawKey.SEPARATOR] = DistinctKey.Separator, + [RawKey.PREVTRACK] = DistinctKey.MediaPreviousTrack, + [RawKey.NEXTTRACK] = DistinctKey.MediaNextTrack, + [RawKey.NUMPADENTER] = DistinctKey.NumPadEnter, + [RawKey.RIGHTCONTROL] = DistinctKey.RightCtrl, + [RawKey.MUTE] = DistinctKey.VolumeMute, + [RawKey.CALCULATOR] = DistinctKey.LaunchApplication2, + [RawKey.PLAYPAUSE] = DistinctKey.MediaPlayPause, + [RawKey.STOP] = DistinctKey.MediaStop, + [RawKey.VOLUMEDOWN] = DistinctKey.VolumeDown, + [RawKey.VOLUMEUP] = DistinctKey.VolumeUp, + [RawKey.BROWSERHOME] = DistinctKey.BrowserHome, + [RawKey.DIVIDE] = DistinctKey.Divide, + [RawKey.PRINTSCREEN] = DistinctKey.PrintScreen, + [RawKey.RIGHTALT] = DistinctKey.RightAlt, + [RawKey.PAUSE] = DistinctKey.Pause, + [RawKey.HOME] = DistinctKey.Home, + [RawKey.UP] = DistinctKey.Up, + [RawKey.PAGEUP] = DistinctKey.PageUp, + [RawKey.LEFT] = DistinctKey.Left, + [RawKey.RIGHT] = DistinctKey.Right, + [RawKey.END] = DistinctKey.End, + [RawKey.DOWN] = DistinctKey.Down, + [RawKey.PAGEDOWN] = DistinctKey.PageDown, + [RawKey.INSERT] = DistinctKey.Insert, + [RawKey.DELETE] = DistinctKey.Delete, + [RawKey.LEFTGUI] = DistinctKey.LWin, + [RawKey.RIGHTGUI] = DistinctKey.RWin, + [RawKey.APPS] = DistinctKey.Apps, + [RawKey.SLEEP] = DistinctKey.Sleep, + [RawKey.WAKE] = DistinctKey.Sleep, + [RawKey.BROWSERSEARCH] = DistinctKey.BrowserSearch, + [RawKey.BROWSERFAVORITES] = DistinctKey.BrowserFavorites, + [RawKey.BROWSERREFRESH] = DistinctKey.BrowserRefresh, + [RawKey.BROWSERSTOP] = DistinctKey.BrowserStop, + [RawKey.BROWSERFORWARD] = DistinctKey.BrowserForward, + [RawKey.BROWSERBACK] = DistinctKey.BrowserBack, + [RawKey.MYCOMPUTER] = DistinctKey.LaunchApplication1, + [RawKey.MAIL] = DistinctKey.LaunchMail, + [RawKey.MEDIASELECT] = DistinctKey.SelectMedia, + }; + + private static readonly IReadOnlyDictionary VKeyToRawKeyMap = new Dictionary + { + [VirtualKey.VK_BACK] = RawKey.BACKSPACE, + [VirtualKey.VK_TAB] = RawKey.TAB, + [VirtualKey.VK_CLEAR] = RawKey.NUMLOCK, + [VirtualKey.VK_RETURN] = RawKey.ENTER, + [VirtualKey.VK_PAUSE] = RawKey.PAUSE, + [VirtualKey.VK_CAPITAL] = RawKey.CAPSLOCK, + [VirtualKey.VK_KANA] = RawKey.INTL2, + [VirtualKey.VK_ESCAPE] = RawKey.ESCAPE, + [VirtualKey.VK_SPACE] = RawKey.SPACEBAR, + [VirtualKey.VK_PRIOR] = RawKey.PAGEUP, + [VirtualKey.VK_NEXT] = RawKey.PAGEDOWN, + [VirtualKey.VK_END] = RawKey.END, + [VirtualKey.VK_HOME] = RawKey.HOME, + [VirtualKey.VK_LEFT] = RawKey.LEFT, + [VirtualKey.VK_UP] = RawKey.UP, + [VirtualKey.VK_RIGHT] = RawKey.RIGHT, + [VirtualKey.VK_DOWN] = RawKey.DOWN, + [VirtualKey.VK_PRINT] = RawKey.PRINTSCREEN, + [VirtualKey.VK_SNAPSHOT] = RawKey.PRINTSCREEN, + [VirtualKey.VK_INSERT] = RawKey.INSERT, + [VirtualKey.VK_DELETE] = RawKey.DELETE, + [VirtualKey.VK_0] = RawKey._0, + [VirtualKey.VK_1] = RawKey._1, + [VirtualKey.VK_2] = RawKey._2, + [VirtualKey.VK_3] = RawKey._3, + [VirtualKey.VK_4] = RawKey._4, + [VirtualKey.VK_5] = RawKey._5, + [VirtualKey.VK_6] = RawKey._6, + [VirtualKey.VK_7] = RawKey._7, + [VirtualKey.VK_8] = RawKey._8, + [VirtualKey.VK_9] = RawKey._9, + [VirtualKey.VK_A] = RawKey.A, + [VirtualKey.VK_B] = RawKey.B, + [VirtualKey.VK_C] = RawKey.C, + [VirtualKey.VK_D] = RawKey.D, + [VirtualKey.VK_E] = RawKey.E, + [VirtualKey.VK_F] = RawKey.F, + [VirtualKey.VK_G] = RawKey.G, + [VirtualKey.VK_H] = RawKey.H, + [VirtualKey.VK_I] = RawKey.I, + [VirtualKey.VK_J] = RawKey.J, + [VirtualKey.VK_K] = RawKey.K, + [VirtualKey.VK_L] = RawKey.L, + [VirtualKey.VK_M] = RawKey.M, + [VirtualKey.VK_N] = RawKey.N, + [VirtualKey.VK_O] = RawKey.O, + [VirtualKey.VK_P] = RawKey.P, + [VirtualKey.VK_Q] = RawKey.Q, + [VirtualKey.VK_R] = RawKey.R, + [VirtualKey.VK_S] = RawKey.S, + [VirtualKey.VK_T] = RawKey.T, + [VirtualKey.VK_U] = RawKey.U, + [VirtualKey.VK_V] = RawKey.V, + [VirtualKey.VK_W] = RawKey.W, + [VirtualKey.VK_X] = RawKey.X, + [VirtualKey.VK_Y] = RawKey.Y, + [VirtualKey.VK_Z] = RawKey.Z, + [VirtualKey.VK_LWIN] = RawKey.LEFTGUI, + [VirtualKey.VK_RWIN] = RawKey.RIGHTGUI, + [VirtualKey.VK_APPS] = RawKey.APPS, + [VirtualKey.VK_SLEEP] = RawKey.SLEEP, + [VirtualKey.VK_NUMPAD0] = RawKey.NUMPAD0, + [VirtualKey.VK_NUMPAD1] = RawKey.NUMPAD1, + [VirtualKey.VK_NUMPAD2] = RawKey.NUMPAD2, + [VirtualKey.VK_NUMPAD3] = RawKey.NUMPAD3, + [VirtualKey.VK_NUMPAD4] = RawKey.NUMPAD4, + [VirtualKey.VK_NUMPAD5] = RawKey.NUMPAD5, + [VirtualKey.VK_NUMPAD6] = RawKey.NUMPAD6, + [VirtualKey.VK_NUMPAD7] = RawKey.NUMPAD7, + [VirtualKey.VK_NUMPAD8] = RawKey.NUMPAD8, + [VirtualKey.VK_NUMPAD9] = RawKey.NUMPAD9, + [VirtualKey.VK_MULTIPLY] = RawKey.MULTIPLY, + [VirtualKey.VK_ADD] = RawKey.ADD, + [VirtualKey.VK_SEPARATOR] = RawKey.SEPARATOR, + [VirtualKey.VK_SUBTRACT] = RawKey.SUBSTRACT, + [VirtualKey.VK_DECIMAL] = RawKey.DECIMAL, + [VirtualKey.VK_DIVIDE] = RawKey.DIVIDE, + [VirtualKey.VK_F1] = RawKey.F1, + [VirtualKey.VK_F2] = RawKey.F2, + [VirtualKey.VK_F3] = RawKey.F3, + [VirtualKey.VK_F4] = RawKey.F4, + [VirtualKey.VK_F5] = RawKey.F5, + [VirtualKey.VK_F6] = RawKey.F6, + [VirtualKey.VK_F7] = RawKey.F7, + [VirtualKey.VK_F8] = RawKey.F8, + [VirtualKey.VK_F9] = RawKey.F9, + [VirtualKey.VK_F10] = RawKey.F10, + [VirtualKey.VK_F11] = RawKey.F11, + [VirtualKey.VK_F12] = RawKey.F12, + [VirtualKey.VK_F13] = RawKey.F13, + [VirtualKey.VK_F14] = RawKey.F14, + [VirtualKey.VK_F15] = RawKey.F15, + [VirtualKey.VK_F16] = RawKey.F16, + [VirtualKey.VK_F17] = RawKey.F17, + [VirtualKey.VK_F18] = RawKey.F18, + [VirtualKey.VK_F19] = RawKey.F19, + [VirtualKey.VK_F20] = RawKey.F20, + [VirtualKey.VK_F21] = RawKey.F21, + [VirtualKey.VK_F22] = RawKey.F22, + [VirtualKey.VK_F23] = RawKey.F23, + [VirtualKey.VK_F24] = RawKey.F24, + [VirtualKey.VK_NUMLOCK] = RawKey.NUMLOCK, + [VirtualKey.VK_SCROLL] = RawKey.SCROLLLOCK, + [VirtualKey.VK_OEM_FJ_JISHO] = RawKey.NUMPADEQUALS, + [VirtualKey.VK_LSHIFT] = RawKey.LEFTSHIFT, + [VirtualKey.VK_RSHIFT] = RawKey.RIGHTSHIFT, + [VirtualKey.VK_LCONTROL] = RawKey.LEFTCONTROL, + [VirtualKey.VK_RCONTROL] = RawKey.RIGHTCONTROL, + [VirtualKey.VK_LMENU] = RawKey.LEFTGUI, + [VirtualKey.VK_RMENU] = RawKey.RIGHTGUI, + [VirtualKey.VK_BROWSER_BACK] = RawKey.BROWSERBACK, + [VirtualKey.VK_BROWSER_FORWARD] = RawKey.BROWSERFORWARD, + [VirtualKey.VK_BROWSER_REFRESH] = RawKey.BROWSERREFRESH, + [VirtualKey.VK_BROWSER_STOP] = RawKey.BROWSERSTOP, + [VirtualKey.VK_BROWSER_SEARCH] = RawKey.BROWSERSEARCH, + [VirtualKey.VK_BROWSER_FAVORITES] = RawKey.BROWSERFAVORITES, + [VirtualKey.VK_BROWSER_HOME] = RawKey.BROWSERHOME, + [VirtualKey.VK_VOLUME_MUTE] = RawKey.MUTE, + [VirtualKey.VK_VOLUME_DOWN] = RawKey.VOLUMEDOWN, + [VirtualKey.VK_VOLUME_UP] = RawKey.VOLUMEUP, + [VirtualKey.VK_MEDIA_NEXT_TRACK] = RawKey.NEXTTRACK, + [VirtualKey.VK_MEDIA_PREV_TRACK] = RawKey.PREVTRACK, + [VirtualKey.VK_MEDIA_STOP] = RawKey.STOP, + [VirtualKey.VK_MEDIA_PLAY_PAUSE] = RawKey.PLAYPAUSE, + [VirtualKey.VK_LAUNCH_MAIL] = RawKey.MAIL, + [VirtualKey.VK_LAUNCH_MEDIA_SELECT] = RawKey.MEDIASELECT, + [VirtualKey.VK_LAUNCH_APP1] = RawKey.MYCOMPUTER, + [VirtualKey.VK_LAUNCH_APP2] = RawKey.CALCULATOR, + [VirtualKey.VK_OEM_1] = RawKey.SEMICOLON, + [VirtualKey.VK_OEM_PLUS] = RawKey.EQUALS, + [VirtualKey.VK_OEM_COMMA] = RawKey.COMMA, + [VirtualKey.VK_OEM_MINUS] = RawKey.MINUS, + [VirtualKey.VK_OEM_PERIOD] = RawKey.PERIOD, + [VirtualKey.VK_OEM_2] = RawKey.SLASH, + [VirtualKey.VK_OEM_3] = RawKey.GRAVE, + [VirtualKey.VK_ABNT_C1] = RawKey.BACKSLASH, + [VirtualKey.VK_ABNT_C2] = RawKey.SEPARATOR, + [VirtualKey.VK_OEM_4] = RawKey.LEFTBRACKET, + [VirtualKey.VK_OEM_5] = RawKey.BACKSLASH, + [VirtualKey.VK_OEM_6] = RawKey.RIGHTBRACKET, + [VirtualKey.VK_OEM_7] = RawKey.APOSTROPHE, + [VirtualKey.VK_OEM_8] = RawKey.RIGHTCONTROL, + [VirtualKey.VK_OEM_102] = RawKey.EUROPE2, + [VirtualKey.VK_OEM_ATTN] = RawKey.CAPSLOCK, + [VirtualKey.VK_OEM_FINISH] = RawKey.RIGHTCONTROL, + [VirtualKey.VK_OEM_COPY] = RawKey.LEFTALT, + [VirtualKey.VK_OEM_AUTO] = RawKey.GRAVE, + }; } } diff --git a/src/BizHawk.Bizware.Input/OSTailoredKeyInputAdapter.cs b/src/BizHawk.Bizware.Input/OSTailoredKeyInputAdapter.cs index 1714046d0f..7e3ca364e3 100644 --- a/src/BizHawk.Bizware.Input/OSTailoredKeyInputAdapter.cs +++ b/src/BizHawk.Bizware.Input/OSTailoredKeyInputAdapter.cs @@ -12,7 +12,7 @@ namespace BizHawk.Bizware.Input /// Abstract class which only handles keyboard input /// Uses OS specific functionality, as there is no good cross platform way to do this /// (Mostly as all the available cross-platform options require a focused window, arg!) - /// TODO: Doesn't work for Wayland yet (well, XWayland probably works fine? Probably want libinput support regardless) + /// TODO: Doesn't work for Wayland yet (must use XWayland, which Wayland users need to use anyways for BizHawk) /// public abstract class OSTailoredKeyInputAdapter : IHostInputAdapter { diff --git a/src/BizHawk.Common/Win32/RawInputImports.cs b/src/BizHawk.Common/Win32/RawInputImports.cs index e1cd04e6e4..8377b3f086 100644 --- a/src/BizHawk.Common/Win32/RawInputImports.cs +++ b/src/BizHawk.Common/Win32/RawInputImports.cs @@ -8,6 +8,358 @@ namespace BizHawk.Common { public static class RawInputImports { + /// + /// This enum generally assumes a QWERTY layout (and goes off PS/2 Set 1 scancodes, i.e. what RAWINPUT uses) + /// Bit7 will indicate that the input has an E0 prefix + /// (This also somewhat mimics DirectInput's DIK_ enum) + /// + public enum RawKey : byte + { + ESCAPE = 0x01, + _1 = 0x02, + _2 = 0x03, + _3 = 0x04, + _4 = 0x05, + _5 = 0x06, + _6 = 0x07, + _7 = 0x08, + _8 = 0x09, + _9 = 0x0A, + _0 = 0x0B, + MINUS = 0x0C, + EQUALS = 0x0D, + BACKSPACE = 0x0E, + TAB = 0x0F, + Q = 0x10, + W = 0x11, + E = 0x12, + R = 0x13, + T = 0x14, + Y = 0x15, + U = 0x16, + I = 0x17, + O = 0x18, + P = 0x19, + LEFTBRACKET = 0x1A, + RIGHTBRACKET = 0x1B, + ENTER = 0x1C, + LEFTCONTROL = 0x1D, + A = 0x1E, + S = 0x1F, + D = 0x20, + F = 0x21, + G = 0x22, + H = 0x23, + J = 0x24, + K = 0x25, + L = 0x26, + SEMICOLON = 0x27, + APOSTROPHE = 0x28, + GRAVE = 0x29, + LEFTSHIFT = 0x2A, + BACKSLASH = 0x2B, // also EUROPE1 + Z = 0x2C, + X = 0x2D, + C = 0x2E, + V = 0x2F, + B = 0x30, + N = 0x31, + M = 0x32, + COMMA = 0x33, + PERIOD = 0x34, + SLASH = 0x35, + RIGHTSHIFT = 0x36, + MULTIPLY = 0x37, + LEFTALT = 0x38, + SPACEBAR = 0x39, + CAPSLOCK = 0x3A, + F1 = 0x3B, + F2 = 0x3C, + F3 = 0x3D, + F4 = 0x3E, + F5 = 0x3F, + F6 = 0x40, + F7 = 0x41, + F8 = 0x42, + F9 = 0x43, + F10 = 0x44, + NUMLOCK = 0x45, + SCROLLLOCK = 0x46, + NUMPAD7 = 0x47, + NUMPAD8 = 0x48, + NUMPAD9 = 0x49, + SUBSTRACT = 0x4A, + NUMPAD4 = 0x4B, + NUMPAD5 = 0x4C, + NUMPAD6 = 0x4D, + ADD = 0x4E, + NUMPAD1 = 0x4F, + NUMPAD2 = 0x50, + NUMPAD3 = 0x51, + NUMPAD0 = 0x52, + DECIMAL = 0x53, + EUROPE2 = 0x56, + F11 = 0x57, + F12 = 0x58, + NUMPADEQUALS = 0x59, + INTL6 = 0x5C, + F13 = 0x64, + F14 = 0x65, + F15 = 0x66, + F16 = 0x67, + F17 = 0x68, + F18 = 0x69, + F19 = 0x6A, + F20 = 0x6B, + F21 = 0x6C, + F22 = 0x6D, + F23 = 0x6E, + INTL2 = 0x70, + INTL1 = 0x73, + F24 = 0x76, // also LANG5 + LANG4 = 0x77, + LANG3 = 0x78, + INTL4 = 0x79, + INTL5 = 0x7B, + INTL3 = 0x7D, + SEPARATOR = 0x7E, + PREVTRACK = 0x90, + NEXTTRACK = 0x97, + NUMPADENTER = 0x9C, + RIGHTCONTROL = 0x9D, + MUTE = 0xA0, + CALCULATOR = 0xA1, + PLAYPAUSE = 0xA2, + STOP = 0xA4, + VOLUMEDOWN = 0xAE, + VOLUMEUP = 0xB0, + BROWSERHOME = 0xB2, + DIVIDE = 0xB5, + PRINTSCREEN = 0xB7, + RIGHTALT = 0xB8, + PAUSE = 0xC5, + HOME = 0xC7, + UP = 0xC8, + PAGEUP = 0xC9, + LEFT = 0xCB, + RIGHT = 0xCD, + END = 0xCF, + DOWN = 0xD0, + PAGEDOWN = 0xD1, + INSERT = 0xD2, + DELETE = 0xD3, + LEFTGUI = 0xDB, + RIGHTGUI = 0xDC, + APPS = 0xDD, + POWER = 0xDE, + SLEEP = 0xDF, + WAKE = 0xE3, + BROWSERSEARCH = 0xE5, + BROWSERFAVORITES = 0xE6, + BROWSERREFRESH = 0xE7, + BROWSERSTOP = 0xE8, + BROWSERFORWARD = 0xE9, + BROWSERBACK = 0xEA, + MYCOMPUTER = 0xEB, + MAIL = 0xEC, + MEDIASELECT = 0xED, + } + + public enum VirtualKey : ushort + { + VK_BACK = 0x08, + VK_TAB = 0x09, + VK_CLEAR = 0x0C, + VK_RETURN = 0x0D, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_PAUSE = 0x13, + VK_CAPITAL = 0x14, + VK_KANA = 0x15, + VK_IME_ON = 0x16, + VK_JUNJA = 0x17, + VK_FINAL = 0x18, + VK_KANJI = 0x19, + VK_IME_OFF = 0x1A, + VK_ESCAPE = 0x1B, + VK_CONVERT = 0x1C, + VK_NONCONVERT = 0x1D, + VK_ACCEPT = 0x1E, + VK_MODECHANGE = 0x1F, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_PRINT = 0x2A, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_INSERT = 0x2D, + VK_DELETE = 0x2E, + VK_HELP = 0x2F, + VK_0 = 0x30, + VK_1 = 0x31, + VK_2 = 0x32, + VK_3 = 0x33, + VK_4 = 0x34, + VK_5 = 0x35, + VK_6 = 0x36, + VK_7 = 0x37, + VK_8 = 0x38, + VK_9 = 0x39, + VK_A = 0x41, + VK_B = 0x42, + VK_C = 0x43, + VK_D = 0x44, + VK_E = 0x45, + VK_F = 0x46, + VK_G = 0x47, + VK_H = 0x48, + VK_I = 0x49, + VK_J = 0x4A, + VK_K = 0x4B, + VK_L = 0x4C, + VK_M = 0x4D, + VK_N = 0x4E, + VK_O = 0x4F, + VK_P = 0x50, + VK_Q = 0x51, + VK_R = 0x52, + VK_S = 0x53, + VK_T = 0x54, + VK_U = 0x55, + VK_V = 0x56, + VK_W = 0x57, + VK_X = 0x58, + VK_Y = 0x59, + VK_Z = 0x5A, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_SLEEP = 0x5F, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, + VK_OEM_FJ_JISHO = 0x92, + VK_OEM_FJ_MASSHOU = 0x93, + VK_OEM_FJ_TOUROKU = 0x94, + VK_OEM_FJ_LOYA = 0x95, + VK_OEM_FJ_ROYA = 0x96, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5, + VK_BROWSER_BACK = 0xA6, + VK_BROWSER_FORWARD = 0xA7, + VK_BROWSER_REFRESH = 0xA8, + VK_BROWSER_STOP = 0xA9, + VK_BROWSER_SEARCH = 0xAA, + VK_BROWSER_FAVORITES = 0xAB, + VK_BROWSER_HOME = 0xAC, + VK_VOLUME_MUTE = 0xAD, + VK_VOLUME_DOWN = 0xAE, + VK_VOLUME_UP = 0xAF, + VK_MEDIA_NEXT_TRACK = 0xB0, + VK_MEDIA_PREV_TRACK = 0xB1, + VK_MEDIA_STOP = 0xB2, + VK_MEDIA_PLAY_PAUSE = 0xB3, + VK_LAUNCH_MAIL = 0xB4, + VK_LAUNCH_MEDIA_SELECT = 0xB5, + VK_LAUNCH_APP1 = 0xB6, + VK_LAUNCH_APP2 = 0xB7, + VK_OEM_1 = 0xBA, + VK_OEM_PLUS = 0xBB, + VK_OEM_COMMA = 0xBC, + VK_OEM_MINUS = 0xBD, + VK_OEM_PERIOD = 0xBE, + VK_OEM_2 = 0xBF, + VK_OEM_3 = 0xC0, + VK_ABNT_C1 = 0xC1, + VK_ABNT_C2 = 0xC2, + VK_OEM_4 = 0xDB, + VK_OEM_5 = 0xDC, + VK_OEM_6 = 0xDD, + VK_OEM_7 = 0xDE, + VK_OEM_8 = 0xDF, + VK_OEM_AX = 0xE1, + VK_OEM_102 = 0xE2, + VK_ICO_HELP = 0xE3, + VK_ICO_00 = 0xE4, + VK_PROCESSKEY = 0xE5, + VK_ICO_CLEAR = 0xE6, + VK_PACKET = 0xE7, + VK_OEM_RESET = 0xE9, + VK_OEM_JUMP = 0xEA, + VK_OEM_PA1 = 0xEB, + VK_OEM_PA2 = 0xEC, + VK_OEM_PA3 = 0xED, + VK_OEM_WSCTRL = 0xEE, + VK_OEM_CUSEL = 0xEF, + VK_OEM_ATTN = 0xF0, + VK_OEM_FINISH = 0xF1, + VK_OEM_COPY = 0xF2, + VK_OEM_AUTO = 0xF3, + VK_OEM_ENLW = 0xF4, + VK_OEM_BACKTAB = 0xF5, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE, + VK_NONE = 0xFF, + } + [StructLayout(LayoutKind.Sequential)] public struct RAWINPUTDEVICE { @@ -90,7 +442,7 @@ namespace BizHawk.Common public ushort MakeCode; public RI_KEY Flags; public ushort Reserved; - public ushort VKey; + public VirtualKey VKey; public uint Message; public uint ExtraInformation; @@ -146,5 +498,8 @@ namespace BizHawk.Common [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, int cbSize); + + [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] + public static extern uint MapVirtualKeyW(uint uCode, uint uMapType); } } diff --git a/src/BizHawk.Common/Win32/Win32Imports.cs b/src/BizHawk.Common/Win32/Win32Imports.cs index 7068d40143..8a5c146c37 100644 --- a/src/BizHawk.Common/Win32/Win32Imports.cs +++ b/src/BizHawk.Common/Win32/Win32Imports.cs @@ -57,9 +57,6 @@ namespace BizHawk.Common [DllImport("kernel32.dll", ExactSpelling = true)] public static extern uint GetLastError(); - [DllImport("user32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] - public static extern uint MapVirtualKeyW(uint uCode, uint uMapType); - [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] public static extern bool PathRelativePathToW([Out] char[] pszPath, [In] string pszFrom, [In] FileAttributes dwAttrFrom, [In] string pszTo, [In] FileAttributes dwAttrTo);