pyglet sync
This commit is contained in:
parent
7bc5be0974
commit
e9f5a5fdac
@ -215,7 +215,6 @@ class FreeTypeFont(base.Font):
|
||||
if not match:
|
||||
raise base.FontException(f"Could not match font '{self._name}'")
|
||||
self.filename = match.file
|
||||
print(match)
|
||||
self.face = FreeTypeFace.from_fontconfig(match)
|
||||
|
||||
@classmethod
|
||||
|
@ -1,7 +1,7 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# pyglet
|
||||
# Copyright (c) 2006-2008 Alex Holkner
|
||||
# Copyright (c) 2008-2022 pyglet contributors
|
||||
# Copyright (c) 2008-2023 pyglet contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -42,6 +42,13 @@ from ctypes import *
|
||||
from pyglet.gl.lib import link_GL as _link_function
|
||||
from pyglet.gl.lib import c_ptrdiff_t
|
||||
|
||||
class struct___GLsync(Structure):
|
||||
__slots__ = [
|
||||
]
|
||||
struct___GLsync._fields_ = [
|
||||
('_opaque_struct', c_int)
|
||||
]
|
||||
|
||||
# END OF gl.template
|
||||
|
||||
# GL type definitions
|
||||
@ -66,6 +73,8 @@ GLintptr = c_ptrdiff_t
|
||||
GLsizeiptr = c_ptrdiff_t
|
||||
GLint64 = c_int64
|
||||
GLuint64 = c_uint64
|
||||
GLsync = POINTER(struct___GLsync)
|
||||
GLDEBUGPROC = CFUNCTYPE(None, GLenum, GLenum, GLuint, GLenum, GLsizei, POINTER(GLchar), POINTER(GLvoid))
|
||||
|
||||
# GL enumerant (token) definitions
|
||||
GL_FALSE = 0
|
||||
@ -1582,6 +1591,7 @@ glClearNamedFramebufferuiv = _link_function('glClearNamedFramebufferuiv', None,
|
||||
glClearStencil = _link_function('glClearStencil', None, [GLint], requires='OpenGL 1.0')
|
||||
glClearTexImage = _link_function('glClearTexImage', None, [GLuint, GLint, GLenum, GLenum, POINTER(GLvoid)], requires='OpenGL 4.4')
|
||||
glClearTexSubImage = _link_function('glClearTexSubImage', None, [GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, POINTER(GLvoid)], requires='OpenGL 4.4')
|
||||
glClientWaitSync = _link_function('glClientWaitSync', GLenum, [GLsync, GLbitfield, GLuint64], requires='OpenGL 3.2')
|
||||
glClipControl = _link_function('glClipControl', None, [GLenum, GLenum], requires='OpenGL 4.5')
|
||||
glColorMask = _link_function('glColorMask', None, [GLboolean, GLboolean, GLboolean, GLboolean], requires='OpenGL 1.0')
|
||||
glColorMaski = _link_function('glColorMaski', None, [GLuint, GLboolean, GLboolean, GLboolean, GLboolean], requires='OpenGL 3.0')
|
||||
@ -1623,6 +1633,7 @@ glCreateTextures = _link_function('glCreateTextures', None, [GLenum, GLsizei, PO
|
||||
glCreateTransformFeedbacks = _link_function('glCreateTransformFeedbacks', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.5')
|
||||
glCreateVertexArrays = _link_function('glCreateVertexArrays', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.5')
|
||||
glCullFace = _link_function('glCullFace', None, [GLenum], requires='OpenGL 1.0')
|
||||
glDebugMessageCallback = _link_function('glDebugMessageCallback', None, [GLDEBUGPROC, POINTER(GLvoid)], requires='OpenGL 4.3')
|
||||
glDebugMessageControl = _link_function('glDebugMessageControl', None, [GLenum, GLenum, GLenum, GLsizei, POINTER(GLuint), GLboolean], requires='OpenGL 4.3')
|
||||
glDebugMessageInsert = _link_function('glDebugMessageInsert', None, [GLenum, GLenum, GLuint, GLenum, GLsizei, POINTER(GLchar)], requires='OpenGL 4.3')
|
||||
glDeleteBuffers = _link_function('glDeleteBuffers', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 1.5')
|
||||
@ -1635,6 +1646,7 @@ glDeleteRenderbuffers = _link_function('glDeleteRenderbuffers', None, [GLsizei,
|
||||
glDeleteRenderbuffersEXT = _link_function('glDeleteRenderbuffersEXT', None, [GLsizei, POINTER(GLuint)], requires='None')
|
||||
glDeleteSamplers = _link_function('glDeleteSamplers', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 3.3')
|
||||
glDeleteShader = _link_function('glDeleteShader', None, [GLuint], requires='OpenGL 2.0')
|
||||
glDeleteSync = _link_function('glDeleteSync', None, [GLsync], requires='OpenGL 3.2')
|
||||
glDeleteTextures = _link_function('glDeleteTextures', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 1.1')
|
||||
glDeleteTransformFeedbacks = _link_function('glDeleteTransformFeedbacks', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.0')
|
||||
glDeleteVertexArrays = _link_function('glDeleteVertexArrays', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 3.0')
|
||||
@ -1678,6 +1690,7 @@ glEndConditionalRender = _link_function('glEndConditionalRender', None, [], requ
|
||||
glEndQuery = _link_function('glEndQuery', None, [GLenum], requires='OpenGL 1.5')
|
||||
glEndQueryIndexed = _link_function('glEndQueryIndexed', None, [GLenum, GLuint], requires='OpenGL 4.0')
|
||||
glEndTransformFeedback = _link_function('glEndTransformFeedback', None, [], requires='OpenGL 3.0')
|
||||
glFenceSync = _link_function('glFenceSync', GLsync, [GLenum, GLbitfield], requires='OpenGL 3.2')
|
||||
glFinish = _link_function('glFinish', None, [], requires='OpenGL 1.0')
|
||||
glFlush = _link_function('glFlush', None, [], requires='OpenGL 1.0')
|
||||
glFlushMappedBufferRange = _link_function('glFlushMappedBufferRange', None, [GLenum, GLintptr, GLsizeiptr], requires='OpenGL 3.0')
|
||||
@ -1794,6 +1807,7 @@ glGetString = _link_function('glGetString', POINTER(GLubyte), [GLenum], requires
|
||||
glGetStringi = _link_function('glGetStringi', POINTER(GLubyte), [GLenum, GLuint], requires='OpenGL 3.0')
|
||||
glGetSubroutineIndex = _link_function('glGetSubroutineIndex', GLuint, [GLuint, GLenum, POINTER(GLchar)], requires='OpenGL 4.0')
|
||||
glGetSubroutineUniformLocation = _link_function('glGetSubroutineUniformLocation', GLint, [GLuint, GLenum, POINTER(GLchar)], requires='OpenGL 4.0')
|
||||
glGetSynciv = _link_function('glGetSynciv', None, [GLsync, GLenum, GLsizei, POINTER(GLsizei), POINTER(GLint)], requires='OpenGL 3.2')
|
||||
glGetTexImage = _link_function('glGetTexImage', None, [GLenum, GLint, GLenum, GLenum, POINTER(GLvoid)], requires='OpenGL 1.0')
|
||||
glGetTexLevelParameterfv = _link_function('glGetTexLevelParameterfv', None, [GLenum, GLint, GLenum, POINTER(GLfloat)], requires='OpenGL 1.0')
|
||||
glGetTexLevelParameteriv = _link_function('glGetTexLevelParameteriv', None, [GLenum, GLint, GLenum, POINTER(GLint)], requires='OpenGL 1.0')
|
||||
@ -1870,6 +1884,7 @@ glIsRenderbuffer = _link_function('glIsRenderbuffer', GLboolean, [GLuint], requi
|
||||
glIsRenderbufferEXT = _link_function('glIsRenderbufferEXT', GLboolean, [GLuint], requires='None')
|
||||
glIsSampler = _link_function('glIsSampler', GLboolean, [GLuint], requires='OpenGL 3.3')
|
||||
glIsShader = _link_function('glIsShader', GLboolean, [GLuint], requires='OpenGL 2.0')
|
||||
glIsSync = _link_function('glIsSync', GLboolean, [GLsync], requires='OpenGL 3.2')
|
||||
glIsTexture = _link_function('glIsTexture', GLboolean, [GLuint], requires='OpenGL 1.1')
|
||||
glIsTransformFeedback = _link_function('glIsTransformFeedback', GLboolean, [GLuint], requires='OpenGL 4.0')
|
||||
glIsVertexArray = _link_function('glIsVertexArray', GLboolean, [GLuint], requires='OpenGL 3.0')
|
||||
@ -2224,6 +2239,7 @@ glViewport = _link_function('glViewport', None, [GLint, GLint, GLsizei, GLsizei]
|
||||
glViewportArrayv = _link_function('glViewportArrayv', None, [GLuint, GLsizei, POINTER(GLfloat)], requires='OpenGL 4.1')
|
||||
glViewportIndexedf = _link_function('glViewportIndexedf', None, [GLuint, GLfloat, GLfloat, GLfloat, GLfloat], requires='OpenGL 4.1')
|
||||
glViewportIndexedfv = _link_function('glViewportIndexedfv', None, [GLuint, POINTER(GLfloat)], requires='OpenGL 4.1')
|
||||
glWaitSync = _link_function('glWaitSync', None, [GLsync, GLbitfield, GLuint64], requires='OpenGL 3.2')
|
||||
|
||||
|
||||
__all__ = [
|
||||
@ -2248,6 +2264,8 @@ __all__ = [
|
||||
'GLsizeiptr',
|
||||
'GLint64',
|
||||
'GLuint64',
|
||||
'GLsync',
|
||||
'GLDEBUGPROC',
|
||||
'GL_DEPTH_BUFFER_BIT',
|
||||
'GL_STENCIL_BUFFER_BIT',
|
||||
'GL_COLOR_BUFFER_BIT',
|
||||
@ -3760,6 +3778,7 @@ __all__ = [
|
||||
'glClearStencil',
|
||||
'glClearTexImage',
|
||||
'glClearTexSubImage',
|
||||
'glClientWaitSync',
|
||||
'glClipControl',
|
||||
'glColorMask',
|
||||
'glColorMaski',
|
||||
@ -3801,6 +3820,7 @@ __all__ = [
|
||||
'glCreateTransformFeedbacks',
|
||||
'glCreateVertexArrays',
|
||||
'glCullFace',
|
||||
'glDebugMessageCallback',
|
||||
'glDebugMessageControl',
|
||||
'glDebugMessageInsert',
|
||||
'glDeleteBuffers',
|
||||
@ -3813,6 +3833,7 @@ __all__ = [
|
||||
'glDeleteRenderbuffersEXT',
|
||||
'glDeleteSamplers',
|
||||
'glDeleteShader',
|
||||
'glDeleteSync',
|
||||
'glDeleteTextures',
|
||||
'glDeleteTransformFeedbacks',
|
||||
'glDeleteVertexArrays',
|
||||
@ -3856,6 +3877,7 @@ __all__ = [
|
||||
'glEndQuery',
|
||||
'glEndQueryIndexed',
|
||||
'glEndTransformFeedback',
|
||||
'glFenceSync',
|
||||
'glFinish',
|
||||
'glFlush',
|
||||
'glFlushMappedBufferRange',
|
||||
@ -3972,6 +3994,7 @@ __all__ = [
|
||||
'glGetStringi',
|
||||
'glGetSubroutineIndex',
|
||||
'glGetSubroutineUniformLocation',
|
||||
'glGetSynciv',
|
||||
'glGetTexImage',
|
||||
'glGetTexLevelParameterfv',
|
||||
'glGetTexLevelParameteriv',
|
||||
@ -4048,6 +4071,7 @@ __all__ = [
|
||||
'glIsRenderbufferEXT',
|
||||
'glIsSampler',
|
||||
'glIsShader',
|
||||
'glIsSync',
|
||||
'glIsTexture',
|
||||
'glIsTransformFeedback',
|
||||
'glIsVertexArray',
|
||||
@ -4402,4 +4426,5 @@ __all__ = [
|
||||
'glViewportArrayv',
|
||||
'glViewportIndexedf',
|
||||
'glViewportIndexedfv',
|
||||
'glWaitSync',
|
||||
]
|
||||
|
@ -1,7 +1,7 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# pyglet
|
||||
# Copyright (c) 2006-2008 Alex Holkner
|
||||
# Copyright (c) 2008-2022 pyglet contributors
|
||||
# Copyright (c) 2008-2023 pyglet contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
@ -42,6 +42,13 @@ from ctypes import *
|
||||
from pyglet.gl.lib import link_GL as _link_function
|
||||
from pyglet.gl.lib import c_ptrdiff_t
|
||||
|
||||
class struct___GLsync(Structure):
|
||||
__slots__ = [
|
||||
]
|
||||
struct___GLsync._fields_ = [
|
||||
('_opaque_struct', c_int)
|
||||
]
|
||||
|
||||
# END OF gl.template
|
||||
|
||||
# GL type definitions
|
||||
@ -66,6 +73,8 @@ GLintptr = c_ptrdiff_t
|
||||
GLsizeiptr = c_ptrdiff_t
|
||||
GLint64 = c_int64
|
||||
GLuint64 = c_uint64
|
||||
GLsync = POINTER(struct___GLsync)
|
||||
GLDEBUGPROC = CFUNCTYPE(None, GLenum, GLenum, GLuint, GLenum, GLsizei, POINTER(GLchar), POINTER(GLvoid))
|
||||
|
||||
# GL enumerant (token) definitions
|
||||
GL_FALSE = 0
|
||||
@ -2021,6 +2030,7 @@ glClearStencil = _link_function('glClearStencil', None, [GLint], requires='OpenG
|
||||
glClearTexImage = _link_function('glClearTexImage', None, [GLuint, GLint, GLenum, GLenum, POINTER(GLvoid)], requires='OpenGL 4.4')
|
||||
glClearTexSubImage = _link_function('glClearTexSubImage', None, [GLuint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, POINTER(GLvoid)], requires='OpenGL 4.4')
|
||||
glClientActiveTexture = _link_function('glClientActiveTexture', None, [GLenum], requires='OpenGL 1.3')
|
||||
glClientWaitSync = _link_function('glClientWaitSync', GLenum, [GLsync, GLbitfield, GLuint64], requires='OpenGL 3.2')
|
||||
glClipControl = _link_function('glClipControl', None, [GLenum, GLenum], requires='OpenGL 4.5')
|
||||
glClipPlane = _link_function('glClipPlane', None, [GLenum, POINTER(GLdouble)], requires='OpenGL 1.0')
|
||||
glColor3b = _link_function('glColor3b', None, [GLbyte, GLbyte, GLbyte], requires='OpenGL 1.0')
|
||||
@ -2098,6 +2108,7 @@ glCreateTextures = _link_function('glCreateTextures', None, [GLenum, GLsizei, PO
|
||||
glCreateTransformFeedbacks = _link_function('glCreateTransformFeedbacks', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.5')
|
||||
glCreateVertexArrays = _link_function('glCreateVertexArrays', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.5')
|
||||
glCullFace = _link_function('glCullFace', None, [GLenum], requires='OpenGL 1.0')
|
||||
glDebugMessageCallback = _link_function('glDebugMessageCallback', None, [GLDEBUGPROC, POINTER(GLvoid)], requires='OpenGL 4.3')
|
||||
glDebugMessageControl = _link_function('glDebugMessageControl', None, [GLenum, GLenum, GLenum, GLsizei, POINTER(GLuint), GLboolean], requires='OpenGL 4.3')
|
||||
glDebugMessageInsert = _link_function('glDebugMessageInsert', None, [GLenum, GLenum, GLuint, GLenum, GLsizei, POINTER(GLchar)], requires='OpenGL 4.3')
|
||||
glDeleteBuffers = _link_function('glDeleteBuffers', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 1.5')
|
||||
@ -2111,6 +2122,7 @@ glDeleteRenderbuffers = _link_function('glDeleteRenderbuffers', None, [GLsizei,
|
||||
glDeleteRenderbuffersEXT = _link_function('glDeleteRenderbuffersEXT', None, [GLsizei, POINTER(GLuint)], requires='None')
|
||||
glDeleteSamplers = _link_function('glDeleteSamplers', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 3.3')
|
||||
glDeleteShader = _link_function('glDeleteShader', None, [GLuint], requires='OpenGL 2.0')
|
||||
glDeleteSync = _link_function('glDeleteSync', None, [GLsync], requires='OpenGL 3.2')
|
||||
glDeleteTextures = _link_function('glDeleteTextures', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 1.1')
|
||||
glDeleteTransformFeedbacks = _link_function('glDeleteTransformFeedbacks', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 4.0')
|
||||
glDeleteVertexArrays = _link_function('glDeleteVertexArrays', None, [GLsizei, POINTER(GLuint)], requires='OpenGL 3.0')
|
||||
@ -2175,6 +2187,7 @@ glEvalMesh2 = _link_function('glEvalMesh2', None, [GLenum, GLint, GLint, GLint,
|
||||
glEvalPoint1 = _link_function('glEvalPoint1', None, [GLint], requires='OpenGL 1.0')
|
||||
glEvalPoint2 = _link_function('glEvalPoint2', None, [GLint, GLint], requires='OpenGL 1.0')
|
||||
glFeedbackBuffer = _link_function('glFeedbackBuffer', None, [GLsizei, GLenum, POINTER(GLfloat)], requires='OpenGL 1.0')
|
||||
glFenceSync = _link_function('glFenceSync', GLsync, [GLenum, GLbitfield], requires='OpenGL 3.2')
|
||||
glFinish = _link_function('glFinish', None, [], requires='OpenGL 1.0')
|
||||
glFlush = _link_function('glFlush', None, [], requires='OpenGL 1.0')
|
||||
glFlushMappedBufferRange = _link_function('glFlushMappedBufferRange', None, [GLenum, GLintptr, GLsizeiptr], requires='OpenGL 3.0')
|
||||
@ -2314,6 +2327,7 @@ glGetString = _link_function('glGetString', POINTER(GLubyte), [GLenum], requires
|
||||
glGetStringi = _link_function('glGetStringi', POINTER(GLubyte), [GLenum, GLuint], requires='OpenGL 3.0')
|
||||
glGetSubroutineIndex = _link_function('glGetSubroutineIndex', GLuint, [GLuint, GLenum, POINTER(GLchar)], requires='OpenGL 4.0')
|
||||
glGetSubroutineUniformLocation = _link_function('glGetSubroutineUniformLocation', GLint, [GLuint, GLenum, POINTER(GLchar)], requires='OpenGL 4.0')
|
||||
glGetSynciv = _link_function('glGetSynciv', None, [GLsync, GLenum, GLsizei, POINTER(GLsizei), POINTER(GLint)], requires='OpenGL 3.2')
|
||||
glGetTexEnvfv = _link_function('glGetTexEnvfv', None, [GLenum, GLenum, POINTER(GLfloat)], requires='OpenGL 1.0')
|
||||
glGetTexEnviv = _link_function('glGetTexEnviv', None, [GLenum, GLenum, POINTER(GLint)], requires='OpenGL 1.0')
|
||||
glGetTexGendv = _link_function('glGetTexGendv', None, [GLenum, GLenum, POINTER(GLdouble)], requires='OpenGL 1.0')
|
||||
@ -2410,6 +2424,7 @@ glIsRenderbuffer = _link_function('glIsRenderbuffer', GLboolean, [GLuint], requi
|
||||
glIsRenderbufferEXT = _link_function('glIsRenderbufferEXT', GLboolean, [GLuint], requires='None')
|
||||
glIsSampler = _link_function('glIsSampler', GLboolean, [GLuint], requires='OpenGL 3.3')
|
||||
glIsShader = _link_function('glIsShader', GLboolean, [GLuint], requires='OpenGL 2.0')
|
||||
glIsSync = _link_function('glIsSync', GLboolean, [GLsync], requires='OpenGL 3.2')
|
||||
glIsTexture = _link_function('glIsTexture', GLboolean, [GLuint], requires='OpenGL 1.1')
|
||||
glIsTransformFeedback = _link_function('glIsTransformFeedback', GLboolean, [GLuint], requires='OpenGL 4.0')
|
||||
glIsVertexArray = _link_function('glIsVertexArray', GLboolean, [GLuint], requires='OpenGL 3.0')
|
||||
@ -2985,6 +3000,7 @@ glViewport = _link_function('glViewport', None, [GLint, GLint, GLsizei, GLsizei]
|
||||
glViewportArrayv = _link_function('glViewportArrayv', None, [GLuint, GLsizei, POINTER(GLfloat)], requires='OpenGL 4.1')
|
||||
glViewportIndexedf = _link_function('glViewportIndexedf', None, [GLuint, GLfloat, GLfloat, GLfloat, GLfloat], requires='OpenGL 4.1')
|
||||
glViewportIndexedfv = _link_function('glViewportIndexedfv', None, [GLuint, POINTER(GLfloat)], requires='OpenGL 4.1')
|
||||
glWaitSync = _link_function('glWaitSync', None, [GLsync, GLbitfield, GLuint64], requires='OpenGL 3.2')
|
||||
glWindowPos2d = _link_function('glWindowPos2d', None, [GLdouble, GLdouble], requires='OpenGL 1.4')
|
||||
glWindowPos2dv = _link_function('glWindowPos2dv', None, [POINTER(GLdouble)], requires='OpenGL 1.4')
|
||||
glWindowPos2f = _link_function('glWindowPos2f', None, [GLfloat, GLfloat], requires='OpenGL 1.4')
|
||||
@ -3025,6 +3041,8 @@ __all__ = [
|
||||
'GLsizeiptr',
|
||||
'GLint64',
|
||||
'GLuint64',
|
||||
'GLsync',
|
||||
'GLDEBUGPROC',
|
||||
'GL_DEPTH_BUFFER_BIT',
|
||||
'GL_STENCIL_BUFFER_BIT',
|
||||
'GL_COLOR_BUFFER_BIT',
|
||||
@ -4976,6 +4994,7 @@ __all__ = [
|
||||
'glClearTexImage',
|
||||
'glClearTexSubImage',
|
||||
'glClientActiveTexture',
|
||||
'glClientWaitSync',
|
||||
'glClipControl',
|
||||
'glClipPlane',
|
||||
'glColor3b',
|
||||
@ -5053,6 +5072,7 @@ __all__ = [
|
||||
'glCreateTransformFeedbacks',
|
||||
'glCreateVertexArrays',
|
||||
'glCullFace',
|
||||
'glDebugMessageCallback',
|
||||
'glDebugMessageControl',
|
||||
'glDebugMessageInsert',
|
||||
'glDeleteBuffers',
|
||||
@ -5066,6 +5086,7 @@ __all__ = [
|
||||
'glDeleteRenderbuffersEXT',
|
||||
'glDeleteSamplers',
|
||||
'glDeleteShader',
|
||||
'glDeleteSync',
|
||||
'glDeleteTextures',
|
||||
'glDeleteTransformFeedbacks',
|
||||
'glDeleteVertexArrays',
|
||||
@ -5130,6 +5151,7 @@ __all__ = [
|
||||
'glEvalPoint1',
|
||||
'glEvalPoint2',
|
||||
'glFeedbackBuffer',
|
||||
'glFenceSync',
|
||||
'glFinish',
|
||||
'glFlush',
|
||||
'glFlushMappedBufferRange',
|
||||
@ -5269,6 +5291,7 @@ __all__ = [
|
||||
'glGetStringi',
|
||||
'glGetSubroutineIndex',
|
||||
'glGetSubroutineUniformLocation',
|
||||
'glGetSynciv',
|
||||
'glGetTexEnvfv',
|
||||
'glGetTexEnviv',
|
||||
'glGetTexGendv',
|
||||
@ -5365,6 +5388,7 @@ __all__ = [
|
||||
'glIsRenderbufferEXT',
|
||||
'glIsSampler',
|
||||
'glIsShader',
|
||||
'glIsSync',
|
||||
'glIsTexture',
|
||||
'glIsTransformFeedback',
|
||||
'glIsVertexArray',
|
||||
@ -5940,6 +5964,7 @@ __all__ = [
|
||||
'glViewportArrayv',
|
||||
'glViewportIndexedf',
|
||||
'glViewportIndexedfv',
|
||||
'glWaitSync',
|
||||
'glWindowPos2d',
|
||||
'glWindowPos2dv',
|
||||
'glWindowPos2f',
|
||||
|
@ -33,27 +33,26 @@
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
"""Low-level graphics rendering.
|
||||
"""Low-level graphics rendering and abstractions.
|
||||
|
||||
This module provides an efficient low-level abstraction over OpenGL. It gives
|
||||
very good performance for rendering OpenGL primitives. The module is used
|
||||
internally by other areas of pyglet.
|
||||
This module provides efficient abstractions over OpenGL objects, such as
|
||||
Shaders and Buffers. It also provides classes for highly performant batched
|
||||
rendering and grouping.
|
||||
|
||||
See the :ref:`guide_graphics` for details on how to use this graphics API.
|
||||
|
||||
Batches and groups
|
||||
==================
|
||||
|
||||
Without even needing to understand the details on how to draw primitives with
|
||||
the graphics API, developers can make use of :py:class:`~pyglet.graphics.Batch`
|
||||
and :py:class:`~pyglet.graphics.Group` objects to improve performance of sprite
|
||||
and text rendering.
|
||||
Developers can make use of :py:class:`~pyglet.graphics.Batch` and
|
||||
:py:class:`~pyglet.graphics.Group` objects to improve performance when
|
||||
rendering a large number of objects.
|
||||
|
||||
The :py:class:`~pyglet.sprite.Sprite`, :py:func:`~pyglet.text.Label` and
|
||||
:py:func:`~pyglet.text.layout.TextLayout` classes all accept a ``batch`` and
|
||||
``group`` parameter in their constructors. A batch manages a set of objects
|
||||
that will be drawn all at once, and a group describes the manner in which an
|
||||
object is drawn.
|
||||
The :py:class:`~pyglet.sprite.Sprite`, :py:func:`~pyglet.text.Label`,
|
||||
:py:func:`~pyglet.text.layout.TextLayout`, and other classes all accept a
|
||||
``batch`` and ``group`` parameter in their constructors. A Batch manages
|
||||
a set of objects that will be drawn all at once, and a Group can be used
|
||||
to set OpenGL state and further sort the draw operation.
|
||||
|
||||
The following example creates a batch, adds two sprites to the batch, and then
|
||||
draws the entire batch::
|
||||
@ -65,64 +64,29 @@ draws the entire batch::
|
||||
def on_draw()
|
||||
batch.draw()
|
||||
|
||||
Drawing a complete batch is much faster than drawing the items in the batch
|
||||
Drawing a complete Batch is much faster than drawing the items in the batch
|
||||
individually, especially when those items belong to a common group.
|
||||
|
||||
Groups describe the OpenGL state required for an item. This is for the most
|
||||
part managed by the sprite and text classes, however you can also use custom
|
||||
groups to ensure items are drawn in a particular order. For example, the
|
||||
part managed by the sprite, text, and other classes, however you can also use
|
||||
custom groups to ensure items are drawn in a particular order. For example, the
|
||||
following example adds a background sprite which is guaranteed to be drawn
|
||||
before the car and the boat::
|
||||
|
||||
batch = pyglet.graphics.Batch()
|
||||
background = pyglet.sprite.SpriteGroup(0)
|
||||
foreground = pyglet.sprite.SpriteGroup(1)
|
||||
background = pyglet.graphics.Group(order=0)
|
||||
foreground = pyglet.graphics.Group(order=1)
|
||||
|
||||
background = pyglet.sprite.Sprite(background_image,
|
||||
batch=batch, group=background)
|
||||
background = pyglet.sprite.Sprite(background_image, batch=batch, group=background)
|
||||
car = pyglet.sprite.Sprite(car_image, batch=batch, group=foreground)
|
||||
boat = pyglet.sprite.Sprite(boat_image, batch=batch, group=foreground)
|
||||
|
||||
def on_draw()
|
||||
batch.draw()
|
||||
|
||||
It's preferable to manage sprites and text objects within as few batches as
|
||||
possible. If the drawing of sprites or text objects need to be interleaved
|
||||
with other drawing that does not use the graphics API, multiple batches will
|
||||
be required.
|
||||
|
||||
Drawing modes
|
||||
=============
|
||||
|
||||
Methods in this module that accept a ``mode`` parameter will accept any value
|
||||
in the OpenGL drawing mode enumeration: ``GL_POINTS``, ``GL_LINE_STRIP``,
|
||||
``GL_LINE_LOOP``, ``GL_LINES``, ``GL_TRIANGLE_STRIP``, ``GL_TRIANGLE_FAN``,
|
||||
``GL_TRIANGLES``, and ``GL_POLYGON``.
|
||||
|
||||
::
|
||||
|
||||
pyglet.graphics.draw(1, GL_POINTS, ('v2i',(10,20)))
|
||||
|
||||
However, because of the way the graphics API renders multiple primitives with
|
||||
shared state, ``GL_POLYGON``, ``GL_LINE_LOOP`` and ``GL_TRIANGLE_FAN`` cannot
|
||||
be used --- the results are undefined.
|
||||
|
||||
When using ``GL_LINE_STRIP`` or ``GL_TRIANGLE_STRIP``, care must be taken to
|
||||
insert degenerate vertices at the beginning and end of each
|
||||
vertex list. For example, given the vertex list::
|
||||
|
||||
A, B, C, D
|
||||
|
||||
the correct vertex list to provide the vertex list is::
|
||||
|
||||
A, A, B, C, D, D
|
||||
|
||||
Alternatively, the ``NV_primitive_restart`` extension can be used if it is
|
||||
present. This also permits use of ``GL_POLYGON``, ``GL_LINE_LOOP`` and
|
||||
``GL_TRIANGLE_FAN``. Unfortunately the extension is not provided by older
|
||||
video drivers, and requires indexed vertex lists.
|
||||
|
||||
.. versionadded:: 1.1
|
||||
It's preferable to manage pyglet objects within as few batches as possible. If
|
||||
the drawing of sprites or text objects need to be interleaved with other
|
||||
drawing that does not use the graphics API, multiple batches will be required.
|
||||
"""
|
||||
|
||||
import ctypes
|
||||
@ -140,6 +104,9 @@ _debug_graphics_batch = pyglet.options['debug_graphics_batch']
|
||||
def draw(size, mode, **data):
|
||||
"""Draw a primitive immediately.
|
||||
|
||||
:warning: This function is deprecated as of 2.0.4, and will be removed
|
||||
in the next release.
|
||||
|
||||
:Parameters:
|
||||
`size` : int
|
||||
Number of vertices given
|
||||
@ -189,6 +156,9 @@ def draw(size, mode, **data):
|
||||
def draw_indexed(size, mode, indices, **data):
|
||||
"""Draw a primitive with indexed vertices immediately.
|
||||
|
||||
:warning: This function is deprecated as of 2.0.4, and will be removed
|
||||
in the next release.
|
||||
|
||||
:Parameters:
|
||||
`size` : int
|
||||
Number of vertices given
|
||||
|
@ -494,6 +494,8 @@ class TextEntry(WidgetBase):
|
||||
if self._check_hit(x, y):
|
||||
self._set_focus(True)
|
||||
self._caret.on_mouse_press(x, y, buttons, modifiers)
|
||||
else:
|
||||
self._set_focus(False)
|
||||
|
||||
def on_text(self, text):
|
||||
if not self.enabled:
|
||||
|
@ -316,7 +316,7 @@ class HIDDevice:
|
||||
def get_guid(self):
|
||||
"""Generate an SDL2 style GUID from the product guid."""
|
||||
|
||||
if self.transport == 'USB':
|
||||
if self.transport.upper() == 'USB':
|
||||
bustype = 0x03
|
||||
vendor = self.vendorID or 0
|
||||
product = self.productID or 0
|
||||
@ -328,7 +328,7 @@ class HIDDevice:
|
||||
version = ((version << 8) | (version >> 8)) & 0xFFFF
|
||||
return "{:04x}0000{:04x}0000{:04x}0000{:04x}0000".format(bustype, vendor, product, version)
|
||||
|
||||
elif self.transport == 'BLUETOOTH':
|
||||
elif self.transport.upper() == 'BLUETOOTH':
|
||||
bustype = 0x05
|
||||
# Byte swap (ABCD --> CDAB):
|
||||
bustype = ((bustype << 8) | (bustype >> 8)) & 0xFFFF
|
||||
@ -726,7 +726,7 @@ def get_apple_remote(display=None):
|
||||
|
||||
|
||||
def _create_controller(device, display):
|
||||
if device.transport in ('USB', 'BLUETOOTH'):
|
||||
if device.transport.upper() in ('USB', 'BLUETOOTH'):
|
||||
mapping = get_mapping(device.get_guid())
|
||||
if not mapping:
|
||||
return
|
||||
|
@ -46,56 +46,15 @@ IS64 = struct.calcsize("P") == 8
|
||||
|
||||
_debug_win32 = pyglet.options['debug_win32']
|
||||
|
||||
if _debug_win32:
|
||||
import traceback
|
||||
DebugLibrary = lambda lib: ctypes.WinDLL(lib, use_last_error=True if _debug_win32 else False)
|
||||
|
||||
_GetLastError = windll.kernel32.GetLastError
|
||||
_SetLastError = windll.kernel32.SetLastError
|
||||
_FormatMessageA = windll.kernel32.FormatMessageA
|
||||
|
||||
_log_win32 = open('debug_win32.log', 'w')
|
||||
|
||||
|
||||
def format_error(err):
|
||||
msg = create_string_buffer(256)
|
||||
_FormatMessageA(constants.FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
c_void_p(),
|
||||
err,
|
||||
0,
|
||||
msg,
|
||||
len(msg),
|
||||
c_void_p())
|
||||
return msg.value
|
||||
|
||||
|
||||
class DebugLibrary:
|
||||
def __init__(self, lib):
|
||||
self.lib = lib
|
||||
|
||||
def __getattr__(self, name):
|
||||
fn = getattr(self.lib, name)
|
||||
|
||||
def f(*args):
|
||||
_SetLastError(0)
|
||||
result = fn(*args)
|
||||
err = _GetLastError()
|
||||
if err != 0:
|
||||
for entry in traceback.format_list(traceback.extract_stack()[:-1]):
|
||||
_log_win32.write(entry)
|
||||
print(format_error(err), file=_log_win32)
|
||||
return result
|
||||
|
||||
return f
|
||||
else:
|
||||
DebugLibrary = lambda lib: lib
|
||||
|
||||
_gdi32 = DebugLibrary(windll.gdi32)
|
||||
_kernel32 = DebugLibrary(windll.kernel32)
|
||||
_user32 = DebugLibrary(windll.user32)
|
||||
_dwmapi = DebugLibrary(windll.dwmapi)
|
||||
_shell32 = DebugLibrary(windll.shell32)
|
||||
_ole32 = DebugLibrary(windll.ole32)
|
||||
_oleaut32 = DebugLibrary(windll.oleaut32)
|
||||
_gdi32 = DebugLibrary('gdi32')
|
||||
_kernel32 = DebugLibrary('kernel32')
|
||||
_user32 = DebugLibrary('user32')
|
||||
_dwmapi = DebugLibrary('dwmapi')
|
||||
_shell32 = DebugLibrary('shell32')
|
||||
_ole32 = DebugLibrary('ole32')
|
||||
_oleaut32 = DebugLibrary('oleaut32')
|
||||
|
||||
# _gdi32
|
||||
_gdi32.AddFontMemResourceEx.restype = HANDLE
|
||||
@ -216,6 +175,8 @@ _user32.LoadCursorW.restype = HCURSOR
|
||||
_user32.LoadCursorW.argtypes = [HINSTANCE, c_wchar_p]
|
||||
_user32.LoadIconW.restype = HICON
|
||||
_user32.LoadIconW.argtypes = [HINSTANCE, c_wchar_p]
|
||||
_user32.LoadImageW.restype = HICON
|
||||
_user32.LoadImageW.argtypes = [HINSTANCE, LPCWSTR, UINT, c_int, c_int, UINT]
|
||||
_user32.MapVirtualKeyW.restype = UINT
|
||||
_user32.MapVirtualKeyW.argtypes = [UINT, UINT]
|
||||
_user32.MapWindowPoints.restype = c_int
|
||||
@ -319,6 +280,37 @@ _oleaut32.VariantInit.argtypes = [c_void_p]
|
||||
_oleaut32.VariantClear.restype = HRESULT
|
||||
_oleaut32.VariantClear.argtypes = [c_void_p]
|
||||
|
||||
if _debug_win32:
|
||||
import traceback
|
||||
|
||||
_log_win32 = open('debug_win32.log', 'w')
|
||||
|
||||
|
||||
def win32_errcheck(result, func, args):
|
||||
last_err = ctypes.get_last_error()
|
||||
if last_err != 0: # If the result is not success and last error is invalid.
|
||||
for entry in traceback.format_list(traceback.extract_stack()[:-1]):
|
||||
_log_win32.write(entry)
|
||||
print(f"[Result {result}] Error #{last_err} - {ctypes.FormatError(last_err)}", file=_log_win32)
|
||||
return args
|
||||
|
||||
|
||||
def set_errchecks(lib):
|
||||
"""Set errcheck hook on all functions we have defined."""
|
||||
for key in lib.__dict__:
|
||||
if key.startswith('_'): # Ignore builtins.
|
||||
continue
|
||||
lib.__dict__[key].errcheck = win32_errcheck
|
||||
|
||||
|
||||
set_errchecks(_gdi32)
|
||||
set_errchecks(_kernel32)
|
||||
set_errchecks(_user32)
|
||||
set_errchecks(_dwmapi)
|
||||
set_errchecks(_shell32)
|
||||
set_errchecks(_ole32)
|
||||
set_errchecks(_oleaut32)
|
||||
|
||||
# Initialize COM in MTA mode. Required for: WIC (DirectWrite), WMF, and XInput
|
||||
try:
|
||||
_ole32.CoInitializeEx(None, constants.COINIT_MULTITHREADED)
|
||||
@ -332,4 +324,5 @@ def _uninitialize():
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
atexit.register(_uninitialize)
|
||||
|
@ -230,6 +230,10 @@ class Vec2:
|
||||
return Vec2(self.x + (alpha * (other.x - self.x)),
|
||||
self.y + (alpha * (other.y - self.y)))
|
||||
|
||||
def reflect(self, normal: Vec2) -> Vec2:
|
||||
"""Create a new Vec2 reflected (ricochet) from the given normal."""
|
||||
return self - normal * 2 * normal.dot(self)
|
||||
|
||||
def rotate(self, angle: float) -> Vec2:
|
||||
"""Create a new Vector rotated by the angle. The magnitude remains unchanged.
|
||||
|
||||
|
@ -599,6 +599,111 @@ class Arc(ShapeBase):
|
||||
self._vertex_list.draw(self._draw_mode)
|
||||
|
||||
|
||||
class BezierCurve(ShapeBase):
|
||||
_draw_mode = GL_LINES
|
||||
|
||||
def __init__(self, *points, t=1.0, segments=100, color=(255, 255, 255, 255), batch=None, group=None):
|
||||
"""Create a Bézier curve.
|
||||
|
||||
The curve's anchor point (x, y) defaults to its first control point.
|
||||
|
||||
:Parameters:
|
||||
`points` : List[[int, int]]
|
||||
Control points of the curve.
|
||||
`t` : float
|
||||
Draw `100*t` percent of the curve. 0.5 means the curve
|
||||
is half drawn and 1.0 means draw the whole curve.
|
||||
`segments` : int
|
||||
You can optionally specify how many line segments the
|
||||
curve should be made from.
|
||||
`color` : (int, int, int, int)
|
||||
The RGB or RGBA color of the curve, specified as a
|
||||
tuple of 3 or 4 ints in the range of 0-255. RGB colors
|
||||
will be treated as having an opacity of 255.
|
||||
`batch` : `~pyglet.graphics.Batch`
|
||||
Optional batch to add the curve to.
|
||||
`group` : `~pyglet.graphics.Group`
|
||||
Optional parent group of the curve.
|
||||
"""
|
||||
self._points = list(points)
|
||||
self._t = t
|
||||
self._segments = segments
|
||||
self._num_verts = self._segments * 2
|
||||
r, g, b, *a = color
|
||||
self._rgba = r, g, b, a[0] if a else 255
|
||||
|
||||
program = get_default_shader()
|
||||
self._batch = batch or Batch()
|
||||
self._group = _ShapeGroup(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, program, group)
|
||||
|
||||
self._create_vertex_list()
|
||||
self._update_vertices()
|
||||
|
||||
def _make_curve(self, t):
|
||||
n = len(self._points) - 1
|
||||
p = [0, 0]
|
||||
for i in range(n + 1):
|
||||
m = math.comb(n, i) * (1 - t) ** (n - i) * t ** i
|
||||
p[0] += m * self._points[i][0]
|
||||
p[1] += m * self._points[i][1]
|
||||
return p
|
||||
|
||||
def _create_vertex_list(self):
|
||||
self._vertex_list = self._group.program.vertex_list(
|
||||
self._num_verts, self._draw_mode, self._batch, self._group,
|
||||
colors=('Bn', self._rgba * self._num_verts),
|
||||
translation=('f', (self._points[0]) * self._num_verts))
|
||||
|
||||
def _update_vertices(self):
|
||||
if not self._visible:
|
||||
vertices = (0,) * self._segments * 4
|
||||
else:
|
||||
x = -self._anchor_x
|
||||
y = -self._anchor_y
|
||||
|
||||
# Calculate the points of the curve:
|
||||
points = [(x + self._make_curve(self._t * t / self._segments)[0],
|
||||
y + self._make_curve(self._t * t / self._segments)[1]) for t in range(self._segments + 1)]
|
||||
trans_x, trans_y = points[0]
|
||||
trans_x += self._anchor_x
|
||||
trans_y += self._anchor_y
|
||||
coords = [[x - trans_x, y - trans_y] for x, y in points]
|
||||
|
||||
# Create a list of doubled-up points from the points:
|
||||
vertices = []
|
||||
for i in range(len(coords) - 1):
|
||||
line_points = *coords[i], *coords[i + 1]
|
||||
vertices.extend(line_points)
|
||||
|
||||
self._vertex_list.vertices[:] = vertices
|
||||
|
||||
@property
|
||||
def points(self):
|
||||
"""Control points of the curve.
|
||||
|
||||
:type: List[[int, int]]
|
||||
"""
|
||||
return self._points
|
||||
|
||||
@points.setter
|
||||
def points(self, value):
|
||||
self._points = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def t(self):
|
||||
"""Draw `100*t` percent of the curve.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._t
|
||||
|
||||
@t.setter
|
||||
def t(self, value):
|
||||
self._t = value
|
||||
self._update_vertices()
|
||||
|
||||
|
||||
class Circle(ShapeBase):
|
||||
def __init__(self, x, y, radius, segments=None, color=(255, 255, 255, 255),
|
||||
batch=None, group=None):
|
||||
@ -799,14 +904,6 @@ class Ellipse(ShapeBase):
|
||||
self._rotation = rotation
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
def draw(self):
|
||||
"""Draw the shape at its current position.
|
||||
|
||||
Using this method is not recommended. Instead, add the
|
||||
shape to a `pyglet.graphics.Batch` for efficient rendering.
|
||||
"""
|
||||
self._vertex_list.draw(self._draw_mode)
|
||||
|
||||
|
||||
class Sector(ShapeBase):
|
||||
def __init__(self, x, y, radius, segments=None, angle=math.tau, start_angle=0,
|
||||
@ -1677,4 +1774,4 @@ class Polygon(ShapeBase):
|
||||
self._vertex_list.rotation[:] = (rotation,) * self._num_verts
|
||||
|
||||
|
||||
__all__ = 'Arc', 'Circle', 'Ellipse', 'Line', 'Rectangle', 'BorderedRectangle', 'Triangle', 'Star', 'Polygon', 'Sector'
|
||||
__all__ = 'Arc', 'BezierCurve', 'Circle', 'Ellipse', 'Line', 'Rectangle', 'BorderedRectangle', 'Triangle', 'Star', 'Polygon', 'Sector'
|
||||
|
@ -185,7 +185,8 @@ class Win32Window(BaseWindow):
|
||||
self._get_window_proc(self._event_handlers))
|
||||
self._window_class.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC
|
||||
self._window_class.hInstance = 0
|
||||
self._window_class.hIcon = _user32.LoadIconW(module, MAKEINTRESOURCE(1))
|
||||
self._window_class.hIcon = _user32.LoadImageW(module, MAKEINTRESOURCE(1), IMAGE_ICON,
|
||||
0, 0, LR_DEFAULTSIZE | LR_SHARED)
|
||||
self._window_class.hbrBackground = black
|
||||
self._window_class.lpszMenuName = None
|
||||
self._window_class.cbClsExtra = 0
|
||||
@ -233,10 +234,6 @@ class Win32Window(BaseWindow):
|
||||
self._view_window_class.hInstance,
|
||||
0)
|
||||
|
||||
if not self._view_hwnd:
|
||||
last_error = _kernel32.GetLastError()
|
||||
raise Exception("Failed to create handle", self, last_error, self._view_hwnd, self._hwnd)
|
||||
|
||||
self._dc = _user32.GetDC(self._view_hwnd)
|
||||
|
||||
# Only allow files being dropped if specified.
|
||||
@ -295,9 +292,9 @@ class Win32Window(BaseWindow):
|
||||
self.context.attach(self.canvas)
|
||||
self._wgl_context = self.context._context
|
||||
|
||||
self.set_caption(self._caption)
|
||||
|
||||
self.switch_to()
|
||||
|
||||
self.set_caption(self._caption)
|
||||
self.set_vsync(self._vsync)
|
||||
|
||||
if self._visible:
|
||||
@ -320,6 +317,8 @@ class Win32Window(BaseWindow):
|
||||
super(Win32Window, self).close()
|
||||
return
|
||||
|
||||
self.set_mouse_platform_visible(True)
|
||||
|
||||
_user32.DestroyWindow(self._hwnd)
|
||||
_user32.UnregisterClassW(self._view_window_class.lpszClassName, 0)
|
||||
_user32.UnregisterClassW(self._window_class.lpszClassName, 0)
|
||||
@ -328,7 +327,6 @@ class Win32Window(BaseWindow):
|
||||
self._view_window_class = None
|
||||
self._view_event_handlers.clear()
|
||||
self._event_handlers.clear()
|
||||
self.set_mouse_platform_visible(True)
|
||||
self._hwnd = None
|
||||
self._dc = None
|
||||
self._wgl_context = None
|
||||
@ -464,7 +462,7 @@ class Win32Window(BaseWindow):
|
||||
else:
|
||||
cursor = self._create_cursor_from_image(self._mouse_cursor)
|
||||
|
||||
_user32.SetClassLongW(self._view_hwnd, GCL_HCURSOR, cursor)
|
||||
_user32.SetClassLongPtrW(self._view_hwnd, GCL_HCURSOR, cursor)
|
||||
_user32.SetCursor(cursor)
|
||||
|
||||
if platform_visible == self._mouse_platform_visible:
|
||||
@ -546,7 +544,7 @@ class Win32Window(BaseWindow):
|
||||
|
||||
if exclusive and self._has_focus:
|
||||
_user32.RegisterHotKey(self._hwnd, 0, WIN32_MOD_ALT, VK_TAB)
|
||||
else:
|
||||
elif self._exclusive_keyboard and not exclusive:
|
||||
_user32.UnregisterHotKey(self._hwnd, 0)
|
||||
|
||||
self._exclusive_keyboard = exclusive
|
||||
|
Loading…
Reference in New Issue
Block a user