Skip to content
Snippets Groups Projects
sdl_con.c 52 KiB
Newer Older
deuce's avatar
deuce committed
		sdl.mutexP(sdl_keylock);
		if(sdl_keynext+1==sdl_key) {
			sdl_beep();
deuce's avatar
deuce committed
			sdl.mutexV(sdl_keylock);
			return;
		}
		if((sdl_keynext+2==sdl_key) && keyval > 0xff) {
			if(keyval==CIO_KEY_MOUSE)
				sdl_pending_mousekeys++;
			else
				sdl_beep();
deuce's avatar
deuce committed
			sdl.mutexV(sdl_keylock);
			return;
		}
		sdl_keybuf[sdl_keynext++]=keyval & 0xff;
deuce's avatar
deuce committed
		sdl.SemPost(sdl_key_pending);
		if(keyval>0xff) {
			sdl_keybuf[sdl_keynext++]=keyval >> 8;
deuce's avatar
deuce committed
			sdl.SemPost(sdl_key_pending);
deuce's avatar
deuce committed
		sdl.mutexV(sdl_keylock);
	}
}

/* Called from event thread only */
int sdl_load_font(char *filename)
{
	static char current_filename[MAX_PATH];
	unsigned char *font;
	unsigned int fontsize;
	int fw;
	int fh;
	int	ch;
	int x;
	int y;
	int charrow;
	int charcol;
	SDL_Rect r;
	if(sdl_current_font==-99 || sdl_current_font>(sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)-2)) {
		for(x=0; conio_fontdata[x].desc != NULL; x++) {
			if(!strcmp(conio_fontdata[x].desc, "Codepage 437 English")) {
				sdl_current_font=x;
				break;
			}
		}
		if(conio_fontdata[x].desc==NULL)
			sdl_current_font=0;
	if(sdl_current_font==-1)
		filename=current_filename;
	else if(conio_fontdata[sdl_current_font].desc==NULL)
deuce's avatar
deuce committed
	sdl.mutexP(sdl_vstatlock);
	fh=vstat.charheight;
	fw=vstat.charwidth/8+(vstat.charwidth%8?1:0);

	fontsize=fw*fh*256*sizeof(unsigned char);

deuce's avatar
deuce committed
	if((font=(unsigned char *)malloc(fontsize))==NULL) {
deuce's avatar
deuce committed
		sdl.mutexV(sdl_vstatlock);
	if(filename != NULL) {
		if(flength(filename)!=fontsize) {
			sdl.mutexV(sdl_vstatlock);
			free(font);
			return(-1);
		}
		if((fontfile=fopen(filename,"rb"))==NULL) {
			sdl.mutexV(sdl_vstatlock);
			free(font);
			return(-1);
		}
		if(fread(font, 1, fontsize, fontfile)!=fontsize) {
deuce's avatar
deuce committed
			sdl.mutexV(sdl_vstatlock);
		}
		fclose(fontfile);
		sdl_current_font=-1;
		if(filename != current_filename)
			SAFECOPY(current_filename,filename);
	}
	else {
		switch(vstat.charwidth) {
			case 8:
				switch(vstat.charheight) {
					case 8:
						if(conio_fontdata[sdl_current_font].eight_by_eight==NULL) {
							sdl.mutexV(sdl_vstatlock);
							free(font);
							return(-1);
						}
						memcpy(font, conio_fontdata[sdl_current_font].eight_by_eight, fontsize);
						break;
					case 14:
						if(conio_fontdata[sdl_current_font].eight_by_fourteen==NULL) {
							sdl.mutexV(sdl_vstatlock);
							free(font);
							return(-1);
						}
						memcpy(font, conio_fontdata[sdl_current_font].eight_by_fourteen, fontsize);
						break;
					case 16:
						if(conio_fontdata[sdl_current_font].eight_by_sixteen==NULL) {
							sdl.mutexV(sdl_vstatlock);
							free(font);
							return(-1);
						}
						memcpy(font, conio_fontdata[sdl_current_font].eight_by_sixteen, fontsize);
						break;
					default:
						sdl.mutexV(sdl_vstatlock);
						free(font);
						return(-1);
				}
				break;
			default:
				sdl.mutexV(sdl_vstatlock);
				free(font);
				return(-1);
		}
deuce's avatar
deuce committed
		sdl.FreeSurface(sdl_font);
	sdl_font=sdl.CreateRGBSurface(SDL_SWSURFACE, vstat.charwidth*vstat.scaling, vstat.charheight*256*vstat.scaling, 8, 0, 0, 0, 0);
	if(sdl_font == NULL) {
deuce's avatar
deuce committed
		sdl.mutexV(sdl_vstatlock);
    	return(-1);
	}
	else {
		for(ch=0; ch<256; ch++) {
			for(charrow=0; charrow<vstat.charheight; charrow++) {
				for(charcol=0; charcol<vstat.charwidth; charcol++) {
					if(font[(ch*vstat.charheight+charrow)*fw+(charcol/8)] & (0x80 >> (charcol%8))) {
						r.x=charcol*vstat.scaling;
						r.y=(ch*vstat.charheight+charrow)*vstat.scaling;
						r.w=vstat.scaling;
						r.h=vstat.scaling;
deuce's avatar
deuce committed
						sdl.FillRect(sdl_font, &r, 1);
deuce's avatar
deuce committed
	sdl.mutexV(sdl_vstatlock);
    return(0);
}

/* Called from events thread only */
int sdl_setup_colours(SDL_Surface *surf, int xor)
{
	int i;
	int ret=0;
	SDL_Color	co[16];

deuce's avatar
deuce committed
	sdl.mutexP(sdl_vstatlock);
		co[i^xor].r=dac_default[vstat.palette[i]].red;
		co[i^xor].g=dac_default[vstat.palette[i]].green;
		co[i^xor].b=dac_default[vstat.palette[i]].blue;
deuce's avatar
deuce committed
	sdl.mutexV(sdl_vstatlock);
	sdl.SetColors(surf, co, 0, 16);
	return(ret);
}

/* Called from events thread only */
void sdl_draw_cursor(void)
{
	SDL_Rect	src;
	SDL_Rect	dst;
	int	x;
	int	y;

deuce's avatar
deuce committed
	sdl.mutexP(sdl_vstatlock);
	if(vstat.blink && vstat.curs_start<=vstat.curs_end) {
		dst.x=0;
		dst.y=0;
		src.x=vstat.curs_col*vstat.charwidth*vstat.scaling;
		src.y=(vstat.curs_row*vstat.charheight+vstat.curs_start)*vstat.scaling;
deuce's avatar
deuce committed
		src.w=dst.w=vstat.charwidth*vstat.scaling;
		src.h=dst.h=(vstat.curs_end-vstat.curs_start+1)*vstat.scaling;
		sdl_setup_colours(sdl_cursor, 0);
deuce's avatar
deuce committed
		sdl.BlitSurface(win, &src, sdl_cursor, &dst);
		sdl_setup_colours(sdl_cursor, vstat.currattr&0x07);
deuce's avatar
deuce committed
		sdl.BlitSurface(sdl_cursor, &dst, win, &src);
		lastcursor_x=vstat.curs_col;
		lastcursor_y=vstat.curs_row;
	}
deuce's avatar
deuce committed
	sdl.mutexV(sdl_vstatlock);
deuce's avatar
deuce committed
/* ONLY Called from sdl_full_screen_redraw() which holds the mutex... */
int sdl_draw_one_char(unsigned short sch, unsigned int x, unsigned int y, struct video_stats *vs)
{
	SDL_Color	co;
	SDL_Rect	src;
	SDL_Rect	dst;
	unsigned char	ch;

	ch=(sch >> 8) & 0x0f;
		co.r=dac_default[vs->palette[ch]].red;
		co.g=dac_default[vs->palette[ch]].green;
		co.b=dac_default[vs->palette[ch]].blue;
deuce's avatar
deuce committed
		sdl.SetColors(sdl_font, &co, 1, 1);
		co.r=dac_default[vs->palette[ch]].red;
		co.g=dac_default[vs->palette[ch]].green;
		co.b=dac_default[vs->palette[ch]].blue;
deuce's avatar
deuce committed
		sdl.SetColors(sdl_font, &co, 0, 1);
	dst.x=x*vs->charwidth*vs->scaling;
	dst.y=y*vs->charheight*vs->scaling;
	dst.w=vs->charwidth*vs->scaling;
	dst.h=vs->charheight*vs->scaling;
	src.w=vs->charwidth*vs->scaling;
	src.h=vs->charheight*vs->scaling;
	src.y=vs->charheight*vs->scaling;
	if((sch >>15) && !(vs->blink))
deuce's avatar
deuce committed
		sdl.BlitSurface(sdl_font, &src, win, &dst);
deuce's avatar
deuce committed
	return(0);
deuce's avatar
deuce committed

/* Called from event thread only, */
deuce's avatar
deuce committed
int sdl_full_screen_redraw(int force)
{
	static int last_blink;
	int x;
	int y;
	unsigned int pos;
	unsigned short *p;
	unsigned short *newvmem;
deuce's avatar
deuce committed
	static unsigned short *vmemcopies[2]={ NULL, NULL };
	static SDL_Rect	*rects=NULL;
	static int this_new=0;
	static unsigned short *last_vmem=NULL;
deuce's avatar
deuce committed
	static struct video_stats vs;
	int	redraw_cursor=0;
	int	lastlineupdated=0;
	int	lastcharupdated=0;
deuce's avatar
deuce committed
	sdl.mutexP(sdl_vstatlock);
deuce's avatar
deuce committed
	if(vs.cols!=vstat.cols || vs.rows != vstat.rows || vmemcopies[0]==NULL || vmemcopies[1]==NULL || rects==NULL) {
		FREE_AND_NULL(vmemcopies[0]);
		if((vmemcopies[0]=(unsigned short *)malloc(vstat.cols*vstat.rows*sizeof(unsigned short)))==NULL) {
			sdl.mutexV(sdl_vstatlock);
			return(-1);
		}
		FREE_AND_NULL(vmemcopies[1]);
		if((vmemcopies[1]=(unsigned short *)malloc(vstat.cols*vstat.rows*sizeof(unsigned short)))==NULL) {
			sdl.mutexV(sdl_vstatlock);
			return(-1);
		}
		FREE_AND_NULL(rects);
		if((rects=(SDL_Rect *)malloc(sizeof(SDL_Rect)*vstat.cols*vstat.rows))==NULL) {
			sdl.mutexV(sdl_vstatlock);
			return(-1);
		}
	}
	this_new = (this_new+1) % 2;
	newvmem=vmemcopies[this_new];
	memcpy(&vs, &vstat, sizeof(vs));
	memcpy(newvmem, vs.vmem, vs.cols*vs.rows*sizeof(unsigned short));
deuce's avatar
deuce committed
	sdl.mutexV(sdl_vstatlock);
	sdl.mutexP(sdl_updlock);
deuce's avatar
deuce committed
	sdl.mutexV(sdl_updlock);
deuce's avatar
deuce committed
	if(last_vmem==NULL)
		force=1;
	if(last_blink != vs.blink
			|| lastcursor_x!=vs.curs_col
			|| lastcursor_y!=vs.curs_row)
		redraw_cursor=1;
	for(y=0;y<vs.rows;y++) {
		for(x=0;x<vs.cols;x++) {
deuce's avatar
deuce committed
			if(force
					|| (last_vmem[pos] != newvmem[pos]) 
					|| (last_blink != vs.blink && newvmem[pos]>>15) 
deuce's avatar
deuce committed
					|| (redraw_cursor && ((lastcursor_x==x && lastcursor_y==y) || (vs.curs_col==x && vs.curs_row==y)))
				sdl_draw_one_char(newvmem[pos],x,y,&vs);
				if(lastcharupdated) {
					rects[rcount-1].w+=vs.charwidth*vs.scaling;
					lastcharupdated++;
				}
				else {
					rects[rcount].x=x*vs.charwidth*vs.scaling;
					rects[rcount].y=y*vs.charheight*vs.scaling;
					rects[rcount].w=vs.charwidth*vs.scaling;
					rects[rcount++].h=vs.charheight*vs.scaling;
					lastcharupdated++;
				}
deuce's avatar
deuce committed
				if(!redraw_cursor && x==vs.curs_col && y==vs.curs_row)
					redraw_cursor=1;
		if(lastcharupdated==vs.cols) {
			if(lastlineupdated) {
				rcount--;
				rects[rcount-1].h+=vs.charheight*vs.scaling;
			}
			else
				lastlineupdated=1;
		}
		else
			lastlineupdated=0;
		lastcharupdated=0;
deuce's avatar
deuce committed
	if(redraw_cursor)
		sdl_draw_cursor();
deuce's avatar
deuce committed
		sdl.UpdateRects(win,rcount,rects);
deuce's avatar
deuce committed
	return(0);
unsigned int cp437_convert(unsigned int unicode)
{
deuce's avatar
deuce committed
	if(unicode <= 0x80)
		return(unicode);
	switch(unicode) {
		case 0x00c7:
			return(0x80);
		case 0x00fc:
			return(0x81);
		case 0x00e9:
			return(0x82);
		case 0x00e2:
			return(0x83);
		case 0x00e4:
			return(0x84);
		case 0x00e0:
			return(0x85);
		case 0x00e5:
			return(0x86);
		case 0x00e7:
			return(0x87);
		case 0x00ea:
			return(0x88);
		case 0x00eb:
			return(0x89);
		case 0x00e8:
			return(0x8a);
		case 0x00ef:
			return(0x8b);
		case 0x00ee:
			return(0x8c);
		case 0x00ec:
			return(0x8d);
		case 0x00c4:
			return(0x8e);
		case 0x00c5:
			return(0x8f);
		case 0x00c9:
			return(0x90);
		case 0x00e6:
			return(0x91);
		case 0x00c6:
			return(0x92);
		case 0x00f4:
			return(0x93);
		case 0x00f6:
			return(0x94);
		case 0x00f2:
			return(0x95);
		case 0x00fb:
			return(0x96);
		case 0x00f9:
			return(0x97);
		case 0x00ff:
			return(0x98);
		case 0x00d6:
			return(0x99);
		case 0x00dc:
			return(0x9a);
		case 0x00a2:
			return(0x9b);
		case 0x00a3:
			return(0x9c);
		case 0x00a5:
			return(0x9d);
		case 0x20a7:
			return(0x9e);
		case 0x0192:
			return(0x9f);
		case 0x00e1:
			return(0xa0);
		case 0x00ed:
			return(0xa1);
		case 0x00f3:
			return(0xa2);
		case 0x00fa:
			return(0xa3);
		case 0x00f1:
			return(0xa4);
		case 0x00d1:
			return(0xa5);
		case 0x00aa:
			return(0xa6);
		case 0x00ba:
			return(0xa7);
		case 0x00bf:
			return(0xa8);
		case 0x2310:
			return(0xa9);
		case 0x00ac:
			return(0xaa);
		case 0x00bd:
			return(0xab);
		case 0x00bc:
			return(0xac);
		case 0x00a1:
			return(0xad);
		case 0x00ab:
			return(0xae);
		case 0x00bb:
			return(0xaf);
		case 0x2591:
			return(0xb0);
		case 0x2592:
			return(0xb1);
		case 0x2593:
			return(0xb2);
		case 0x2502:
			return(0xb3);
		case 0x2524:
			return(0xb4);
		case 0x2561:
			return(0xb5);
		case 0x2562:
			return(0xb6);
		case 0x2556:
			return(0xb7);
		case 0x2555:
			return(0xb8);
		case 0x2563:
			return(0xb9);
		case 0x2551:
			return(0xba);
		case 0x2557:
			return(0xbb);
		case 0x255d:
			return(0xbc);
		case 0x255c:
			return(0xbd);
		case 0x255b:
			return(0xbe);
		case 0x2510:
			return(0xbf);
		case 0x2514:
			return(0xc0);
		case 0x2534:
			return(0xc1);
		case 0x252c:
			return(0xc2);
		case 0x251c:
			return(0xc3);
		case 0x2500:
			return(0xc4);
		case 0x253c:
			return(0xc5);
		case 0x255e:
			return(0xc6);
		case 0x255f:
			return(0xc7);
		case 0x255a:
			return(0xc8);
		case 0x2554:
			return(0xc9);
		case 0x2569:
			return(0xca);
		case 0x2566:
			return(0xcb);
		case 0x2560:
			return(0xcc);
		case 0x2550:
			return(0xcd);
		case 0x256c:
			return(0xce);
		case 0x2567:
			return(0xcf);
		case 0x2568:
			return(0xd0);
		case 0x2564:
			return(0xd1);
		case 0x2565:
			return(0xd2);
		case 0x2559:
			return(0xd3);
		case 0x2558:
			return(0xd4);
		case 0x2552:
			return(0xd5);
		case 0x2553:
			return(0xd6);
		case 0x256b:
			return(0xd7);
		case 0x256a:
			return(0xd8);
		case 0x2518:
			return(0xd9);
		case 0x250c:
			return(0xda);
		case 0x2588:
			return(0xdb);
		case 0x2584:
			return(0xdc);
		case 0x258c:
			return(0xdd);
		case 0x2590:
			return(0xde);
		case 0x2580:
			return(0xdf);
		case 0x03b1:
			return(0xe0);
		case 0x00df:
			return(0xe1);
		case 0x0393:
			return(0xe2);
		case 0x03c0:
			return(0xe3);
		case 0x03a3:
			return(0xe4);
		case 0x03c3:
			return(0xe5);
		case 0x00b5:
			return(0xe6);
		case 0x03c4:
			return(0xe7);
		case 0x03a6:
			return(0xe8);
		case 0x0398:
			return(0xe9);
		case 0x03a9:
			return(0xea);
		case 0x03b4:
			return(0xeb);
		case 0x221e:
			return(0xec);
		case 0x03c6:
			return(0xed);
		case 0x03b5:
			return(0xee);
		case 0x2229:
			return(0xef);
		case 0x2261:
			return(0xf0);
		case 0x00b1:
			return(0xf1);
		case 0x2265:
			return(0xf2);
		case 0x2264:
			return(0xf3);
		case 0x2320:
			return(0xf4);
		case 0x2321:
			return(0xf5);
		case 0x00f7:
			return(0xf6);
		case 0x2248:
			return(0xf7);
		case 0x00b0:
			return(0xf8);
		case 0x2219:
			return(0xf9);
		case 0x00b7:
			return(0xfa);
		case 0x221a:
			return(0xfb);
		case 0x207f:
			return(0xfc);
		case 0x00b2:
			return(0xfd);
		case 0x25a0:
			return(0xfe);
		case 0x00a0:
			return(0xff);
	}
	return(0x01ffff);
}

/* Called from event thread only */
unsigned int sdl_get_char_code(unsigned int keysym, unsigned int mod, unsigned int unicode)
deuce's avatar
deuce committed
	int expect;
	int i;

#ifdef __DARWIN__
deuce's avatar
deuce committed
	if(unicode==0x7f) {
deuce's avatar
deuce committed
		unicode=0x08;
		keysym=SDLK_BACKSPACE;
deuce's avatar
deuce committed
	if((!unicode) || (mod & (KMOD_META|KMOD_ALT))) {
		for(i=0;sdl_keyval[i].keysym;i++) {
			if(sdl_keyval[i].keysym==keysym) {
				if(mod & KMOD_CTRL)
					expect=sdl_keyval[i].ctrl;
				else if(mod & KMOD_SHIFT)
					expect=sdl_keyval[i].shift;
				else
					expect=sdl_keyval[i].key;

				/*
				 * Apparently, Win32 SDL doesn't interpret keypad with numlock...
				 * So, do that here. *sigh*
				 */
				if(keysym >= SDLK_KP0 && keysym <= SDLK_KP_EQUALS 
						&& (mod & KMOD_NUM)
						&& (!(mod & (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_META) ))) {
					switch(keysym) {
						case SDLK_KP_PERIOD:
						case SDLK_KP_DIVIDE:
						case SDLK_KP_MULTIPLY:
						case SDLK_KP_MINUS:
						case SDLK_KP_ENTER:
						case SDLK_KP_EQUALS:
deuce's avatar
deuce committed
				/* "Extended" syms are always right */
				if(!unicode)
					return(expect);
				if(sdl_keyval[i].key > 255)
					return(expect);
				/*
				 * If we don't know that this key should
				 * return the unicode translation, then
				 * we're not right and this is prolly
				 * an AltGr sequence.
				 */
deuce's avatar
deuce committed
				if(unicode==expect)
					return(sdl_keyval[i].alt);
deuce's avatar
deuce committed
				return(0x0001ffff);
deuce's avatar
deuce committed
		return(0x0001ffff);
deuce's avatar
deuce committed
	}
	return(cp437_convert(unicode));
/* Mouse event/keyboard thread */
deuce's avatar
deuce committed
int sdl_mouse_thread(void *data)
{
	while(1) {
		if(mouse_wait())
			sdl_add_key(CIO_KEY_MOUSE);
	}
}

int sdl_video_event_thread(void *data)
deuce's avatar
deuce committed

	if(!init_sdl_video()) {
deuce's avatar
deuce committed
		while(1) {
			if(sdl.WaitEvent(&ev)==1) {
				switch (ev.type) {
					case SDL_ACTIVEEVENT:		/* Focus change */
						break;
					case SDL_KEYDOWN:			/* Keypress */
						sdl_add_key(sdl_get_char_code(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode));
deuce's avatar
deuce committed
					case SDL_KEYUP:				/* Ignored (handled in KEYDOWN event) */
deuce's avatar
deuce committed
					case SDL_MOUSEMOTION:
						if(!ciolib_mouse_initialized)
deuce's avatar
deuce committed
						sdl.mutexP(sdl_vstatlock);
						ciomouse_gotevent(CIOLIB_MOUSE_MOVE,ev.motion.x/(vstat.charwidth*vstat.scaling)+1,ev.motion.y/(vstat.charheight*vstat.scaling)+1);
						sdl.mutexV(sdl_vstatlock);
deuce's avatar
deuce committed
					case SDL_MOUSEBUTTONDOWN:
						if(!ciolib_mouse_initialized)
deuce's avatar
deuce committed
						switch(ev.button.button) {
							case SDL_BUTTON_LEFT:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_PRESS(1),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
							case SDL_BUTTON_MIDDLE:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_PRESS(2),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
							case SDL_BUTTON_RIGHT:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_PRESS(3),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
deuce's avatar
deuce committed
						break;
					case SDL_MOUSEBUTTONUP:
						if(!ciolib_mouse_initialized)
deuce's avatar
deuce committed
						switch(ev.button.button) {
							case SDL_BUTTON_LEFT:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(1),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
							case SDL_BUTTON_MIDDLE:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(2),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
							case SDL_BUTTON_RIGHT:
								sdl.mutexP(sdl_vstatlock);
								ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(3),ev.button.x/(vstat.charwidth*vstat.scaling)+1,ev.button.y/(vstat.charheight*vstat.scaling)+1);
								sdl.mutexV(sdl_vstatlock);
								break;
						}
						break;
					case SDL_QUIT:
						sdl.SemPost(sdl_exit_sem);
deuce's avatar
deuce committed
						return(sdl_exitcode);
					case SDL_VIDEORESIZE:
						if(ev.resize.w > 0 && ev.resize.h > 0) {
							sdl.mutexP(sdl_vstatlock);
							vstat.scaling=(int)(ev.resize.w/(vstat.charwidth*vstat.cols));
							if(vstat.scaling < 1)
								vstat.scaling=1;
deuce's avatar
deuce committed
							if(fullscreen) {
deuce's avatar
deuce committed
								win=sdl.SetVideoMode(
									 vstat.charwidth*vstat.cols*vstat.scaling
									,vstat.charheight*vstat.rows*vstat.scaling
deuce's avatar
deuce committed
									,8
deuce's avatar
deuce committed
									,SDL_SWSURFACE|SDL_FULLSCREEN|SDL_ANYFORMAT
deuce's avatar
deuce committed
							}
deuce's avatar
deuce committed
								win=sdl.SetVideoMode(
									 vstat.charwidth*vstat.cols*vstat.scaling
									,vstat.charheight*vstat.rows*vstat.scaling
									,8
deuce's avatar
deuce committed
									,SDL_SWSURFACE|SDL_RESIZABLE|SDL_ANYFORMAT
deuce's avatar
deuce committed
	#if (defined(__MACH__) && defined(__APPLE__))
deuce's avatar
deuce committed
								if(sdl.VideoDriverName(driver, sizeof(driver))!=NULL) {
									if(!strcmp(driver,"Quartz"))
										sdl_using_quartz=TRUE;
								}
deuce's avatar
deuce committed
	#endif

								if(sdl_cursor!=NULL)
deuce's avatar
deuce committed
									sdl.FreeSurface(sdl_cursor);
								sdl_cursor=sdl.CreateRGBSurface(SDL_SWSURFACE, vstat.charwidth*vstat.scaling, vstat.charheight*vstat.scaling, 8, 0, 0, 0, 0);
deuce's avatar
deuce committed
						    	/* Update font. */
						    	sdl_load_font(NULL);
						    	sdl_setup_colours(win,0);
deuce's avatar
deuce committed
								sdl_full_screen_redraw(TRUE);
							}
							else if(sdl_init_good) {
								ev.type=SDL_QUIT;
								sdl_exitcode=1;
deuce's avatar
deuce committed
								sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff);
deuce's avatar
deuce committed
							sdl.mutexV(sdl_vstatlock);
						}
						break;
					case SDL_VIDEOEXPOSE:
deuce's avatar
deuce committed
						sdl_full_screen_redraw(TRUE);
deuce's avatar
deuce committed
						break;
					case SDL_USEREVENT: {
						/* Tell SDL to do various stuff... */
						switch(ev.user.code) {
							case SDL_USEREVENT_QUIT:
								sdl_ufunc_retval=0;
								sdl.SemPost(sdl_ufunc_ret);
							case SDL_USEREVENT_LOADFONT:
								sdl_ufunc_retval=sdl_load_font((char *)ev.user.data1);
								FREE_AND_NULL(ev.user.data1);
								sdl.SemPost(sdl_ufunc_ret);
deuce's avatar
deuce committed
								sdl_full_screen_redraw(TRUE);
								break;
deuce's avatar
deuce committed
							case SDL_USEREVENT_UPDATERECT:
deuce's avatar
deuce committed
								sdl_full_screen_redraw(FALSE);
deuce's avatar
deuce committed
								break;
							case SDL_USEREVENT_SETNAME:
								sdl.WM_SetCaption((char *)ev.user.data1,(char *)ev.user.data1);
								free(ev.user.data1);
								break;
							case SDL_USEREVENT_SETICON:
								if(sdl_icon != NULL)
									sdl.FreeSurface(sdl_icon);
								sdl_icon=sdl.CreateRGBSurfaceFrom(ev.user.data1
										, *(unsigned long *)ev.user.data2
										, *(unsigned long *)ev.user.data2
										, 32
										, *(unsigned long *)ev.user.data2*4
										, *(DWORD *)"\377\0\0\0"
										, *(DWORD *)"\0\377\0\0"
										, *(DWORD *)"\0\0\377\0"
										, *(DWORD *)"\0\0\0\377"
								);
								sdl.WM_SetIcon(sdl_icon,NULL);
								free(ev.user.data2);
								break;
deuce's avatar
deuce committed
							case SDL_USEREVENT_SETTITLE:
								sdl.WM_SetCaption((char *)ev.user.data1,NULL);
								free(ev.user.data1);
								break;
							case SDL_USEREVENT_SETVIDMODE:
								sdl.mutexP(sdl_vstatlock);
								if(fullscreen)
									win=sdl.SetVideoMode(
										 vstat.charwidth*vstat.cols*vstat.scaling
										,vstat.charheight*vstat.rows*vstat.scaling
										,8
deuce's avatar
deuce committed
										,SDL_SWSURFACE|SDL_FULLSCREEN|SDL_ANYFORMAT
deuce's avatar
deuce committed
									);
								else
									win=sdl.SetVideoMode(
										 vstat.charwidth*vstat.cols*vstat.scaling
										,vstat.charheight*vstat.rows*vstat.scaling
										,8
deuce's avatar
deuce committed
										,SDL_SWSURFACE|SDL_RESIZABLE|SDL_ANYFORMAT
deuce's avatar
deuce committed
									);
								if(win!=NULL) {
	#if (defined(__MACH__) && defined(__APPLE__))
									char	driver[16];
deuce's avatar
deuce committed
									if(sdl.VideoDriverName(driver, sizeof(driver))!=NULL) {
deuce's avatar
deuce committed
										if(!strcmp(driver,"Quartz"))
											sdl_using_quartz=TRUE;
deuce's avatar
deuce committed
	#endif
									vstat.scaling=(int)(win->w/(vstat.charwidth*vstat.cols));
									if(vstat.scaling < 1)
										vstat.scaling=1;
									sdl_setup_colours(win,0);
									if(sdl_cursor!=NULL)
										sdl.FreeSurface(sdl_cursor);
									sdl_cursor=sdl.CreateRGBSurface(SDL_SWSURFACE, vstat.charwidth*vstat.scaling, vstat.charheight*vstat.scaling, 8, 0, 0, 0, 0);
deuce's avatar
deuce committed
									/* Update font. */
									sdl_load_font(NULL);
deuce's avatar
deuce committed
									sdl_full_screen_redraw(TRUE);
deuce's avatar
deuce committed
								else if(sdl_init_good) {
									ev.type=SDL_QUIT;
									sdl_exitcode=1;
									sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff);
								}
								free(ev.user.data1);
								free(ev.user.data2);
								sdl.mutexV(sdl_vstatlock);
								break;
							case SDL_USEREVENT_HIDEMOUSE:
								sdl.ShowCursor(SDL_DISABLE);
								break;
							case SDL_USEREVENT_SHOWMOUSE:
								sdl.ShowCursor(SDL_ENABLE);
								break;
							case SDL_USEREVENT_INIT:
								if(!sdl_init_good) {
									if(sdl.WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO) {
										if(win != NULL) {
											sdl.EnableUNICODE(1);
											sdl.EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
											blinker_thread=sdl.CreateThread(sdl_blinker_thread, NULL);
											mouse_thread=sdl.CreateThread(sdl_mouse_thread, NULL);
deuce's avatar
deuce committed
											sdl_init_good=1;
deuce's avatar
deuce committed
								sdl.SemPost(sdl_init_complete);
deuce's avatar
deuce committed
							case SDL_USEREVENT_COPY:
	#if (defined(__MACH__) && defined(__APPLE__))
								if(sdl_using_quartz) {
									ScrapRef	scrap;
									sdl.mutexP(sdl_copybuf_mutex);
									if(sdl_copybuf!=NULL) {
										if(!ClearCurrentScrap()) {		/* purge the current contents of the scrap. */
											if(!GetCurrentScrap(&scrap)) {		/* obtain a reference to the current scrap. */
												PutScrapFlavor(scrap, kScrapFlavorTypeText, kScrapFlavorMaskTranslated /* kScrapFlavorMaskNone */, strlen(sdl_copybuf), sdl_copybuf); 		/* write the data to the scrap */
											}
										}
									}
									FREE_AND_NULL(sdl_copybuf);
									sdl.mutexV(sdl_copybuf_mutex);
									break;
								}
	#endif
deuce's avatar
deuce committed
	#if !defined(NO_X) && defined(__unix__)
								if(sdl_x11available && sdl_using_x11()) {
									SDL_SysWMinfo	wmi;
deuce's avatar
deuce committed
									sdl.GetWMInfo(&wmi);
									sdl_x11.XSetSelectionOwner(wmi.info.x11.display, CONSOLE_CLIPBOARD, wmi.info.x11.window, CurrentTime);
									break;
								}
	#endif
deuce's avatar
deuce committed
							case SDL_USEREVENT_PASTE:
	#if (defined(__MACH__) && defined(__APPLE__))
								if(sdl_using_quartz) {
									ScrapRef	scrap;
									UInt32	fl;
									Size		scraplen;

									FREE_AND_NULL(sdl_pastebuf);
									if(!GetCurrentScrap(&scrap)) {		/* obtain a reference to the current scrap. */
										if(!GetScrapFlavorFlags(scrap, kScrapFlavorTypeText, &fl) && (fl & kScrapFlavorMaskTranslated)) {
											if(!GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &scraplen)) {
												sdl_pastebuf=(char *)malloc(scraplen+1);
												if(sdl_pastebuf!=NULL) {
													if(GetScrapFlavorData(scrap, kScrapFlavorTypeText, &scraplen, sdl_pastebuf)) {
														FREE_AND_NULL(sdl_pastebuf);
													}
deuce's avatar
deuce committed
									sdl.SemPost(sdl_pastebuf_set);
									sdl.SemWait(sdl_pastebuf_copied);
									break;
deuce's avatar
deuce committed
	#endif
deuce's avatar
deuce committed
	#if !defined(NO_X) && defined(__unix__)
								if(sdl_x11available && sdl_using_x11()) {
									Window sowner=None;
									SDL_SysWMinfo	wmi;
deuce's avatar
deuce committed
									sdl.GetWMInfo(&wmi);
deuce's avatar
deuce committed
									sowner=sdl_x11.XGetSelectionOwner(wmi.info.x11.display, CONSOLE_CLIPBOARD);
									if(sowner==wmi.info.x11.window) {
										/* Get your own primary selection */
										if(sdl_copybuf==NULL) {