
/* Test out the multi-threaded event handling functions */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "SDL.h"
#include "SDL_thread.h"

/* Are we done yet? */
static int done = 0;

/* Is the cursor visible? */
static int visible = 1;

SDL_Surface *LoadIconSurface(char *file, Uint8 **maskp)
{
	SDL_Surface *icon;
	Uint8       *pixels;
	Uint8       *mask;
	int          mlen, i;

	*maskp = NULL;

	/* Load the icon surface */
	icon = SDL_LoadBMP(file);
	if ( icon == NULL ) {
		fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
		return(NULL);
	}

	/* Check width and height */
	if ( (icon->w%8) != 0 ) {
		fprintf(stderr, "Icon width must be a multiple of 8!\n");
		SDL_FreeSurface(icon);
		return(NULL);
	}
	if ( icon->format->palette == NULL ) {
		fprintf(stderr, "Icon must have a palette!\n");
		SDL_FreeSurface(icon);
		return(NULL);
	}

	/* Set the colorkey */
	SDL_SetColorKey(icon, SDL_SRCCOLORKEY, *((Uint8 *)icon->pixels));

	/* Create the mask */
	pixels = (Uint8 *)icon->pixels;
	printf("Transparent pixel: (%d,%d,%d)\n",
				icon->format->palette->colors[*pixels].r,
				icon->format->palette->colors[*pixels].g,
				icon->format->palette->colors[*pixels].b);
	mlen = icon->w*icon->h;
	mask = (Uint8 *)malloc(mlen/8);
	if ( mask == NULL ) {
		fprintf(stderr, "Out of memory!\n");
		SDL_FreeSurface(icon);
		return(NULL);
	}
	memset(mask, 0, mlen/8);
	for ( i=0; i<mlen; ) {
		if ( pixels[i] != *pixels )
			mask[i/8] |= 0x01;
		++i;
		if ( (i%8) != 0 )
			mask[i/8] <<= 1;
	}
	*maskp = mask;
	return(icon);
}

int FilterEvents(const SDL_Event *event)
{
	static int reallyquit = 0;

	switch (event->type) {

		case SDL_ACTIVEEVENT:
			/* See what happened */
			printf("App %s ",
				event->active.gain ? "gained" : "lost");
			if ( event->active.state & SDL_APPACTIVE )
				printf("active ");
			if ( event->active.state & SDL_APPMOUSEFOCUS )
				printf("mouse ");
			if ( event->active.state & SDL_APPINPUTFOCUS )
				printf("input ");
			printf("focus\n");

			/* See if we are iconified or restored */
			if ( event->active.state & SDL_APPACTIVE ) {
				printf("App has been %s\n",
					event->active.gain ?
						 "restored" : "iconified");
			}
			return(0);

		/* This is important!  Queue it if we want to quit. */
		case SDL_QUIT:
			if ( ! reallyquit ) {
				reallyquit = 1;
				printf("Quit requested\n");
				return(0);
			}
			printf("Quit demanded\n");
			return(1);

		/* Mouse and keyboard events go to threads */
		case SDL_MOUSEMOTION:
		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
		case SDL_KEYDOWN:
		case SDL_KEYUP:
			return(1);

		/* Drop all other events */
		default:
			return(0);
	}
}

int HandleMouse(void *unused)
{
	SDL_Event events[10];
	int i, found;
	Uint32 mask;

	/* Handle mouse events here */
	mask = (SDL_MOUSEMOTIONMASK|SDL_MOUSEBUTTONDOWNMASK|SDL_MOUSEBUTTONUPMASK);
	while ( ! done ) {
		found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
		for ( i=0; i<found; ++i ) {
			switch(events[i].type) {
				/* We want to toggle visibility on buttonpress */
				case SDL_MOUSEBUTTONDOWN:
				case SDL_MOUSEBUTTONUP:
					if ( events[i].button.state == SDL_PRESSED ) {
						visible = !visible;
						SDL_ShowCursor(visible);
					}
					printf("Mouse button %d has been %s\n",
						events[i].button.button,
						(events[i].button.state == SDL_PRESSED) ?
						"pressed" : "released");
					break;
				/* Show relative mouse motion */
				case SDL_MOUSEMOTION:
					printf("Mouse relative motion: {%d,%d}\n",
							events[i].motion.xrel, events[i].motion.yrel);
					break;
			}
		}
		/* Give up some CPU to allow events to arrive */
		SDL_Delay(20);
	}
	return(0);
}

