test/threadwin.c
changeset 0 74212992fb08
child 562 cb40b26523a5
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/test/threadwin.c	Thu Apr 26 16:45:43 2001 +0000
     1.3 @@ -0,0 +1,307 @@
     1.4 +
     1.5 +/* Test out the multi-threaded event handling functions */
     1.6 +
     1.7 +#include <stdlib.h>
     1.8 +#include <stdio.h>
     1.9 +#include <string.h>
    1.10 +
    1.11 +#include "SDL.h"
    1.12 +#include "SDL_thread.h"
    1.13 +
    1.14 +/* Are we done yet? */
    1.15 +static int done = 0;
    1.16 +
    1.17 +/* Is the cursor visible? */
    1.18 +static int visible = 1;
    1.19 +
    1.20 +SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
    1.21 +{
    1.22 +	SDL_Surface *icon;
    1.23 +	Uint8       *pixels;
    1.24 +	Uint8       *mask;
    1.25 +	int          mlen, i;
    1.26 +
    1.27 +	*maskp = NULL;
    1.28 +
    1.29 +	/* Load the icon surface */
    1.30 +	icon = SDL_LoadBMP(file);
    1.31 +	if ( icon == NULL ) {
    1.32 +		fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
    1.33 +		return(NULL);
    1.34 +	}
    1.35 +
    1.36 +	/* Check width and height */
    1.37 +	if ( (icon->w%8) != 0 ) {
    1.38 +		fprintf(stderr, "Icon width must be a multiple of 8!\n");
    1.39 +		SDL_FreeSurface(icon);
    1.40 +		return(NULL);
    1.41 +	}
    1.42 +	if ( icon->format->palette == NULL ) {
    1.43 +		fprintf(stderr, "Icon must have a palette!\n");
    1.44 +		SDL_FreeSurface(icon);
    1.45 +		return(NULL);
    1.46 +	}
    1.47 +
    1.48 +	/* Set the colorkey */
    1.49 +	SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));
    1.50 +
    1.51 +	/* Create the mask */
    1.52 +	pixels = (Uint8 *)icon->pixels;
    1.53 +	printf("Transparent pixel: (%d,%d,%d)\n",
    1.54 +				icon->format->palette->colors[*pixels].r,
    1.55 +				icon->format->palette->colors[*pixels].g,
    1.56 +				icon->format->palette->colors[*pixels].b);
    1.57 +	mlen = icon->w*icon->h;
    1.58 +	mask = (Uint8 *)malloc(mlen/8);
    1.59 +	if ( mask == NULL ) {
    1.60 +		fprintf(stderr, "Out of memory!\n");
    1.61 +		SDL_FreeSurface(icon);
    1.62 +		return(NULL);
    1.63 +	}
    1.64 +	memset(mask, 0, mlen/8);
    1.65 +	for ( i=0; i<mlen; ) {
    1.66 +		if ( pixels[i] != *pixels )
    1.67 +			mask[i/8] |= 0x01;
    1.68 +		++i;
    1.69 +		if ( (i%8) != 0 )
    1.70 +			mask[i/8] <<= 1;
    1.71 +	}
    1.72 +	*maskp = mask;
    1.73 +	return(icon);
    1.74 +}
    1.75 +
    1.76 +int FilterEvents(const SDL_Event *event)
    1.77 +{
    1.78 +	static int reallyquit = 0;
    1.79 +
    1.80 +	switch (event->type) {
    1.81 +
    1.82 +		case SDL_ACTIVEEVENT:
    1.83 +			/* See what happened */
    1.84 +			printf("App %s ",
    1.85 +				event->active.gain ? "gained" : "lost");
    1.86 +			if ( event->active.state & SDL_APPACTIVE )
    1.87 +				printf("active ");
    1.88 +			if ( event->active.state & SDL_APPMOUSEFOCUS )
    1.89 +				printf("mouse ");
    1.90 +			if ( event->active.state & SDL_APPINPUTFOCUS )
    1.91 +				printf("input ");
    1.92 +			printf("focus\n");
    1.93 +
    1.94 +			/* See if we are iconified or restored */
    1.95 +			if ( event->active.state & SDL_APPACTIVE ) {
    1.96 +				printf("App has been %s\n",
    1.97 +					event->active.gain ?
    1.98 +						 "restored" : "iconified");
    1.99 +			}
   1.100 +			return(0);
   1.101 +
   1.102 +		/* This is important!  Queue it if we want to quit. */
   1.103 +		case SDL_QUIT:
   1.104 +			if ( ! reallyquit ) {
   1.105 +				reallyquit = 1;
   1.106 +				printf("Quit requested\n");
   1.107 +				return(0);
   1.108 +			}
   1.109 +			printf("Quit demanded\n");
   1.110 +			return(1);
   1.111 +
   1.112 +		/* Mouse and keyboard events go to threads */
   1.113 +		case SDL_MOUSEMOTION:
   1.114 +		case SDL_MOUSEBUTTONDOWN:
   1.115 +		case SDL_MOUSEBUTTONUP:
   1.116 +		case SDL_KEYDOWN:
   1.117 +		case SDL_KEYUP:
   1.118 +			return(1);
   1.119 +
   1.120 +		/* Drop all other events */
   1.121 +		default:
   1.122 +			return(0);
   1.123 +	}
   1.124 +}
   1.125 +
   1.126 +int HandleMouse(void *unused)
   1.127 +{
   1.128 +	SDL_Event events[10];
   1.129 +	int i, found;
   1.130 +	Uint32 mask;
   1.131 +
   1.132 +	/* Handle mouse events here */
   1.133 +	mask = (SDL_MOUSEMOTIONMASK|SDL_MOUSEBUTTONDOWNMASK|SDL_MOUSEBUTTONUPMASK);
   1.134 +	while ( ! done ) {
   1.135 +		found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
   1.136 +		for ( i=0; i<found; ++i ) {
   1.137 +			switch(events[i].type) {
   1.138 +				/* We want to toggle visibility on buttonpress */
   1.139 +				case SDL_MOUSEBUTTONDOWN:
   1.140 +				case SDL_MOUSEBUTTONUP:
   1.141 +					if ( events[i].button.state == SDL_PRESSED ) {
   1.142 +						visible = !visible;
   1.143 +						SDL_ShowCursor(visible);
   1.144 +					}
   1.145 +					printf("Mouse button %d has been %s\n",
   1.146 +						events[i].button.button,
   1.147 +						(events[i].button.state == SDL_PRESSED) ?
   1.148 +						"pressed" : "released");
   1.149 +					break;
   1.150 +				/* Show relative mouse motion */
   1.151 +				case SDL_MOUSEMOTION:
   1.152 +					printf("Mouse relative motion: {%d,%d}\n",
   1.153 +							events[i].motion.xrel, events[i].motion.yrel);
   1.154 +					break;
   1.155 +			}
   1.156 +		}
   1.157 +		/* Give up some CPU to allow events to arrive */
   1.158 +		SDL_Delay(20);
   1.159 +	}
   1.160 +	return(0);
   1.161 +}
   1.162 +
   1.163 +int HandleKeyboard(void *unused)
   1.164 +{
   1.165 +	SDL_Event events[10];
   1.166 +	int i, found;
   1.167 +	Uint32 mask;
   1.168 +
   1.169 +	/* Handle mouse events here */
   1.170 +	mask = (SDL_KEYDOWNMASK|SDL_KEYUPMASK);
   1.171 +	while ( ! done ) {
   1.172 +		found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
   1.173 +		for ( i=0; i<found; ++i ) {
   1.174 +			switch(events[i].type) {
   1.175 +			    /* We want to toggle visibility on buttonpress */
   1.176 +			    case SDL_KEYDOWN:
   1.177 +			    case SDL_KEYUP:
   1.178 +			    	/* Allow hitting <ESC> to quit the app */
   1.179 +			    	if ( events[i].key.keysym.sym == SDLK_ESCAPE ) {
   1.180 +			    		done = 1;
   1.181 +			    	}
   1.182 +			    	printf("Key '%c' has been %s\n",
   1.183 +						events[i].key.keysym.unicode,
   1.184 +					(events[i].key.state == SDL_PRESSED) ?
   1.185 +						"pressed" : "released");
   1.186 +			    	break;
   1.187 +			}
   1.188 +		}
   1.189 +		/* Give up some CPU to allow events to arrive */
   1.190 +		SDL_Delay(20);
   1.191 +	}
   1.192 +	return(0);
   1.193 +}
   1.194 +
   1.195 +int main(int argc, char *argv[])
   1.196 +{
   1.197 +	SDL_Surface *screen;
   1.198 +	SDL_Surface *icon;
   1.199 +	Uint8 *icon_mask;
   1.200 +	int i, parsed;
   1.201 +	Uint8 *buffer;
   1.202 +	SDL_Color palette[256];
   1.203 +	Uint32 init_flags;
   1.204 +	Uint8  video_bpp;
   1.205 +	Uint32 video_flags;
   1.206 +	SDL_Thread *mouse_thread;
   1.207 +	SDL_Thread *keybd_thread;
   1.208 +
   1.209 +	/* Set the options, based on command line arguments */
   1.210 +	init_flags = SDL_INIT_VIDEO;
   1.211 +	video_bpp = 8;
   1.212 +	video_flags = SDL_SWSURFACE;
   1.213 +	parsed = 1;
   1.214 +	while ( parsed ) {
   1.215 +		/* If the threaded option is enabled, and the SDL library hasn't
   1.216 +		   been compiled with threaded events enabled, then the mouse and
   1.217 +		   keyboard won't respond.
   1.218 +		 */
   1.219 +		if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) {
   1.220 +			init_flags |= SDL_INIT_EVENTTHREAD;
   1.221 +			argc -= 1;
   1.222 +			argv += 1;
   1.223 +			printf("Running with threaded events\n");
   1.224 +		} else
   1.225 +		if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
   1.226 +			video_flags |= SDL_FULLSCREEN;
   1.227 +			argc -= 1;
   1.228 +			argv += 1;
   1.229 +		} else
   1.230 +		if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
   1.231 +			video_bpp = atoi(argv[2]);
   1.232 +			argc -= 2;
   1.233 +			argv += 2;
   1.234 +		} else {
   1.235 +			parsed = 0;
   1.236 +		}
   1.237 +	}
   1.238 +
   1.239 +	/* Initialize SDL with the requested flags */
   1.240 +	if ( SDL_Init(init_flags) < 0 ) {
   1.241 +		fprintf(stderr,
   1.242 +			"Couldn't initialize SDL: %s\n", SDL_GetError());
   1.243 +		exit(1);
   1.244 +	}
   1.245 +	atexit(SDL_Quit);
   1.246 +
   1.247 +	/* Set the icon -- this must be done before the first mode set */
   1.248 +	icon = LoadIconSurface("icon.bmp", &icon_mask);
   1.249 +	if ( icon != NULL ) {
   1.250 +		SDL_WM_SetIcon(icon, icon_mask);
   1.251 +	}
   1.252 +	if ( icon_mask != NULL )
   1.253 +		free(icon_mask);
   1.254 +
   1.255 +	/* Initialize the display */
   1.256 +	screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags);
   1.257 +	if (  screen == NULL ) {
   1.258 +		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
   1.259 +						video_bpp, SDL_GetError());
   1.260 +		exit(1);
   1.261 +	}
   1.262 +	printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
   1.263 +						"fullscreen" : "windowed");
   1.264 +
   1.265 +	/* Enable printable characters */
   1.266 +	SDL_EnableUNICODE(1);
   1.267 +
   1.268 +	/* Set an event filter that discards everything but QUIT */
   1.269 +	SDL_SetEventFilter(FilterEvents);
   1.270 +
   1.271 +	/* Create the event handling threads */
   1.272 +	mouse_thread = SDL_CreateThread(HandleMouse, NULL);
   1.273 +	keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);
   1.274 +
   1.275 +	/* Set the surface pixels and refresh! */
   1.276 +	for ( i=0; i<256; ++i ) {
   1.277 +		palette[i].r = 255-i;
   1.278 +		palette[i].g = 255-i;
   1.279 +		palette[i].b = 255-i;
   1.280 +	}
   1.281 +	SDL_SetColors(screen, palette, 0, 256);
   1.282 +	if ( SDL_LockSurface(screen) < 0 ) {
   1.283 +		fprintf(stderr, "Couldn't lock display surface: %s\n",
   1.284 +							SDL_GetError());
   1.285 +		exit(2);
   1.286 +	}
   1.287 +	buffer = (Uint8 *)screen->pixels;
   1.288 +	for ( i=0; i<screen->h; ++i ) {
   1.289 +		memset(buffer,(i*255)/screen->h,
   1.290 +				screen->w*screen->format->BytesPerPixel);
   1.291 +		buffer += screen->pitch;
   1.292 +	}
   1.293 +	SDL_UnlockSurface(screen);
   1.294 +	SDL_UpdateRect(screen, 0, 0, 0, 0);
   1.295 +
   1.296 +	/* Loop, waiting for QUIT */
   1.297 +	while ( ! done ) {
   1.298 +		if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) {
   1.299 +			SDL_PumpEvents(); /* Needed when event thread is off */
   1.300 +		}
   1.301 +		if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) {
   1.302 +			done = 1;
   1.303 +		}
   1.304 +		/* Give up some CPU so the events can accumulate */
   1.305 +		SDL_Delay(20);
   1.306 +	}
   1.307 +	SDL_WaitThread(mouse_thread, NULL);
   1.308 +	SDL_WaitThread(keybd_thread, NULL);
   1.309 +	return(0);
   1.310 +}