##// END OF EJS Templates
Merge pull request #12384 from cool-RR/2020-06-10-glut...
Matthias Bussonnier -
r25832:695e1531 merge
parent child Browse files
Show More
@@ -1,172 +1,172 b''
1 1 # coding: utf-8
2 2 """
3 3 GLUT Inputhook support functions
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 # GLUT is quite an old library and it is difficult to ensure proper
14 14 # integration within IPython since original GLUT does not allow to handle
15 15 # events one by one. Instead, it requires for the mainloop to be entered
16 16 # and never returned (there is not even a function to exit he
17 17 # mainloop). Fortunately, there are alternatives such as freeglut
18 18 # (available for linux and windows) and the OSX implementation gives
19 19 # access to a glutCheckLoop() function that blocks itself until a new
20 20 # event is received. This means we have to setup the idle callback to
21 21 # ensure we got at least one event that will unblock the function.
22 22 #
23 23 # Furthermore, it is not possible to install these handlers without a window
24 24 # being first created. We choose to make this window invisible. This means that
25 25 # display mode options are set at this level and user won't be able to change
26 26 # them later without modifying the code. This should probably be made available
27 27 # via IPython options system.
28 28
29 29 #-----------------------------------------------------------------------------
30 30 # Imports
31 31 #-----------------------------------------------------------------------------
32 32 import os
33 33 import sys
34 34 import time
35 35 import signal
36 36 import OpenGL.GLUT as glut
37 37 import OpenGL.platform as platform
38 38 from timeit import default_timer as clock
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Constants
42 42 #-----------------------------------------------------------------------------
43 43
44 44 # Frame per second : 60
45 45 # Should probably be an IPython option
46 46 glut_fps = 60
47 47
48 48
49 49 # Display mode : double buffeed + rgba + depth
50 50 # Should probably be an IPython option
51 51 glut_display_mode = (glut.GLUT_DOUBLE |
52 52 glut.GLUT_RGBA |
53 53 glut.GLUT_DEPTH)
54 54
55 55 glutMainLoopEvent = None
56 56 if sys.platform == 'darwin':
57 57 try:
58 58 glutCheckLoop = platform.createBaseFunction(
59 59 'glutCheckLoop', dll=platform.GLUT, resultType=None,
60 60 argTypes=[],
61 61 doc='glutCheckLoop( ) -> None',
62 62 argNames=(),
63 63 )
64 64 except AttributeError:
65 65 raise RuntimeError(
66 '''Your glut implementation does not allow interactive sessions'''
66 '''Your glut implementation does not allow interactive sessions. '''
67 67 '''Consider installing freeglut.''')
68 68 glutMainLoopEvent = glutCheckLoop
69 69 elif glut.HAVE_FREEGLUT:
70 70 glutMainLoopEvent = glut.glutMainLoopEvent
71 71 else:
72 72 raise RuntimeError(
73 73 '''Your glut implementation does not allow interactive sessions. '''
74 74 '''Consider installing freeglut.''')
75 75
76 76
77 77 #-----------------------------------------------------------------------------
78 78 # Platform-dependent imports and functions
79 79 #-----------------------------------------------------------------------------
80 80
81 81 if os.name == 'posix':
82 82 import select
83 83
84 84 def stdin_ready():
85 85 infds, outfds, erfds = select.select([sys.stdin],[],[],0)
86 86 if infds:
87 87 return True
88 88 else:
89 89 return False
90 90
91 91 elif sys.platform == 'win32':
92 92 import msvcrt
93 93
94 94 def stdin_ready():
95 95 return msvcrt.kbhit()
96 96
97 97 #-----------------------------------------------------------------------------
98 98 # Callback functions
99 99 #-----------------------------------------------------------------------------
100 100
101 101 def glut_display():
102 102 # Dummy display function
103 103 pass
104 104
105 105 def glut_idle():
106 106 # Dummy idle function
107 107 pass
108 108
109 109 def glut_close():
110 110 # Close function only hides the current window
111 111 glut.glutHideWindow()
112 112 glutMainLoopEvent()
113 113
114 114 def glut_int_handler(signum, frame):
115 115 # Catch sigint and print the default message
116 116 signal.signal(signal.SIGINT, signal.default_int_handler)
117 117 print('\nKeyboardInterrupt')
118 118 # Need to reprint the prompt at this stage
119 119
120 120
121 121
122 122 #-----------------------------------------------------------------------------
123 123 # Code
124 124 #-----------------------------------------------------------------------------
125 125 def inputhook_glut():
126 126 """Run the pyglet event loop by processing pending events only.
127 127
128 128 This keeps processing pending events until stdin is ready. After
129 129 processing all pending events, a call to time.sleep is inserted. This is
130 130 needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
131 131 though for best performance.
132 132 """
133 133 # We need to protect against a user pressing Control-C when IPython is
134 134 # idle and this is running. We trap KeyboardInterrupt and pass.
135 135
136 136 signal.signal(signal.SIGINT, glut_int_handler)
137 137
138 138 try:
139 139 t = clock()
140 140
141 141 # Make sure the default window is set after a window has been closed
142 142 if glut.glutGetWindow() == 0:
143 143 glut.glutSetWindow( 1 )
144 144 glutMainLoopEvent()
145 145 return 0
146 146
147 147 while not stdin_ready():
148 148 glutMainLoopEvent()
149 149 # We need to sleep at this point to keep the idle CPU load
150 150 # low. However, if sleep to long, GUI response is poor. As
151 151 # a compromise, we watch how often GUI events are being processed
152 152 # and switch between a short and long sleep time. Here are some
153 153 # stats useful in helping to tune this.
154 154 # time CPU load
155 155 # 0.001 13%
156 156 # 0.005 3%
157 157 # 0.01 1.5%
158 158 # 0.05 0.5%
159 159 used_time = clock() - t
160 160 if used_time > 10.0:
161 161 # print 'Sleep for 1 s' # dbg
162 162 time.sleep(1.0)
163 163 elif used_time > 0.1:
164 164 # Few GUI events coming in, so we can sleep longer
165 165 # print 'Sleep for 0.05 s' # dbg
166 166 time.sleep(0.05)
167 167 else:
168 168 # Many GUI events coming in, so sleep only very little
169 169 time.sleep(0.001)
170 170 except KeyboardInterrupt:
171 171 pass
172 172 return 0
@@ -1,140 +1,140 b''
1 1 """GLUT Input hook for interactive use with prompt_toolkit
2 2 """
3 3
4 4
5 5 # GLUT is quite an old library and it is difficult to ensure proper
6 6 # integration within IPython since original GLUT does not allow to handle
7 7 # events one by one. Instead, it requires for the mainloop to be entered
8 8 # and never returned (there is not even a function to exit he
9 9 # mainloop). Fortunately, there are alternatives such as freeglut
10 10 # (available for linux and windows) and the OSX implementation gives
11 11 # access to a glutCheckLoop() function that blocks itself until a new
12 12 # event is received. This means we have to setup the idle callback to
13 13 # ensure we got at least one event that will unblock the function.
14 14 #
15 15 # Furthermore, it is not possible to install these handlers without a window
16 16 # being first created. We choose to make this window invisible. This means that
17 17 # display mode options are set at this level and user won't be able to change
18 18 # them later without modifying the code. This should probably be made available
19 19 # via IPython options system.
20 20
21 21 import sys
22 22 import time
23 23 import signal
24 24 import OpenGL.GLUT as glut
25 25 import OpenGL.platform as platform
26 26 from timeit import default_timer as clock
27 27
28 28 # Frame per second : 60
29 29 # Should probably be an IPython option
30 30 glut_fps = 60
31 31
32 32 # Display mode : double buffeed + rgba + depth
33 33 # Should probably be an IPython option
34 34 glut_display_mode = (glut.GLUT_DOUBLE |
35 35 glut.GLUT_RGBA |
36 36 glut.GLUT_DEPTH)
37 37
38 38 glutMainLoopEvent = None
39 39 if sys.platform == 'darwin':
40 40 try:
41 41 glutCheckLoop = platform.createBaseFunction(
42 42 'glutCheckLoop', dll=platform.GLUT, resultType=None,
43 43 argTypes=[],
44 44 doc='glutCheckLoop( ) -> None',
45 45 argNames=(),
46 46 )
47 47 except AttributeError:
48 48 raise RuntimeError(
49 '''Your glut implementation does not allow interactive sessions'''
49 '''Your glut implementation does not allow interactive sessions. '''
50 50 '''Consider installing freeglut.''')
51 51 glutMainLoopEvent = glutCheckLoop
52 52 elif glut.HAVE_FREEGLUT:
53 53 glutMainLoopEvent = glut.glutMainLoopEvent
54 54 else:
55 55 raise RuntimeError(
56 56 '''Your glut implementation does not allow interactive sessions. '''
57 57 '''Consider installing freeglut.''')
58 58
59 59
60 60 def glut_display():
61 61 # Dummy display function
62 62 pass
63 63
64 64 def glut_idle():
65 65 # Dummy idle function
66 66 pass
67 67
68 68 def glut_close():
69 69 # Close function only hides the current window
70 70 glut.glutHideWindow()
71 71 glutMainLoopEvent()
72 72
73 73 def glut_int_handler(signum, frame):
74 74 # Catch sigint and print the defaultipyt message
75 75 signal.signal(signal.SIGINT, signal.default_int_handler)
76 76 print('\nKeyboardInterrupt')
77 77 # Need to reprint the prompt at this stage
78 78
79 79 # Initialisation code
80 80 glut.glutInit( sys.argv )
81 81 glut.glutInitDisplayMode( glut_display_mode )
82 82 # This is specific to freeglut
83 83 if bool(glut.glutSetOption):
84 84 glut.glutSetOption( glut.GLUT_ACTION_ON_WINDOW_CLOSE,
85 85 glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS )
86 86 glut.glutCreateWindow( b'ipython' )
87 87 glut.glutReshapeWindow( 1, 1 )
88 88 glut.glutHideWindow( )
89 89 glut.glutWMCloseFunc( glut_close )
90 90 glut.glutDisplayFunc( glut_display )
91 91 glut.glutIdleFunc( glut_idle )
92 92
93 93
94 94 def inputhook(context):
95 95 """Run the pyglet event loop by processing pending events only.
96 96
97 97 This keeps processing pending events until stdin is ready. After
98 98 processing all pending events, a call to time.sleep is inserted. This is
99 99 needed, otherwise, CPU usage is at 100%. This sleep time should be tuned
100 100 though for best performance.
101 101 """
102 102 # We need to protect against a user pressing Control-C when IPython is
103 103 # idle and this is running. We trap KeyboardInterrupt and pass.
104 104
105 105 signal.signal(signal.SIGINT, glut_int_handler)
106 106
107 107 try:
108 108 t = clock()
109 109
110 110 # Make sure the default window is set after a window has been closed
111 111 if glut.glutGetWindow() == 0:
112 112 glut.glutSetWindow( 1 )
113 113 glutMainLoopEvent()
114 114 return 0
115 115
116 116 while not context.input_is_ready():
117 117 glutMainLoopEvent()
118 118 # We need to sleep at this point to keep the idle CPU load
119 119 # low. However, if sleep to long, GUI response is poor. As
120 120 # a compromise, we watch how often GUI events are being processed
121 121 # and switch between a short and long sleep time. Here are some
122 122 # stats useful in helping to tune this.
123 123 # time CPU load
124 124 # 0.001 13%
125 125 # 0.005 3%
126 126 # 0.01 1.5%
127 127 # 0.05 0.5%
128 128 used_time = clock() - t
129 129 if used_time > 10.0:
130 130 # print 'Sleep for 1 s' # dbg
131 131 time.sleep(1.0)
132 132 elif used_time > 0.1:
133 133 # Few GUI events coming in, so we can sleep longer
134 134 # print 'Sleep for 0.05 s' # dbg
135 135 time.sleep(0.05)
136 136 else:
137 137 # Many GUI events coming in, so sleep only very little
138 138 time.sleep(0.001)
139 139 except KeyboardInterrupt:
140 140 pass
General Comments 0
You need to be logged in to leave comments. Login now