src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 17 Nov 2005 02:35:15 +0000
changeset 1171 f84c6f1397cd
parent 1168 045f186426e1
child 1226 d05306f0dc21
permissions -rw-r--r--
Fixed crash when dynamic X11 fails to load system Xlib libraries at runtime.
icculus@1168
     1
/*
icculus@1168
     2
    SDL - Simple DirectMedia Layer
icculus@1168
     3
    Copyright (C) 1997-2004 Sam Lantinga
icculus@1168
     4
icculus@1168
     5
    This library is free software; you can redistribute it and/or
icculus@1168
     6
    modify it under the terms of the GNU Library General Public
icculus@1168
     7
    License as published by the Free Software Foundation; either
icculus@1168
     8
    version 2 of the License, or (at your option) any later version.
icculus@1168
     9
icculus@1168
    10
    This library is distributed in the hope that it will be useful,
icculus@1168
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
icculus@1168
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
icculus@1168
    13
    Library General Public License for more details.
icculus@1168
    14
icculus@1168
    15
    You should have received a copy of the GNU Library General Public
icculus@1168
    16
    License along with this library; if not, write to the Free
icculus@1168
    17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
icculus@1168
    18
icculus@1168
    19
    Sam Lantinga
icculus@1168
    20
    slouken@libsdl.org
icculus@1168
    21
*/
icculus@1168
    22
icculus@1168
    23
/*#define DEBUG_DYNAMIC_X11 1*/
icculus@1168
    24
icculus@1168
    25
#include "SDL_x11dyn.h"
icculus@1168
    26
icculus@1168
    27
#ifdef DEBUG_DYNAMIC_X11
icculus@1168
    28
#include <stdio.h>
icculus@1168
    29
#endif
icculus@1168
    30
icculus@1168
    31
#ifdef X11_DYNAMIC
icculus@1168
    32
#include <dlfcn.h>
icculus@1168
    33
#include "SDL_name.h"
icculus@1168
    34
#include "SDL_loadso.h"
icculus@1168
    35
static const char *x11_library = X11_DYNAMIC;
icculus@1168
    36
static void *x11_handle = NULL;
icculus@1168
    37
static const char *x11ext_library = X11EXT_DYNAMIC;
icculus@1168
    38
static void *x11ext_handle = NULL;
icculus@1168
    39
icculus@1168
    40
static void *X11_GetSym(const char *fnname, int *rc)
icculus@1168
    41
{
icculus@1168
    42
	void *fn = NULL;
icculus@1168
    43
	if (*rc) {  /* haven't already failed on a previous lookup? */
icculus@1168
    44
		fn = SDL_LoadFunction(x11_handle, fnname);
icculus@1168
    45
		#if DEBUG_DYNAMIC_X11
icculus@1168
    46
		if (fn != NULL)
icculus@1168
    47
			printf("X11: Found '%s' in libX11 (%p)\n", fnname, fn);
icculus@1168
    48
		#endif
icculus@1168
    49
icculus@1168
    50
		if (fn == NULL) {  /* not found? Check libX11ext ... */
icculus@1168
    51
			fn = SDL_LoadFunction(x11ext_handle, fnname);
icculus@1168
    52
			#if DEBUG_DYNAMIC_X11
icculus@1168
    53
			if (fn != NULL)
icculus@1168
    54
				printf("X11: Found '%s' in libXext (%p)\n", fnname, fn);
icculus@1168
    55
			else
icculus@1168
    56
				printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
icculus@1168
    57
			#endif
icculus@1168
    58
		}
icculus@1168
    59
		*rc = (fn != NULL);
icculus@1168
    60
	}
icculus@1168
    61
icculus@1168
    62
	return fn;
icculus@1168
    63
}
icculus@1168
    64
#endif  /* defined X11_DYNAMIC */
icculus@1168
    65
icculus@1168
    66
/* Define all the function pointers... */
icculus@1168
    67
#define SDL_X11_SYM(ret,fn,params) ret (*p##fn) params = NULL;
icculus@1168
    68
#include "SDL_x11sym.h"
icculus@1168
    69
#undef SDL_X11_SYM
icculus@1168
    70
icculus@1168
    71
static int x11_load_refcount = 0;
icculus@1168
    72
icculus@1168
    73
void SDL_X11_UnloadSymbols(void)
icculus@1168
    74
{
icculus@1168
    75
	/* Don't actually unload if more than one module is using the libs... */
icculus@1168
    76
	if (x11_load_refcount > 0) {
icculus@1168
    77
		if (--x11_load_refcount == 0) {
icculus@1168
    78
			/* set all the function pointers to NULL. */
icculus@1168
    79
			#define SDL_X11_SYM(ret,fn,params) p##fn = NULL;
icculus@1168
    80
			#include "SDL_x11sym.h"
icculus@1168
    81
			#undef SDL_X11_SYM
icculus@1168
    82
icculus@1168
    83
			#ifdef X11_DYNAMIC
icculus@1168
    84
			if (x11_handle != NULL) {
icculus@1168
    85
				SDL_UnloadObject(x11_handle);
icculus@1168
    86
				x11_handle = NULL;
icculus@1168
    87
			}
icculus@1168
    88
			if (x11ext_handle != NULL) {
icculus@1168
    89
				SDL_UnloadObject(x11ext_handle);
icculus@1168
    90
				x11ext_handle = NULL;
icculus@1168
    91
			}
icculus@1168
    92
			#endif
icculus@1168
    93
		}
icculus@1168
    94
	}
icculus@1168
    95
}
icculus@1168
    96
icculus@1168
    97
/* returns non-zero if all needed symbols were loaded. */
icculus@1168
    98
int SDL_X11_LoadSymbols(void)
icculus@1168
    99
{
icculus@1168
   100
	int rc = 1;
icculus@1168
   101
icculus@1168
   102
    /* deal with multiple modules (dga, x11, etc) needing these symbols... */
icculus@1168
   103
	if (x11_load_refcount++ == 0) {
icculus@1168
   104
		#ifdef X11_DYNAMIC
icculus@1168
   105
			x11_handle = SDL_LoadObject(x11_library);
icculus@1168
   106
			x11ext_handle = SDL_LoadObject(x11ext_library);
icculus@1171
   107
			rc = ((x11_handle != NULL) && (x11ext_handle != NULL));
icculus@1171
   108
			#define SDL_X11_SYM(r,fn,arg) p##fn = X11_GetSym(#fn, &rc);
icculus@1171
   109
			#include "SDL_x11sym.h"
icculus@1171
   110
			#undef SDL_X11_SYM
icculus@1168
   111
icculus@1168
   112
			if (!rc)
icculus@1168
   113
				SDL_X11_UnloadSymbols();  /* in case one of these loaded... */
icculus@1168
   114
icculus@1168
   115
		#else
icculus@1168
   116
			#define SDL_X11_SYM(r,fn,arg) p##fn = fn;
icculus@1168
   117
			#include "SDL_x11sym.h"
icculus@1168
   118
			#undef SDL_X11_SYM
icculus@1168
   119
		#endif
icculus@1168
   120
	}
icculus@1168
   121
icculus@1168
   122
	return rc;
icculus@1168
   123
}
icculus@1168
   124
icculus@1168
   125
/* end of SDL_x11dyn.c ... */
icculus@1168
   126