src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 23 Mar 2006 02:47:56 +0000
changeset 1593 5115439d67b1
parent 1589 34cca785be57
child 1610 a1ee5944412b
permissions -rw-r--r--
Consolidate all the X11 libraries, so you don't have to update 12 different
places in the source when adding a new one. Also handles build systems that
don't define a given library.
     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@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 <dlfcn.h>
    35 #include "SDL_name.h"
    36 #include "SDL_loadso.h"
    37 
    38 typedef struct
    39 {
    40     void *lib;
    41     const char *libname;
    42 } x11dynlib;
    43 
    44 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC
    45 #define SDL_VIDEO_DRIVER_X11_DYNAMIC NULL
    46 #endif
    47 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT
    48 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT NULL
    49 #endif
    50 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER
    51 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER NULL
    52 #endif
    53 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
    54 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
    55 #endif
    56 
    57 static x11dynlib x11libs[] =
    58 {
    59     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC },
    60     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT },
    61     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER },
    62     { NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR },
    63 };
    64 
    65 static void *X11_GetSym(const char *fnname, int *rc)
    66 {
    67 	int i;
    68 	void *fn = NULL;
    69 	for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    70 		if (x11libs[i].lib != NULL)
    71 		{
    72 			fn = SDL_LoadFunction(x11libs[i].lib, fnname);
    73 			if (fn != NULL)
    74 				break;
    75 		}
    76 	}
    77 
    78 	#if DEBUG_DYNAMIC_X11
    79 	if (fn != NULL)
    80 		printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, fn);
    81 	else
    82 		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
    83 	#endif
    84 
    85 	if (fn == NULL)
    86 		*rc = 0;  /* kill this module. */
    87 
    88 	return fn;
    89 }
    90 
    91 
    92 /* Define all the function pointers and wrappers... */
    93 #define SDL_X11_MODULE(modname)
    94 #define SDL_X11_SYM(rc,fn,params,args,ret) \
    95 	static rc (*p##fn) params = NULL; \
    96 	rc fn params { ret p##fn args ; }
    97 #include "SDL_x11sym.h"
    98 #undef SDL_X11_MODULE
    99 #undef SDL_X11_SYM
   100 #endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
   101 
   102 /* Annoying varargs entry point... */
   103 #ifdef X_HAVE_UTF8_STRING
   104 XIC (*pXCreateIC)(XIM,...) = NULL;
   105 #endif
   106 
   107 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
   108 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
   109 #define SDL_X11_SYM(rc,fn,params,args,ret)
   110 #include "SDL_x11sym.h"
   111 #undef SDL_X11_MODULE
   112 #undef SDL_X11_SYM
   113 
   114 
   115 static int x11_load_refcount = 0;
   116 
   117 void SDL_X11_UnloadSymbols(void)
   118 {
   119 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   120 	/* Don't actually unload if more than one module is using the libs... */
   121 	if (x11_load_refcount > 0) {
   122 		if (--x11_load_refcount == 0) {
   123 			int i;
   124 
   125 			/* set all the function pointers to NULL. */
   126 			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
   127 			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
   128 			#include "SDL_x11sym.h"
   129 			#undef SDL_X11_MODULE
   130 			#undef SDL_X11_SYM
   131 
   132 			#ifdef X_HAVE_UTF8_STRING
   133 			pXCreateIC = NULL;
   134 			#endif
   135 
   136 			for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   137 				if (x11libs[i].lib != NULL) {
   138 					SDL_UnloadObject(x11libs[i].lib);
   139 					x11libs[i].lib = NULL;
   140 				}
   141 			}
   142 		}
   143 	}
   144 	#endif
   145 }
   146 
   147 /* returns non-zero if all needed symbols were loaded. */
   148 int SDL_X11_LoadSymbols(void)
   149 {
   150 	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
   151 
   152 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   153 	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
   154 	if (x11_load_refcount++ == 0) {
   155 		int i;
   156 		int *thismod = NULL;
   157 		for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   158 			if (x11libs[i].libname != NULL) {
   159 				x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
   160 			}
   161 		}
   162 		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
   163 		#define SDL_X11_SYM(a,fn,x,y,z) p##fn = X11_GetSym(#fn,thismod);
   164 		#include "SDL_x11sym.h"
   165 		#undef SDL_X11_MODULE
   166 		#undef SDL_X11_SYM
   167 
   168 		#ifdef X_HAVE_UTF8_STRING
   169 		pXCreateIC = X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8);
   170 		#endif
   171 
   172 		if (!SDL_X11_HAVE_BASEXLIB) {  /* some required symbol didn't load. */
   173 			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
   174 		}
   175 	}
   176 	#else
   177 		#ifdef X_HAVE_UTF8_STRING
   178 		pXCreateIC = XCreateIC;
   179 		#endif
   180 	#endif
   181 
   182 	return rc;
   183 }
   184 
   185 /* end of SDL_x11dyn.c ... */
   186