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 */