src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 13 Jun 2007 08:00:10 +0000
branchSDL-1.2
changeset 3958 85b6fb6a5e3c
parent 3957 b1d5b56aa549
child 3978 b966761fef6c
permissions -rw-r--r--
Actually, this is a better fix...clear the error state once if everything we
need loaded; it's more efficient, and works even if the last unnecessary
xrandr symbol failed to load. Otherwise, leave the original loadso error, so
the end user can find out what symbol failed.
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@1589
    24
#define DEBUG_DYNAMIC_X11 0
icculus@1168
    25
icculus@1168
    26
#include "SDL_x11dyn.h"
icculus@1168
    27
icculus@1589
    28
#if DEBUG_DYNAMIC_X11
icculus@1168
    29
#include <stdio.h>
icculus@1168
    30
#endif
icculus@1168
    31
slouken@1361
    32
#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1593
    33
icculus@1168
    34
#include "SDL_name.h"
icculus@1168
    35
#include "SDL_loadso.h"
icculus@1168
    36
icculus@1575
    37
typedef struct
icculus@1168
    38
{
icculus@1575
    39
    void *lib;
icculus@1575
    40
    const char *libname;
icculus@1593
    41
} x11dynlib;
icculus@1593
    42
icculus@1593
    43
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1593
    44
#define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
icculus@1593
    45
#endif
icculus@1593
    46
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
icculus@1593
    47
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
icculus@1593
    48
#endif
icculus@1593
    49
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
icculus@1593
    50
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
icculus@1593
    51
#endif
icculus@1593
    52
#ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
icculus@1593
    53
#define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
icculus@1593
    54
#endif
icculus@1593
    55
icculus@1593
    56
static x11dynlib x11libs[] =
icculus@1593
    57
{
icculus@1593
    58
    { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC },
icculus@1593
    59
    { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT },
icculus@1593
    60
    { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER },
icculus@1593
    61
    { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR },
icculus@1593
    62
};
icculus@1575
    63
slouken@1842
    64
static void X11_GetSym(const char *fnname, int *rc, void **fn)
icculus@1575
    65
{
icculus@1575
    66
	int i;
icculus@1593
    67
	for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
icculus@1593
    68
		if (x11libs[i].lib != NULL)
icculus@1575
    69
		{
slouken@1842
    70
			*fn = SDL_LoadFunction(x11libs[i].lib, fnname);
slouken@1842
    71
			if (*fn != NULL)
icculus@1575
    72
				break;
icculus@1168
    73
		}
icculus@1168
    74
	}
icculus@1168
    75
icculus@1575
    76
	#if DEBUG_DYNAMIC_X11
slouken@1842
    77
	if (*fn != NULL)
slouken@1842
    78
		printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn);
icculus@1575
    79
	else
icculus@1575
    80
		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
icculus@1575
    81
	#endif
icculus@1575
    82
slouken@1842
    83
	if (*fn == NULL)
icculus@1575
    84
		*rc = 0;  /* kill this module. */
icculus@1168
    85
}
icculus@1575
    86
icculus@1575
    87
icculus@1575
    88
/* Define all the function pointers and wrappers... */
icculus@1575
    89
#define SDL_X11_MODULE(modname)
icculus@1575
    90
