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# ---------------------------------------------------------------------------- 35 36import sys 37import ctypes 38from ctypes import * 39from ctypes.wintypes import * 40 41 42_int_types = (c_int16, c_int32) 43if hasattr(ctypes, 'c_int64'): 44 # Some builds of ctypes apparently do not have c_int64 45 # defined; it's a pretty good bet that these builds do not 46 # have 64-bit pointers. 47 _int_types += (c_int64,) 48for t in _int_types: 49 if sizeof(t) == sizeof(c_size_t): 50 c_ptrdiff_t = t 51del t 52del _int_types 53 54 55# PUINT is defined only from >= python 3.2 56if sys.version_info < (3, 2)[:2]: 57 PUINT = POINTER(UINT) 58 59 60class c_void(Structure): 61 # c_void_p is a buggy return type, converting to int, so 62 # POINTER(None) == c_void_p is actually written as 63 # POINTER(c_void), so it can be treated as a real pointer. 64 _fields_ = [('dummy', c_int)] 65 66 67def POINTER_(obj): 68 p = ctypes.POINTER(obj) 69 70 # Convert None to a real NULL pointer to work around bugs 71 # in how ctypes handles None on 64-bit platforms 72 if not isinstance(p.from_param, classmethod): 73 def from_param(cls, x): 74 if x is None: 75 return cls() 76 else: 77 return x 78 p.from_param = classmethod(from_param) 79 80 return p 81 82 83c_void_p = POINTER_(c_void) 84INT = c_int 85LPVOID = c_void_p 86HCURSOR = HANDLE 87LRESULT = LPARAM 88COLORREF = DWORD 89PVOID = c_void_p 90WCHAR = c_wchar 91BCHAR = c_wchar 92LPRECT = POINTER(RECT) 93LPPOINT = POINTER(POINT) 94LPMSG = POINTER(MSG) 95UINT_PTR = HANDLE 96LONG_PTR = HANDLE 97HDROP = HANDLE 98LPTSTR = LPWSTR 99 100LF_FACESIZE = 32 101CCHDEVICENAME = 32 102CCHFORMNAME = 32 103 104WNDPROC = WINFUNCTYPE(LRESULT, HWND, UINT, WPARAM, LPARAM) 105TIMERPROC = WINFUNCTYPE(None, HWND, UINT, POINTER(UINT), DWORD) 106TIMERAPCPROC = WINFUNCTYPE(None, PVOID, DWORD, DWORD) 107MONITORENUMPROC = WINFUNCTYPE(BOOL, HMONITOR, HDC, LPRECT, LPARAM) 108 109 110def MAKEINTRESOURCE(i): 111 return cast(ctypes.c_void_p(i & 0xFFFF), c_wchar_p) 112 113 114class WNDCLASS(Structure): 115 _fields_ = [ 116 ('style', UINT), 117 ('lpfnWndProc', WNDPROC), 118 ('cbClsExtra', c_int), 119 ('cbWndExtra', c_int), 120 ('hInstance', HINSTANCE), 121 ('hIcon', HICON), 122 ('hCursor', HCURSOR), 123 ('hbrBackground', HBRUSH), 124 ('lpszMenuName', c_char_p), 125 ('lpszClassName', c_wchar_p) 126 ] 127 128 129class SECURITY_ATTRIBUTES(Structure): 130 _fields_ = [ 131 ("nLength", DWORD), 132 ("lpSecurityDescriptor", c_void_p), 133 ("bInheritHandle", BOOL) 134 ] 135 __slots__ = [f[0] for f in _fields_] 136 137 138class PIXELFORMATDESCRIPTOR(Structure): 139 _fields_ = [ 140 ('nSize', WORD), 141 ('nVersion', WORD), 142 ('dwFlags', DWORD), 143 ('iPixelType', BYTE), 144 ('cColorBits', BYTE), 145 ('cRedBits', BYTE), 146 ('cRedShift', BYTE), 147 ('cGreenBits', BYTE), 148 ('cGreenShift', BYTE), 149 ('cBlueBits', BYTE), 150 ('cBlueShift', BYTE), 151 ('cAlphaBits', BYTE), 152 ('cAlphaShift', BYTE), 153 ('cAccumBits', BYTE), 154 ('cAccumRedBits', BYTE), 155 ('cAccumGreenBits', BYTE), 156 ('cAccumBlueBits', BYTE), 157 ('cAccumAlphaBits', BYTE), 158 ('cDepthBits', BYTE), 159 ('cStencilBits', BYTE), 160 ('cAuxBuffers', BYTE), 161 ('iLayerType', BYTE), 162 ('bReserved', BYTE), 163 ('dwLayerMask', DWORD), 164 ('dwVisibleMask', DWORD), 165 ('dwDamageMask', DWORD) 166 ] 167 168 169class RGBQUAD(Structure): 170 _fields_ = [ 171 ('rgbBlue', BYTE), 172 ('rgbGreen', BYTE), 173 ('rgbRed', BYTE), 174 ('rgbReserved', BYTE), 175 ] 176 __slots__ = [f[0] for f in _fields_] 177 178 179class CIEXYZ(Structure): 180 _fields_ = [ 181 ('ciexyzX', DWORD), 182 ('ciexyzY', DWORD), 183 ('ciexyzZ', DWORD), 184 ] 185 __slots__ = [f[0] for f in _fields_] 186 187 188class CIEXYZTRIPLE(Structure): 189 _fields_ = [ 190 ('ciexyzRed', CIEXYZ), 191 ('ciexyzBlue', CIEXYZ), 192 ('ciexyzGreen', CIEXYZ), 193 ] 194 __slots__ = [f[0] for f in _fields_] 195 196 197class BITMAPINFOHEADER(Structure): 198 _fields_ = [ 199 ('biSize', DWORD), 200 ('biWidth', LONG), 201 ('biHeight', LONG), 202 ('biPlanes', WORD), 203 ('biBitCount', WORD), 204 ('biCompression', DWORD), 205 ('biSizeImage', DWORD), 206 ('biXPelsPerMeter', LONG), 207 ('biYPelsPerMeter', LONG), 208 ('biClrUsed', DWORD), 209 ('biClrImportant', DWORD), 210 ] 211 212 213class BITMAPV5HEADER(Structure): 214 _fields_ = [ 215 ('bV5Size', DWORD), 216 ('bV5Width', LONG), 217 ('bV5Height', LONG), 218 ('bV5Planes', WORD), 219 ('bV5BitCount', WORD), 220 ('bV5Compression', DWORD), 221 ('bV5SizeImage', DWORD), 222 ('bV5XPelsPerMeter', LONG), 223 ('bV5YPelsPerMeter', LONG), 224 ('bV5ClrUsed', DWORD), 225 ('bV5ClrImportant', DWORD), 226 ('bV5RedMask', DWORD), 227 ('bV5GreenMask', DWORD), 228 ('bV5BlueMask', DWORD), 229 ('bV5AlphaMask', DWORD), 230 ('bV5CSType', DWORD), 231 ('bV5Endpoints', CIEXYZTRIPLE), 232 ('bV5GammaRed', DWORD), 233 ('bV5GammaGreen', DWORD), 234 ('bV5GammaBlue', DWORD), 235 ('bV5Intent', DWORD), 236 ('bV5ProfileData', DWORD), 237 ('bV5ProfileSize', DWORD), 238 ('bV5Reserved', DWORD), 239 ] 240 241 242class BITMAPINFO(Structure): 243 _fields_ = [ 244 ('bmiHeader', BITMAPINFOHEADER), 245 ('bmiColors', RGBQUAD * 1) 246 ] 247 __slots__ = [f[0] for f in _fields_] 248 249 250class LOGFONT(Structure): 251 _fields_ = [ 252 ('lfHeight', LONG), 253 ('lfWidth', LONG), 254 ('lfEscapement', LONG), 255 ('lfOrientation', LONG), 256 ('lfWeight', LONG), 257 ('lfItalic', BYTE), 258 ('lfUnderline', BYTE), 259 ('lfStrikeOut', BYTE), 260 ('lfCharSet', BYTE), 261 ('lfOutPrecision', BYTE), 262 ('lfClipPrecision', BYTE), 263 ('lfQuality', BYTE), 264 ('lfPitchAndFamily', BYTE), 265 ('lfFaceName', (c_char * LF_FACESIZE)) # Use ASCII 266 ] 267 268 269class TRACKMOUSEEVENT(Structure): 270 _fields_ = [ 271 ('cbSize', DWORD), 272 ('dwFlags', DWORD), 273 ('hwndTrack', HWND), 274 ('dwHoverTime', DWORD) 275 ] 276 __slots__ = [f[0] for f in _fields_] 277 278 279class MINMAXINFO(Structure): 280 _fields_ = [ 281 ('ptReserved', POINT), 282 ('ptMaxSize', POINT), 283 ('ptMaxPosition', POINT), 284 ('ptMinTrackSize', POINT), 285 ('ptMaxTrackSize', POINT) 286 ] 287 __slots__ = [f[0] for f in _fields_] 288 289 290class ABC(Structure): 291 _fields_ = [ 292 ('abcA', c_int), 293 ('abcB', c_uint), 294 ('abcC', c_int) 295 ] 296 __slots__ = [f[0] for f in _fields_] 297 298 299class TEXTMETRIC(Structure): 300 _fields_ = [ 301 ('tmHeight', c_long), 302 ('tmAscent', c_long), 303 ('tmDescent', c_long), 304 ('tmInternalLeading', c_long), 305 ('tmExternalLeading', c_long), 306 ('tmAveCharWidth', c_long), 307 ('tmMaxCharWidth', c_long), 308 ('tmWeight', c_long), 309 ('tmOverhang', c_long), 310 ('tmDigitizedAspectX', c_long), 311 ('tmDigitizedAspectY', c_long), 312 ('tmFirstChar', c_char), # Use ASCII 313 ('tmLastChar', c_char), 314 ('tmDefaultChar', c_char), 315 ('tmBreakChar', c_char), 316 ('tmItalic', c_byte), 317 ('tmUnderlined', c_byte), 318 ('tmStruckOut', c_byte), 319 ('tmPitchAndFamily', c_byte), 320 ('tmCharSet', c_byte) 321 ] 322 __slots__ = [f[0] for f in _fields_] 323 324 325class MONITORINFOEX(Structure): 326 _fields_ = [ 327 ('cbSize', DWORD), 328 ('rcMonitor', RECT), 329 ('rcWork', RECT), 330 ('dwFlags', DWORD), 331 ('szDevice', WCHAR * CCHDEVICENAME) 332 ] 333 __slots__ = [f[0] for f in _fields_] 334 335 336class DEVMODE(Structure): 337 _fields_ = [ 338 ('dmDeviceName', BCHAR * CCHDEVICENAME), 339 ('dmSpecVersion', WORD), 340 ('dmDriverVersion', WORD), 341 ('dmSize', WORD), 342 ('dmDriverExtra', WORD), 343 ('dmFields', DWORD), 344 # Just using largest union member here 345 ('dmOrientation', c_short), 346 ('dmPaperSize', c_short), 347 ('dmPaperLength', c_short), 348 ('dmPaperWidth', c_short), 349 ('dmScale', c_short), 350 ('dmCopies', c_short), 351 ('dmDefaultSource', c_short), 352 ('dmPrintQuality', c_short), 353 # End union 354 ('dmColor', c_short), 355 ('dmDuplex', c_short), 356 ('dmYResolution', c_short), 357 ('dmTTOption', c_short), 358 ('dmCollate', c_short), 359 ('dmFormName', BCHAR * CCHFORMNAME), 360 ('dmLogPixels', WORD), 361 ('dmBitsPerPel', DWORD), 362 ('dmPelsWidth', DWORD), 363 ('dmPelsHeight', DWORD), 364 ('dmDisplayFlags', DWORD), # union with dmNup 365 ('dmDisplayFrequency', DWORD), 366 ('dmICMMethod', DWORD), 367 ('dmICMIntent', DWORD), 368 ('dmDitherType', DWORD), 369 ('dmReserved1', DWORD), 370 ('dmReserved2', DWORD), 371 ('dmPanningWidth', DWORD), 372 ('dmPanningHeight', DWORD), 373 ] 374 375 376class ICONINFO(Structure): 377 _fields_ = [ 378 ('fIcon', BOOL), 379 ('xHotspot', DWORD), 380 ('yHotspot', DWORD), 381 ('hbmMask', HBITMAP), 382 ('hbmColor', HBITMAP) 383 ] 384 __slots__ = [f[0] for f in _fields_] 385 386 387class RAWINPUTDEVICE(Structure): 388 _fields_ = [ 389 ('usUsagePage', USHORT), 390 ('usUsage', USHORT), 391 ('dwFlags', DWORD), 392 ('hwndTarget', HWND) 393 ] 394 395 396PCRAWINPUTDEVICE = POINTER(RAWINPUTDEVICE) 397HRAWINPUT = HANDLE 398 399 400class RAWINPUTHEADER(Structure): 401 _fields_ = [ 402 ('dwType', DWORD), 403 ('dwSize', DWORD), 404 ('hDevice', HANDLE), 405 ('wParam', WPARAM), 406 ] 407 408 409class _Buttons(Structure): 410 _fields_ = [ 411 ('usButtonFlags', USHORT), 412 ('usButtonData', USHORT), 413 ] 414 415 416class _U(Union): 417 _anonymous_ = ('_buttons',) 418 _fields_ = [ 419 ('ulButtons', ULONG), 420 ('_buttons', _Buttons), 421 ] 422 423 424class RAWMOUSE(Structure): 425 _anonymous_ = ('u',) 426 _fields_ = [ 427 ('usFlags', USHORT), 428 ('u', _U), 429 ('ulRawButtons', ULONG), 430 ('lLastX', LONG), 431 ('lLastY', LONG), 432 ('ulExtraInformation', ULONG), 433 ] 434 435 436class RAWKEYBOARD(Structure): 437 _fields_ = [ 438 ('MakeCode', USHORT), 439 ('Flags', USHORT), 440 ('Reserved', USHORT), 441 ('VKey', USHORT), 442 ('Message', UINT), 443 ('ExtraInformation', ULONG), 444 ] 445 446 447class RAWHID(Structure): 448 _fields_ = [ 449 ('dwSizeHid', DWORD), 450 ('dwCount', DWORD), 451 ('bRawData', POINTER(BYTE)), 452 ] 453 454 455class _RAWINPUTDEVICEUNION(Union): 456 _fields_ = [ 457 ('mouse', RAWMOUSE), 458 ('keyboard', RAWKEYBOARD), 459 ('hid', RAWHID), 460 ] 461 462 463class RAWINPUT(Structure): 464 _fields_ = [ 465 ('header', RAWINPUTHEADER), 466 ('data', _RAWINPUTDEVICEUNION), 467 ] 468