int HandleKeyboard(void *unused)
{
	SDL_Event events[10];
	int i, found;
	Uint32 mask;

	/* Handle mouse events here */
	mask = (SDL_KEYDOWNMASK|SDL_KEYUPMASK);
	while ( ! done ) {
		found = SDL_PeepEvents(events, 10, SDL_GETEVENT, mask);
		for ( i=0; i<found; ++i ) {
			switch(events[i].type) {
			    /* We want to toggle visibility on buttonpress */
			    case SDL_KEYDOWN:
			    case SDL_KEYUP:
			    	/* Allow hitting <ESC> to quit the app */
			    	if ( events[i].key.keysym.sym == SDLK_ESCAPE ) {
			    		done = 1;
			    	}
			    	printf("Key '%c' has been %s\n",
						events[i].key.keysym.unicode,
					(events[i].key.state == SDL_PRESSED) ?
						"pressed" : "released");
			    	break;
			}
		}
		/* Give up some CPU to allow events to arrive */
		SDL_Delay(20);
	}
	return(0);
}

int main(int argc, char *argv[])
{
	SDL_Surface *screen;
	SDL_Surface *icon;
	Uint8 *icon_mask;
	int i, parsed;
	Uint8 *buffer;
	SDL_Color palette[256];
	Uint32 init_flags;
	Uint8  video_bpp;
	Uint32 video_flags;
	SDL_Thread *mouse_thread;
	SDL_Thread *keybd_thread;

	/* Set the options, based on command line arguments */
	init_flags = SDL_INIT_VIDEO;
	video_bpp = 8;
	video_flags = SDL_SWSURFACE;
	parsed = 1;
	while ( parsed ) {
		/* If the threaded option is enabled, and the SDL library hasn't
		   been compiled with threaded events enabled, then the mouse and
		   keyboard won't respond.
		 */
		if ( (argc >= 2) && (strcmp(argv[1], "-threaded") == 0) ) {
			init_flags |= SDL_INIT_EVENTTHREAD;
			argc -= 1;
			argv += 1;
			printf("Running with threaded events\n");
		} else
		if ( (argc >= 2) && (strcmp(argv[1], "-fullscreen") == 0) ) {
			video_flags |= SDL_FULLSCREEN;
			argc -= 1;
			argv += 1;
		} else
		if ( (argc >= 3) && (strcmp(argv[1], "-bpp") == 0) ) {
			video_bpp = atoi(argv[2]);
			argc -= 2;
			argv += 2;
		} else {
			parsed = 0;
		}
	}

	/* Initialize SDL with the requested flags */
	if ( SDL_Init(init_flags) < 0 ) {
		fprintf(stderr,
			"Couldn't initialize SDL: %s\n", SDL_GetError());
		exit(1);
	}
	atexit(SDL_Quit);

	/* Set the icon -- this must be done before the first mode set */
	icon = LoadIconSurface("icon.bmp", &icon_mask);
	if ( icon != NULL ) {
		SDL_WM_SetIcon(icon, icon_mask);
	}
	if ( icon_mask != NULL )
		free(icon_mask);

	/* Initialize the display */
	screen = SDL_SetVideoMode(640, 480, video_bpp, video_flags);
	if (  screen == NULL ) {
		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",
						video_bpp, SDL_GetError());
		exit(1);
	}
	printf("Running in %s mode\n", screen->flags & SDL_FULLSCREEN ?
						"fullscreen" : "windowed");

	/* Enable printable characters */
	SDL_EnableUNICODE(1);

	/* Set an event filter that discards everything but QUIT */
	SDL_SetEventFilter(FilterEvents);

	/* Create the event handling threads */
	mouse_thread = SDL_CreateThread(HandleMouse, NULL);
	keybd_thread = SDL_CreateThread(HandleKeyboard, NULL);

	/* Set the surface pixels and refresh! */
	for ( i=0; i<256; ++i ) {
		palette[i].r = 255-i;
		palette[i].g = 255-i;
		palette[i].b = 255-i;
	}
	SDL_SetColors(screen, palette, 0, 256);
	if ( SDL_LockSurface(screen) < 0 ) {
		fprintf(stderr, "Couldn't lock display surface: %s\n",
							SDL_GetError());
		exit(2);
	}
	buffer = (Uint8 *)screen->pixels;
	for ( i=0; i<screen->h; ++i ) {
		memset(buffer,(i*255)/screen->h,
				screen->w*screen->format->BytesPerPixel);
		buffer += screen->pitch;
	}
	SDL_UnlockSurface(screen);
	SDL_UpdateRect(screen, 0, 0, 0, 0);

	/* Loop, waiting for QUIT */
	while ( ! done ) {
		if ( ! (init_flags & SDL_INIT_EVENTTHREAD) ) {
			SDL_PumpEvents(); /* Needed when event thread is off */
		}
		if ( SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_QUITMASK) ) {
			done = 1;
		}
		/* Give up some CPU so the events can accumulate */
		SDL_Delay(20);
	}
	SDL_WaitThread(mouse_thread, NULL);
	SDL_WaitThread(keybd_thread, NULL);
	return(0);
}
