1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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) 65 { 66 void *fn = NULL; 67 int i; 68 for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { 69 if (x11libs[i].lib != NULL) 70 { 71 fn = SDL_LoadFunction(x11libs[i].lib, fnname); 72 if (fn != NULL) 73 break; 74 } 75 } 76 77 #if DEBUG_DYNAMIC_X11 78 if (fn != NULL) 79 printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, *fn); 80 else 81 printf("X11: Symbol '%s' NOT FOUND!\n", fnname); 82 #endif 83 84 if (fn == NULL) 85 *rc = 0; /* kill this module. */ 86 87 return fn; 88 } 89 90 91 /* Define all the function pointers and wrappers... */ 92 #define SDL_X11_MODULE(modname) 93 #define SDL_X11_SYM(rc,fn,params,args,ret) \ 94 static rc (*p##fn) params = NULL; \ 95 rc fn params { ret p##fn args ; } 96 #include "SDL_x11sym.h" 97 #undef SDL_X11_MODULE 98 #undef SDL_X11_SYM 99 #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */ 100 101 /* Annoying varargs entry point... */ 102 #ifdef X_HAVE_UTF8_STRING 103 XIC (*pXCreateIC)(XIM,...) = NULL; 104 char *(*pXGetICValues)(XIC, ...) = 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 void *SDL_XGetRequest_workaround(Display* dpy, CARD8 type, size_t len) 116 { 117 xReq *req; 118 WORD64ALIGN 119 if (dpy->bufptr + len > dpy->bufmax) 120 _XFlush(dpy); 121 dpy->last_req = dpy->bufptr; 122 req = (xReq*)dpy->bufptr; 123 req->reqType = type; 124 req->length = len / 4; 125 dpy->bufptr += len; 126 dpy->request++; 127 return req; 128 } 129 130 static int x11_load_refcount = 0; 131 132 void SDL_X11_UnloadSymbols(void) 133 { 134 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC 135 /* Don't actually unload if more than one module is using the libs... */ 136 if (x11_load_refcount > 0) { 137 if (--x11_load_refcount == 0) { 138 int i; 139 140 /* set all the function pointers to NULL. */ 141 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; 142 #define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL; 143 #include "SDL_x11sym.h" 144 #undef SDL_X11_MODULE 145 #undef SDL_X11_SYM 146 147 #ifdef X_HAVE_UTF8_STRING 148 pXCreateIC = NULL; 149 pXGetICValues = NULL; 150 #endif 151 152 for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { 153 if (x11libs[i].lib != NULL) { 154 SDL_UnloadObject(x11libs[i].lib); 155 x11libs[i].lib = NULL; 156 } 157 } 158 } 159 } 160 #endif 161 } 162 163 /* returns non-zero if all needed symbols were loaded. */ 164 int SDL_X11_LoadSymbols(void) 165 { 166 int rc = 1; /* always succeed if not using Dynamic X11 stuff. */ 167 168 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC 169 /* deal with multiple modules (dga, x11, etc) needing these symbols... */ 170 if (x11_load_refcount++ == 0) { 171 int i; 172 int *thismod = NULL; 173 for (i = 0; i < SDL_TABLESIZE(x11libs); i++) { 174 if (x11libs[i].libname != NULL) { 175 x11libs[i].lib = SDL_LoadObject(x11libs[i].libname); 176 } 177 } 178 #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname; 179 #define SDL_X11_SYM(rc,fn,params,args,ret) \ 180 p##fn = (rc(*)params) X11_GetSym(#fn, thismod); 181 #include "SDL_x11sym.h" 182 #undef SDL_X11_MODULE 183 #undef SDL_X11_SYM 184 185 #ifdef X_HAVE_UTF8_STRING 186 pXCreateIC = (XIC(*)(XIM,...)) X11_GetSym("XCreateIC", 187 &SDL_X11_HAVE_UTF8); 188 pXGetICValues = (char * (*)(XIC,...)) X11_GetSym("XGetICValues", 189 &SDL_X11_HAVE_UTF8); 190 #endif 191 192 /* 193 * In case we're built with newer Xlib headers, we need to make sure 194 * that _XGetRequest() is available, even on older systems. 195 * Otherwise, various Xlib macros we use will call a NULL pointer. 196 */ 197 if (!SDL_X11_HAVE_XGETREQUEST) { 198 p_XGetRequest = SDL_XGetRequest_workaround; 199 } 200 201 if (SDL_X11_HAVE_BASEXLIB) { /* all required symbols loaded. */ 202 SDL_ClearError(); 203 XInitThreads(); 204 } else { 205 SDL_X11_UnloadSymbols(); /* in case something got loaded... */ 206 rc = 0; 207 } 208 } 209 #else 210 #if DEBUG_DYNAMIC_X11 211 printf("X11: No dynamic X11 support in this build of SDL.\n"); 212 #endif 213 #ifdef X_HAVE_UTF8_STRING 214 pXCreateIC = XCreateIC; 215 pXGetICValues = XGetICValues; 216 #endif 217 #endif 218 219 return rc; 220 } 221 222 /* end of SDL_x11dyn.c ... */ 223 224