diff --git a/libs/pyglet/__init__.py b/libs/pyglet/__init__.py index fd21d83..aed95d0 100644 --- a/libs/pyglet/__init__.py +++ b/libs/pyglet/__init__.py @@ -44,7 +44,7 @@ import sys from typing import TYPE_CHECKING #: The release version -version = '2.0.0' +version = '2.0.1' __version__ = version MIN_PYTHON_VERSION = 3, 8 diff --git a/libs/pyglet/app/base.py b/libs/pyglet/app/base.py index 92123e8..2356187 100644 --- a/libs/pyglet/app/base.py +++ b/libs/pyglet/app/base.py @@ -52,7 +52,6 @@ class PlatformEventLoop: def __init__(self): self._event_queue = queue.Queue() self._is_running = threading.Event() - self._is_running.clear() def is_running(self): """Return True if the event loop is currently processing, or False diff --git a/libs/pyglet/app/win32.py b/libs/pyglet/app/win32.py index c4cf879..a9a5d70 100644 --- a/libs/pyglet/app/win32.py +++ b/libs/pyglet/app/win32.py @@ -33,6 +33,8 @@ # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- +import ctypes + from .base import PlatformEventLoop from pyglet.libs.win32 import _kernel32, _user32, types, constants @@ -41,7 +43,7 @@ from pyglet.libs.win32.types import * class Win32EventLoop(PlatformEventLoop): def __init__(self): - super(Win32EventLoop, self).__init__() + super().__init__() self._next_idle_time = None @@ -50,7 +52,7 @@ class Win32EventLoop(PlatformEventLoop): # imports pyglet.app _must_ own the main run loop. msg = types.MSG() _user32.PeekMessageW(ctypes.byref(msg), 0, - constants.WM_USER, constants.WM_USER, + constants.WM_USER, constants.WM_USER, constants.PM_NOREMOVE) self._event_thread = _kernel32.GetCurrentThreadId() @@ -60,9 +62,15 @@ class Win32EventLoop(PlatformEventLoop): self._timer_proc = types.TIMERPROC(self._timer_proc_func) self._timer = _user32.SetTimer(0, 0, constants.USER_TIMER_MAXIMUM, self._timer_proc) - self._timer_func = None + # Windows Multimedia timer precision functions + # https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod + self._winmm = ctypes.windll.LoadLibrary('winmm') + timecaps = TIMECAPS() + self._winmm.timeGetDevCaps(ctypes.byref(timecaps), ctypes.sizeof(timecaps)) + self._timer_precision = min(max(1, timecaps.wPeriodMin), timecaps.wPeriodMax) + def add_wait_object(self, obj, func): self._wait_objects.append((obj, func)) self._recreate_wait_objects_array() @@ -81,8 +89,7 @@ class Win32EventLoop(PlatformEventLoop): return self._wait_objects_n = len(self._wait_objects) - self._wait_objects_array = \ - (HANDLE * self._wait_objects_n)(*[o for o, f in self._wait_objects]) + self._wait_objects_array = (HANDLE * self._wait_objects_n)(*[o for o, f in self._wait_objects]) def start(self): if _kernel32.GetCurrentThreadId() != self._event_thread: @@ -90,8 +97,8 @@ class Win32EventLoop(PlatformEventLoop): 'thread that imports pyglet.app') self._timer_func = None - self._polling = False - self._allow_polling = True + + self._winmm.timeBeginPeriod(self._timer_precision) def step(self, timeout=None): self.dispatch_posted_events() @@ -100,7 +107,7 @@ class Win32EventLoop(PlatformEventLoop): if timeout is None: timeout = constants.INFINITE else: - timeout = int(timeout * 1000) # milliseconds + timeout = int(timeout * 1000) # milliseconds result = _user32.MsgWaitForMultipleObjects( self._wait_objects_n, @@ -122,6 +129,9 @@ class Win32EventLoop(PlatformEventLoop): # Return True if timeout was interrupted. return result <= self._wait_objects_n + def stop(self): + self._winmm.timeEndPeriod(self._timer_precision) + def notify(self): # Nudge the event loop with a message it will discard. Note that only # user events are actually posted. The posted event will not @@ -133,11 +143,11 @@ class Win32EventLoop(PlatformEventLoop): if func is None or interval is None: interval = constants.USER_TIMER_MAXIMUM else: - interval = int(interval * 1000) # milliseconds - + interval = int(interval * 1000) # milliseconds + self._timer_func = func _user32.SetTimer(0, self._timer, interval, self._timer_proc) - + def _timer_proc_func(self, hwnd, msg, timer, t): if self._timer_func: self._timer_func() diff --git a/libs/pyglet/canvas/base.py b/libs/pyglet/canvas/base.py index 251cc57..9636f85 100644 --- a/libs/pyglet/canvas/base.py +++ b/libs/pyglet/canvas/base.py @@ -98,12 +98,18 @@ class Display: raise NotImplementedError('abstract') def get_default_screen(self): - """Get the default screen as specified by the user's operating system + """Get the default (primary) screen as specified by the user's operating system preferences. :rtype: :class:`Screen` """ - return self.get_screens()[0] + screens = self.get_screens() + for screen in screens: + if screen.x == 0 and screen.y == 0: + return screen + + # No Primary screen found? + return screens[0] def get_windows(self): """Get the windows currently attached to this display. diff --git a/libs/pyglet/gl/base.py b/libs/pyglet/gl/base.py index 729fabf..2cc3b9c 100644 --- a/libs/pyglet/gl/base.py +++ b/libs/pyglet/gl/base.py @@ -120,7 +120,7 @@ class Config: major_version = None minor_version = None forward_compatible = None - opengl_api = "gl" + opengl_api = None debug = None def __init__(self, **kwargs): @@ -137,13 +137,7 @@ class Config: else: setattr(self, name, None) - def requires_gl_3(self): - # TODO: remove deprecated - if self.major_version is not None and self.major_version >= 3: - return True - if self.forward_compatible or self.debug: - return True - return False + self.opengl_api = self.opengl_api or "gl" def get_gl_attributes(self): """Return a list of attributes set on this config. @@ -263,15 +257,6 @@ class Context: GL objects. """ - - #: Context share behaviour indicating that objects should not be - #: shared with existing contexts. - CONTEXT_SHARE_NONE = None - - #: Context share behaviour indicating that objects are shared with - #: the most recently created context (the default). - CONTEXT_SHARE_EXISTING = 1 - # gl_info.GLInfo instance, filled in on first set_current _info = None diff --git a/libs/pyglet/gl/cocoa.py b/libs/pyglet/gl/cocoa.py index 15a494f..88025d1 100644 --- a/libs/pyglet/gl/cocoa.py +++ b/libs/pyglet/gl/cocoa.py @@ -288,7 +288,7 @@ class CocoaContext(Context): def attach(self, canvas): # See if we want OpenGL 3 in a non-Lion OS - if _os_x_version < os_x_release['lion'] and self.config.requires_gl_3(): + if _os_x_version < os_x_release['lion']: raise ContextException('OpenGL 3 not supported') super(CocoaContext, self).attach(canvas) diff --git a/libs/pyglet/gl/headless.py b/libs/pyglet/gl/headless.py index 05ddc50..5a07a5b 100644 --- a/libs/pyglet/gl/headless.py +++ b/libs/pyglet/gl/headless.py @@ -33,7 +33,6 @@ # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- -import warnings from ctypes import * from pyglet import gl @@ -53,6 +52,7 @@ _fake_gl_attributes = { 'accum_alpha_size': 0 } + class HeadlessConfig(Config): def match(self, canvas): if not isinstance(canvas, HeadlessCanvas): diff --git a/libs/pyglet/gl/xlib.py b/libs/pyglet/gl/xlib.py index 7d02532..f1125da 100644 --- a/libs/pyglet/gl/xlib.py +++ b/libs/pyglet/gl/xlib.py @@ -36,7 +36,7 @@ import warnings from ctypes import * -from .base import Config, CanvasConfig, Context, OpenGLAPI +from .base import Config, CanvasConfig, Context from pyglet.canvas.xlib import XlibCanvas from pyglet.gl import glx from pyglet.gl import glxext_arb @@ -47,6 +47,7 @@ from pyglet import gl class XlibConfig(Config): + def match(self, canvas): if not isinstance(canvas, XlibCanvas): raise RuntimeError('Canvas must be an instance of XlibCanvas') @@ -55,51 +56,36 @@ class XlibConfig(Config): x_screen = canvas.display.x_screen info = glx_info.GLXInfo(x_display) - have_13 = info.have_version(1, 3) - if have_13: - config_class = XlibCanvasConfig13 - else: - config_class = XlibCanvasConfig10 # Construct array of attributes attrs = [] for name, value in self.get_gl_attributes(): - attr = config_class.attribute_ids.get(name, None) + attr = XlibCanvasConfig.attribute_ids.get(name, None) if attr and value is not None: attrs.extend([attr, int(value)]) - if have_13: - attrs.extend([glx.GLX_X_RENDERABLE, True]) - else: - attrs.extend([glx.GLX_RGBA, True]) - + attrs.extend([glx.GLX_X_RENDERABLE, True]) attrs.extend([0, 0]) # attrib_list must be null terminated + attrib_list = (c_int * len(attrs))(*attrs) - if have_13: - elements = c_int() - configs = glx.glXChooseFBConfig(x_display, x_screen, attrib_list, byref(elements)) - if not configs: - return [] + elements = c_int() + configs = glx.glXChooseFBConfig(x_display, x_screen, attrib_list, byref(elements)) + if not configs: + return [] - configs = cast(configs, POINTER(glx.GLXFBConfig * elements.value)).contents + configs = cast(configs, POINTER(glx.GLXFBConfig * elements.value)).contents - result = [config_class(canvas, info, c, self) for c in configs] + result = [XlibCanvasConfig(canvas, info, c, self) for c in configs] - # Can't free array until all XlibGLConfig13's are GC'd. Too much - # hassle, live with leak. XXX - # xlib.XFree(configs) + # Can't free array until all XlibGLConfig's are GC'd. Too much + # hassle, live with leak. XXX + # xlib.XFree(configs) - return result - else: - try: - return [config_class(canvas, info, attrib_list, self)] - except gl.ContextException: - return [] + return result -class BaseXlibCanvasConfig(CanvasConfig): - # Common code shared between GLX 1.0 and GLX 1.3 configs. +class XlibCanvasConfig(CanvasConfig): attribute_ids = { 'buffer_size': glx.GLX_BUFFER_SIZE, @@ -117,56 +103,7 @@ class BaseXlibCanvasConfig(CanvasConfig): 'accum_green_size': glx.GLX_ACCUM_GREEN_SIZE, 'accum_blue_size': glx.GLX_ACCUM_BLUE_SIZE, 'accum_alpha_size': glx.GLX_ACCUM_ALPHA_SIZE, - } - def __init__(self, canvas, glx_info, config): - super(BaseXlibCanvasConfig, self).__init__(canvas, config) - self.glx_info = glx_info - - def compatible(self, canvas): - # TODO check more - return isinstance(canvas, XlibCanvas) - - def _create_glx_context(self, share): - raise NotImplementedError('abstract') - - def is_complete(self): - return True - - def get_visual_info(self): - raise NotImplementedError('abstract') - - -class XlibCanvasConfig10(BaseXlibCanvasConfig): - def __init__(self, canvas, glx_info, attrib_list, config): - super(XlibCanvasConfig10, self).__init__(canvas, glx_info, config) - x_display = canvas.display._display - x_screen = canvas.display.x_screen - - self._visual_info = glx.glXChooseVisual( - x_display, x_screen, attrib_list) - if not self._visual_info: - raise gl.ContextException('No conforming visual exists') - - for name, attr in self.attribute_ids.items(): - value = c_int() - result = glx.glXGetConfig( - x_display, self._visual_info, attr, byref(value)) - if result >= 0: - setattr(self, name, value.value) - self.sample_buffers = 0 - self.samples = 0 - - def get_visual_info(self): - return self._visual_info.contents - - def create_context(self, share): - return XlibContext10(self, share) - - -class XlibCanvasConfig13(BaseXlibCanvasConfig): - attribute_ids = BaseXlibCanvasConfig.attribute_ids.copy() - attribute_ids.update({ 'sample_buffers': glx.GLX_SAMPLE_BUFFERS, 'samples': glx.GLX_SAMPLES, @@ -182,33 +119,40 @@ class XlibCanvasConfig13(BaseXlibCanvasConfig): # Used internally 'x_renderable': glx.GLX_X_RENDERABLE, - }) + } - def __init__(self, canvas, glx_info, fbconfig, config): - super(XlibCanvasConfig13, self).__init__(canvas, glx_info, config) - x_display = canvas.display._display + def __init__(self, canvas, info, fbconfig, config): + super().__init__(canvas, config) + + self.glx_info = info + self.fbconfig = fbconfig - self._fbconfig = fbconfig for name, attr in self.attribute_ids.items(): value = c_int() - result = glx.glXGetFBConfigAttrib( - x_display, self._fbconfig, attr, byref(value)) + result = glx.glXGetFBConfigAttrib(canvas.display._display, self.fbconfig, attr, byref(value)) if result >= 0: setattr(self, name, value.value) def get_visual_info(self): - return glx.glXGetVisualFromFBConfig(self.canvas.display._display, self._fbconfig).contents + return glx.glXGetVisualFromFBConfig(self.canvas.display._display, self.fbconfig).contents def create_context(self, share): - if self.glx_info.have_extension('GLX_ARB_create_context'): - return XlibContextARB(self, share) - else: - return XlibContext13(self, share) + return XlibContext(self, share) + + def compatible(self, canvas): + # TODO check more + return isinstance(canvas, XlibCanvas) + + def _create_glx_context(self, share): + raise NotImplementedError('abstract') + + def is_complete(self): + return True -class BaseXlibContext(Context): +class XlibContext(Context): def __init__(self, config, share): - super(BaseXlibContext, self).__init__(config, share) + super().__init__(config, share) self.x_display = config.canvas.display._display @@ -230,12 +174,81 @@ class BaseXlibContext(Context): self._use_video_sync = (self._have_SGI_video_sync and not (self._have_EXT_swap_control or self._have_MESA_swap_control)) - # XXX mandate that vsync defaults on across all platforms. + # XXX Mandate that vsync defaults on across all platforms. self._vsync = True + self.glx_window = None + def is_direct(self): return glx.glXIsDirect(self.x_display, self.glx_context) + def _create_glx_context(self, share): + if share: + share_context = share.glx_context + else: + share_context = None + + attribs = [] + if self.config.major_version is not None: + attribs.extend([glxext_arb.GLX_CONTEXT_MAJOR_VERSION_ARB, self.config.major_version]) + if self.config.minor_version is not None: + attribs.extend([glxext_arb.GLX_CONTEXT_MINOR_VERSION_ARB, self.config.minor_version]) + + if self.config.opengl_api == "gl": + attribs.extend([glxext_arb.GLX_CONTEXT_PROFILE_MASK_ARB, glxext_arb.GLX_CONTEXT_CORE_PROFILE_BIT_ARB]) + elif self.config.opengl_api == "gles": + attribs.extend([glxext_arb.GLX_CONTEXT_PROFILE_MASK_ARB, glxext_arb.GLX_CONTEXT_ES2_PROFILE_BIT_EXT]) + + flags = 0 + if self.config.forward_compatible: + flags |= glxext_arb.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB + if self.config.debug: + flags |= glxext_arb.GLX_CONTEXT_DEBUG_BIT_ARB + + if flags: + attribs.extend([glxext_arb.GLX_CONTEXT_FLAGS_ARB, flags]) + attribs.append(0) + attribs = (c_int * len(attribs))(*attribs) + + return glxext_arb.glXCreateContextAttribsARB(self.config.canvas.display._display, + self.config.fbconfig, share_context, True, attribs) + + def attach(self, canvas): + if canvas is self.canvas: + return + + super().attach(canvas) + + self.glx_window = glx.glXCreateWindow(self.x_display, self.config.fbconfig, canvas.x_window, None) + self.set_current() + + def set_current(self): + glx.glXMakeContextCurrent(self.x_display, self.glx_window, self.glx_window, self.glx_context) + super().set_current() + + def detach(self): + if not self.canvas: + return + + self.set_current() + gl.glFlush() + + super().detach() + + glx.glXMakeContextCurrent(self.x_display, 0, 0, None) + if self.glx_window: + glx.glXDestroyWindow(self.x_display, self.glx_window) + self.glx_window = None + + def destroy(self): + super().destroy() + if self.glx_window: + glx.glXDestroyWindow(self.config.display._display, self.glx_window) + self.glx_window = None + if self.glx_context: + glx.glXDestroyContext(self.x_display, self.glx_context) + self.glx_context = None + def set_vsync(self, vsync=True): self._vsync = vsync interval = vsync and 1 or 0 @@ -258,157 +271,11 @@ class BaseXlibContext(Context): glxext_arb.glXGetVideoSyncSGI(byref(count)) glxext_arb.glXWaitVideoSyncSGI(2, (count.value + 1) % 2, byref(count)) - -class XlibContext10(BaseXlibContext): - def __init__(self, config, share): - super(XlibContext10, self).__init__(config, share) - - def _create_glx_context(self, share): - if self.config.requires_gl_3(): - raise gl.ContextException( - 'Require GLX_ARB_create_context extension to create OpenGL 3 contexts.') - - if share: - share_context = share.glx_context - else: - share_context = None - - return glx.glXCreateContext(self.config.canvas.display._display, - self.config._visual_info, share_context, True) - - def attach(self, canvas): - super(XlibContext10, self).attach(canvas) - - self.set_current() - - def set_current(self): - glx.glXMakeCurrent(self.x_display, self.canvas.x_window, self.glx_context) - super(XlibContext10, self).set_current() - - def detach(self): - if not self.canvas: - return - - self.set_current() - gl.glFlush() - glx.glXMakeCurrent(self.x_display, 0, None) - super(XlibContext10, self).detach() - - def destroy(self): - super(XlibContext10, self).destroy() - - glx.glXDestroyContext(self.x_display, self.glx_context) - self.glx_context = None - - def flip(self): - if not self.canvas: - return - - if self._vsync: - self._wait_vsync() - glx.glXSwapBuffers(self.x_display, self.canvas.x_window) - - -class XlibContext13(BaseXlibContext): - def __init__(self, config, share): - super(XlibContext13, self).__init__(config, share) - self.glx_window = None - - def _create_glx_context(self, share): - if self.config.requires_gl_3(): - raise gl.ContextException( - 'Require GLX_ARB_create_context extension to create ' + - 'OpenGL 3 contexts.') - - if share: - share_context = share.glx_context - else: - share_context = None - - return glx.glXCreateNewContext(self.config.canvas.display._display, - self.config._fbconfig, glx.GLX_RGBA_TYPE, share_context, - True) - - def attach(self, canvas): - if canvas is self.canvas: - return - - super(XlibContext13, self).attach(canvas) - - self.glx_window = glx.glXCreateWindow( - self.x_display, self.config._fbconfig, canvas.x_window, None) - self.set_current() - - def set_current(self): - glx.glXMakeContextCurrent( - self.x_display, self.glx_window, self.glx_window, self.glx_context) - super(XlibContext13, self).set_current() - - def detach(self): - if not self.canvas: - return - - self.set_current() - gl.glFlush() # needs to be in try/except? - - super(XlibContext13, self).detach() - - glx.glXMakeContextCurrent(self.x_display, 0, 0, None) - if self.glx_window: - glx.glXDestroyWindow(self.x_display, self.glx_window) - self.glx_window = None - - def destroy(self): - super(XlibContext13, self).destroy() - if self.glx_window: - glx.glXDestroyWindow(self.config.display._display, self.glx_window) - self.glx_window = None - if self.glx_context: - glx.glXDestroyContext(self.x_display, self.glx_context) - self.glx_context = None - def flip(self): if not self.glx_window: return if self._vsync: self._wait_vsync() + glx.glXSwapBuffers(self.x_display, self.glx_window) - - -class XlibContextARB(XlibContext13): - def _create_glx_context(self, share): - if share: - share_context = share.glx_context - else: - share_context = None - - attribs = [] - if self.config.major_version is not None: - attribs.extend([glxext_arb.GLX_CONTEXT_MAJOR_VERSION_ARB, - self.config.major_version]) - if self.config.minor_version is not None: - attribs.extend([glxext_arb.GLX_CONTEXT_MINOR_VERSION_ARB, - self.config.minor_version]) - - if self.config.opengl_api == "gl": - attribs.extend([glxext_arb.GLX_CONTEXT_PROFILE_MASK_ARB, glxext_arb.GLX_CONTEXT_CORE_PROFILE_BIT_ARB]) - elif self.config.opengl_api == "gles": - attribs.extend([glxext_arb.GLX_CONTEXT_PROFILE_MASK_ARB, glxext_arb.GLX_CONTEXT_ES2_PROFILE_BIT_EXT]) - else: - raise ValueError(f"Unknown OpenGL API: {self.opengl_api}") - - flags = 0 - if self.config.forward_compatible: - flags |= glxext_arb.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB - if self.config.debug: - flags |= glxext_arb.GLX_CONTEXT_DEBUG_BIT_ARB - - if flags: - attribs.extend([glxext_arb.GLX_CONTEXT_FLAGS_ARB, flags]) - attribs.append(0) - attribs = (c_int * len(attribs))(*attribs) - - return glxext_arb.glXCreateContextAttribsARB( - self.config.canvas.display._display, - self.config._fbconfig, share_context, True, attribs) diff --git a/libs/pyglet/graphics/shader.py b/libs/pyglet/graphics/shader.py index 899b816..7c6949a 100644 --- a/libs/pyglet/graphics/shader.py +++ b/libs/pyglet/graphics/shader.py @@ -687,7 +687,7 @@ class ShaderProgram: raise ShaderException(f"\nThe attribute `{name}` doesn't exist. Valid names: \n{list(attributes)}") batch = batch or pyglet.graphics.get_default_batch() - domain = batch.get_domain(False, mode, group, self._id, attributes) + domain = batch.get_domain(False, mode, group, self, attributes) # Create vertex list and initialize vlist = domain.create(count) @@ -731,7 +731,7 @@ class ShaderProgram: raise ShaderException(f"\nThe attribute `{name}` doesn't exist. Valid names: \n{list(attributes)}") batch = batch or pyglet.graphics.get_default_batch() - domain = batch.get_domain(True, mode, group, self._id, attributes) + domain = batch.get_domain(True, mode, group, self, attributes) # Create vertex list and initialize vlist = domain.create(count, len(indices)) diff --git a/libs/pyglet/libs/win32/types.py b/libs/pyglet/libs/win32/types.py index b9d7d1e..f26d8c4 100644 --- a/libs/pyglet/libs/win32/types.py +++ b/libs/pyglet/libs/win32/types.py @@ -33,12 +33,13 @@ # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- -import sys import ctypes -from . import com + from ctypes import * from ctypes.wintypes import * +from . import com + _int_types = (c_int16, c_int32) if hasattr(ctypes, 'c_int64'): @@ -53,11 +54,6 @@ del t del _int_types -# PUINT is defined only from >= python 3.2 -if sys.version_info < (3, 2)[:2]: - PUINT = POINTER(UINT) - - class c_void(Structure): # c_void_p is a buggy return type, converting to int, so # POINTER(None) == c_void_p is actually written as @@ -76,6 +72,7 @@ def POINTER_(obj): return cls() else: return x + p.from_param = classmethod(from_param) return p @@ -367,6 +364,7 @@ class _DUMMYSTRUCTNAME(Structure): ('dmPrintQuality', c_short), ] + class _DUMMYSTRUCTNAME2(Structure): _fields_ = [ ('dmPosition', POINTL), @@ -374,6 +372,7 @@ class _DUMMYSTRUCTNAME2(Structure): ('dmDisplayFixedOutput', DWORD) ] + class _DUMMYDEVUNION(Union): _anonymous_ = ('_dummystruct1', '_dummystruct2') _fields_ = [ @@ -382,6 +381,7 @@ class _DUMMYDEVUNION(Union): ('_dummystruct2', _DUMMYSTRUCTNAME2), ] + class DEVMODE(Structure): _anonymous_ = ('_dummyUnion',) _fields_ = [ @@ -391,7 +391,7 @@ class DEVMODE(Structure): ('dmSize', WORD), ('dmDriverExtra', WORD), ('dmFields', DWORD), - # Just using largest union member here + # Just using the largest union member here ('_dummyUnion', _DUMMYDEVUNION), # End union ('dmColor', c_short), @@ -404,7 +404,7 @@ class DEVMODE(Structure): ('dmBitsPerPel', DWORD), ('dmPelsWidth', DWORD), ('dmPelsHeight', DWORD), - ('dmDisplayFlags', DWORD), # union with dmNup + ('dmDisplayFlags', DWORD), # union with dmNup ('dmDisplayFrequency', DWORD), ('dmICMMethod', DWORD), ('dmICMIntent', DWORD), @@ -511,7 +511,7 @@ class RAWINPUT(Structure): # PROPVARIANT wrapper, doesn't require InitPropVariantFromInt64 this way. -class _VarTable(ctypes.Union): +class _VarTable(Union): """Must be in an anonymous union or values will not work across various VT's.""" _fields_ = [ ('llVal', ctypes.c_longlong), @@ -519,7 +519,7 @@ class _VarTable(ctypes.Union): ] -class PROPVARIANT(ctypes.Structure): +class PROPVARIANT(Structure): _anonymous_ = ['union'] _fields_ = [ @@ -530,14 +530,15 @@ class PROPVARIANT(ctypes.Structure): ('union', _VarTable) ] -class _VarTableVariant(ctypes.Union): + +class _VarTableVariant(Union): """Must be in an anonymous union or values will not work across various VT's.""" _fields_ = [ ('bstrVal', LPCWSTR) ] -class VARIANT(ctypes.Structure): +class VARIANT(Structure): _anonymous_ = ['union'] _fields_ = [ @@ -548,7 +549,8 @@ class VARIANT(ctypes.Structure): ('union', _VarTableVariant) ] -class DWM_BLURBEHIND(ctypes.Structure): + +class DWM_BLURBEHIND(Structure): _fields_ = [ ("dwFlags", DWORD), ("fEnable", BOOL), @@ -557,7 +559,7 @@ class DWM_BLURBEHIND(ctypes.Structure): ] -class STATSTG(ctypes.Structure): +class STATSTG(Structure): _fields_ = [ ('pwcsName', LPOLESTR), ('type', DWORD), @@ -572,6 +574,12 @@ class STATSTG(ctypes.Structure): ('reserved', DWORD), ] + +class TIMECAPS(Structure): + _fields_ = (('wPeriodMin', UINT), + ('wPeriodMax', UINT)) + + class IStream(com.pIUnknown): _methods_ = [ ('Read', diff --git a/libs/pyglet/shapes.py b/libs/pyglet/shapes.py index f656f55..c377dc1 100644 --- a/libs/pyglet/shapes.py +++ b/libs/pyglet/shapes.py @@ -87,7 +87,7 @@ import pyglet from pyglet.gl import GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA from pyglet.gl import GL_TRIANGLES, GL_LINES, GL_BLEND from pyglet.gl import glBlendFunc, glEnable, glDisable -from pyglet.graphics import shader, Batch, Group +from pyglet.graphics import Batch, Group vertex_source = """#version 150 core