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