sgl
diff src/wsys_glut.c @ 7:edbfc96fe80d
glut wsys thingy and stuff...
author | John Tsiombikas <nuclear@siggraph.org> |
---|---|
date | Sat, 14 May 2011 08:26:10 +0300 |
parents | |
children | 0b07dd867b2f |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/wsys_glut.c Sat May 14 08:26:10 2011 +0300 1.3 @@ -0,0 +1,367 @@ 1.4 +/* SimplyGL window system module for GLUT */ 1.5 +/* link-with: -lglut */ 1.6 + 1.7 +#include "config.h" 1.8 + 1.9 +#ifdef USE_WSYS_MODULE_GLUT 1.10 + 1.11 +#include <setjmp.h> 1.12 +#ifndef __APPLE__ 1.13 +#include <GL/glut.h> 1.14 +#undef FREEGLUT 1.15 +#ifdef FREEGLUT 1.16 +#include <GL/freeglut_ext.h> 1.17 +#endif /* freeglut */ 1.18 + 1.19 +#else /* apple */ 1.20 +#include <GLUT/glut.h> 1.21 +#endif 1.22 + 1.23 +#include "sgl.h" 1.24 +#include "wsys.h" 1.25 + 1.26 +struct window { 1.27 + int id; 1.28 + struct window *next; 1.29 +}; 1.30 + 1.31 +static int init(void); 1.32 +static void shutdown(void); 1.33 + 1.34 +/* video mode switching */ 1.35 +static int set_vidmode(int xsz, int ysz); 1.36 +static int get_vidmode(int *xsz, int *ysz); 1.37 + 1.38 +/* create/destroy windows */ 1.39 +static int create_window(int xsz, int ysz, unsigned int flags); 1.40 +static void close_window(int id); 1.41 + 1.42 +/* window management */ 1.43 +static int set_active(int id); 1.44 +static int set_title(const char *str); 1.45 +static void redisplay(void); 1.46 +static void swap_buffers(void); 1.47 + 1.48 +static int get_modifiers(void); 1.49 + 1.50 +/* event handling and friends */ 1.51 +static void set_event(int idx, int enable); 1.52 +static int process_events(void); 1.53 + 1.54 +/* callbacks */ 1.55 +static void disp_cb(void); 1.56 +static void reshape_cb(int x, int y); 1.57 +static void keyb_down_cb(unsigned char c, int x, int y); 1.58 +static void keyb_up_cb(unsigned char c, int x, int y); 1.59 +static void special_down_cb(int c, int x, int y); 1.60 +static void special_up_cb(int c, int x, int y); 1.61 +static void mouse_cb(int bn, int state, int x, int y); 1.62 +static void motion_cb(int x, int y); 1.63 +static void passive_cb(int x, int y); 1.64 +static void idle_cb(void); 1.65 + 1.66 + 1.67 +static struct wsys_module ws = { 1.68 + "glut", 1, 1.69 + init, 1.70 + shutdown, 1.71 + set_vidmode, 1.72 + get_vidmode, 1.73 + create_window, 1.74 + close_window, 1.75 + set_active, 1.76 + set_title, 1.77 + redisplay, 1.78 + swap_buffers, 1.79 + get_modifiers, 1.80 + set_event, 1.81 + process_events, 1.82 + 0 1.83 +}; 1.84 + 1.85 +#ifndef FREEGLUT 1.86 +static jmp_buf jbuf; 1.87 +#endif 1.88 + 1.89 +static struct window *winlist; 1.90 + 1.91 + 1.92 +/* this is the only exported function, everything else should be static */ 1.93 +void sgl_register_glut(void) 1.94 +{ 1.95 + sgl_register_module(&ws); 1.96 +} 1.97 + 1.98 +static int init(void) 1.99 +{ 1.100 + char *argv[] = { "simplygl", 0 }; 1.101 + int argc = 1; 1.102 + 1.103 + glutInit(&argc, argv); 1.104 + return 0; 1.105 +} 1.106 + 1.107 +static void shutdown(void) 1.108 +{ 1.109 + struct window *win = winlist; 1.110 + 1.111 + while(win) { 1.112 + int id = win->id; 1.113 + win = win->next; 1.114 + 1.115 + close_window(id); 1.116 + } 1.117 + winlist = 0; 1.118 +} 1.119 + 1.120 +static int set_vidmode(int xsz, int ysz) 1.121 +{ 1.122 + /* TODO */ 1.123 + return 0; 1.124 +} 1.125 + 1.126 +static int get_vidmode(int *xsz, int *ysz) 1.127 +{ 1.128 + /* TODO */ 1.129 + return 0; 1.130 +} 1.131 + 1.132 +static int create_window(int xsz, int ysz, unsigned int flags) 1.133 +{ 1.134 + struct window *win; 1.135 + unsigned int glut_flags = GLUT_RGBA; 1.136 + 1.137 + if(flags & SGL_DOUBLE) { 1.138 + glut_flags |= GLUT_DOUBLE; 1.139 + } 1.140 + if(flags & SGL_DEPTH) { 1.141 + glut_flags |= GLUT_DEPTH; 1.142 + } 1.143 + if(flags & SGL_STENCIL) { 1.144 + glut_flags |= GLUT_STENCIL; 1.145 + } 1.146 + if(flags & SGL_STEREO) { 1.147 + glut_flags |= GLUT_STEREO; 1.148 + } 1.149 + if(flags & SGL_MULTISAMPLE) { 1.150 + glut_flags |= GLUT_MULTISAMPLE; 1.151 + } 1.152 + 1.153 + if(!(win = malloc(sizeof *win))) { 1.154 + return -1; 1.155 + } 1.156 + 1.157 + glutInitDisplayMode(glut_flags); 1.158 + glutInitWindowSize(xsz, ysz); 1.159 + if((win->id = glutCreateWindow("OpenGL/GLUT")) <= 0) { 1.160 + free(win); 1.161 + return -1; 1.162 + } 1.163 + 1.164 + win->next = winlist; 1.165 + winlist = win; 1.166 + return win->id; 1.167 +} 1.168 + 1.169 +static void close_window(int id) 1.170 +{ 1.171 + struct window dummy, *win, *prev; 1.172 + 1.173 + dummy.next = win = winlist; 1.174 + prev = &dummy; 1.175 + 1.176 + while(win) { 1.177 + if(win->id == id) { 1.178 + prev->next = win->next; 1.179 + free(win); 1.180 + break; 1.181 + } 1.182 + win = win->next; 1.183 + } 1.184 + 1.185 + glutDestroyWindow(id); 1.186 +} 1.187 + 1.188 +static int set_active(int id) 1.189 +{ 1.190 + glutSetWindow(id); 1.191 + return 0; 1.192 +} 1.193 + 1.194 +static int set_title(const char *str) 1.195 +{ 1.196 + glutSetWindowTitle(str); 1.197 + glutSetIconTitle(str); 1.198 + return 0; 1.199 +} 1.200 + 1.201 +static void redisplay(void) 1.202 +{ 1.203 + glutPostRedisplay(); 1.204 +} 1.205 + 1.206 +static void swap_buffers(void) 1.207 +{ 1.208 + glutSwapBuffers(); 1.209 +} 1.210 + 1.211 +static int get_modifiers(void) 1.212 +{ 1.213 + return glutGetModifiers(); 1.214 +} 1.215 + 1.216 +static void set_event(int idx, int enable) 1.217 +{ 1.218 + switch(idx) { 1.219 + case SGL_DISPLAY: 1.220 + glutDisplayFunc(enable ? disp_cb : 0); 1.221 + break; 1.222 + case SGL_RESHAPE: 1.223 + glutReshapeFunc(enable ? reshape_cb : 0); 1.224 + break; 1.225 + case SGL_KEYBOARD: 1.226 + glutKeyboardFunc(enable ? keyb_down_cb : 0); 1.227 + glutKeyboardUpFunc(enable ? keyb_up_cb : 0); 1.228 + glutSpecialFunc(enable ? special_down_cb : 0); 1.229 + glutSpecialUpFunc(enable ? special_up_cb : 0); 1.230 + break; 1.231 + case SGL_MOUSE: 1.232 + glutMouseFunc(enable ? mouse_cb : 0); 1.233 + break; 1.234 + case SGL_MOTION: 1.235 + glutMotionFunc(enable ? motion_cb : 0); 1.236 + break; 1.237 + case SGL_PASSIVE: 1.238 + glutPassiveMotionFunc(enable ? passive_cb : 0); 1.239 + break; 1.240 + case SGL_IDLE: 1.241 + glutIdleFunc(enable ? idle_cb : 0); 1.242 + break; 1.243 + default: 1.244 + break; 1.245 + } 1.246 +} 1.247 + 1.248 +static int process_events(void) 1.249 +{ 1.250 +#ifdef FREEGLUT 1.251 + glutMainLoopEvent(); 1.252 +#else 1.253 + if(setjmp(jbuf) == 0) { 1.254 + glutMainLoop(); 1.255 + } 1.256 + /* ok ... what happens is any callback that kicks in will set the idle func 1.257 + * if it's not set, and then the idle func will longjmp right back here... 1.258 + */ 1.259 +#endif 1.260 + return 0; 1.261 +} 1.262 + 1.263 +static void disp_cb(void) 1.264 +{ 1.265 + sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY); 1.266 + func(); 1.267 + 1.268 +#ifndef FREEGLUT 1.269 + glutIdleFunc(idle_cb); 1.270 +#endif 1.271 +} 1.272 + 1.273 +static void reshape_cb(int x, int y) 1.274 +{ 1.275 + sgl_reshape_callback_t func = sgl_get_callback(SGL_RESHAPE); 1.276 + func(x, y); 1.277 + 1.278 +#ifndef FREEGLUT 1.279 + glutIdleFunc(idle_cb); 1.280 +#endif 1.281 +} 1.282 + 1.283 +static void keyb_down_cb(unsigned char c, int x, int y) 1.284 +{ 1.285 + sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD); 1.286 + func((int)c, 1); 1.287 + 1.288 +#ifndef FREEGLUT 1.289 + glutIdleFunc(idle_cb); 1.290 +#endif 1.291 +} 1.292 + 1.293 +static void keyb_up_cb(unsigned char c, int x, int y) 1.294 +{ 1.295 + sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD); 1.296 + func((int)c, 0); 1.297 + 1.298 +#ifndef FREEGLUT 1.299 + glutIdleFunc(idle_cb); 1.300 +#endif 1.301 +} 1.302 + 1.303 +static void special_down_cb(int c, int x, int y) 1.304 +{ 1.305 + sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD); 1.306 + func(c, 1); 1.307 + 1.308 +#ifndef FREEGLUT 1.309 + glutIdleFunc(idle_cb); 1.310 +#endif 1.311 +} 1.312 + 1.313 +static void special_up_cb(int c, int x, int y) 1.314 +{ 1.315 + sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD); 1.316 + func(c, 0); 1.317 + 1.318 +#ifndef FREEGLUT 1.319 + glutIdleFunc(idle_cb); 1.320 +#endif 1.321 +} 1.322 + 1.323 +static void mouse_cb(int bn, int state, int x, int y) 1.324 +{ 1.325 + sgl_mouse_callback_t func = sgl_get_callback(SGL_MOUSE); 1.326 + func(0, bn, state, x, y); 1.327 + 1.328 +#ifndef FREEGLUT 1.329 + glutIdleFunc(idle_cb); 1.330 +#endif 1.331 +} 1.332 + 1.333 +static void motion_cb(int x, int y) 1.334 +{ 1.335 + sgl_motion_callback_t func = sgl_get_callback(SGL_MOTION); 1.336 + func(0, x, y); 1.337 + 1.338 +#ifndef FREEGLUT 1.339 + glutIdleFunc(idle_cb); 1.340 +#endif 1.341 +} 1.342 + 1.343 +static void passive_cb(int x, int y) 1.344 +{ 1.345 + sgl_passive_callback_t func = sgl_get_callback(SGL_PASSIVE); 1.346 + func(0, x, y); 1.347 + 1.348 +#ifndef FREEGLUT 1.349 + glutIdleFunc(idle_cb); 1.350 +#endif 1.351 +} 1.352 + 1.353 +static void idle_cb(void) 1.354 +{ 1.355 + sgl_idle_callback_t func = sgl_get_callback(SGL_IDLE); 1.356 + if(func) { 1.357 + func(); 1.358 +#ifndef FREEGLUT 1.359 + } else { 1.360 + /* this was just the longjmp trick so restore the lack of idle func */ 1.361 + glutIdleFunc(0); 1.362 +#endif 1.363 + } 1.364 + 1.365 +#ifndef FREEGLUT 1.366 + longjmp(jbuf, 0); 1.367 +#endif 1.368 +} 1.369 + 1.370 +#endif /* USE_WSYS_MODULE_GLUT */