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