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
@@ -38,7 +38,7 @@ from contextlib import contextmanager
38
38
 
39
39
  from ctypes import *
40
40
  from ctypes import util
41
- from typing import Type, TypeVar, Sequence, Any
41
+ from typing import Type, TypeVar, Sequence, Any, Callable
42
42
 
43
43
  from .cocoatypes import *
44
44
 
@@ -66,33 +66,14 @@ libc = cdll.LoadLibrary(util.find_library('c'))
66
66
  libc.free.restype = None
67
67
  libc.free.argtypes = [c_void_p]
68
68
 
69
- libc.sysctlbyname.argtypes = [c_char_p, c_void_p, POINTER(c_size_t), c_void_p, c_size_t]
70
- libc.sysctlbyname.restype = c_int
69
+ _NSConcreteGlobalBlock = c_void_p.in_dll(libc, "_NSConcreteGlobalBlock")
71
70
 
72
- def _sysctl_get(name: str) -> str:
73
- name_bytes = name.encode("utf-8")
74
-
75
- size = c_size_t()
76
- # Gets buffer size.
77
- libc.sysctlbyname(name_bytes, None, byref(size), None, 0)
78
-
79
- buf = create_string_buffer(size.value)
80
- libc.sysctlbyname(name_bytes, buf, byref(size), None, 0)
81
- return buf.value.decode("utf-8")
82
-
83
- def get_chip_model() -> str:
84
- """Return Apple chip model name.
85
-
86
- For example: "Apple M2"
87
- """
88
- try:
89
- # Newer field.
90
- return _sysctl_get("machdep.cpu.brand_string")
91
- except Exception:
92
- try:
93
- return _sysctl_get("hw.model")
94
- except Exception:
95
- return "Unknown"
71
+ BLOCK_IS_NOESCAPE = (1 << 23)
72
+ BLOCK_HAS_COPY_DISPOSE = (1 << 25)
73
+ BLOCK_HAS_CTOR = (1 << 26)
74
+ BLOCK_IS_GLOBAL = (1 << 28)
75
+ BLOCK_HAS_STRET = (1 << 29)
76
+ BLOCK_HAS_SIGNATURE = (1 << 30)
96
77
 
97
78
  ######################################################################
98
79
 
@@ -462,6 +443,9 @@ OBJC_ASSOCIATION_ASSIGN = 0 # Weak reference to the associated object.
462
443
  OBJC_ASSOCIATION_RETAIN = 0x0301 # Strong reference to the associated object. The association is made atomically.
463
444
  OBJC_ASSOCIATION_COPY = 0x0303 # Specifies that the associated object is copied. The association is made atomically.
464
445
 
446
+ class MissingEncodingType(Exception):
447
+ """If an encoding type is missing."""
448
+
465
449
 
466
450
  def ensure_bytes(x: bytes | str) -> bytes:
467
451
  """Attempt to encode an object as :py:class:`bytes`.
@@ -820,7 +804,7 @@ def send_super(receiver, selName, *args, superclass_name=None, **kwargs):
820
804
  cfunctype_table = {}
821
805
 
822
806
 
823
- def parse_type_encoding(encoding):
807
+ def parse_type_encoding(encoding: bytes):
824
808
  """Takes a type encoding string and outputs a list of the separated type codes.
825
809
  Currently does not handle unions or bitfields and strips out any field width
826
810
  specifiers or type specifiers from the encoding. For Python 3.2+, encoding is
@@ -875,6 +859,9 @@ def parse_type_encoding(encoding):
875
859
  if typecode and typecode[-1:] == b'^':
876
860
  # Previous char was pointer specifier, so keep going.
877
861
  typecode += c
862
+ elif typecode and c == b'?' and typecode[-1:] == b'@':
863
+ # Block type, combine them.
864
+ typecode += c
878
865
  else:
879
866
  # Add previous type code to the list.
880
867
  if typecode:
@@ -911,8 +898,10 @@ def cfunctype_for_encoding(encoding):
911
898
  argtypes.append(typecodes[code])
912
899
  elif code[0:1] == b'^' and code[1:] in typecodes:
913
900
  argtypes.append(POINTER(typecodes[code[1:]]))
901
+ elif code[0:2] == b'@?':
902
+ argtypes.append(c_void_p)
914
903
  else:
915
- raise Exception('unknown type encoding: ' + code)
904
+ raise Exception(f'unknown type encoding: {code}')
916
905
 
917
906
  cfunctype = CFUNCTYPE(*argtypes)
918
907
 
