1# ---------------------------------------------------------------------------- 2# pyglet 3# Copyright (c) 2006-2008 Alex Holkner 4# Copyright (c) 2008-2020 pyglet contributors 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 11# * Redistributions of source code must retain the above copyright 12# notice, this list of conditions and the following disclaimer. 13# * Redistributions in binary form must reproduce the above copyright 14# notice, this list of conditions and the following disclaimer in 15# the documentation and/or other materials provided with the 16# distribution. 17# * Neither the name of pyglet nor the names of its 18# contributors may be used to endorse or promote products 19# derived from this software without specific prior written 20# permission. 21# 22# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33# POSSIBILITY OF SUCH DAMAGE. 34# ---------------------------------------------------------------------------- 35import ctypes 36 37from pyglet import com 38 39lib = ctypes.oledll.dinput8 40 41LPVOID = ctypes.c_void_p 42WORD = ctypes.c_uint16 43DWORD = ctypes.c_uint32 44LPDWORD = ctypes.POINTER(DWORD) 45BOOL = ctypes.c_int 46WCHAR = ctypes.c_wchar 47UINT = ctypes.c_uint 48HWND = ctypes.c_uint32 49HANDLE = LPVOID 50MAX_PATH = 260 51 52DIENUM_STOP = 0 53DIENUM_CONTINUE = 1 54 55DIEDFL_ALLDEVICES = 0x00000000 56DIEDFL_ATTACHEDONLY = 0x00000001 57DIEDFL_FORCEFEEDBACK = 0x00000100 58DIEDFL_INCLUDEALIASES = 0x00010000 59DIEDFL_INCLUDEPHANTOMS = 0x00020000 60DIEDFL_INCLUDEHIDDEN = 0x00040000 61 62DI8DEVCLASS_ALL = 0 63DI8DEVCLASS_DEVICE = 1 64DI8DEVCLASS_POINTER = 2 65DI8DEVCLASS_KEYBOARD = 3 66DI8DEVCLASS_GAMECTRL = 4 67 68DI8DEVTYPE_DEVICE = 0x11 69DI8DEVTYPE_MOUSE = 0x12 70DI8DEVTYPE_KEYBOARD = 0x13 71DI8DEVTYPE_JOYSTICK = 0x14 72DI8DEVTYPE_GAMEPAD = 0x15 73DI8DEVTYPE_DRIVING = 0x16 74DI8DEVTYPE_FLIGHT = 0x17 75DI8DEVTYPE_1STPERSON = 0x18 76DI8DEVTYPE_DEVICECTRL = 0x19 77DI8DEVTYPE_SCREENPOINTER = 0x1A 78DI8DEVTYPE_REMOTE = 0x1B 79DI8DEVTYPE_SUPPLEMENTAL = 0x1C 80DI8DEVTYPEMOUSE_UNKNOWN = 1 81DI8DEVTYPEMOUSE_TRADITIONAL = 2 82DI8DEVTYPEMOUSE_FINGERSTICK = 3 83DI8DEVTYPEMOUSE_TOUCHPAD = 4 84DI8DEVTYPEMOUSE_TRACKBALL = 5 85DI8DEVTYPEMOUSE_ABSOLUTE = 6 86 87DI8DEVTYPEKEYBOARD_UNKNOWN = 0 88DI8DEVTYPEKEYBOARD_PCXT = 1 89DI8DEVTYPEKEYBOARD_OLIVETTI = 2 90DI8DEVTYPEKEYBOARD_PCAT = 3 91DI8DEVTYPEKEYBOARD_PCENH = 4 92DI8DEVTYPEKEYBOARD_NOKIA1050 = 5 93DI8DEVTYPEKEYBOARD_NOKIA9140 = 6 94DI8DEVTYPEKEYBOARD_NEC98 = 7 95DI8DEVTYPEKEYBOARD_NEC98LAPTOP = 8 96DI8DEVTYPEKEYBOARD_NEC98106 = 9 97DI8DEVTYPEKEYBOARD_JAPAN106 = 10 98DI8DEVTYPEKEYBOARD_JAPANAX = 11 99DI8DEVTYPEKEYBOARD_J3100 = 12 100 101DI8DEVTYPE_LIMITEDGAMESUBTYPE = 1 102 103DI8DEVTYPEJOYSTICK_LIMITED = DI8DEVTYPE_LIMITEDGAMESUBTYPE 104DI8DEVTYPEJOYSTICK_STANDARD = 2 105 106DI8DEVTYPEGAMEPAD_LIMITED = DI8DEVTYPE_LIMITEDGAMESUBTYPE 107DI8DEVTYPEGAMEPAD_STANDARD = 2 108DI8DEVTYPEGAMEPAD_TILT = 3 109 110DI8DEVTYPEDRIVING_LIMITED = DI8DEVTYPE_LIMITEDGAMESUBTYPE 111DI8DEVTYPEDRIVING_COMBINEDPEDALS = 2 112DI8DEVTYPEDRIVING_DUALPEDALS = 3 113DI8DEVTYPEDRIVING_THREEPEDALS = 4 114DI8DEVTYPEDRIVING_HANDHELD = 5 115 116DI8DEVTYPEFLIGHT_LIMITED = DI8DEVTYPE_LIMITEDGAMESUBTYPE 117DI8DEVTYPEFLIGHT_STICK = 2 118DI8DEVTYPEFLIGHT_YOKE = 3 119DI8DEVTYPEFLIGHT_RC = 4 120 121DI8DEVTYPE1STPERSON_LIMITED = DI8DEVTYPE_LIMITEDGAMESUBTYPE 122DI8DEVTYPE1STPERSON_UNKNOWN = 2 123DI8DEVTYPE1STPERSON_SIXDOF = 3 124DI8DEVTYPE1STPERSON_SHOOTER = 4 125 126DI8DEVTYPESCREENPTR_UNKNOWN = 2 127DI8DEVTYPESCREENPTR_LIGHTGUN = 3 128DI8DEVTYPESCREENPTR_LIGHTPEN = 4 129DI8DEVTYPESCREENPTR_TOUCH = 5 130 131DI8DEVTYPEREMOTE_UNKNOWN = 2 132 133DI8DEVTYPEDEVICECTRL_UNKNOWN = 2 134DI8DEVTYPEDEVICECTRL_COMMSSELECTION = 3 135DI8DEVTYPEDEVICECTRL_COMMSSELECTION_HARDWIRED = 4 136 137DI8DEVTYPESUPPLEMENTAL_UNKNOWN = 2 138DI8DEVTYPESUPPLEMENTAL_2NDHANDCONTROLLER = 3 139DI8DEVTYPESUPPLEMENTAL_HEADTRACKER = 4 140DI8DEVTYPESUPPLEMENTAL_HANDTRACKER = 5 141DI8DEVTYPESUPPLEMENTAL_SHIFTSTICKGATE = 6 142DI8DEVTYPESUPPLEMENTAL_SHIFTER = 7 143DI8DEVTYPESUPPLEMENTAL_THROTTLE = 8 144DI8DEVTYPESUPPLEMENTAL_SPLITTHROTTLE = 9 145DI8DEVTYPESUPPLEMENTAL_COMBINEDPEDALS = 10 146DI8DEVTYPESUPPLEMENTAL_DUALPEDALS = 11 147DI8DEVTYPESUPPLEMENTAL_THREEPEDALS = 12 148DI8DEVTYPESUPPLEMENTAL_RUDDERPEDALS = 13 149DIDC_ATTACHED = 0x00000001 150DIDC_POLLEDDEVICE = 0x00000002 151DIDC_EMULATED = 0x00000004 152DIDC_POLLEDDATAFORMAT = 0x00000008 153DIDC_FORCEFEEDBACK = 0x00000100 154DIDC_FFATTACK = 0x00000200 155DIDC_FFFADE = 0x00000400 156DIDC_SATURATION = 0x00000800 157DIDC_POSNEGCOEFFICIENTS = 0x00001000 158DIDC_POSNEGSATURATION = 0x00002000 159DIDC_DEADBAND = 0x00004000 160DIDC_STARTDELAY = 0x00008000 161DIDC_ALIAS = 0x00010000 162DIDC_PHANTOM = 0x00020000 163DIDC_HIDDEN = 0x00040000 164 165def DIDFT_GETINSTANCE(n): 166 return (n >> 8) & 0xffff 167 168DIDFT_ALL = 0x00000000 169 170DIDFT_RELAXIS = 0x00000001 171DIDFT_ABSAXIS = 0x00000002 172DIDFT_AXIS = 0x00000003 173 174DIDFT_PSHBUTTON = 0x00000004 175DIDFT_TGLBUTTON = 0x00000008 176DIDFT_BUTTON = 0x0000000C 177 178DIDFT_POV = 0x00000010 179DIDFT_COLLECTION = 0x00000040 180DIDFT_NODATA = 0x00000080 181 182DIDFT_ANYINSTANCE = 0x00FFFF00 183DIDFT_INSTANCEMASK = DIDFT_ANYINSTANCE 184DIDFT_FFACTUATOR = 0x01000000 185DIDFT_FFEFFECTTRIGGER = 0x02000000 186DIDFT_OUTPUT = 0x10000000 187DIDFT_VENDORDEFINED = 0x04000000 188DIDFT_ALIAS = 0x08000000 189DIDFT_OPTIONAL = 0x80000000 190 191DIDFT_NOCOLLECTION = 0x00FFFF00 192 193DIA_FORCEFEEDBACK = 0x00000001 194DIA_APPMAPPED = 0x00000002 195DIA_APPNOMAP = 0x00000004 196DIA_NORANGE = 0x00000008 197DIA_APPFIXED = 0x00000010 198 199DIAH_UNMAPPED = 0x00000000 200DIAH_USERCONFIG = 0x00000001 201DIAH_APPREQUESTED = 0x00000002 202DIAH_HWAPP = 0x00000004 203DIAH_HWDEFAULT = 0x00000008 204DIAH_DEFAULT = 0x00000020 205DIAH_ERROR = 0x80000000 206DIAFTS_NEWDEVICELOW = 0xFFFFFFFF 207DIAFTS_NEWDEVICEHIGH = 0xFFFFFFFF 208DIAFTS_UNUSEDDEVICELOW = 0x00000000 209DIAFTS_UNUSEDDEVICEHIGH = 0x00000000 210 211DIDBAM_DEFAULT = 0x00000000 212DIDBAM_PRESERVE = 0x00000001 213DIDBAM_INITIALIZE = 0x00000002 214DIDBAM_HWDEFAULTS = 0x00000004 215 216DIDSAM_DEFAULT = 0x00000000 217DIDSAM_NOUSER = 0x00000001 218DIDSAM_FORCESAVE = 0x00000002 219 220DICD_DEFAULT = 0x00000000 221DICD_EDIT = 0x00000001 222 223DIDOI_FFACTUATOR = 0x00000001 224DIDOI_FFEFFECTTRIGGER = 0x00000002 225DIDOI_POLLED = 0x00008000 226DIDOI_ASPECTPOSITION = 0x00000100 227DIDOI_ASPECTVELOCITY = 0x00000200 228DIDOI_ASPECTACCEL = 0x00000300 229DIDOI_ASPECTFORCE = 0x00000400 230DIDOI_ASPECTMASK = 0x00000F00 231DIDOI_GUIDISUSAGE = 0x00010000 232 233DIPH_DEVICE = 0 234DIPH_BYOFFSET = 1 235DIPH_BYID = 2 236DIPH_BYUSAGE = 3 237 238DISCL_EXCLUSIVE = 0x00000001 239DISCL_NONEXCLUSIVE = 0x00000002 240DISCL_FOREGROUND = 0x00000004 241DISCL_BACKGROUND = 0x00000008 242DISCL_NOWINKEY = 0x00000010 243 244DIPROP_BUFFERSIZE = 1 245 246GUID_XAxis = \ 247 com.GUID(0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00) 248 249 250class DIDEVICEINSTANCE(ctypes.Structure): 251 _fields_ = ( 252 ('dwSize', DWORD), 253 ('guidInstance', com.GUID), 254 ('guidProduct', com.GUID), 255 ('dwDevType', DWORD), 256 ('tszInstanceName', WCHAR * MAX_PATH), 257 ('tszProductName', WCHAR * MAX_PATH), 258 ('guidFFDriver', com.GUID), 259 ('wUsagePage', WORD), 260 ('wUsage', WORD) 261 ) 262LPDIDEVICEINSTANCE = ctypes.POINTER(DIDEVICEINSTANCE) 263LPDIENUMDEVICESCALLBACK = ctypes.WINFUNCTYPE(BOOL, LPDIDEVICEINSTANCE, LPVOID) 264 265class DIDEVICEOBJECTINSTANCE(ctypes.Structure): 266 _fields_ = ( 267 ('dwSize', DWORD), 268 ('guidType', com.GUID), 269 ('dwOfs', DWORD), 270 ('dwType', DWORD), 271 ('dwFlags', DWORD), 272 ('tszName', WCHAR * MAX_PATH), 273 ('dwFFMaxForce', DWORD), 274 ('dwFFForceResolution', DWORD), 275 ('wCollectionNumber', WORD), 276 ('wDesignatorIndex', WORD), 277 ('wUsagePage', WORD), 278 ('wUsage', WORD), 279 ('dwDimension', DWORD), 280 ('wExponent', WORD), 281 ('wReportId', WORD) 282 ) 283LPDIDEVICEOBJECTINSTANCE = ctypes.POINTER(DIDEVICEOBJECTINSTANCE) 284LPDIENUMDEVICEOBJECTSCALLBACK = \ 285 ctypes.WINFUNCTYPE( BOOL, LPDIDEVICEOBJECTINSTANCE, LPVOID) 286 287class DIOBJECTDATAFORMAT(ctypes.Structure): 288 _fields_ = ( 289 ('pguid', ctypes.POINTER(com.GUID)), 290 ('dwOfs', DWORD), 291 ('dwType', DWORD), 292 ('dwFlags', DWORD) 293 ) 294 __slots__ = [n for n, t in _fields_] 295LPDIOBJECTDATAFORMAT = ctypes.POINTER(DIOBJECTDATAFORMAT) 296 297class DIDATAFORMAT(ctypes.Structure): 298 _fields_ = ( 299 ('dwSize', DWORD), 300 ('dwObjSize', DWORD), 301 ('dwFlags', DWORD), 302 ('dwDataSize', DWORD), 303 ('dwNumObjs', DWORD), 304 ('rgodf', LPDIOBJECTDATAFORMAT) 305 ) 306 __slots__ = [n for n, t in _fields_] 307LPDIDATAFORMAT = ctypes.POINTER(DIDATAFORMAT) 308 309class DIDEVICEOBJECTDATA(ctypes.Structure): 310 _fields_ = ( 311 ('dwOfs', DWORD), 312 ('dwData', DWORD), 313 ('dwTimeStamp', DWORD), 314 ('dwSequence', DWORD), 315 ('uAppData', ctypes.POINTER(UINT)) 316 ) 317LPDIDEVICEOBJECTDATA = ctypes.POINTER(DIDEVICEOBJECTDATA) 318 319class DIPROPHEADER(ctypes.Structure): 320 _fields_ = ( 321 ('dwSize', DWORD), 322 ('dwHeaderSize', DWORD), 323 ('dwObj', DWORD), 324 ('dwHow', DWORD) 325 ) 326LPDIPROPHEADER = ctypes.POINTER(DIPROPHEADER) 327 328class DIPROPDWORD(ctypes.Structure): 329 _fields_ = ( 330 ('diph', DIPROPHEADER), 331 ('dwData', DWORD) 332 ) 333 334# All method names in the interfaces are filled in, but unused (so far) 335# methods have no parameters.. they'll crash when we try and use them, at 336# which point we can go in and fill them in. 337 338# IDirect* interfaces are all Unicode (e.g. IDirectInputDevice8W). 339 340class IDirectInputDevice8(com.IUnknown): 341 _methods_ = [ 342 ('GetCapabilities', 343 com.STDMETHOD()), 344 ('EnumObjects', 345 com.STDMETHOD(LPDIENUMDEVICEOBJECTSCALLBACK, LPVOID, DWORD)), 346 ('GetProperty', 347 com.STDMETHOD()), 348 ('SetProperty', 349 com.STDMETHOD(LPVOID, LPDIPROPHEADER)), 350 ('Acquire', 351 com.STDMETHOD()), 352 ('Unacquire', 353 com.STDMETHOD()), 354 ('GetDeviceState', 355 com.STDMETHOD()), 356 ('GetDeviceData', 357 com.STDMETHOD(DWORD, LPDIDEVICEOBJECTDATA, LPDWORD, DWORD)), 358 ('SetDataFormat', 359 com.STDMETHOD(LPDIDATAFORMAT)), 360 ('SetEventNotification', 361 com.STDMETHOD(HANDLE)), 362 ('SetCooperativeLevel', 363 com.STDMETHOD(HWND, DWORD)), 364 ('GetObjectInfo', 365 com.STDMETHOD()), 366 ('GetDeviceInfo', 367 com.STDMETHOD()), 368 ('RunControlPanel', 369 com.STDMETHOD()), 370 ('Initialize', 371 com.STDMETHOD()), 372 ('CreateEffect', 373 com.STDMETHOD()), 374 ('EnumEffects', 375 com.STDMETHOD()), 376 ('GetEffectInfo', 377 com.STDMETHOD()), 378 ('GetForceFeedbackState', 379 com.STDMETHOD()), 380 ('SendForceFeedbackCommand', 381 com.STDMETHOD()), 382 ('EnumCreatedEffectObjects', 383 com.STDMETHOD()), 384 ('Escape', 385 com.STDMETHOD()), 386 ('Poll', 387 com.STDMETHOD()), 388 ('SendDeviceData', 389 com.STDMETHOD()), 390 ('EnumEffectsInFile', 391 com.STDMETHOD()), 392 ('WriteEffectToFile', 393 com.STDMETHOD()), 394 ('BuildActionMap', 395 com.STDMETHOD()), 396 ('SetActionMap', 397 com.STDMETHOD()), 398 ('GetImageInfo', 399 com.STDMETHOD()), 400 ] 401 402class IDirectInput8(com.IUnknown): 403 _methods_ = [ 404 ('CreateDevice', 405 com.STDMETHOD(ctypes.POINTER(com.GUID), 406 ctypes.POINTER(IDirectInputDevice8), 407 ctypes.c_void_p)), 408 ('EnumDevices', 409 com.STDMETHOD(DWORD, LPDIENUMDEVICESCALLBACK, LPVOID, DWORD)), 410 ('GetDeviceStatus', 411 com.STDMETHOD()), 412 ('RunControlPanel', 413 com.STDMETHOD()), 414 ('Initialize', 415 com.STDMETHOD()), 416 ('FindDevice', 417 com.STDMETHOD()), 418 ('EnumDevicesBySemantics', 419 com.STDMETHOD()), 420 ('ConfigureDevices', 421 com.STDMETHOD()), 422 ] 423 424IID_IDirectInput8W = \ 425 com.GUID(0xBF798031,0x483A,0x4DA2,0xAA,0x99,0x5D,0x64,0xED,0x36,0x97,0x00) 426 427DIRECTINPUT_VERSION = 0x0800 428DirectInput8Create = lib.DirectInput8Create 429DirectInput8Create.argtypes = \ 430 (ctypes.c_void_p, DWORD, com.LPGUID, ctypes.c_void_p, ctypes.c_void_p) 431 432