|
1 |
|
2 /* Test out the window manager interaction functions */ |
|
3 |
|
4 #include <stdio.h> |
|
5 #include <stdlib.h> |
|
6 #include <string.h> |
|
7 |
|
8 #include "SDL.h" |
|
9 |
|
10 /* Is the cursor visible? */ |
|
11 static int visible = 1; |
|
12 |
|
13 static Uint8 video_bpp; |
|
14 static Uint32 video_flags; |
|
15 |
|
16 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
|
17 static void quit(int rc) |
|
18 { |
|
19 SDL_Quit(); |
|
20 exit(rc); |
|
21 } |
|
22 |
|
23 int SetVideoMode(int w, int h) |
|
24 { |
|
25 SDL_Surface *screen; |
|
26 int i; |
|
27 Uint8 *buffer; |
|
28 SDL_Color palette[256]; |
|
29 |
|
30 screen = SDL_SetVideoMode(w, h, video_bpp, video_flags); |
|
31 if ( screen == NULL ) { |
|
32 fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n", |
|
33 w, h, video_bpp, SDL_GetError()); |
|
34 return(-1); |
|
35 } |
|
36 printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? |
|
37 "fullscreen" : "windowed"); |
|
38 |
|
39 /* Set the surface pixels and refresh! */ |
|
40 for ( i=0; i<256; ++i ) { |
|
41 palette[i].r = 255-i; |
|
42 palette[i].g = 255-i; |
|
43 palette[i].b = 255-i; |
|
44 } |
|
45 SDL_SetColors(screen, palette, 0, 256); |
|
46 if ( SDL_LockSurface(screen) < 0 ) { |
|
47 fprintf(stderr, "Couldn't lock display surface: %s\n", |
|
48 SDL_GetError()); |
|
49 return(-1); |
|
50 } |
|
51 buffer = (Uint8 *)screen->pixels; |
|
52 for ( i=0; i<screen->h; ++i ) { |
|
53 memset(buffer,(i*255)/screen->h, |
|
54 screen->w*screen->format->BytesPerPixel); |
|
55 buffer += screen->pitch; |
|
56 } |
|
57 SDL_UnlockSurface(screen); |
|
58 SDL_UpdateRect(screen, 0, 0, 0, 0); |
|
59 |
|
60 return(0); |
|
61 } |
|
62 |
|
63 SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) |
|
64 { |
|
65 SDL_Surface *icon; |
|
66 Uint8 *pixels; |
|
67 Uint8 *mask; |
|
68 int mlen, i, j; |
|
69 |
|
70 *maskp = NULL; |
|
71 |
|
72 /* Load the icon surface */ |
|
73 icon = SDL_LoadBMP(file); |
|
74 if ( icon == NULL ) { |
|
75 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); |
|
76 return(NULL); |
|
77 } |
|
78 |
|
79 /* Check width and height |
|
80 if ( (icon->w%8) != 0 ) { |
|
81 fprintf(stderr, "Icon width must be a multiple of 8!\n"); |
|
82 SDL_FreeSurface(icon); |
|
83 return(NULL); |
|
84 } |
|
85 */ |
|
86 |
|
87 |
|
88 if ( icon->format->palette == NULL ) { |
|
89 fprintf(stderr, "Icon must have a palette!\n"); |
|
90 SDL_FreeSurface(icon); |
|
91 return(NULL); |
|
92 } |
|
93 |
|
94 /* Set the colorkey */ |
|
95 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); |
|
96 |
|
97 /* Create the mask */ |
|
98 pixels = (Uint8 *)icon->pixels; |
|
99 printf("Transparent pixel: (%d,%d,%d)\n", |
|
100 icon->format->palette->colors[*pixels].r, |
|
101 icon->format->palette->colors[*pixels].g, |
|
102 icon->format->palette->colors[*pixels].b); |
|
103 mlen = (icon->w*icon->h + 7) / 8; |
|
104 mask = (Uint8 *)malloc(mlen); |
|
105 if ( mask == NULL ) { |
|
106 fprintf(stderr, "Out of memory!\n"); |
|
107 SDL_FreeSurface(icon); |
|
108 return(NULL); |
|
109 } |
|
110 memset(mask, 0, mlen); |
|
111 for ( i=0; i < icon->h; i++) |
|
112 for (j=0; j < icon->w; j++) { |
|
113 int pindex = i * icon->pitch + j; |
|
114 int mindex = i * icon->w + j; |
|
115 if ( pixels[pindex] != *pixels ) |
|
116 mask[mindex>>3] |= 1 << (7 - (mindex & 7)); |
|
117 } |
|
118 *maskp = mask; |
|
119 return(icon); |
|
120 } |
|
121 |
|
122 void HotKey_ToggleFullScreen(void) |
|
123 { |
|
124 SDL_Surface *screen; |
|
125 |
|
126 screen = SDL_GetVideoSurface(); |
|
127 if ( SDL_WM_ToggleFullScreen(screen) ) { |
|
128 printf("Toggled fullscreen mode - now %s\n", |
|
129 (screen->flags&SDL_FULLSCREEN) ? "fullscreen" : "windowed"); |
|
130 } else { |
|
131 printf("Unable to toggle fullscreen mode\n"); |
|
132 video_flags ^= SDL_FULLSCREEN; |
|
133 SetVideoMode(screen->w, screen->h); |
|
134 } |
|
135 } |
|
136 |
|
137 void HotKey_ToggleGrab(void) |
|
138 { |
|
139 SDL_GrabMode mode; |
|
140 |
|
141 printf("Ctrl-G: toggling input grab!\n"); |
|
142 mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); |
|
143 if ( mode == SDL_GRAB_ON ) { |
|
144 printf("Grab was on\n"); |
|
145 } else { |
|
146 printf("Grab was off\n"); |
|
147 } |
|
148 mode = SDL_WM_GrabInput(mode ? SDL_GRAB_OFF : SDL_GRAB_ON); |
|
149 if ( mode == SDL_GRAB_ON ) { |
|
150 printf("Grab is now on\n"); |
|
151 } else { |
|
152 printf("Grab is now off\n"); |
|
153 } |
|
154 } |
|
155 |
|
156 void HotKey_Iconify(void) |
|
157 { |
|
158 printf("Ctrl-Z: iconifying window!\n"); |
|
159 SDL_WM_IconifyWindow(); |
|
160 } |
|
161 |
|
162 void HotKey_Quit(void) |
|
163 { |
|
164 SDL_Event event; |
|
165 |
|
166 printf("Posting internal quit request\n"); |
|
167 event.type = SDL_USEREVENT; |
|
168 SDL_PushEvent(&event); |
|
169 } |
|
170 |
|
171 int SDLCALL FilterEvents(const SDL_Event *event) |
|
172 { |
|
173 static int reallyquit = 0; |
|
174 |
|
175 switch (event->type) { |
|
176 |
|
177 case SDL_ACTIVEEVENT: |
|
178 /* See what happened */ |
|
179 printf("App %s ", |
|
180 event->active.gain ? "gained" : "lost"); |
|
181 if ( event->active.state & SDL_APPACTIVE ) |
|
182 printf("active "); |
|
183 if ( event->active.state & SDL_APPINPUTFOCUS ) |
|
184 printf("input "); |
|
185 if ( event->active.state & SDL_APPMOUSEFOCUS ) |
|
186 printf("mouse "); |
|
187 printf("focus\n"); |
|
188 |
|
189 /* See if we are iconified or restored */ |
|
190 if ( event->active.state & SDL_APPACTIVE ) { |
|
191 printf("App has been %s\n", |
|
192 event->active.gain ? |
|
193 "restored" : "iconified"); |
|
194 } |
|
195 return(0); |
|
196 |
|
197 /* We want to toggle visibility on buttonpress */ |
|
198 case SDL_MOUSEBUTTONDOWN: |
|
199 case SDL_MOUSEBUTTONUP: |
|
200 if ( event->button.state == SDL_PRESSED ) { |
|
201 visible = !visible; |
|
202 SDL_ShowCursor(visible); |
|
203 } |
|
204 printf("Mouse button %d has been %s\n", |
|
205 event->button.button, |
|
206 (event->button.state == SDL_PRESSED) ? |
|
207 "pressed" : "released"); |
|
208 return(0); |
|
209 |
|
210 /* Show relative mouse motion */ |
|
211 case SDL_MOUSEMOTION: |
|
212 #if 0 |
|
213 printf("Mouse motion: {%d,%d} (%d,%d)\n", |
|
214 event->motion.x, event->motion.y, |
|
215 event->motion.xrel, event->motion.yrel); |
|
216 #endif |
|
217 return(0); |
|
218 |
|
219 case SDL_KEYDOWN: |
|
220 if ( event->key.keysym.sym == SDLK_ESCAPE ) { |
|
221 HotKey_Quit(); |
|
222 } |
|
223 if ( (event->key.keysym.sym == SDLK_g) && |
|
224 (event->key.keysym.mod & KMOD_CTRL) ) { |
|
225 HotKey_ToggleGrab(); |
|
226 } |
|
227 if ( (event->key.keysym.sym == SDLK_z) && |
|
228 (event->key.keysym.mod & KMOD_CTRL) ) { |
|
229 HotKey_Iconify(); |
|
230 } |
|
231 if ( (event->key.keysym.sym == SDLK_RETURN) && |
|
232 (event->key.keysym.mod & KMOD_ALT) ) { |
|
233 HotKey_ToggleFullScreen(); |
|
234 } |
|
235 return(0); |
|
236 |
|
237 /* Pass the video resize event through .. */ |
|
238 case SDL_VIDEORESIZE: |
|
239 return(1); |
|
240 |
|
241 /* This is important! Queue it if we want to quit. */ |
|
242 case SDL_QUIT: |
|
243 if ( ! reallyquit ) { |
|
244 reallyquit = 1; |
|
245 printf("Quit requested\n"); |
|
246 return(0); |
|
247 } |
|
248 printf("Quit demanded\n"); |
|
249 return(1); |
|
250 |
|
251 /* This will never happen because events queued directly |
|
252 to the event queue are not filtered. |
|
253 */ |
|
254 case SDL_USEREVENT: |
|
255 return(1); |
|
256 |
|
257 /* Drop all other events */ |
|
258 default: |
|
259 return(0); |
|
260 } |
|
261 } |
|
262 |
|
263 int main(int argc, char *argv[]) |
|
264 { |
|
265 SDL_Event event; |
|
266 char *title; |
|
267 SDL_Surface *icon; |
|
268 Uint8 *icon_mask; |
|
269 int parsed; |
|
270 int w, h; |
|
271 |
|
272 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { |
|
273 fprintf(stderr, |
|
274 "Couldn't initialize SDL: %s\n", SDL_GetError()); |
|
275 return(1); |
|
276 } |
|
277 |
|
278 /* Check command line arguments */ |
|
279 w = 640; |
|
280 h = 480; |
|
281 video_bpp = 8; |
|
282 video_flags = SDL_SWSURFACE; |
|
283 parsed = 1; |
|
284 while ( parsed ) { |
|
285 if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { |
|
286 video_flags |= SDL_FULLSCREEN; |
|
287 argc -= 1; |
|
288 argv += 1; |
|
289 } else |
|
290 if ( (argc >= 2) && (strcmp(argv[1], "-resize") == 0) ) { |
|
291 video_flags |= SDL_RESIZABLE; |
|
292 argc -= 1; |
|
293 argv += 1; |
|
294 } else |
|
295 if ( (argc >= 2) && (strcmp(argv[1], "-noframe") == 0) ) { |
|
296 video_flags |= SDL_NOFRAME; |
|
297 argc -= 1; |
|
298 argv += 1; |
|
299 } else |
|
300 if ( (argc >= 3) && (strcmp(argv[1], "-width") == 0) ) { |
|
301 w = atoi(argv[2]); |
|
302 argc -= 2; |
|
303 argv += 2; |
|
304 } else |
|
305 if ( (argc >= 3) && (strcmp(argv[1], "-height") == 0) ) { |
|
306 h = atoi(argv[2]); |
|
307 argc -= 2; |
|
308 argv += 2; |
|
309 } else |
|
310 if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { |
|
311 video_bpp = atoi(argv[2]); |
|
312 argc -= 2; |
|
313 argv += 2; |
|
314 } else { |
|
315 parsed = 0; |
|
316 } |
|
317 } |
|
318 |
|
319 /* Set the icon -- this must be done before the first mode set */ |
|
320 icon = LoadIconSurface("icon.bmp", &icon_mask); |
|
321 if ( icon != NULL ) { |
|
322 SDL_WM_SetIcon(icon, icon_mask); |
|
323 } |
|
324 if ( icon_mask != NULL ) |
|
325 free(icon_mask); |
|
326 |
|
327 /* Set the title bar */ |
|
328 if ( argv[1] == NULL ) |
|
329 title = "Testing 1.. 2.. 3..."; |
|
330 else |
|
331 title = argv[1]; |
|
332 SDL_WM_SetCaption(title, "testwm"); |
|
333 |
|
334 /* See if it's really set */ |
|
335 SDL_WM_GetCaption(&title, NULL); |
|
336 if ( title ) |
|
337 printf("Title was set to: %s\n", title); |
|
338 else |
|
339 printf("No window title was set!\n"); |
|
340 |
|
341 /* Initialize the display */ |
|
342 if ( SetVideoMode(w, h) < 0 ) { |
|
343 quit(1); |
|
344 } |
|
345 |
|
346 /* Set an event filter that discards everything but QUIT */ |
|
347 SDL_SetEventFilter(FilterEvents); |
|
348 |
|
349 /* Ignore key up events, they don't even get filtered */ |
|
350 SDL_EventState(SDL_KEYUP, SDL_IGNORE); |
|
351 |
|
352 /* Loop, waiting for QUIT */ |
|
353 while ( SDL_WaitEvent(&event) ) { |
|
354 switch (event.type) { |
|
355 case SDL_VIDEORESIZE: |
|
356 printf("Got a resize event: %dx%d\n", |
|
357 event.resize.w, event.resize.h); |
|
358 SetVideoMode(event.resize.w, event.resize.h); |
|
359 break; |
|
360 case SDL_USEREVENT: |
|
361 printf("Handling internal quit request\n"); |
|
362 /* Fall through to the quit handler */ |
|
363 case SDL_QUIT: |
|
364 printf("Bye bye..\n"); |
|
365 quit(0); |
|
366 default: |
|
367 /* This should never happen */ |
|
368 printf("Warning: Event %d wasn't filtered\n", |
|
369 event.type); |
|
370 break; |
|
371 } |
|
372 } |
|
373 printf("SDL_WaitEvent() error: %s\n", SDL_GetError()); |
|
374 SDL_Quit(); |
|
375 return(255); |
|
376 } |