sgl

annotate src/wsys_sdl.c @ 35:3d6ee9fb9ac1

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