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,267 @@
1
+ from __future__ import annotations
2
+
3
+ import warnings
4
+ from ctypes import c_int, c_uint, sizeof, byref
5
+ from dataclasses import asdict
6
+
7
+ from typing import TYPE_CHECKING
8
+ from pyglet.config.gl import GLSurfaceConfig
9
+ from pyglet.libs.win32 import PIXELFORMATDESCRIPTOR, _gdi32, wglext_arb, wgl
10
+ from pyglet.libs.win32.constants import PFD_DRAW_TO_WINDOW, PFD_SUPPORT_OPENGL, PFD_DOUBLEBUFFER, \
11
+ PFD_DOUBLEBUFFER_DONTCARE, PFD_STEREO, PFD_STEREO_DONTCARE, PFD_DEPTH_DONTCARE, PFD_TYPE_RGBA
12
+ from pyglet.libs.win32.wgl import WGLFunctions
13
+ from pyglet.util import asstr
14
+
15
+ if TYPE_CHECKING:
16
+ from pyglet.config import OpenGLConfig
17
+ from pyglet.window.win32 import Win32Window
18
+ from pyglet.graphics.api import OpenGLBackend
19
+ from pyglet.graphics.api.gl.win32.context import Win32ARBContext, Win32Context
20
+
21
+
22
+ class _WGL:
23
+ """This is a staging area for WGL function loading.
24
+
25
+ WGL requires a context to be active before many functions can be called. Paradoxically, to create a WGL context,
26
+ another context has to already exist. Therefore, a bare temporary context is created and then destroyed after WGL
27
+ proc addresses are loaded and stored.
28
+ """
29
+ def __init__(self):
30
+ self._funcs = None
31
+ self._loaded = False
32
+ self._extensions = []
33
+
34
+ @property
35
+ def funcs(self):
36
+ return self._funcs
37
+
38
+ @property
39
+ def loaded(self) -> bool:
40
+ return self._loaded
41
+
42
+ def have_extension(self, extension: str) -> bool:
43
+ return extension in self._extensions
44
+
45
+ def create(self) -> bool:
46
+ from pyglet.window import _shadow_window # noqa: PLC0415
47
+ funcs = self._initialize_wgl_funcs(_shadow_window)
48
+ if funcs:
49
+ self._loaded = True
50
+ self._funcs = funcs
51
+ self._extensions = asstr(funcs.wglGetExtensionsStringEXT()).split()
52
+ return True
53
+
54
+ return False
55
+
56
+ def _initialize_wgl_funcs(self, shadow_window: Win32Window) -> WGLFunctions | None:
57
+ """Creates a temporary context, creates WGL functions to proc addresses, then destroys the context."""
58
+ pfd = PIXELFORMATDESCRIPTOR()
59
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR)
60
+ pfd.nVersion = 1
61
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER
62
+ pfd.iPixelType = PFD_TYPE_RGBA
63
+ pfd.cColorBits = 24
64
+
65
+ shadow_dc = shadow_window.dc
66
+ assert shadow_dc is not None
67
+
68
+ # !!! # Will break transparent windows if using the main visible window.
69
+ # Must use the shadow window here as once a pixel format is set for a Window it cannot be altered.
70
+ pf = _gdi32.ChoosePixelFormat(shadow_dc, byref(pfd))
71
+ if pf:
72
+ if not _gdi32.SetPixelFormat(shadow_dc, pf, byref(pfd)):
73
+ warnings.warn("Unable to set pixel format.")
74
+ return None
75
+ else:
76
+ warnings.warn("Unable to find a pixel format.")
77
+ return None
78
+
79
+ dummy_ctx = wgl.wglCreateContext(shadow_dc)
80
+ if not dummy_ctx:
81
+ warnings.warn("Unable to create dummy context.")
82
+ return None
83
+
84
+ current_dc = wgl.wglGetCurrentDC()
85
+ current_ctx = wgl.wglGetCurrentContext()
86
+
87
+ if not wgl.wglMakeCurrent(shadow_dc, dummy_ctx):
88
+ print("Unable to make dummy context current.")
89
+ # Set back to old context and dc and delete dummy context.
90
+ wgl.wglMakeCurrent(current_dc, current_ctx)
91
+ wgl.wglDeleteContext(dummy_ctx)
92
+ return None
93
+
94
+ funcs = WGLFunctions()
95
+ wgl.wglMakeCurrent(current_dc, current_ctx)
96
+ wgl.wglDeleteContext(dummy_ctx)
97
+ return funcs
98
+
99
+ # A global WGL instance object that has retrieved all the proc addresses for WGL functions.
100
+ _global_wgl = _WGL()
101
+
102
+ def match(config: OpenGLConfig, window: Win32Window) -> GLSurfaceConfig | None:
103
+ if not _global_wgl.loaded:
104
+ _global_wgl.create()
105
+
106
+ if _global_wgl.have_extension('WGL_ARB_pixel_format'):
107
+ finalized_config = _get_arb_pixel_format_matching_configs(config, window)
108
+ else:
109
+ finalized_config = _get_pixel_format_descriptor_matching_configs(config, window)
110
+
111
+ return finalized_config
112
+
113
+ def _get_pixel_format_descriptor_matching_configs(config: OpenGLConfig, window: Win32Window) -> GLLegacyConfig | None:
114
+ """Get matching configs using standard PIXELFORMATDESCRIPTOR technique."""
115
+ pfd = PIXELFORMATDESCRIPTOR()
116
+ pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR)
117
+ pfd.nVersion = 1
118
+ pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
119
+
120
+ if config.double_buffer:
121
+ pfd.dwFlags |= PFD_DOUBLEBUFFER
122
+ else:
123
+ pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE
124
+
125
+ if config.stereo:
126
+ pfd.dwFlags |= PFD_STEREO
127
+ else:
128
+ pfd.dwFlags |= PFD_STEREO_DONTCARE
129
+
130
+ # Not supported in pyglet API: swap_copy: PFD_SWAP_COPY and swap_exchange: PFD_SWAP_EXCHANGE
131
+
132
+ if not config.depth_size:
133
+ pfd.dwFlags |= PFD_DEPTH_DONTCARE
134
+
135
+ pfd.iPixelType = PFD_TYPE_RGBA
136
+ pfd.cColorBits = config.buffer_size or 0
137
+ pfd.cRedBits = config.red_size or 0
138
+ pfd.cGreenBits = config.green_size or 0
139
+ pfd.cBlueBits = config.blue_size or 0
140
+ pfd.cAlphaBits = config.alpha_size or 0
141
+ pfd.cAccumRedBits = config.accum_red_size or 0
142
+ pfd.cAccumGreenBits = config.accum_green_size or 0
143
+ pfd.cAccumBlueBits = config.accum_blue_size or 0
144
+ pfd.cAccumAlphaBits = config.accum_alpha_size or 0
145
+ pfd.cDepthBits = config.depth_size or 0
146
+ pfd.cStencilBits = config.stencil_size or 0
147
+ pfd.cAuxBuffers = config.aux_buffers or 0
148
+
149
+ pf = _gdi32.ChoosePixelFormat(window.dc, byref(pfd))
150
+ if pf:
151
+ return GLLegacyConfig(window, pf, config)
152
+
153
+ return None
154
+
155
+ def _get_arb_pixel_format_matching_configs(config: OpenGLConfig, window: Win32Window) -> GLSurfaceConfig | None:
156
+ """Get configs using the WGL_ARB_pixel_format extension.
157
+
158
+ This method assumes a (dummy) GL context is already created.
159
+ """
160
+ # # Check for required extensions
161
+ # if (self.sample_buffers or self.samples) and not global_backend.have_extension('GL_ARB_multisample'):
162
+ # return None
163
+
164
+ # Construct array of attributes
165
+ attrs = []
166
+ for name, value in asdict(config).items():
167
+ attr = GLSurfaceConfig.attribute_ids.get(name, None)
168
+ if attr and value is not None:
169
+ attrs.extend([attr, int(value)])
170
+ attrs.append(0)
171
+ attrs = (c_int * len(attrs))(*attrs)
172
+
173
+ pformats = (c_int * 16)()
174
+ nformats = c_uint(16)
175
+
176
+ _global_wgl.funcs.wglChoosePixelFormatARB(window.dc, attrs, None, nformats, pformats, nformats)
177
+
178
+ # Only choose the first format, because these are in order of best matching from driver.
179
+ # (Maybe not always the case?)
180
+ if pformats[0]:
181
+ pf = pformats[:nformats.value][0]
182
+ m =GLSurfaceConfig(window, pf, config)
183
+ return m
184
+
185
+ return None
186
+
187
+
188
+
189
+ class GLLegacyConfig(GLSurfaceConfig):
190
+ def __init__(self, window: Win32Window, pf: int, user_config: OpenGLConfig) -> None:
191
+ super().__init__(window, user_config, pf)
192
+ self._pf = pf
193
+ self._pfd = PIXELFORMATDESCRIPTOR()
194
+
195
+ _gdi32.DescribePixelFormat(window.dc, pf, sizeof(PIXELFORMATDESCRIPTOR), byref(self._pfd))
196
+
197
+ self.double_buffer = bool(self._pfd.dwFlags & PFD_DOUBLEBUFFER)
198
+ self.sample_buffers = 0
199
+ self.samples = 0
200
+ self.stereo = bool(self._pfd.dwFlags & PFD_STEREO)
201
+ self.buffer_size = self._pfd.cColorBits
202
+ self.red_size = self._pfd.cRedBits
203
+ self.green_size = self._pfd.cGreenBits
204
+ self.blue_size = self._pfd.cBlueBits
205
+ self.alpha_size = self._pfd.cAlphaBits
206
+ self.accum_red_size = self._pfd.cAccumRedBits
207
+ self.accum_green_size = self._pfd.cAccumGreenBits
208
+ self.accum_blue_size = self._pfd.cAccumBlueBits
209
+ self.accum_alpha_size = self._pfd.cAccumAlphaBits
210
+ self.depth_size = self._pfd.cDepthBits
211
+ self.stencil_size = self._pfd.cStencilBits
212
+ self.aux_buffers = self._pfd.cAuxBuffers
213
+
214
+ def apply_format(self) -> None:
215
+ _gdi32.SetPixelFormat(self._window.dc, self._pf, byref(self._pfd))
216
+
217
+ def create_context(self, opengl_backend: OpenGLBackend, share: Win32ARBContext | None) -> Win32ARBContext | Win32Context:
218
+ from pyglet.graphics.api.gl.win32.context import Win32Context # noqa: PLC0415
219
+ return Win32Context(opengl_backend, self._window, self, share)
220
+
221
+
222
+ class GLSurfaceConfig(GLSurfaceConfig):
223
+ attribute_ids = { # noqa: RUF012
224
+ 'double_buffer': wglext_arb.WGL_DOUBLE_BUFFER_ARB,
225
+ 'stereo': wglext_arb.WGL_STEREO_ARB,
226
+ 'buffer_size': wglext_arb.WGL_COLOR_BITS_ARB,
227
+ 'aux_buffers': wglext_arb.WGL_AUX_BUFFERS_ARB,
228
+ 'sample_buffers': wglext_arb.WGL_SAMPLE_BUFFERS_ARB,
229
+ 'samples': wglext_arb.WGL_SAMPLES_ARB,
230
+ 'red_size': wglext_arb.WGL_RED_BITS_ARB,
231
+ 'green_size': wglext_arb.WGL_GREEN_BITS_ARB,
232
+ 'blue_size': wglext_arb.WGL_BLUE_BITS_ARB,
233
+ 'alpha_size': wglext_arb.WGL_ALPHA_BITS_ARB,
234
+ 'depth_size': wglext_arb.WGL_DEPTH_BITS_ARB,
235
+ 'stencil_size': wglext_arb.WGL_STENCIL_BITS_ARB,
236
+ 'accum_red_size': wglext_arb.WGL_ACCUM_RED_BITS_ARB,
237
+ 'accum_green_size': wglext_arb.WGL_ACCUM_GREEN_BITS_ARB,
238
+ 'accum_blue_size': wglext_arb.WGL_ACCUM_BLUE_BITS_ARB,
239
+ 'accum_alpha_size': wglext_arb.WGL_ACCUM_ALPHA_BITS_ARB,
240
+ }
241
+
242
+ def __init__(self, window: Win32Window, pf: int, user_config: OpenGLConfig) -> None:
243
+ super().__init__(window, user_config, pf)
244
+ self._pf = pf
245
+
246
+ names = list(self.attribute_ids.keys())
247
+ attrs = list(self.attribute_ids.values())
248
+ attrs = (c_int * len(attrs))(*attrs)
249
+ values = (c_int * len(attrs))()
250
+ _global_wgl.funcs.wglGetPixelFormatAttribivARB(window.dc, pf, 0, len(attrs), attrs, values)
251
+
252
+ for name, value in zip(names, values):
253
+ setattr(self, name, value)
254
+
255
+ def apply_format(self) -> None:
256
+ _gdi32.SetPixelFormat(self._window.dc, self._pf, None)
257
+
258
+ def create_context(
259
+ self, opengl_backend: OpenGLBackend, share: Win32ARBContext | None,
260
+ ) -> Win32ARBContext | Win32Context:
261
+ #super().create_context(opengl_backend, share)
262
+ from pyglet.graphics.api.gl.win32.context import Win32ARBContext, Win32Context # noqa: PLC0415
263
+ if _global_wgl.have_extension('WGL_ARB_create_context'):
264
+ # Graphics adapters that ONLY support up to OpenGL 3.1/3.2 should be using the Win32ARBContext class.
265
+ return Win32ARBContext(opengl_backend, self._window, self, share)
266
+
267
+ return Win32Context(opengl_backend, self._window, self, share)
@@ -0,0 +1,142 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import asdict
4
+ from typing import NoReturn, TYPE_CHECKING
5
+
6
+ from ctypes import c_int, cast, byref, POINTER, _Pointer
7
+
8
+ from pyglet.libs.linux.glx import glx
9
+ from pyglet.libs.linux.x11 import xlib
10
+ from pyglet.libs.linux.x11.xrender import XRenderFindVisualFormat
11
+ from pyglet.config import SurfaceConfig
12
+
13
+ if TYPE_CHECKING:
14
+ from pyglet.graphics.api.gl.xlib.context import XlibContext
15
+ from pyglet.graphics.api import OpenGLBackend
16
+ from pyglet.config import OpenGLConfig
17
+ from pyglet.graphics.api.gl.xlib import glx_info
18
+ from pyglet.window.xlib import XlibWindow
19
+
20
+
21
+ def match(config: OpenGLConfig, window: XlibWindow) -> XlibGLSurfaceConfig | None:
22
+ x_display = window._x_display # noqa: SLF001
23
+ x_screen = window._x_screen_id # noqa: SLF001
24
+
25
+ # Construct array of attributes
26
+ attrs = []
27
+ for name, value in asdict(config).items():
28
+ attr = XlibGLSurfaceConfig.attribute_ids.get(name, None)
29
+ if attr and value is not None:
30
+ attrs.extend([attr, int(value)])
31
+
32
+ attrs.extend([glx.GLX_X_RENDERABLE, True])
33
+ attrs.extend([0, 0]) # attrib_list must be null terminated
34
+
35
+ attrib_list = (c_int * len(attrs))(*attrs)
36
+
37
+ elements = c_int()
38
+ configs = glx.glXChooseFBConfig(x_display, x_screen, attrib_list, byref(elements))
39
+ if not configs:
40
+ return None
41
+
42
+ configs = cast(configs, POINTER(glx.GLXFBConfig * elements.value)).contents
43
+
44
+ result = [XlibGLSurfaceConfig(window, c, config) for c in configs]
45
+
46
+ # If we intend to have a transparent framebuffer.
47
+ if config.transparent_framebuffer:
48
+ result = [fb_cf for fb_cf in result if fb_cf.transparent]
49
+
50
+ # If we intend to have a transparent framebuffer.
51
+ if config.transparent_framebuffer:
52
+ result = [fb_cf for fb_cf in result if fb_cf.transparent]
53
+
54
+ # Can't free array until all XlibGLConfig's are GC'd. Too much
55
+ # hassle, live with leak. XXX
56
+ # xlib.XFree(configs)
57
+ return result[0]
58
+
59
+
60
+ class XlibGLSurfaceConfig(SurfaceConfig):
61
+ _glx_info: glx_info.GLXInfo
62
+
63
+ attribute_ids = { # noqa: RUF012
64
+ 'buffer_size': glx.GLX_BUFFER_SIZE,
65
+ 'level': glx.GLX_LEVEL, # Not supported
66
+ 'double_buffer': glx.GLX_DOUBLEBUFFER,
67
+ 'stereo': glx.GLX_STEREO,
68
+ 'aux_buffers': glx.GLX_AUX_BUFFERS,
69
+ 'red_size': glx.GLX_RED_SIZE,
70
+ 'green_size': glx.GLX_GREEN_SIZE,
71
+ 'blue_size': glx.GLX_BLUE_SIZE,
72
+ 'alpha_size': glx.GLX_ALPHA_SIZE,
73
+ 'depth_size': glx.GLX_DEPTH_SIZE,
74
+ 'stencil_size': glx.GLX_STENCIL_SIZE,
75
+ 'accum_red_size': glx.GLX_ACCUM_RED_SIZE,
76
+ 'accum_green_size': glx.GLX_ACCUM_GREEN_SIZE,
77
+ 'accum_blue_size': glx.GLX_ACCUM_BLUE_SIZE,
78
+ 'accum_alpha_size': glx.GLX_ACCUM_ALPHA_SIZE,
79
+
80
+ 'sample_buffers': glx.GLX_SAMPLE_BUFFERS,
81
+ 'samples': glx.GLX_SAMPLES,
82
+
83
+ # Not supported in current pyglet API:
84
+ # 'render_type': glx.GLX_RENDER_TYPE,
85
+ # 'drawable_type': glx.GLX_DRAWABLE_TYPE,
86
+ # 'config_caveat': glx.GLX_CONFIG_CAVEAT,
87
+ # 'transparent_type': glx.GLX_TRANSPARENT_TYPE,
88
+ # 'transparent_index_value': glx.GLX_TRANSPARENT_INDEX_VALUE,
89
+ # 'transparent_red_value': glx.GLX_TRANSPARENT_RED_VALUE,
90
+ # 'transparent_green_value': glx.GLX_TRANSPARENT_GREEN_VALUE,
91
+ # 'transparent_blue_value': glx.GLX_TRANSPARENT_BLUE_VALUE,
92
+ # 'transparent_alpha_value': glx.GLX_TRANSPARENT_ALPHA_VALUE,
93
+
94
+ # Used internally
95
+ 'x_renderable': glx.GLX_X_RENDERABLE,
96
+ }
97
+
98
+ def __init__(self, window: XlibWindow, fbconfig: glx.GLXFBConfig,
99
+ config: OpenGLConfig) -> None:
100
+ super().__init__(window, config, fbconfig)
101
+
102
+ self.fbconfig = fbconfig
103
+ self.transparent = False
104
+
105
+ for name, attr in self.attribute_ids.items():
106
+ value = c_int()
107
+ result = glx.glXGetFBConfigAttrib(self._window._x_display, self.fbconfig, attr, # noqa: SLF001
108
+ byref(value))
109
+ if result >= 0:
110
+ setattr(self, name, value.value)
111
+
112
+ # If user intends for a transparent framebuffer, the visual info needs to be
113
+ # queried for it. Even if a config supports alpha_size 8 and depth_size 32, there is no
114
+ # guarantee the visual info supports that same configuration.
115
+ if config.transparent_framebuffer:
116
+ xvi_ptr = glx.glXGetVisualFromFBConfig(self._window._x_display, self.fbconfig) # noqa: SLF001
117
+ if xvi_ptr:
118
+ self.transparent = window._is_visual_transparent(xvi_ptr.contents.visual) # noqa: SLF001
119
+ xlib.XFree(xvi_ptr)
120
+
121
+ def _is_visual_transparent(self, visual: _Pointer[xlib.Visual]) -> bool:
122
+ if not XRenderFindVisualFormat:
123
+ return False
124
+
125
+ xrender_format = XRenderFindVisualFormat(self.canvas.display._display, visual)
126
+ return xrender_format and xrender_format.contents.direct.alphaMask != 0
127
+
128
+ def get_visual_info(self) -> glx.XVisualInfo:
129
+ return glx.glXGetVisualFromFBConfig(self._window._x_display, self.fbconfig).contents # noqa: SLF001
130
+
131
+ def create_context(self, opengl_backend: OpenGLBackend, share: XlibContext | None) -> XlibContext:
132
+ from pyglet.graphics.api.gl.xlib.context import XlibContext # noqa: PLC0415
133
+ return XlibContext(opengl_backend, self._window, self, share)
134
+
135
+ def _create_glx_context(self, _share: None) -> NoReturn:
136
+ raise NotImplementedError
137
+
138
+ def apply_format(self) -> None:
139
+ pass
140
+
141
+ def is_complete(self) -> bool:
142
+ return True
pyglet/customtypes.py CHANGED
@@ -1,9 +1,11 @@
1
1
  """Holds type aliases used throughout the codebase."""
