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