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