2
+ from __future__ import annotations
2
3
  import ctypes
3
4
  import sys
4
5
 
5
- from typing import Union, Literal
6
+ from typing import Union, Literal, Type, Protocol, Tuple
6
7
 
8
+ from ctypes import _SimpleCData, _Pointer # type: ignore # noqa: PGH003
7
9
 
8
10
  if sys.version_info >= (3, 12):
9
11
  from collections.abc import Buffer
@@ -16,8 +18,47 @@ AnchorX = Literal["left", "center", "right"]
16
18
  AnchorY = Literal["top", "bottom", "center", "baseline"]
17
19
  ContentVAlign = Literal["bottom", "center", "top"]
18
20
 
21
+ Number = Union[int, float]
22
+
23
+ RGBColor = Tuple[Number, Number, Number]
24
+ RGBAColor = Tuple[Number, Number, Number, Number]
25
+
26
+ DataTypes = Literal[
27
+ 'f', # float
28
+ 'i', # int
29
+ 'I', # unsigned int
30
+ 'h', # short
31
+ 'H', # unsigned short
32
+ 'b', # byte
33
+ 'B', # unsigned byte
34
+ 'q', # long long
35
+ 'Q', # unsigned long long
36
+ '?', # bool
37
+ 'd', # double
38
+ ]
39
+
40
+ CType = Type[_SimpleCData]
41
+ CTypesPointer = _Pointer
42
+
43
+
44
+
45
+ class ScissorProtocol(Protocol):
46
+ x: int
47
+ y: int
48
+ width: int
49
+ height: int
50
+
19
51
 
