sgl

view src/wsys_glut.c @ 10:1532e43bf858

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