pyglet 2.1.13__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.
Files changed (267) hide show
  1. pyglet/__init__.py +67 -61
  2. pyglet/__init__.pyi +15 -8
  3. pyglet/app/__init__.py +22 -13
  4. pyglet/app/async_app.py +212 -0
  5. pyglet/app/base.py +2 -1
  6. pyglet/app/{xlib.py → linux.py} +3 -3
  7. pyglet/config/__init__.py +101 -0
  8. pyglet/config/gl/__init__.py +30 -0
  9. pyglet/config/gl/egl.py +120 -0
  10. pyglet/config/gl/macos.py +262 -0
  11. pyglet/config/gl/windows.py +267 -0
  12. pyglet/config/gl/x11.py +142 -0
  13. pyglet/customtypes.py +43 -2
  14. pyglet/display/__init__.py +8 -6
  15. pyglet/display/base.py +3 -63
  16. pyglet/display/cocoa.py +12 -17
  17. pyglet/display/emscripten.py +39 -0
  18. pyglet/display/headless.py +23 -30
  19. pyglet/display/wayland.py +157 -0
  20. pyglet/display/win32.py +5 -21
  21. pyglet/display/xlib.py +19 -27
  22. pyglet/display/xlib_vidmoderestore.py +2 -2
  23. pyglet/enums.py +183 -0
  24. pyglet/event.py +0 -1
  25. pyglet/experimental/geoshader_sprite.py +15 -13
  26. pyglet/experimental/hidraw.py +6 -15
  27. pyglet/experimental/multitexture_sprite.py +31 -19
  28. pyglet/experimental/particles.py +13 -35
  29. pyglet/font/__init__.py +251 -85
  30. pyglet/font/base.py +116 -61
  31. pyglet/font/dwrite/__init__.py +349 -204
  32. pyglet/font/dwrite/dwrite_lib.py +27 -5
  33. pyglet/font/fontconfig.py +14 -6
  34. pyglet/font/freetype.py +138 -87
  35. pyglet/font/freetype_lib.py +19 -0
  36. pyglet/font/group.py +179 -0
  37. pyglet/font/harfbuzz/__init__.py +3 -3
  38. pyglet/font/pyodide_js.py +310 -0
  39. pyglet/font/quartz.py +319 -126
  40. pyglet/font/ttf.py +45 -3
  41. pyglet/font/user.py +14 -19
  42. pyglet/font/win32.py +45 -21
  43. pyglet/graphics/__init__.py +8 -787
  44. pyglet/graphics/allocation.py +115 -1
  45. pyglet/graphics/api/__init__.py +77 -0
  46. pyglet/graphics/api/base.py +299 -0
  47. pyglet/graphics/api/gl/__init__.py +58 -0
  48. pyglet/graphics/api/gl/base.py +24 -0
  49. pyglet/graphics/{vertexbuffer.py → api/gl/buffer.py} +104 -159
  50. pyglet/graphics/api/gl/cocoa/context.py +76 -0
  51. pyglet/graphics/api/gl/context.py +391 -0
  52. pyglet/graphics/api/gl/default_shaders.py +0 -0
  53. pyglet/graphics/api/gl/draw.py +627 -0
  54. pyglet/graphics/api/gl/egl/__init__.py +0 -0
  55. pyglet/graphics/api/gl/egl/context.py +92 -0
  56. pyglet/graphics/api/gl/enums.py +76 -0
  57. pyglet/graphics/api/gl/framebuffer.py +315 -0
  58. pyglet/graphics/api/gl/gl.py +5463 -0
  59. pyglet/graphics/api/gl/gl_info.py +188 -0
  60. pyglet/graphics/api/gl/global_opengl.py +226 -0
  61. pyglet/{gl → graphics/api/gl}/lib.py +34 -18
  62. pyglet/graphics/api/gl/shader.py +1476 -0
  63. pyglet/graphics/api/gl/shapes.py +55 -0
  64. pyglet/graphics/api/gl/sprite.py +102 -0
  65. pyglet/graphics/api/gl/state.py +219 -0
  66. pyglet/graphics/api/gl/text.py +190 -0
  67. pyglet/graphics/api/gl/texture.py +1526 -0
  68. pyglet/graphics/{vertexarray.py → api/gl/vertexarray.py} +11 -13
  69. pyglet/graphics/api/gl/vertexdomain.py +751 -0
  70. pyglet/graphics/api/gl/win32/__init__.py +0 -0
  71. pyglet/graphics/api/gl/win32/context.py +108 -0
  72. pyglet/graphics/api/gl/win32/wgl_info.py +24 -0
  73. pyglet/graphics/api/gl/xlib/__init__.py +0 -0
  74. pyglet/graphics/api/gl/xlib/context.py +174 -0
  75. pyglet/{gl → graphics/api/gl/xlib}/glx_info.py +26 -31
  76. pyglet/graphics/api/gl1/__init__.py +0 -0
  77. pyglet/{gl → graphics/api/gl1}/gl_compat.py +3 -2
  78. pyglet/graphics/api/gl2/__init__.py +0 -0
  79. pyglet/graphics/api/gl2/buffer.py +320 -0
  80. pyglet/graphics/api/gl2/draw.py +600 -0
  81. pyglet/graphics/api/gl2/global_opengl.py +122 -0
  82. pyglet/graphics/api/gl2/shader.py +200 -0
  83. pyglet/graphics/api/gl2/shapes.py +51 -0
  84. pyglet/graphics/api/gl2/sprite.py +79 -0
  85. pyglet/graphics/api/gl2/text.py +175 -0
  86. pyglet/graphics/api/gl2/vertexdomain.py +364 -0
  87. pyglet/graphics/api/webgl/__init__.py +233 -0
  88. pyglet/graphics/api/webgl/buffer.py +302 -0
  89. pyglet/graphics/api/webgl/context.py +234 -0
  90. pyglet/graphics/api/webgl/draw.py +590 -0
  91. pyglet/graphics/api/webgl/enums.py +76 -0
  92. pyglet/graphics/api/webgl/framebuffer.py +360 -0
  93. pyglet/graphics/api/webgl/gl.py +1537 -0
  94. pyglet/graphics/api/webgl/gl_info.py +130 -0
  95. pyglet/graphics/api/webgl/shader.py +1346 -0
  96. pyglet/graphics/api/webgl/shapes.py +92 -0
  97. pyglet/graphics/api/webgl/sprite.py +102 -0
  98. pyglet/graphics/api/webgl/state.py +227 -0
  99. pyglet/graphics/api/webgl/text.py +187 -0
  100. pyglet/graphics/api/webgl/texture.py +1227 -0
  101. pyglet/graphics/api/webgl/vertexarray.py +54 -0
  102. pyglet/graphics/api/webgl/vertexdomain.py +616 -0
  103. pyglet/graphics/api/webgl/webgl_js.pyi +307 -0
  104. pyglet/{image → graphics}/atlas.py +33 -32
  105. pyglet/graphics/base.py +10 -0
  106. pyglet/graphics/buffer.py +245 -0
  107. pyglet/graphics/draw.py +578 -0
  108. pyglet/graphics/framebuffer.py +26 -0
  109. pyglet/graphics/instance.py +178 -69
  110. pyglet/graphics/shader.py +267 -1553
  111. pyglet/graphics/state.py +83 -0
  112. pyglet/graphics/texture.py +703 -0
  113. pyglet/graphics/vertexdomain.py +695 -538
  114. pyglet/gui/ninepatch.py +10 -10
  115. pyglet/gui/widgets.py +120 -10
  116. pyglet/image/__init__.py +20 -1973
  117. pyglet/image/animation.py +12 -12
  118. pyglet/image/base.py +730 -0
  119. pyglet/image/codecs/__init__.py +9 -0
  120. pyglet/image/codecs/bmp.py +53 -30
  121. pyglet/image/codecs/dds.py +53 -31
  122. pyglet/image/codecs/gdiplus.py +38 -14
  123. pyglet/image/codecs/gdkpixbuf2.py +0 -2
  124. pyglet/image/codecs/js_image.py +99 -0
  125. pyglet/image/codecs/ktx2.py +161 -0
  126. pyglet/image/codecs/pil.py +1 -1
  127. pyglet/image/codecs/png.py +1 -1
  128. pyglet/image/codecs/wic.py +11 -2
  129. pyglet/info.py +26 -24
  130. pyglet/input/__init__.py +8 -0
  131. pyglet/input/base.py +163 -105
  132. pyglet/input/controller.py +13 -19
  133. pyglet/input/controller_db.py +39 -24
  134. pyglet/input/emscripten/__init__.py +18 -0
  135. pyglet/input/emscripten/gamepad_js.py +397 -0
  136. pyglet/input/linux/__init__.py +11 -5
  137. pyglet/input/linux/evdev.py +10 -11
  138. pyglet/input/linux/x11_xinput.py +2 -2
  139. pyglet/input/linux/x11_xinput_tablet.py +1 -1
  140. pyglet/input/macos/__init__.py +7 -2
  141. pyglet/input/macos/darwin_gc.py +559 -0
  142. pyglet/input/win32/__init__.py +1 -1
  143. pyglet/input/win32/directinput.py +34 -29
  144. pyglet/input/win32/xinput.py +11 -61
  145. pyglet/lib.py +3 -3
  146. pyglet/libs/__init__.py +1 -1
  147. pyglet/{gl → libs/darwin}/agl.py +1 -1
  148. pyglet/libs/darwin/cocoapy/__init__.py +2 -2
  149. pyglet/libs/darwin/cocoapy/cocoahelpers.py +181 -0
  150. pyglet/libs/darwin/cocoapy/cocoalibs.py +31 -0
  151. pyglet/libs/darwin/cocoapy/cocoatypes.py +27 -0
  152. pyglet/libs/darwin/cocoapy/runtime.py +81 -45
  153. pyglet/libs/darwin/coreaudio.py +4 -4
  154. pyglet/{gl → libs/darwin}/lib_agl.py +9 -8
  155. pyglet/libs/darwin/quartzkey.py +1 -3
  156. pyglet/libs/egl/__init__.py +2 -0
  157. pyglet/libs/egl/egl_lib.py +576 -0
  158. pyglet/libs/egl/eglext.py +51 -5
  159. pyglet/libs/linux/__init__.py +0 -0
  160. pyglet/libs/linux/egl/__init__.py +0 -0
  161. pyglet/libs/linux/egl/eglext.py +22 -0
  162. pyglet/libs/linux/glx/__init__.py +0 -0
  163. pyglet/{gl → libs/linux/glx}/glx.py +13 -14
  164. pyglet/{gl → libs/linux/glx}/glxext_arb.py +408 -192
  165. pyglet/{gl → libs/linux/glx}/glxext_mesa.py +1 -1
  166. pyglet/{gl → libs/linux/glx}/glxext_nv.py +345 -164
  167. pyglet/{gl → libs/linux/glx}/lib_glx.py +3 -2
  168. pyglet/libs/linux/wayland/__init__.py +0 -0
  169. pyglet/libs/linux/wayland/client.py +1068 -0
  170. pyglet/libs/linux/wayland/lib_wayland.py +207 -0
  171. pyglet/libs/linux/wayland/wayland_egl.py +38 -0
  172. pyglet/libs/{wayland → linux/wayland}/xkbcommon.py +26 -0
  173. pyglet/libs/{x11 → linux/x11}/xf86vmode.py +4 -4
  174. pyglet/libs/{x11 → linux/x11}/xinerama.py +2 -2
  175. pyglet/libs/{x11 → linux/x11}/xinput.py +10 -10
  176. pyglet/libs/linux/x11/xrandr.py +0 -0
  177. pyglet/libs/{x11 → linux/x11}/xrender.py +1 -1
  178. pyglet/libs/shared/__init__.py +0 -0
  179. pyglet/libs/shared/spirv/__init__.py +0 -0
  180. pyglet/libs/shared/spirv/lib_shaderc.py +85 -0
  181. pyglet/libs/shared/spirv/lib_spirv_cross.py +126 -0
  182. pyglet/libs/win32/__init__.py +28 -8
  183. pyglet/libs/win32/constants.py +59 -48
  184. pyglet/libs/win32/context_managers.py +20 -3
  185. pyglet/libs/win32/dinput.py +105 -88
  186. pyglet/{gl → libs/win32}/lib_wgl.py +52 -26
  187. pyglet/libs/win32/types.py +58 -23
  188. pyglet/{gl → libs/win32}/wgl.py +32 -25
  189. pyglet/{gl → libs/win32}/wglext_arb.py +364 -2
  190. pyglet/media/__init__.py +9 -10
  191. pyglet/media/codecs/__init__.py +12 -1
  192. pyglet/media/codecs/base.py +99 -96
  193. pyglet/media/codecs/ffmpeg.py +2 -2
  194. pyglet/media/codecs/ffmpeg_lib/libavformat.py +3 -8
  195. pyglet/media/codecs/webaudio_pyodide.py +111 -0
  196. pyglet/media/drivers/__init__.py +9 -4
  197. pyglet/media/drivers/base.py +4 -4
  198. pyglet/media/drivers/openal/__init__.py +1 -1
  199. pyglet/media/drivers/openal/adaptation.py +3 -3
  200. pyglet/media/drivers/pulse/__init__.py +1 -1
  201. pyglet/media/drivers/pulse/adaptation.py +3 -3
  202. pyglet/media/drivers/pyodide_js/__init__.py +8 -0
  203. pyglet/media/drivers/pyodide_js/adaptation.py +288 -0
  204. pyglet/media/drivers/xaudio2/adaptation.py +3 -3
  205. pyglet/media/player.py +276 -193
  206. pyglet/media/player_worker_thread.py +1 -1
  207. pyglet/model/__init__.py +39 -29
  208. pyglet/model/codecs/base.py +4 -4
  209. pyglet/model/codecs/gltf.py +3 -3
  210. pyglet/model/codecs/obj.py +71 -43
  211. pyglet/resource.py +129 -78
  212. pyglet/shapes.py +154 -194
  213. pyglet/sprite.py +47 -164
  214. pyglet/text/__init__.py +44 -54
  215. pyglet/text/caret.py +12 -7
  216. pyglet/text/document.py +19 -17
  217. pyglet/text/formats/html.py +2 -2
  218. pyglet/text/formats/structured.py +10 -40
  219. pyglet/text/layout/__init__.py +20 -13
  220. pyglet/text/layout/base.py +176 -287
  221. pyglet/text/layout/incremental.py +9 -10
  222. pyglet/text/layout/scrolling.py +7 -95
  223. pyglet/window/__init__.py +183 -172
  224. pyglet/window/cocoa/__init__.py +62 -51
  225. pyglet/window/cocoa/pyglet_delegate.py +2 -25
  226. pyglet/window/cocoa/pyglet_view.py +9 -8
  227. pyglet/window/dialog/__init__.py +184 -0
  228. pyglet/window/dialog/base.py +99 -0
  229. pyglet/window/dialog/darwin.py +121 -0
  230. pyglet/window/dialog/linux.py +72 -0
  231. pyglet/window/dialog/windows.py +194 -0
  232. pyglet/window/emscripten/__init__.py +779 -0
  233. pyglet/window/headless/__init__.py +44 -28
  234. pyglet/window/key.py +2 -0
  235. pyglet/window/mouse.py +2 -2
  236. pyglet/window/wayland/__init__.py +377 -0
  237. pyglet/window/win32/__init__.py +101 -46
  238. pyglet/window/xlib/__init__.py +104 -66
  239. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/METADATA +2 -3
  240. pyglet-3.0.dev1.dist-info/RECORD +322 -0
  241. {pyglet-2.1.13.dist-info → pyglet-3.0.dev1.dist-info}/WHEEL +1 -1
  242. pyglet/gl/__init__.py +0 -208
  243. pyglet/gl/base.py +0 -499
  244. pyglet/gl/cocoa.py +0 -309
  245. pyglet/gl/gl.py +0 -4625
  246. pyglet/gl/gl.pyi +0 -2320
  247. pyglet/gl/gl_compat.pyi +0 -3097
  248. pyglet/gl/gl_info.py +0 -190
  249. pyglet/gl/headless.py +0 -166
  250. pyglet/gl/wgl_info.py +0 -36
  251. pyglet/gl/wglext_nv.py +0 -1096
  252. pyglet/gl/win32.py +0 -268
  253. pyglet/gl/xlib.py +0 -295
  254. pyglet/image/buffer.py +0 -274
  255. pyglet/image/codecs/s3tc.py +0 -354
  256. pyglet/libs/x11/xrandr.py +0 -166
  257. pyglet-2.1.13.dist-info/RECORD +0 -234
  258. /pyglet/{libs/wayland → graphics/api/gl/cocoa}/__init__.py +0 -0
  259. /pyglet/libs/{egl → linux/egl}/egl.py +0 -0
  260. /pyglet/libs/{egl → linux/egl}/lib.py +0 -0
  261. /pyglet/libs/{ioctl.py → linux/ioctl.py} +0 -0
  262. /pyglet/libs/{wayland → linux/wayland}/gbm.py +0 -0
  263. /pyglet/libs/{x11 → linux/x11}/__init__.py +0 -0
  264. /pyglet/libs/{x11 → linux/x11}/cursorfont.py +0 -0
  265. /pyglet/libs/{x11 → linux/x11}/xlib.py +0 -0
  266. /pyglet/libs/{x11 → linux/x11}/xsync.py +0 -0
  267. {pyglet-2.1.13.dist-info/licenses → pyglet-3.0.dev1.dist-info}/LICENSE +0 -0
