sgl

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