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@7
|
66 "glut", 1,
|
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@7
|
180 win = win->next;
|
nuclear@7
|
181 }
|
nuclear@7
|
182
|
nuclear@7
|
183 glutDestroyWindow(id);
|
nuclear@7
|
184 }
|
nuclear@7
|
185
|
nuclear@7
|
186 static int set_active(int id)
|
nuclear@7
|
187 {
|
nuclear@7
|
188 glutSetWindow(id);
|
nuclear@7
|
189 return 0;
|
nuclear@7
|
190 }
|
nuclear@7
|
191
|
nuclear@7
|
192 static int set_title(const char *str)
|
nuclear@7
|
193 {
|
nuclear@7
|
194 glutSetWindowTitle(str);
|
nuclear@7
|
195 glutSetIconTitle(str);
|
nuclear@7
|
196 return 0;
|
nuclear@7
|
197 }
|
nuclear@7
|
198
|
nuclear@7
|
199 static void redisplay(void)
|
nuclear@7
|
200 {
|
nuclear@7
|
201 glutPostRedisplay();
|
nuclear@7
|
202 }
|
nuclear@7
|
203
|
nuclear@7
|
204 static void swap_buffers(void)
|
nuclear@7
|
205 {
|
nuclear@7
|
206 glutSwapBuffers();
|
nuclear@7
|
207 }
|
nuclear@7
|
208
|
nuclear@7
|
209 static int get_modifiers(void)
|
nuclear@7
|
210 {
|
nuclear@7
|
211 return glutGetModifiers();
|
nuclear@7
|
212 }
|
nuclear@7
|
213
|
nuclear@7
|
214 static void set_event(int idx, int enable)
|
nuclear@7
|
215 {
|
nuclear@7
|
216 switch(idx) {
|
nuclear@7
|
217 case SGL_DISPLAY:
|
nuclear@7
|
218 glutDisplayFunc(enable ? disp_cb : 0);
|
nuclear@7
|
219 break;
|
nuclear@7
|
220 case SGL_RESHAPE:
|
nuclear@7
|
221 glutReshapeFunc(enable ? reshape_cb : 0);
|
nuclear@7
|
222 break;
|
nuclear@7
|
223 case SGL_KEYBOARD:
|
nuclear@7
|
224 glutKeyboardFunc(enable ? keyb_down_cb : 0);
|
nuclear@7
|
225 glutKeyboardUpFunc(enable ? keyb_up_cb : 0);
|
nuclear@7
|
226 glutSpecialFunc(enable ? special_down_cb : 0);
|
nuclear@7
|
227 glutSpecialUpFunc(enable ? special_up_cb : 0);
|
nuclear@7
|
228 break;
|
nuclear@7
|
229 case SGL_MOUSE:
|
nuclear@7
|
230 glutMouseFunc(enable ? mouse_cb : 0);
|
nuclear@7
|
231 break;
|
nuclear@7
|
232 case SGL_MOTION:
|
nuclear@7
|
233 glutMotionFunc(enable ? motion_cb : 0);
|
nuclear@7
|
234 break;
|
nuclear@7
|
235 case SGL_PASSIVE:
|
nuclear@7
|
236 glutPassiveMotionFunc(enable ? passive_cb : 0);
|
nuclear@7
|
237 break;
|
nuclear@7
|
238 case SGL_IDLE:
|
nuclear@7
|
239 glutIdleFunc(enable ? idle_cb : 0);
|
nuclear@7
|
240 break;
|
nuclear@7
|
241 default:
|
nuclear@7
|
242 break;
|
nuclear@7
|
243 }
|
nuclear@7
|
244 }
|
nuclear@7
|
245
|
nuclear@7
|
246 static int process_events(void)
|
nuclear@7
|
247 {
|
nuclear@7
|
248 #ifdef FREEGLUT
|
nuclear@7
|
249 glutMainLoopEvent();
|
nuclear@7
|
250 #else
|
nuclear@7
|
251 if(setjmp(jbuf) == 0) {
|
nuclear@7
|
252 glutMainLoop();
|
nuclear@7
|
253 }
|
nuclear@7
|
254 /* ok ... what happens is any callback that kicks in will set the idle func
|
nuclear@7
|
255 * if it's not set, and then the idle func will longjmp right back here...
|
nuclear@7
|
256 */
|
nuclear@7
|
257 #endif
|
nuclear@7
|
258 return 0;
|
nuclear@7
|
259 }
|
nuclear@7
|
260
|
nuclear@7
|
261 static void disp_cb(void)
|
nuclear@7
|
262 {
|
nuclear@7
|
263 sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY);
|
nuclear@7
|
264 func();
|
nuclear@7
|
265
|
nuclear@7
|
266 #ifndef FREEGLUT
|
nuclear@7
|
267 glutIdleFunc(idle_cb);
|
nuclear@7
|
268 #endif
|
nuclear@7
|
269 }
|
nuclear@7
|
270
|
nuclear@7
|
271 static void reshape_cb(int x, int y)
|
nuclear@7
|
272 {
|
nuclear@7
|
273 sgl_reshape_callback_t func = sgl_get_callback(SGL_RESHAPE);
|
nuclear@7
|
274 func(x, y);
|
nuclear@7
|
275
|
nuclear@7
|
276 #ifndef FREEGLUT
|
nuclear@7
|
277 glutIdleFunc(idle_cb);
|
nuclear@7
|
278 #endif
|
nuclear@7
|
279 }
|
nuclear@7
|
280
|
nuclear@7
|
281 static void keyb_down_cb(unsigned char c, int x, int y)
|
nuclear@7
|
282 {
|
nuclear@7
|
283 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
284 func((int)c, 1);
|
nuclear@7
|
285
|
nuclear@7
|
286 #ifndef FREEGLUT
|
nuclear@7
|
287 glutIdleFunc(idle_cb);
|
nuclear@7
|
288 #endif
|
nuclear@7
|
289 }
|
nuclear@7
|
290
|
nuclear@7
|
291 static void keyb_up_cb(unsigned char c, int x, int y)
|
nuclear@7
|
292 {
|
nuclear@7
|
293 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
294 func((int)c, 0);
|
nuclear@7
|
295
|
nuclear@7
|
296 #ifndef FREEGLUT
|
nuclear@7
|
297 glutIdleFunc(idle_cb);
|
nuclear@7
|
298 #endif
|
nuclear@7
|
299 }
|
nuclear@7
|
300
|
nuclear@7
|
301 static void special_down_cb(int c, int x, int y)
|
nuclear@7
|
302 {
|
nuclear@7
|
303 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
304 func(c, 1);
|
nuclear@7
|
305
|
nuclear@7
|
306 #ifndef FREEGLUT
|
nuclear@7
|
307 glutIdleFunc(idle_cb);
|
nuclear@7
|
308 #endif
|
nuclear@7
|
309 }
|
nuclear@7
|
310
|
nuclear@7
|
311 static void special_up_cb(int c, int x, int y)
|
nuclear@7
|
312 {
|
nuclear@7
|
313 sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
|
nuclear@7
|
314 func(c, 0);
|
nuclear@7
|
315
|
nuclear@7
|
316 #ifndef FREEGLUT
|
nuclear@7
|
317 glutIdleFunc(idle_cb);
|
nuclear@7
|
318 #endif
|
nuclear@7
|
319 }
|
nuclear@7
|
320
|
nuclear@7
|
321 static void mouse_cb(int bn, int state, int x, int y)
|
nuclear@7
|
322 {
|
nuclear@7
|
323 sgl_mouse_callback_t func = sgl_get_callback(SGL_MOUSE);
|
nuclear@7
|
324 func(0, bn, state, x, y);
|
nuclear@7
|
325
|
nuclear@7
|
326 #ifndef FREEGLUT
|
nuclear@7
|
327 glutIdleFunc(idle_cb);
|
nuclear@7
|
328 #endif
|
nuclear@7
|
329 }
|
nuclear@7
|
330
|
nuclear@7
|
331 static void motion_cb(int x, int y)
|
nuclear@7
|
332 {
|
nuclear@7
|
333 sgl_motion_callback_t func = sgl_get_callback(SGL_MOTION);
|
nuclear@7
|
334 func(0, x, y);
|
nuclear@7
|
335
|
nuclear@7
|
336 #ifndef FREEGLUT
|
nuclear@7
|
337 glutIdleFunc(idle_cb);
|
nuclear@7
|
338 #endif
|
nuclear@7
|
339 }
|
nuclear@7
|
340
|
nuclear@7
|
341 static void passive_cb(int x, int y)
|
nuclear@7
|
342 {
|
nuclear@7
|
343 sgl_passive_callback_t func = sgl_get_callback(SGL_PASSIVE);
|
nuclear@7
|
344 func(0, x, y);
|
nuclear@7
|
345
|
nuclear@7
|
346 #ifndef FREEGLUT
|
nuclear@7
|
347 glutIdleFunc(idle_cb);
|
nuclear@7
|
348 #endif
|
nuclear@7
|
349 }
|
nuclear@7
|
350
|
nuclear@7
|
351 static void idle_cb(void)
|
nuclear@7
|
352 {
|
nuclear@7
|
353 sgl_idle_callback_t func = sgl_get_callback(SGL_IDLE);
|
nuclear@7
|
354 if(func) {
|
nuclear@7
|
355 func();
|
nuclear@7
|
356 #ifndef FREEGLUT
|
nuclear@7
|
357 } else {
|
nuclear@7
|
358 /* this was just the longjmp trick so restore the lack of idle func */
|
nuclear@7
|
359 glutIdleFunc(0);
|
nuclear@7
|
360 #endif
|
nuclear@7
|
361 }
|
nuclear@7
|
362
|
nuclear@7
|
363 #ifndef FREEGLUT
|
nuclear@7
|
364 longjmp(jbuf, 0);
|
nuclear@7
|
365 #endif
|
nuclear@7
|
366 }
|
nuclear@7
|
367
|
nuclear@8
|
368 #else
|
nuclear@8
|
369 int sgl_wsys_glut_silence_the_fucking_empty_file_warnings;
|
nuclear@7
|
370 #endif /* USE_WSYS_MODULE_GLUT */
|