sgl

view src/wsys_sdl.c @ 33:46e90f9c1e0f

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