Newer
Older
#if (defined(__MACH__) && defined(__APPLE__))
#include <Carbon/Carbon.h>
#define USE_PASTEBOARD
#include "pasteboard.h"
#include <stdarg.h>
#include <stdio.h> /* NULL */
#include <string.h>
#include "gen_defs.h"
#include "genwrap.h"
#include "dirwrap.h"
#include "xpbeep.h"
#ifdef __unix__
#include <xp_dl.h>
#endif
#if (defined CIOLIB_IMPORTS)
#undef CIOLIB_IMPORTS
#endif
#if (defined CIOLIB_EXPORTS)
#undef CIOLIB_EXPORTS
#endif
#include "ciolib.h"
#include "vidmodes.h"
#include "SDL.h"
int bitmap_width,bitmap_height;
/* 256 bytes so I can cheat */
unsigned char sdl_keybuf[256]; /* Keyboard buffer */
unsigned char sdl_key=0; /* Index into keybuf for next key in buffer */
unsigned char sdl_keynext=0; /* Index into keybuf for next free position */
SDL_mutex *win_mutex;
SDL_mutex *newrect_mutex;
SDL_mutex *bitmap_init_mutex;
static int bitmap_initialized = 0;
/* *nix copy/paste stuff */
SDL_sem *sdl_pastebuf_set;
SDL_sem *sdl_pastebuf_copied;
SDL_mutex *sdl_copybuf_mutex;
char *sdl_copybuf=NULL;
char *sdl_pastebuf=NULL;
SDL_sem *sdl_ufunc_ret;
SDL_sem *sdl_ufunc_rec;
SDL_mutex *sdl_ufunc_mtx;
SDL_sem *sdl_flush_sem;
int pending_updates=0;
int sdl_init_good=0;
SDL_mutex *sdl_keylock;
SDL_sem *sdl_key_pending;
static unsigned int sdl_pending_mousekeys=0;
static SDL_Color *sdl_co = NULL;
static Uint32 *sdl_dac_default = NULL;
static size_t sdl_dac_defaultsz = 0;
static struct video_stats cvstat;
struct yuv_settings {
int enabled;
int win_width;
int win_height;
Uint8 (*colours)[3];
size_t colourssz;
static struct yuv_settings yuv={0,0,0,0,0,0,0,NULL, NULL, 0};
struct sdl_keyvals {
int keysym
,key
,shift
,ctrl
,alt;
};
struct update_rect {
int x;
int y;
int width;
int height;
struct sdl_palette {
uint32_t index;
uint8_t r;
uint8_t g;
uint8_t b;
};
enum {
SDL_USEREVENT_UPDATERECT
,SDL_USEREVENT_SETTITLE
,SDL_USEREVENT_SETNAME
,SDL_USEREVENT_SETVIDMODE
,SDL_USEREVENT_SHOWMOUSE
,SDL_USEREVENT_HIDEMOUSE
,SDL_USEREVENT_COPY
,SDL_USEREVENT_PASTE
};
const struct sdl_keyvals sdl_keyval[] =
{
{SDLK_BACKSPACE, 0x08, 0x08, 0x7f, 0x0e00},
{SDLK_TAB, 0x09, 0x0f00, 0x9400, 0xa500},
{SDLK_RETURN, 0x0d, 0x0d, 0x0a, 0xa600},
{SDLK_ESCAPE, 0x1b, 0x1b, 0x1b, 0x0100},
{SDLK_SPACE, 0x20, 0x20, 0x0300, 0x20},
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
{SDLK_0, '0', ')', 0, 0x8100},
{SDLK_1, '1', '!', 0, 0x7800},
{SDLK_2, '2', '@', 0x0300, 0x7900},
{SDLK_3, '3', '#', 0, 0x7a00},
{SDLK_4, '4', '$', 0, 0x7b00},
{SDLK_5, '5', '%', 0, 0x7c00},
{SDLK_6, '6', '^', 0x1e, 0x7d00},
{SDLK_7, '7', '&', 0, 0x7e00},
{SDLK_8, '8', '*', 0, 0x7f00},
{SDLK_9, '9', '(', 0, 0x8000},
{SDLK_a, 'a', 'A', 0x01, 0x1e00},
{SDLK_b, 'b', 'B', 0x02, 0x3000},
{SDLK_c, 'c', 'C', 0x03, 0x2e00},
{SDLK_d, 'd', 'D', 0x04, 0x2000},
{SDLK_e, 'e', 'E', 0x05, 0x1200},
{SDLK_f, 'f', 'F', 0x06, 0x2100},
{SDLK_g, 'g', 'G', 0x07, 0x2200},
{SDLK_h, 'h', 'H', 0x08, 0x2300},
{SDLK_i, 'i', 'I', 0x09, 0x1700},
{SDLK_j, 'j', 'J', 0x0a, 0x2400},
{SDLK_k, 'k', 'K', 0x0b, 0x2500},
{SDLK_l, 'l', 'L', 0x0c, 0x2600},
{SDLK_m, 'm', 'M', 0x0d, 0x3200},
{SDLK_n, 'n', 'N', 0x0e, 0x3100},
{SDLK_o, 'o', 'O', 0x0f, 0x1800},
{SDLK_p, 'p', 'P', 0x10, 0x1900},
{SDLK_q, 'q', 'Q', 0x11, 0x1000},
{SDLK_r, 'r', 'R', 0x12, 0x1300},
{SDLK_s, 's', 'S', 0x13, 0x1f00},
{SDLK_t, 't', 'T', 0x14, 0x1400},
{SDLK_u, 'u', 'U', 0x15, 0x1600},
{SDLK_v, 'v', 'V', 0x16, 0x2f00},
{SDLK_w, 'w', 'W', 0x17, 0x1100},
{SDLK_x, 'x', 'X', 0x18, 0x2d00},
{SDLK_y, 'y', 'Y', 0x19, 0x1500},
{SDLK_z, 'z', 'Z', 0x1a, 0x2c00},
{SDLK_PAGEUP, 0x4900, 0x4900, 0x8400, 0x9900},
{SDLK_PAGEDOWN, 0x5100, 0x5100, 0x7600, 0xa100},
{SDLK_END, 0x4f00, 0x4f00, 0x7500, 0x9f00},
{SDLK_HOME, 0x4700, 0x4700, 0x7700, 0x9700},
{SDLK_LEFT, 0x4b00, 0x4b00, 0x7300, 0x9b00},
{SDLK_UP, 0x4800, 0x4800, 0x8d00, 0x9800},
{SDLK_RIGHT, 0x4d00, 0x4d00, 0x7400, 0x9d00},
{SDLK_DOWN, 0x5000, 0x5000, 0x9100, 0xa000},
{SDLK_INSERT, 0x5200, 0x5200, 0x9200, 0xa200},
{SDLK_DELETE, 0x5300, 0x5300, 0x9300, 0xa300},
{SDLK_KP0, 0x5200, 0x5200, 0x9200, 0},
{SDLK_KP1, 0x4f00, 0x4f00, 0x7500, 0},
{SDLK_KP2, 0x5000, 0x5000, 0x9100, 0},
{SDLK_KP3, 0x5100, 0x5100, 0x7600, 0},
{SDLK_KP4, 0x4b00, 0x4b00, 0x7300, 0},
{SDLK_KP5, 0x4c00, 0x4c00, 0x8f00, 0},
{SDLK_KP6, 0x4d00, 0x4d00, 0x7400, 0},
{SDLK_KP7, 0x4700, 0x4700, 0x7700, 0},
{SDLK_KP8, 0x4800, 0x4800, 0x8d00, 0},
{SDLK_KP9, 0x4900, 0x4900, 0x8400, 0},
{SDLK_KP_MULTIPLY, '*', '*', 0x9600, 0x3700},
{SDLK_KP_PLUS, '+', '+', 0x9000, 0x4e00},
{SDLK_KP_MINUS, '-', '-', 0x8e00, 0x4a00},
{SDLK_KP_PERIOD, 0x7f, 0x7f, 0x5300, 0x9300},
{SDLK_KP_DIVIDE, '/', '/', 0x9500, 0xa400},
{SDLK_KP_ENTER, 0x0d, 0x0d, 0x0a, 0xa600},
{SDLK_F1, 0x3b00, 0x5400, 0x5e00, 0x6800},
{SDLK_F2, 0x3c00, 0x5500, 0x5f00, 0x6900},
{SDLK_F3, 0x3d00, 0x5600, 0x6000, 0x6a00},
{SDLK_F4, 0x3e00, 0x5700, 0x6100, 0x6b00},
{SDLK_F5, 0x3f00, 0x5800, 0x6200, 0x6c00},
{SDLK_F6, 0x4000, 0x5900, 0x6300, 0x6d00},
{SDLK_F7, 0x4100, 0x5a00, 0x6400, 0x6e00},
{SDLK_F8, 0x4200, 0x5b00, 0x6500, 0x6f00},
{SDLK_F9, 0x4300, 0x5c00, 0x6600, 0x7000},
{SDLK_F10, 0x4400, 0x5d00, 0x6700, 0x7100},
{SDLK_F11, 0x8500, 0x8700, 0x8900, 0x8b00},
{SDLK_F12, 0x8600, 0x8800, 0x8a00, 0x8c00},
{SDLK_BACKSLASH, '\\', '|', 0x1c, 0x2b00},
{SDLK_SLASH, '/', '?', 0, 0x3500},
{SDLK_MINUS, '-', '_', 0x1f, 0x8200},
{SDLK_EQUALS, '=', '+', 0, 0x8300},
{SDLK_LEFTBRACKET, '[', '{', 0x1b, 0x1a00},
{SDLK_RIGHTBRACKET, ']', '}', 0x1d, 0x1b00},
{SDLK_SEMICOLON, ';', ':', 0, 0x2700},
{SDLK_QUOTE, '\'', '"', 0, 0x2800},
{SDLK_COMMA, ',', '<', 0, 0x3300},
{SDLK_PERIOD, '.', '>', 0, 0x3400},
{SDLK_BACKQUOTE, '`', '~', 0, 0x2900},
{0, 0, 0, 0, 0} /** END **/
};
#if !defined(NO_X) && defined(__unix__)
#include "SDL_syswm.h"
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#define CONSOLE_CLIPBOARD XA_PRIMARY
int sdl_x11available=0;
/* X functions */
struct x11 {
int (*XFree) (void *data);
Window (*XGetSelectionOwner) (Display*, Atom);
int (*XConvertSelection) (Display*, Atom, Atom, Atom, Window, Time);
int (*XGetWindowProperty) (Display*, Window, Atom, long, long, Bool, Atom, Atom*, int*, unsigned long *, unsigned long *, unsigned char **);
int (*XChangeProperty) (Display*, Window, Atom, Atom, int, int, _Xconst unsigned char*, int);
Status (*XSendEvent) (Display*, Window, Bool, long, XEvent*);
int (*XSetSelectionOwner) (Display*, Atom, Window, Time);
};
struct x11 sdl_x11;
#endif
void RGBtoYUV(Uint8 r, Uint8 g, Uint8 b, Uint8 *yuv_array, int monochrome, int luminance)
{
if (monochrome)
{
#if 0 /* these are the two formulas that I found on the FourCC site... */
yuv_array[0] = 0.299*r + 0.587*g + 0.114*b;
yuv_array[1] = 128;
yuv_array[2] = 128;
#else
yuv_array[0] = (Uint8)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
yuv_array[1] = 128;
yuv_array[2] = 128;
#endif
}
else
{
#if 0 /* these are the two formulas that I found on the FourCC site... */
yuv_array[0] = 0.299*r + 0.587*g + 0.114*b;
yuv_array[1] = (b-yuv[0])*0.565 + 128;
yuv_array[2] = (r-yuv[0])*0.713 + 128;
#else
yuv_array[0] = (Uint8)((0.257 * r) + (0.504 * g) + (0.098 * b) + 16);
yuv_array[1] = (Uint8)(128 - (0.148 * r) - (0.291 * g) + (0.439 * b));
yuv_array[2] = (Uint8)(128 + (0.439 * r) - (0.368 * g) - (0.071 * b));
#endif
}
if (luminance!=100)
yuv_array[0]=yuv_array[0]*luminance/100;
}
void yuv_fillrect(SDL_Overlay *overlay, SDL_Rect *r, int dac_entry)
int uplane,vplane; /* Planar formats */
int y0pack, y1pack, u0pack, v0pack; /* Packed formats */
if(!overlay)
return;
if(r->x > overlay->w || r->y > overlay->h)
return;
if(r->x + r->w > overlay->w)
r->w=overlay->w-r->x;
if(r->y + r->h > overlay->h)
r->h=overlay->h-r->y;
yuv.changed=1;
switch(overlay->format) {
case SDL_IYUV_OVERLAY:
/* YUV 4:2:0 NxM Y followed by (N/2)x(M/2) U and V (12bpp) */
uplane=1;
vplane=2;
goto planar;
case SDL_YV12_OVERLAY:
/* YUV 4:2:0 NxM Y followed by (N/2)x(M/2) V and U (12bpp) */
goto planar;
case SDL_YUY2_OVERLAY:
y0pack=0;
u0pack=1;
v0pack=3;
goto packed;
case SDL_UYVY_OVERLAY:
goto packed;
case SDL_YVYU_OVERLAY:
y1pack=2;
u0pack=3;
goto packed;
}
return;
planar:
sdl.LockYUVOverlay(overlay);
Uint8 *Y,*U,*V;
int odd_line;
int uvlen=(r->w)>>1;
int uvoffset=overlay->pitches[1]*((r->y+1)>>1)+((r->x+1)>>1);
odd_line=(r->y)&1;
Y=overlay->pixels[0]+overlay->pitches[0]*(r->y)+(r->x);
U=overlay->pixels[uplane]+uvoffset;
V=overlay->pixels[vplane]+uvoffset;
for(y=0; y<r->h; y++)
{
memset(Y, yuv.colours[dac_entry][0], r->w);
Y+=overlay->pitches[0];
if(odd_line) {
U+=overlay->pitches[uplane];
V+=overlay->pitches[vplane];
}
else {
memset(U, yuv.colours[dac_entry][1], uvlen);
memset(V, yuv.colours[dac_entry][2], uvlen);
}
sdl.UnlockYUVOverlay(overlay);
return;
packed:
sdl.LockYUVOverlay(overlay);
{
int x,y;
Uint32 colour;
Uint32 *offset;
colour_array[y0pack]=yuv.colours[dac_entry][0];
colour_array[y1pack]=yuv.colours[dac_entry][0];
colour_array[u0pack]=yuv.colours[dac_entry][1];
colour_array[v0pack]=yuv.colours[dac_entry][2];
offset=(Uint32 *)(overlay->pixels[0]+overlay->pitches[0]*(r->y));
for(y=0; y<r->h; y++)
{
for(x=0; x<r->w; x+=2)
sdl.UnlockYUVOverlay(overlay);
void sdl_user_func(int func, ...)
{
va_list argptr;
ev.type=SDL_USEREVENT;
ev.user.data1=NULL;
ev.user.data2=NULL;
ev.user.code=func;
va_start(argptr, func);
sdl.mutexP(sdl_ufunc_mtx);
ev.user.data1=va_arg(argptr, void *);
if((ev.user.data2=(unsigned long *)malloc(sizeof(unsigned long)))==NULL) {
sdl.mutexV(sdl_ufunc_mtx);
*(unsigned long *)ev.user.data2=va_arg(argptr, unsigned long);
case SDL_USEREVENT_SETTITLE:
if((ev.user.data1=strdup(va_arg(argptr, char *)))==NULL) {
sdl.mutexV(sdl_ufunc_mtx);
va_end(argptr);
return;
}
break;
ev.user.data1=va_arg(argptr, struct update_rect *);
case SDL_USEREVENT_SETPALETTE:
ev.user.data1=va_arg(argptr, struct sdl_palette *);
break;
case SDL_USEREVENT_COPY:
case SDL_USEREVENT_PASTE:
case SDL_USEREVENT_SHOWMOUSE:
case SDL_USEREVENT_HIDEMOUSE:
case SDL_USEREVENT_FLUSH:
while(1) {
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
if (func != SDL_USEREVENT_UPDATERECT && func != SDL_USEREVENT_FLUSH) {
if (sdl.SemWaitTimeout(sdl_ufunc_rec, 1000) != 0)
continue;
}
break;
}
sdl.mutexV(sdl_ufunc_mtx);
va_end(argptr);
}
/* Called from main thread only */
int sdl_user_func_ret(int func, ...)
{
va_list argptr;
SDL_Event ev;
int passed=FALSE;
ev.type=SDL_USEREVENT;
ev.user.data1=NULL;
ev.user.data2=NULL;
ev.user.code=func;
va_start(argptr, func);
sdl.mutexP(sdl_ufunc_mtx);
while(1) {
switch(func) {
case SDL_USEREVENT_SETVIDMODE:
case SDL_USEREVENT_INIT:
case SDL_USEREVENT_QUIT:
while(sdl.PeepEvents(&ev, 1, SDL_ADDEVENT, 0xffffffff)!=1)
YIELD();
passed=TRUE;
break;
}
if(passed) {
/*
* This is needed for lost event detection.
* Lost events only occur on SYSWMEVENT which is what
* we need for copy/paste on X11.
* This hack can be removed for SDL2
*/
if(sdl.SemWaitTimeout(sdl_ufunc_rec, 1000)!=0)
continue;
if(sdl.SemWait(sdl_ufunc_ret)==0)
break;
}
else {
sdl_ufunc_retval=-1;
sdl.mutexV(sdl_ufunc_mtx);
va_end(argptr);
return(sdl_ufunc_retval);
}
void exit_sdl_con(void)
{
sdl_user_func_ret(SDL_USEREVENT_QUIT);
}
void sdl_copytext(const char *text, size_t buflen)
{
#if (defined(__MACH__) && defined(__APPLE__))
#if defined(USE_PASTEBOARD)
if (text && buflen)
OSX_copytext(text, buflen);
return;
#endif
#if defined(USE_SCRAP_MANAGER)
ScrapRef scrap;
if(text && buflen) {
if(!ClearCurrentScrap()) { /* purge the current contents of the scrap. */
if(!GetCurrentScrap(&scrap)) { /* obtain a reference to the current scrap. */
PutScrapFlavor(scrap, kScrapFlavorTypeText, /* kScrapFlavorMaskTranslated */ kScrapFlavorMaskNone, buflen, text); /* write the data to the scrap */
}
}
#endif
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11) {
FREE_AND_NULL(sdl_copybuf);
sdl_copybuf=(char *)malloc(buflen+1);
if(sdl_copybuf!=NULL) {
strcpy(sdl_copybuf, text);
sdl_user_func(SDL_USEREVENT_COPY,0,0,0,0);
}
FREE_AND_NULL(sdl_copybuf);
return;
}
char *sdl_getcliptext(void)
{
char *ret=NULL;
#if (defined(__MACH__) && defined(__APPLE__))
#if defined(USE_PASTEBOARD)
return OSX_getcliptext();
#endif
#if defined(USE_SCRAP_MANAGER)
ScrapRef scrap;
UInt32 fl;
Size scraplen;
if(!GetCurrentScrap(&scrap)) { /* obtain a reference to the current scrap. */
if(!GetScrapFlavorFlags(scrap, kScrapFlavorTypeText, &fl) /* && (fl & kScrapFlavorMaskTranslated) */) {
if(!GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &scraplen)) {
ret=(char *)malloc(scraplen+1);
if(ret!=NULL) {
if(GetScrapFlavorData(scrap, kScrapFlavorTypeText, &scraplen, sdl_pastebuf))
ret[scraplen]=0;
}
}
}
return ret;
#endif
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11) {
sdl_user_func(SDL_USEREVENT_PASTE,0,0,0,0);
if(sdl_pastebuf!=NULL) {
ret=(char *)malloc(strlen(sdl_pastebuf)+1);
if(ret!=NULL)
strcpy(ret,sdl_pastebuf);
}
else
ret=NULL;
sdl.SemPost(sdl_pastebuf_copied);
return(ret);
}
void sdl_drawrect(int xoffset,int yoffset,int width,int height,uint32_t *data)
rect=(struct update_rect *)malloc(sizeof(struct update_rect));
if(rect) {
rect->x=xoffset;
rect->y=yoffset;
rect->width=width;
rect->height=height;
rect->data=data;
sdl_user_func(SDL_USEREVENT_UPDATERECT, rect);
}
else
free(data);
int sdl_setpalette(uint32_t index, uint16_t r, uint16_t g, uint16_t b)
{
struct sdl_palette *pal;
if (sdl_init_good) {
pal = (struct sdl_palette *)malloc(sizeof(struct sdl_palette));
if (pal) {
pal->index = index;
pal->r = r>>8;
pal->g = g>>8;
pal->b = b>>8;
sdl_user_func(SDL_USEREVENT_SETPALETTE, pal);
sdl_user_func(SDL_USEREVENT_FLUSH);
int sdl_init_mode(int mode)
int oldcols;
pthread_rwlock_rdlock(&vstatlock);
oldcols = vstat.cols;
cvstat = vstat;
pthread_rwlock_unlock(&vstatlock);
sdl_user_func(SDL_USEREVENT_FLUSH);
/* Deal with 40 col doubling */
pthread_rwlock_wrlock(&vstatlock);
if(yuv.enabled) {
vstat.scaling=2;
}
else {
if(oldcols != vstat.cols) {
if(oldcols == 40)
vstat.scaling /= 2;
if(vstat.cols == 40)
vstat.scaling *= 2;
}
}
if(vstat.scaling < 1)
vstat.scaling = 1;
if(vstat.vmultiplier < 1)
vstat.vmultiplier = 1;
cvstat = vstat;
pthread_rwlock_unlock(&vstatlock);
sdl_user_func_ret(SDL_USEREVENT_SETVIDMODE);
return(0);
}
/* Called from main thread only (Passes Event) */
#if !defined(NO_X) && defined(__unix__)
dll_handle dl;
const char *libnames[2]={"X11", NULL};
if(init_sdl_video()) {
fprintf(stderr, "SDL Video Init Failed\n");
bitmap_init(sdl_drawrect, sdl_flush);
sdl.mutexP(bitmap_init_mutex);
bitmap_initialized=1;
sdl.mutexV(bitmap_init_mutex);
if(mode==CIOLIB_MODE_SDL_FULLSCREEN)
fullscreen=1;
yuv.enabled=1;
if(mode==CIOLIB_MODE_SDL_YUV_FULLSCREEN) {
yuv.enabled=1;
fullscreen=1;
}
#if (SDL_MAJOR_VERSION > 1) || (SDL_MINOR_VERSION > 2) || (SDL_PATCHLEVEL > 9)
if(yuv.enabled) {
if(linked->major > 1 || linked->minor > 2 || linked->patch > 9) {
yuv.screen_width=sdl.initial_videoinfo.current_w;
yuv.screen_height=sdl.initial_videoinfo.current_h;
}
if(yuv.enabled && yuv.overlay==NULL) {
fprintf(stderr, "YUV Enabled, but overlay is NULL\n");
sdl_init_good=0;
sdl_user_func_ret(SDL_USEREVENT_INIT);
if(sdl_init_good) {
cio_api.mode=fullscreen?CIOLIB_MODE_SDL_FULLSCREEN:CIOLIB_MODE_SDL;
FreeConsole();
#endif
#if !defined(NO_X) && defined(__unix__)
dl=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,7);
if(dl!=NULL) {
sdl_x11available=TRUE;
if(sdl_x11available && (sdl_x11.XFree=xp_dlsym(dl,XFree))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetSelectionOwner=xp_dlsym(dl,XGetSelectionOwner))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XConvertSelection=xp_dlsym(dl,XConvertSelection))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XGetWindowProperty=xp_dlsym(dl,XGetWindowProperty))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XChangeProperty=xp_dlsym(dl,XChangeProperty))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSendEvent=xp_dlsym(dl,XSendEvent))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
if(sdl_x11available && (sdl_x11.XSetSelectionOwner=xp_dlsym(dl,XSetSelectionOwner))==NULL) {
xp_dlclose(dl);
sdl_x11available=FALSE;
}
}
if(sdl_x11available)
sdl.EventState(SDL_SYSWMEVENT, SDL_ENABLE);
cio_api.options |= CONIO_OPT_PALETTE_SETTING | CONIO_OPT_SET_TITLE | CONIO_OPT_SET_NAME | CONIO_OPT_SET_ICON;
/* Called from main thread only */
void sdl_setscaling(int new_value)
{
if (yuv.enabled)
return;
bitmap_setscaling(new_value);
}
/* Called from main thread only */
int sdl_getscaling(void)
{
if (yuv.enabled)
return 1;
return bitmap_getscaling();
}
/* Called from main thread only */
int sdl_kbhit(void)
{
int ret;
ret=(sdl_key!=sdl_keynext);
return(ret);
}
/* Called from main thread only */
int sdl_getch(void)
{
int ch;
/* This always frees up space in keybuf for one more char */
ch=sdl_keybuf[sdl_key++];
/* If we have missed mouse keys, tack them on to the end of the buffer now */
if(sdl_pending_mousekeys) {
if(sdl_pending_mousekeys & 1) /* Odd number... second char */
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE >> 8;
else /* Even number... first char */
sdl_keybuf[sdl_keynext++]=CIO_KEY_MOUSE & 0xff;
sdl.SemPost(sdl_key_pending);
sdl_pending_mousekeys--;
}
return(ch);
}
/* Called from main thread only */
void sdl_textmode(int mode)
{
sdl_init_mode(mode);
}
/* Called from main thread only (Passes Event) */
int sdl_setname(const char *name)
{
sdl_user_func(SDL_USEREVENT_SETNAME,name);
return(0);
}
/* Called from main thread only (Passes Event) */
int sdl_seticon(const void *icon, unsigned long size)
{
sdl_user_func(SDL_USEREVENT_SETICON,icon,size);
return(0);
}
/* Called from main thread only (Passes Event) */
int sdl_settitle(const char *title)
{
sdl_user_func(SDL_USEREVENT_SETTITLE,title);
return(0);
}
int sdl_showmouse(void)
{
sdl_user_func(SDL_USEREVENT_SHOWMOUSE);
return(1);
}
int sdl_hidemouse(void)
{
sdl_user_func(SDL_USEREVENT_HIDEMOUSE);
int sdl_get_window_info(int *width, int *height, int *xpos, int *ypos)
{
sdl.mutexP(win_mutex);
if(xpos)
*xpos=-1;
if(ypos)
*ypos=-1;
sdl.mutexV(win_mutex);
return(0);
}
/* Called from events thread only */
int sdl_setup_colours(SDL_Surface *surf)
{
int i;
int ret=0;
if (sdl_dac_defaultsz < sizeof(dac_default)/sizeof(struct dac_colors)) {
Uint32 *newdd;
size_t newsz = sizeof(dac_default)/sizeof(struct dac_colors);
newdd = realloc(sdl_dac_default, newsz * sizeof(sdl_dac_default[0]));
if (newdd == NULL)
return -1;
newco = realloc(sdl_co, newsz * sizeof(sdl_co[0]));
if (newco == NULL) {
free(newdd);
return -1;
}
sdl_co = newco;
sdl_dac_default = newdd;
for(i=sdl_dac_defaultsz; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
sdl_co[i].r=dac_default[i].red;
sdl_co[i].g=dac_default[i].green;
sdl_co[i].b=dac_default[i].blue;
}
sdl.SetColors(surf, sdl_co, 0, sdl_dac_defaultsz);
for(i=0; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
sdl_dac_default[i]=sdl.MapRGB(win->format, sdl_co[i].r, sdl_co[i].g, sdl_co[i].b);
}
sdl_dac_defaultsz = newsz;
else
sdl.SetColors(surf, sdl_co, 0, sdl_dac_defaultsz);
return(ret);
}
int sdl_setup_yuv_colours(void)
{
int i;
int ret=0;
if(yuv.enabled) {
if (yuv.colourssz < sizeof(dac_default)/sizeof(struct dac_colors)) {
size_t newsz = sizeof(dac_default)/sizeof(struct dac_colors);
Uint8 (*newc)[3];
newc = realloc(yuv.colours, newsz * sizeof(yuv.colours[0]));
if (newc == NULL)
return -1;
yuv.colours = newc;
yuv.colourssz = newsz;
}
for(i=0; i<(sizeof(dac_default)/sizeof(struct dac_colors)); i++) {
RGBtoYUV(dac_default[i].red, dac_default[i].green, dac_default[i].blue, &(yuv.colours[i][0]), 0, 100);
}
}
return(ret);
}
/* Call with vstatlock held (reader or writer) */
int char_width;
int char_height;
int flags=SDL_HWSURFACE|SDL_ANYFORMAT;
SDL_Surface *tmp_rect;
SDL_Event ev;
int charwidth, charheight, cols, scaling, rows, vmultiplier;
if(fullscreen)
flags |= SDL_FULLSCREEN;
else
flags |= SDL_RESIZABLE;
sdl.mutexP(win_mutex);
charwidth = vstat.charwidth;
charheight = vstat.charheight;
cols = vstat.cols;
scaling = vstat.scaling;
rows = vstat.rows;
vmultiplier = vstat.vmultiplier;
char_width=charwidth*cols*scaling;
char_height=charheight*rows*scaling*vmultiplier;
if(yuv.enabled) {
if(!yuv.win_width)
if(fullscreen && yuv.screen_width && yuv.screen_height)
win=sdl.SetVideoMode(yuv.screen_width,yuv.screen_height,0,flags);
else
win=sdl.SetVideoMode(yuv.win_width,yuv.win_height,0,flags);
}
else
win=sdl.SetVideoMode(char_width,char_height,0,flags);
#if !defined(NO_X) && defined(__unix__)
if(sdl_x11available && sdl_using_x11) {
XEvent respond;
SDL_SysWMinfo wmi;
SDL_VERSION(&(wmi.version));
sdl.GetWMInfo(&wmi);
respond.type=ConfigureNotify;
respond.xconfigure.height = win->h;
respond.xconfigure.width = win->w;
sdl_x11.XSendEvent(wmi.info.x11.display,wmi.info.x11.window,0,0,&respond);
}
sdl.mutexP(newrect_mutex);