@@ -0,0 +1,101 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any, TYPE_CHECKING
5
+
6
+
7
+ if TYPE_CHECKING:
8
+ from pyglet.window import Window
9
+
10
+
11
+
12
+ class SurfaceConfig:
13
+ """Surface configuration information returned by a platform.
14
+
15
+ This describes the information a desired surface or window can support.
16
+ """
17
+ def __init__(self, window: Window, config: UserConfig, handle: Any) -> None:
18
+ """A config representing the capabilities of a specific surface.
19
+
20
+ This is returned by the platform on a specific window and is not meant to be created by users.
21
+
22
+ Args:
23
+ window:
24
+ The current window or display.
25
+ config:
26
+ The requested user configuration.
27
+ handle:
28
+ A handle to the underlying configuration unique to each platform.
29
+ """
30
+ self._window = window
31
+ self.config = config
32
+ self.handle = handle
33
+
34
+ @property
35
+ def attributes(self) -> dict[str, Any]:
36
+ """The public attributes of this configuration."""
37
+ return {attrib: value for attrib, value in self.__dict__.items() if attrib[0] != '_'}
38
+
39
+ def is_finalized(self) -> bool:
40
+ return True
41
+
42
+ class UserConfig:
43
+ """User configuration information."""
44
+
45
+ @dataclass
46
+ class OpenGLConfig(UserConfig):
47
+ """An OpenGL Graphics configuration."""
48
+ #: Specify the presence of a back-buffer for every color buffer.
49
+ double_buffer: bool | None = None
50
+ #: Specify the presence of separate left and right buffer sets.
51
+ stereo: bool | None = None
52
+ #: Total bits per sample per color buffer.
53
+ buffer_size: int | None = None
54
+ #: The number of auxiliary color buffers.
55
+ aux_buffers: int | None = None
56
+ #: The number of multisample buffers.
57
+ sample_buffers: int | None = None
58
+ #: The number of samples per pixel, or 0 if there are no multisample buffers.
59
+ samples: int | None = None
60
+ #: Bits per sample per buffer devoted to the red component.
61
+ red_size: int | None = None
62
+ #: Bits per sample per buffer devoted to the green component.
63
+ green_size: int | None = None
64
+ #: Bits per sample per buffer devoted to the blue component.
65
+ blue_size: int | None = None
66
+ #: Bits per sample per buffer devoted to the alpha component.
67
+ alpha_size: int | None = None
68
+ #: Bits per sample in the depth buffer.
69
+ depth_size: int | None = None
70
+ #: Bits per sample in the stencil buffer.
71
+ stencil_size: int | None = None
72
+ #: Bits per pixel devoted to the red component in the accumulation buffer. Deprecated.
73
+ accum_red_size: int | None = None
74
+ #: Bits per pixel devoted to the green component in the accumulation buffer. Deprecated.
75
+ accum_green_size: int | None = None
76
+ #: Bits per pixel devoted to the blue component in the accumulation buffer. Deprecated.
77
+ accum_blue_size: int | None = None
78
+ #: Bits per pixel devoted to the alpha component in the accumulation buffer. Deprecated.
79
+ accum_alpha_size: int | None = None
80
+ #: The OpenGL major version.
81
+ major_version: int | None = None
82
+ #: The OpenGL minor version.
83
+ minor_version: int | None = None
84
+ #: Whether to use forward compatibility mode.
85
+ forward_compatible: bool | None = None
86
+ opengl_api: str | None = "gl"
87
+ #: Debug mode.
88
+ debug: bool | None = None
89
+ #: If the framebuffer should be transparent.
90
+ transparent_framebuffer: bool | None = None
91
+
92
+ @property
93
+ def is_finalized(self) -> bool:
94
+ return False
95
+
96
+
97
+ def match_surface_config(config: UserConfig, surface: Window) -> SurfaceConfig | None:
98
+ if isinstance(config, OpenGLConfig):
99
+ from pyglet.config.gl import get_surface_config # noqa: PLC0415
100
+ return get_surface_config(config, surface)
101
+ return None
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+ import pyglet
3
+ from pyglet.config import UserConfig, SurfaceConfig, OpenGLConfig
4
+
5
+
6
+ class GLSurfaceConfig(SurfaceConfig):
7
+ config: OpenGLConfig
8
+
9
+
10
+ def get_surface_config(user_config: UserConfig, surface: pyglet.window.Window) -> SurfaceConfig | None:
11
+ if pyglet.options.headless or pyglet.options.wayland:
12
+ from pyglet.config.gl.egl import match
13
+
14
+ return match(user_config, surface)
15
+ if pyglet.compat_platform == "win32":
16
+ from pyglet.config.gl.windows import match # noqa: PLC0415
17
+
18
+ return match(user_config, surface)
19
+ if pyglet.compat_platform.startswith("linux"):
20
+ from pyglet.config.gl.x11 import match # noqa: PLC0415
21
+
22
+ return match(user_config, surface)
23
+ if pyglet.compat_platform == "darwin":
24
+ from pyglet.config.gl.macos import match # noqa: PLC0415
25
+
26
+ return match(user_config, surface)
27
+
28
+ if pyglet.compat_platform == "emscripten":
29
+ return GLSurfaceConfig(surface, user_config, None)
30
+ return None
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ from ctypes import byref
4
+ from dataclasses import asdict
5
+ from typing import TYPE_CHECKING
6
+
7
+ from pyglet import options
8
+ from pyglet.graphics.api.gl.egl.context import EGLContext
9
+ from pyglet.libs import egl
10
+ from pyglet.config import SurfaceConfig
11
+
12
+ if TYPE_CHECKING:
13
+ from pyglet.graphics.api import OpenGLBackend
14
+ from pyglet.config import OpenGLConfig
15
+ from pyglet.window.headless import HeadlessWindow
16
+ from pyglet.window.wayland import WaylandWindow
17
+
18
+ _fake_gl_attributes = {
19
+ 'double_buffer': True,
20
+ 'stereo': 0,
21
+ 'aux_buffers': 0,
22
+ 'accum_red_size': 0,
23
+ 'accum_green_size': 0,
24
+ 'accum_blue_size': 0,
25
+ 'accum_alpha_size': 0,
26
+ }
27
+
28
+
29
+ def match(config: OpenGLConfig, window: HeadlessWindow | WaylandWindow) -> EGLSurfaceConfig:
30
+ display_connection = window.egl_display_connection # noqa: SLF001
31
+ assert display_connection is not None
32
+
33
+ # Construct array of attributes
34
+ attrs = []
35
+ for name, value in asdict(config).items():
36
+ if name == 'double_buffer':
37
+ continue
38
+ attr = EGLSurfaceConfig.attribute_ids.get(name, None)
39
+ if attr and value is not None:
40
+ attrs.extend([attr, int(value)])
41
+
42
+ if options.headless:
43
+ attrs.extend([egl.EGL_SURFACE_TYPE, egl.EGL_PBUFFER_BIT])
44
+ else:
45
+ attrs.extend([egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT])
46
+ attrs.extend([egl.EGL_RED_SIZE, 8])
47
+ attrs.extend([egl.EGL_GREEN_SIZE, 8])
48
+ attrs.extend([egl.EGL_BLUE_SIZE, 8])
49
+ attrs.extend([egl.EGL_ALPHA_SIZE, 8])
50
+ attrs.extend([egl.EGL_DEPTH_SIZE, 8])
51
+
52
+ if config.opengl_api == "gl":
53
+ attrs.extend([egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_BIT])
54
+ elif config.opengl_api == "gles":
55
+ attrs.extend([egl.EGL_RENDERABLE_TYPE, egl.EGL_OPENGL_ES3_BIT])
56
+ else:
57
+ msg = f"Unknown OpenGL API: {config.opengl_api}"
58
+ raise ValueError(msg)
59
+
60
+ attrs.extend([egl.EGL_NONE])
61
+ attrs_list = (egl.EGLint * len(attrs))(*attrs)
62
+
63
+ num_config = egl.EGLint()
64
+ egl.eglChooseConfig(display_connection, attrs_list, None, 0, byref(num_config))
65
+ configs = (egl.EGLConfig * num_config.value)()
66
+ egl.eglChooseConfig(display_connection, attrs_list, configs, num_config.value, byref(num_config))
67
+
68
+ result = [EGLSurfaceConfig(window, c, config) for c in configs]
69
+ return result[0]
70
+
71
+
72
+ class EGLSurfaceConfig(SurfaceConfig):
73
+ window: HeadlessWindow | WaylandWindow
74
+
75
+ attribute_ids = { # noqa: RUF012
76
+ 'buffer_size': egl.EGL_BUFFER_SIZE,
77
+ 'level': egl.EGL_LEVEL, # Not supported
78
+ 'red_size': egl.EGL_RED_SIZE,
79
+ 'green_size': egl.EGL_GREEN_SIZE,
80
+ 'blue_size': egl.EGL_BLUE_SIZE,
81
+ 'alpha_size': egl.EGL_ALPHA_SIZE,
82
+ 'depth_size': egl.EGL_DEPTH_SIZE,
83
+ 'stencil_size': egl.EGL_STENCIL_SIZE,
84
+ 'sample_buffers': egl.EGL_SAMPLE_BUFFERS,
85
+ 'samples': egl.EGL_SAMPLES,
86
+ }
87
+
88
+ def __init__(self, window: HeadlessWindow | WaylandWindow, egl_config: egl.EGLConfig, config: OpenGLConfig) -> None:
89
+ super().__init__(window, config, egl_config)
90
+ self._egl_config = egl_config
91
+
92
+ context_attribs = [egl.EGL_CONTEXT_MAJOR_VERSION, config.major_version or 2,
93
+ egl.EGL_CONTEXT_MINOR_VERSION, config.minor_version or 0]
94
+
95
+ if config.opengl_api == "gl" and config.forward_compatible:
96
+ context_attribs.extend([egl.EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE, 1])
97
+
98
+ if config.debug:
99
+ context_attribs.extend([egl.EGL_CONTEXT_OPENGL_DEBUG, config.debug])
100
+
101
+ context_attribs.append(egl.EGL_NONE)
102
+
103
+ self._context_attrib_array = (egl.EGLint * len(context_attribs))(*context_attribs)
104
+
105
+ for name, attr in self.attribute_ids.items():
106
+ value = egl.EGLint()
107
+ result = egl.eglGetConfigAttrib(window.egl_display_connection, egl_config, attr, byref(value)) # noqa: SLF001
108
+ if result == egl.EGL_TRUE:
109
+ setattr(self, name, value.value)
110
+
111
+ # TODO: real attributes?
112
+ for name, value in _fake_gl_attributes.items():
113
+ setattr(self, name, value)
114
+
115
+ def create_context(self, opengl_backend: OpenGLBackend, share: EGLContext | None) -> EGLContext:
116
+ return EGLContext(opengl_backend, self._window, self, share)
117
+
118
+ def apply_format(self) -> None:
119
+ pass
120
+
@@ -0,0 +1,262 @@
1
+ from __future__ import annotations
2
+
3
+ import platform
4
+ from dataclasses import asdict
5
+
6
+ from ctypes import byref, c_uint32, c_int
7
+
8
+ from pyglet.config.gl import GLSurfaceConfig
9
+
10
+ from pyglet.libs.darwin import cocoapy, quartz
11
+
12
+ from typing import TYPE_CHECKING
13
+ if TYPE_CHECKING:
14
+ from pyglet.config import OpenGLConfig
15
+ from pyglet.graphics.api.gl.cocoa.context import NSOpenGLPixelFormat, CocoaContext
16
+ from pyglet.window.cocoa import CocoaWindow
17
+ from pyglet.graphics.api import OpenGLBackend
18
+
19
+ # Version info, needed as OpenGL different Lion and onward
20
+ """Version is based on Darwin kernel, not OS-X version.
21
+ OS-X / Darwin version history
22
+ http://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
23
+ pre-release: 0.1, 0.2, 1.0, 1.1,
24
+ kodiak: 1.2.1,
25
+ cheetah: 1.3.1,
26
+ puma: 1.4.1, 5.1 -> 5.5
27
+ jaguar: 6.0.1 -> 6.8
28
+ panther: 7.0 -> 7.9
29
+ tiger: 8.0 -> 8.11
30
+ leopard: 9.0 -> 9.8
31
+ snow_leopard: 10.0 -> 10.8
32
+ lion: 11.0 -> 11.4
33
+ mountain_lion: 12.0 -> 12.5
34
+ mavericks: 13.0 -> 13.4
35
+ yosemite: 14.0 -> 14.5
36
+ el_capitan: 15.0 -> 15.6
37
+ sierra: 16.0 -> 16.6
38
+ high_sierra: 17.0 -> 17.7
39
+ mojave: 18.0 -> 18.2
40
+ catalina: 19.0 -> 19.6
41
+ big_sur: 20.0 ->
42
+ """
43
+
44
+ os_x_release: dict[str, tuple[float] | tuple[float, float] | tuple[float, float, float]] = {
45
+ 'pre-release': (0, 1),
46
+ 'kodiak': (1, 2, 1),
47
+ 'cheetah': (1, 3, 1),
48
+ 'puma': (1, 4.1),
49
+ 'jaguar': (6, 0, 1),
50
+ 'panther': (7,),
51
+ 'tiger': (8,),
52
+ 'leopard': (9,),
53
+ 'snow_leopard': (10,),
54
+ 'lion': (11,),
55
+ 'mountain_lion': (12,),
56
+ 'mavericks': (13,),
57
+ 'yosemite': (14,),
58
+ 'el_capitan': (15,),
59
+ 'sierra': (16,),
60
+ 'high_sierra': (17,),
61
+ 'mojave': (18,),
62
+ 'catalina': (19,),
63
+ 'big_sur': (20,),
64
+ }
65
+
66
+
67
+ def os_x_version() -> tuple[int, ...] | tuple[tuple[int, ...]]:
68
+ version = tuple([int(v) for v in platform.release().split('.')])
69
+
70
+ # ensure we return a tuple
71
+ if len(version) > 0:
72
+ return version
73
+ return (version,)
74
+
75
+
76
+ _os_x_version = os_x_version()
77
+
78
+ # Valid names for GL attributes and their corresponding NSOpenGL constant.
79
+ _gl_attributes = {
80
+ 'double_buffer': cocoapy.NSOpenGLPFADoubleBuffer,
81
+ 'stereo': cocoapy.NSOpenGLPFAStereo,
82
+ 'buffer_size': cocoapy.NSOpenGLPFAColorSize,
83
+ 'sample_buffers': cocoapy.NSOpenGLPFASampleBuffers,
84
+ 'samples': cocoapy.NSOpenGLPFASamples,
85
+ 'aux_buffers': cocoapy.NSOpenGLPFAAuxBuffers,
86
+ 'alpha_size': cocoapy.NSOpenGLPFAAlphaSize,
87
+ 'depth_size': cocoapy.NSOpenGLPFADepthSize,
88
+ 'stencil_size': cocoapy.NSOpenGLPFAStencilSize,
89
+
90
+ # Not exposed by pyglet API (set internally)
91
+ 'all_renderers': cocoapy.NSOpenGLPFAAllRenderers,
92
+ 'fullscreen': cocoapy.NSOpenGLPFAFullScreen,
93
+ 'minimum_policy': cocoapy.NSOpenGLPFAMinimumPolicy,
94
+ 'maximum_policy': cocoapy.NSOpenGLPFAMaximumPolicy,
95
+ 'screen_mask': cocoapy.NSOpenGLPFAScreenMask,
96
+
97
+ # Not supported in current pyglet API
98
+ 'color_float': cocoapy.NSOpenGLPFAColorFloat,
99
+ 'offscreen': cocoapy.NSOpenGLPFAOffScreen,
100
+ 'sample_alpha': cocoapy.NSOpenGLPFASampleAlpha,
101
+ 'multisample': cocoapy.NSOpenGLPFAMultisample,
102
+ 'supersample': cocoapy.NSOpenGLPFASupersample,
103
+ }
104
+
105
+ # NSOpenGL constants which do not require a value.
106
+ _boolean_gl_attributes = frozenset([
107
+ cocoapy.NSOpenGLPFAAllRenderers,
108
+ cocoapy.NSOpenGLPFADoubleBuffer,
109
+ cocoapy.NSOpenGLPFAStereo,
110
+ cocoapy.NSOpenGLPFAMinimumPolicy,
111
+ cocoapy.NSOpenGLPFAMaximumPolicy,
112
+ cocoapy.NSOpenGLPFAOffScreen,
113
+ cocoapy.NSOpenGLPFAFullScreen,
114
+ cocoapy.NSOpenGLPFAColorFloat,
115
+ cocoapy.NSOpenGLPFAMultisample,
116
+ cocoapy.NSOpenGLPFASupersample,
117
+ cocoapy.NSOpenGLPFASampleAlpha,
118
+ ])
119
+
120
+ # Attributes for which no NSOpenGLPixelFormatAttribute name exists.
121
+ # We could probably compute actual values for these using
122
+ # NSOpenGLPFAColorSize / 4 and NSOpenGLFAAccumSize / 4, but I'm not that
123
+ # confident I know what I'm doing.
124
+ _fake_gl_attributes = {
125
+ 'red_size': 0,
126
+ 'green_size': 0,
127
+ 'blue_size': 0,
128
+ 'accum_red_size': 0,
129
+ 'accum_green_size': 0,
130
+ 'accum_blue_size': 0,
131
+ 'accum_alpha_size': 0,
132
+ }
133
+
134
+
135
+ def match(config: OpenGLConfig, window: CocoaWindow) -> CocoaGLSurfaceConfig | None:
136
+ # Construct array of attributes for NSOpenGLPixelFormat
137
+ attrs = []
138
+ for name, value in asdict(config).items():
139
+ attr = _gl_attributes.get(name)
140
+ if not attr or not value:
141
+ continue
142
+ attrs.append(attr)
143
+ if attr not in _boolean_gl_attributes:
144
+ attrs.append(int(value))
145
+
146
+ # Support for RAGE-II, which is not compliant.
147
+ attrs.append(cocoapy.NSOpenGLPFAAllRenderers)
148
+
149
+ # Force selection policy.
150
+ attrs.append(cocoapy.NSOpenGLPFAMaximumPolicy)
151
+
152
+ # NSOpenGLPFAFullScreen is always supplied so we can switch to and
153
+ # from fullscreen without losing the context. Also must supply the
154
+ # NSOpenGLPFAScreenMask attribute with appropriate display ID.
155
+ # Note that these attributes aren't necessary to render in fullscreen
156
+ # on Mac OS X 10.6, because there we are simply rendering into a
157
+ # screen sized window. See:
158
+ # http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/OpenGL-MacProgGuide
159
+ # /opengl_fullscreen/opengl_cgl.html%23//apple_ref/doc/uid/TP40001987-CH210-SW6
160
+ # Otherwise, make sure we refer to the correct Profile for OpenGL (Core or
161
+ # Legacy) on Lion and afterwards
162
+ if _os_x_version < os_x_release['snow_leopard']:
163
+ attrs.append(cocoapy.NSOpenGLPFAFullScreen)
164
+ attrs.append(cocoapy.NSOpenGLPFAScreenMask)
165
+ attrs.append(quartz.CGDisplayIDToOpenGLDisplayMask(quartz.CGMainDisplayID()))
166
+ elif _os_x_version >= os_x_release['lion']:
167
+ # check for opengl profile
168
+ # This requires OS-X Lion (Darwin 11) or higher
169
+ version = (getattr(config, 'major_version', None) or 3,
170
+ getattr(config, 'minor_version', None) or 3)
171
+
172
+ # tell os-x we want to request a profile
173
+ attrs.append(cocoapy.NSOpenGLPFAOpenGLProfile)
174
+
175
+ # check if we're wanting core or legacy
176
+ # Mavericks (Darwin 13) and up are capable of the Core 4.1 profile,
177
+ # while Lion and up are only capable of Core 3.2
178
+ if version[0] >= 4 and _os_x_version >= os_x_release['mavericks']:
179
+ attrs.append(int(cocoapy.NSOpenGLProfileVersion4_1Core))
180
+ elif version[0] >= 3:
181
+ attrs.append(int(cocoapy.NSOpenGLProfileVersion3_2Core))
182
+ else:
183
+ attrs.append(int(cocoapy.NSOpenGLProfileVersionLegacy))
184
+ # Terminate the list.
185
+ attrs.append(0)
186
+
187
+ # Create the pixel format.
188
+ attrs_array_type = c_uint32 * len(attrs)
189
+ attrs_array = attrs_array_type(*attrs)
190
+ from pyglet.graphics.api.gl.cocoa.context import NSOpenGLPixelFormat # noqa: PLC0415
191
+ pixel_format = NSOpenGLPixelFormat.alloc().initWithAttributes_(attrs_array)
192
+
193
+ # Return the match list.
194
+ if pixel_format is None:
195
+ return None
196
+
197
+ return CocoaGLSurfaceConfig(window, config, pixel_format)
198
+
199
+
200
+ class CocoaGLSurfaceConfig(GLSurfaceConfig):
201
+
202
+ def __init__(self, window: CocoaWindow, config: OpenGLConfig, pixel_format: NSOpenGLPixelFormat) -> None:
203
+ super().__init__(window, config, pixel_format)
204
+ self._pixel_format = pixel_format
205
+
206
+ # Query values for the attributes of the pixel format, and then set the
207
+ # corresponding attributes of the window config.
208
+ for name, attr in _gl_attributes.items():
209
+ vals = c_int()
210
+ self._pixel_format.getValues_forAttribute_forVirtualScreen_(byref(vals), attr, 0)
211
+ setattr(self, name, vals.value)
212
+
213
+ # Set these attributes so that we can run pyglet.info.
214
+ for name, value in _fake_gl_attributes.items():
215
+ setattr(self, name, value)
216
+
217
+ # Update the minor/major version from profile if (Mountain)Lion
218
+ if _os_x_version >= os_x_release['lion']:
219
+ vals = c_int()
220
+ self._pixel_format.getValues_forAttribute_forVirtualScreen_(
221
+ byref(vals),
222
+ cocoapy.NSOpenGLPFAOpenGLProfile,
223
+ 0,
224
+ )
225
+
226
+ if vals.value == cocoapy.NSOpenGLProfileVersion4_1Core:
227
+ self.major_version = 4
228
+ self.minor_version = 1
229
+ elif vals.value == cocoapy.NSOpenGLProfileVersion3_2Core:
230
+ self.major_version = 3
231
+ self.minor_version = 2
232
+ else:
233
+ self.major_version = 2
234
+ self.minor_version = 1
235
+
236
+ def create_context(self, opengl_backend: OpenGLBackend, share: CocoaContext | None) -> CocoaContext:
237
+ # Determine the shared NSOpenGLContext.
238
+ from pyglet.graphics.api.gl.cocoa.context import CocoaContext, NSOpenGLContext # noqa: PLC0415
239
+
240
+ if share:
241
+ share_context = share._nscontext # noqa: SLF001
242
+ else:
243
+ share_context = None
244
+
245
+ # Create a new NSOpenGLContext.
246
+ nscontext = NSOpenGLContext.alloc().initWithFormat_shareContext_(
247
+ self._pixel_format,
248
+ share_context)
249
+
250
+ if self.config.transparent_framebuffer:
251
+ opaque = c_int(0)
252
+ nscontext.setValues_forParameter_(byref(opaque), cocoapy.NSOpenGLCPSurfaceOpacity)
253
+
254
+ # No longer needed after context creation.
255
+ if self._pixel_format:
256
+ self._pixel_format.release()
257
+ self._pixel_format = None
258
+
259
+ return CocoaContext(opengl_backend, self._window, self, nscontext, share)
260
+
261
+ def apply_format(self) -> None:
262
+ pass