Newer
Older
case 0x00a0:
return(0xff);
}
return(0x01ffff);
}
/* Called from event thread only */
static unsigned int sdl_get_char_code(unsigned int keysym, unsigned int mod)
if(keysym==0x7f && !(mod & KMOD_CTRL)) {
keysym=0x08;
keysym=SDLK_BACKSPACE;
/*
* No Unicode translation available.
* Or there *IS* an SDL keysym.
* Or ALT (GUI) pressed
// SDL2: This needs to be replaced with... betterness.
if((keysym > SDLK_UNKNOWN) || (mod & (KMOD_GUI|KMOD_ALT))) {
/* Find the SDL keysym */
for(i=0;sdl_keyval[i].keysym;i++) {
if(sdl_keyval[i].keysym==keysym) {
/* KeySym found in table */
/*
* Using the modifiers, look up the expected scan code.
* Under windows, this is what unicode will be set to
* if the ALT key is not AltGr
*/
if(mod & KMOD_CTRL)
expect=sdl_keyval[i].ctrl;
else if(mod & KMOD_SHIFT) {
if(mod & KMOD_CAPS)
expect=sdl_keyval[i].key;
else
expect=sdl_keyval[i].shift;
}
else {
if(mod & KMOD_CAPS && (toupper(sdl_keyval[i].key) == sdl_keyval[i].shift))
expect=sdl_keyval[i].shift;
else
expect=sdl_keyval[i].key;
}
/*
* Now handle the ALT case so that expect will
* be what we expect to return
*/
if(mod & (KMOD_GUI|KMOD_ALT)) {
if(keysym==expect || keysym == 0)
return(sdl_keyval[i].alt);
/* AltGr apparently... translate unicode or give up */
return(cp437_convert(keysym));
/*
* If the keysym is a keypad one
* AND numlock is locked
* AND none of Control, Shift, ALT, or GUI are pressed
if(keysym >= SDLK_KP_0 && keysym <= SDLK_KP_EQUALS &&
(!(mod & (KMOD_CTRL|KMOD_SHIFT|KMOD_ALT|KMOD_GUI) ))) {
#if defined(_WIN32)
/*
* Apparently, Win32 SDL doesn't interpret keypad with numlock...
* and doesn't know the state of numlock either...
* So, do that here. *sigh*
*/
mod &= ~KMOD_NUM; // Ignore "current" mod state
if (GetKeyState(VK_NUMLOCK) & 1)
mod |= KMOD_NUM;
#endif
if (mod & KMOD_NUM) {
switch(keysym) {
return('0');
return('1');
return('2');
return('3');
return('4');
return('5');
return('6');
return('7');
return('8');
return('9');
case SDLK_KP_PERIOD:
return('.');
case SDLK_KP_DIVIDE:
return('/');
case SDLK_KP_MULTIPLY:
return('*');
case SDLK_KP_MINUS:
return('-');
case SDLK_KP_PLUS:
return('+');
case SDLK_KP_ENTER:
return('\r');
case SDLK_KP_EQUALS:
return('=');
}
/*
* "Extended" keys are always right since we can't compare to unicode
* This does *NOT* mean ALT-x, it means things like F1 and Print Screen
*/
if(sdl_keyval[i].key > 255) /* Extended regular key */
* If there is no unicode translation available,
* we *MUST* use our table since we have
* no other data to use. This is apparently
* never true on OS X.
* At this point, we no longer have a reason to distrust the
* unicode mapping. If we can coerce it into CP437, we will.
* If we can't, just give up.
return(cp437_convert(expect));
/*
* Well, we can't find it in our table...
* If there's a unicode character, use that if possible.
*/
if(keysym)
return(cp437_convert(keysym));
/*
* No unicode... perhaps it's ASCII?
* Most likely, this would be a strangely
* entered control character.
*
* If *any* modifier key is down though
* we're not going to trust the keysym
* value since we can't.
*/
if(keysym <= 127 && !(mod & (KMOD_GUI|KMOD_ALT|KMOD_CTRL|KMOD_SHIFT)))
return(keysym);
/* Give up. It's not working out for us. */
return(0x0001ffff);
}
/* Mouse event/keyboard thread */
while(1) {
if(mouse_wait())
sdl_add_key(CIO_KEY_MOUSE);
}
}
int ret;
ret = winpos/(cvstat.charwidth*cvstat.scaling)+1;
return ret;
int ret;
ret = winpos/(cvstat.charheight*cvstat.scaling*cvstat.vmultiplier)+1;
return ret;
{
SDL_Event ev;
int old_scaling;
char *driver;
if((driver = sdl.GetCurrentVideoDriver())!=NULL) {
if(!strcmp(driver,"directx"))
sdl_using_directx=TRUE;
sdl_using_directx=FALSE;
#endif
#if (defined(__MACH__) && defined(__APPLE__))
if(!strcmp(driver,"Quartz"))
sdl_using_quartz=TRUE;
sdl_using_quartz=FALSE;
#endif
#if !defined(NO_X) && defined(__unix__)
if(!strcmp(driver,"x11"))
sdl_using_x11=TRUE;
if(!strcmp(driver,"dga"))
sdl_using_x11=TRUE;
while(1) {
if(sdl.WaitEventTimeout(&ev, 1)!=1) {
if (new_scaling != -1 || cvstat.scaling != old_scaling) {
if (new_scaling == -1)
new_scaling = cvstat.scaling;
sdl_setscaling(new_scaling);
new_scaling = -1;
if(cvstat.scaling < 1)
sdl_setscaling(1);
setup_surfaces();
old_scaling = cvstat.scaling;
}
else {
switch (ev.type) {
case SDL_KEYDOWN: /* Keypress */
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
if ((ev.key.keysym.mod & KMOD_GUI) &&
(ev.key.keysym.sym == SDLK_LEFT ||
ev.key.keysym.sym == SDLK_RIGHT ||
ev.key.keysym.sym == SDLK_UP ||
ev.key.keysym.sym == SDLK_DOWN)) {
int w, h;
sdl.mutexP(win_mutex);
sdl.GetWindowSize(win, &w, &h);
switch(ev.key.keysym.sym) {
case SDLK_LEFT:
if (w % (cvstat.charwidth * cvstat.cols)) {
w = w - w % (cvstat.charwidth * cvstat.cols);
}
else {
w -= (cvstat.charwidth * cvstat.cols);
if (w < (cvstat.charwidth * cvstat.cols))
w = cvstat.charwidth * cvstat.cols;
}
break;
case SDLK_RIGHT:
w = (w - w % (cvstat.charwidth * cvstat.cols)) + (cvstat.charwidth * cvstat.cols);
break;
case SDLK_UP:
if (h % (cvstat.charheight * cvstat.rows * cvstat.vmultiplier)) {
h = h - h % (cvstat.charheight * cvstat.rows);
}
else {
h -= (cvstat.charheight * cvstat.rows * cvstat.vmultiplier);
if (h < (cvstat.charheight * cvstat.rows * cvstat.vmultiplier))
h = cvstat.charheight * cvstat.rows * cvstat.vmultiplier;
}
break;
case SDLK_DOWN:
h = (h - h % (cvstat.charheight * cvstat.rows * cvstat.vmultiplier)) + (cvstat.charheight * cvstat.rows * cvstat.vmultiplier);
break;
}
sdl.SetWindowSize(win, w, h);
sdl.mutexP(win_mutex);
}
else
sdl_add_key(sdl_get_char_code(ev.key.keysym.sym, ev.key.keysym.mod));
break;
case SDL_KEYUP: /* Ignored (handled in KEYDOWN event) */
break;
case SDL_MOUSEMOTION:
if(!ciolib_mouse_initialized)
ciomouse_gotevent(CIOLIB_MOUSE_MOVE,win_to_text_xpos(ev.motion.x),win_to_text_ypos(ev.motion.y));
break;
case SDL_MOUSEBUTTONDOWN:
if(!ciolib_mouse_initialized)
switch(ev.button.button) {
case SDL_BUTTON_LEFT:
ciomouse_gotevent(CIOLIB_BUTTON_PRESS(1),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
case SDL_BUTTON_MIDDLE:
ciomouse_gotevent(CIOLIB_BUTTON_PRESS(2),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
case SDL_BUTTON_RIGHT:
ciomouse_gotevent(CIOLIB_BUTTON_PRESS(3),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
}
break;
case SDL_MOUSEBUTTONUP:
if(!ciolib_mouse_initialized)
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
switch(ev.button.button) {
case SDL_BUTTON_LEFT:
ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(1),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
case SDL_BUTTON_MIDDLE:
ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(2),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
case SDL_BUTTON_RIGHT:
ciomouse_gotevent(CIOLIB_BUTTON_RELEASE(3),win_to_text_xpos(ev.button.x),win_to_text_ypos(ev.button.y));
break;
}
break;
case SDL_QUIT:
/*
* SDL2: Do we still need the reaper?
* This is what exit()s programs when the
* X is hit.
*/
if (ciolib_reaper)
exit(0);
else
sdl_add_key(CIO_KEY_QUIT);
break;
case SDL_WINDOWEVENT:
switch(ev.window.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
// SDL2: User resized window
case SDL_WINDOWEVENT_RESIZED:
{
// SDL2: Something resized window
const char *newh;
if(ev.window.data1 > 0 && ev.window.data2 > 0) {
new_scaling = (int)(ev.window.data1/(cvstat.charwidth*cvstat.cols));
}
if ((ev.window.data1 % (cvstat.charwidth * cvstat.cols)) || (ev.window.data2 % (cvstat.charheight * cvstat.rows)))
newh = "2";
else
newh = "0";
sdl.mutexP(win_mutex);
if (strcmp(newh, sdl.GetHint(SDL_HINT_RENDER_SCALE_QUALITY))) {
sdl.SetHint(SDL_HINT_RENDER_SCALE_QUALITY, newh );
sdl.DestroyTexture(texture);
texture = sdl.CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, cvstat.charwidth*cvstat.cols, cvstat.charheight*cvstat.rows);
bitmap_drv_request_pixels();
}
sdl.mutexV(win_mutex);
break;
case SDL_WINDOWEVENT_EXPOSED:
{
sdl.mutexP(win_mutex);
sdl.RenderCopy(renderer, texture, NULL, NULL);
sdl.RenderPresent(renderer);
sdl.mutexV(win_mutex);
break;
}
break;
case SDL_USEREVENT: {
struct rectlist *list;
struct rectlist *old_next;
/* Tell SDL to do various stuff... */
if (ev.user.code != SDL_USEREVENT_FLUSH)
if(sdl_x11available && sdl_using_x11)
sdl.SemPost(sdl_ufunc_rec);
switch(ev.user.code) {
case SDL_USEREVENT_QUIT:
sdl_ufunc_retval=0;
sdl.SemPost(sdl_ufunc_ret);
case SDL_USEREVENT_FLUSH:
sdl.mutexP(win_mutex);
if (win != NULL) {
sdl.mutexP(sdl_headlock);
list = update_list;
update_list = update_list_tail = NULL;
sdl.mutexV(sdl_headlock);
if (list->next == NULL) {
sdl.UpdateTexture(texture, NULL, list->data, list->rect.width * sizeof(uint32_t));
src.x = 0;
src.y = 0;
src.w = list->rect.width;
src.h = list->rect.height;
sdl.RenderCopy(renderer, texture, &src, NULL);
bitmap_drv_free_rect(list);
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
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
sdl.RenderPresent(renderer);
}
sdl.mutexV(win_mutex);
break;
case SDL_USEREVENT_SETNAME:
sdl.SetWindowTitle(win, (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.SetWindowIcon(win, sdl_icon);
free(ev.user.data2);
break;
case SDL_USEREVENT_SETTITLE:
sdl.SetWindowTitle(win, (char *)ev.user.data1);
free(ev.user.data1);
break;
case SDL_USEREVENT_SETVIDMODE:
new_scaling = -1;
old_scaling = cvstat.scaling;
setup_surfaces();
sdl_ufunc_retval=0;
sdl.SemPost(sdl_ufunc_ret);
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) {
sdl.mutexP(win_mutex);
sdl_init_good=1;
sdl.mutexV(win_mutex);
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
}
sdl_ufunc_retval=0;
sdl.SemPost(sdl_ufunc_ret);
break;
case SDL_USEREVENT_COPY:
#if !defined(NO_X) && defined(__unix__) && defined(SDL_VIDEO_DRIVER_X11)
if(sdl_x11available && sdl_using_x11) {
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
sdl.GetWindowWMInfo(win, &wmi);
sdl.EventState(SDL_SYSWMEVENT, SDL_ENABLE);
copy_needs_events = 1;
sdl_x11.XSetSelectionOwner(wmi.info.x11.display, CONSOLE_CLIPBOARD, wmi.info.x11.window, CurrentTime);
}
#endif
break;
case SDL_USEREVENT_PASTE:
#if !defined(NO_X) && defined(__unix__) && defined(SDL_VIDEO_DRIVER_X11)
if(sdl_x11available && sdl_using_x11) {
Window sowner=None;
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
sdl.GetWindowWMInfo(win, &wmi);
paste_needs_events = 1;
sdl.EventState(SDL_SYSWMEVENT, SDL_ENABLE);
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=(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);
paste_needs_events = 0;
if (!copy_needs_events)
sdl.EventState(SDL_SYSWMEVENT, SDL_DISABLE);
else if(sowner!=None) {
sdl_x11.XConvertSelection(wmi.info.x11.display, CONSOLE_CLIPBOARD, XA_STRING, XA_STRING, wmi.info.x11.window, CurrentTime);
}
else {
/* Set paste buffer */
FREE_AND_NULL(sdl_pastebuf);
sdl.SemPost(sdl_pastebuf_set);
sdl.SemWait(sdl_pastebuf_copied);
paste_needs_events = 0;
if (!copy_needs_events)
sdl.EventState(SDL_SYSWMEVENT, SDL_DISABLE);
#endif
break;
}
break;
}
case SDL_SYSWMEVENT: /* ToDo... This is where Copy/Paste needs doing */
// SDL2: There's a better way...
#if !defined(NO_X) && defined(__unix__) && defined(SDL_VIDEO_DRIVER_X11)
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
if(sdl_x11available && sdl_using_x11) {
XEvent *e;
e=&ev.syswm.msg->msg.x11.event;
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);
copy_needs_events = 0;
if (!paste_needs_events)
sdl.EventState(SDL_SYSWMEVENT, SDL_DISABLE);
break;
}
case SelectionNotify: {
int format=0;
unsigned long len, bytes_left, dummy;
Atom type;
XSelectionEvent *req;
SDL_VERSION(&(wmi.version));
sdl.GetWindowWMInfo(win, &wmi);
req=&(e->xselection);
if(req->requestor!=wmi.info.x11.window)
break;
if(req->property) {
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 {
}
else {
FREE_AND_NULL(sdl_pastebuf);
}
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
/* Set paste buffer */
sdl.SemPost(sdl_pastebuf_set);
sdl.SemWait(sdl_pastebuf_copied);
paste_needs_events = 0;
if (!copy_needs_events)
sdl.EventState(SDL_SYSWMEVENT, SDL_DISABLE);
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;
}
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;
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;
}
}
}
int sdl_initciolib(int mode)
{
if(init_sdl_video()) {
fprintf(stderr,"SDL Video Initialization Failed\n");
return(-1);
sdl_key_pending=sdl.SDL_CreateSemaphore(0);
sdl_ufunc_ret=sdl.SDL_CreateSemaphore(0);
sdl_ufunc_rec=sdl.SDL_CreateSemaphore(0);
sdl_ufunc_mtx=sdl.SDL_CreateMutex();
sdl_headlock=sdl.SDL_CreateMutex();
win_mutex=sdl.SDL_CreateMutex();
sdl_keylock=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();
#endif
return(sdl_init(mode));
}