A game framework written with osu! in mind.
at master 312 lines 10 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Drawing; 6using System.Runtime.InteropServices; 7 8namespace osu.Framework.Platform.Windows.Native 9{ 10 internal static class Input 11 { 12 [DllImport("user32.dll")] 13 public static extern bool RegisterRawInputDevices( 14 [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] 15 RawInputDevice[] pRawInputDevices, 16 int uiNumDevices, 17 int cbSize); 18 19 [DllImport("user32.dll")] 20 public static extern int GetRawInputData(IntPtr hRawInput, RawInputCommand uiCommand, out RawInputData pData, ref int pcbSize, int cbSizeHeader); 21 22 internal static Rectangle VirtualScreenRect => new Rectangle( 23 GetSystemMetrics(SM_XVIRTUALSCREEN), 24 GetSystemMetrics(SM_YVIRTUALSCREEN), 25 GetSystemMetrics(SM_CXVIRTUALSCREEN), 26 GetSystemMetrics(SM_CYVIRTUALSCREEN)); 27 28 internal const int WM_INPUT = 0x00FF; 29 30 [DllImport("user32.dll")] 31 public static extern int GetSystemMetrics(int nIndex); 32 33 internal static Rectangle GetVirtualScreenRect() => new Rectangle( 34 GetSystemMetrics(SM_XVIRTUALSCREEN), 35 GetSystemMetrics(SM_YVIRTUALSCREEN), 36 GetSystemMetrics(SM_CXVIRTUALSCREEN), 37 GetSystemMetrics(SM_CYVIRTUALSCREEN) 38 ); 39 40 public const int SM_XVIRTUALSCREEN = 76; 41 public const int SM_YVIRTUALSCREEN = 77; 42 public const int SM_CXVIRTUALSCREEN = 78; 43 public const int SM_CYVIRTUALSCREEN = 79; 44 } 45 46 /// <summary> 47 /// Value type for raw input. 48 /// </summary> 49 public struct RawInputData 50 { 51 /// <summary>Header for the data.</summary> 52 public RawInputHeader Header; 53 54 /// <summary>Mouse raw input data.</summary> 55 public RawMouse Mouse; 56 57 // This struct is a lot larger but the remaining elements have been omitted until required (Keyboard / HID / Touch). 58 } 59 60 /// <summary> 61 /// Contains information about the state of the mouse. 62 /// </summary> 63 public struct RawMouse 64 { 65 /// <summary> 66 /// The mouse state. 67 /// </summary> 68 public RawMouseFlags Flags; 69 70 /// <summary> 71 /// Flags for the event. 72 /// </summary> 73 public RawMouseButtons ButtonFlags; 74 75 /// <summary> 76 /// If the mouse wheel is moved, this will contain the delta amount. 77 /// </summary> 78 public short ButtonData; 79 80 /// <summary> 81 /// Raw button data. 82 /// </summary> 83 public uint RawButtons; 84 85 /// <summary> 86 /// The motion in the X direction. This is signed relative motion or 87 /// absolute motion, depending on the value of usFlags. 88 /// </summary> 89 public int LastX; 90 91 /// <summary> 92 /// The motion in the Y direction. This is signed relative motion or absolute motion, 93 /// depending on the value of usFlags. 94 /// </summary> 95 public int LastY; 96 97 /// <summary> 98 /// The device-specific additional information for the event. 99 /// </summary> 100 public uint ExtraInformation; 101 } 102 103 /// <summary> 104 /// Enumeration containing the flags for raw mouse data. 105 /// </summary> 106 [Flags] 107 public enum RawMouseFlags : ushort 108 { 109 /// <summary>Relative to the last position.</summary> 110 MoveRelative = 0, 111 112 /// <summary>Absolute positioning.</summary> 113 MoveAbsolute = 1, 114 115 /// <summary>Coordinate data is mapped to a virtual desktop.</summary> 116 VirtualDesktop = 2, 117 118 /// <summary>Attributes for the mouse have changed.</summary> 119 AttributesChanged = 4, 120 121 /// <summary>WM_MOUSEMOVE and WM_INPUT don't coalesce</summary> 122 MoveNoCoalesce = 8, 123 } 124 125 /// <summary> 126 /// Enumeration containing the button data for raw mouse input. 127 /// </summary> 128 public enum RawMouseButtons : ushort 129 { 130 /// <summary>No button.</summary> 131 None = 0, 132 133 /// <summary>Left (button 1) down.</summary> 134 LeftDown = 0x0001, 135 136 /// <summary>Left (button 1) up.</summary> 137 LeftUp = 0x0002, 138 139 /// <summary>Right (button 2) down.</summary> 140 RightDown = 0x0004, 141 142 /// <summary>Right (button 2) up.</summary> 143 RightUp = 0x0008, 144 145 /// <summary>Middle (button 3) down.</summary> 146 MiddleDown = 0x0010, 147 148 /// <summary>Middle (button 3) up.</summary> 149 MiddleUp = 0x0020, 150 151 /// <summary>Button 4 down.</summary> 152 Button4Down = 0x0040, 153 154 /// <summary>Button 4 up.</summary> 155 Button4Up = 0x0080, 156 157 /// <summary>Button 5 down.</summary> 158 Button5Down = 0x0100, 159 160 /// <summary>Button 5 up.</summary> 161 Button5Up = 0x0200, 162 163 /// <summary>Mouse wheel moved.</summary> 164 MouseWheel = 0x0400 165 } 166 167 /// <summary> 168 /// Enumeration contanining the command types to issue. 169 /// </summary> 170 public enum RawInputCommand 171 { 172 /// <summary> 173 /// Get input data. 174 /// </summary> 175 Input = 0x10000003, 176 177 /// <summary> 178 /// Get header data. 179 /// </summary> 180 Header = 0x10000005 181 } 182 183 /// <summary> 184 /// Enumeration containing the type device the raw input is coming from. 185 /// </summary> 186 public enum RawInputType 187 { 188 /// <summary> 189 /// Mouse input. 190 /// </summary> 191 Mouse = 0, 192 193 /// <summary> 194 /// Keyboard input. 195 /// </summary> 196 Keyboard = 1, 197 198 /// <summary> 199 /// Another device that is not the keyboard or the mouse. 200 /// </summary> 201 HID = 2 202 } 203 204 /// <summary> 205 /// Value type for a raw input header. 206 /// </summary> 207 [StructLayout(LayoutKind.Sequential)] 208 public struct RawInputHeader 209 { 210 /// <summary>Type of device the input is coming from.</summary> 211 public RawInputType Type; 212 213 /// <summary>Size of the packet of data.</summary> 214 public int Size; 215 216 /// <summary>Handle to the device sending the data.</summary> 217 public IntPtr Device; 218 219 /// <summary>wParam from the window message.</summary> 220 public IntPtr wParam; 221 } 222 223 [StructLayout(LayoutKind.Sequential)] 224 public struct RawInputDevice 225 { 226 /// <summary>Top level collection Usage page for the raw input device.</summary> 227 public HIDUsagePage UsagePage; 228 229 /// <summary>Top level collection Usage for the raw input device. </summary> 230 public HIDUsage Usage; 231 232 /// <summary>Mode flag that specifies how to interpret the information provided by UsagePage and Usage.</summary> 233 public RawInputDeviceFlags Flags; 234 235 /// <summary>Handle to the target device. If NULL, it follows the keyboard focus.</summary> 236 public IntPtr WindowHandle; 237 } 238 239 /// <summary>Enumeration containing flags for a raw input device.</summary> 240 public enum RawInputDeviceFlags 241 { 242 /// <summary>No flags.</summary> 243 None = 0, 244 245 /// <summary>If set, this removes the top level collection from the inclusion list. This tells the operating system to stop reading from a device which matches the top level collection.</summary> 246 Remove = 0x00000001, 247 248 /// <summary>If set, this specifies the top level collections to exclude when reading a complete usage page. This flag only affects a TLC whose usage page is already specified with PageOnly.</summary> 249 Exclude = 0x00000010, 250 251 /// <summary>If set, this specifies all devices whose top level collection is from the specified usUsagePage. Note that Usage must be zero. To exclude a particular top level collection, use Exclude.</summary> 252 PageOnly = 0x00000020, 253 254 /// <summary>If set, this prevents any devices specified by UsagePage or Usage from generating legacy messages. This is only for the mouse and keyboard.</summary> 255 NoLegacy = 0x00000030, 256 257 /// <summary>If set, this enables the caller to receive the input even when the caller is not in the foreground. Note that WindowHandle must be specified.</summary> 258 InputSink = 0x00000100, 259 260 /// <summary>If set, the mouse button click does not activate the other window.</summary> 261 CaptureMouse = 0x00000200, 262 263 /// <summary>If set, the application-defined keyboard device hotkeys are not handled. However, the system hotkeys; for example, ALT+TAB and CTRL+ALT+DEL, are still handled. By default, all keyboard hotkeys are handled. NoHotKeys can be specified even if NoLegacy is not specified and WindowHandle is NULL.</summary> 264 NoHotKeys = 0x00000200, 265 266 /// <summary>If set, application keys are handled. NoLegacy must be specified. Keyboard only.</summary> 267 AppKeys = 0x00000400 268 } 269 270 public enum HIDUsage : ushort 271 { 272 Pointer = 0x01, 273 Mouse = 0x02, 274 Joystick = 0x04, 275 Gamepad = 0x05, 276 Keyboard = 0x06, 277 Keypad = 0x07, 278 SystemControl = 0x80, 279 } 280 281 public enum HIDUsagePage : ushort 282 { 283 Undefined = 0x00, 284 Generic = 0x01, 285 Simulation = 0x02, 286 VR = 0x03, 287 Sport = 0x04, 288 Game = 0x05, 289 Keyboard = 0x07, 290 LED = 0x08, 291 Button = 0x09, 292 Ordinal = 0x0A, 293 Telephony = 0x0B, 294 Consumer = 0x0C, 295 Digitizer = 0x0D, 296 PID = 0x0F, 297 Unicode = 0x10, 298 AlphaNumeric = 0x14, 299 Medical = 0x40, 300 MonitorPage0 = 0x80, 301 MonitorPage1 = 0x81, 302 MonitorPage2 = 0x82, 303 MonitorPage3 = 0x83, 304 PowerPage0 = 0x84, 305 PowerPage1 = 0x85, 306 PowerPage2 = 0x86, 307 PowerPage3 = 0x87, 308 BarCode = 0x8C, 309 Scale = 0x8D, 310 MSR = 0x8E 311 } 312}