src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 22 Mar 2006 05:00:59 +0000
changeset 1575 3ba88cb7eb1b
parent 1402 d910939febfa
child 1587 7fd9fc1f2be5
permissions -rw-r--r--
Updated dynamic X11 code. See details in Bugzilla #170.
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
*/
slouken@1402
    22
#include "SDL_config.h"
icculus@1168
    23
icculus@1575
    24
#if 1
icculus@1235
    25
#define DEBUG_DYNAMIC_X11 1
icculus@1235
    26
#endif
icculus@1168
    27
icculus@1168
    28
#include "SDL_x11dyn.h"
icculus@1168
    29
icculus@1168
    30
#ifdef DEBUG_DYNAMIC_X11
icculus@1168
    31
#include <stdio.h>
icculus@1168
    32
#endif
icculus@1168
    33
slouken@1361
    34
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1168
    35
#include <dlfcn.h>
icculus@1168
    36
#include "SDL_name.h"
icculus@1168
    37
#include "SDL_loadso.h"
slouken@1361
    38
static const char *x11_library = SDL_VIDEO_DRIVER_X11_DYNAMIC;
icculus@1168
    39
static void *x11_handle = NULL;
slouken@1361
    40
static const char *x11ext_library = SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT;
icculus@1168
    41
static void *x11ext_handle = NULL;
icculus@1168
    42
icculus@1575
    43
typedef struct
icculus@1168
    44
{
icculus@1575
    45
    void *lib;
icculus@1575
    46
    const char *libname;
icculus@1575
    47
} x11libitem;
icculus@1575
    48
icculus@1575
    49
static void *X11_GetSym(const char *fnname, int *rc)
icculus@1575
    50
{
icculus@1575
    51
	int i;
icculus@1168
    52
	void *fn = NULL;
icculus@1575
    53
	const x11libitem libs[] =
icculus@1575
    54
	{
icculus@1575
    55
		{ x11_handle, "libX11" },
icculus@1575
    56
		{ x11ext_handle, "libX11ext" },
icculus@1575
    57
	};
icculus@1168
    58
icculus@1575
    59
	for (i = 0; i < (sizeof (libs) / sizeof (libs[0])); i++)
icculus@1575
    60
	{
icculus@1575
    61
		if (libs[i].lib != NULL)
icculus@1575
    62
		{
icculus@1575
    63
			fn = SDL_LoadFunction(libs[i].lib, fnname);
icculus@1168
    64
			if (fn != NULL)
icculus@1575
    65
				break;
icculus@1168
    66
		}
icculus@1168
    67
	}
icculus@1168
    68
icculus@1575
    69
	#if DEBUG_DYNAMIC_X11
icculus@1575
    70
	if (fn != NULL)
icculus@1575
    71
	    printf("X11: Found '%s' in %s (%p)\n", fnname, libs[i].libname, fn);
icculus@1575
    72
	else
icculus@1575
    73
		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
icculus@1575
    74
	#endif
icculus@1575
    75
icculus@1575
    76
	if (fn == NULL)
icculus@1575
    77
		*rc = 0;  /* kill this module. */
icculus@1575
    78
icculus@1168
    79
	return fn;
icculus@1168
    80
}
icculus@1575
    81
icculus@1575
    82
icculus@1575
    83
/* Define all the function pointers and wrappers... */
icculus@1575
    84
#define SDL_X11_MODULE(modname)
icculus@1575
    85
