# ---------------------------------------------------------------------------- # pyglet # Copyright (c) 2006-2008 Alex Holkner # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # * Neither the name of pyglet nor the names of its # contributors may be used to endorse or promote products # derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- '''pyglet is a cross-platform games and multimedia package. Detailed documentation is available at http://www.pyglet.org ''' __docformat__ = 'restructuredtext' __version__ = '$Id: __init__.py 2284 2008-10-04 02:29:50Z Alex.Holkner $' import os import sys _is_epydoc = hasattr(sys, 'is_epydoc') and sys.is_epydoc #: The release version of this pyglet installation. #: #: Valid only if pyglet was installed from a source or binary distribution #: (i.e. not in a checked-out copy from SVN). #: #: Use setuptools if you need to check for a specific release version, e.g.:: #: #: >>> import pyglet #: >>> from pkg_resources import parse_version #: >>> parse_version(pyglet.version) >= parse_version('1.1') #: True #: version = '1.1.2' def _require_ctypes_version(version): # Check ctypes version import ctypes req = [int(i) for i in version.split('.')] have = [int(i) for i in ctypes.__version__.split('.')] if not tuple(have) >= tuple(req): raise ImportError('pyglet requires ctypes %s or later.' % version) _require_ctypes_version('1.0.0') _enable_optimisations = not __debug__ if getattr(sys, 'frozen', None): _enable_optimisations = True #: Global dict of pyglet options. To change an option from its default, you #: must import ``pyglet`` before any sub-packages. For example:: #: #: import pyglet #: pyglet.options['debug_gl'] = False #: #: The default options can be overridden from the OS environment. The #: corresponding environment variable for each option key is prefaced by #: ``PYGLET_``. For example, in Bash you can set the ``debug_gl`` option with:: #: #: PYGLET_DEBUG_GL=True; export PYGLET_DEBUG_GL #: #: For options requiring a tuple of values, separate each value with a comma. #: #: The non-development options are: #: #: audio #: A sequence of the names of audio modules to attempt to load, in #: order of preference. Valid driver names are: #: #: * directsound, the Windows DirectSound audio module (Windows only) #: * alsa, the ALSA audio module (Linux only) #: * openal, the OpenAL audio module #: * silent, no audio #: debug_lib #: If True, prints the path of each dynamic library loaded. #: debug_gl #: If True, all calls to OpenGL functions are checked afterwards for #: errors using ``glGetError``. This will severely impact performance, #: but provides useful exceptions at the point of failure. By default, #: this option is enabled if ``__debug__`` is (i.e., if Python was not run #: with the -O option). It is disabled by default when pyglet is "frozen" #: within a py2exe or py2app library archive. #: shadow_window #: By default, pyglet creates a hidden window with a GL context when #: pyglet.gl is imported. This allows resources to be loaded before #: the application window is created, and permits GL objects to be #: shared between windows even after they've been closed. You can #: disable the creation of the shadow window by setting this option to #: False. Recommended for advanced devlopers only. #: #: **Since:** pyglet 1.1 #: vsync #: If set, the `pyglet.window.Window.vsync` property is ignored, and #: this option overrides it (to either force vsync on or off). If unset, #: or set to None, the `pyglet.window.Window.vsync` property behaves #: as documented. #: xsync #: If set (the default), pyglet will attempt to synchronise the drawing of #: double-buffered windows to the border updates of the X11 window #: manager. This improves the appearance of the window during resize #: operations. This option only affects double-buffered windows on #: X11 servers supporting the Xsync extension with a window manager #: that implements the _NET_WM_SYNC_REQUEST protocol. #: #: **Since:** pyglet 1.1 #: options = { 'audio': ('directsound', 'openal', 'alsa', 'silent'), 'font': ('gdiplus', 'win32'), # ignored outside win32; win32 is deprecated 'debug_font': False, 'debug_gl': not _enable_optimisations, 'debug_gl_trace': False, 'debug_gl_trace_args': False, 'debug_graphics_batch': False, 'debug_lib': False, 'debug_media': False, 'debug_texture': False, 'debug_trace': False, 'debug_trace_args': False, 'debug_trace_depth': 1, 'debug_trace_flush': True, 'debug_win32': False, 'debug_x11': False, 'graphics_vbo': True, 'shadow_window': True, 'vsync': None, 'xsync': True, } _option_types = { 'audio': tuple, 'font': tuple, 'debug_font': bool, 'debug_gl': bool, 'debug_gl_trace': bool, 'debug_gl_trace_args': bool, 'debug_graphics_batch': bool, 'debug_lib': bool, 'debug_media': bool, 'debug_texture': bool, 'debug_trace': bool, 'debug_trace_args': bool, 'debug_trace_depth': int, 'debug_trace_flush': bool, 'debug_win32': bool, 'debug_x11': bool, 'graphics_vbo': bool, 'shadow_window': bool, 'vsync': bool, 'xsync': bool, } def _read_environment(): '''Read defaults for options from environment''' for key in options: env = 'PYGLET_%s' % key.upper() try: value = os.environ['PYGLET_%s' % key.upper()] if _option_types[key] is tuple: options[key] = value.split(',') elif _option_types[key] is bool: options[key] = value in ('true', 'TRUE', 'True', '1') elif _option_types[key] is int: options[key] = int(value) except KeyError: pass _read_environment() if sys.platform == 'cygwin': # This hack pretends that the posix-like ctypes provides windows # functionality. COM does not work with this hack, so there is no # DirectSound support. import ctypes ctypes.windll = ctypes.cdll ctypes.oledll = ctypes.cdll ctypes.WINFUNCTYPE = ctypes.CFUNCTYPE ctypes.HRESULT = ctypes.c_long # Call tracing # ------------ _trace_filename_abbreviations = {} def _trace_repr(value, size=40): value = repr(value) if len(value) > size: value = value[:size//2-2] + '...' + value[-size//2-1:] return value def _trace_frame(frame, indent): from pyglet import lib import os if frame.f_code is lib._TraceFunction.__call__.func_code: is_ctypes = True func = frame.f_locals['self']._func name = func.__name__ location = '[ctypes]' else: is_ctypes = False code = frame.f_code name = code.co_name path = code.co_filename line = code.co_firstlineno try: filename = _trace_filename_abbreviations[path] except KeyError: # Trim path down dir = '' path, filename = os.path.split(path) while len(dir + filename) < 30: filename = os.path.join(dir, filename) path, dir = os.path.split(path) if not dir: filename = os.path.join('', filename) break else: filename = os.path.join('...', filename) _trace_filename_abbreviations[path] = filename location = '(%s:%d)' % (filename, line) if indent: name = 'Called from %s' % name print '%s%s %s' % (indent, name, location) if _trace_args: if is_ctypes: args = [_trace_repr(arg) for arg in frame.f_locals['args']] print ' %sargs=(%s)' % (indent, ', '.join(args)) else: for argname in code.co_varnames[:code.co_argcount]: try: argvalue = _trace_repr(frame.f_locals[argname]) print ' %s%s=%s' % (indent, argname, argvalue) except: pass if _trace_flush: sys.stdout.flush() def _trace_func(frame, event, arg): if event == 'call': indent = '' for i in range(_trace_depth): _trace_frame(frame, indent) indent += ' ' frame = frame.f_back if not frame: break elif event == 'exception': (exception, value, traceback) = arg print 'First chance exception raised:', repr(exception) def _install_trace(): sys.setprofile(_trace_func) _trace_args = options['debug_trace_args'] _trace_depth = options['debug_trace_depth'] _trace_flush = options['debug_trace_flush'] if options['debug_trace']: _install_trace() # Lazy loading # ------------ class _ModuleProxy(object): _module = None def __init__(self, name): self.__dict__['_module_name'] = name def __getattr__(self, name): try: return getattr(self._module, name) except AttributeError: if self._module is not None: raise import_name = 'pyglet.%s' % self._module_name __import__(import_name) module = sys.modules[import_name] object.__setattr__(self, '_module', module) globals()[self._module_name] = module return getattr(module, name) def __setattr__(self, name, value): try: setattr(self._module, name, value) except AttributeError: if self._module is not None: raise import_name = 'pyglet.%s' % self._module_name __import__(import_name) module = sys.modules[import_name] object.__setattr__(self, '_module', module) globals()[self._module_name] = module setattr(module, name, value) if not _is_epydoc: app = _ModuleProxy('app') clock = _ModuleProxy('clock') com = _ModuleProxy('com') event = _ModuleProxy('event') font = _ModuleProxy('font') gl = _ModuleProxy('gl') graphics = _ModuleProxy('graphics') image = _ModuleProxy('image') lib = _ModuleProxy('lib') media = _ModuleProxy('media') resource = _ModuleProxy('resource') sprite = _ModuleProxy('sprite') text = _ModuleProxy('text') window = _ModuleProxy('window') # Fool py2exe, py2app into including all top-level modules (doesn't understand # lazy loading) if False: import app import clock import com import event import font import gl import graphics import image import lib import media import resource import sprite import text import window # Hack around some epydoc bug that causes it to think pyglet.window is None. if _is_epydoc: import window