Home | History | Annotate | Download | only in x11
      1 /*
      2     SDL - Simple DirectMedia Layer
      3     Copyright (C) 1997-2004 Sam Lantinga
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Library General Public
      7     License as published by the Free Software Foundation; either
      8     version 2 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Library General Public License for more details.
     14 
     15     You should have received a copy of the GNU Library General Public
     16     License along with this library; if not, write to the Free
     17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     18 
     19     Sam Lantinga
     20     slouken (at) libsdl.org
     21 */
     22 #include "SDL_config.h"
     23 
     24 #define DEBUG_DYNAMIC_X11 0
     25 
     26 #include "SDL_x11dyn.h"
     27 
     28 #if DEBUG_DYNAMIC_X11
     29 #include <stdio.h>
     30 #endif
     31 
     32 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
     33 
     34 #include "SDL_name.h"
     35 #include "SDL_loadso.h"
     36 
     37 typedef struct
     38 {
     39     void *lib;
     40     const char *libname;
     41 } x11dynlib;
     42 
     43 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
     44 #define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
     45 #endif
     46 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
     47 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
     48 #endif
     49 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
     50 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
     51 #endif
     52 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
     53 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
     54 #endif
     55 
     56 static x11dynlib x11libs[] =
     57 {
     58     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC },
     59     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT },
     60     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER },
     61     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR },
     62 };
     63 
     64 static void X11_GetSym(const char *fnname, int *rc, void **fn)
     65 {
     66 	int i;
     67 	for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
     68 		if (x11libs[i].lib != NULL)
     69 		{
     70 			*fn = SDL_LoadFunction(x11libs[i].lib, fnname);
     71 			if (*fn != NULL)
     72 				break;
     73 		}
     74 	}
     75 
     76 	#if DEBUG_DYNAMIC_X11
     77 	if (*fn != NULL)
     78 		printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn);
     79 	else
     80 		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
     81 	#endif
     82 
     83 	if (*fn == NULL)
     84 		*rc = 0;  /* kill this module. */
     85 }
     86 
     87 
     88 /* Define all the function pointers and wrappers... */
     89 #define SDL_X11_MODULE(modname)
     90 #define SDL_X11_SYM(rc,fn,params,args,ret) \
     91 	static rc (*p##fn) params = NULL; \
     92 	rc fn params { ret p##fn args ; }
     93 #include "SDL_x11sym.h"
     94 #undef SDL_X11_MODULE
     95 #undef SDL_X11_SYM
     96 #endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
     97 
     98 /* Annoying varargs entry point... */
     99 #ifdef X_HAVE_UTF8_STRING
    100 XIC (*pXCreateIC)(XIM,...) = NULL;
    101 char *(*pXGetICValues)(XIC, ...) = NULL;
    102 #endif
    103 
    104 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
    105 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
    106 #define SDL_X11_SYM(rc,fn,params,args,ret)
    107 #include "SDL_x11sym.h"
    108 #undef SDL_X11_MODULE
    109 #undef SDL_X11_SYM
    110 
    111 
    112 static int x11_load_refcount = 0;
    113 
    114 void SDL_X11_UnloadSymbols(void)
    115 {
    116 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
    117 	/* Don't actually unload if more than one module is using the libs... */
    118 	if (x11_load_refcount > 0) {
    119 		if (--x11_load_refcount == 0) {
    120 			int i;
    121 
    122 			/* set all the function pointers to NULL. */
    123 			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
    124 			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
    125 			#include "SDL_x11sym.h"
    126 			#undef SDL_X11_MODULE
    127 			#undef SDL_X11_SYM
    128 
    129 			#ifdef X_HAVE_UTF8_STRING
    130 			pXCreateIC = NULL;
    131 			pXGetICValues = NULL;
    132 			#endif
    133 
    134 			for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    135 				if (x11libs[i].lib != NULL) {
    136 					SDL_UnloadObject(x11libs[i].lib);
    137 					x11libs[i].lib = NULL;
    138 				}
    139 			}
    140 		}
    141 	}
    142 	#endif
    143 }
    144 
    145 /* returns non-zero if all needed symbols were loaded. */
    146 int SDL_X11_LoadSymbols(void)
    147 {
    148 	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
    149 
    150 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
    151 	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
    152 	if (x11_load_refcount++ == 0) {
    153 		int i;
    154 		int *thismod = NULL;
    155 		for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    156 			if (x11libs[i].libname != NULL) {
    157 				x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
    158 			}
    159 		}
    160 		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
    161 		#define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
    162 		#include "SDL_x11sym.h"
    163 		#undef SDL_X11_MODULE
    164 		#undef SDL_X11_SYM
    165 
    166 		#ifdef X_HAVE_UTF8_STRING
    167 		X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8,(void **)&pXCreateIC);
    168 		X11_GetSym("XGetICValues",&SDL_X11_HAVE_UTF8,(void **)&pXGetICValues);
    169 		#endif
    170 
    171 		if (SDL_X11_HAVE_BASEXLIB) {  /* all required symbols loaded. */
    172 			SDL_ClearError();
    173 			XInitThreads();
    174 		} else {
    175 			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
    176 			rc = 0;
    177 		}
    178 	}
    179 	#else
    180 		#if DEBUG_DYNAMIC_X11
    181 		printf("X11: No dynamic X11 support in this build of SDL.\n");
    182 		#endif
    183 		#ifdef X_HAVE_UTF8_STRING
    184 		pXCreateIC = XCreateIC;
    185 		pXGetICValues = XGetICValues;
    186 		#endif
    187 	#endif
    188 
    189 	return rc;
    190 }
    191 
    192 /* end of SDL_x11dyn.c ... */
    193 
    194