sgl
diff src/wsys_sdl.c @ 20:0697fbd075b6
added fallback SDL module
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 26 Jun 2011 07:56:13 +0300 |
parents | |
children | 3d6ee9fb9ac1 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/wsys_sdl.c Sun Jun 26 07:56:13 2011 +0300 1.3 @@ -0,0 +1,277 @@ 1.4 +/* SimplyGL window system module for SDL */ 1.5 +/* link-with: `sdl-config --libs` */ 1.6 + 1.7 +#include "config.h" 1.8 + 1.9 +#ifdef USE_WSYS_MODULE_SDL 1.10 + 1.11 +#include <SDL/SDL.h> 1.12 +#include "sgl.h" 1.13 +#include "wsys.h" 1.14 + 1.15 + 1.16 + 1.17 +static int init(void); 1.18 +static void shutdown(void); 1.19 + 1.20 +/* video mode switching */ 1.21 +static int set_vidmode(int xsz, int ysz); 1.22 +static int get_vidmode(int *xsz, int *ysz); 1.23 + 1.24 +/* create/destroy windows */ 1.25 +static int create_window(int xsz, int ysz, unsigned int flags); 1.26 +static void close_window(int wid); 1.27 + 1.28 +/* window management */ 1.29 +static int set_active(int wid); 1.30 +static int set_title(const char *str); 1.31 +static void redisplay(void); 1.32 +static void swap_buffers(void); 1.33 + 1.34 +static int get_modifiers(void); 1.35 + 1.36 +/* event handling and friends */ 1.37 +static void set_event(int idx, int enable); 1.38 +static int process_events(void); 1.39 +static int handle_event(SDL_Event *ev); 1.40 + 1.41 + 1.42 +static struct wsys_module ws = { 1.43 + "sdl", 6, 1.44 + init, 1.45 + shutdown, 1.46 + set_vidmode, 1.47 + get_vidmode, 1.48 + create_window, 1.49 + close_window, 1.50 + set_active, 1.51 + set_title, 1.52 + redisplay, 1.53 + swap_buffers, 1.54 + get_modifiers, 1.55 + set_event, 1.56 + process_events, 1.57 + 0 1.58 +}; 1.59 + 1.60 +static int must_redisplay = 1; 1.61 +static int win_width, win_height; 1.62 +static unsigned int sdl_flags; 1.63 + 1.64 + 1.65 +void sgl_register_sdl(void) 1.66 +{ 1.67 + sgl_register_module(&ws); 1.68 +} 1.69 + 1.70 + 1.71 +static int init(void) 1.72 +{ 1.73 + return SDL_Init(SDL_INIT_VIDEO); 1.74 +} 1.75 + 1.76 +static void shutdown(void) 1.77 +{ 1.78 + SDL_Quit(); 1.79 +} 1.80 + 1.81 +/* video mode switching */ 1.82 +static int set_vidmode(int xsz, int ysz) 1.83 +{ 1.84 + return 0; /* TODO */ 1.85 +} 1.86 + 1.87 +static int get_vidmode(int *xsz, int *ysz) 1.88 +{ 1.89 + return 0; /* TODO */ 1.90 +} 1.91 + 1.92 +/* create/destroy windows */ 1.93 +static int create_window(int xsz, int ysz, unsigned int flags) 1.94 +{ 1.95 + void (*func)(); 1.96 + 1.97 + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 1.98 + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 1.99 + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); 1.100 + 1.101 + if(flags & SGL_DOUBLE) { 1.102 + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 1.103 + } 1.104 + if(flags & SGL_DEPTH) { 1.105 + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); 1.106 + } 1.107 + if(flags & SGL_STENCIL) { 1.108 + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 1.109 + } 1.110 + if(flags & SGL_STEREO) { 1.111 + SDL_GL_SetAttribute(SDL_GL_STEREO, 1); 1.112 + } 1.113 + if(flags & SGL_MULTISAMPLE) { 1.114 + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); 1.115 + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); 1.116 + } 1.117 + 1.118 + sdl_flags = SDL_OPENGL | SDL_RESIZABLE; 1.119 + 1.120 + if(!SDL_SetVideoMode(xsz, ysz, 32, sdl_flags)) { 1.121 + return -1; 1.122 + } 1.123 + win_width = xsz; 1.124 + win_height = ysz; 1.125 + set_title("OpenGL/SDL"); 1.126 + 1.127 + if((func = sgl_get_callback(SGL_CREATE))) { 1.128 + func(0); 1.129 + } 1.130 + if((func = sgl_get_callback(SGL_RESHAPE))) { 1.131 + func(xsz, ysz); 1.132 + } 1.133 + 1.134 + return 0; 1.135 +} 1.136 + 1.137 +static void close_window(int wid) 1.138 +{ 1.139 + SDL_Quit(); 1.140 +} 1.141 + 1.142 +/* window management */ 1.143 +static int set_active(int wid) 1.144 +{ 1.145 + return 0; /* only one window is supported in SDL */ 1.146 +} 1.147 + 1.148 +static int set_title(const char *str) 1.149 +{ 1.150 + SDL_WM_SetCaption(str, str); 1.151 + return 0; 1.152 +} 1.153 + 1.154 +static void redisplay(void) 1.155 +{ 1.156 + must_redisplay = 1; 1.157 +} 1.158 + 1.159 +static void swap_buffers(void) 1.160 +{ 1.161 + SDL_GL_SwapBuffers(); 1.162 +} 1.163 + 1.164 +static int get_modifiers(void) 1.165 +{ 1.166 + int mod = 0; 1.167 + SDLMod sdlmod = SDL_GetModState(); 1.168 + 1.169 + if(sdlmod & (KMOD_LSHIFT | KMOD_RSHIFT)) { 1.170 + mod |= SGL_MOD_SHIFT; 1.171 + } 1.172 + if(sdlmod & (KMOD_LCTRL | KMOD_RCTRL)) { 1.173 + mod |= SGL_MOD_CONTROL; 1.174 + } 1.175 + if(sdlmod & (KMOD_LALT | KMOD_RALT)) { 1.176 + mod |= SGL_MOD_ALT; 1.177 + } 1.178 + return mod; 1.179 +} 1.180 + 1.181 +/* event handling and friends */ 1.182 +static void set_event(int idx, int enable) 1.183 +{ 1.184 + /* no need to do anything for SDL */ 1.185 +} 1.186 + 1.187 +static int process_events(void) 1.188 +{ 1.189 + int got_event; 1.190 + SDL_Event ev; 1.191 + sgl_idle_callback_t idle = sgl_get_callback(SGL_IDLE); 1.192 + sgl_display_callback_t disp = sgl_get_callback(SGL_DISPLAY); 1.193 + 1.194 + if(must_redisplay && disp) { 1.195 + disp(); 1.196 + must_redisplay = 0; 1.197 + } 1.198 + 1.199 + if(idle) { 1.200 + got_event = SDL_PollEvent(&ev); 1.201 + } else { 1.202 + if(!SDL_WaitEvent(&ev)) { 1.203 + return -1; 1.204 + } 1.205 + got_event = 1; 1.206 + } 1.207 + 1.208 + if(got_event) { 1.209 + do { 1.210 + if(handle_event(&ev) == -1) { 1.211 + return -1; 1.212 + } 1.213 + } while(SDL_PollEvent(&ev)); 1.214 + } 1.215 + 1.216 + if(idle) { 1.217 + idle(); 1.218 + } 1.219 + 1.220 + return 0; 1.221 +} 1.222 + 1.223 +static int handle_event(SDL_Event *ev) 1.224 +{ 1.225 + void (*func)(); 1.226 + 1.227 + switch(ev->type) { 1.228 + case SDL_VIDEORESIZE: 1.229 + /* XXX this'll fuck up big time on windows, will lose the gl state! */ 1.230 + SDL_SetVideoMode(ev->resize.w, ev->resize.h, 32, sdl_flags); 1.231 + 1.232 + if((func = sgl_get_callback(SGL_RESHAPE)) && 1.233 + (ev->resize.w != win_width || ev->resize.h != win_height)) { 1.234 + win_width = ev->resize.w; 1.235 + win_height = ev->resize.h; 1.236 + 1.237 + func(win_width, win_height); 1.238 + } 1.239 + break; 1.240 + 1.241 + case SDL_VIDEOEXPOSE: 1.242 + must_redisplay = 1; 1.243 + break; 1.244 + 1.245 + case SDL_KEYDOWN: 1.246 + case SDL_KEYUP: 1.247 + if((func = sgl_get_callback(SGL_KEYBOARD))) { 1.248 + func(ev->key.keysym.sym, ev->key.state == SDL_PRESSED); 1.249 + } 1.250 + break; 1.251 + 1.252 + case SDL_MOUSEBUTTONDOWN: 1.253 + case SDL_MOUSEBUTTONUP: 1.254 + if((func = sgl_get_callback(SGL_MOUSE))) { 1.255 + func(ev->button.which - 1, ev->button.state == SDL_PRESSED, ev->button.x, ev->button.y); 1.256 + } 1.257 + break; 1.258 + 1.259 + case SDL_MOUSEMOTION: 1.260 + if(ev->motion.state) { 1.261 + func = sgl_get_callback(SGL_MOTION); 1.262 + } else { 1.263 + func = sgl_get_callback(SGL_PASSIVE); 1.264 + } 1.265 + 1.266 + if(func) { 1.267 + func(ev->motion.x, ev->motion.y); 1.268 + } 1.269 + break; 1.270 + 1.271 + case SDL_QUIT: 1.272 + return -1; 1.273 + } 1.274 + 1.275 + return 0; 1.276 +} 1.277 + 1.278 +#else 1.279 +int sgl_wsys_sdl_silence_the_fucking_empty_file_warnings; 1.280 +#endif /* USE_WSYS_MODULE_SDL */