test/threadwin.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 09 May 2006 07:26:58 +0000
changeset 1790 828a17e05192
parent 1769 290b5baf2fca
child 1662 782fd950bd46
child 1895 c121d94672cb
child 3956 3868bebb9f5b
permissions -rw-r--r--
Date: Mon, 8 May 2006 14:19:30 -0700
From: Bob Ippolito
Subject: SDL trunk (r2346) and Mac OS X

The current state of the trunk doesn't quite compile on Mac OS X,
I've attached a series of patches that gets it to compile and kills a
few warnings.

sdl-trunk-r2346-dlcompat-warnings.diff:
The dlcompat thing is just loaded with incorrect type signatures ..
some of them have changed since 10.2 and others are just flat wrong.
This puts it in sync with the latest headers. People on 10.2 will get
the warnings instead of people with new kits.
     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 
    17 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    18 static void quit(int rc)
    19 {
    20 	SDL_Quit();
    21 	exit(rc);
    22 }
    23 
    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 
    80 int SDLCALL FilterEvents(const SDL_Event *event)
    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 
   130 int SDLCALL HandleMouse(void *unused)
   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 
   167 int SDLCALL HandleKeyboard(void *unused)
   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:
   182 			    	printf("Key '%c' has been %s\n",
   183 						events[i].key.keysym.unicode,
   184 					(events[i].key.state == SDL_PRESSED) ?
   185 						"pressed" : "released");
   186 
   187 			    	/* Allow hitting <ESC> to quit the app */
   188 			    	if ( events[i].key.keysym.sym == SDLK_ESCAPE ) {
   189 			    		done = 1;
   190 			    	}
   191 
   192 					/* skip events now that aren't KEYUPs... */
   193 					if (events[i].key.state == SDL_PRESSED)
   194 						break;
   195 
   196 			    	if ( events[i].key.keysym.sym == SDLK_f ) {
   197 						int rc = 0;
   198 						printf("attempting to toggle fullscreen...\n");
   199 						rc = SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
   200                         printf("SDL_WM_ToggleFullScreen returned %d.\n", rc);
   201 			    	}
   202 
   203 			    	if ( events[i].key.keysym.sym == SDLK_g ) {
   204 						SDL_GrabMode m;
   205 						m = SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON ?
   206 								SDL_GRAB_OFF : SDL_GRAB_ON;
   207 						printf("attempting to toggle input grab to %s...\n",
   208                                 m == SDL_GRAB_ON ? "ON" : "OFF");
   209                         SDL_WM_GrabInput(m);
   210 						printf("attempt finished.\n");
   211 			    	}
   212 
   213 			    	break;
   214 			}
   215 		}
   216 		/* Give up some CPU to allow events to arrive */
   217 		SDL_Delay(20);
   218 	}
   219 	return(0);
   220 }
   221 
   222 int main(int argc, char *argv[])
   223 {
   224 	SDL_Surface *screen;
   225 	SDL_Surface *icon;
   226 	Uint8 *icon_mask;
   227 	int i, parsed;
   228 	Uint8 *buffer;
   229 	SDL_Color palette[256];
   230 	Uint32 init_flags;
   231 	Uint8  video_bpp;
   232 	Uint32 video_flags;
   233 	SDL_Thread *mouse_thread;
   234 	SDL_Thread *keybd_thread;
   235 
   236 	/* Set the options, based on command line arguments */
   237 	init_flags = SDL_INIT_VIDEO;
   238 	video_bpp = 8;
   239 	video_flags = SDL_SWSURFACE;
   240 	parsed = 1;
   241 	while ( parsed ) {
   242 		/* If the threaded option is enabled, and the SDL library hasn't
   243 		   been compiled with threaded events enabled, then the mouse and
   244 		   keyboard won't respond.
   245 		 */
   246 		if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) {
   247 			init_flags |= SDL_INIT_EVENTTHREAD;
   248 			argc -= 1;
   249 			argv += 1;
   250 			printf("Running with threaded events\n");
   251 		} else
   252 		if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
   253 			video_flags |= SDL_FULLSCREEN;
   254 			argc -= 1;
   255 			argv += 1;
   256 		} else
   257 		if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
   258 			video_bpp = atoi(argv[2]);
   259 			argc -= 2;
   260 			argv += 2;
   261 		} else {
   262 			parsed = 0;
   263 		}
   264 	}
   265 
   266 	/* Initialize SDL with the requested flags */
   267 	if ( SDL_Init(init_flags) < 0 ) {
   268 		fprintf(stderr,
   269 			"Couldn't initialize SDL: %s\n", SDL_GetError());
   270 		return(1);
   271 	}
   272 
   273 	/* Set the icon -- this must be done before the first mode set */
   274 	icon = LoadIconSurface("icon.bmp", &icon_mask);
   275 	if ( icon != NULL ) {
   276 		SDL_WM_SetIcon(icon, icon_mask);
   277 	}
   278 	if ( icon_mask != NULL )
   279 		free(icon_mask);
   280 
   281 	/* Initialize the display */
   282 	screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags);
   283 	if (  screen == NULL ) {
   284 		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
   285 						video_bpp, SDL_GetError());
   286 		quit(1);
   287 	}
   288 	printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
   289 						"fullscreen" : "windowed");
   290 
   291 	/* Enable printable characters */
   292 	SDL_EnableUNICODE(1);
   293 
   294 	/* Set an event filter that discards everything but QUIT */
   295 	SDL_SetEventFilter(FilterEvents);
   296 
   297 	/* Create the event handling threads */
   298 	mouse_thread = SDL_CreateThread(HandleMouse, NULL);
   299 	keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
   300 
   301 	/* Set the surface pixels and refresh! */
   302 	for ( i=0; i<256; ++i ) {
   303 		palette[i].r = 255-i;
   304 		palette[i].g = 255-i;
   305 		palette[i].b = 255-i;
   306 	}
   307 	SDL_SetColors(screen, palette, 0, 256);
   308 	if ( SDL_LockSurface(screen) < 0 ) {
   309 		fprintf(stderr, "Couldn't lock display surface: %s\n",
   310 							SDL_GetError());
   311 		quit(2);
   312 	}
   313 	buffer = (Uint8 *)screen->pixels;
   314 	for ( i=0; i<screen->h; ++i ) {
   315 		memset(buffer,(i*255)/screen->h,
   316 				screen->w*screen->format->BytesPerPixel);
   317 		buffer += screen->pitch;
   318 	}
   319 	SDL_UnlockSurface(screen);
   320 	SDL_UpdateRect(screen, 0, 0, 0, 0);
   321 
   322 	/* Loop, waiting for QUIT */
   323 	while ( ! done ) {
   324 		if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) {
   325 			SDL_PumpEvents(); /* Needed when event thread is off */
   326 		}
   327 		if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) {
   328 			done = 1;
   329 		}
   330 		/* Give up some CPU so the events can accumulate */
   331 		SDL_Delay(20);
   332 	}
   333 	SDL_WaitThread(mouse_thread, NULL);
   334 	SDL_WaitThread(keybd_thread, NULL);
   335 	SDL_Quit();
   336 	return(0);
   337 }