Mercurial > sdl-ios-xcode
annotate test/threadwin.c @ 4068:86746036a6d6 SDL-1.2
I think this fixes bug #454
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 15 Jul 2007 14:05:31 +0000 |
parents | 3868bebb9f5b |
children |
rev | line source |
---|---|
0 | 1 |
2 /* Test out the multi-threaded event handling functions */ | |
3 | |
4 #include <stdlib.h> | |
5 #include <stdio.h> | |
6 #include <string.h> | |
7 | |
8 #include "SDL.h" | |
9 #include "SDL_thread.h" | |
10 | |
11 /* Are we done yet? */ | |
12 static int done = 0; | |
13 | |
14 /* Is the cursor visible? */ | |
15 static int visible = 1; | |
16 | |
1151
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
17 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
18 static void quit(int rc) |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
19 { |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
20 SDL_Quit(); |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
21 exit(rc); |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
22 } |
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
23 |
0 | 24 SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp) |
25 { | |
26 SDL_Surface *icon; | |
27 Uint8 *pixels; | |
28 Uint8 *mask; | |
29 int mlen, i; | |
30 | |
31 *maskp = NULL; | |
32 | |
33 /* Load the icon surface */ | |
34 icon = SDL_LoadBMP(file); | |
35 if ( icon == NULL ) { | |
36 fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); | |
37 return(NULL); | |
38 } | |
39 | |
40 /* Check width and height */ | |
41 if ( (icon->w%8) != 0 ) { | |
42 fprintf(stderr, "Icon width must be a multiple of 8!\n"); | |
43 SDL_FreeSurface(icon); | |
44 return(NULL); | |
45 } | |
46 if ( icon->format->palette == NULL ) { | |
47 fprintf(stderr, "Icon must have a palette!\n"); | |
48 SDL_FreeSurface(icon); | |
49 return(NULL); | |
50 } | |
51 | |
52 /* Set the colorkey */ | |
53 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels)); | |
54 | |
55 /* Create the mask */ | |
56 pixels = (Uint8 *)icon->pixels; | |
57 printf("Transparent pixel: (%d,%d,%d)\n", | |
58 icon->format->palette->colors[*pixels].r, | |
59 icon->format->palette->colors[*pixels].g, | |
60 icon->format->palette->colors[*pixels].b); | |
61 mlen = icon->w*icon->h; | |
62 mask = (Uint8 *)malloc(mlen/8); | |
63 if ( mask == NULL ) { | |
64 fprintf(stderr, "Out of memory!\n"); | |
65 SDL_FreeSurface(icon); | |
66 return(NULL); | |
67 } | |
68 memset(mask, 0, mlen/8); | |
69 for ( i=0; i<mlen; ) { | |
70 if ( pixels[i] != *pixels ) | |
71 mask[i/8] |= 0x01; | |
72 ++i; | |
73 if ( (i%8) != 0 ) | |
74 mask[i/8] <<= 1; | |
75 } | |
76 *maskp = mask; | |
77 return(icon); | |
78 } | |
79 | |
1769 | 80 int SDLCALL FilterEvents(const SDL_Event *event) |
0 | 81 { |
82 static int reallyquit = 0; | |
83 | |
84 switch (event->type) { | |
85 | |
86 case SDL_ACTIVEEVENT: | |
87 /* See what happened */ | |
88 printf("App %s ", | |
89 event->active.gain ? "gained" : "lost"); | |
90 if ( event->active.state & SDL_APPACTIVE ) | |
91 printf("active "); | |
92 if ( event->active.state & SDL_APPMOUSEFOCUS ) | |
93 printf("mouse "); | |
94 if ( event->active.state & SDL_APPINPUTFOCUS ) | |
95 printf("input "); | |
96 printf("focus\n"); | |
97 | |
98 /* See if we are iconified or restored */ | |
99 if ( event->active.state & SDL_APPACTIVE ) { | |
100 printf("App has been %s\n", | |
101 event->active.gain ? | |
102 "restored" : "iconified"); | |
103 } | |
104 return(0); | |
105 | |
106 /* This is important! Queue it if we want to quit. */ | |
107 case SDL_QUIT: | |
108 if ( ! reallyquit ) { | |
109 reallyquit = 1; | |
110 printf("Quit requested\n"); | |
111 return(0); | |
112 } | |
113 printf("Quit demanded\n"); | |
114 return(1); | |
115 | |
116 /* Mouse and keyboard events go to threads */ | |
117 case SDL_MOUSEMOTION: | |
118 case SDL_MOUSEBUTTONDOWN: | |
119 case SDL_MOUSEBUTTONUP: | |
120 case SDL_KEYDOWN: | |
121 case SDL_KEYUP: | |
122 return(1); | |
123 | |
124 /* Drop all other events */ | |
125 default: | |
126 return(0); | |
127 } | |
128 } | |
129 | |
1769 | 130 int SDLCALL HandleMouse(void *unused) |
0 | 131 { |
132 SDL_Event events[10]; | |
133 int i, found; | |
134 Uint32 mask; | |
135 | |
136 /* Handle mouse events here */ | |
137 mask = (SDL_MOUSEMOTIONMASK|SDL_MOUSEBUTTONDOWNMASK|SDL_MOUSEBUTTONUPMASK); | |
138 while ( ! done ) { | |
139 found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask); | |
140 for ( i=0; i<found; ++i ) { | |
141 switch(events[i].type) { | |
142 /* We want to toggle visibility on buttonpress */ | |
143 case SDL_MOUSEBUTTONDOWN: | |
144 case SDL_MOUSEBUTTONUP: | |
145 if ( events[i].button.state == SDL_PRESSED ) { | |
146 visible = !visible; | |
147 SDL_ShowCursor(visible); | |
148 } | |
149 printf("Mouse button %d has been %s\n", | |
150 events[i].button.button, | |
151 (events[i].button.state == SDL_PRESSED) ? | |
152 "pressed" : "released"); | |
153 break; | |
154 /* Show relative mouse motion */ | |
155 case SDL_MOUSEMOTION: | |
156 printf("Mouse relative motion: {%d,%d}\n", | |
157 events[i].motion.xrel, events[i].motion.yrel); | |
158 break; | |
159 } | |
160 } | |
161 /* Give up some CPU to allow events to arrive */ | |
162 SDL_Delay(20); | |
163 } | |
164 return(0); | |
165 } | |
166 | |
1769 | 167 int SDLCALL HandleKeyboard(void *unused) |
0 | 168 { |
169 SDL_Event events[10]; | |
170 int i, found; | |
171 Uint32 mask; | |
172 | |
173 /* Handle mouse events here */ | |
174 mask = (SDL_KEYDOWNMASK|SDL_KEYUPMASK); | |
175 while ( ! done ) { | |
176 found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask); | |
177 for ( i=0; i<found; ++i ) { | |
178 switch(events[i].type) { | |
179 /* We want to toggle visibility on buttonpress */ | |
180 case SDL_KEYDOWN: | |
181 case SDL_KEYUP: | |
3956
3868bebb9f5b
Print keysym with key events.
Ryan C. Gordon <icculus@icculus.org>
parents:
1769
diff
changeset
|
182 printf("Key '%c' (keysym==%d) has been %s\n", |
562
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
183 events[i].key.keysym.unicode, |
3956
3868bebb9f5b
Print keysym with key events.
Ryan C. Gordon <icculus@icculus.org>
parents:
1769
diff
changeset
|
184 (int) events[i].key.keysym.sym, |
562
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
185 (events[i].key.state == SDL_PRESSED) ? |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
186 "pressed" : "released"); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
187 |
0 | 188 /* Allow hitting <ESC> to quit the app */ |
189 if ( events[i].key.keysym.sym == SDLK_ESCAPE ) { | |
190 done = 1; | |
191 } | |
562
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
192 |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
193 /* skip events now that aren't KEYUPs... */ |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
194 if (events[i].key.state == SDL_PRESSED) |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
195 break; |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
196 |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
197 if ( events[i].key.keysym.sym == SDLK_f ) { |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
198 int rc = 0; |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
199 printf("attempting to toggle fullscreen...\n"); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
200 rc = SDL_WM_ToggleFullScreen(SDL_GetVideoSurface()); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
201 printf("SDL_WM_ToggleFullScreen returned %d.\n", rc); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
202 } |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
203 |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
204 if ( events[i].key.keysym.sym == SDLK_g ) { |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
205 SDL_GrabMode m; |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
206 m = SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON ? |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
207 SDL_GRAB_OFF : SDL_GRAB_ON; |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
208 printf("attempting to toggle input grab to %s...\n", |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
209 m == SDL_GRAB_ON ? "ON" : "OFF"); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
210 SDL_WM_GrabInput(m); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
211 printf("attempt finished.\n"); |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
212 } |
cb40b26523a5
Added some code to toggle fullscreen and input grab for testing... --ryan.
Ryan C. Gordon <icculus@icculus.org>
parents:
0
diff
changeset
|
213 |
0 | 214 break; |
215 } | |
216 } | |
217 /* Give up some CPU to allow events to arrive */ | |
218 SDL_Delay(20); | |
219 } | |
220 return(0); | |
221 } | |
222 | |
223 int main(int argc, char *argv[]) | |
224 { | |
225 SDL_Surface *screen; | |
226 SDL_Surface *icon; | |
227 Uint8 *icon_mask; | |
228 int i, parsed; | |
229 Uint8 *buffer; | |
230 SDL_Color palette[256]; | |
231 Uint32 init_flags; | |
232 Uint8 video_bpp; | |
233 Uint32 video_flags; | |
234 SDL_Thread *mouse_thread; | |
235 SDL_Thread *keybd_thread; | |
236 | |
237 /* Set the options, based on command line arguments */ | |
238 init_flags = SDL_INIT_VIDEO; | |
239 video_bpp = 8; | |
240 video_flags = SDL_SWSURFACE; | |
241 parsed = 1; | |
242 while ( parsed ) { | |
243 /* If the threaded option is enabled, and the SDL library hasn't | |
244 been compiled with threaded events enabled, then the mouse and | |
245 keyboard won't respond. | |
246 */ | |
247 if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) { | |
248 init_flags |= SDL_INIT_EVENTTHREAD; | |
249 argc -= 1; | |
250 argv += 1; | |
251 printf("Running with threaded events\n"); | |
252 } else | |
253 if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) { | |
254 video_flags |= SDL_FULLSCREEN; | |
255 argc -= 1; | |
256 argv += 1; | |
257 } else | |
258 if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) { | |
259 video_bpp = atoi(argv[2]); | |
260 argc -= 2; | |
261 argv += 2; | |
262 } else { | |
263 parsed = 0; | |
264 } | |
265 } | |
266 | |
267 /* Initialize SDL with the requested flags */ | |
268 if ( SDL_Init(init_flags) < 0 ) { | |
269 fprintf(stderr, | |
270 "Couldn't initialize SDL: %s\n", SDL_GetError()); | |
1151
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
271 return(1); |
0 | 272 } |
273 | |
274 /* Set the icon -- this must be done before the first mode set */ | |
275 icon = LoadIconSurface("icon.bmp", &icon_mask); | |
276 if ( icon != NULL ) { | |
277 SDL_WM_SetIcon(icon, icon_mask); | |
278 } | |
279 if ( icon_mask != NULL ) | |
280 free(icon_mask); | |
281 | |
282 /* Initialize the display */ | |
283 screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags); | |
284 if ( screen == NULL ) { | |
285 fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", | |
286 video_bpp, SDL_GetError()); | |
1151
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
287 quit(1); |
0 | 288 } |
289 printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ? | |
290 "fullscreen" : "windowed"); | |
291 | |
292 /* Enable printable characters */ | |
293 SDL_EnableUNICODE(1); | |
294 | |
295 /* Set an event filter that discards everything but QUIT */ | |
296 SDL_SetEventFilter(FilterEvents); | |
297 | |
298 /* Create the event handling threads */ | |
299 mouse_thread = SDL_CreateThread(HandleMouse, NULL); | |
300 keybd_thread = SDL_CreateThread(HandleKeyboard, NULL); | |
301 | |
302 /* Set the surface pixels and refresh! */ | |
303 for ( i=0; i<256; ++i ) { | |
304 palette[i].r = 255-i; | |
305 palette[i].g = 255-i; | |
306 palette[i].b = 255-i; | |
307 } | |
308 SDL_SetColors(screen, palette, 0, 256); | |
309 if ( SDL_LockSurface(screen) < 0 ) { | |
310 fprintf(stderr, "Couldn't lock display surface: %s\n", | |
311 SDL_GetError()); | |
1151
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
312 quit(2); |
0 | 313 } |
314 buffer = (Uint8 *)screen->pixels; | |
315 for ( i=0; i<screen->h; ++i ) { | |
316 memset(buffer,(i*255)/screen->h, | |
317 screen->w*screen->format->BytesPerPixel); | |
318 buffer += screen->pitch; | |
319 } | |
320 SDL_UnlockSurface(screen); | |
321 SDL_UpdateRect(screen, 0, 0, 0, 0); | |
322 | |
323 /* Loop, waiting for QUIT */ | |
324 while ( ! done ) { | |
325 if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) { | |
326 SDL_PumpEvents(); /* Needed when event thread is off */ | |
327 } | |
328 if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) { | |
329 done = 1; | |
330 } | |
331 /* Give up some CPU so the events can accumulate */ | |
332 SDL_Delay(20); | |
333 } | |
334 SDL_WaitThread(mouse_thread, NULL); | |
335 SDL_WaitThread(keybd_thread, NULL); | |
1151
be9c9c8f6d53
Removed atexit() from most of the test programs; atexit(SDL_Quit) isn't safe
Ryan C. Gordon <icculus@icculus.org>
parents:
562
diff
changeset
|
336 SDL_Quit(); |
0 | 337 return(0); |
338 } |