# coding: utf-8 """ GLUT Inputhook support functions """ #----------------------------------------------------------------------------- # Copyright (C) 2008-2009 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- # GLUT is quite an old library and it is difficult to ensure proper # integration within IPython since original GLUT does not allow to handle # events one by one. Instead, it requires for the mainloop to be entered # and never returned (there is not even a function to exit he # mainloop). Fortunately, there are alternatives such as freeglut # (available for linux and windows) and the OSX implementation gives # access to a glutCheckLoop() function that blocks itself until a new # event is received. This means we have to setup a default timer to # ensure we got at least one event that will unblock the function. We set # a default timer of 60fps. # # Furthermore, it is not possible to install these handlers without a # window being first created. We choose to make this window invisible and # the user is supposed to make it visible when needed (see gui-glut.py in # the docs/examples/lib directory). This means that display mode options # are set at this level and user won't be able to change them later # without modifying the code. This should probably be made available via # IPython options system. #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import sys import time import signal import OpenGL OpenGL.ERROR_CHECKING = False import OpenGL.GLUT as glut import OpenGL.platform as platform #----------------------------------------------------------------------------- # Constants #----------------------------------------------------------------------------- # Frame per second : 60 # Should probably be an IPython option glut_fps = 60 # Display mode : double buffeed + rgba + depth # Should probably be an IPython option glut_display_mode = (glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH) glutMainLoopEvent = None if sys.platform == 'darwin': try: glutCheckLoop = platform.createBaseFunction( 'glutCheckLoop', dll=platform.GLUT, resultType=None, argTypes=[], doc='glutCheckLoop( ) -> None', argNames=(), ) except AttributeError: raise RuntimeError( '''Your glut implementation does not allow interactive sessions''' '''Consider installing freeglut.''') glutMainLoopEvent = glutCheckLoop elif glut.HAVE_FREEGLUT: glutMainLoopEvent = glut.glutMainLoopEvent else: raise RuntimeError( '''Your glut implementation does not allow interactive sessions. ''' '''Consider installing freeglut.''') #----------------------------------------------------------------------------- # Callback functions #----------------------------------------------------------------------------- def glut_display(): # Dummy display function pass def glut_timer(fps): # We should normally set the active window to 1 and post a # redisplay for each window. The problem is that we do not know # how much active windows we have and there is no function in glut # to get that number. # glut.glutSetWindow(1) glut.glutTimerFunc( int(1000.0/fps), glut_timer, fps) glut.glutPostRedisplay() def glut_close(): glut.glutHideWindow() def glut_int_handler(signum, frame): signal.signal(signal.SIGINT, signal.default_int_handler) print '\nKeyboardInterrupt' # Need to reprint the prompt at this stage def inputhook_glut(): """ Process pending GLUT events only. """ # We need to protect against a user pressing Control-C when IPython # is idle and this is running. We should trap KeyboardInterrupt and # pass but it does not seem to work with glutMainLoopEvent. # Instead, we setup a signal handler on SIGINT and returns after # having restored the default python SIGINT handler. signal.signal(signal.SIGINT, glut_int_handler) try: glutMainLoopEvent() except KeyboardInterrupt: # this catch doesn't work for some reasons... pass return 0