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