Newer
Older
}
}
}
free(font);
lastfg=-1;
lastbg=-1;
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];
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;
}
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;
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;
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);
sdl_setup_colours(sdl_cursor, vstat.currattr&0x07);
lastcursor_x=vstat.curs_col;
lastcursor_y=vstat.curs_row;
}
}
/* Called from event thread */
/* 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;
if(lastfg!=ch) {
co.r=dac_default256[vs->palette[ch]].red;
co.g=dac_default256[vs->palette[ch]].green;
co.b=dac_default256[vs->palette[ch]].blue;
lastfg=ch;
}
ch=(sch >> 12) & 0x07;
if(lastbg!=ch) {
co.r=dac_default256[vs->palette[ch]].red;
co.g=dac_default256[vs->palette[ch]].green;
co.b=dac_default256[vs->palette[ch]].blue;
lastbg=ch;
}
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.x=0;
src.w=vs->charwidth;
src.h=vs->charheight;
src.y=vs->charheight*vs->scaling;
ch=sch & 0xff;
if((sch >>15) && !(vs->blink))
src.y *= ' ';
else
src.y *= ch;
if(sdl_font != NULL)
}
/* 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;
struct video_stats vs;
memcpy(&vs, &vstat, sizeof(vs));
if((newvmem=(unsigned short *)malloc(vs.cols*vs.rows*sizeof(unsigned short)))==NULL)
memcpy(newvmem, vs.vmem, vs.cols*vs.rows*sizeof(unsigned short));
rects=(SDL_Rect *)malloc(sizeof(SDL_Rect)*vs.cols*vs.rows);
if(rects==NULL)
sdl_updated=1;
/* Redraw all chars */
pos=0;
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;
}
pos++;
}
}
last_blink=vs.blink;
p=last_vmem;
last_vmem=newvmem;
free(p);
sdl_draw_cursor();
if(rcount)
free(rects);
}
/* Called from event thread only */
unsigned int sdl_get_char_code(unsigned int keysym, unsigned int mod, unsigned int unicode)
{
int i;
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);
}
}
#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 */
{
struct mainparams *mp=data;
sdl_exitcode=CIOLIB_main(mp->argc, mp->argv);
ev.type=SDL_QUIT;
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1);
}
/* Mouse event/keyboard thread */
{
while(1) {
if(mouse_wait())
sdl_add_key(CIO_KEY_MOUSE);
}
}
/* Event Thread */
int main(int argc, char **argv)
{
SDL_Event ev;
struct mainparams mp;
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
}
if(sdl.VideoDriverName(drivername, sizeof(drivername))!=NULL) {
/* Unacceptable drivers */
if(!strcmp(drivername,"aalib"))
sdl.gotfuncs=FALSE;
if(!strcmp(drivername,"dummy"))
sdl.gotfuncs=FALSE;
}
if(sdl.gotfuncs) {
mp.argc=argc;
mp.argv=argv;
sdl_key_pending=sdl.SDL_CreateSemaphore(0);
sdl_init_complete=sdl.SDL_CreateSemaphore(0);
sdl_updlock=sdl.SDL_CreateMutex();
sdl_keylock=sdl.SDL_CreateMutex();
sdl_vstatlock=sdl.SDL_CreateMutex();
#if !defined(NO_X) && defined(__unix__)
sdl_pastebuf_set=sdl.SDL_CreateSemaphore(0);
sdl_pastebuf_copied=sdl.SDL_CreateSemaphore(0);
sdl_copybuf_mutex=sdl.SDL_CreateMutex();
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 */
if(ev.key.keysym.unicode=='\t' && ev.key.keysym.mod & KMOD_ALT)
/* 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);
}
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));
}
break;
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);
case SDL_MOUSEBUTTONDOWN:
if(!ciolib_mouse_initialized)
break;
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;
break;
case SDL_MOUSEBUTTONUP:
if(!ciolib_mouse_initialized)
break;
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
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) {
FREE_AND_NULL(last_vmem);
sdl.mutexP(sdl_vstatlock);
vstat.scaling=(int)(ev.resize.w/(vstat.charwidth*vstat.cols));
if(vstat.scaling < 1)
vstat.scaling=1;

deuce
committed
if(fullscreen)

deuce
committed
vstat.charwidth*vstat.cols*vstat.scaling
,vstat.charheight*vstat.rows*vstat.scaling

deuce
committed
,SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN
);
else

deuce
committed
vstat.charwidth*vstat.cols*vstat.scaling
,vstat.charheight*vstat.rows*vstat.scaling
,8
,SDL_HWSURFACE|SDL_HWPALETTE|SDL_RESIZABLE
);
if(!strcmp(driver,"Quartz"))
sdl_using_quartz=TRUE;
}
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;
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
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) {
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];
#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();
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
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;
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
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11()) {
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
sdl.GetWMInfo(&wmi);
sdl_x11.XSetSelectionOwner(wmi.info.x11.display, CONSOLE_CLIPBOARD, wmi.info.x11.window, CurrentTime);
break;
}
#endif
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);
}
sdl.SemPost(sdl_pastebuf_set);
sdl.SemWait(sdl_pastebuf_copied);
break;
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11()) {
Window sowner=None;
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
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);
}
else if(sowner!=None) {
sdl_x11.XConvertSelection(wmi.info.x11.display, CONSOLE_CLIPBOARD, XA_STRING, None, wmi.info.x11.window, CurrentTime);
FREE_AND_NULL(sdl_pastebuf);
sdl.SemPost(sdl_pastebuf_set);
sdl.SemWait(sdl_pastebuf_copied);
}
#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);
sdl.mutexV(sdl_copybuf_mutex);
break;
}
case SelectionNotify: {
int format=0;
unsigned long len, bytes_left, dummy;
Atom type;
XSelectionEvent *req;
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
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;
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
}
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;
}
}
}
}
else {