pyglet 2.1.12__py3-none-any.whl → 3.0.dev1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyglet/__init__.py +67 -61
- pyglet/__init__.pyi +15 -8
- pyglet/app/__init__.py +22 -13
- pyglet/app/async_app.py +212 -0
- pyglet/app/base.py +2 -1
- pyglet/app/{xlib.py → linux.py} +3 -3
- pyglet/config/__init__.py +101 -0
- pyglet/config/gl/__init__.py +30 -0
- pyglet/config/gl/egl.py +120 -0
- pyglet/config/gl/macos.py +262 -0
- pyglet/config/gl/windows.py +267 -0
- pyglet/config/gl/x11.py +142 -0
- pyglet/customtypes.py +43 -2
- pyglet/display/__init__.py +8 -6
- pyglet/display/base.py +3 -63
- pyglet/display/cocoa.py +12 -17
- pyglet/display/emscripten.py +39 -0
- pyglet/display/headless.py +23 -30
- pyglet/display/wayland.py +157 -0
- pyglet/display/win32.py +4 -17
- pyglet/display/xlib.py +19 -27
- pyglet/display/xlib_vidmoderestore.py +2 -2
- pyglet/enums.py +183 -0
- pyglet/event.py +0 -1
- pyglet/experimental/geoshader_sprite.py +15 -13
- pyglet/experimental/hidraw.py +6 -15
- pyglet/experimental/multitexture_sprite.py +31 -19
- pyglet/experimental/particles.py +13 -35
- pyglet/font/__init__.py +251 -85
- pyglet/font/base.py +116 -61
- pyglet/font/dwrite/__init__.py +349 -204
- pyglet/font/dwrite/dwrite_lib.py +27 -5
- pyglet/font/fontconfig.py +14 -6
- pyglet/font/freetype.py +138 -87
- pyglet/font/freetype_lib.py +19 -0
- pyglet/font/group.py +179 -0
- pyglet/font/harfbuzz/__init__.py +3 -3
- pyglet/font/pyodide_js.py +310 -0
- pyglet/font/quartz.py +319 -126
- pyglet/font/ttf.py +45 -3
- pyglet/font/user.py +14 -19
- pyglet/font/win32.py +45 -21
- pyglet/graphics/__init__.py +8 -787
- pyglet/graphics/allocation.py +115 -1
- pyglet/graphics/api/__init__.py +77 -0
- pyglet/graphics/api/base.py +299 -0
- pyglet/graphics/api/gl/__init__.py +58 -0
- pyglet/graphics/api/gl/base.py +24 -0
- pyglet/graphics/{vertexbuffer.py → api/gl/buffer.py} +104 -159
- pyglet/graphics/api/gl/cocoa/context.py +76 -0
- pyglet/graphics/api/gl/context.py +391 -0
- pyglet/graphics/api/gl/default_shaders.py +0 -0
- pyglet/graphics/api/gl/draw.py +627 -0
- pyglet/graphics/api/gl/egl/__init__.py +0 -0
- pyglet/graphics/api/gl/egl/context.py +92 -0
- pyglet/graphics/api/gl/enums.py +76 -0
- pyglet/graphics/api/gl/framebuffer.py +315 -0
- pyglet/graphics/api/gl/gl.py +5463 -0
- pyglet/graphics/api/gl/gl_info.py +188 -0
- pyglet/graphics/api/gl/global_opengl.py +226 -0
- pyglet/{gl → graphics/api/gl}/lib.py +34 -18
- pyglet/graphics/api/gl/shader.py +1476 -0
- pyglet/graphics/api/gl/shapes.py +55 -0
- pyglet/graphics/api/gl/sprite.py +102 -0
- pyglet/graphics/api/gl/state.py +219 -0
- pyglet/graphics/api/gl/text.py +190 -0
- pyglet/graphics/api/gl/texture.py +1526 -0
- pyglet/graphics/{vertexarray.py → api/gl/vertexarray.py} +11 -13
- pyglet/graphics/api/gl/vertexdomain.py +751 -0
- pyglet/graphics/api/gl/win32/__init__.py +0 -0
- pyglet/graphics/api/gl/win32/context.py +108 -0
- pyglet/graphics/api/gl/win32/wgl_info.py +24 -0
- pyglet/graphics/api/gl/xlib/__init__.py +0 -0
- pyglet/graphics/api/gl/xlib/context.py +174 -0
- pyglet/{gl → graphics/api/gl/xlib}/glx_info.py +26 -31
- pyglet/graphics/api/gl1/__init__.py +0 -0
- pyglet/{gl → graphics/api/gl1}/gl_compat.py +3 -2
- pyglet/graphics/api/gl2/__init__.py +0 -0
- pyglet/graphics/api/gl2/buffer.py +320 -0
- pyglet/graphics/api/gl2/draw.py +600 -0
- pyglet/graphics/api/gl2/global_opengl.py +122 -0
- pyglet/graphics/api/gl2/shader.py +200 -0
- pyglet/graphics/api/gl2/shapes.py +51 -0
- pyglet/graphics/api/gl2/sprite.py +79 -0
- pyglet/graphics/api/gl2/text.py +175 -0
- pyglet/graphics/api/gl2/vertexdomain.py +364 -0
- pyglet/graphics/api/webgl/__init__.py +233 -0
- pyglet/graphics/api/webgl/buffer.py +302 -0
- pyglet/graphics/api/webgl/context.py +234 -0
- pyglet/graphics/api/webgl/draw.py +590 -0
- pyglet/graphics/api/webgl/enums.py +76 -0
- pyglet/graphics/api/webgl/framebuffer.py +360 -0
- pyglet/graphics/api/webgl/gl.py +1537 -0
- pyglet/graphics/api/webgl/gl_info.py +130 -0
- pyglet/graphics/api/webgl/shader.py +1346 -0
- pyglet/graphics/api/webgl/shapes.py +92 -0
- pyglet/graphics/api/webgl/sprite.py +102 -0
- pyglet/graphics/api/webgl/state.py +227 -0
- pyglet/graphics/api/webgl/text.py +187 -0
- pyglet/graphics/api/webgl/texture.py +1227 -0
- pyglet/graphics/api/webgl/vertexarray.py +54 -0
- pyglet/graphics/api/webgl/vertexdomain.py +616 -0
- pyglet/graphics/api/webgl/webgl_js.pyi +307 -0
- pyglet/{image → graphics}/atlas.py +33 -32
- pyglet/graphics/base.py +10 -0
- pyglet/graphics/buffer.py +245 -0
- pyglet/graphics/draw.py +578 -0
- pyglet/graphics/framebuffer.py +26 -0
- pyglet/graphics/instance.py +178 -69
- pyglet/graphics/shader.py +267 -1553
- pyglet/graphics/state.py +83 -0
- pyglet/graphics/texture.py +703 -0
- pyglet/graphics/vertexdomain.py +695 -538
- pyglet/gui/ninepatch.py +10 -10
- pyglet/gui/widgets.py +120 -10
- pyglet/image/__init__.py +20 -1973
- pyglet/image/animation.py +12 -12
- pyglet/image/base.py +730 -0
- pyglet/image/codecs/__init__.py +9 -0
- pyglet/image/codecs/bmp.py +53 -30
- pyglet/image/codecs/dds.py +53 -31
- pyglet/image/codecs/gdiplus.py +38 -14
- pyglet/image/codecs/gdkpixbuf2.py +0 -2
- pyglet/image/codecs/js_image.py +99 -0
- pyglet/image/codecs/ktx2.py +161 -0
- pyglet/image/codecs/pil.py +1 -1
- pyglet/image/codecs/png.py +1 -1
- pyglet/image/codecs/wic.py +11 -2
- pyglet/info.py +26 -24
- pyglet/input/__init__.py +8 -0
- pyglet/input/base.py +163 -105
- pyglet/input/controller.py +13 -19
- pyglet/input/controller_db.py +39 -24
- pyglet/input/emscripten/__init__.py +18 -0
- pyglet/input/emscripten/gamepad_js.py +397 -0
- pyglet/input/linux/__init__.py +11 -5
- pyglet/input/linux/evdev.py +10 -11
- pyglet/input/linux/x11_xinput.py +2 -2
- pyglet/input/linux/x11_xinput_tablet.py +1 -1
- pyglet/input/macos/__init__.py +7 -2
- pyglet/input/macos/darwin_gc.py +559 -0
- pyglet/input/win32/__init__.py +1 -1
- pyglet/input/win32/directinput.py +34 -29
- pyglet/input/win32/xinput.py +11 -61
- pyglet/lib.py +3 -3
- pyglet/libs/__init__.py +1 -1
- pyglet/{gl → libs/darwin}/agl.py +1 -1
- pyglet/libs/darwin/cocoapy/__init__.py +2 -2
- pyglet/libs/darwin/cocoapy/cocoahelpers.py +181 -0
- pyglet/libs/darwin/cocoapy/cocoalibs.py +31 -0
- pyglet/libs/darwin/cocoapy/cocoatypes.py +27 -0
- pyglet/libs/darwin/cocoapy/runtime.py +81 -45
- pyglet/libs/darwin/coreaudio.py +4 -4
- pyglet/{gl → libs/darwin}/lib_agl.py +9 -8
- pyglet/libs/darwin/quartzkey.py +1 -3
- pyglet/libs/egl/__init__.py +2 -0
- pyglet/libs/egl/egl_lib.py +576 -0
- pyglet/libs/egl/eglext.py +51 -5
- pyglet/libs/linux/__init__.py +0 -0
- pyglet/libs/linux/egl/__init__.py +0 -0
- pyglet/libs/linux/egl/eglext.py +22 -0
- pyglet/libs/linux/glx/__init__.py +0 -0
- pyglet/{gl → libs/linux/glx}/glx.py +13 -14
- pyglet/{gl → libs/linux/glx}/glxext_arb.py +408 -192
- pyglet/{gl → libs/linux/glx}/glxext_mesa.py +1 -1
- pyglet/{gl → libs/linux/glx}/glxext_nv.py +345 -164
- pyglet/{gl → libs/linux/glx}/lib_glx.py +3 -2
- pyglet/libs/linux/wayland/__init__.py +0 -0
- pyglet/libs/linux/wayland/client.py +1068 -0
- pyglet/libs/linux/wayland/lib_wayland.py +207 -0
- pyglet/libs/linux/wayland/wayland_egl.py +38 -0
- pyglet/libs/{wayland → linux/wayland}/xkbcommon.py +26 -0
- pyglet/libs/{x11 → linux/x11}/xf86vmode.py +4 -4
- pyglet/libs/{x11 → linux/x11}/xinerama.py +2 -2
- pyglet/libs/{x11 → linux/x11}/xinput.py +10 -10
- pyglet/libs/linux/x11/xrandr.py +0 -0
- pyglet/libs/{x11 → linux/x11}/xrender.py +1 -1
- pyglet/libs/shared/__init__.py +0 -0
- pyglet/libs/shared/spirv/__init__.py +0 -0
- pyglet/libs/shared/spirv/lib_shaderc.py +85 -0
- pyglet/libs/shared/spirv/lib_spirv_cross.py +126 -0
- pyglet/libs/win32/__init__.py +27 -5
- pyglet/libs/win32/constants.py +59 -48
- pyglet/libs/win32/context_managers.py +20 -3
- pyglet/libs/win32/dinput.py +105 -88
- pyglet/{gl → libs/win32}/lib_wgl.py +52 -26
- pyglet/libs/win32/types.py +58 -23
- pyglet/{gl → libs/win32}/wgl.py +32 -25
- pyglet/{gl → libs/win32}/wglext_arb.py +364 -2
- pyglet/media/__init__.py +9 -10
- pyglet/media/codecs/__init__.py +12 -1
- pyglet/media/codecs/base.py +99 -96
- pyglet/media/codecs/ffmpeg.py +2 -2
- pyglet/media/codecs/ffmpeg_lib/libavformat.py +3 -8
- pyglet/media/codecs/webaudio_pyodide.py +111 -0
- pyglet/media/drivers/__init__.py +9 -4
- pyglet/media/drivers/base.py +4 -4
- pyglet/media/drivers/openal/__init__.py +1 -1
- pyglet/media/drivers/openal/adaptation.py +3 -3
- pyglet/media/drivers/pulse/__init__.py +1 -1
- pyglet/media/drivers/pulse/adaptation.py +3 -3
- pyglet/media/drivers/pyodide_js/__init__.py +8 -0
- pyglet/media/drivers/pyodide_js/adaptation.py +288 -0
- pyglet/media/drivers/xaudio2/adaptation.py +3 -3
- pyglet/media/player.py +276 -193
- pyglet/media/player_worker_thread.py +1 -1
- pyglet/model/__init__.py +39 -29
- pyglet/model/codecs/base.py +4 -4
- pyglet/model/codecs/gltf.py +3 -3
- pyglet/model/codecs/obj.py +71 -43
- pyglet/resource.py +129 -78
- pyglet/shapes.py +147 -177
- pyglet/sprite.py +47 -164
- pyglet/text/__init__.py +44 -54
- pyglet/text/caret.py +12 -7
- pyglet/text/document.py +19 -17
- pyglet/text/formats/html.py +2 -2
- pyglet/text/formats/structured.py +10 -40
- pyglet/text/layout/__init__.py +20 -13
- pyglet/text/layout/base.py +176 -287
- pyglet/text/layout/incremental.py +9 -10
- pyglet/text/layout/scrolling.py +7 -95
- pyglet/window/__init__.py +183 -172
- pyglet/window/cocoa/__init__.py +62 -51
- pyglet/window/cocoa/pyglet_delegate.py +2 -25
- pyglet/window/cocoa/pyglet_view.py +9 -8
- pyglet/window/dialog/__init__.py +184 -0
- pyglet/window/dialog/base.py +99 -0
- pyglet/window/dialog/darwin.py +121 -0
- pyglet/window/dialog/linux.py +72 -0
- pyglet/window/dialog/windows.py +194 -0
- pyglet/window/emscripten/__init__.py +779 -0
- pyglet/window/headless/__init__.py +44 -28
- pyglet/window/key.py +2 -0
- pyglet/window/mouse.py +2 -2
- pyglet/window/wayland/__init__.py +377 -0
- pyglet/window/win32/__init__.py +101 -46
- pyglet/window/xlib/__init__.py +104 -66
- {pyglet-2.1.12.dist-info → pyglet-3.0.dev1.dist-info}/METADATA +2 -3
- pyglet-3.0.dev1.dist-info/RECORD +322 -0
- {pyglet-2.1.12.dist-info → pyglet-3.0.dev1.dist-info}/WHEEL +1 -1
- pyglet/gl/__init__.py +0 -208
- pyglet/gl/base.py +0 -499
- pyglet/gl/cocoa.py +0 -309
- pyglet/gl/gl.py +0 -4625
- pyglet/gl/gl.pyi +0 -2320
- pyglet/gl/gl_compat.pyi +0 -3097
- pyglet/gl/gl_info.py +0 -190
- pyglet/gl/headless.py +0 -166
- pyglet/gl/wgl_info.py +0 -36
- pyglet/gl/wglext_nv.py +0 -1096
- pyglet/gl/win32.py +0 -268
- pyglet/gl/xlib.py +0 -295
- pyglet/image/buffer.py +0 -274
- pyglet/image/codecs/s3tc.py +0 -354
- pyglet/libs/x11/xrandr.py +0 -166
- pyglet-2.1.12.dist-info/RECORD +0 -234
- /pyglet/{libs/wayland → graphics/api/gl/cocoa}/__init__.py +0 -0
- /pyglet/libs/{egl → linux/egl}/egl.py +0 -0
- /pyglet/libs/{egl → linux/egl}/lib.py +0 -0
- /pyglet/libs/{ioctl.py → linux/ioctl.py} +0 -0
- /pyglet/libs/{wayland → linux/wayland}/gbm.py +0 -0
- /pyglet/libs/{x11 → linux/x11}/__init__.py +0 -0
- /pyglet/libs/{x11 → linux/x11}/cursorfont.py +0 -0
- /pyglet/libs/{x11 → linux/x11}/xlib.py +0 -0
- /pyglet/libs/{x11 → linux/x11}/xsync.py +0 -0
- {pyglet-2.1.12.dist-info/licenses → pyglet-3.0.dev1.dist-info}/LICENSE +0 -0
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import ctypes
|
|
2
4
|
import warnings
|
|
3
5
|
|
|
4
|
-
from typing import
|
|
6
|
+
from typing import Optional
|
|
5
7
|
|
|
6
8
|
from pyglet.libs.win32.constants import WM_DEVICECHANGE, DBT_DEVICEARRIVAL, DBT_DEVICEREMOVECOMPLETE, \
|
|
7
9
|
DBT_DEVTYP_DEVICEINTERFACE, DEVICE_NOTIFY_WINDOW_HANDLE
|
|
@@ -55,7 +57,7 @@ def _create_control(object_instance):
|
|
|
55
57
|
elif ctrl_type & dinput.DIDFT_POV:
|
|
56
58
|
control = base.AbsoluteAxis(base.AbsoluteAxis.HAT, 0, 0xffffffff, raw_name)
|
|
57
59
|
else:
|
|
58
|
-
return
|
|
60
|
+
return None
|
|
59
61
|
|
|
60
62
|
control._type = object_instance.dwType
|
|
61
63
|
return control
|
|
@@ -124,17 +126,18 @@ class DirectInputDevice(base.Device):
|
|
|
124
126
|
prop.dwData = 64 * ctypes.sizeof(dinput.DIDATAFORMAT)
|
|
125
127
|
self._device.SetProperty(dinput.DIPROP_BUFFERSIZE, ctypes.byref(prop.diph))
|
|
126
128
|
|
|
127
|
-
def open(self, window=None, exclusive=False):
|
|
129
|
+
def open(self, window: pyglet.window.Window | None=None, exclusive: bool=False) -> None:
|
|
128
130
|
if not self.controls:
|
|
129
131
|
return
|
|
130
132
|
|
|
131
133
|
if window is None:
|
|
132
|
-
# Pick any open window
|
|
133
|
-
# have been created yet.
|
|
134
|
-
window = pyglet.gl._shadow_window
|
|
134
|
+
# Pick any open window or the shadow window if no windows are available.
|
|
135
135
|
for window in pyglet.app.windows:
|
|
136
136
|
break
|
|
137
137
|
|
|
138
|
+
if not window:
|
|
139
|
+
window = pyglet.window._shadow_window # noqa: SLF001
|
|
140
|
+
|
|
138
141
|
flags = dinput.DISCL_BACKGROUND
|
|
139
142
|
if exclusive:
|
|
140
143
|
flags |= dinput.DISCL_EXCLUSIVE
|
|
@@ -215,31 +218,34 @@ class DIDeviceManager(EventDispatcher):
|
|
|
215
218
|
self.registered = False
|
|
216
219
|
self.window = None
|
|
217
220
|
self._devnotify = None
|
|
218
|
-
self.devices:
|
|
221
|
+
self.devices: list[DirectInputDevice] = []
|
|
219
222
|
|
|
220
223
|
if self.register_device_events(skip_warning=True):
|
|
221
224
|
self.set_current_devices()
|
|
222
225
|
|
|
223
|
-
def set_current_devices(self):
|
|
224
|
-
"""Sets all currently discovered devices in the
|
|
225
|
-
|
|
226
|
-
|
|
226
|
+
def set_current_devices(self) -> None:
|
|
227
|
+
"""Sets all currently discovered devices in the device list.
|
|
228
|
+
|
|
229
|
+
.. note:: Be careful when using this, as this creates new device objects. Only to be called on the
|
|
230
|
+
initialization of the manager, and if the window connection event isn't already registered.
|
|
227
231
|
"""
|
|
228
232
|
new_devices, _ = self._get_devices()
|
|
229
233
|
self.devices = new_devices
|
|
230
234
|
|
|
231
|
-
def register_device_events(self, skip_warning=False, window=None):
|
|
235
|
+
def register_device_events(self, skip_warning: bool=False, window: pyglet.window.Window | None=None) -> bool:
|
|
232
236
|
"""Register the first OS Window to receive events of disconnect and connection of devices.
|
|
233
|
-
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
True if events were successfully registered.
|
|
234
240
|
"""
|
|
235
241
|
if not self.registered:
|
|
236
|
-
#
|
|
237
|
-
if
|
|
238
|
-
|
|
239
|
-
|
|
242
|
+
# Pick any open window or the shadow window if no windows are available.
|
|
243
|
+
if window is None:
|
|
244
|
+
for window in pyglet.app.windows:
|
|
245
|
+
break
|
|
246
|
+
|
|
240
247
|
if not window:
|
|
241
|
-
|
|
242
|
-
break
|
|
248
|
+
window = pyglet.window._shadow_window # noqa: SLF001
|
|
243
249
|
|
|
244
250
|
self.window = window
|
|
245
251
|
if self.window is not None:
|
|
@@ -255,9 +261,8 @@ class DIDeviceManager(EventDispatcher):
|
|
|
255
261
|
self.registered = True
|
|
256
262
|
self.window.push_handlers(self)
|
|
257
263
|
return True
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
warnings.warn("DirectInput Device Manager requires a window to receive device connection events.")
|
|
264
|
+
if not skip_warning:
|
|
265
|
+
warnings.warn("DirectInput Device Manager requires a window to receive device connection events.")
|
|
261
266
|
|
|
262
267
|
return False
|
|
263
268
|
|
|
@@ -288,12 +293,13 @@ class DIDeviceManager(EventDispatcher):
|
|
|
288
293
|
|
|
289
294
|
def _get_devices(self, display=None):
|
|
290
295
|
"""Enumerate all the devices on the system.
|
|
291
|
-
Returns two values: new devices, missing devices
|
|
296
|
+
Returns two values: new devices, missing devices
|
|
297
|
+
"""
|
|
292
298
|
_missing_devices = list(self.devices)
|
|
293
299
|
_new_devices = []
|
|
294
300
|
_xinput_devices = []
|
|
295
301
|
|
|
296
|
-
if not pyglet.options
|
|
302
|
+
if not pyglet.options.win32_disable_xinput:
|
|
297
303
|
try:
|
|
298
304
|
from pyglet.input.win32.xinput import get_xinput_guids
|
|
299
305
|
_xinput_devices = get_xinput_guids()
|
|
@@ -359,7 +365,7 @@ class DIControllerManager(ControllerManager):
|
|
|
359
365
|
|
|
360
366
|
def __init__(self, display=None):
|
|
361
367
|
self._display = display
|
|
362
|
-
self._controllers:
|
|
368
|
+
self._controllers: dict[DirectInputDevice, base.Controller] = {}
|
|
363
369
|
|
|
364
370
|
for device in _di_manager.devices:
|
|
365
371
|
self._add_controller(device)
|
|
@@ -398,7 +404,7 @@ def get_devices(display=None):
|
|
|
398
404
|
_devices = []
|
|
399
405
|
_xinput_devices = []
|
|
400
406
|
|
|
401
|
-
if not pyglet.options
|
|
407
|
+
if not pyglet.options.win32_disable_xinput:
|
|
402
408
|
try:
|
|
403
409
|
from pyglet.input.win32.xinput import get_xinput_guids
|
|
404
410
|
_xinput_devices = get_xinput_guids()
|
|
@@ -429,9 +435,8 @@ def _create_controller(device):
|
|
|
429
435
|
if device._type in (dinput.DI8DEVTYPE_JOYSTICK, dinput.DI8DEVTYPE_1STPERSON, dinput.DI8DEVTYPE_GAMEPAD):
|
|
430
436
|
if mapping is not None:
|
|
431
437
|
return base.Controller(device, mapping)
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
f"has no controller mappings. Update the mappings in the Controller DB.")
|
|
438
|
+
warnings.warn(f"Warning: {device} (GUID: {device.get_guid()}) "
|
|
439
|
+
f"has no controller mappings. Update the mappings in the Controller DB.")
|
|
435
440
|
|
|
436
441
|
|
|
437
442
|
def _create_joystick(device):
|
pyglet/input/win32/xinput.py
CHANGED
|
@@ -6,13 +6,12 @@ from ctypes.wintypes import DWORD, LONG, LPCWSTR, SHORT, ULONG, WORD
|
|
|
6
6
|
|
|
7
7
|
import pyglet
|
|
8
8
|
from pyglet.event import EventDispatcher
|
|
9
|
-
from pyglet.input.base import AbsoluteAxis, Button, Controller, ControllerManager, Device
|
|
9
|
+
from pyglet.input.base import AbsoluteAxis, Button, Controller, ControllerManager, Device, Sign
|
|
10
10
|
from pyglet.libs.win32 import _ole32 as ole32
|
|
11
11
|
from pyglet.libs.win32 import _oleaut32 as oleaut32
|
|
12
12
|
from pyglet.libs.win32 import com
|
|
13
13
|
from pyglet.libs.win32.constants import CLSCTX_INPROC_SERVER
|
|
14
14
|
from pyglet.libs.win32.types import BYTE, VARIANT
|
|
15
|
-
from pyglet.math import Vec2
|
|
16
15
|
|
|
17
16
|
for library_name in ['xinput1_4', 'xinput9_1_0', 'xinput1_3']:
|
|
18
17
|
try:
|
|
@@ -360,8 +359,8 @@ controller_api_to_pyglet = {
|
|
|
360
359
|
XINPUT_GAMEPAD_START: "start",
|
|
361
360
|
XINPUT_GAMEPAD_BACK: "back",
|
|
362
361
|
XINPUT_GAMEPAD_GUIDE: "guide",
|
|
363
|
-
XINPUT_GAMEPAD_LEFT_THUMB: "
|
|
364
|
-
XINPUT_GAMEPAD_RIGHT_THUMB: "
|
|
362
|
+
XINPUT_GAMEPAD_LEFT_THUMB: "leftthumb",
|
|
363
|
+
XINPUT_GAMEPAD_RIGHT_THUMB: "rightthumb",
|
|
365
364
|
XINPUT_GAMEPAD_LEFT_SHOULDER: "leftshoulder",
|
|
366
365
|
XINPUT_GAMEPAD_RIGHT_SHOULDER: "rightshoulder",
|
|
367
366
|
XINPUT_GAMEPAD_A: "a",
|
|
@@ -396,17 +395,17 @@ class XInputDevice(Device):
|
|
|
396
395
|
'guide': Button('guide'),
|
|
397
396
|
'leftshoulder': Button('leftshoulder'),
|
|
398
397
|
'rightshoulder': Button('rightshoulder'),
|
|
399
|
-
'
|
|
400
|
-
'
|
|
398
|
+
'leftthumb': Button('leftthumb'),
|
|
399
|
+
'rightthumb': Button('rightthumb'),
|
|
401
400
|
'dpup': Button('dpup'),
|
|
402
401
|
'dpdown': Button('dpdown'),
|
|
403
402
|
'dpleft': Button('dpleft'),
|
|
404
403
|
'dpright': Button('dpright'),
|
|
405
404
|
|
|
406
405
|
'leftx': AbsoluteAxis('leftx', -32768, 32768),
|
|
407
|
-
'lefty': AbsoluteAxis('lefty', -32768, 32768),
|
|
406
|
+
'lefty': AbsoluteAxis('lefty', -32768, 32768, inverted=True),
|
|
408
407
|
'rightx': AbsoluteAxis('rightx', -32768, 32768),
|
|
409
|
-
'righty': AbsoluteAxis('righty', -32768, 32768),
|
|
408
|
+
'righty': AbsoluteAxis('righty', -32768, 32768, inverted=True),
|
|
410
409
|
'lefttrigger': AbsoluteAxis('lefttrigger', 0, 255),
|
|
411
410
|
'righttrigger': AbsoluteAxis('righttrigger', 0, 255)
|
|
412
411
|
}
|
|
@@ -546,68 +545,19 @@ _device_manager = XInputDeviceManager()
|
|
|
546
545
|
|
|
547
546
|
class XInputController(Controller):
|
|
548
547
|
|
|
548
|
+
device: XInputDevice
|
|
549
|
+
|
|
549
550
|
def _initialize_controls(self):
|
|
550
551
|
|
|
551
552
|
for button_name in controller_api_to_pyglet.values():
|
|
552
553
|
control = self.device.controls[button_name]
|
|
553
554
|
self._button_controls.append(control)
|
|
554
|
-
self.
|
|
555
|
+
self._bind_button_control(control, button_name)
|
|
555
556
|
|
|
556
557
|
for axis_name in "leftx", "lefty", "rightx", "righty", "lefttrigger", "righttrigger":
|
|
557
558
|
control = self.device.controls[axis_name]
|
|
558
559
|
self._axis_controls.append(control)
|
|
559
|
-
self.
|
|
560
|
-
|
|
561
|
-
def _add_axis(self, control, name):
|
|
562
|
-
tscale = 1.0 / (control.max - control.min)
|
|
563
|
-
scale = 2.0 / (control.max - control.min)
|
|
564
|
-
bias = -1.0 - control.min * scale
|
|
565
|
-
|
|
566
|
-
if name in ("lefttrigger", "righttrigger"):
|
|
567
|
-
@control.event
|
|
568
|
-
def on_change(value):
|
|
569
|
-
normalized_value = value * tscale
|
|
570
|
-
setattr(self, name, normalized_value)
|
|
571
|
-
self.dispatch_event('on_trigger_motion', self, name, normalized_value)
|
|
572
|
-
|
|
573
|
-
elif name in ("leftx", "lefty"):
|
|
574
|
-
@control.event
|
|
575
|
-
def on_change(value):
|
|
576
|
-
normalized_value = value * scale + bias
|
|
577
|
-
setattr(self, name, normalized_value)
|
|
578
|
-
self.leftanalog = Vec2(self.leftx, self.lefty)
|
|
579
|
-
self.dispatch_event('on_stick_motion', self, "leftstick", self.leftanalog)
|
|
580
|
-
|
|
581
|
-
elif name in ("rightx", "righty"):
|
|
582
|
-
@control.event
|
|
583
|
-
def on_change(value):
|
|
584
|
-
normalized_value = value * scale + bias
|
|
585
|
-
setattr(self, name, normalized_value)
|
|
586
|
-
self.rightanalog = Vec2(self.rightx, self.righty)
|
|
587
|
-
self.dispatch_event('on_stick_motion', self, "rightstick", self.rightanalog)
|
|
588
|
-
|
|
589
|
-
def _add_button(self, control, name):
|
|
590
|
-
|
|
591
|
-
if name in ("dpleft", "dpright", "dpup", "dpdown"):
|
|
592
|
-
@control.event
|
|
593
|
-
def on_change(value):
|
|
594
|
-
target, bias = {'dpleft': ('dpadx', -1.0), 'dpright': ('dpadx', 1.0),
|
|
595
|
-
'dpdown': ('dpady', -1.0), 'dpup': ('dpady', 1.0)}[name]
|
|
596
|
-
setattr(self, target, bias * value)
|
|
597
|
-
self.dpad = Vec2(self.dpadx, self.dpady)
|
|
598
|
-
self.dispatch_event('on_dpad_motion', self, self.dpad)
|
|
599
|
-
else:
|
|
600
|
-
@control.event
|
|
601
|
-
def on_change(value):
|
|
602
|
-
setattr(self, name, value)
|
|
603
|
-
|
|
604
|
-
@control.event
|
|
605
|
-
def on_press():
|
|
606
|
-
self.dispatch_event('on_button_press', self, name)
|
|
607
|
-
|
|
608
|
-
@control.event
|
|
609
|
-
def on_release():
|
|
610
|
-
self.dispatch_event('on_button_release', self, name)
|
|
560
|
+
self._bind_axis_control(control, axis_name, Sign.DEFAULT)
|
|
611
561
|
|
|
612
562
|
def rumble_play_weak(self, strength=1.0, duration=0.5):
|
|
613
563
|
self.device.vibration.wRightMotorSpeed = int(max(min(1.0, strength), 0) * 0xFFFF)
|
pyglet/lib.py
CHANGED
|
@@ -15,12 +15,12 @@ import ctypes.util
|
|
|
15
15
|
import pyglet
|
|
16
16
|
from typing import NoReturn, Callable, Any
|
|
17
17
|
|
|
18
|
-
_debug_lib = pyglet.options
|
|
19
|
-
_debug_trace = pyglet.options
|
|
18
|
+
_debug_lib = pyglet.options.debug_lib
|
|
19
|
+
_debug_trace = pyglet.options.debug_trace
|
|
20
20
|
|
|
21
21
|
_is_pyglet_doc_run = getattr(sys, "is_pyglet_doc_run", False)
|
|
22
22
|
|
|
23
|
-
if pyglet.options
|
|
23
|
+
if pyglet.options.search_local_libs:
|
|
24
24
|
script_path = pyglet.resource.get_script_home()
|
|
25
25
|
cwd = os.getcwd()
|
|
26
26
|
_local_lib_paths = [script_path, os.path.join(script_path, 'lib'), os.path.join(cwd, 'lib')]
|
pyglet/libs/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ When documenting these modules:
|
|
|
13
13
|
|
|
14
14
|
Simple docstrings with minimal formatting are best because:
|
|
15
15
|
|
|
16
|
-
1. No web doc is built for pyglet.
|
|
16
|
+
1. No web doc is built for pyglet.libs
|
|
17
17
|
2. The docstrings will be used to debug complex platform issues
|
|
18
18
|
3. IDEs mangle formatting in any hover tooltips while debugging
|
|
19
19
|
"""
|
pyglet/{gl → libs/darwin}/agl.py
RENAMED
|
@@ -5,7 +5,7 @@ Do not modify this file.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from ctypes import Structure, POINTER, c_int, c_long, c_ubyte, c_ulong
|
|
8
|
-
from pyglet.gl.lib import link_AGL as _link_function
|
|
8
|
+
from pyglet.graphics.api.gl.lib import link_AGL as _link_function
|
|
9
9
|
|
|
10
10
|
if not _link_function:
|
|
11
11
|
raise ImportError('AGL framework is not available.')
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
# POSSIBILITY OF SUCH DAMAGE.
|
|
31
31
|
from contextlib import contextmanager
|
|
32
32
|
|
|
33
|
-
from .runtime import objc, send_message, send_super, AutoReleasePool
|
|
33
|
+
from .runtime import objc, send_message, send_super, AutoReleasePool, ObjCBlock
|
|
34
34
|
from .runtime import get_selector
|
|
35
35
|
from .runtime import ObjCClass, ObjCInstance, ObjCSubclass
|
|
36
36
|
|
|
37
37
|
from .cocoatypes import *
|
|
38
38
|
from .cocoalibs import *
|
|
39
|
-
|
|
39
|
+
from .cocoahelpers import *
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pyglet.libs.darwin.cocoapy.runtime import ObjCInstance, ObjCClass
|
|
6
|
+
|
|
7
|
+
NSSet = ObjCClass('NSSet')
|
|
8
|
+
NSNull = ObjCClass('NSNull')
|
|
9
|
+
NSString = ObjCClass("NSString")
|
|
10
|
+
NSData = ObjCClass("NSData")
|
|
11
|
+
NSNumber = ObjCClass("NSNumber")
|
|
12
|
+
NSMutableArray = ObjCClass("NSMutableArray")
|
|
13
|
+
NSArray = ObjCClass("NSArray")
|
|
14
|
+
NSDictionary = ObjCClass("NSDictionary")
|
|
15
|
+
NSMutableDictionary = ObjCClass("NSMutableDictionary")
|
|
16
|
+
|
|
17
|
+
def pystr_to_ns(value: str):
|
|
18
|
+
return NSString.stringWithUTF8String_(value.encode("utf-8"))
|
|
19
|
+
|
|
20
|
+
def pybool_to_ns(value: bool):
|
|
21
|
+
return NSNumber.numberWithBool_(value)
|
|
22
|
+
|
|
23
|
+
def pyint_to_ns(value: int):
|
|
24
|
+
return NSNumber.numberWithInt_(value)
|
|
25
|
+
|
|
26
|
+
def pyfloat_to_ns(value: float):
|
|
27
|
+
return NSNumber.numberWithDouble_(value)
|
|
28
|
+
|
|
29
|
+
def pynone_to_ns(_value):
|
|
30
|
+
return NSNull.null()
|
|
31
|
+
|
|
32
|
+
def _iterable_to_mutable_array(value: list | tuple):
|
|
33
|
+
arr = NSMutableArray.array()
|
|
34
|
+
for item in value:
|
|
35
|
+
arr.addObject_(py_to_ns(item))
|
|
36
|
+
return arr
|
|
37
|
+
|
|
38
|
+
def pylist_to_ns(value: list) -> NSMutableArray:
|
|
39
|
+
"""Convert Python list to NSMutableArray."""
|
|
40
|
+
return _iterable_to_mutable_array(value)
|
|
41
|
+
|
|
42
|
+
def pytuple_to_ns(value: tuple) -> NSArray:
|
|
43
|
+
"""Convert Python tuple to NSArray (immutable)."""
|
|
44
|
+
mutable = _iterable_to_mutable_array(value)
|
|
45
|
+
return NSArray.arrayWithArray_(mutable)
|
|
46
|
+
|
|
47
|
+
def pydict_to_ns(value: dict, mutable: bool=True) -> NSMutableDictionary | NSDictionary:
|
|
48
|
+
"""Convert Python dict to NSMutableDictionary."""
|
|
49
|
+
d = NSMutableDictionary.dictionary()
|
|
50
|
+
for k, v in value.items():
|
|
51
|
+
ns_key = py_to_ns(k)
|
|
52
|
+
ns_val = py_to_ns(v)
|
|
53
|
+
d.setObject_forKey_(ns_val, ns_key)
|
|
54
|
+
if not mutable:
|
|
55
|
+
return NSDictionary.dictionaryWithDictionary_(d)
|
|
56
|
+
return d
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
_CONVERTERS = {
|
|
60
|
+
str: pystr_to_ns,
|
|
61
|
+
bool: pybool_to_ns,
|
|
62
|
+
int: pyint_to_ns,
|
|
63
|
+
float: pyfloat_to_ns,
|
|
64
|
+
list: pylist_to_ns,
|
|
65
|
+
tuple: pytuple_to_ns,
|
|
66
|
+
dict: pydict_to_ns,
|
|
67
|
+
type(None): pynone_to_ns,
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
def py_to_ns(value: Any) -> ObjCInstance:
|
|
71
|
+
"""General Python to NS object converter.
|
|
72
|
+
|
|
73
|
+
Should be used whenever interacting with AppKit, Cocoa, or any other NS-related functions.
|
|
74
|
+
"""
|
|
75
|
+
if isinstance(value, ObjCInstance):
|
|
76
|
+
return value
|
|
77
|
+
|
|
78
|
+
t = type(value)
|
|
79
|
+
converter = _CONVERTERS.get(t)
|
|
80
|
+
|
|
81
|
+
if converter:
|
|
82
|
+
return converter(value)
|
|
83
|
+
|
|
84
|
+
raise TypeError(f"Cannot convert Python type {t} to NS object")
|
|
85
|
+
|
|
86
|
+
# ===== Converting from NS to Python
|
|
87
|
+
def nsstr_to_py(nsobj: NSString) -> str:
|
|
88
|
+
return nsobj.UTF8String().decode("utf-8")
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def nsnum_to_py(nsobj: NSNumber) -> int | float:
|
|
92
|
+
"""Converting from NSNumber
|
|
93
|
+
|
|
94
|
+
NSNumber can represent bool, int, or float internally"""
|
|
95
|
+
t = nsobj.objCType().decode()
|
|
96
|
+
|
|
97
|
+
if t == 'c': # char / BOOL
|
|
98
|
+
return bool(nsobj.boolValue())
|
|
99
|
+
elif t in ('i', 'l', 'q', 's'):
|
|
100
|
+
return int(nsobj.intValue())
|
|
101
|
+
elif t in ('f', 'd'):
|
|
102
|
+
return float(nsobj.doubleValue())
|
|
103
|
+
|
|
104
|
+
return nsobj.doubleValue()
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def nsarray_to_py(nsobj: NSArray) -> list:
|
|
108
|
+
py_list = []
|
|
109
|
+
for i in range(nsobj.count()):
|
|
110
|
+
item = nsobj.objectAtIndex_(i)
|
|
111
|
+
py_list.append(ns_to_py(item))
|
|
112
|
+
return py_list
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def nsmutarray_to_py(nsobj: NSMutableArray):
|
|
116
|
+
return nsarray_to_py(nsobj)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def nsdict_to_py(nsobj: NSDictionary):
|
|
120
|
+
py_dict = {}
|
|
121
|
+
|
|
122
|
+
# NSDictionary requires enumerating keys
|
|
123
|
+
keys = nsobj.allKeys()
|
|
124
|
+
for i in range(keys.count()):
|
|
125
|
+
key = keys.objectAtIndex_(i)
|
|
126
|
+
val = nsobj.objectForKey_(key)
|
|
127
|
+
|
|
128
|
+
py_key = ns_to_py(key)
|
|
129
|
+
py_val = ns_to_py(val)
|
|
130
|
+
|
|
131
|
+
py_dict[py_key] = py_val
|
|
132
|
+
|
|
133
|
+
return py_dict
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
# NSMutableDictionary handled the same
|
|
137
|
+
def nsmutdict_to_py(nsobj: NSMutableDictionary):
|
|
138
|
+
return nsdict_to_py(nsobj)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def nsset_to_py(nsset) -> set:
|
|
142
|
+
"""Convert NSSet or NSFrozenSet to a Python set."""
|
|
143
|
+
py = set()
|
|
144
|
+
enumerator = nsset.objectEnumerator()
|
|
145
|
+
while True:
|
|
146
|
+
obj = enumerator.nextObject()
|
|
147
|
+
if obj is None:
|
|
148
|
+
break
|
|
149
|
+
py.add(ns_to_py(obj))
|
|
150
|
+
return py
|
|
151
|
+
|
|
152
|
+
def nsnull_to_py(_nsnull):
|
|
153
|
+
return None
|
|
154
|
+
|
|
155
|
+
_NS_TO_PY_CONVERTERS = {
|
|
156
|
+
NSString: nsstr_to_py,
|
|
157
|
+
NSNumber: nsnum_to_py,
|
|
158
|
+
NSArray: nsarray_to_py,
|
|
159
|
+
NSMutableArray: nsmutarray_to_py,
|
|
160
|
+
NSDictionary: nsdict_to_py,
|
|
161
|
+
NSMutableDictionary: nsmutdict_to_py,
|
|
162
|
+
NSNull: nsnull_to_py,
|
|
163
|
+
NSSet: nsset_to_py,
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def ns_to_py(nsobj: ObjCInstance):
|
|
168
|
+
"""Convert NS object to Python, recursively."""
|
|
169
|
+
if nsobj is None:
|
|
170
|
+
return None
|
|
171
|
+
|
|
172
|
+
if not isinstance(nsobj, ObjCInstance):
|
|
173
|
+
raise Exception(f"{nsobj} Not an ObjCInstance")
|
|
174
|
+
|
|
175
|
+
for cls, converter in _NS_TO_PY_CONVERTERS.items():
|
|
176
|
+
# NS Objects have many different variations of the same type.
|
|
177
|
+
# For example a string can be NSTaggedPointerString, __NSCFString, NSMutableString, NSString, etc..
|
|
178
|
+
if nsobj.isKindOfClass_(cls):
|
|
179
|
+
return converter(nsobj)
|
|
180
|
+
|
|
181
|
+
return nsobj
|
|
@@ -24,6 +24,7 @@ CFURLRef = c_void_p
|
|
|
24
24
|
CFStringRef = c_void_p
|
|
25
25
|
CFURLPathStyle = c_int
|
|
26
26
|
CFDataRef = c_void_p
|
|
27
|
+
CTRunRef = c_void_p
|
|
27
28
|
|
|
28
29
|
cf.CFStringCreateWithCString.restype = c_void_p
|
|
29
30
|
cf.CFStringCreateWithCString.argtypes = [CFAllocatorRef, c_char_p, CFStringEncoding]
|
|
@@ -46,6 +47,9 @@ cf.CFStringGetTypeID.argtypes = []
|
|
|
46
47
|
cf.CFAttributedStringCreate.restype = c_void_p
|
|
47
48
|
cf.CFAttributedStringCreate.argtypes = [CFAllocatorRef, c_void_p, c_void_p]
|
|
48
49
|
|
|
50
|
+
cf.CFShow.restype = None
|
|
51
|
+
cf.CFShow.argtypes = [c_void_p]
|
|
52
|
+
|
|
49
53
|
# Core Foundation type to Python type conversion functions
|
|
50
54
|
|
|
51
55
|
def CFSTR(string: str):
|
|
@@ -649,6 +653,18 @@ ct.CTFontCopyFamilyName.argtypes = [c_void_p]
|
|
|
649
653
|
ct.CTFontCopyFullName.restype = c_void_p
|
|
650
654
|
ct.CTFontCopyFullName.argtypes = [c_void_p]
|
|
651
655
|
|
|
656
|
+
ct.CTFontCopyPostScriptName.restype = c_void_p
|
|
657
|
+
ct.CTFontCopyPostScriptName.argtypes = [c_void_p]
|
|
658
|
+
|
|
659
|
+
ct.CTFontCreateUIFontForLanguage.restype = c_void_p
|
|
660
|
+
ct.CTFontCreateUIFontForLanguage.argtypes = [c_uint32, c_double, c_void_p]
|
|
661
|
+
|
|
662
|
+
ct.CTFontCreateCopyWithSymbolicTraits.restype = c_void_p
|
|
663
|
+
ct.CTFontCreateCopyWithSymbolicTraits.argtypes = [c_void_p, CGFloat, c_void_p, c_uint32, c_uint32]
|
|
664
|
+
|
|
665
|
+
ct.CTFontCreateCopyWithAttributes.restype = c_void_p
|
|
666
|
+
ct.CTFontCreateCopyWithAttributes.argtypes = [c_void_p, c_double, c_void_p, c_void_p]
|
|
667
|
+
|
|
652
668
|
ct.CTFontCreateWithFontDescriptor.restype = c_void_p
|
|
653
669
|
ct.CTFontCreateWithFontDescriptor.argtypes = [c_void_p, CGFloat, c_void_p]
|
|
654
670
|
|
|
@@ -667,6 +683,21 @@ ct.CTFontDescriptorCreateMatchingFontDescriptor.argtypes = [c_void_p, c_void_p]
|
|
|
667
683
|
ct.CTFontCopyTraits.restype = c_void_p
|
|
668
684
|
ct.CTFontCopyTraits.argtypes = [c_void_p]
|
|
669
685
|
|
|
686
|
+
ct.CTLineGetGlyphRuns.restype = c_void_p # CFArrayRef
|
|
687
|
+
ct.CTLineGetGlyphRuns.argtypes = [c_void_p] # CTLineRef
|
|
688
|
+
|
|
689
|
+
ct.CTRunGetGlyphCount.restype = CFIndex
|
|
690
|
+
ct.CTRunGetGlyphCount.argtypes = [CTRunRef]
|
|
691
|
+
|
|
692
|
+
ct.CTRunGetGlyphs.restype = None
|
|
693
|
+
ct.CTRunGetGlyphs.argtypes = [CTRunRef, CFRange, POINTER(CGGlyph)]
|
|
694
|
+
|
|
695
|
+
ct.CTRunGetPositions.restype = None
|
|
696
|
+
ct.CTRunGetPositions.argtypes = [CTRunRef, CFRange, POINTER(CGPoint)]
|
|
697
|
+
|
|
698
|
+
ct.CTRunGetAttributes.restype = c_void_p
|
|
699
|
+
ct.CTRunGetAttributes.argtypes = [CTRunRef]
|
|
700
|
+
|
|
670
701
|
kCTFontURLAttribute = c_void_p.in_dll(ct, 'kCTFontURLAttribute')
|
|
671
702
|
|
|
672
703
|
######################################################################
|
|
@@ -46,6 +46,10 @@ NSZoneEncoding = b'{_NSZone=}'
|
|
|
46
46
|
# from /System/Library/Frameworks/Foundation.framework/Headers/NSGeometry.h
|
|
47
47
|
class NSPoint(Structure):
|
|
48
48
|
_fields_ = [ ("x", CGFloat), ("y", CGFloat) ]
|
|
49
|
+
|
|
50
|
+
def __repr__(self):
|
|
51
|
+
return f"{self.__class__.__name__}(x={self.x}, y={self.y})"
|
|
52
|
+
|
|
49
53
|
CGPoint = NSPoint
|
|
50
54
|
|
|
51
55
|
class NSSize(Structure):
|
|
@@ -83,3 +87,26 @@ NSZeroPoint = NSPoint(0,0)
|
|
|
83
87
|
|
|
84
88
|
CFTypeID = c_ulong
|
|
85
89
|
CFNumberType = c_uint32
|
|
90
|
+
|
|
91
|
+
_dispose_helper_cb = CFUNCTYPE(c_void_p, c_void_p)
|
|
92
|
+
_copy_helper_cb = CFUNCTYPE(c_void_p, c_void_p, c_void_p)
|
|
93
|
+
|
|
94
|
+
class Block_descriptor_1(Structure):
|
|
95
|
+
_fields_ = [
|
|
96
|
+
("reserved", c_ulong),
|
|
97
|
+
("Block_size", c_ulong),
|
|
98
|
+
("copy_helper", _copy_helper_cb), # Optional
|
|
99
|
+
("dispose_helper", _dispose_helper_cb), # Optional
|
|
100
|
+
("signature", c_char_p),
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class Block_literal_1(Structure):
|
|
105
|
+
_fields_ = [
|
|
106
|
+
("isa", c_void_p), # address to ConcreteStack/ConcreteGlobal
|
|
107
|
+
("flags", c_int),
|
|
108
|
+
("reserved", c_int),
|
|
109
|
+
("invoke", c_void_p), # Invoke function
|
|
110
|
+
("descriptor", Block_descriptor_1),
|
|
111
|
+
]
|
|
112
|
+
|