20
52
 
21
53
  __all__ = [
22
- "Buffer", "HorizontalAlign", "AnchorX", "AnchorY", "ContentVAlign"
54
+ "AnchorX",
55
+ "AnchorY",
56
+ "Buffer",
57
+ "CType",
58
+ "CTypesPointer",
59
+ "ContentVAlign",
60
+ "DataTypes",
61
+ "HorizontalAlign",
62
+ "RGBAColor",
63
+ "RGBColor",
23
64
  ]
@@ -29,25 +29,27 @@ _is_pyglet_doc_run = hasattr(sys, "is_pyglet_doc_run") and sys.is_pyglet_doc_run
29
29
 
30
30
 
31
31
  if _is_pyglet_doc_run:
32
- from pyglet.display.base import Display, Screen, Canvas, ScreenMode
32
+ from pyglet.display.base import Display, Screen, ScreenMode
33
33
  else:
34
34
  from pyglet import compat_platform, options
35
35
  if options['headless']:
36
36
  from pyglet.display.headless import HeadlessDisplay as Display
37
37
  from pyglet.display.headless import HeadlessScreen as Screen
38
- from pyglet.display.headless import HeadlessCanvas as Canvas
39
38
  elif compat_platform == 'darwin':
40
39
  from pyglet.display.cocoa import CocoaDisplay as Display
