Skip to content
Snippets Groups Projects
sdl_con.c 45 KiB
Newer Older
		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|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight*256, 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.charheight; 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);
	for(i=0; i<16; i++) {
		co[i^xor].r=dac_default256[vstat.palette[i]].red;
		co[i^xor].g=dac_default256[vstat.palette[i]].green;
		co[i^xor].b=dac_default256[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_default256[vs->palette[ch]].red;
		co.g=dac_default256[vs->palette[ch]].green;
		co.b=dac_default256[vs->palette[ch]].blue;
deuce's avatar
deuce committed
		sdl.SetColors(sdl_font, &co, 1, 1);
		co.r=dac_default256[vs->palette[ch]].red;
		co.g=dac_default256[vs->palette[ch]].green;
		co.b=dac_default256[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;
	src.h=vs->charheight;
	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);
}

/* Called from event thread only, */
int sdl_full_screen_redraw(void)
{
	static int last_blink;
	int x;
	int y;
	unsigned int pos;
	unsigned short *newvmem;
	unsigned short *p;
	SDL_Rect	*rects;
	int rcount=0;
deuce's avatar
deuce committed
	sdl.mutexP(sdl_vstatlock);
	memcpy(&vs, &vstat, sizeof(vs));
	if((newvmem=(unsigned short *)malloc(vs.cols*vs.rows*sizeof(unsigned short)))==NULL)
deuce's avatar
deuce committed
		return(-1);
	memcpy(newvmem, vs.vmem, vs.cols*vs.rows*sizeof(unsigned short));
deuce's avatar
deuce committed
	sdl.mutexV(sdl_vstatlock);
	rects=(SDL_Rect *)malloc(sizeof(SDL_Rect)*vs.cols*vs.rows);
	if(rects==NULL)
deuce's avatar
deuce committed
		return(-1);
deuce's avatar
deuce committed
	sdl.mutexP(sdl_updlock);
deuce's avatar
deuce committed
	sdl.mutexV(sdl_updlock);
	for(y=0;y<vs.rows;y++) {
		for(x=0;x<vs.cols;x++) {
			if((last_vmem==NULL)
					|| (last_vmem[pos] != newvmem[pos]) 
					|| (last_blink != vs.blink && newvmem[pos]>>15) 
					|| (lastcursor_x==x && lastcursor_y==y)
					|| (vs.curs_col==x && vs.curs_row==y)
				sdl_draw_one_char(newvmem[pos],x,y,&vs);
				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;
	p=last_vmem;
	last_vmem=newvmem;
	free(p);

	sdl_draw_cursor();
	if(rcount)
deuce's avatar
deuce committed
		sdl.UpdateRects(win,rcount,rects);
deuce's avatar
deuce committed
	return(0);
unsigned int sdl_get_char_code(unsigned int keysym, unsigned int mod, unsigned int unicode)
#ifdef __DARWIN__
	if(unicode==\x7f) {
		unicode=0x0f;
		keysym=SDLK_DELETE;
	}
#endif
	if((mod & KMOD_META|KMOD_ALT) && (mod & KMOD_CTRL) && unicode && (unicode < 256))
		return(unicode);
	for(i=0;sdl_keyval[i].keysym;i++) {
		if(sdl_keyval[i].keysym==keysym) {
			if(mod & (KMOD_META|KMOD_ALT))
				return(sdl_keyval[i].alt);
			if(mod & KMOD_CTRL)
				return(sdl_keyval[i].ctrl);
			if(mod & KMOD_SHIFT)
				return(sdl_keyval[i].shift);
			return(sdl_keyval[i].key);
		}
	}
deuce's avatar
deuce committed
#ifdef _WIN32
	if((mod & (KMOD_META|KMOD_ALT)) && (unicode=='\t'))
		return(0x01ffff);
#endif
	if(unicode  && unicode < 256)
		return(unicode);
	return(0x01ffff);
}

/* Called from events thread only */
struct mainparams {
	int	argc;
	char	**argv;
};

/* Called from events thread only */
deuce's avatar
deuce committed
int sdl_runmain(void *data)
	sdl_exitcode=CIOLIB_main(mp->argc, mp->argv);
	ev.type=SDL_QUIT;
deuce's avatar
deuce committed
	while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
deuce's avatar
deuce committed
	return(0);
/* 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);
	}
}

/* Event Thread */
int main(int argc, char **argv)
{
deuce's avatar
deuce committed
	unsigned int i;
deuce's avatar
deuce committed
	char	drivername[64];
deuce's avatar
deuce committed
#ifndef _WIN32
	load_sdl_funcs(&sdl);
#endif
deuce's avatar
deuce committed

	if(sdl.gotfuncs) {
#ifdef _WIN32
		/* Fail to windib (ie: No mouse attached) */
		if(sdl.Init(SDL_INIT_VIDEO)) {
			if(getenv("SDL_VIDEODRIVER")==NULL) {
				putenv("SDL_VIDEODRIVER=windib");
				WinExec(GetCommandLine(), SW_SHOWDEFAULT);
				exit(0);
			}
			sdl.gotfuncs=FALSE;
		}
#else
		if(sdl.Init(SDL_INIT_VIDEO))
			sdl.gotfuncs=FALSE;
#endif
	}
deuce's avatar
deuce committed
	if(sdl.VideoDriverName(drivername, sizeof(drivername))!=NULL) {
		/* Unacceptable drivers */
		if(!strcmp(drivername,"aalib"))
			sdl.gotfuncs=FALSE;
		if(!strcmp(drivername,"dummy"))
			sdl.gotfuncs=FALSE;
	}
deuce's avatar
deuce committed

deuce's avatar
deuce committed
	if(sdl.gotfuncs) {
		mp.argc=argc;
		mp.argv=argv;

		sdl_key_pending=sdl.SDL_CreateSemaphore(0);
		sdl_init_complete=sdl.SDL_CreateSemaphore(0);
		sdl_ufunc_ret=sdl.SDL_CreateSemaphore(0);
deuce's avatar
deuce committed
		sdl_updlock=sdl.SDL_CreateMutex();
		sdl_keylock=sdl.SDL_CreateMutex();
		sdl_vstatlock=sdl.SDL_CreateMutex();
		sdl_ufunc_lock=sdl.SDL_CreateMutex();
#if !defined(NO_X) && defined(__unix__)
deuce's avatar
deuce committed
		sdl_pastebuf_set=sdl.SDL_CreateSemaphore(0);
		sdl_pastebuf_copied=sdl.SDL_CreateSemaphore(0);
		sdl_copybuf_mutex=sdl.SDL_CreateMutex();
deuce's avatar
deuce committed
		sdl.CreateThread(sdl_runmain, &mp);
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 */
						if(ev.key.keysym.unicode > 0 && ev.key.keysym.unicode <= 0x7f) {		/* ASCII Key (Whoopee!) */
							/* ALT-TAB stuff doesn't work correctly inder Win32,
							 * seems ot pass a whole slew of TABs though here.
							 * Kludge-fix 'em by ignoring all ALT-TAB keystrokes
							 * that appear to be a tab */
deuce's avatar
deuce committed
							if(ev.key.keysym.unicode=='\t' && ev.key.keysym.mod & KMOD_ALT)
deuce's avatar
deuce committed
							/* Need magical handling here... 
							 * if ALT is pressed, run 'er through 
							 * sdl_get_char_code() ANYWAYS unless
							 * both right ALT and left controll are
							 * pressed in which case it may be an
							 * AltGr combo */
							if((ev.key.keysym.mod & (KMOD_RALT))==(KMOD_RALT)) {
								sdl_add_key(ev.key.keysym.unicode);
							}
							else if(ev.key.keysym.mod & (KMOD_META|KMOD_ALT)) {
								sdl_add_key(sdl_get_char_code(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode));
							}
							else {
								sdl_add_key(ev.key.keysym.unicode&0x7f);
							}
deuce's avatar
deuce committed
						else 
							if((ev.key.keysym.mod & KMOD_NUM) && ev.key.keysym.sym >= SDLK_KP0 && ev.key.keysym.sym <= SDLK_KP9) {
								sdl_add_key(ev.key.keysym.sym - SDLK_KP0 + '0');
							}
							else if((ev.key.keysym.mod & KMOD_NUM) && ev.key.keysym.sym == SDLK_KP_PERIOD) {
								sdl_add_key('.');
							}
							else {
								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:
						return(sdl_exitcode);
					case SDL_VIDEORESIZE:
						if(ev.resize.w > 0 && ev.resize.h > 0) {
deuce's avatar
deuce committed
							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
								win=sdl.SetVideoMode(
									 vstat.charwidth*vstat.cols*vstat.scaling
									,vstat.charheight*vstat.rows*vstat.scaling
deuce's avatar
deuce committed
									,8
									,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN
								);
							else
deuce's avatar
deuce committed
								win=sdl.SetVideoMode(
									 vstat.charwidth*vstat.cols*vstat.scaling
									,vstat.charheight*vstat.rows*vstat.scaling
									,8
									,SDL_HWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE
								);
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|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight, 8, 0, 0, 0, 0);
						    	/* Update font. */
						    	sdl_load_font(NULL);
						    	sdl_setup_colours(win,0);
								sdl_full_screen_redraw();
							}
							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:
						FREE_AND_NULL(last_vmem);
						sdl_full_screen_redraw();
						break;
					case SDL_USEREVENT: {
						/* Tell SDL to do various stuff... */
						switch(ev.user.code) {
								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
							case SDL_USEREVENT_UPDATERECT:
								sdl_full_screen_redraw();
								break;
							case SDL_USEREVENT_SETNAME:
								sdl.WM_SetCaption((char *)ev.user.data1,(char *)ev.user.data1);
								free(ev.user.data1);
								break;
							case SDL_USEREVENT_SETTITLE:
								sdl.WM_SetCaption((char *)ev.user.data1,NULL);
								free(ev.user.data1);
								break;
							case SDL_USEREVENT_SETVIDMODE:
								FREE_AND_NULL(last_vmem);
								sdl.mutexP(sdl_vstatlock);
								if(fullscreen)
									win=sdl.SetVideoMode(
										 vstat.charwidth*vstat.cols*vstat.scaling
										,vstat.charheight*vstat.rows*vstat.scaling
										,8
										,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN
									);
								else
									win=sdl.SetVideoMode(
										 vstat.charwidth*vstat.cols*vstat.scaling
										,vstat.charheight*vstat.rows*vstat.scaling
										,8
										,SDL_HWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE
									);
								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|SDL_SRCCOLORKEY, vstat.charwidth, vstat.charheight, 8, 0, 0, 0, 0);
									/* Update font. */
									sdl_load_font(NULL);
									sdl_full_screen_redraw();
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);

											sdl.CreateThread(sdl_blinker_thread, NULL);
											sdl.CreateThread(sdl_mouse_thread, NULL);
											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) {
											FREE_AND_NULL(sdl_pastebuf);
										}
										else
											sdl_pastebuf=(unsigned char *)malloc(strlen(sdl_copybuf)+1);
										if(sdl_pastebuf!=NULL)
											strcpy(sdl_pastebuf,sdl_copybuf);
										/* Set paste buffer */
										sdl.SemPost(sdl_pastebuf_set);
										sdl.SemWait(sdl_pastebuf_copied);
										FREE_AND_NULL(sdl_pastebuf);
									}
deuce's avatar
deuce committed
									else if(sowner!=None) {
										sdl_x11.XConvertSelection(wmi.info.x11.display, CONSOLE_CLIPBOARD, XA_STRING, None, wmi.info.x11.window, CurrentTime);
deuce's avatar
deuce committed
										/* Set paste buffer */
										FREE_AND_NULL(sdl_pastebuf);
deuce's avatar
deuce committed
										sdl.SemPost(sdl_pastebuf_set);
										sdl.SemWait(sdl_pastebuf_copied);
deuce's avatar
deuce committed
								}
	#else
								break;
	#endif
						}
						break;
					}
					case SDL_SYSWMEVENT:			/* ToDo... This is where Copy/Paste needs doing */
	#if !defined(NO_X) && defined(__unix__)
						if(sdl_x11available && sdl_using_x11()) {
							XEvent *e;
							e=&ev.syswm.msg->event.xevent;
							switch(e->type) {
								case SelectionClear: {
										XSelectionClearEvent *req;

										req=&(e->xselectionclear);
										sdl.mutexP(sdl_copybuf_mutex);
										if(req->selection==CONSOLE_CLIPBOARD) {
											FREE_AND_NULL(sdl_copybuf);
deuce's avatar
deuce committed
										sdl.mutexV(sdl_copybuf_mutex);
										break;
								}
								case SelectionNotify: {
										int format=0;
										unsigned long len, bytes_left, dummy;
										Atom type;
										XSelectionEvent *req;
										SDL_SysWMinfo	wmi;

deuce's avatar
deuce committed
										sdl.GetWMInfo(&wmi);
										req=&(e->xselection);
										if(req->requestor!=wmi.info.x11.window)
											break;
										sdl_x11.XGetWindowProperty(wmi.info.x11.display, wmi.info.x11.window, req->property, 0, 0, 0, AnyPropertyType, &type, &format, &len, &bytes_left, (unsigned char **)(&sdl_pastebuf));
										if(bytes_left > 0 && format==8)
											sdl_x11.XGetWindowProperty(wmi.info.x11.display, wmi.info.x11.window, req->property,0,bytes_left,0,AnyPropertyType,&type,&format,&len,&dummy,(unsigned char **)&sdl_pastebuf);
										else {
											FREE_AND_NULL(sdl_pastebuf);
										}

										/* Set paste buffer */
										sdl.SemPost(sdl_pastebuf_set);
										sdl.SemWait(sdl_pastebuf_copied);
										if(sdl_pastebuf!=NULL) {
											sdl_x11.XFree(sdl_pastebuf);
											sdl_pastebuf=NULL;
										}
										break;
								}
								case SelectionRequest: {
										XSelectionRequestEvent *req;
										XEvent respond;

										req=&(e->xselectionrequest);
										sdl.mutexP(sdl_copybuf_mutex);
										if(sdl_copybuf==NULL) {
											respond.xselection.property=None;
deuce's avatar
deuce committed
										}
										else {
											if(req->target==XA_STRING) {
												sdl_x11.XChangeProperty(req->display, req->requestor, req->property, XA_STRING, 8, PropModeReplace, (unsigned char *)sdl_copybuf, strlen(sdl_copybuf));
												respond.xselection.property=req->property;
											}
											else
												respond.xselection.property=None;
										}
										sdl.mutexV(sdl_copybuf_mutex);
										respond.xselection.type=SelectionNotify;
										respond.xselection.display=req->display;
										respond.xselection.requestor=req->requestor;
										respond.xselection.selection=req->selection;
										respond.xselection.target=req->target;
										respond.xselection.time=req->time;
										sdl_x11.XSendEvent(req->display,req->requestor,0,0,&respond);
										break;
								}
							}	/* switch */
						}	/* usingx11 */
	#endif				

					/* Ignore this stuff */
					case SDL_JOYAXISMOTION:
					case SDL_JOYBALLMOTION:
					case SDL_JOYHATMOTION:
					case SDL_JOYBUTTONDOWN:
					case SDL_JOYBUTTONUP:
					default:
						break;
				}
deuce's avatar
deuce committed
		return(CIOLIB_main(argc, argv));