sgl

annotate 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
rev   line source
nuclear@20 1 /* SimplyGL window system module for SDL */
nuclear@20 2 /* link-with: `sdl-config --libs` */
nuclear@20 3
nuclear@20 4 #include "config.h"
nuclear@20 5
nuclear@20 6 #ifdef USE_WSYS_MODULE_SDL
nuclear@20 7
nuclear@20 8 #include <SDL/SDL.h>
nuclear@20 9 #include "sgl.h"
nuclear@20 10 #include "wsys.h"
nuclear@20 11
nuclear@20 12
nuclear@20 13
nuclear@20 14 static int init(void);
nuclear@20 15 static void shutdown(void);
nuclear@20 16
nuclear@20 17 /* video mode switching */
nuclear@20 18 static int set_vidmode(int xsz, int ysz);
nuclear@20 19 static int get_vidmode(int *xsz, int *ysz);
nuclear@20 20
nuclear@20 21 /* create/destroy windows */
nuclear@20 22 static int create_window(int xsz, int ysz, unsigned int flags);
nuclear@20 23 static void close_window(int wid);
nuclear@20 24
nuclear@20 25 /* window management */
nuclear@20 26 static int set_active(int wid);
nuclear@20 27 static int set_title(const char *str);
nuclear@20 28 static void redisplay(void);
nuclear@20 29 static void swap_buffers(void);
nuclear@20 30
nuclear@20 31 static int get_modifiers(void);
nuclear@20 32
nuclear@20 33 /* event handling and friends */
nuclear@20 34 static void set_event(int idx, int enable);
nuclear@20 35 static int process_events(void);
nuclear@20 36 static int handle_event(SDL_Event *ev);
nuclear@20 37
nuclear@20 38
nuclear@20 39 static struct wsys_module ws = {
nuclear@20 40 "sdl", 6,
nuclear@20 41 init,
nuclear@20 42 shutdown,
nuclear@20 43 set_vidmode,
nuclear@20 44 get_vidmode,
nuclear@20 45 create_window,
nuclear@20 46 close_window,
nuclear@20 47 set_active,
nuclear@20 48 set_title,
nuclear@20 49 redisplay,
nuclear@20 50 swap_buffers,
nuclear@20 51 get_modifiers,
nuclear@20 52 set_event,
nuclear@20 53 process_events,
nuclear@20 54 0
nuclear@20 55 };
nuclear@20 56
nuclear@20 57 static int must_redisplay = 1;
nuclear@20 58 static int win_width, win_height;
nuclear@20 59 static unsigned int sdl_flags;
nuclear@20 60
nuclear@20 61
nuclear@20 62 void sgl_register_sdl(void)
nuclear@20 63 {
nuclear@20 64 sgl_register_module(&ws);
nuclear@20 65 }
nuclear@20 66
nuclear@20 67
nuclear@20 68 static int init(void)
nuclear@20 69 {
nuclear@20 70 return SDL_Init(SDL_INIT_VIDEO);
nuclear@20 71 }
nuclear@20 72
nuclear@20 73 static void shutdown(void)
nuclear@20 74 {
nuclear@20 75 SDL_Quit();
nuclear@20 76 }
nuclear@20 77
nuclear@20 78 /* video mode switching */
nuclear@20 79 static int set_vidmode(int xsz, int ysz)
nuclear@20 80 {
nuclear@20 81 return 0; /* TODO */
nuclear@20 82 }
nuclear@20 83
nuclear@20 84 static int get_vidmode(int *xsz, int *ysz)
nuclear@20 85 {
nuclear@20 86 return 0; /* TODO */
nuclear@20 87 }
nuclear@20 88
nuclear@20 89 /* create/destroy windows */
nuclear@20 90 static int create_window(int xsz, int ysz, unsigned int flags)
nuclear@20 91 {
nuclear@20 92 void (*func)();
nuclear@20 93
nuclear@20 94 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
nuclear@20 95 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
nuclear@20 96 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
nuclear@20 97
nuclear@20 98 if(flags & SGL_DOUBLE) {
nuclear@20 99 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
nuclear@20 100 }
nuclear@20 101 if(flags & SGL_DEPTH) {
nuclear@20 102 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
nuclear@20 103 }
nuclear@20 104 if(flags & SGL_STENCIL) {
nuclear@20 105 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
nuclear@20 106 }
nuclear@20 107 if(flags & SGL_STEREO) {
nuclear@20 108 SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
nuclear@20 109 }
nuclear@20 110 if(flags & SGL_MULTISAMPLE) {
nuclear@20 111 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
nuclear@20 112 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
nuclear@20 113 }
nuclear@20 114
nuclear@20 115 sdl_flags = SDL_OPENGL | SDL_RESIZABLE;
nuclear@20 116
nuclear@20 117 if(!SDL_SetVideoMode(xsz, ysz, 32, sdl_flags)) {
nuclear@20 118 return -1;
nuclear@20 119 }
nuclear@20 120 win_width = xsz;
nuclear@20 121 win_height = ysz;
nuclear@20 122 set_title("OpenGL/SDL");
nuclear@20 123
nuclear@20 124 if((func = sgl_get_callback(SGL_CREATE))) {
nuclear@20 125 func(0);
nuclear@20 126 }
nuclear@20 127 if((func = sgl_get_callback(SGL_RESHAPE))) {
nuclear@20 128 func(xsz, ysz);
nuclear@20 129 }
nuclear@20 130
nuclear@20 131 return 0;
nuclear@20 132 }
nuclear@20 133
nuclear@20 134 static void close_window(int wid)
nuclear@20 135 {
nuclear@20 136 SDL_Quit();
nuclear@20 137 }
nuclear@20 138
nuclear@20 139 /* window management */
nuclear@20 140 static int set_active(int wid)
nuclear@20 141 {
nuclear@20 142 return 0; /* only one window is supported in SDL */
nuclear@20 143 }
nuclear@20 144
nuclear@20 145 static int set_title(const char *str)
nuclear@20 146 {
nuclear@20 147 SDL_WM_SetCaption(str, str);
nuclear@20 148 return 0;
nuclear@20 149 }
nuclear@20 150
nuclear@20 151 static void redisplay(void)
nuclear@20 152 {
nuclear@20 153 must_redisplay = 1;
nuclear@20 154 }
nuclear@20 155
nuclear@20 156 static void swap_buffers(void)
nuclear@20 157 {
nuclear@20 158 SDL_GL_SwapBuffers();
nuclear@20 159 }
nuclear@20 160
nuclear@20 161 static int get_modifiers(void)
nuclear@20 162 {
nuclear@20 163 int mod = 0;
nuclear@20 164 SDLMod sdlmod = SDL_GetModState();
nuclear@20 165
nuclear@20 166 if(sdlmod & (KMOD_LSHIFT | KMOD_RSHIFT)) {
nuclear@20 167 mod |= SGL_MOD_SHIFT;
nuclear@20 168 }
nuclear@20 169 if(sdlmod & (KMOD_LCTRL | KMOD_RCTRL)) {
nuclear@20 170 mod |= SGL_MOD_CONTROL;
nuclear@20 171 }
nuclear@20 172 if(sdlmod & (KMOD_LALT | KMOD_RALT)) {
nuclear@20 173 mod |= SGL_MOD_ALT;
nuclear@20 174 }
nuclear@20 175 return mod;
nuclear@20 176 }
nuclear@20 177
nuclear@20 178 /* event handling and friends */
nuclear@20 179 static void set_event(int idx, int enable)
nuclear@20 180 {
nuclear@20 181 /* no need to do anything for SDL */
nuclear@20 182 }
nuclear@20 183
nuclear@20 184 static int process_events(void)
nuclear@20 185 {
nuclear@20 186 int got_event;
nuclear@20 187 SDL_Event ev;
nuclear@20 188 sgl_idle_callback_t idle = sgl_get_callback(SGL_IDLE);
nuclear@20 189 sgl_display_callback_t disp = sgl_get_callback(SGL_DISPLAY);
nuclear@20 190
nuclear@20 191 if(must_redisplay && disp) {
nuclear@20 192 disp();
nuclear@20 193 must_redisplay = 0;
nuclear@20 194 }
nuclear@20 195
nuclear@20 196 if(idle) {
nuclear@20 197 got_event = SDL_PollEvent(&ev);
nuclear@20 198 } else {
nuclear@20 199 if(!SDL_WaitEvent(&ev)) {
nuclear@20 200 return -1;
nuclear@20 201 }
nuclear@20 202 got_event = 1;
nuclear@20 203 }
nuclear@20 204
nuclear@20 205 if(got_event) {
nuclear@20 206 do {
nuclear@20 207 if(handle_event(&ev) == -1) {
nuclear@20 208 return -1;
nuclear@20 209 }
nuclear@20 210 } while(SDL_PollEvent(&ev));
nuclear@20 211 }
nuclear@20 212
nuclear@20 213 if(idle) {
nuclear@20 214 idle();
nuclear@20 215 }
nuclear@20 216
nuclear@20 217 return 0;
nuclear@20 218 }
nuclear@20 219
nuclear@20 220 static int handle_event(SDL_Event *ev)
nuclear@20 221 {
nuclear@20 222 void (*func)();
nuclear@20 223
nuclear@20 224 switch(ev->type) {
nuclear@20 225 case SDL_VIDEORESIZE:
nuclear@20 226 /* XXX this'll fuck up big time on windows, will lose the gl state! */
nuclear@20 227 SDL_SetVideoMode(ev->resize.w, ev->resize.h, 32, sdl_flags);
nuclear@20 228
nuclear@20 229 if((func = sgl_get_callback(SGL_RESHAPE)) &&
nuclear@20 230 (ev->resize.w != win_width || ev->resize.h != win_height)) {
nuclear@20 231 win_width = ev->resize.w;
nuclear@20 232 win_height = ev->resize.h;
nuclear@20 233
nuclear@20 234 func(win_width, win_height);
nuclear@20 235 }
nuclear@20 236 break;
nuclear@20 237
nuclear@20 238 case SDL_VIDEOEXPOSE:
nuclear@20 239 must_redisplay = 1;
nuclear@20 240 break;
nuclear@20 241
nuclear@20 242 case SDL_KEYDOWN:
nuclear@20 243 case SDL_KEYUP:
nuclear@20 244 if((func = sgl_get_callback(SGL_KEYBOARD))) {
nuclear@20 245 func(ev->key.keysym.sym, ev->key.state == SDL_PRESSED);
nuclear@20 246 }
nuclear@20 247 break;
nuclear@20 248
nuclear@20 249 case SDL_MOUSEBUTTONDOWN:
nuclear@20 250 case SDL_MOUSEBUTTONUP:
nuclear@20 251 if((func = sgl_get_callback(SGL_MOUSE))) {
nuclear@20 252 func(ev->button.which - 1, ev->button.state == SDL_PRESSED, ev->button.x, ev->button.y);
nuclear@20 253 }
nuclear@20 254 break;
nuclear@20 255
nuclear@20 256 case SDL_MOUSEMOTION:
nuclear@20 257 if(ev->motion.state) {
nuclear@20 258 func = sgl_get_callback(SGL_MOTION);
nuclear@20 259 } else {
nuclear@20 260 func = sgl_get_callback(SGL_PASSIVE);
nuclear@20 261 }
nuclear@20 262
nuclear@20 263 if(func) {
nuclear@20 264 func(ev->motion.x, ev->motion.y);
nuclear@20 265 }
nuclear@20 266 break;
nuclear@20 267
nuclear@20 268 case SDL_QUIT:
nuclear@20 269 return -1;
nuclear@20 270 }
nuclear@20 271
nuclear@20 272 return 0;
nuclear@20 273 }
nuclear@20 274
nuclear@20 275 #else
nuclear@20 276 int sgl_wsys_sdl_silence_the_fucking_empty_file_warnings;
nuclear@20 277 #endif /* USE_WSYS_MODULE_SDL */