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 } else { 174 SDL_X11_UnloadSymbols(); /* in case something got loaded... */ 175 rc = 0; 176 } 177 } 178 #else 179 #if DEBUG_DYNAMIC_X11 180 printf("X11: No dynamic X11 support in this build of SDL.\n"); 181 #endif 182 #ifdef X_HAVE_UTF8_STRING 183 pXCreateIC = XCreateIC; 184 pXGetICValues = XGetICValues; 185 #endif 186 #endif 187 188 return rc; 189 } 190 191 /* end of SDL_x11dyn.c ... */ 192 193