sgl

annotate src/wsys_glut.c @ 13:e989ab58ec5b

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