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.
     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 "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 #endif
   102 
   103 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
   104 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
   105 #define SDL_X11_SYM(rc,fn,params,args,ret)
   106 #include "SDL_x11sym.h"
   107 #undef SDL_X11_MODULE
   108 #undef SDL_X11_SYM
   109 
   110 
   111 static int x11_load_refcount = 0;
   112 
   113 void SDL_X11_UnloadSymbols(void)
   114 {
   115 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   116 	/* Don't actually unload if more than one module is using the libs... */
   117 	if (x11_load_refcount > 0) {
   118 		if (--x11_load_refcount == 0) {
   119 			int i;
   120 
   121 			/* set all the function pointers to NULL. */
   122 			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
   123 			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
   124 			#include "SDL_x11sym.h"
   125 			#undef SDL_X11_MODULE
   126 			#undef SDL_X11_SYM
   127 
   128 			#ifdef X_HAVE_UTF8_STRING
   129 			pXCreateIC = NULL;
   130 			#endif
   131 
   132 			for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   133 				if (x11libs[i].lib != NULL) {
   134 					SDL_UnloadObject(x11libs[i].lib);
   135 					x11libs[i].lib = NULL;
   136 				}
   137 			}
   138 		}
   139 	}
   140 	#endif
   141 }
   142 
   143 /* returns non-zero if all needed symbols were loaded. */
   144 int SDL_X11_LoadSymbols(void)
   145 {
   146 	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
   147 
   148 	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   149 	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
   150 	if (x11_load_refcount++ == 0) {
   151 		int i;
   152 		int *thismod = NULL;
   153 		for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   154 			if (x11libs[i].libname != NULL) {
   155 				x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
   156 			}
   157 		}
   158 		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
   159 		#define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
   160 		#include "SDL_x11sym.h"
   161 		#undef SDL_X11_MODULE
   162 		#undef SDL_X11_SYM
   163 
   164 		#ifdef X_HAVE_UTF8_STRING
   165 		X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8,(void **)&pXCreateIC);
   166 		#endif
   167 
   168 		if (SDL_X11_HAVE_BASEXLIB) {  /* all required symbols loaded. */
   169 			SDL_ClearError();
   170 		} else {
   171 			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
   172 			rc = 0;
   173 		}
   174 	}
   175 	#else
   176 		#if DEBUG_DYNAMIC_X11
   177 		printf("X11: No dynamic X11 support in this build of SDL.\n");
   178 		#endif
   179 		#ifdef X_HAVE_UTF8_STRING
   180 		pXCreateIC = XCreateIC;
   181 		#endif
   182 	#endif
   183 
   184 	return rc;
   185 }
   186 
   187 /* end of SDL_x11dyn.c ... */
   188