VIDEO: Fix crash using libSDL on hosts which display using X11.

This commit is contained in:
Mark Pizzolato 2015-12-01 08:04:01 -08:00
parent 78f4d07c3d
commit b64401cbdd

View file

@ -284,6 +284,37 @@ int32 vid_width;
int32 vid_height;
t_bool vid_ready;
#if SDL_MAJOR_VERSION == 1
/*
Some platforms that use X11 display technology have libSDL
environments which need to call XInitThreads when libSDL is used
in multi-threaded programs. This routine attempts to locate
the X11 shareable library and if it is found loads it and calls
the XInitThreads routine to meet this requirement.
*/
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
#endif
static void _XInitThreads (void)
{
#ifdef HAVE_DLOPEN
static void *hLib = 0; /* handle to Library */
#define __STR_QUOTE(tok) #tok
#define __STR(tok) __STR_QUOTE(tok)
static const char* lib_name = "libX11." __STR(HAVE_DLOPEN);
typedef int (*_func)();
_func _func_ptr;
if (!hLib)
hLib = dlopen(lib_name, RTLD_NOW);
if (hLib)
_func_ptr = (_func)((size_t)dlsym(hLib, "XInitThreads"));
if (_func_ptr)
_func_ptr();
#endif
}
t_bool vid_key_state[SDLK_LAST];
SDL_Surface *vid_image; /* video buffer */
SDL_Surface *vid_window; /* window handle */
@ -322,7 +353,8 @@ user_event.type = SDL_USEREVENT;
user_event.user.code = EVENT_EXIT;
user_event.user.data1 = NULL;
user_event.user.data2 = NULL;
SDL_PushEvent (&user_event);
while (SDL_PushEvent (&user_event) < 0)
sim_os_ms_sleep (10);
return stat;
}
@ -335,6 +367,7 @@ main_argc = argc;
main_argv = argv;
#if SDL_MAJOR_VERSION == 1
_XInitThreads();
SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE);
vid_main_thread_handle = SDL_CreateThread (main_thread , NULL);
@ -373,7 +406,7 @@ while (1) {
}
else {
if (status < 0)
sim_printf ("main() - SDL_WaitEvent error: %s\n", SDL_GetError());
sim_printf ("main() - ` error: %s\n", SDL_GetError());
}
}
SDL_WaitThread (vid_main_thread_handle, &status);
@ -474,7 +507,8 @@ if (vid_active) {
user_event.user.data1 = NULL;
user_event.user.data2 = NULL;
SDL_PushEvent (&user_event);
while (SDL_PushEvent (&user_event) < 0)
sim_os_ms_sleep (10);
if (vid_thread_handle) {
SDL_WaitThread (vid_thread_handle, &status);
vid_thread_handle = NULL;
@ -545,17 +579,6 @@ return stat;
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
{
#if SDL_MAJOR_VERSION == 1
int32 i;
uint32* pixels;
sim_debug (SIM_VID_DBG_VIDEO, vid_dev, "vid_draw(%d, %d, %d, %d)\n", x, y, w, h);
pixels = (uint32 *)vid_image->pixels;
for (i = 0; i < h; i++)
memcpy (pixels + ((i + y) * vid_width) + x, buf + w*i, w*sizeof(*pixels));
#else
SDL_Event user_event;
SDL_Rect *vid_dst;
uint32 *vid_data;
@ -578,7 +601,6 @@ if (SDL_PushEvent (&user_event) < 0) {
free (vid_dst);
free (vid_data);
}
#endif
}
t_stat vid_set_cursor (t_bool visible, uint32 width, uint32 height, uint8 *data, uint8 *mask)
@ -1312,7 +1334,6 @@ SDL_WarpMouseInWindow (NULL, vid_cursor_x, vid_cursor_y);
SDL_PumpEvents ();
}
#if SDL_MAJOR_VERSION != 1
void vid_draw_region (SDL_UserEvent *event)
{
SDL_Rect *vid_dst = (SDL_Rect *)event->data1;
@ -1320,14 +1341,25 @@ uint32 *buf = (uint32 *)event->data2;
sim_debug (SIM_VID_DBG_VIDEO, vid_dev, "Draw Region Event: (%d,%d,%d,%d)\n", vid_dst->x, vid_dst->x, vid_dst->w, vid_dst->h);
#if SDL_MAJOR_VERSION == 1
if (1) {
int32 i;
uint32* pixels;
pixels = (uint32 *)vid_image->pixels;
for (i = 0; i < vid_dst->h; i++)
memcpy (pixels + ((i + vid_dst->y) * vid_width) + vid_dst->x, buf + vid_dst->w*i, vid_dst->w*sizeof(*pixels));
}
#else
if (SDL_UpdateTexture(vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)))
sim_printf ("%s: vid_draw() - SDL_UpdateTexture error: %s\n", sim_dname(vid_dev), SDL_GetError());
#endif
free (vid_dst);
free (buf);
event->data1 = NULL;
}
#endif
int vid_video_events (void)
{
@ -1634,12 +1666,10 @@ if (0) while (SDL_PeepEvents (&event, 1, SDL_GETEVENT, SD
if (event.user.code == EVENT_CLOSE) {
event.user.code = 0; /* Mark as done */
}
#if SDL_MAJOR_VERSION != 1
if (event.user.code == EVENT_DRAW) {
vid_draw_region ((SDL_UserEvent*)&event);
event.user.code = 0; /* Mark as done */
}
#endif
if (event.user.code == EVENT_SHOW) {
vid_show_video_event ();
event.user.code = 0; /* Mark as done */
@ -1684,6 +1714,7 @@ return 0;
int vid_thread (void *arg)
{
#if SDL_MAJOR_VERSION == 1
_XInitThreads();
SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE);
#else
SDL_SetHint (SDL_HINT_RENDER_DRIVER, "software");
@ -1998,7 +2029,8 @@ user_event.user.code = EVENT_SHOW;
user_event.user.data1 = NULL;
user_event.user.data2 = NULL;
#if defined (SDL_MAIN_AVAILABLE)
SDL_PushEvent (&user_event);
while (SDL_PushEvent (&user_event) < 0)
sim_os_ms_sleep (10);
#else
vid_show_video_event ();
#endif
@ -2073,7 +2105,8 @@ user_event.user.code = EVENT_SCREENSHOT;
user_event.user.data1 = NULL;
user_event.user.data2 = NULL;
#if defined (SDL_MAIN_AVAILABLE)
SDL_PushEvent (&user_event);
while (SDL_PushEvent (&user_event) < 0)
sim_os_ms_sleep (10);
#else
vid_screenshot_event ();
#endif