@@ -1011,11 +1000,10 @@ class ObjCMethod:
1011
1000
  # Get types for all the arguments.
1012
1001
  try:
1013
1002
  self.argtypes = [self.ctype_for_encoding(t) for t in self.argument_types]
1014
- except:
1015
- # print(f'no argtypes encoding for {self.name} ({self.argument_types})')
1003
+ except MissingEncodingType as e:
1004
+ #print(f'no argtypes encoding for {self.name}: {e}')
1016
1005
  self.argtypes = None
1017
1006
  # Get types for the return type.
1018
-
1019
1007
  try:
1020
1008
  if self.return_type == b'@':
1021
1009
  self.restype = ObjCInstance
@@ -1032,7 +1020,7 @@ class ObjCMethod:
1032
1020
  libc.free(return_type_ptr)
1033
1021
 
1034
1022
 
1035
- def ctype_for_encoding(self, encoding):
1023
+ def ctype_for_encoding(self, encoding: bytes):
1036
1024
  """Return ctypes type for an encoded Objective-C type."""
1037
1025
  if encoding in self.typecodes:
1038
1026
  return self.typecodes[encoding]
@@ -1047,8 +1035,10 @@ class ObjCMethod:
1047
1035
  elif encoding[0:2] == b'r^' and encoding[2:] in self.typecodes:
1048
1036
  # const pointer, also don't care
1049
1037
  return POINTER(self.typecodes[encoding[2:]])
1038
+ elif encoding[0:2] == b'@?':
1039
+ return c_void_p
1050
1040
  else:
1051
- raise Exception('unknown encoding for %s: %s' % (self.name, encoding))
1041
+ raise MissingEncodingType(encoding)
1052
1042
 
1053
1043
  def get_prototype(self):
1054
1044
  """Returns a ctypes CFUNCTYPE for the method."""
@@ -1099,7 +1089,8 @@ class ObjCMethod:
1099
1089
  # Add more useful info to argument error exceptions, then reraise.
1100
1090
  error.args += ('selector = ' + str(self.name),
1101
1091
  'argtypes =' + str(self.argtypes),
1102
- 'encoding = ' + str(self.encoding))
1092
+ 'encoding = ' + str(self.encoding),
1093
+ f'args passed = {args}')
1103
1094
  raise
1104
1095
 
1105
1096
 
@@ -1109,7 +1100,7 @@ class ObjCBoundMethod:
1109
1100
  """This represents an Objective-C method (an IMP) which has been bound
1110
1101
  to some id which will be passed as the first parameter to the method."""
1111
1102
 
1112
- def __init__(self, method, objc_id):
1103
+ def __init__(self, method: ObjCMethod, objc_id):
1113
1104
  """Initialize with a method and ObjCInstance or ObjCClass object."""
1114
1105
  self.method = method
1115
1106
  self.objc_id = objc_id
@@ -1397,11 +1388,10 @@ def get_cached_instances():
1397
1388
  return [(obj.objc_class.name, obj._retained, obj.pool, obj) for obj in ObjCInstance._cached_objects.values()]
1398
1389
 
1399
1390
 
1400
- def convert_method_arguments(encoding, args):
1391
+ def convert_method_arguments(arg_encodings, args):
1401
1392
  """Used by ObjCSubclass to convert Objective-C method arguments to
1402
1393
  Python values before passing them on to the Python-defined method."""
1403
1394
  new_args = []
1404
- arg_encodings = parse_type_encoding(encoding)[3:]
1405
1395
  for e, a in zip(arg_encodings, args):
1406
1396
  if e == b'@':
1407
1397
  new_args.append(ObjCInstance(a))
@@ -1516,18 +1506,20 @@ class ObjCSubclass:
1516
1506
 
1517
1507
  return decorator
1518
1508
 
1519
- def method(self, encoding):
1509
+ def method(self, encoding: bytes | str):
1520
1510
  """Function decorator for instance methods."""
1521
1511
  # Add encodings for hidden self and cmd arguments.
1522
- encoding = ensure_bytes(encoding)
1523
- typecodes = parse_type_encoding(encoding)
1512
+ encoding_bytes = ensure_bytes(encoding)
1513
+ typecodes = parse_type_encoding(encoding_bytes)
1524
1514
  typecodes.insert(1, b'@:')
1525
- encoding = b''.join(typecodes)
1515
+ encoding_bytes = b''.join(typecodes)
1526
1516
 
1527
1517
  def decorator(f):