41
40
  from pyglet.display.cocoa import CocoaScreen as Screen
42
- from pyglet.display.cocoa import CocoaCanvas as Canvas
43
41
  elif compat_platform in ('win32', 'cygwin'):
44
42
  from pyglet.display.win32 import Win32Display as Display
45
43
  from pyglet.display.win32 import Win32Screen as Screen
46
- from pyglet.display.win32 import Win32Canvas as Canvas
44
+ elif compat_platform == 'linux' and options.wayland:
45
+ from pyglet.display.wayland import WaylandDisplay as Display
46
+ from pyglet.display.wayland import WaylandScreen as Screen
47
47
  elif compat_platform == 'linux':
48
48
  from pyglet.display.xlib import XlibDisplay as Display
49
49
  from pyglet.display.xlib import XlibScreen as Screen
50
- from pyglet.display.xlib import XlibCanvas as Canvas
50
+ elif compat_platform == 'emscripten':
51
+ from pyglet.display.emscripten import EmscriptenDisplay as Display
52
+ from pyglet.display.emscripten import EmscriptenScreen as Screen
51
53
  else:
52
54
  msg = f"A display interface for '{compat_platform}' is not yet implemented."
53
55
  raise NotImplementedError(msg)
@@ -77,4 +79,4 @@ def get_display() -> Display:
77
79
  return Display()
