sgl

view src/wsys_glut.c @ 12:bf34fa677960

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