1518
+ arg_encoding = parse_type_encoding(encoding_bytes)[3:]
1519
+
1528
1520
  def objc_method(objc_self, objc_cmd, *args):
1529
1521
  py_self = ObjCInstance(objc_self)
1530
- args = convert_method_arguments(encoding, args)
1522
+ args = convert_method_arguments(arg_encoding, args)
1531
1523
  result = f(py_self, *args)
1532
1524
  if isinstance(result, ObjCClass):
1533
1525
  result = result.ptr.value
@@ -1536,7 +1528,7 @@ class ObjCSubclass:
1536
1528
  return result
1537
1529
 
1538
1530
  name = f.__name__.replace('_', ':')
1539
- self.add_method(objc_method, name, encoding)
1531
+ self.add_method(objc_method, name, encoding_bytes)
1540
1532
  return objc_method
1541
1533
 
1542
1534
  return decorator
@@ -1550,9 +1542,10 @@ class ObjCSubclass:
1550
1542
  encoding = b''.join(typecodes)
1551
1543
 
1552
1544
  def decorator(f):
1545
+ arg_encoding = parse_type_encoding(encoding)[3:]
1553
1546
  def objc_class_method(objc_cls, objc_cmd, *args):
1554
1547
  py_cls = ObjCClass(objc_cls)
1555
- args = convert_method_arguments(encoding, args)
1548
+ args = convert_method_arguments(arg_encoding, args)
1556
1549
  result = f(py_cls, *args)
1557
1550
  if isinstance(result, ObjCClass):
1558
1551
  result = result.ptr.value
@@ -1670,3 +1663,46 @@ def AutoReleasePool():
1670
1663
  yield
1671
1664
  finally:
1672
1665
  objc.objc_autoreleasePoolPop(pool)
1666
+
1667
+ def get_callback_block(func: Callable, *, encoding: list[bytes | str]):
1668
+ """Creates a block to handle callbacks from ObjC."""
1669
+ bytes_list = [ensure_bytes(char) for char in encoding]
1670
+ return ObjCBlock(func, encoding=bytes_list)
1671
+
1672
+ class ObjCBlock:
1673
+ """A basic implementation of a Global ObjC Block.
1674
+
1675
+ You must keep this object alive and referenced.
1676
+ """
1677
+ def __init__(self, func: Callable, *, encoding: list[bytes]):
1678
+ if not callable(func):
1679
+ raise TypeError("Blocks must be callable")
1680
+
1681
+ self.func = func
1682
+
1683
+ # Signature is return, block, args
1684
+ desc_signature = encoding[0] + b"@?" + b"".join(encoding[1:])
1685
+
1686
+ cfunc_type = cfunctype_for_encoding(desc_signature)
1687
+
1688
+ self.cfunc_wrapper = cfunc_type(self._wrapper)
1689
+
1690
+ self._descriptor = Block_descriptor_1(
1691
+ reserved=0,
1692
+ Block_size=sizeof(Block_literal_1),
1693
+ signature=desc_signature,
1694
+ )
1695
+
1696
+ self.literal = Block_literal_1(
1697
+ isa=addressof(_NSConcreteGlobalBlock),
1698
+ flags=BLOCK_IS_GLOBAL | BLOCK_HAS_SIGNATURE,
1699
+ reserved=0,
1700
+ invoke=cast(self.cfunc_wrapper, c_void_p),
1701
+ descriptor=self._descriptor,
1702
+ )
1703
+
1704
+ self.block = cast(byref(self.literal), c_void_p)
1705
+ self._as_parameter_ = self.block # for ctypes to treat this as the block.
1706
+
1707
+ def _wrapper(self, _block, *args):
1708
+ return self.func(*args)
@@ -12,6 +12,7 @@ This module includes:
12
12
  * Error checking helpers
13
13
 