#define SDL_X11_SYM(rc,fn,params,args,ret) \
icculus@1575
    86
	static rc (*p##fn) params = NULL; \
icculus@1575
    87
	rc fn params { ret p##fn args ; }
icculus@1575
    88
#include "SDL_x11sym.h"
icculus@1575
    89
#undef SDL_X11_MODULE
icculus@1575
    90
#undef SDL_X11_SYM
slouken@1361
    91
#endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
icculus@1168
    92
icculus@1575
    93
/* Annoying varargs entry point... */
icculus@1575
    94
#ifdef X_HAVE_UTF8_STRING
icculus@1575
    95
XIC (*pXCreateIC)(XIM,...) = NULL;
icculus@1575
    96
#endif
icculus@1575
    97
icculus@1575
    98
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
icculus@1575
    99
#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
icculus@1575
   100
#define SDL_X11_SYM(rc,fn,params,args,ret)
icculus@1168
   101
#include "SDL_x11sym.h"
icculus@1575
   102
#undef SDL_X11_MODULE
icculus@1168
   103
#undef SDL_X11_SYM
icculus@1168
   104
icculus@1575
   105
icculus@1168
   106
static int x11_load_refcount = 0;
icculus@1168
   107
icculus@1168
   108
void SDL_X11_UnloadSymbols(void)
icculus@1168
   109
{
icculus@1575
   110
	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1168
   111
	/* Don't actually unload if more than one module is using the libs... */
icculus@1168
   112
	if (x11_load_refcount > 0) {
icculus@1168
   113
		if (--x11_load_refcount == 0) {
icculus@1168
   114
			/* set all the function pointers to NULL. */
icculus@1575
   115
			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
icculus@1575
   116
			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
icculus@1168
   117
			#include "SDL_x11sym.h"
icculus@1575
   118
			#undef SDL_X11_MODULE
icculus@1168
   119
			#undef SDL_X11_SYM
icculus@1168
   120
icculus@1575
   121
            #ifdef X_HAVE_UTF8_STRING
icculus@1575
   122
            pXCreateIC = NULL;
icculus@1575
   123
            #endif
icculus@1575
   124
icculus@1168
   125
			if (x11_handle != NULL) {
icculus@1168
   126
				SDL_UnloadObject(x11_handle);
icculus@1168
   127
				x11_handle = NULL;
icculus@1168
   128
			}
icculus@1168
   129
			if (x11ext_handle != NULL) {
icculus@1168
   130
				SDL_UnloadObject(x11ext_handle);
icculus@1168
   131
				x11ext_handle = NULL;
icculus@1168
   132
			}
icculus@1168
   133
		}
icculus@1168
   134
	}
icculus@1575
   135
	#endif
icculus@1168
   136
}
icculus@1168
   137
icculus@1168
   138
/* returns non-zero if all needed symbols were loaded. */
icculus@1168
   139
int SDL_X11_LoadSymbols(void)
icculus@1168
   140
{
icculus@1575
   141
	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
icculus@1168
   142
icculus@1575
   143
	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1575
   144
	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
icculus@1168
   145
	if (x11_load_refcount++ == 0) {
icculus@1575
   146
		int *thismod = NULL;
icculus@1575
   147
		x11_handle = SDL_LoadObject(x11_library);
icculus@1575
   148
		x11ext_handle = SDL_LoadObject(x11ext_library);
icculus@1575
   149
		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
icculus@1575
   150
		#define SDL_X11_SYM(a,fn,x,y,z) p##fn = X11_GetSym(#fn,thismod);
icculus@1575
   151
		#include "SDL_x11sym.h"
icculus@1575
   152
		#undef SDL_X11_MODULE
icculus@1575
   153
		#undef SDL_X11_SYM
icculus@1168
   154
icculus@1575
   155
		#ifdef X_HAVE_UTF8_STRING
icculus@1575
   156
		pXCreateIC = X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8);
icculus@1575
   157
		#endif
icculus@1168
   158
icculus@1575
   159
		if (!SDL_X11_HAVE_BASEXLIB) {  /* some required symbol didn't load. */
icculus@1575
   160
			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
icculus@1575
   161
		}
icculus@1575
   162
	}
icculus@1575
   163
	#else
icculus@1575
   164
		#ifdef X_HAVE_UTF8_STRING
icculus@1575
   165
		pXCreateIC = XCreateIC;
icculus@1168
   166
		#endif
icculus@1575
   167
	#endif
icculus@1168
   168
icculus@1168
   169
	return rc;
icculus@1168
   170
}
icculus@1168
   171
icculus@1168
   172
/* end of SDL_x11dyn.c ... */
icculus@1168
   173