#define SDL_X11_SYM(rc,fn,params,args,ret) \
icculus@1575
    91
	static rc (*p##fn) params = NULL; \
icculus@1575
    92
	rc fn params { ret p##fn args ; }
icculus@1575
    93
#include "SDL_x11sym.h"
icculus@1575
    94
#undef SDL_X11_MODULE
icculus@1575
    95
#undef SDL_X11_SYM
slouken@1361
    96
#endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
icculus@1168
    97
icculus@1575
    98
/* Annoying varargs entry point... */
icculus@1575
    99
#ifdef X_HAVE_UTF8_STRING
icculus@1575
   100
XIC (*pXCreateIC)(XIM,...) = NULL;
icculus@1575
   101
#endif
icculus@1575
   102
icculus@1575
   103
/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
icculus@1575
   104
#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
icculus@1575
   105
#define SDL_X11_SYM(rc,fn,params,args,ret)
icculus@1168
   106
#include "SDL_x11sym.h"
icculus@1575
   107
#undef SDL_X11_MODULE
icculus@1168
   108
#undef SDL_X11_SYM
icculus@1168
   109
icculus@1575
   110
icculus@1168
   111
static int x11_load_refcount = 0;
icculus@1168
   112
icculus@1168
   113
void SDL_X11_UnloadSymbols(void)
icculus@1168
   114
{
icculus@1575
   115
	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1168
   116
	/* Don't actually unload if more than one module is using the libs... */
icculus@1168
   117
	if (x11_load_refcount > 0) {
icculus@1168
   118
		if (--x11_load_refcount == 0) {
icculus@1593
   119
			int i;
icculus@1593
   120
icculus@1168
   121
			/* set all the function pointers to NULL. */
icculus@1575
   122
			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
icculus@1575
   123
			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
icculus@1168
   124
			#include "SDL_x11sym.h"
icculus@1575
   125
			#undef SDL_X11_MODULE
icculus@1168
   126
			#undef SDL_X11_SYM
icculus@1168
   127
icculus@1593
   128
			#ifdef X_HAVE_UTF8_STRING
icculus@1593
   129
			pXCreateIC = NULL;
icculus@1593
   130
			#endif
icculus@1575
   131
icculus@1593
   132
			for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
icculus@1593
   133
				if (x11libs[i].lib != NULL) {
icculus@1593
   134
					SDL_UnloadObject(x11libs[i].lib);
icculus@1593
   135
					x11libs[i].lib = NULL;
icculus@1593
   136
				}
icculus@1589
   137
			}
icculus@1168
   138
		}
icculus@1168
   139
	}
icculus@1575
   140
	#endif
icculus@1168
   141
}
icculus@1168
   142
icculus@1168
   143
/* returns non-zero if all needed symbols were loaded. */
icculus@1168
   144
int SDL_X11_LoadSymbols(void)
icculus@1168
   145
{
icculus@1575
   146
	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
icculus@1168
   147
icculus@1575
   148
	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
icculus@1575
   149
	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
icculus@1168
   150
	if (x11_load_refcount++ == 0) {
icculus@1593
   151
		int i;
icculus@1575
   152
		int *thismod = NULL;
icculus@1593
   153
		for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
icculus@1593
   154
			if (x11libs[i].libname != NULL) {
icculus@1593
   155
				x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
icculus@1593
   156
			}
icculus@1593
   157
		}
icculus@1575
   158
		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
slouken@1842
   159
		#define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
icculus@1575
   160
		#include "SDL_x11sym.h"
icculus@1575
   161
		#undef SDL_X11_MODULE
icculus@1575
   162
		#undef SDL_X11_SYM
icculus@1168
   163
icculus@1575
   164
		#ifdef X_HAVE_UTF8_STRING
slouken@1842
   165
		X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8,(void **)&pXCreateIC);
icculus@1575
   166
		#endif
icculus@1168
   167
icculus@3958
   168
		if (SDL_X11_HAVE_BASEXLIB) {  /* all required symbols loaded. */
icculus@3958
   169
			SDL_ClearError();
icculus@3958
   170
		} else {
icculus@1575
   171
			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
icculus@1610
   172
			rc = 0;
icculus@1575
   173
		}
icculus@1575
   174
	}
icculus@1575
   175
	#else
icculus@1874
   176
		#if DEBUG_DYNAMIC_X11
icculus@1874
   177
		printf("X11: No dynamic X11 support in this build of SDL.\n");
icculus@1874
   178
		#endif
icculus@1575
   179
		#ifdef X_HAVE_UTF8_STRING
icculus@1575
   180
		pXCreateIC = XCreateIC;
icculus@1168
   181
		#endif
icculus@1575
   182
	#endif
icculus@1168
   183
icculus@1168
   184
	return rc;
icculus@1168
   185
}
icculus@1168
   186
icculus@1168
   187
/* end of SDL_x11dyn.c ... */
icculus@1168
   188