sgl

changeset 7:edbfc96fe80d

glut wsys thingy and stuff...
author John Tsiombikas <nuclear@siggraph.org>
date Sat, 14 May 2011 08:26:10 +0300
parents 0cb438c86b98
children 0b07dd867b2f
files Makefile.in README configure include/sgl.h src/sgl.c src/wsys.c src/wsys.h src/wsys_glut.c src/wsys_x11.c
diffstat 9 files changed, 561 insertions(+), 23 deletions(-) [+]
line diff
     1.1 --- a/Makefile.in	Fri May 13 09:44:21 2011 +0300
     1.2 +++ b/Makefile.in	Sat May 14 08:26:10 2011 +0300
     1.3 @@ -23,7 +23,7 @@
     1.4  AR = ar
     1.5  CC = gcc
     1.6  CFLAGS = -pedantic -Wall -g -fPIC -Iinclude -Isrc
     1.7 -LDFLAGS = -lX11
     1.8 +LDFLAGS = $(wsys_libs)
     1.9  
    1.10  .PHONY: all
    1.11  all: $(lib_so) $(lib_a)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/README	Sat May 14 08:26:10 2011 +0300
     2.3 @@ -0,0 +1,14 @@
     2.4 +Author: John Tsiombikas
     2.5 +Contact: nuclear@member.fsf.org
     2.6 +
     2.7 +Adding window system modules
     2.8 +----------------------------
     2.9 +Window system modules are detected automatically by configure. For this to work,
    2.10 +each module must be a single file in src/ called wsys_whatever.c.
    2.11 +
    2.12 +Somewhere in the module, there must be a comment of the form: /* link-with:
    2.13 +whatever */ where the whatever part is passed to the linker, and is also used to
    2.14 +determine at compile time if the module should be enabled.
    2.15 +
    2.16 +Finally the module source code must start by including "config.h", and the rest
    2.17 +of it from that point on must be in a big ifdef USE_WSYS_MODULE_WHATEVER block.
     3.1 --- a/configure	Fri May 13 09:44:21 2011 +0300
     3.2 +++ b/configure	Sat May 14 08:26:10 2011 +0300
     3.3 @@ -1,27 +1,85 @@
     3.4  #!/bin/sh
     3.5  
     3.6 -gen_module_init()
     3.7 +cfgfile=src/config.h
     3.8 +modfile=src/modules.c
     3.9 +
    3.10 +get_depline()
    3.11  {
    3.12 -	# collect all src/wsys_whatever.c files
    3.13 -	modules=`ls src/wsys_*.c 2>/dev/null | sort | sed 's/src\/wsys_//' | sed 's/\.c//'`
    3.14 -
    3.15 -	echo "/* this file is generated by $0, do not edit */"
    3.16 -	for m in $modules; do
    3.17 -		echo "void sgl_register_$m();"
    3.18 -	done
    3.19 -
    3.20 -	echo
    3.21 -	echo 'void sgl_modules_init(void)'
    3.22 -	echo '{'
    3.23 -
    3.24 -	for m in $modules; do
    3.25 -		echo "	sgl_register_$m();"
    3.26 -	done
    3.27 -
    3.28 -	echo '}'
    3.29 +	grep 'link-with:' $1 | sed 's/^.*link-with: \?\(.*\) \?\*\//\1/'
    3.30  }
    3.31  
    3.32 -gen_module_init >src/modules.c
    3.33 +get_usedef()
    3.34 +{
    3.35 +	grep '#ifdef *USE_WSYS_MODULE' $1 | sed 's/^.*\(USE_WSYS_MODULE_.*\)/\1/'
    3.36 +}
    3.37  
    3.38 +try_link()
    3.39 +{
    3.40 +	srcfile=/tmp/sgl-trylink.c
    3.41 +	aout=/tmp/sgl-a.out
    3.42 +
    3.43 +	echo 'int main(void) { return 0; }' >$srcfile
    3.44 +	cc -o $aout $srcfile $1 >/dev/null 2>/dev/null
    3.45 +}
    3.46 +
    3.47 +# write beginning of config.h
    3.48 +echo '#ifndef CONFIG_H_' >$cfgfile
    3.49 +echo '#define CONFIG_H_' >>$cfgfile
    3.50 +echo >>$cfgfile
    3.51 +
    3.52 +# write beginning of modules.c
    3.53 +echo "/* this file is generated by $0, do not edit */" >$modfile
    3.54 +echo >>$modfile
    3.55 +echo 'void sgl_modules_init(void)' >>$modfile
    3.56 +echo '{' >>$modfile
    3.57 +
    3.58 +
    3.59 +# start scanning for modules
    3.60 +echo 'Looking for usable window system modules ...'
    3.61 +
    3.62 +# collect all src/wsys_whatever.c files
    3.63 +all_files=`ls src/wsys_*.c 2>/dev/null`
    3.64 +
    3.65 +for m in $all_files; do
    3.66 +	# extract USE_WSYS_MODULE_* define
    3.67 +	def=`get_usedef $m`
    3.68 +
    3.69 +	# extract link-with line
    3.70 +	dep=`get_depline $m`
    3.71 +	name=`echo $m | sort | sed 's/src\/wsys_//' | sed 's/\.c//'`
    3.72 +	echo -n "-> trying module $name (needs: $dep) ... "
    3.73 +
    3.74 +	if try_link $dep; then
    3.75 +		echo ok
    3.76 +
    3.77 +		libs="$libs $dep"
    3.78 +
    3.79 +		# emmit the USE_ define in config.h
    3.80 +		echo "#define $def" >>$cfgfile
    3.81 +		echo >>$cfgfile
    3.82 +
    3.83 +		# make the registration call in modules.c
    3.84 +		echo "	void sgl_register_$name();" >>$modfile
    3.85 +		echo "	sgl_register_$name();" >>$modfile
    3.86 +		echo >>$modfile
    3.87 +	else
    3.88 +		echo failed
    3.89 +	fi
    3.90 +done
    3.91 +echo "Will link with: $libs"
    3.92 +
    3.93 +# wrap up the modules.c file
    3.94 +echo '}' >>$modfile
    3.95 +
    3.96 +# wrap up the config.h file
    3.97 +echo '#endif	/* CONFIG_H_ */' >>$cfgfile
    3.98 +
    3.99 +# generate makefile
   3.100 +echo Generating makefile ...
   3.101 +
   3.102 +# hardcode prefix for now, too lazy to actually add an option...
   3.103  echo 'PREFIX = /usr/local' >Makefile
   3.104 +echo "wsys_libs = $libs" >>Makefile
   3.105  cat Makefile.in >>Makefile
   3.106 +
   3.107 +echo 'Configuration complete. Run make (or gmake) to compile.'
     4.1 --- a/include/sgl.h	Fri May 13 09:44:21 2011 +0300
     4.2 +++ b/include/sgl.h	Sat May 14 08:26:10 2011 +0300
     4.3 @@ -37,6 +37,19 @@
     4.4  	SGL_RIGHT_BUTTON
     4.5  };
     4.6  
     4.7 +/* these values happen to coincide with X11 keysyms */
     4.8 +#define SGL_KEY_LSHIFT		0xffe1
     4.9 +#define SGL_KEY_RSHIFT		0xffe2
    4.10 +#define SGL_KEY_LCONTROL	0xffe3
    4.11 +#define SGL_KEY_RCONTROL	0xffe4
    4.12 +#define SGL_KEY_LALT		0xffe9
    4.13 +#define SGL_KEY_RALT		0xffea
    4.14 +
    4.15 +/* for the sgl_modifiers bitmask */
    4.16 +#define SGL_MOD_SHIFT		1
    4.17 +#define SGL_MOD_CONTROL		2
    4.18 +#define SGL_MOD_ALT			4
    4.19 +
    4.20  int sgl_init(void);
    4.21  void sgl_quit(void);
    4.22  
    4.23 @@ -52,6 +65,8 @@
    4.24  void sgl_redisplay(void);
    4.25  void sgl_swap_buffers(void);
    4.26  
    4.27 +int sgl_modifiers(void);
    4.28 +
    4.29  int sgl_process_events(void);
    4.30  void sgl_event_loop(void);
    4.31  
     5.1 --- a/src/sgl.c	Fri May 13 09:44:21 2011 +0300
     5.2 +++ b/src/sgl.c	Sat May 14 08:26:10 2011 +0300
     5.3 @@ -9,6 +9,7 @@
     5.4  {
     5.5  	sgl_modules_init();
     5.6  	sgl_sort_modules();
     5.7 +	sgl_print_modules();
     5.8  
     5.9  	if(!(ws = sgl_wsys_module())) {
    5.10  		return -1;
     6.1 --- a/src/wsys.c	Fri May 13 09:44:21 2011 +0300
     6.2 +++ b/src/wsys.c	Sat May 14 08:26:10 2011 +0300
     6.3 @@ -1,11 +1,13 @@
     6.4  #include <stdio.h>
     6.5 +#include <stdlib.h>
     6.6 +#include <string.h>
     6.7  #include "wsys.h"
     6.8  
     6.9  static struct wsys_module *merge(struct wsys_module *list1, struct wsys_module *list2);
    6.10  static struct wsys_module *msort(struct wsys_module *list, int count);
    6.11  
    6.12  
    6.13 -struct wsys_module *wslist;
    6.14 +struct wsys_module *wslist, *sel;
    6.15  int wscount;
    6.16  
    6.17  int sgl_register_module(struct wsys_module *ws)
    6.18 @@ -21,9 +23,38 @@
    6.19  	wslist = msort(wslist, wscount);
    6.20  }
    6.21  
    6.22 +void sgl_print_modules(void)
    6.23 +{
    6.24 +	struct wsys_module *ws = wslist;
    6.25 +
    6.26 +	printf("window system modules:\n");
    6.27 +	while(ws) {
    6.28 +		printf("- %s\n", ws->name);
    6.29 +		ws = ws->next;
    6.30 +	}
    6.31 +}
    6.32 +
    6.33  struct wsys_module *sgl_wsys_module(void)
    6.34  {
    6.35 -	return wslist;
    6.36 +	if(!sel) {
    6.37 +		char *modname;
    6.38 +		if((modname = getenv("SGL_MODULE"))) {
    6.39 +			struct wsys_module *ws = wslist;
    6.40 +			while(ws) {
    6.41 +				if(strcmp(ws->name, modname) == 0) {
    6.42 +					sel = ws;
    6.43 +					break;
    6.44 +				}
    6.45 +				ws = ws->next;
    6.46 +			}
    6.47 +			if(!sel) {
    6.48 +				sel = wslist;
    6.49 +			}
    6.50 +		} else {
    6.51 +			sel = wslist;
    6.52 +		}
    6.53 +	}
    6.54 +	return sel;
    6.55  }
    6.56  
    6.57  #define APPEND(node) \
     7.1 --- a/src/wsys.h	Fri May 13 09:44:21 2011 +0300
     7.2 +++ b/src/wsys.h	Sat May 14 08:26:10 2011 +0300
     7.3 @@ -20,6 +20,8 @@
     7.4  	void (*redisplay)(void);
     7.5  	void (*swap_buffers)(void);
     7.6  
     7.7 +	int (*get_modifiers)(void);
     7.8 +
     7.9  	void (*set_event)(int idx, int enable);
    7.10  	int (*process_events)(void);
    7.11  
    7.12 @@ -28,6 +30,7 @@
    7.13  
    7.14  int sgl_register_module(struct wsys_module *ws);
    7.15  void sgl_sort_modules(void);
    7.16 +void sgl_print_modules(void);
    7.17  struct wsys_module *sgl_wsys_module(void);
    7.18  
    7.19  void dbg(void);
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/wsys_glut.c	Sat May 14 08:26:10 2011 +0300
     8.3 @@ -0,0 +1,367 @@
     8.4 +/* SimplyGL window system module for GLUT */
     8.5 +/* link-with: -lglut */
     8.6 +
     8.7 +#include "config.h"
     8.8 +
     8.9 +#ifdef USE_WSYS_MODULE_GLUT
    8.10 +
    8.11 +#include <setjmp.h>
    8.12 +#ifndef __APPLE__
    8.13 +#include <GL/glut.h>
    8.14 +#undef FREEGLUT
    8.15 +#ifdef FREEGLUT
    8.16 +#include <GL/freeglut_ext.h>
    8.17 +#endif	/* freeglut */
    8.18 +
    8.19 +#else	/* apple */
    8.20 +#include <GLUT/glut.h>
    8.21 +#endif
    8.22 +
    8.23 +#include "sgl.h"
    8.24 +#include "wsys.h"
    8.25 +
    8.26 +struct window {
    8.27 +	int id;
    8.28 +	struct window *next;
    8.29 +};
    8.30 +
    8.31 +static int init(void);
    8.32 +static void shutdown(void);
    8.33 +
    8.34 +/* video mode switching */
    8.35 +static int set_vidmode(int xsz, int ysz);
    8.36 +static int get_vidmode(int *xsz, int *ysz);
    8.37 +
    8.38 +/* create/destroy windows */
    8.39 +static int create_window(int xsz, int ysz, unsigned int flags);
    8.40 +static void close_window(int id);
    8.41 +
    8.42 +/* window management */
    8.43 +static int set_active(int id);
    8.44 +static int set_title(const char *str);
    8.45 +static void redisplay(void);
    8.46 +static void swap_buffers(void);
    8.47 +
    8.48 +static int get_modifiers(void);
    8.49 +
    8.50 +/* event handling and friends */
    8.51 +static void set_event(int idx, int enable);
    8.52 +static int process_events(void);
    8.53 +
    8.54 +/* callbacks */
    8.55 +static void disp_cb(void);
    8.56 +static void reshape_cb(int x, int y);
    8.57 +static void keyb_down_cb(unsigned char c, int x, int y);
    8.58 +static void keyb_up_cb(unsigned char c, int x, int y);
    8.59 +static void special_down_cb(int c, int x, int y);
    8.60 +static void special_up_cb(int c, int x, int y);
    8.61 +static void mouse_cb(int bn, int state, int x, int y);
    8.62 +static void motion_cb(int x, int y);
    8.63 +static void passive_cb(int x, int y);
    8.64 +static void idle_cb(void);
    8.65 +
    8.66 +
    8.67 +static struct wsys_module ws = {
    8.68 +	"glut", 1,
    8.69 +	init,
    8.70 +	shutdown,
    8.71 +	set_vidmode,
    8.72 +	get_vidmode,
    8.73 +	create_window,
    8.74 +	close_window,
    8.75 +	set_active,
    8.76 +	set_title,
    8.77 +	redisplay,
    8.78 +	swap_buffers,
    8.79 +	get_modifiers,
    8.80 +	set_event,
    8.81 +	process_events,
    8.82 +	0
    8.83 +};
    8.84 +
    8.85 +#ifndef FREEGLUT
    8.86 +static jmp_buf jbuf;
    8.87 +#endif
    8.88 +
    8.89 +static struct window *winlist;
    8.90 +
    8.91 +
    8.92 +/* this is the only exported function, everything else should be static */
    8.93 +void sgl_register_glut(void)
    8.94 +{
    8.95 +	sgl_register_module(&ws);
    8.96 +}
    8.97 +
    8.98 +static int init(void)
    8.99 +{
   8.100 +	char *argv[] = { "simplygl", 0 };
   8.101 +	int argc = 1;
   8.102 +
   8.103 +	glutInit(&argc, argv);
   8.104 +	return 0;
   8.105 +}
   8.106 +
   8.107 +static void shutdown(void)
   8.108 +{
   8.109 +	struct window *win = winlist;
   8.110 +
   8.111 +	while(win) {
   8.112 +		int id = win->id;
   8.113 +		win = win->next;
   8.114 +
   8.115 +		close_window(id);
   8.116 +	}
   8.117 +	winlist = 0;
   8.118 +}
   8.119 +
   8.120 +static int set_vidmode(int xsz, int ysz)
   8.121 +{
   8.122 +	/* TODO */
   8.123 +	return 0;
   8.124 +}
   8.125 +
   8.126 +static int get_vidmode(int *xsz, int *ysz)
   8.127 +{
   8.128 +	/* TODO */
   8.129 +	return 0;
   8.130 +}
   8.131 +
   8.132 +static int create_window(int xsz, int ysz, unsigned int flags)
   8.133 +{
   8.134 +	struct window *win;
   8.135 +	unsigned int glut_flags = GLUT_RGBA;
   8.136 +
   8.137 +	if(flags & SGL_DOUBLE) {
   8.138 +		glut_flags |= GLUT_DOUBLE;
   8.139 +	}
   8.140 +	if(flags & SGL_DEPTH) {
   8.141 +		glut_flags |= GLUT_DEPTH;
   8.142 +	}
   8.143 +	if(flags & SGL_STENCIL) {
   8.144 +		glut_flags |= GLUT_STENCIL;
   8.145 +	}
   8.146 +	if(flags & SGL_STEREO) {
   8.147 +		glut_flags |= GLUT_STEREO;
   8.148 +	}
   8.149 +	if(flags & SGL_MULTISAMPLE) {
   8.150 +		glut_flags |= GLUT_MULTISAMPLE;
   8.151 +	}
   8.152 +
   8.153 +	if(!(win = malloc(sizeof *win))) {
   8.154 +		return -1;
   8.155 +	}
   8.156 +
   8.157 +	glutInitDisplayMode(glut_flags);
   8.158 +	glutInitWindowSize(xsz, ysz);
   8.159 +	if((win->id = glutCreateWindow("OpenGL/GLUT")) <= 0) {
   8.160 +		free(win);
   8.161 +		return -1;
   8.162 +	}
   8.163 +
   8.164 +	win->next = winlist;
   8.165 +	winlist = win;
   8.166 +	return win->id;
   8.167 +}
   8.168 +
   8.169 +static void close_window(int id)
   8.170 +{
   8.171 +	struct window dummy, *win, *prev;
   8.172 +
   8.173 +	dummy.next = win = winlist;
   8.174 +	prev = &dummy;
   8.175 +
   8.176 +	while(win) {
   8.177 +		if(win->id == id) {
   8.178 +			prev->next = win->next;
   8.179 +			free(win);
   8.180 +			break;
   8.181 +		}
   8.182 +		win = win->next;
   8.183 +	}
   8.184 +
   8.185 +	glutDestroyWindow(id);
   8.186 +}
   8.187 +
   8.188 +static int set_active(int id)
   8.189 +{
   8.190 +	glutSetWindow(id);
   8.191 +	return 0;
   8.192 +}
   8.193 +
   8.194 +static int set_title(const char *str)
   8.195 +{
   8.196 +	glutSetWindowTitle(str);
   8.197 +	glutSetIconTitle(str);
   8.198 +	return 0;
   8.199 +}
   8.200 +
   8.201 +static void redisplay(void)
   8.202 +{
   8.203 +	glutPostRedisplay();
   8.204 +}
   8.205 +
   8.206 +static void swap_buffers(void)
   8.207 +{
   8.208 +	glutSwapBuffers();
   8.209 +}
   8.210 +
   8.211 +static int get_modifiers(void)
   8.212 +{
   8.213 +	return glutGetModifiers();
   8.214 +}
   8.215 +
   8.216 +static void set_event(int idx, int enable)
   8.217 +{
   8.218 +	switch(idx) {
   8.219 +	case SGL_DISPLAY:
   8.220 +		glutDisplayFunc(enable ? disp_cb : 0);
   8.221 +		break;
   8.222 +	case SGL_RESHAPE:
   8.223 +		glutReshapeFunc(enable ? reshape_cb : 0);
   8.224 +		break;
   8.225 +	case SGL_KEYBOARD:
   8.226 +		glutKeyboardFunc(enable ? keyb_down_cb : 0);
   8.227 +		glutKeyboardUpFunc(enable ? keyb_up_cb : 0);
   8.228 +		glutSpecialFunc(enable ? special_down_cb : 0);
   8.229 +		glutSpecialUpFunc(enable ? special_up_cb : 0);
   8.230 +		break;
   8.231 +	case SGL_MOUSE:
   8.232 +		glutMouseFunc(enable ? mouse_cb : 0);
   8.233 +		break;
   8.234 +	case SGL_MOTION:
   8.235 +		glutMotionFunc(enable ? motion_cb : 0);
   8.236 +		break;
   8.237 +	case SGL_PASSIVE:
   8.238 +		glutPassiveMotionFunc(enable ? passive_cb : 0);
   8.239 +		break;
   8.240 +	case SGL_IDLE:
   8.241 +		glutIdleFunc(enable ? idle_cb : 0);
   8.242 +		break;
   8.243 +	default:
   8.244 +		break;
   8.245 +	}
   8.246 +}
   8.247 +
   8.248 +static int process_events(void)
   8.249 +{
   8.250 +#ifdef FREEGLUT
   8.251 +	glutMainLoopEvent();
   8.252 +#else
   8.253 +	if(setjmp(jbuf) == 0) {
   8.254 +		glutMainLoop();
   8.255 +	}
   8.256 +	/* ok ... what happens is any callback that kicks in will set the idle func
   8.257 +	 * if it's not set,  and then the idle func will longjmp right back here...
   8.258 +	 */
   8.259 +#endif
   8.260 +	return 0;
   8.261 +}
   8.262 +
   8.263 +static void disp_cb(void)
   8.264 +{
   8.265 +	sgl_display_callback_t func = sgl_get_callback(SGL_DISPLAY);
   8.266 +	func();
   8.267 +
   8.268 +#ifndef FREEGLUT
   8.269 +	glutIdleFunc(idle_cb);
   8.270 +#endif
   8.271 +}
   8.272 +
   8.273 +static void reshape_cb(int x, int y)
   8.274 +{
   8.275 +	sgl_reshape_callback_t func = sgl_get_callback(SGL_RESHAPE);
   8.276 +	func(x, y);
   8.277 +
   8.278 +#ifndef FREEGLUT
   8.279 +	glutIdleFunc(idle_cb);
   8.280 +#endif
   8.281 +}
   8.282 +
   8.283 +static void keyb_down_cb(unsigned char c, int x, int y)
   8.284 +{
   8.285 +	sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
   8.286 +	func((int)c, 1);
   8.287 +
   8.288 +#ifndef FREEGLUT
   8.289 +	glutIdleFunc(idle_cb);
   8.290 +#endif
   8.291 +}
   8.292 +
   8.293 +static void keyb_up_cb(unsigned char c, int x, int y)
   8.294 +{
   8.295 +	sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
   8.296 +	func((int)c, 0);
   8.297 +
   8.298 +#ifndef FREEGLUT
   8.299 +	glutIdleFunc(idle_cb);
   8.300 +#endif
   8.301 +}
   8.302 +
   8.303 +static void special_down_cb(int c, int x, int y)
   8.304 +{
   8.305 +	sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
   8.306 +	func(c, 1);
   8.307 +
   8.308 +#ifndef FREEGLUT
   8.309 +	glutIdleFunc(idle_cb);
   8.310 +#endif
   8.311 +}
   8.312 +
   8.313 +static void special_up_cb(int c, int x, int y)
   8.314 +{
   8.315 +	sgl_keyboard_callback_t func = sgl_get_callback(SGL_KEYBOARD);
   8.316 +	func(c, 0);
   8.317 +
   8.318 +#ifndef FREEGLUT
   8.319 +	glutIdleFunc(idle_cb);
   8.320 +#endif
   8.321 +}
   8.322 +
   8.323 +static void mouse_cb(int bn, int state, int x, int y)
   8.324 +{
   8.325 +	sgl_mouse_callback_t func = sgl_get_callback(SGL_MOUSE);
   8.326 +	func(0, bn, state, x, y);
   8.327 +
   8.328 +#ifndef FREEGLUT
   8.329 +	glutIdleFunc(idle_cb);
   8.330 +#endif
   8.331 +}
   8.332 +
   8.333 +static void motion_cb(int x, int y)
   8.334 +{
   8.335 +	sgl_motion_callback_t func = sgl_get_callback(SGL_MOTION);
   8.336 +	func(0, x, y);
   8.337 +
   8.338 +#ifndef FREEGLUT
   8.339 +	glutIdleFunc(idle_cb);
   8.340 +#endif
   8.341 +}
   8.342 +
   8.343 +static void passive_cb(int x, int y)
   8.344 +{
   8.345 +	sgl_passive_callback_t func = sgl_get_callback(SGL_PASSIVE);
   8.346 +	func(0, x, y);
   8.347 +
   8.348 +#ifndef FREEGLUT
   8.349 +	glutIdleFunc(idle_cb);
   8.350 +#endif
   8.351 +}
   8.352 +
   8.353 +static void idle_cb(void)
   8.354 +{
   8.355 +	sgl_idle_callback_t func = sgl_get_callback(SGL_IDLE);
   8.356 +	if(func) {
   8.357 +		func();
   8.358 +#ifndef FREEGLUT
   8.359 +	} else {
   8.360 +		/* this was just the longjmp trick so restore the lack of idle func */
   8.361 +		glutIdleFunc(0);
   8.362 +#endif
   8.363 +	}
   8.364 +
   8.365 +#ifndef FREEGLUT
   8.366 +	longjmp(jbuf, 0);
   8.367 +#endif
   8.368 +}
   8.369 +
   8.370 +#endif	/* USE_WSYS_MODULE_GLUT */
     9.1 --- a/src/wsys_x11.c	Fri May 13 09:44:21 2011 +0300
     9.2 +++ b/src/wsys_x11.c	Sat May 14 08:26:10 2011 +0300
     9.3 @@ -1,4 +1,12 @@
     9.4 +/* SimplyGL window system module for X11/GLX */
     9.5 +/* link-with: -lX11 */
     9.6 +
     9.7 +#include "config.h"
     9.8 +
     9.9 +#ifdef USE_WSYS_MODULE_X11
    9.10 +
    9.11  #include <stdlib.h>
    9.12 +#include <ctype.h>
    9.13  #include <X11/Xlib.h>
    9.14  #include <GL/glx.h>
    9.15  #include "sgl.h"
    9.16 @@ -37,12 +45,15 @@
    9.17  static void redisplay(void);
    9.18  static void swap_buffers(void);
    9.19  
    9.20 +static int get_modifiers(void);
    9.21 +
    9.22  /* event handling and friends */
    9.23  static void set_bits(long *mask, long bits);
    9.24  static void clear_bits(long *mask, long bits);
    9.25  static void set_event(int idx, int enable);
    9.26  static int process_events(void);
    9.27  static int handle_event(XEvent *xev);
    9.28 +static void process_key(KeySym sym, int state);
    9.29  static int translate_keysym(KeySym sym);
    9.30  
    9.31  static struct wsys_module ws = {
    9.32 @@ -57,6 +68,7 @@
    9.33  	set_title,
    9.34  	redisplay,
    9.35  	swap_buffers,
    9.36 +	get_modifiers,
    9.37  	set_event,
    9.38  	process_events,
    9.39  	0
    9.40 @@ -68,6 +80,7 @@
    9.41  static Atom xa_wm_prot, xa_wm_del_win;
    9.42  static struct window *winlist;
    9.43  static struct window *active_win, *prev_active;
    9.44 +static int modkeys;
    9.45  
    9.46  /* this is the only exported function, everything else should be static */
    9.47  void sgl_register_x11(void)
    9.48 @@ -355,6 +368,11 @@
    9.49  	glXSwapBuffers(dpy, active_win->win);
    9.50  }
    9.51  
    9.52 +static int get_modifiers(void)
    9.53 +{
    9.54 +	return modkeys;
    9.55 +}
    9.56 +
    9.57  static void set_bits(long *mask, long bits)
    9.58  {
    9.59  	*mask |= bits;
    9.60 @@ -449,6 +467,7 @@
    9.61  	int state;
    9.62  	struct window *win;
    9.63  	void (*func)();
    9.64 +	KeySym sym;
    9.65  
    9.66  	if((win = find_window(xev->xany.window))) {
    9.67  		activate_window(win);
    9.68 @@ -505,8 +524,10 @@
    9.69  	case KeyRelease:
    9.70  			state = 0;
    9.71  		}
    9.72 +		sym = XLookupKeysym(&xev->xkey, 0);
    9.73 +		process_key(sym, state);
    9.74 +
    9.75  		if((func = sgl_get_callback(SGL_KEYBOARD))) {
    9.76 -			KeySym sym = XLookupKeysym(&xev->xkey, 0);
    9.77  			func(translate_keysym(sym), state);
    9.78  		}
    9.79  		break;
    9.80 @@ -540,9 +561,35 @@
    9.81  	return 0;
    9.82  }
    9.83  
    9.84 +static void process_key(KeySym sym, int state)
    9.85 +{
    9.86 +	switch(sym) {
    9.87 +	case XK_Shift_L:
    9.88 +	case XK_Shift_R:
    9.89 +		modkeys = state ? (modkeys | SGL_MOD_SHIFT) : (modkeys & ~SGL_MOD_SHIFT);
    9.90 +		break;
    9.91 +
    9.92 +	case XK_Control_L:
    9.93 +	case XK_Control_R:
    9.94 +		modkeys = state ? (modkeys | SGL_MOD_CONTROL) : (modkeys & ~SGL_MOD_CONTROL);
    9.95 +		break;
    9.96 +
    9.97 +	case XK_Alt_L:
    9.98 +	case XK_Alt_R:
    9.99 +		modkeys = state ? (modkeys | SGL_MOD_ALT) : (modkeys & ~SGL_MOD_ALT);
   9.100 +		break;
   9.101 +
   9.102 +	default:
   9.103 +		break;
   9.104 +	}
   9.105 +}
   9.106 +
   9.107  static int translate_keysym(KeySym sym)
   9.108  {
   9.109  	if(sym < 256) {
   9.110 +		if(isalpha(sym) && (modkeys & SGL_MOD_SHIFT)) {
   9.111 +			sym = toupper(sym);
   9.112 +		}
   9.113  		return sym;
   9.114  	}
   9.115  
   9.116 @@ -562,3 +609,5 @@
   9.117  	}
   9.118  	return (int)sym;
   9.119  }
   9.120 +
   9.121 +#endif	/* USE_WSYS_MODULE_X11 */