add RAWInput keyboard handler, use it for OSTailoredKeyInputAdapter / SDL2
re-removes hard DirectInput dependency
This commit is contained in:
parent
a320928a6f
commit
5fc37d6aac
|
@ -82,7 +82,8 @@ namespace BizHawk.Bizware.Input
|
||||||
return VKeyToDKeyMap.GetValueOrDefault(virtualKey, DInputKey.Unknown);
|
return VKeyToDKeyMap.GetValueOrDefault(virtualKey, DInputKey.Unknown);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly IReadOnlyDictionary<DInputKey, DistinctKey> KeyEnumMap = new Dictionary<DInputKey, DistinctKey>
|
// DInputKey is just a scancode so it's used with RAWKeyInput
|
||||||
|
/*private*/ internal static readonly IReadOnlyDictionary<DInputKey, DistinctKey> KeyEnumMap = new Dictionary<DInputKey, DistinctKey>
|
||||||
{
|
{
|
||||||
[DInputKey.D0] = DistinctKey.D0,
|
[DInputKey.D0] = DistinctKey.D0,
|
||||||
[DInputKey.D1] = DistinctKey.D1,
|
[DInputKey.D1] = DistinctKey.D1,
|
||||||
|
@ -231,7 +232,7 @@ namespace BizHawk.Bizware.Input
|
||||||
[DInputKey.Unknown] = DistinctKey.Unknown
|
[DInputKey.Unknown] = DistinctKey.Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
private static readonly IReadOnlyDictionary<uint, DInputKey> VKeyToDKeyMap = new Dictionary<uint, DInputKey>
|
/*private*/ internal static readonly IReadOnlyDictionary<uint, DInputKey> VKeyToDKeyMap = new Dictionary<uint, DInputKey>
|
||||||
{
|
{
|
||||||
[0x30] = DInputKey.D0,
|
[0x30] = DInputKey.D0,
|
||||||
[0x31] = DInputKey.D1,
|
[0x31] = DInputKey.D1,
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace BizHawk.Bizware.Input
|
||||||
//break;
|
//break;
|
||||||
throw new NotSupportedException("TODO QUARTZ");
|
throw new NotSupportedException("TODO QUARTZ");
|
||||||
case OSTailoredCode.DistinctOS.Windows:
|
case OSTailoredCode.DistinctOS.Windows:
|
||||||
DKeyInput.Cleanup();
|
RAWKeyInput.Deinitialize();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
@ -54,10 +54,7 @@ namespace BizHawk.Bizware.Input
|
||||||
//break;
|
//break;
|
||||||
throw new NotSupportedException("TODO QUARTZ");
|
throw new NotSupportedException("TODO QUARTZ");
|
||||||
case OSTailoredCode.DistinctOS.Windows:
|
case OSTailoredCode.DistinctOS.Windows:
|
||||||
// TODO: Consider if we want to use RAWINPUT API for keyboards instead
|
RAWKeyInput.Initialize();
|
||||||
// Would remove DInput depenency on Windows (DInput gamepads could be considered optional in this sense)
|
|
||||||
// (also, this would be needed for keyboard support with UWP, which doesn't support DInput)
|
|
||||||
DKeyInput.Initialize(mainFormHandle);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
|
@ -80,7 +77,7 @@ namespace BizHawk.Bizware.Input
|
||||||
{
|
{
|
||||||
OSTailoredCode.DistinctOS.Linux => X11KeyInput.Update(),
|
OSTailoredCode.DistinctOS.Linux => X11KeyInput.Update(),
|
||||||
OSTailoredCode.DistinctOS.macOS => throw new NotSupportedException("TODO QUARTZ"),
|
OSTailoredCode.DistinctOS.macOS => throw new NotSupportedException("TODO QUARTZ"),
|
||||||
OSTailoredCode.DistinctOS.Windows => DKeyInput.Update(_config ?? throw new(nameof(ProcessHostKeyboards) + " called before the global config was passed")),
|
OSTailoredCode.DistinctOS.Windows => RAWKeyInput.Update(_config ?? throw new(nameof(ProcessHostKeyboards) + " called before the global config was passed")),
|
||||||
_ => throw new InvalidOperationException()
|
_ => throw new InvalidOperationException()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
using BizHawk.Client.Common;
|
||||||
|
using BizHawk.Common;
|
||||||
|
using BizHawk.Common.CollectionExtensions;
|
||||||
|
|
||||||
|
using static BizHawk.Common.Win32Imports;
|
||||||
|
|
||||||
|
using RAWKey = Vortice.DirectInput.Key;
|
||||||
|
|
||||||
|
namespace BizHawk.Bizware.Input
|
||||||
|
{
|
||||||
|
internal static class RAWKeyInput
|
||||||
|
{
|
||||||
|
private static volatile bool _isInit;
|
||||||
|
private static IntPtr _rawInputWindowAtom;
|
||||||
|
private static IntPtr _rawInputWindow;
|
||||||
|
private static bool _handleAlternativeKeyboardLayouts;
|
||||||
|
private static List<KeyEvent> _keyEvents = new();
|
||||||
|
|
||||||
|
private static readonly WNDPROC _wndProc = WndProc;
|
||||||
|
private static readonly object _lockObj = new();
|
||||||
|
|
||||||
|
private static unsafe IntPtr WndProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
const uint WM_INPUT = 0x00FF;
|
||||||
|
|
||||||
|
if (uMsg != WM_INPUT)
|
||||||
|
{
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetRawInputData(lParam, RID.INPUT, IntPtr.Zero,
|
||||||
|
out var size, Marshal.SizeOf<RAWINPUTHEADER>()) == -1)
|
||||||
|
{
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't think size should ever be this big, but just in case
|
||||||
|
var buffer = size > 1024
|
||||||
|
? new byte[size]
|
||||||
|
: stackalloc byte[size];
|
||||||
|
|
||||||
|
fixed (byte* p = buffer)
|
||||||
|
{
|
||||||
|
var input = (RAWINPUT*)p;
|
||||||
|
|
||||||
|
if (GetRawInputData(lParam, RID.INPUT, input,
|
||||||
|
ref size, Marshal.SizeOf<RAWINPUTHEADER>()) == -1)
|
||||||
|
{
|
||||||
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input->header.dwType == RAWINPUTHEADER.RIM_TYPE.KEYBOARD && input->data.keyboard.Flags <= RAWKEYBOARD.RIM_KEY.E1)
|
||||||
|
{
|
||||||
|
var rawKey = _handleAlternativeKeyboardLayouts
|
||||||
|
? DKeyInput.VKeyToDKeyMap.GetValueOrDefault(input->data.keyboard.VKey, RAWKey.Unknown)
|
||||||
|
: (RAWKey)(input->data.keyboard.MakeCode |
|
||||||
|
(input->data.keyboard.Flags >= RAWKEYBOARD.RIM_KEY.E0 ? 0x80 : 0));
|
||||||
|
|
||||||
|
if (DKeyInput.KeyEnumMap.TryGetValue(rawKey, out var key) && key != DistinctKey.Unknown)
|
||||||
|
{
|
||||||
|
_keyEvents.Add(new(key, input->data.keyboard.Flags is RAWKEYBOARD.RIM_KEY.MAKE or RAWKEYBOARD.RIM_KEY.E0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefRawInputProc(input, 0, Marshal.SizeOf<RAWINPUTHEADER>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateRawInputWindow()
|
||||||
|
{
|
||||||
|
const int WS_CHILD = 0x40000000;
|
||||||
|
var window = CreateWindowEx(
|
||||||
|
dwExStyle: 0,
|
||||||
|
lpClassName: _rawInputWindowAtom,
|
||||||
|
lpWindowName: "RAWKeyInput",
|
||||||
|
dwStyle: WS_CHILD,
|
||||||
|
X: 0,
|
||||||
|
Y: 0,
|
||||||
|
nWidth: 1,
|
||||||
|
nHeight: 1,
|
||||||
|
hWndParent: HWND_MESSAGE,
|
||||||
|
hMenu: IntPtr.Zero,
|
||||||
|
hInstance: GetModuleHandle(null),
|
||||||
|
lpParam: IntPtr.Zero);
|
||||||
|
|
||||||
|
if (window == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Failed to create RAWINPUT window");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ri = new RAWINPUTDEVICE[1];
|
||||||
|
ri[0].usUsagePage = RAWINPUTDEVICE.HidUsagePage.GENERIC;
|
||||||
|
ri[0].usUsage = RAWINPUTDEVICE.HidUsageId.GENERIC_KEYBOARD;
|
||||||
|
ri[0].dwFlags = RAWINPUTDEVICE.RIDEV.INPUTSINK;
|
||||||
|
ri[0].hwndTarget = window;
|
||||||
|
|
||||||
|
if (!RegisterRawInputDevices(ri, 1, Marshal.SizeOf<RAWINPUTDEVICE>()))
|
||||||
|
{
|
||||||
|
DestroyWindow(window);
|
||||||
|
throw new InvalidOperationException("Failed to register RAWINPUTDEVICE");
|
||||||
|
}
|
||||||
|
|
||||||
|
_rawInputWindow = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
if (OSTailoredCode.IsUnixHost)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("RAWINPUT is Windows only");
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (_lockObj)
|
||||||
|
{
|
||||||
|
Deinitialize();
|
||||||
|
|
||||||
|
if (_rawInputWindowAtom == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
var wc = default(WNDCLASS);
|
||||||
|
wc.lpfnWndProc = _wndProc;
|
||||||
|
wc.hInstance = GetModuleHandle(null);
|
||||||
|
wc.lpszClassName = "RAWKeyInputClass";
|
||||||
|
|
||||||
|
_rawInputWindowAtom = RegisterClass(ref wc);
|
||||||
|
if (_rawInputWindowAtom == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Failed to register RAWINPUT window class");
|
||||||
|
}
|
||||||
|
|
||||||
|
// we can't use a window created on this thread, as Update is called on a different thread
|
||||||
|
// but we can still test window creation
|
||||||
|
CreateRawInputWindow(); // this will throw if window creation or rawinput registering fails
|
||||||
|
DestroyWindow(_rawInputWindow);
|
||||||
|
_rawInputWindow = IntPtr.Zero;
|
||||||
|
|
||||||
|
_isInit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Deinitialize()
|
||||||
|
{
|
||||||
|
lock (_lockObj)
|
||||||
|
{
|
||||||
|
if (_rawInputWindow != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
// Can't use DestroyWindow, that's only allowed in the thread that created the window!
|
||||||
|
const int WM_CLOSE = 0x0010;
|
||||||
|
PostMessage(_rawInputWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
_rawInputWindow = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
_keyEvents.Clear();
|
||||||
|
_isInit = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<KeyEvent> Update(Config config)
|
||||||
|
{
|
||||||
|
lock (_lockObj)
|
||||||
|
{
|
||||||
|
if (!_isInit)
|
||||||
|
{
|
||||||
|
return Enumerable.Empty<KeyEvent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_rawInputWindow == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
CreateRawInputWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleAlternativeKeyboardLayouts = config.HandleAlternateKeyboardLayouts;
|
||||||
|
|
||||||
|
while (PeekMessage(out var msg, _rawInputWindow, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
TranslateMessage(ref msg);
|
||||||
|
DispatchMessage(ref msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = _keyEvents;
|
||||||
|
_keyEvents = new();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ namespace BizHawk.Common
|
||||||
{
|
{
|
||||||
public const int MAX_PATH = 260;
|
public const int MAX_PATH = 260;
|
||||||
public const uint PM_REMOVE = 0x0001U;
|
public const uint PM_REMOVE = 0x0001U;
|
||||||
|
public static readonly IntPtr HWND_MESSAGE = new(-3);
|
||||||
|
|
||||||
public delegate int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData);
|
public delegate int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData);
|
||||||
|
|
||||||
|
@ -98,6 +99,144 @@ namespace BizHawk.Common
|
||||||
public int y;
|
public int y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWINPUTDEVICE
|
||||||
|
{
|
||||||
|
public HidUsagePage usUsagePage;
|
||||||
|
public HidUsageId usUsage;
|
||||||
|
public RIDEV dwFlags;
|
||||||
|
public IntPtr hwndTarget;
|
||||||
|
|
||||||
|
public enum HidUsagePage : ushort
|
||||||
|
{
|
||||||
|
GENERIC = 1,
|
||||||
|
GAME = 5,
|
||||||
|
LED = 8,
|
||||||
|
BUTTON = 9,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum HidUsageId : ushort
|
||||||
|
{
|
||||||
|
GENERIC_POINTER = 1,
|
||||||
|
GENERIC_MOUSE = 2,
|
||||||
|
GENERIC_JOYSTICK = 4,
|
||||||
|
GENERIC_GAMEPAD = 5,
|
||||||
|
GENERIC_KEYBOARD = 6,
|
||||||
|
GENERIC_KEYPAD = 7,
|
||||||
|
GENERIC_MULTI_AXIS_CONTROLLER = 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum RIDEV : int
|
||||||
|
{
|
||||||
|
REMOVE = 0x00000001,
|
||||||
|
EXCLUDE = 0x00000010,
|
||||||
|
PAGEONLY = 0x00000020,
|
||||||
|
NOLEGACY = PAGEONLY | EXCLUDE,
|
||||||
|
INPUTSINK = 0x00000100,
|
||||||
|
CAPTUREMOUSE = 0x00000200,
|
||||||
|
NOHOTKEYS = CAPTUREMOUSE,
|
||||||
|
APPKEYS = 0x00000400,
|
||||||
|
EXINPUTSINK = 0x00001000,
|
||||||
|
DEVNOTIFY = 0x00002000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum RID : uint
|
||||||
|
{
|
||||||
|
HEADER = 0x10000005,
|
||||||
|
INPUT = 0x10000003,
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWINPUTHEADER
|
||||||
|
{
|
||||||
|
public RIM_TYPE dwType;
|
||||||
|
public uint dwSize;
|
||||||
|
public IntPtr hDevice;
|
||||||
|
public IntPtr wParam;
|
||||||
|
|
||||||
|
public enum RIM_TYPE : uint
|
||||||
|
{
|
||||||
|
MOUSE = 0,
|
||||||
|
KEYBOARD = 1,
|
||||||
|
HID = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWMOUSE
|
||||||
|
{
|
||||||
|
public ushort usFlags;
|
||||||
|
public uint ulButtons;
|
||||||
|
public uint ulRawButtons;
|
||||||
|
public int lLastX;
|
||||||
|
public int lLastY;
|
||||||
|
public uint ulExtraInformation;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWKEYBOARD
|
||||||
|
{
|
||||||
|
public ushort MakeCode;
|
||||||
|
public RIM_KEY Flags;
|
||||||
|
public ushort Reserved;
|
||||||
|
public ushort VKey;
|
||||||
|
public uint Message;
|
||||||
|
public uint ExtraInformation;
|
||||||
|
|
||||||
|
public enum RIM_KEY : ushort
|
||||||
|
{
|
||||||
|
MAKE = 0,
|
||||||
|
BREAK = 1,
|
||||||
|
E0 = 2,
|
||||||
|
E1 = 3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWHID
|
||||||
|
{
|
||||||
|
public uint dwSizeHid;
|
||||||
|
public uint dwCount;
|
||||||
|
public byte bRawData;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct RAWINPUTDATA
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public RAWMOUSE mouse;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public RAWKEYBOARD keyboard;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public RAWHID hid;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct RAWINPUT
|
||||||
|
{
|
||||||
|
public RAWINPUTHEADER header;
|
||||||
|
public RAWINPUTDATA data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate IntPtr WNDPROC(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
|
public struct WNDCLASS
|
||||||
|
{
|
||||||
|
public uint style;
|
||||||
|
public WNDPROC lpfnWndProc;
|
||||||
|
public int cbClsExtra;
|
||||||
|
public int cbWndExtra;
|
||||||
|
public IntPtr hInstance;
|
||||||
|
public IntPtr hIcon;
|
||||||
|
public IntPtr hCursor;
|
||||||
|
public IntPtr hbrBackground;
|
||||||
|
public string lpszMenuName;
|
||||||
|
public string lpszClassName;
|
||||||
|
}
|
||||||
|
|
||||||
[Guid("00000002-0000-0000-C000-000000000046")]
|
[Guid("00000002-0000-0000-C000-000000000046")]
|
||||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
public interface IMalloc
|
public interface IMalloc
|
||||||
|
@ -113,9 +252,23 @@ namespace BizHawk.Common
|
||||||
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern uint _control87(uint @new, uint mask);
|
public static extern uint _control87(uint @new, uint mask);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern IntPtr CreateWindowEx(int dwExStyle, IntPtr lpClassName, string lpWindowName,
|
||||||
|
int dwStyle, int X, int Y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
[DllImport("kernel32.dll", EntryPoint = "DeleteFileW", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
|
||||||
public static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
|
public static extern bool DeleteFileW([MarshalAs(UnmanagedType.LPWStr)] string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern unsafe IntPtr DefRawInputProc(RAWINPUT* paRawInput, int nInput, int cbSizeHeader);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern IntPtr DefWindowProc(IntPtr hWnd, uint uMsg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static extern bool DestroyWindow(IntPtr hWnd);
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
public static extern IntPtr DispatchMessage([In] ref MSG lpMsg);
|
public static extern IntPtr DispatchMessage([In] ref MSG lpMsg);
|
||||||
|
|
||||||
|
@ -125,12 +278,21 @@ namespace BizHawk.Common
|
||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
public static extern IntPtr GetActiveWindow();
|
public static extern IntPtr GetActiveWindow();
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||||
|
|
||||||
[DllImport("kernel32", SetLastError = true, EntryPoint = "GetProcAddress")]
|
[DllImport("kernel32", SetLastError = true, EntryPoint = "GetProcAddress")]
|
||||||
public static extern IntPtr GetProcAddressOrdinal(IntPtr hModule, IntPtr procName);
|
public static extern IntPtr GetProcAddressOrdinal(IntPtr hModule, IntPtr procName);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
public static extern IntPtr GetProcessHeap();
|
public static extern IntPtr GetProcessHeap();
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern int GetRawInputData(IntPtr hRawInput, RID uiCommand, IntPtr pData, out int bSize, int cbSizeHeader);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
public static extern unsafe int GetRawInputData(IntPtr hRawInput, RID uiCommand, RAWINPUT* pData, ref int bSize, int cbSizeHeader);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = false)]
|
[DllImport("kernel32.dll", SetLastError = false)]
|
||||||
public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, int dwBytes);
|
public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, int dwBytes);
|
||||||
|
|
||||||
|
@ -157,6 +319,16 @@ namespace BizHawk.Common
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
|
public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern IntPtr PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
|
public static extern IntPtr RegisterClass([In] ref WNDCLASS lpWndClass);
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static extern bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevices, uint uiNumDevices, int cbSize);
|
||||||
|
|
||||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref HDITEM lParam);
|
public static extern IntPtr SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref HDITEM lParam);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue