Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Tried to fix the CTRL-C problem (ipython#742) and take other comments…

…/typos into account
  • Loading branch information...
commit cf4c3264e4c0328ed7baa3f60f48c64d2dc3c361 1 parent 81308e3
Nicolas P. Rougier authored fperez committed
Showing with 142 additions and 79 deletions.
  1. +142 −79 IPython/lib/inputhook.py
221 IPython/lib/inputhook.py
View
@@ -285,15 +285,8 @@ def disable_tk(self):
"""
self.clear_inputhook()
-
-<<<<<<< HEAD
-
- def enable_pyglet(self, app=None):
- """Enable event loop integration with pyglet.
-=======
def enable_glut(self, app=None):
"""Enable event loop integration with GLUT.
->>>>>>> Added code for the GLUT interactive session
Parameters
----------
@@ -304,46 +297,17 @@ def enable_glut(self, app=None):
Notes
-----
-<<<<<<< HEAD
- This methods sets the ``PyOS_InputHook`` for pyglet, which allows
- pyglet to integrate with terminal based applications like
- IPython.
-
- """
- import pyglet
- from IPython.lib.inputhookpyglet import inputhook_pyglet
- self.set_inputhook(inputhook_pyglet)
- self._current_gui = GUI_PYGLET
- return app
-
- def disable_pyglet(self):
- """Disable event loop integration with pyglet.
- This merely sets PyOS_InputHook to NULL.
- """
-=======
- This methods sets the PyOS_InputHook for GLUT, which allows
- the GLUT to integrate with terminal based applications like
- IPython.
+ This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to
+ integrate with terminal based applications like IPython. Due to GLUT
+ limitations, it is currently not possible to start the event loop
+ without first creating a window. You should thus not create another
+ window but use instead the created one. See 'gui-glut.py' in the
+ docs/examples/lib directory.
+
+ The default screen mode is set to:
- 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.
+ glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH
Script integration
------------------
@@ -361,12 +325,44 @@ def disable_pyglet(self):
if not interactive:
glut.glutMainLoop()
"""
+ # 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.
+
+ import OpenGL
+ OpenGL.ERROR_CHECKING = False
import OpenGL.GLUT as glut
import OpenGL.platform as platform
+ import time
- def timer_none(fps):
- ''' Dummy timer function '''
- pass
+
+ # 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)
+
+ glut_interrupted = False
def display():
''' Dummy display function '''
@@ -381,13 +377,16 @@ def timer(fps):
glut.glutTimerFunc( int(1000.0/fps), timer, fps)
glut.glutPostRedisplay()
+ def close():
+ glut.glutHideWindow()
+
glutMainLoopEvent = None
if sys.platform == 'darwin':
try:
- glutCheckLoop = platform.createBaseFunction(
- 'glutCheckLoop', dll=platform.GLUT, resultType=None,
+ glutCheckLoop = platform.createBaseFunction(
+ 'glutCheckLoop', dll=platform.GLUT, resultType=None,
argTypes=[],
- doc='glutCheckLoop( ) -> None',
+ doc='glutCheckLoop( ) -> None',
argNames=(),
)
except AttributeError:
@@ -403,50 +402,120 @@ def timer(fps):
'''Consider installing freeglut.''')
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 trap KeyboardInterrupt and pass.
+ """ 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.
+ import signal
+ def handler(signum, frame):
+ signal.signal(signal.SIGINT, signal.default_int_handler)
+ print '\nKeyboardInterrupt'
+ # Need to reprint the prompt at this stage
+
+ signal.signal(signal.SIGINT, handler)
+
try:
glutMainLoopEvent()
- except KeyboardInterrupt:
+ except KeyboardInterrupt: # this catch doesn't work for some reasons...
pass
- return 0
- # Frame per second : 60
- # Should be probably an IPython option
- fps = 60
+ return 0
+
if not self._apps.has_key(GUI_GLUT):
glut.glutInit(sys.argv)
-
- # Display mode shoudl be also an Ipython option since user won't be able
+ # Display mode should be also an Ipython option since user won't be able
# to change it later
- glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH)
+ glut.glutInitDisplayMode(glut_display_mode)
glut.glutCreateWindow(sys.argv[0])
- # glut.glutReshapeWindow(1,1)
glut.glutHideWindow()
+ glut.glutWMCloseFunc(close)
glut.glutDisplayFunc(display)
- glut.glutTimerFunc( int(1000.0/fps), timer, fps)
+ glut.glutTimerFunc( int(1000.0/glut_fps), timer, glut_fps)
else:
+ glut.glutWMCloseFunc(close)
glut.glutDisplayFunc(display)
- glut.glutTimerFunc( int(1000.0/fps), timer, fps)
+ glut.glutTimerFunc( int(1000.0/glut_fps), timer, glut_fps)
self.set_inputhook(inputhook_glut)
self._current_gui = GUI_GLUT
self._apps[GUI_GLUT] = True
-
def disable_glut(self):
"""Disable event loop integration with glut.
-
+
This sets PyOS_InputHook to NULL and set the display function to a
dummy one and set the timer to a dummy timer that will be triggered
very far in the future.
"""
- glut.HideWindow()
- glut.glutTimerFunc( sys.maxint-1, null_timer_none, 0)
->>>>>>> Added code for the GLUT interactive session
+ import signal
+ import OpenGL
+ OpenGL.ERROR_CHECKING = False
+ import OpenGL.GLUT as glut
+ import OpenGL.platform as platform
+
+ def timer_none(fps):
+ ''' Dummy timer function '''
+ pass
+
+ 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.''')
+
+ glut.glutHideWindow() # This is an event to be processed below
+ glutMainLoopEvent()
+ #glut.glutTimerFunc( sys.maxint-1, timer_none, 0)
self.clear_inputhook()
+ #signal.signal(signal.SIGINT, signal.default_int_handler)
+
+ def enable_pyglet(self, app=None):
+ """Enable event loop integration with pyglet.
+
+ Parameters
+ ----------
+ app : ignored
+ Ignored, it's only a placeholder to keep the call signature of all
+ gui activation methods consistent, which simplifies the logic of
+ supporting magics.
+ Notes
+ -----
+ This methods sets the ``PyOS_InputHook`` for pyglet, which allows
+ pyglet to integrate with terminal based applications like
+ IPython.
+
+ """
+ import pyglet
+ from IPython.lib.inputhookpyglet import inputhook_pyglet
+ self.set_inputhook(inputhook_pyglet)
+ self._current_gui = GUI_PYGLET
+ return app
+
+ def disable_pyglet(self):
+ """Disable event loop integration with pyglet.
+
+ This merely sets PyOS_InputHook to NULL.
+ """
+ self.clear_inputhook()
def current_gui(self):
"""Return a string indicating the currently active GUI or None."""
@@ -462,13 +531,10 @@ def current_gui(self):
disable_gtk = inputhook_manager.disable_gtk
enable_tk = inputhook_manager.enable_tk
disable_tk = inputhook_manager.disable_tk
-<<<<<<< HEAD
-enable_pyglet = inputhook_manager.enable_pyglet
-disable_pyglet = inputhook_manager.disable_pyglet
-=======
enable_glut = inputhook_manager.enable_glut
disable_glut = inputhook_manager.disable_glut
->>>>>>> Added code for the GLUT interactive session
+enable_pyglet = inputhook_manager.enable_pyglet
+disable_pyglet = inputhook_manager.disable_pyglet
clear_inputhook = inputhook_manager.clear_inputhook
set_inputhook = inputhook_manager.set_inputhook
current_gui = inputhook_manager.current_gui
@@ -507,12 +573,9 @@ def enable_gui(gui=None, app=None):
GUI_WX: enable_wx,
GUI_QT: enable_qt4, # qt3 not supported
GUI_QT4: enable_qt4,
-<<<<<<< HEAD
+ GUI_GLUT: enable_glut,
GUI_PYGLET: enable_pyglet,
}
-=======
- GUI_GLUT: enable_glut}
->>>>>>> Added code for the GLUT interactive session
try:
gui_hook = guis[gui]
except KeyError:
Please sign in to comment.
Something went wrong with that request. Please try again.