##// END OF EJS Templates
Tried to fix the CTRL-C problem (https://github.com/ipython/ipython/pull/742) and take other comments/typos into account
Nicolas Rougier -
Show More
@@ -285,15 +285,8 b' class InputHookManager(object):'
285 """
285 """
286 self.clear_inputhook()
286 self.clear_inputhook()
287
287
288
289 <<<<<<< HEAD
290
291 def enable_pyglet(self, app=None):
292 """Enable event loop integration with pyglet.
293 =======
294 def enable_glut(self, app=None):
288 def enable_glut(self, app=None):
295 """Enable event loop integration with GLUT.
289 """Enable event loop integration with GLUT.
296 >>>>>>> Added code for the GLUT interactive session
297
290
298 Parameters
291 Parameters
299 ----------
292 ----------
@@ -304,46 +297,17 b' class InputHookManager(object):'
304
297
305 Notes
298 Notes
306 -----
299 -----
307 <<<<<<< HEAD
308 This methods sets the ``PyOS_InputHook`` for pyglet, which allows
309 pyglet to integrate with terminal based applications like
310 IPython.
311
312 """
313 import pyglet
314 from IPython.lib.inputhookpyglet import inputhook_pyglet
315 self.set_inputhook(inputhook_pyglet)
316 self._current_gui = GUI_PYGLET
317 return app
318
319 def disable_pyglet(self):
320 """Disable event loop integration with pyglet.
321
300
322 This merely sets PyOS_InputHook to NULL.
301 This methods sets the PyOS_InputHook for GLUT, which allows the GLUT to
323 """
302 integrate with terminal based applications like IPython. Due to GLUT
324 =======
303 limitations, it is currently not possible to start the event loop
325 This methods sets the PyOS_InputHook for GLUT, which allows
304 without first creating a window. You should thus not create another
326 the GLUT to integrate with terminal based applications like
305 window but use instead the created one. See 'gui-glut.py' in the
327 IPython.
306 docs/examples/lib directory.
307
308 The default screen mode is set to:
328
309
329 GLUT is quite an old library and it is difficult to ensure proper
310 glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH
330 integration within IPython since original GLUT does not allow to handle
331 events one by one. Instead, it requires for the mainloop to be entered
332 and never returned (there is not even a function to exit he
333 mainloop). Fortunately, there are alternatives such as freeglut
334 (available for linux and windows) and the OSX implementation gives
335 access to a glutCheckLoop() function that blocks itself until a new
336 event is received. This means we have to setup a default timer to
337 ensure we got at least one event that will unblock the function. We set
338 a default timer of 60fps.
339
340 Furthermore, it is not possible to install these handlers without a
341 window being first created. We choose to make this window invisible and
342 the user is supposed to make it visible when needed (see gui-glut.py in
343 the docs/examples/lib directory). This means that display mode options
344 are set at this level and user won't be able to change them later
345 without modifying the code. This should probably be made available via
346 IPython options system.
347
311
348 Script integration
312 Script integration
349 ------------------
313 ------------------
@@ -361,12 +325,44 b' class InputHookManager(object):'
361 if not interactive:
325 if not interactive:
362 glut.glutMainLoop()
326 glut.glutMainLoop()
363 """
327 """
328 # GLUT is quite an old library and it is difficult to ensure proper
329 # integration within IPython since original GLUT does not allow to handle
330 # events one by one. Instead, it requires for the mainloop to be entered
331 # and never returned (there is not even a function to exit he
332 # mainloop). Fortunately, there are alternatives such as freeglut
333 # (available for linux and windows) and the OSX implementation gives
334 # access to a glutCheckLoop() function that blocks itself until a new
335 # event is received. This means we have to setup a default timer to
336 # ensure we got at least one event that will unblock the function. We set
337 # a default timer of 60fps.
338 #
339 # Furthermore, it is not possible to install these handlers without a
340 # window being first created. We choose to make this window invisible and
341 # the user is supposed to make it visible when needed (see gui-glut.py in
342 # the docs/examples/lib directory). This means that display mode options
343 # are set at this level and user won't be able to change them later
344 # without modifying the code. This should probably be made available via
345 # IPython options system.
346
347 import OpenGL
348 OpenGL.ERROR_CHECKING = False
364 import OpenGL.GLUT as glut
349 import OpenGL.GLUT as glut
365 import OpenGL.platform as platform
350 import OpenGL.platform as platform
351 import time
366
352
367 def timer_none(fps):
353
368 ''' Dummy timer function '''
354 # Frame per second : 60
369 pass
355 # Should probably be an IPython option
356 glut_fps = 60
357
358
359 # Display mode : double buffeed + rgba + depth
360 # Should probably be an IPython option
361 glut_display_mode = (glut.GLUT_DOUBLE |
362 glut.GLUT_RGBA |
363 glut.GLUT_DEPTH)
364
365 glut_interrupted = False
370
366
371 def display():
367 def display():
372 ''' Dummy display function '''
368 ''' Dummy display function '''
@@ -381,13 +377,16 b' class InputHookManager(object):'
381 glut.glutTimerFunc( int(1000.0/fps), timer, fps)
377 glut.glutTimerFunc( int(1000.0/fps), timer, fps)
382 glut.glutPostRedisplay()
378 glut.glutPostRedisplay()
383
379
380 def close():
381 glut.glutHideWindow()
382
384 glutMainLoopEvent = None
383 glutMainLoopEvent = None
385 if sys.platform == 'darwin':
384 if sys.platform == 'darwin':
386 try:
385 try:
387 glutCheckLoop = platform.createBaseFunction(
386 glutCheckLoop = platform.createBaseFunction(
388 'glutCheckLoop', dll=platform.GLUT, resultType=None,
387 'glutCheckLoop', dll=platform.GLUT, resultType=None,
389 argTypes=[],
388 argTypes=[],
390 doc='glutCheckLoop( ) -> None',
389 doc='glutCheckLoop( ) -> None',
391 argNames=(),
390 argNames=(),
392 )
391 )
393 except AttributeError:
392 except AttributeError:
@@ -403,50 +402,120 b' class InputHookManager(object):'
403 '''Consider installing freeglut.''')
402 '''Consider installing freeglut.''')
404
403
405 def inputhook_glut():
404 def inputhook_glut():
406 """ Process pending GLUT events only. """
405 """ Process pending GLUT events only. """
407 # We need to protect against a user pressing Control-C when IPython is
406
408 # idle and this is running. We trap KeyboardInterrupt and pass.
407 # We need to protect against a user pressing Control-C when IPython
408 # is idle and this is running. We should trap KeyboardInterrupt and
409 # pass but it does not seem to work with glutMainLoopEvent.
410 # Instead, we setup a signal handler on SIGINT and returns after
411 # having restored the default python SIGINT handler.
412 import signal
413 def handler(signum, frame):
414 signal.signal(signal.SIGINT, signal.default_int_handler)
415 print '\nKeyboardInterrupt'
416 # Need to reprint the prompt at this stage
417
418 signal.signal(signal.SIGINT, handler)
419
409 try:
420 try:
410 glutMainLoopEvent()
421 glutMainLoopEvent()
411 except KeyboardInterrupt:
422 except KeyboardInterrupt: # this catch doesn't work for some reasons...
412 pass
423 pass
413 return 0
414
424
415 # Frame per second : 60
425 return 0
416 # Should be probably an IPython option
426
417 fps = 60
418 if not self._apps.has_key(GUI_GLUT):
427 if not self._apps.has_key(GUI_GLUT):
419 glut.glutInit(sys.argv)
428 glut.glutInit(sys.argv)
420
429 # Display mode should be also an Ipython option since user won't be able
421 # Display mode shoudl be also an Ipython option since user won't be able
422 # to change it later
430 # to change it later
423 glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH)
431 glut.glutInitDisplayMode(glut_display_mode)
424 glut.glutCreateWindow(sys.argv[0])
432 glut.glutCreateWindow(sys.argv[0])
425 # glut.glutReshapeWindow(1,1)
426 glut.glutHideWindow()
433 glut.glutHideWindow()
434 glut.glutWMCloseFunc(close)
427 glut.glutDisplayFunc(display)
435 glut.glutDisplayFunc(display)
428 glut.glutTimerFunc( int(1000.0/fps), timer, fps)
436 glut.glutTimerFunc( int(1000.0/glut_fps), timer, glut_fps)
429 else:
437 else:
438 glut.glutWMCloseFunc(close)
430 glut.glutDisplayFunc(display)
439 glut.glutDisplayFunc(display)
431 glut.glutTimerFunc( int(1000.0/fps), timer, fps)
440 glut.glutTimerFunc( int(1000.0/glut_fps), timer, glut_fps)
432
441
433 self.set_inputhook(inputhook_glut)
442 self.set_inputhook(inputhook_glut)
434 self._current_gui = GUI_GLUT
443 self._current_gui = GUI_GLUT
435 self._apps[GUI_GLUT] = True
444 self._apps[GUI_GLUT] = True
436
445
437
438 def disable_glut(self):
446 def disable_glut(self):
439 """Disable event loop integration with glut.
447 """Disable event loop integration with glut.
440
448
441 This sets PyOS_InputHook to NULL and set the display function to a
449 This sets PyOS_InputHook to NULL and set the display function to a
442 dummy one and set the timer to a dummy timer that will be triggered
450 dummy one and set the timer to a dummy timer that will be triggered
443 very far in the future.
451 very far in the future.
444 """
452 """
445 glut.HideWindow()
453 import signal
446 glut.glutTimerFunc( sys.maxint-1, null_timer_none, 0)
454 import OpenGL
447 >>>>>>> Added code for the GLUT interactive session
455 OpenGL.ERROR_CHECKING = False
456 import OpenGL.GLUT as glut
457 import OpenGL.platform as platform
458
459 def timer_none(fps):
460 ''' Dummy timer function '''
461 pass
462
463 glutMainLoopEvent = None
464 if sys.platform == 'darwin':
465 try:
466 glutCheckLoop = platform.createBaseFunction(
467 'glutCheckLoop', dll=platform.GLUT, resultType=None,
468 argTypes=[],
469 doc='glutCheckLoop( ) -> None',
470 argNames=(),
471 )
472 except AttributeError:
473 raise RuntimeError(
474 '''Your glut implementation does not allow interactive sessions'''
475 '''Consider installing freeglut.''')
476 glutMainLoopEvent = glutCheckLoop
477 elif glut.HAVE_FREEGLUT:
478 glutMainLoopEvent = glut.glutMainLoopEvent
479 else:
480 raise RuntimeError(
481 '''Your glut implementation does not allow interactive sessions. '''
482 '''Consider installing freeglut.''')
483
484 glut.glutHideWindow() # This is an event to be processed below
485 glutMainLoopEvent()
486 #glut.glutTimerFunc( sys.maxint-1, timer_none, 0)
448 self.clear_inputhook()
487 self.clear_inputhook()
488 #signal.signal(signal.SIGINT, signal.default_int_handler)
489
490 def enable_pyglet(self, app=None):
491 """Enable event loop integration with pyglet.
492
493 Parameters
494 ----------
495 app : ignored
496 Ignored, it's only a placeholder to keep the call signature of all
497 gui activation methods consistent, which simplifies the logic of
498 supporting magics.
449
499
500 Notes
501 -----
502 This methods sets the ``PyOS_InputHook`` for pyglet, which allows
503 pyglet to integrate with terminal based applications like
504 IPython.
505
506 """
507 import pyglet
508 from IPython.lib.inputhookpyglet import inputhook_pyglet
509 self.set_inputhook(inputhook_pyglet)
510 self._current_gui = GUI_PYGLET
511 return app
512
513 def disable_pyglet(self):
514 """Disable event loop integration with pyglet.
515
516 This merely sets PyOS_InputHook to NULL.
517 """
518 self.clear_inputhook()
450
519
451 def current_gui(self):
520 def current_gui(self):
452 """Return a string indicating the currently active GUI or None."""
521 """Return a string indicating the currently active GUI or None."""
@@ -462,13 +531,10 b' enable_gtk = inputhook_manager.enable_gtk'
462 disable_gtk = inputhook_manager.disable_gtk
531 disable_gtk = inputhook_manager.disable_gtk
463 enable_tk = inputhook_manager.enable_tk
532 enable_tk = inputhook_manager.enable_tk
464 disable_tk = inputhook_manager.disable_tk
533 disable_tk = inputhook_manager.disable_tk
465 <<<<<<< HEAD
466 enable_pyglet = inputhook_manager.enable_pyglet
467 disable_pyglet = inputhook_manager.disable_pyglet
468 =======
469 enable_glut = inputhook_manager.enable_glut
534 enable_glut = inputhook_manager.enable_glut
470 disable_glut = inputhook_manager.disable_glut
535 disable_glut = inputhook_manager.disable_glut
471 >>>>>>> Added code for the GLUT interactive session
536 enable_pyglet = inputhook_manager.enable_pyglet
537 disable_pyglet = inputhook_manager.disable_pyglet
472 clear_inputhook = inputhook_manager.clear_inputhook
538 clear_inputhook = inputhook_manager.clear_inputhook
473 set_inputhook = inputhook_manager.set_inputhook
539 set_inputhook = inputhook_manager.set_inputhook
474 current_gui = inputhook_manager.current_gui
540 current_gui = inputhook_manager.current_gui
@@ -507,12 +573,9 b' def enable_gui(gui=None, app=None):'
507 GUI_WX: enable_wx,
573 GUI_WX: enable_wx,
508 GUI_QT: enable_qt4, # qt3 not supported
574 GUI_QT: enable_qt4, # qt3 not supported
509 GUI_QT4: enable_qt4,
575 GUI_QT4: enable_qt4,
510 <<<<<<< HEAD
576 GUI_GLUT: enable_glut,
511 GUI_PYGLET: enable_pyglet,
577 GUI_PYGLET: enable_pyglet,
512 }
578 }
513 =======
514 GUI_GLUT: enable_glut}
515 >>>>>>> Added code for the GLUT interactive session
516 try:
579 try:
517 gui_hook = guis[gui]
580 gui_hook = guis[gui]
518 except KeyError:
581 except KeyError:
General Comments 0
You need to be logged in to leave comments. Login now