sgl

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