comparison test/threadwin.c @ 1662:782fd950bd46 SDL-1.3

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