sgl

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