78
80
 
79
81
 
80
- __all__ = ['Display', 'Screen', 'Canvas', 'ScreenMode', 'get_display']
82
+ __all__ = ['Display', 'Screen', 'ScreenMode', 'get_display']
pyglet/display/base.py CHANGED
@@ -3,10 +3,9 @@ from __future__ import annotations
3
3
  import abc
4
4
  from typing import TYPE_CHECKING, Literal
5
5
 
6
- from pyglet import app, display, gl, window
6
+ from pyglet import app, display
7
7
 
8
8
  if TYPE_CHECKING:
9
- from pyglet.gl import Config
10
9
  from pyglet.window import BaseWindow
11
10
 
12
11
 
@@ -26,8 +25,8 @@ class Display:
26
25
  default is usually ``":1"``. On X11, :attr:`x_screen` gives the X
27
26
  screen number to use with this display. A pyglet display can only be
28
27
  used with one X screen; open multiple display connections to access
29
- multiple X screens.
30
-
28
+ multiple X screens.
29
+
31
30
  Note that TwinView, Xinerama, xrandr and other extensions present
32
31
  multiple monitors on a single X screen; this is usually the preferred
33
32
  mechanism for working with multiple monitors under X11 and allows each
@@ -100,52 +99,6 @@ class Screen(abc.ABC):
100
99
  def __repr__(self) -> str:
101
100
  return f"{self.__class__.__name__}(x={self.x}, y={self.y}, width={self.width}, height={self.height})"
102
101
 
103
- def get_best_config(self, template: Config = None) -> Config:
104
- """Get the best available GL config.
105
-
106
- Any required attributes can be specified in ``template``. If
107
- no configuration matches the template,
108
- :class:`~pyglet.window.NoSuchConfigException` will be raised.
109
- A configuration supported by the platform that best fulfils
110
- the needs described by the template.
111
-
112
- :deprecated: Use :meth:`pyglet.gl.Config.match`.
113
-
114
- Args:
115
- template:
116
- A configuration with desired attributes filled in.
117
- """
118
- configs = None
119
- if template is None:
120
- for template_config in [gl.Config(double_buffer=True, depth_size=24, major_version=3, minor_version=3),
121
- gl.Config(double_buffer=True, depth_size=16, major_version=3, minor_version=3),
122
- None]:
123
- try:
124
- configs = self.get_matching_configs(template_config)
125
- break
126
- except window.NoSuchConfigException:
127
- pass
128
- else:
129
- configs = self.get_matching_configs(template)
130
- if not configs:
131
- raise window.NoSuchConfigException()
132
- return configs[0]
133
-
134
- def get_matching_configs(self, template: Config) -> list[Config]:
135
- """Get a list of configs that match a specification.
136
-
137
- Any attributes specified in `template` will have values equal
138
- to or greater in each returned config. If no configs satisfy
139
- the template, an empty list is returned.
140
-
141
- :deprecated: Use :meth:`pyglet.gl.Config.match`.
142
-
143
- Args:
144
- template:
145
- A configuration with desired attributes filled in.
146
- """
147
- raise NotImplementedError('abstract')
148
-
149
102
  def get_modes(self) -> list[ScreenMode]:
