pyglet 2.1.5__py3-none-any.whl → 2.1.8__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 +27 -42
- pyglet/app/base.py +2 -2
- pyglet/clock.py +1 -1
- pyglet/display/base.py +31 -21
- pyglet/display/cocoa.py +25 -1
- pyglet/display/headless.py +1 -1
- pyglet/display/win32.py +134 -18
- pyglet/display/xlib.py +285 -70
- pyglet/event.py +17 -1
- pyglet/experimental/README.md +1 -1
- pyglet/experimental/jobs.py +1 -1
- pyglet/experimental/multitexture_sprite.py +2 -2
- pyglet/font/__init__.py +1 -1
- pyglet/font/base.py +8 -5
- pyglet/font/dwrite/__init__.py +13 -8
- pyglet/font/dwrite/dwrite_lib.py +1 -1
- pyglet/font/user.py +1 -1
- pyglet/gl/base.py +8 -4
- pyglet/gl/cocoa.py +4 -0
- pyglet/gl/gl.py +4 -3
- pyglet/gl/gl.pyi +2320 -0
- pyglet/gl/gl_compat.py +7 -18
- pyglet/gl/gl_compat.pyi +3097 -0
- pyglet/gl/xlib.py +24 -0
- pyglet/graphics/shader.py +34 -20
- pyglet/graphics/vertexbuffer.py +1 -1
- pyglet/gui/frame.py +2 -2
- pyglet/gui/widgets.py +1 -1
- pyglet/image/__init__.py +3 -3
- pyglet/image/buffer.py +3 -3
- pyglet/input/base.py +8 -8
- pyglet/input/linux/evdev.py +1 -1
- pyglet/libs/darwin/cocoapy/cocoalibs.py +3 -1
- pyglet/libs/win32/__init__.py +12 -0
- pyglet/libs/win32/constants.py +4 -0
- pyglet/libs/win32/types.py +97 -0
- pyglet/libs/x11/xrandr.py +166 -0
- pyglet/libs/x11/xrender.py +43 -0
- pyglet/libs/x11/xsync.py +43 -0
- pyglet/math.py +40 -49
- pyglet/media/buffered_logger.py +1 -1
- pyglet/media/codecs/ffmpeg.py +18 -34
- pyglet/media/codecs/gstreamer.py +3 -3
- pyglet/media/codecs/pyogg.py +1 -1
- pyglet/media/codecs/wave.py +6 -0
- pyglet/media/codecs/wmf.py +33 -7
- pyglet/media/devices/win32.py +1 -1
- pyglet/media/drivers/base.py +1 -1
- pyglet/media/drivers/directsound/interface.py +4 -0
- pyglet/media/drivers/listener.py +2 -2
- pyglet/media/drivers/xaudio2/interface.py +6 -2
- pyglet/media/drivers/xaudio2/lib_xaudio2.py +1 -1
- pyglet/media/instrumentation.py +2 -2
- pyglet/media/player.py +2 -2
- pyglet/media/player_worker_thread.py +1 -1
- pyglet/media/synthesis.py +1 -1
- pyglet/model/codecs/gltf.py +1 -1
- pyglet/shapes.py +25 -24
- pyglet/sprite.py +1 -1
- pyglet/text/caret.py +44 -5
- pyglet/text/layout/base.py +3 -3
- pyglet/util.py +1 -1
- pyglet/window/__init__.py +54 -14
- pyglet/window/cocoa/__init__.py +27 -0
- pyglet/window/mouse.py +11 -1
- pyglet/window/win32/__init__.py +40 -14
- pyglet/window/xlib/__init__.py +21 -7
- {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/METADATA +1 -1
- {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/RECORD +71 -67
- {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/LICENSE +0 -0
- {pyglet-2.1.5.dist-info → pyglet-2.1.8.dist-info}/WHEEL +0 -0
pyglet/gl/xlib.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import warnings
|
|
4
|
+
from _ctypes import _Pointer
|
|
4
5
|
from ctypes import POINTER, byref, c_int, c_uint, cast
|
|
5
6
|
from typing import TYPE_CHECKING, NoReturn
|
|
6
7
|
|
|
@@ -13,6 +14,8 @@ from pyglet.gl import lib
|
|
|
13
14
|
from pyglet.gl.base import Config, DisplayConfig, Context
|
|
14
15
|
|
|
15
16
|
from pyglet.display.xlib import XlibCanvas
|
|
17
|
+
from pyglet.libs.x11 import xlib
|
|
18
|
+
from pyglet.libs.x11.xrender import XRenderFindVisualFormat
|
|
16
19
|
|
|
17
20
|
if TYPE_CHECKING:
|
|
18
21
|
from pyglet.libs.x11.xlib import Display
|
|
@@ -52,6 +55,10 @@ class XlibConfig(Config): # noqa: D101
|
|
|
52
55
|
|
|
53
56
|
result = [XlibDisplayConfig(canvas, info, c, self) for c in configs]
|
|
54
57
|
|
|
58
|
+
# If we intend to have a transparent framebuffer.
|
|
59
|
+
if self.transparent_framebuffer:
|
|
60
|
+
result = [fb_cf for fb_cf in result if fb_cf.transparent]
|
|
61
|
+
|
|
55
62
|
# Can't free array until all XlibGLConfig's are GC'd. Too much
|
|
56
63
|
# hassle, live with leak. XXX
|
|
57
64
|
# xlib.XFree(configs)
|
|
@@ -102,6 +109,7 @@ class XlibDisplayConfig(DisplayConfig): # noqa: D101
|
|
|
102
109
|
|
|
103
110
|
self.glx_info = info
|
|
104
111
|
self.fbconfig = fbconfig
|
|
112
|
+
self.transparent = False
|
|
105
113
|
|
|
106
114
|
for name, attr in self.attribute_ids.items():
|
|
107
115
|
value = c_int()
|
|
@@ -110,6 +118,22 @@ class XlibDisplayConfig(DisplayConfig): # noqa: D101
|
|
|
110
118
|
if result >= 0:
|
|
111
119
|
setattr(self, name, value.value)
|
|
112
120
|
|
|
121
|
+
# If user intends for a transparent framebuffer, the visual info needs to be
|
|
122
|
+
# queried for it. Even if a config supports alpha_size 8 and depth_size 32, there is no
|
|
123
|
+
# guarantee the visual info supports that same configuration.
|
|
124
|
+
if config.transparent_framebuffer:
|
|
125
|
+
xvi_ptr = glx.glXGetVisualFromFBConfig(canvas.display._display, self.fbconfig) # noqa: SLF001
|
|
126
|
+
if xvi_ptr:
|
|
127
|
+
self.transparent = self._is_visual_transparent(xvi_ptr.contents.visual) # noqa: SLF001
|
|
128
|
+
xlib.XFree(xvi_ptr)
|
|
129
|
+
|
|
130
|
+
def _is_visual_transparent(self, visual: _Pointer[xlib.Visual]) -> bool:
|
|
131
|
+
if not XRenderFindVisualFormat:
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
xrender_format = XRenderFindVisualFormat(self.canvas.display._display, visual)
|
|
135
|
+
return xrender_format and xrender_format.contents.direct.alphaMask != 0
|
|
136
|
+
|
|
113
137
|
def get_visual_info(self) -> glx.XVisualInfo:
|
|
114
138
|
return glx.glXGetVisualFromFBConfig(self.canvas.display._display, self.fbconfig).contents # noqa: SLF001
|
|
115
139
|
|
pyglet/graphics/shader.py
CHANGED
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import re
|
|
4
4
|
import warnings
|
|
5
5
|
import weakref
|
|
6
|
+
from _ctypes import _Pointer, _SimpleCData
|
|
6
7
|
from collections import defaultdict
|
|
7
8
|
from ctypes import (
|
|
8
9
|
POINTER,
|
|
@@ -29,8 +30,6 @@ from ctypes import (
|
|
|
29
30
|
)
|
|
30
31
|
from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, Type, Union
|
|
31
32
|
|
|
32
|
-
from _ctypes import _Pointer, _SimpleCData
|
|
33
|
-
|
|
34
33
|
import pyglet
|
|
35
34
|
from pyglet.gl import Context, GLException, gl, gl_info
|
|
36
35
|
from pyglet.gl.gl import (
|
|
@@ -171,19 +170,19 @@ _uniform_setters: dict[int, tuple[GLDataType, GLFunc, GLFunc, int]] = {
|
|
|
171
170
|
# GL_FLOAT_MAT4x3: glUniformMatrix4x3fv, glProgramUniformMatrix4x3fv,
|
|
172
171
|
|
|
173
172
|
gl.GL_IMAGE_1D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
174
|
-
gl.GL_IMAGE_2D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
175
|
-
gl.GL_IMAGE_2D_RECT: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
176
|
-
gl.GL_IMAGE_3D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
173
|
+
gl.GL_IMAGE_2D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
174
|
+
gl.GL_IMAGE_2D_RECT: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
175
|
+
gl.GL_IMAGE_3D: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
177
176
|
|
|
178
|
-
gl.GL_IMAGE_1D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
179
|
-
gl.GL_IMAGE_2D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
177
|
+
gl.GL_IMAGE_1D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
178
|
+
gl.GL_IMAGE_2D_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
180
179
|
|
|
181
|
-
gl.GL_IMAGE_2D_MULTISAMPLE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
182
|
-
gl.GL_IMAGE_2D_MULTISAMPLE_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
180
|
+
gl.GL_IMAGE_2D_MULTISAMPLE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
181
|
+
gl.GL_IMAGE_2D_MULTISAMPLE_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
183
182
|
|
|
184
|
-
gl.GL_IMAGE_BUFFER: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
183
|
+
gl.GL_IMAGE_BUFFER: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
185
184
|
gl.GL_IMAGE_CUBE: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
186
|
-
gl.GL_IMAGE_CUBE_MAP_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv,
|
|
185
|
+
gl.GL_IMAGE_CUBE_MAP_ARRAY: (gl.GLint, gl.glUniform1iv, gl.glProgramUniform1iv, 1),
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
_attribute_types: dict[int, tuple[int, str]] = {
|
|
@@ -332,8 +331,17 @@ class _UniformArray:
|
|
|
332
331
|
_ptr: CTypesPointer[GLDataType]
|
|
333
332
|
_idx_to_loc: dict[int, int]
|
|
334
333
|
|
|
335
|
-
__slots__ = (
|
|
336
|
-
|
|
334
|
+
__slots__ = (
|
|
335
|
+
'_c_array',
|
|
336
|
+
'_dsa',
|
|
337
|
+
'_gl_getter',
|
|
338
|
+
'_gl_setter',
|
|
339
|
+
'_gl_type',
|
|
340
|
+
'_idx_to_loc',
|
|
341
|
+
'_is_matrix',
|
|
342
|
+
'_ptr',
|
|
343
|
+
'_uniform',
|
|
344
|
+
)
|
|
337
345
|
|
|
338
346
|
def __init__(self, uniform: _Uniform, gl_getter: GLFunc, gl_setter: GLFunc, gl_type: GLDataType, is_matrix: bool,
|
|
339
347
|
dsa: bool) -> None:
|
|
@@ -362,7 +370,7 @@ class _UniformArray:
|
|
|
362
370
|
right location.
|
|
363
371
|
"""
|
|
364
372
|
loc = gl.glGetUniformLocation(self._uniform.program,
|
|
365
|
-
create_string_buffer(f"{self._uniform.name}[{index}]".encode(
|
|
373
|
+
create_string_buffer(f"{self._uniform.name}[{index}]".encode()))
|
|
366
374
|
return loc
|
|
367
375
|
|
|
368
376
|
def _get_array_loc(self, index: int) -> int:
|
|
@@ -471,7 +479,7 @@ class _Uniform:
|
|
|
471
479
|
get: Callable[[], Array[GLDataType] | GLDataType]
|
|
472
480
|
set: Callable[[float], None] | Callable[[Sequence], None]
|
|
473
481
|
|
|
474
|
-
__slots__ = '
|
|
482
|
+
__slots__ = 'count', 'get', 'length', 'location', 'name', 'program', 'set', 'size', 'type'
|
|
475
483
|
|
|
476
484
|
def __init__(self, program: int, name: str, uniform_type: int, size: int, location: int, dsa: bool) -> None:
|
|
477
485
|
self.name = name
|
|
@@ -662,7 +670,7 @@ class UniformBlock:
|
|
|
662
670
|
binding: int
|
|
663
671
|
uniforms: dict[int, tuple[str, GLDataType, int, int]]
|
|
664
672
|
view_cls: type[Structure] | None
|
|
665
|
-
__slots__ = '
|
|
673
|
+
__slots__ = 'binding', 'index', 'name', 'program', 'size', 'uniform_count', 'uniforms', 'view_cls'
|
|
666
674
|
|
|
667
675
|
def __init__(self, program: ShaderProgram, name: str, index: int, size: int, binding: int,
|
|
668
676
|
uniforms: dict[int, tuple[str, GLDataType, int, int]], uniform_count: int) -> None:
|
|
@@ -793,9 +801,15 @@ class UniformBlock:
|
|
|
793
801
|
if part_idx == len(parts) - 1: # The last part is the actual type
|
|
794
802
|
if u_size > 1:
|
|
795
803
|
# If size > 1, treat as an array of type
|
|
796
|
-
|
|
804
|
+
if length > 1:
|
|
805
|
+
current_structure[part_name] = (gl_type * length) * u_size
|
|
806
|
+
else:
|
|
807
|
+
current_structure[part_name] = gl_type * u_size
|
|
797
808
|
else:
|
|
798
|
-
|
|
809
|
+
if length > 1:
|
|
810
|
+
current_structure[part_name] = gl_type * length
|
|
811
|
+
else:
|
|
812
|
+
current_structure[part_name] = gl_type
|
|
799
813
|
|
|
800
814
|
offset_size = offsets[i + 1] - offsets[i]
|
|
801
815
|
c_type_size = sizeof(current_structure[part_name])
|
|
@@ -836,7 +850,7 @@ class UniformBufferObject:
|
|
|
836
850
|
_view_ptr: CTypesPointer[Structure]
|
|
837
851
|
binding: int
|
|
838
852
|
buffer: BufferObject
|
|
839
|
-
__slots__ = '
|
|
853
|
+
__slots__ = '_view_ptr', 'binding', 'buffer', 'view'
|
|
840
854
|
|
|
841
855
|
def __init__(self, view_class: type[Structure], buffer_size: int, binding: int) -> None:
|
|
842
856
|
"""Initialize the Uniform Buffer Object with the specified Structure."""
|
|
@@ -1267,7 +1281,7 @@ class ShaderProgram:
|
|
|
1267
1281
|
_uniforms: dict[str, _Uniform]
|
|
1268
1282
|
_uniform_blocks: dict[str, UniformBlock]
|
|
1269
1283
|
|
|
1270
|
-
__slots__ = '
|
|
1284
|
+
__slots__ = '__weakref__', '_attributes', '_context', '_id', '_uniform_blocks', '_uniforms'
|
|
1271
1285
|
|
|
1272
1286
|
def __init__(self, *shaders: Shader) -> None:
|
|
1273
1287
|
"""Initialize the ShaderProgram using at least two Shader instances."""
|
pyglet/graphics/vertexbuffer.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""OpenGL Buffer Objects.
|
|
2
2
|
|
|
3
|
-
:py:class:`~BufferObject` and a :py:class:`~BackedBufferObject` are
|
|
3
|
+
:py:class:`~BufferObject` and a :py:class:`~BackedBufferObject` are provided.
|
|
4
4
|
The first is a lightweight abstraction over an OpenGL buffer, as created
|
|
5
5
|
with ``glGenBuffers``. The backed buffer object is similar, but provides a
|
|
6
6
|
full mirror of the data in CPU memory. This allows for delayed uploading of
|
pyglet/gui/frame.py
CHANGED
|
@@ -24,7 +24,7 @@ class Frame:
|
|
|
24
24
|
|
|
25
25
|
Args:
|
|
26
26
|
window:
|
|
27
|
-
The SpatialHash will
|
|
27
|
+
The SpatialHash will receive events from this Window.
|
|
28
28
|
Appropriate events will be passed on to all added Widgets.
|
|
29
29
|
enable:
|
|
30
30
|
Whether to enable frame.
|
|
@@ -168,7 +168,7 @@ class MovableFrame(Frame):
|
|
|
168
168
|
|
|
169
169
|
Args:
|
|
170
170
|
window:
|
|
171
|
-
The SpatialHash will
|
|
171
|
+
The SpatialHash will receive events from this Window.
|
|
172
172
|
Appropriate events will be passed on to all added Widgets.
|
|
173
173
|
enable:
|
|
174
174
|
Whether to enable frame.
|
pyglet/gui/widgets.py
CHANGED
|
@@ -601,7 +601,7 @@ class TextEntry(WidgetBase):
|
|
|
601
601
|
self._caret.on_text_motion_select(motion)
|
|
602
602
|
|
|
603
603
|
def on_commit(self, widget: TextEntry, text: str) -> None:
|
|
604
|
-
"""Event: dispatches the current text when
|
|
604
|
+
"""Event: dispatches the current text when committed via Enter/Return key."""
|
|
605
605
|
|
|
606
606
|
|
|
607
607
|
TextEntry.register_event_type('on_commit')
|
pyglet/image/__init__.py
CHANGED
|
@@ -556,7 +556,7 @@ class ImageData(AbstractImage):
|
|
|
556
556
|
Note:
|
|
557
557
|
Conversion to another format is done on the CPU, and can be
|
|
558
558
|
somewhat costly for larger images. Consider performing conversion
|
|
559
|
-
at load time for framerate sensitive
|
|
559
|
+
at load time for framerate sensitive applications.
|
|
560
560
|
"""
|
|
561
561
|
fmt = fmt or self._desired_format
|
|
562
562
|
pitch = pitch or self._current_pitch
|
|
@@ -1201,7 +1201,7 @@ class Texture(AbstractImage):
|
|
|
1201
1201
|
layer: int = 0, access: int = GL_READ_WRITE, fmt: int = GL_RGBA32F):
|
|
1202
1202
|
"""Bind as an ImageTexture for use with a :py:class:`~pyglet.shader.ComputeShaderProgram`.
|
|
1203
1203
|
|
|
1204
|
-
.. note:: OpenGL 4.3, or 4.2 with the GL_ARB_compute_shader
|
|
1204
|
+
.. note:: OpenGL 4.3, or 4.2 with the GL_ARB_compute_shader extension is required.
|
|
1205
1205
|
"""
|
|
1206
1206
|
glBindImageTexture(unit, self.id, level, layered, layer, access, fmt)
|
|
1207
1207
|
|
|
@@ -1211,7 +1211,7 @@ class Texture(AbstractImage):
|
|
|
1211
1211
|
fmt: int = GL_RGBA, blank_data: bool = True) -> Texture:
|
|
1212
1212
|
"""Create a Texture
|
|
1213
1213
|
|
|
1214
|
-
Create a Texture with the specified
|
|
1214
|
+
Create a Texture with the specified dimensions, target and format.
|
|
1215
1215
|
On return, the texture will be bound.
|
|
1216
1216
|
|
|
1217
1217
|
Args:
|
pyglet/image/buffer.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""OpenGL Framebuffer abstractions.
|
|
2
2
|
|
|
3
3
|
This module provides classes for working with Framebuffers & Renderbuffers
|
|
4
|
-
and their attachments.
|
|
4
|
+
and their attachments. Attachments can be pyglet Texture objects, which allows
|
|
5
5
|
easily accessing their data, saving to disk, etc. Renderbuffers can be used
|
|
6
6
|
if you don't need to access their data at a later time. For example::
|
|
7
7
|
|
|
@@ -40,7 +40,7 @@ if TYPE_CHECKING:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def get_max_color_attachments() -> int:
|
|
43
|
-
"""Get the maximum allow Framebuffer Color
|
|
43
|
+
"""Get the maximum allow Framebuffer Color attachments."""
|
|
44
44
|
number = GLint()
|
|
45
45
|
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, number)
|
|
46
46
|
return number.value
|
|
@@ -144,7 +144,7 @@ class Framebuffer:
|
|
|
144
144
|
|
|
145
145
|
Unbind should be called to prevent further rendering
|
|
146
146
|
to the framebuffer, or if you wish to access data
|
|
147
|
-
from its Texture
|
|
147
|
+
from its Texture attachments.
|
|
148
148
|
"""
|
|
149
149
|
glBindFramebuffer(self.target, 0)
|
|
150
150
|
|
pyglet/input/base.py
CHANGED
|
@@ -71,7 +71,7 @@ class Device:
|
|
|
71
71
|
Args:
|
|
72
72
|
window:
|
|
73
73
|
Optional window to associate with the device. The behaviour
|
|
74
|
-
of this parameter is device and operating system
|
|
74
|
+
of this parameter is device and operating system dependent.
|
|
75
75
|
It can usually be omitted for most devices.
|
|
76
76
|
exclusive:
|
|
77
77
|
If ``True`` the device will be opened exclusively so that no
|
|
@@ -103,7 +103,7 @@ class Device:
|
|
|
103
103
|
string. This is generated from the hardware identifiers,
|
|
104
104
|
and is in the same format as was popularized by SDL2.
|
|
105
105
|
GUIDs differ between platforms, but are generally 32
|
|
106
|
-
|
|
106
|
+
hexadecimal characters.
|
|
107
107
|
"""
|
|
108
108
|
raise NotImplementedError('abstract')
|
|
109
109
|
|
|
@@ -506,7 +506,7 @@ class Controller(EventDispatcher):
|
|
|
506
506
|
"""
|
|
507
507
|
|
|
508
508
|
def __init__(self, device: Device, mapping: dict):
|
|
509
|
-
"""Create a Controller
|
|
509
|
+
"""Create a Controller instance mapped to a Device.
|
|
510
510
|
|
|
511
511
|
.. versionadded:: 2.0
|
|
512
512
|
"""
|
|
@@ -575,7 +575,7 @@ class Controller(EventDispatcher):
|
|
|
575
575
|
A string, currently one of "PS", "XB", or "GENERIC".
|
|
576
576
|
"""
|
|
577
577
|
product_id = None
|
|
578
|
-
# TODO: add more checks for
|
|
578
|
+
# TODO: add more checks for vendor hardware ids.
|
|
579
579
|
|
|
580
580
|
# Windows
|
|
581
581
|
if self.name == 'XINPUTCONTROLLER':
|
|
@@ -672,7 +672,7 @@ class Controller(EventDispatcher):
|
|
|
672
672
|
def _bind_dedicated_hat(self, relation: Relation, control: AbsoluteAxis) -> None:
|
|
673
673
|
# 8-directional hat encoded as a single control (Windows/Mac)
|
|
674
674
|
_vecs = (Vec2(0.0, 1.0), Vec2(1.0, 1.0), Vec2(1.0, 0.0), Vec2(1.0, -1.0), # n, ne, e, se
|
|
675
|
-
|
|
675
|
+
Vec2(0.0, -1.0), Vec2(-1.0, -1.0), Vec2(-1.0, 0.0), Vec2(-1.0, 1.0)) # s, sw, w, nw
|
|
676
676
|
_input_map = {key: val for key, val in zip(range(int(control.min), int(control.max + 1)), _vecs)}
|
|
677
677
|
|
|
678
678
|
# For some Directinput devices:
|
|
@@ -730,8 +730,8 @@ class Controller(EventDispatcher):
|
|
|
730
730
|
|
|
731
731
|
self._bind_axis_control(relation, control, dpname)
|
|
732
732
|
|
|
733
|
-
except IndexError:
|
|
734
|
-
warnings.warn(f"Could not map '{relation}' to '{name}'")
|
|
733
|
+
except (IndexError, AttributeError, KeyError):
|
|
734
|
+
warnings.warn(f"Could not map physical Control '{relation}' to '{name}'")
|
|
735
735
|
continue
|
|
736
736
|
|
|
737
737
|
def open(self, window: None | BaseWindow = None, exclusive: bool = False) -> None:
|
|
@@ -1096,7 +1096,7 @@ class ControllerManager(EventDispatcher):
|
|
|
1096
1096
|
|
|
1097
1097
|
def on_connect(self, controller) -> Controller:
|
|
1098
1098
|
"""A Controller has been connected. If this is
|
|
1099
|
-
a previously
|
|
1099
|
+
a previously disconnected Controller that is
|
|
1100
1100
|
being re-connected, the same Controller instance
|
|
1101
1101
|
will be returned.
|
|
1102
1102
|
"""
|
pyglet/input/linux/evdev.py
CHANGED
|
@@ -471,7 +471,7 @@ class EvdevControllerManager(ControllerManager, XlibSelectDevice):
|
|
|
471
471
|
if controller := self._controllers.get(name, _create_controller(device)):
|
|
472
472
|
self._controllers[name] = controller
|
|
473
473
|
# Dispatch event in main thread:
|
|
474
|
-
|
|
474
|
+
self.post_event('on_connect', controller)
|
|
475
475
|
|
|
476
476
|
def select(self):
|
|
477
477
|
"""Triggered whenever the devices_file changes."""
|
|
@@ -232,6 +232,8 @@ NSDeviceSize = c_void_p.in_dll(appkit, 'NSDeviceSize')
|
|
|
232
232
|
NSDeviceResolution = c_void_p.in_dll(appkit, 'NSDeviceResolution')
|
|
233
233
|
NSDragOperationGeneric = 4
|
|
234
234
|
|
|
235
|
+
NSStatusWindowLevel = 25
|
|
236
|
+
|
|
235
237
|
|
|
236
238
|
# /System/Library/Frameworks/AppKit.framework/Headers/NSEvent.h
|
|
237
239
|
NSAnyEventMask = 0xFFFFFFFF # NSUIntegerMax
|
|
@@ -336,7 +338,7 @@ NSOpenGLProfileVersion3_2Core = 0x3200 # choose an OpenGL 3.2 Core Implementa
|
|
|
336
338
|
NSOpenGLProfileVersion4_1Core = 0x4100 # choose an OpenGL 4.1 Core Implementation
|
|
337
339
|
|
|
338
340
|
NSOpenGLCPSwapInterval = 222
|
|
339
|
-
|
|
341
|
+
NSOpenGLCPSurfaceOpacity = 236
|
|
340
342
|
|
|
341
343
|
# /System/Library/Frameworks/ApplicationServices.framework/Frameworks/...
|
|
342
344
|
# CoreGraphics.framework/Headers/CGImage.h
|
pyglet/libs/win32/__init__.py
CHANGED
|
@@ -114,6 +114,8 @@ _user32.DestroyWindow.restype = BOOL
|
|
|
114
114
|
_user32.DestroyWindow.argtypes = [HWND]
|
|
115
115
|
_user32.DispatchMessageW.restype = LRESULT
|
|
116
116
|
_user32.DispatchMessageW.argtypes = [LPMSG]
|
|
117
|
+
_user32.EnumDisplayDevicesW.restype = BOOL
|
|
118
|
+
_user32.EnumDisplayDevicesW.argtypes = [LPCWSTR, DWORD, POINTER(DISPLAY_DEVICEW), DWORD]
|
|
117
119
|
_user32.EnumDisplayMonitors.restype = BOOL
|
|
118
120
|
_user32.EnumDisplayMonitors.argtypes = [HDC, LPRECT, MONITORENUMPROC, LPARAM]
|
|
119
121
|
_user32.EnumDisplaySettingsW.restype = BOOL
|
|
@@ -131,6 +133,8 @@ _user32.GetDesktopWindow.restype = HWND
|
|
|
131
133
|
_user32.GetDesktopWindow.argtypes = []
|
|
132
134
|
_user32.GetKeyState.restype = c_short
|
|
133
135
|
_user32.GetKeyState.argtypes = [c_int]
|
|
136
|
+
_user32.GetLayeredWindowAttributes.restype = BOOL
|
|
137
|
+
_user32.GetLayeredWindowAttributes.argtypes = [HWND, POINTER(COLORREF), POINTER(BYTE), POINTER(DWORD)]
|
|
134
138
|
_user32.GetMessageW.restype = BOOL
|
|
135
139
|
_user32.GetMessageW.argtypes = [LPMSG, HWND, UINT, UINT]
|
|
136
140
|
_user32.GetMonitorInfoW.restype = BOOL
|
|
@@ -139,6 +143,8 @@ _user32.GetQueueStatus.restype = DWORD
|
|
|
139
143
|
_user32.GetQueueStatus.argtypes = [UINT]
|
|
140
144
|
_user32.GetSystemMetrics.restype = c_int
|
|
141
145
|
_user32.GetSystemMetrics.argtypes = [c_int]
|
|
146
|
+
_user32.GetWindowLongW.restype = LONG
|
|
147
|
+
_user32.GetWindowLongW.argtypes = [HWND, c_int]
|
|
142
148
|
_user32.LoadCursorW.restype = HCURSOR
|
|
143
149
|
_user32.LoadCursorW.argtypes = [HINSTANCE, c_wchar_p]
|
|
144
150
|
_user32.LoadIconW.restype = HICON
|
|
@@ -183,6 +189,8 @@ _user32.SetFocus.restype = HWND
|
|
|
183
189
|
_user32.SetFocus.argtypes = [HWND]
|
|
184
190
|
_user32.SetForegroundWindow.restype = BOOL
|
|
185
191
|
_user32.SetForegroundWindow.argtypes = [HWND]
|
|
192
|
+
_user32.SetLayeredWindowAttributes.restype = BOOL
|
|
193
|
+
_user32.SetLayeredWindowAttributes.argtypes = [HWND, COLORREF, BYTE, DWORD]
|
|
186
194
|
_user32.SetTimer.restype = UINT_PTR
|
|
187
195
|
_user32.SetTimer.argtypes = [HWND, UINT_PTR, UINT, TIMERPROC]
|
|
188
196
|
_user32.KillTimer.restype = UINT_PTR
|
|
@@ -249,6 +257,10 @@ _dwmapi.DwmIsCompositionEnabled.restype = c_int
|
|
|
249
257
|
_dwmapi.DwmIsCompositionEnabled.argtypes = [POINTER(INT)]
|
|
250
258
|
_dwmapi.DwmFlush.restype = c_int
|
|
251
259
|
_dwmapi.DwmFlush.argtypes = []
|
|
260
|
+
_dwmapi.DwmGetColorizationColor.restype = HRESULT
|
|
261
|
+
_dwmapi.DwmGetColorizationColor.argtypes = [POINTER(DWORD), POINTER(BOOL)]
|
|
262
|
+
_dwmapi.DwmEnableBlurBehindWindow.restype = HRESULT
|
|
263
|
+
_dwmapi.DwmEnableBlurBehindWindow.argtypes = [HWND, POINTER(DWM_BLURBEHIND)]
|
|
252
264
|
|
|
253
265
|
# _shell32
|
|
254
266
|
_shell32.DragAcceptFiles.restype = c_void
|
pyglet/libs/win32/constants.py
CHANGED
|
@@ -5083,3 +5083,7 @@ DEVICE_NOTIFY_WINDOW_HANDLE = 0
|
|
|
5083
5083
|
DEVICE_NOTIFY_SERVICE_HANDLE = 1
|
|
5084
5084
|
|
|
5085
5085
|
USER_DEFAULT_SCREEN_DPI = 96
|
|
5086
|
+
|
|
5087
|
+
QDC_ONLY_ACTIVE_PATHS = 0x00000002
|
|
5088
|
+
DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 0x00000001
|
|
5089
|
+
DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 0x00000002
|
pyglet/libs/win32/types.py
CHANGED
|
@@ -676,3 +676,100 @@ class DEV_BROADCAST_DEVICEINTERFACE(Structure):
|
|
|
676
676
|
('dbcc_classguid', com.GUID),
|
|
677
677
|
('dbcc_name', ctypes.c_wchar * 256)
|
|
678
678
|
)
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
class DISPLAY_DEVICEW(ctypes.Structure):
|
|
682
|
+
_fields_ = [
|
|
683
|
+
('cb', DWORD),
|
|
684
|
+
('DeviceName', WCHAR * 32),
|
|
685
|
+
('DeviceString', WCHAR * 128),
|
|
686
|
+
('StateFlags', DWORD),
|
|
687
|
+
('DeviceID', WCHAR * 128),
|
|
688
|
+
('DeviceKey', WCHAR * 128),
|
|
689
|
+
]
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
# Structures below are to retrieve a monitor name...
|
|
693
|
+
class LUID(ctypes.Structure):
|
|
694
|
+
_fields_ = [('LowPart', DWORD), ('HighPart', LONG)]
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
class _SourceInfoStruct(ctypes.Structure):
|
|
698
|
+
_fields_ = [('cloneGroupId', UINT32, 16), ('sourceModeInfoIdx', UINT32, 16)]
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
class _DisplayUnion(ctypes.Union):
|
|
702
|
+
_fields_ = [('modeInfoIdx', UINT32), ('DUMMYSTRUCTNAME', _SourceInfoStruct)]
|
|
703
|
+
|
|
704
|
+
|
|
705
|
+
class DISPLAYCONFIG_PATH_SOURCE_INFO(ctypes.Structure):
|
|
706
|
+
_fields_ = [('adapterId', LUID), ('id', UINT32), ('DUMMYUNIONNAME', _DisplayUnion), ('statusFlags', UINT32)]
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
class _DummyStructTarget(ctypes.Structure):
|
|
710
|
+
_fields_ = [
|
|
711
|
+
('desktopModeInfoIdx', UINT32, 16),
|
|
712
|
+
('targetModeInfoIdx', UINT32, 16),
|
|
713
|
+
]
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
class _DummyUnionTarget(ctypes.Union):
|
|
717
|
+
_fields_ = [('modeInfoIdx', UINT32), ('DUMMYSTRUCTNAME', _DummyStructTarget)]
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
class DISPLAYCONFIG_RATIONAL(ctypes.Structure):
|
|
721
|
+
_fields_ = [('Numerator', UINT32), ('Denominator', UINT32)]
|
|
722
|
+
|
|
723
|
+
def __repr__(self):
|
|
724
|
+
return f"DISPLAYCONFIG_RATIONAL(num={self.Numerator}, denom={self.Denominator})"
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
class DISPLAYCONFIG_PATH_TARGET_INFO(ctypes.Structure):
|
|
728
|
+
_fields_ = [
|
|
729
|
+
('adapterId', LUID),
|
|
730
|
+
('id', UINT32),
|
|
731
|
+
('DUMMYUNIONNAME', _DummyUnionTarget),
|
|
732
|
+
('outputTechnology', UINT32),
|
|
733
|
+
('rotation', UINT32),
|
|
734
|
+
('scaling', UINT32),
|
|
735
|
+
('refreshRate', DISPLAYCONFIG_RATIONAL),
|
|
736
|
+
('scanLineOrdering', UINT32),
|
|
737
|
+
('targetAvailable', BOOL),
|
|
738
|
+
('statusFlags', UINT32),
|
|
739
|
+
]
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
class DISPLAYCONFIG_PATH_INFO(ctypes.Structure):
|
|
743
|
+
_fields_ = [
|
|
744
|
+
('sourceInfo', DISPLAYCONFIG_PATH_SOURCE_INFO),
|
|
745
|
+
('targetInfo', DISPLAYCONFIG_PATH_TARGET_INFO),
|
|
746
|
+
('flags', UINT32),
|
|
747
|
+
]
|
|
748
|
+
|
|
749
|
+
|
|
750
|
+
class DISPLAYCONFIG_DEVICE_INFO_HEADER(ctypes.Structure):
|
|
751
|
+
_fields_ = [('type', UINT32),
|
|
752
|
+
('size', UINT32),
|
|
753
|
+
('adapterId', LUID),
|
|
754
|
+
('id', UINT32)
|
|
755
|
+
]
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
class DISPLAYCONFIG_SOURCE_DEVICE_NAME(ctypes.Structure):
|
|
759
|
+
_fields_ = [
|
|
760
|
+
('header', DISPLAYCONFIG_DEVICE_INFO_HEADER),
|
|
761
|
+
('viewGdiDeviceName', WCHAR * 32)
|
|
762
|
+
]
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
class DISPLAYCONFIG_TARGET_DEVICE_NAME(ctypes.Structure):
|
|
766
|
+
_fields_ = [
|
|
767
|
+
('header', DISPLAYCONFIG_DEVICE_INFO_HEADER),
|
|
768
|
+
('flags', UINT32),
|
|
769
|
+
('outputTechnology', UINT32),
|
|
770
|
+
('edidManufactureId', UINT16),
|
|
771
|
+
('edidProductCodeId', UINT16),
|
|
772
|
+
('connectorInstance', UINT32),
|
|
773
|
+
('monitorFriendlyDeviceName', WCHAR * 64),
|
|
774
|
+
('monitorDevicePath', WCHAR * 128),
|
|
775
|
+
]
|