rev |
line source |
nuclear@7
|
1 /* SimplyGL window system module for GLUT */
|
nuclear@7
|
2 /* link-with: -lglut */
|
nuclear@10
|
3 /* mac-framework: -framework GLUT */
|
nuclear@7
|
4
|
nuclear@7
|
5 #include "config.h"
|
nuclear@7
|
6
|
nuclear@7
|
7 #ifdef USE_WSYS_MODULE_GLUT
|
nuclear@7
|
8
|
nuclear@7
|
9 #include <setjmp.h>
|
nuclear@7
|
10 #ifndef __APPLE__
|
nuclear@7
|
11 #include <GL/glut.h>
|
nuclear@7
|
12 #ifdef FREEGLUT
|
nuclear@7
|
13 #include <GL/freeglut_ext.h>
|
nuclear@7
|
14 #endif /* freeglut */
|
nuclear@7
|
15
|
nuclear@7
|
16 #else /* apple */
|
nuclear@7
|
17 #include <GLUT/glut.h>
|
nuclear@7
|
18 #endif
|
nuclear@7
|
19
|
nuclear@7
|
20 #include "sgl.h"
|
nuclear@7
|
21 #include "wsys.h"
|
nuclear@7
|
22
|
nuclear@7
|
23 struct window {
|
nuclear@7
|
24 int id;
|
nuclear@7
|
25 struct window *next;
|
nuclear@7
|
26 };
|
nuclear@7
|
27
|
nuclear@7
|
28 static int init(void);
|
nuclear@7
|
29 static void shutdown(void);
|
nuclear@7
|
30
|
nuclear@7
|
31 /* video mode switching */
|
nuclear@7
|
32 static int set_vidmode(int xsz, int ysz);
|
nuclear@7
|
33 static int get_vidmode(int *xsz, int *ysz);
|
nuclear@7
|
34
|
nuclear@7
|
35 /* create/destroy windows */
|
nuclear@7
|
36 static int create_window(int xsz, int ysz, unsigned int flags);
|
nuclear@7
|
37 static void close_window(int id);
|
nuclear@7
|
38
|
nuclear@7
|
39 /* window management */
|
nuclear@7
|
40 static int set_active(int id);
|
nuclear@7
|
41 static int set_title(const char *str);
|
nuclear@7
|
42 static void redisplay(void);
|
nuclear@7
|
43 static void swap_buffers(void);
|
nuclear@7
|
44
|
nuclear@7
|
45 static int get_modifiers(void);
|
nuclear@7
|
46
|
nuclear@7
|
47 /* event handling and friends */
|
nuclear@7
|
48 static void set_event(int idx, int enable);
|
nuclear@7
|
49 static int process_events(void);
|
nuclear@7
|
50
|
nuclear@7
|
51 /* callbacks */
|
nuclear@7
|
52 static void disp_cb(void);
|
nuclear@7
|
53 static void reshape_cb(int x, int y);
|
nuclear@7
|
54 static void keyb_down_cb(unsigned char c, int x, int y);
|
nuclear@7
|
55 static void keyb_up_cb(unsigned char c, int x, int y);
|
nuclear@7
|
56 static void special_down_cb(int c, int x, int y);
|
nuclear@7
|
57 static void special_up_cb(int c, int x, int y);
|
nuclear@7
|
58 static void mouse_cb(int bn, int state, int x, int y);
|
nuclear@7
|
59 static void motion_cb(int x, int y);
|
nuclear@7
|
60 static void passive_cb(int x, int y);
|
nuclear@7
|
61 static void idle_cb(void);
|
nuclear@7
|
62
|
nuclear@7
|
63
|
nuclear@7
|
64 static struct wsys_module ws = {
|
nuclear@7
|
65 "glut", 1,
|
nuclear@7
|
66 init,
|
nuclear@7
|
67 shutdown,
|
nuclear@7
|
68 set_vidmode,
|
nuclear@7
|
69 get_vidmode,
|
nuclear@7
|
70 create_window,
|
nuclear@7
|
71 close_window,
|
nuclear@7
|
72 set_active,
|
nuclear@7
|
73 set_title,
|
nuclear@7
|
74 redisplay,
|
nuclear@7
|
75 swap_buffers,
|
nuclear@7
|
76 get_modifiers,
|
nuclear@7
|
77 set_event,
|
nuclear@7
|
78 process_events,
|
nuclear@7
|
79 0
|
nuclear@7
|
80 };
|
nuclear@7
|
81
|
nuclear@7
|
82 #ifndef FREEGLUT
|
nuclear@7
|
83 static jmp_buf jbuf;
|
nuclear@7
|
84 #endif
|
nuclear@7
|
85
|
nuclear@7
|
86 static struct window *winlist;
|
nuclear@7
|
87
|
nuclear@7
|
88
|
nuclear@7
|
89 /* this is the only exported function, everything else should be static */
|
nuclear@7
|
90 void sgl_register_glut(void)
|
nuclear@7
|
91 {
|
nuclear@7
|
92 sgl_register_module(&ws);
|
nuclear@7
|
93 }
|
nuclear@7
|
94
|
nuclear@7
|
95 static int init(void)
|
nuclear@7
|
96 {
|
nuclear@7
|
97 char *argv[] = { "simplygl", 0 };
|
nuclear@7
|
98 int argc = 1;
|
nuclear@7
|
99
|
nuclear@7
|
100 glutInit(&argc, argv);
|
nuclear@7
|
101 return 0;
|
nuclear@7
|
102 }
|
nuclear@7
|
103
|
nuclear@7
|
104 static void shutdown(void)
|
nuclear@7
|
105 {
|
nuclear@7
|
106 struct window *win = winlist;
|
nuclear@7
|
107
|
nuclear@7
|
108 while(win) {
|
nuclear@7
|
109 int id = win->id;
|
nuclear@7
|
110 win = win->next;
|
nuclear@7
|
111
|
nuclear@7
|
112 close_window(id);
|
nuclear@7
|
113 }
|
nuclear@7
|
114 winlist = 0;
|
nuclear@7
|
115 }
|
nuclear@7
|
116
|
nuclear@7
|
117 static int set_vidmode(int xsz, int ysz)
|
nuclear@7
|
118 {
|
nuclear@7
|
119 /* TODO */
|
nuclear@7
|
120 return 0;
|
nuclear@7
|
121 }
|
nuclear@7
|
122
|
nuclear@7
|
123 static int get_vidmode(int *xsz, int *ysz)
|
nuclear@7
|
124 {
|
nuclear@7
|
125 /* TODO */
|
nuclear@7
|
126 return 0;
|
nuclear@7
|
127 }
|
nuclear@7
|
128
|
nuclear@7
|
129 static int create_window(int xsz, int ysz, unsigned int flags)
|
nuclear@7
|
130 {
|
nuclear@7
|
131 struct window *win;
|
nuclear@7
|
132 unsigned int glut_flags = GLUT_RGBA;
|
nuclear@7
|
133
|
nuclear@7
|
134 if(flags & SGL_DOUBLE) {
|
nuclear@7
|
135 glut_flags |= GLUT_DOUBLE;
|
nuclear@7
|
136 }
|
nuclear@7
|
137 if(flags & SGL_DEPTH) {
|
nuclear@7
|
138 glut_flags |= GLUT_DEPTH;
|
nuclear@7
|
139 }
|
nuclear@7
|
140 if(flags & SGL_STENCIL) {
|
nuclear@7
|
141 glut_flags |= GLUT_STENCIL;
|
nuclear@7
|
142 }
|
nuclear@7
|
143 if(flags & SGL_STEREO) {
|
nuclear@7
|
144 glut_flags |= GLUT_STEREO;
|
nuclear@7
|
145 }
|
nuclear@7
|
146 if(flags & SGL_MULTISAMPLE) {
|
nuclear@7
|
147 glut_flags |= GLUT_MULTISAMPLE;
|
nuclear@7
|
148 }
|
nuclear@7
|
149
|
nuclear@7
|
150 if(!(win = malloc(sizeof *win))) {
|
nuclear@7
|
151 return -1;
|
nuclear@7
|
152 }
|
nuclear@7
|
153
|
nuclear@7
|
154 glutInitDisplayMode(glut_flags);
|
nuclear@7
|
155 glutInitWindowSize(xsz, ysz);
|
nuclear@7
|
156 if((win->id = glutCreateWindow("OpenGL/GLUT")) <= 0) {
|
nuclear@7
|
157 free(win);
|
nuclear@7
|
158 return -1;
|
nuclear@7
|
159 }
|
nuclear@7
|
160
|
nuclear@7
|
161 win->next = winlist;
|
nuclear@7
|
162 winlist = win;
|
nuclear@7
|
163 return win->id;
|
nuclear@7
|
164 }
|
nuclear@7
|
165
|
nuclear@7
|
166 static void close_window(int id)
|
nuclear@7
|
167 {
|
nuclear@7
|
168 struct window dummy, *win, *prev;
|
nuclear@7
|
169
|
nuclear@7
|
170 dummy.next = win = winlist;
|
nuclear@7
|
171 prev = &dummy;
|
nuclear@7
|
172
|
nuclear@7
|
173 while(win) {
|
nuclear@7
|
174 if(win->id == id) {
|
nuclear@7
|
175 prev->next = win->next;
|
nuclear@7
|
176 free(win);
|
nuclear@7
|
177 break;
|
nuclear@7
|
178 }
|
nuclear@7
|
179 win = win->next;
|
nuclear@7
|
180 }
|
nuclear@7
|
181
|
nuclear@7
|
182 glutDestroyWindow(id);
|
nuclear@7
|
183 }
|
nuclear@7
|
184
|
nuclear@7
|
185 static int set_active(int id)
|
nuclear@7
|
186 {
|
nuclear@7
|
187 glutSetWindow(id);
|
nuclear@7
|
188 return 0;
|
nuclear@7
|
189 }
|
nuclear@7
|
190
|
nuclear@7
|
191 static int set_title(const char *str)
|
nuclear@7
|
192 {
|
nuclear@7
|
193 glutSetWindowTitle(str);
|
nuclear@7
|
194 glutSetIconTitle(str);
|
nuclear@7
|
195 return 0;
|
nuclear@7
|
196 }
|
nuclear@7
|
197
|
nuclear@7
|
198 static void redisplay(void)
|
nuclear@7
|
199 {
|
nuclear@7
|
200 glutPostRedisplay();
|
nuclear@7
|
201 }
|
nuclear@7
|
202
|
nuclear@7
|
203 static void swap_buffers(void)
|
nuclear@7
|
204 {
|
nuclear@7
|
205 glutSwapBuffers();
|
nuclear@7
|
206 }
|
nuclear@7
|
207
|
nuclear@7
|
208 static int get_modifiers(void)
|
nuclear@7
|
209 {
|
nuclear@7
|
210 return glutGetModifiers();
|
nuclear@7
|
211 }
|
nuclear@7
|
212
|
nuclear@7
|
213 static void set_event(int idx, int enable)
|
nuclear@7
|
214 {
|
nuclear@7
|
215 switch(idx) {
|
nuclear@7
|
216 case SGL_DISPLAY:
|
nuclear@7
|
217 glutDisplayFunc(enable ? disp_cb : 0);
|
nuclear@7
|
218 break;
|
nuclear@7
|
219 case SGL_RESHAPE:
|
nuclear@7
|
220 glutReshapeFunc(enable ? reshape_cb : 0);
|
nuclear@7
|
221 break;
|
nuclear@7
|
222 case SGL_KEYBOARD:
|
nuclear@7
|
223 glutKeyboardFunc(enable ? keyb_down_cb : 0);
|
nuclear@7
|
224 glutKeyboardUpFunc(enable ? keyb_up_cb : 0);
|
nuclear@7
|
225 glutSpecialFunc(enable ? special_down_cb : 0);
|
nuclear@7
|
226 glutSpecialUpFunc(enable ? special_up_cb : 0);
|
nuclear@7
|
227 break;
|
nuclear@7
|
228 case SGL_MOUSE:
|
nuclear@7
|
229 glutMouseFunc(enable ? mouse_cb : 0);
|
nuclear@7
|
230 break;
|
nuclear@7
|
231 case SGL_MOTION:
|
nuclear@7
|
232 glutMotionFunc(enable ? motion_cb : 0);
|
nuclear@7
|
233 break;
|
nuclear@7
|
234 case SGL_PASSIVE:
|
nuclear@7
|
235 glutPassiveMotionFunc(enable ? passive_cb : 0);
|
nuclear@7
|
236 break;
|
nuclear@7
|
237 case SGL_IDLE:
|
nuclear@7
|
238 glutIdleFunc(enable ? idle_cb : 0);
|
nuclear@7
|
239 break;
|
nuclear@7
|
240 default:
|
nuclear@7
|
241 break;
|
nuclear@7
|
242 }
|
nuclear@7
|
243 }
|
nuclear@7
|
244
|
nuclear@7
|
245 static int process_events(void)
|
nuclear@7
|
246 {
|
nuclear@7
|
247 #ifdef FREEGLUT
|
nuclear@7
|
248 glutMainLoopEvent();
|
nuclear@7
|
249 #else
|
nuclear@7
|
250 if(setjmp(jbuf) == 0) {
|
nuclear@7
|
251 glutMainLoop();
|
nuclear@7
|
252 }
|
nuclear@7
|
253 /* ok ... what happens is any callback that kicks in will set the idle func
|
nuclear@7
|
254 * if it's not set, and then the idle func will longjmp right back here...
|
nuclear@7
|
255 */
|
nuclear@7
|
256 #endif
|
nuclear@7
|
257 return 0;
|
nuclear@7
|
258 }
|
nuclear@7
|
259
|
nuclear@7
|
260 static void disp_cb(void)
|
nuclear@7
|
261 {
|
nuclear@7
|
262 sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY);
|
nuclear@7
|
263 func();
|
nuclear@7
|
264
|
nuclear@7
|
265 #ifndef FREEGLUT
|
nuclear@7
|
266 glutIdleFunc(idle_cb);
|
nuclear@7
|
267 #endif
|
nuclear@7
|
268 }
|
nuclear@7
|
269
|
nuclear@7
|
270 static void reshape_cb(int x, int y)
|
nuclear@7
|
271 {
|
nuclear@7
|
272 sgl_reshape_callback_t func = sgl_get_callback(SGL_RESHAPE);
|
nuclear@7
|
273 func(x, y);
|
nuclear@7
|
274
|
nuclear@7
|
275 #ifndef FREEGLUT
|
nuclear@7
|
276 glutIdleFunc(idle_cb);
|
nuclear@7
|
277 #endif
|
nuclear@7
|
278 }
|
nuclear@7
|
279
|
nuclear@7
|
280 static void keyb_down_cb(unsigned char c, int x, int y)
|
nuclear@7
|
281 {
|
nuclear@7
|
282 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
283 func((int)c, 1);
|
nuclear@7
|
284
|
nuclear@7
|
285 #ifndef FREEGLUT
|
nuclear@7
|
286 glutIdleFunc(idle_cb);
|
nuclear@7
|
287 #endif
|
nuclear@7
|
288 }
|
nuclear@7
|
289
|
nuclear@7
|
290 static void keyb_up_cb(unsigned char c, int x, int y)
|
nuclear@7
|
291 {
|
nuclear@7
|
292 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
293 func((int)c, 0);
|
nuclear@7
|
294
|
nuclear@7
|
295 #ifndef FREEGLUT
|
nuclear@7
|
296 glutIdleFunc(idle_cb);
|
nuclear@7
|
297 #endif
|
nuclear@7
|
298 }
|
nuclear@7
|
299
|
nuclear@7
|
300 static void special_down_cb(int c, int x, int y)
|
nuclear@7
|
301 {
|
nuclear@7
|
302 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
303 func(c, 1);
|
nuclear@7
|
304
|
nuclear@7
|
305 #ifndef FREEGLUT
|
nuclear@7
|
306 glutIdleFunc(idle_cb);
|
nuclear@7
|
307 #endif
|
nuclear@7
|
308 }
|
nuclear@7
|
309
|
nuclear@7
|
310 static void special_up_cb(int c, int x, int y)
|
nuclear@7
|
311 {
|
nuclear@7
|
312 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
313 func(c, 0);
|
nuclear@7
|
314
|
nuclear@7
|
315 #ifndef FREEGLUT
|
nuclear@7
|
316 glutIdleFunc(idle_cb);
|
nuclear@7
|
317 #endif
|
nuclear@7
|
318 }
|
nuclear@7
|
319
|
nuclear@7
|
320 static void mouse_cb(int bn, int state, int x, int y)
|
nuclear@7
|
321 {
|
nuclear@7
|
322 sgl_mouse_callback_t func = sgl_get_callback(SGL_MOUSE);
|
nuclear@7
|
323 func(0, bn, state, x, y);
|
nuclear@7
|
324
|
nuclear@7
|
325 #ifndef FREEGLUT
|
nuclear@7
|
326 glutIdleFunc(idle_cb);
|
nuclear@7
|
327 #endif
|
nuclear@7
|
328 }
|
nuclear@7
|
329
|
nuclear@7
|
330 static void motion_cb(int x, int y)
|
nuclear@7
|
331 {
|
nuclear@7
|
332 sgl_motion_callback_t func = sgl_get_callback(SGL_MOTION);
|
nuclear@7
|
333 func(0, x, y);
|
nuclear@7
|
334
|
nuclear@7
|
335 #ifndef FREEGLUT
|
nuclear@7
|
336 glutIdleFunc(idle_cb);
|
nuclear@7
|
337 #endif
|
nuclear@7
|
338 }
|
nuclear@7
|
339
|
nuclear@7
|
340 static void passive_cb(int x, int y)
|
nuclear@7
|
341 {
|
nuclear@7
|
342 sgl_passive_callback_t func = sgl_get_callback(SGL_PASSIVE);
|
nuclear@7
|
343 func(0, x, y);
|
nuclear@7
|
344
|
nuclear@7
|
345 #ifndef FREEGLUT
|
nuclear@7
|
346 glutIdleFunc(idle_cb);
|
nuclear@7
|
347 #endif
|
nuclear@7
|
348 }
|
nuclear@7
|
349
|
nuclear@7
|
350 static void idle_cb(void)
|
nuclear@7
|
351 {
|
nuclear@7
|
352 sgl_idle_callback_t func = sgl_get_callback(SGL_IDLE);
|
nuclear@7
|
353 if(func) {
|
nuclear@7
|
354 func();
|
nuclear@7
|
355 #ifndef FREEGLUT
|
nuclear@7
|
356 } else {
|
nuclear@7
|
357 /* this was just the longjmp trick so restore the lack of idle func */
|
nuclear@7
|
358 glutIdleFunc(0);
|
nuclear@7
|
359 #endif
|
nuclear@7
|
360 }
|
nuclear@7
|
361
|
nuclear@7
|
362 #ifndef FREEGLUT
|
nuclear@7
|
363 longjmp(jbuf, 0);
|
nuclear@7
|
364 #endif
|
nuclear@7
|
365 }
|
nuclear@7
|
366
|
nuclear@8
|
367 #else
|
nuclear@8
|
368 int sgl_wsys_glut_silence_the_fucking_empty_file_warnings;
|
nuclear@7
|
369 #endif /* USE_WSYS_MODULE_GLUT */
|