150
103
  """Get a list of screen modes supported by this screen.
151
104
 
@@ -273,16 +226,3 @@ class ScreenMode:
273
226
  def __repr__(self) -> str:
274
227
  return f'{self.__class__.__name__}(width={self.width!r}, height={self.height!r}, depth={self.depth!r}, rate={self.rate})'
275
228
 
276
-
277
- class Canvas:
278
- """Abstract drawing area.
279
-
280
- Canvases are used internally by pyglet to represent drawing areas --
281
- either within a window or full-screen.
282
-
283
- .. versionadded:: 1.2
284
- """
285
-
286
- def __init__(self, display: Display) -> None:
287
- self.display = display
288
- """Display this canvas was created on."""
pyglet/display/cocoa.py CHANGED
@@ -1,13 +1,20 @@
1
1
  # Note: The display mode API used here is Mac OS 10.6 only.
2
2
  from __future__ import annotations
3
3
 
4
- from ctypes import c_uint32, c_void_p, byref
4
+ from ctypes import byref, c_uint32, c_void_p
5
5
 
6
- from .base import Canvas, Display, Screen, ScreenMode
7
- from pyglet.libs.darwin.cocoapy import CGDirectDisplayID, quartz, cf, ObjCClass, get_NSString
8
- from pyglet.libs.darwin.cocoapy import cfstring_to_string, cfarray_to_list
9
6
  from pyglet.libs.darwin import NSDeviceResolution
10
-
7
+ from pyglet.libs.darwin.cocoapy import (
8
+ CGDirectDisplayID,
9
+ ObjCClass,
10
+ cf,
11
+ cfarray_to_list,
12
+ cfstring_to_string,
13
+ get_NSString,
14
+ quartz,
15
+ )
16
+
17
+ from .base import Display, Screen, ScreenMode
11
18
 
12
19
  NSScreen = ObjCClass('NSScreen')
13
20
 
@@ -82,10 +89,6 @@ class CocoaScreen(Screen):
82
89
 
83
90
  return ratio
84
91
 
85
- def get_matching_configs(self, template):
86
- canvas = CocoaCanvas(self.display, self, None)
87
- return template.match(canvas)
88
-
89
92
  def get_modes(self):
90
93
  cgmodes = c_void_p(quartz.CGDisplayCopyAllDisplayModes(self._cg_display_id, None))
91
94
  modes = [CocoaScreenMode(self, cgmode) for cgmode in cfarray_to_list(cgmodes)]
@@ -161,11 +164,3 @@ class CocoaScreenMode(ScreenMode):
161
164
  if pixelEncoding == IO16BitDirectPixels: return 16
162
165
  if pixelEncoding == IO32BitDirectPixels: return 32
163
166
  return 0
164
-
165
-
166
- class CocoaCanvas(Canvas):
167
-
168
- def __init__(self, display, screen, nsview):
169
- super().__init__(display)
170
- self.screen = screen
171
- self.nsview = nsview
@@ -0,0 +1,39 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Literal
4
+
5
+ from pyglet.display.base import Display, Screen
6
+ import js
7
+
8
+ class EmscriptenDisplay(Display):
9
+
10
+ def __init__(self):
11
+ super().__init__()
12
+
13
+ def get_screens(self):
14
+ return [EmscriptenScreen(self)]
15
+
16
+
17
+ class EmscriptenScreen(Screen):
18
+ def __init__(self, display: EmscriptenDisplay):
19
+ width = js.window.screen.width
20
+ height = js.window.screen.height
21
+ super().__init__(display, 0, 0, width, height)
22
+
23
+ def get_display_id(self) -> int:
24
+ return 0
25
+
26
+ def get_monitor_name(self) -> str | Literal["Unknown"]:
27
+ return "BROWSER"
28
+
29
+ def get_modes(self):
30
+ pass
31
+
32
+ def get_mode(self):
33
+ pass
34
+
35
+ def set_mode(self, mode):
36
+ pass
37
+
38
+ def restore_mode(self):
39
+ pass