src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 07 Dec 2012 23:26:28 -0500
changeset 6724 6c5ed0c4cc6d
parent 6376 f7ec45572c54
child 6885 700f1b25f77f
permissions -rw-r--r--
X11 msgbox: try to protect the existing setlocale() state.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "SDL_config.h"
    22 
    23 #if SDL_VIDEO_DRIVER_X11
    24 
    25 #define DEBUG_DYNAMIC_X11 0
    26 
    27 #include "SDL_x11dyn.h"
    28 
    29 #if DEBUG_DYNAMIC_X11
    30 #include <stdio.h>
    31 #endif
    32 
    33 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
    34 
    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_XCURSOR
    51 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR NULL
    52 #endif
    53 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA
    54 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL
    55 #endif
    56 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2
    57 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2 NULL
    58 #endif
    59 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
    60 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
    61 #endif
    62 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS
    63 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL
    64 #endif
    65 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE
    66 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL
    67 #endif
    68 
    69 static x11dynlib x11libs[] = {
    70     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
    71     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
    72     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XCURSOR},
    73     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA},
    74     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT2},
    75     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
    76     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS},
    77     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE}
    78 };
    79 
    80 static void *
    81 X11_GetSym(const char *fnname, int *pHasModule)
    82 {
    83     int i;
    84     void *fn = NULL;
    85     for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    86         if (x11libs[i].lib != NULL) {
    87             fn = SDL_LoadFunction(x11libs[i].lib, fnname);
    88             if (fn != NULL)
    89                 break;
    90         }
    91     }
    92 
    93 #if DEBUG_DYNAMIC_X11
    94     if (fn != NULL)
    95         printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname, fn);
    96     else
    97         printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
    98 #endif
    99 
   100     if (fn == NULL)
   101         *pHasModule = 0;  /* kill this module. */
   102 
   103     return fn;
   104 }
   105 
   106 
   107 /* Define all the function pointers and wrappers... */
   108 #define SDL_X11_MODULE(modname)
   109 #define SDL_X11_SYM(rc,fn,params,args,ret) \
   110 	typedef rc (*SDL_DYNX11FN_##fn) params; \
   111 	static SDL_DYNX11FN_##fn p##fn = NULL; \
   112 	rc fn params { ret p##fn args ; }
   113 #include "SDL_x11sym.h"
   114 #undef SDL_X11_MODULE
   115 #undef SDL_X11_SYM
   116 #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
   117 
   118 /* Annoying varargs entry point... */
   119 #ifdef X_HAVE_UTF8_STRING
   120 typedef XIC(*SDL_DYNX11FN_XCreateIC) (XIM,...);
   121 SDL_DYNX11FN_XCreateIC pXCreateIC = NULL;
   122 typedef char *(*SDL_DYNX11FN_XGetICValues) (XIC, ...);
   123 SDL_DYNX11FN_XGetICValues pXGetICValues = NULL;
   124 #endif
   125 
   126 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
   127 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 0;
   128 #define SDL_X11_SYM(rc,fn,params,args,ret)
   129 #include "SDL_x11sym.h"
   130 #undef SDL_X11_MODULE
   131 #undef SDL_X11_SYM
   132 
   133 
   134 static int x11_load_refcount = 0;
   135 
   136 void
   137 SDL_X11_UnloadSymbols(void)
   138 {
   139 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   140     /* Don't actually unload if more than one module is using the libs... */
   141     if (x11_load_refcount > 0) {
   142         if (--x11_load_refcount == 0) {
   143             int i;
   144 
   145             /* set all the function pointers to NULL. */
   146 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 0;
   147 #define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
   148 #include "SDL_x11sym.h"
   149 #undef SDL_X11_MODULE
   150 #undef SDL_X11_SYM
   151 
   152 #ifdef X_HAVE_UTF8_STRING
   153             pXCreateIC = NULL;
   154             pXGetICValues = NULL;
   155 #endif
   156 
   157             for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   158                 if (x11libs[i].lib != NULL) {
   159                     SDL_UnloadObject(x11libs[i].lib);
   160                     x11libs[i].lib = NULL;
   161                 }
   162             }
   163         }
   164     }
   165 #endif
   166 }
   167 
   168 /* returns non-zero if all needed symbols were loaded. */
   169 int
   170 SDL_X11_LoadSymbols(void)
   171 {
   172     int rc = 1;                 /* always succeed if not using Dynamic X11 stuff. */
   173 
   174 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   175     /* deal with multiple modules (dga, x11, etc) needing these symbols... */
   176     if (x11_load_refcount++ == 0) {
   177         int i;
   178         int *thismod = NULL;
   179         for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   180             if (x11libs[i].libname != NULL) {
   181                 x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
   182             }
   183         }
   184 
   185 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1; /* default yes */
   186 #define SDL_X11_SYM(a,fn,x,y,z)
   187 #include "SDL_x11sym.h"
   188 #undef SDL_X11_MODULE
   189 #undef SDL_X11_SYM
   190 
   191 #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
   192 #define SDL_X11_SYM(a,fn,x,y,z) p##fn = (SDL_DYNX11FN_##fn) X11_GetSym(#fn,thismod);
   193 #include "SDL_x11sym.h"
   194 #undef SDL_X11_MODULE
   195 #undef SDL_X11_SYM
   196 
   197 #ifdef X_HAVE_UTF8_STRING
   198         pXCreateIC = (SDL_DYNX11FN_XCreateIC)
   199                         X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8);
   200         pXGetICValues = (SDL_DYNX11FN_XGetICValues)
   201                         X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8);
   202 #endif
   203 
   204         if (SDL_X11_HAVE_BASEXLIB) {
   205             /* all required symbols loaded. */
   206             SDL_ClearError();
   207         } else {
   208             /* in case something got loaded... */
   209             SDL_X11_UnloadSymbols();
   210             rc = 0;
   211         }
   212     }
   213 #else
   214 #ifdef X_HAVE_UTF8_STRING
   215     pXCreateIC = XCreateIC;
   216     pXGetICValues = XGetICValues;
   217 #endif
   218 #endif
   219 
   220     return rc;
   221 }
   222 
   223 #endif /* SDL_VIDEO_DRIVER_X11 */
   224 
   225 /* vi: set ts=4 sw=4 expandtab: */