14
14
  """
15
+ from __future__ import annotations
15
16
  from ctypes import c_void_p, c_int, c_bool, Structure, c_uint32, util, cdll, c_uint, c_double, POINTER, c_int64, \
16
17
  CFUNCTYPE
17
18
  from typing import Final
@@ -30,7 +31,7 @@ class AudioStreamPacketDescription(Structure):
30
31
  _fields_ = [
31
32
  ('mStartOffset', c_int64),
32
33
  ('mVariableFramesInPacket', c_uint32),
33
- ('mDataByteSize', c_uint32)
34
+ ('mDataByteSize', c_uint32),
34
35
  ]
35
36
 
36
37
 
@@ -44,10 +45,10 @@ class AudioStreamBasicDescription(Structure):
44
45
  ('mBytesPerFrame', c_uint32),
45
46
  ('mChannelsPerFrame', c_uint32),
46
47
  ('mBitsPerChannel', c_uint32),
47
- ('mReserved', c_uint32)
48
+ ('mReserved', c_uint32),
48
49
  ]
49
50
 
50
- def __repr__(self):
51
+ def __repr__(self) -> str:
51
52
  return f"AudioStreamBasicDescription(sample_rate={self.mSampleRate}, channels={self.mChannelsPerFrame}, " \
52
53
  f"fmt={self.mFormatID}, bytes_per_packet={self.mBytesPerPacket}, bits={self.mBitsPerChannel}, " \
53
54
  f"frames_per_packet={self.mFramesPerPacket}, bytes_per_frame={self.mBytesPerFrame})"
@@ -224,7 +225,6 @@ class CoreAudioException(Exception):
224
225
  * kAudio_FileNotFoundError -> OSError (The typical Python file read error
225
226
  * kAudioFileInvalidChunkError -> ValueError (Invalid data)
226
227
  """
227
- ...
228
228
 
229
229
 
230
230
  def err_check(err: int) -> None:
@@ -3,17 +3,13 @@ from __future__ import annotations
3
3
  from typing import Any, Callable, Sequence
4
4
 
5
5
  import pyglet.lib
6
- from pyglet.gl.lib import decorate_function, missing_function
7
-
8
- from typing import Callable
9
-
10
- __all__ = ['link_GL', 'link_AGL']
6
+ from pyglet.graphics.api.gl.lib import decorate_function, missing_function
11
7
 
12
8
  gl_lib = pyglet.lib.load_library(framework='OpenGL')
13
9
  agl_lib = pyglet.lib.load_library(framework='AGL')
14
10
 
15
11
 
16
- def link_GL(name: str, restype: Any, argtypes: Any, requires: str | None = None, # noqa: N802, D103
12
+ def link_GL(name: str, restype: Any, argtypes: Any, requires: str | None = None, # noqa: N802
17
13
  suggestions: Sequence[str] | None = None) -> Callable[..., Any]:
18
14
  try:
19
15
  func = getattr(gl_lib, name)
@@ -25,8 +21,8 @@ def link_GL(name: str, restype: Any, argtypes: Any, requires: str | None = None,
25
21
  return missing_function(name, requires, suggestions)
26
22
 
27
23
 
28
- def link_AGL(name: str, restype: Any, argtypes: Any, requires: str | None = None, # noqa: N802, D103
29
- suggestions: Sequence[str] | None = None) -> Callable[..., Any]:
24
+ def link_AGL(name: str, restype: Any, argtypes: Any, requires: str | None = None, # noqa: N802
25
+ suggestions: Sequence[str] | None = None) -> Callable[..., Any]:
30
26
  try:
31
27
  func = getattr(agl_lib, name)
32
28
  func.restype = restype
@@ -35,3 +31,8 @@ def link_AGL(name: str, restype: Any, argtypes: Any, requires: str | None = None
35
31
  return func
36
32
  except AttributeError:
37
33
  return missing_function(name, requires, suggestions)
34
+
35
+
36
+ link_GL_proxy = link_GL
37
+
38
+ __all__ = ['link_GL', 'link_GL_proxy', 'link_AGL']
@@ -213,7 +213,6 @@ charmap = {
213
213
  '!': key.EXCLAMATION,
214
214
  '"': key.DOUBLEQUOTE,
215
215
  '#': key.HASH,
216
- '#': key.POUND,
217
216
  '$': key.DOLLAR,
218
217
  '%': key.PERCENT,
219
218
  '&': key.AMPERSAND,
@@ -248,7 +247,6 @@ charmap = {
248
247
  ']': key.BRACKETRIGHT,
249
248
  '^': key.ASCIICIRCUM,
250
249
  '_': key.UNDERSCORE,
251
- '`': key.GRAVE,
252
250
  '`': key.QUOTELEFT,
253
251
  'A': key.A,
254
252
  'B': key.B,
@@ -279,5 +277,5 @@ charmap = {
279
277
  '{': key.BRACELEFT,
280
278
  '|': key.BAR,
281
279
  '}': key.BRACERIGHT,
282
- '~': key.ASCIITILDE
280
+ '~': key.ASCIITILDE,
283
281
  }
@@ -0,0 +1,2 @@
1
+ from pyglet.libs.egl.egl_lib import *
2
+ from pyglet.libs.egl.eglext import *