src/video/x11/SDL_x11dyn.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 28 Feb 2011 09:01:53 -0800
changeset 5408 35a63789c3f2
parent 5262 b530ef003506
child 5471 179adad3ae6f
permissions -rw-r--r--
Dynamically load the Xinerama and xf86vmode extensions
This fixes a few bugs with different distributions:
http://bugs.freedesktop.org/show_bug.cgi?id=17431
http://bugs.gentoo.org/show_bug.cgi?id=246177
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2011 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 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     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  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_XINERAMA
    50 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA NULL
    51 #endif
    52 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT
    53 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT NULL
    54 #endif
    55 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR
    56 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR NULL
    57 #endif
    58 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS
    59 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS NULL
    60 #endif
    61 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE
    62 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE NULL
    63 #endif
    64 
    65 static x11dynlib x11libs[] = {
    66     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
    67     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
    68     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINERAMA},
    69     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT},
    70     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
    71     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XSS},
    72     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XVIDMODE}
    73 };
    74 
    75 static void
    76 X11_GetSym(const char *fnname, int *rc, void **fn)
    77 {
    78     int i;
    79     for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    80         if (x11libs[i].lib != NULL) {
    81             *fn = SDL_LoadFunction(x11libs[i].lib, fnname);
    82             if (*fn != NULL)
    83                 break;
    84         }
    85     }
    86 
    87 #if DEBUG_DYNAMIC_X11
    88     if (*fn != NULL)
    89         printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname,
    90                *fn);
    91     else
    92         printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
    93 #endif
    94 
    95     if (*fn == NULL)
    96         *rc = 0;                /* kill this module. */
    97 }
    98 
    99 
   100 /* Define all the function pointers and wrappers... */
   101 #define SDL_X11_MODULE(modname)
   102 #define SDL_X11_SYM(rc,fn,params,args,ret) \
   103 	static rc (*p##fn) params = NULL; \
   104 	rc fn params { ret p##fn args ; }
   105 #include "SDL_x11sym.h"
   106 #undef SDL_X11_MODULE
   107 #undef SDL_X11_SYM
   108 #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
   109 
   110 /* Annoying varargs entry point... */
   111 #ifdef X_HAVE_UTF8_STRING
   112 XIC(*pXCreateIC) (XIM,...) = NULL;
   113 char *(*pXGetICValues) (XIC, ...) = NULL;
   114 #endif
   115 
   116 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
   117 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
   118 #define SDL_X11_SYM(rc,fn,params,args,ret)
   119 #include "SDL_x11sym.h"
   120 #undef SDL_X11_MODULE
   121 #undef SDL_X11_SYM
   122 
   123 
   124 static int x11_load_refcount = 0;
   125 
   126 void
   127 SDL_X11_UnloadSymbols(void)
   128 {
   129 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   130     /* Don't actually unload if more than one module is using the libs... */
   131     if (x11_load_refcount > 0) {
   132         if (--x11_load_refcount == 0) {
   133             int i;
   134 
   135             /* set all the function pointers to NULL. */
   136 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
   137 #define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
   138 #include "SDL_x11sym.h"
   139 #undef SDL_X11_MODULE
   140 #undef SDL_X11_SYM
   141 
   142 #ifdef X_HAVE_UTF8_STRING
   143             pXCreateIC = NULL;
   144             pXGetICValues = NULL;
   145 #endif
   146 
   147             for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   148                 if (x11libs[i].lib != NULL) {
   149                     SDL_UnloadObject(x11libs[i].lib);
   150                     x11libs[i].lib = NULL;
   151                 }
   152             }
   153         }
   154     }
   155 #endif
   156 }
   157 
   158 /* returns non-zero if all needed symbols were loaded. */
   159 int
   160 SDL_X11_LoadSymbols(void)
   161 {
   162     int rc = 1;                 /* always succeed if not using Dynamic X11 stuff. */
   163 
   164 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   165     /* deal with multiple modules (dga, x11, etc) needing these symbols... */
   166     if (x11_load_refcount++ == 0) {
   167         int i;
   168         int *thismod = NULL;
   169         for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   170             if (x11libs[i].libname != NULL) {
   171                 x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
   172             }
   173         }
   174 #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
   175 #define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
   176 #include "SDL_x11sym.h"
   177 #undef SDL_X11_MODULE
   178 #undef SDL_X11_SYM
   179 
   180 #ifdef X_HAVE_UTF8_STRING
   181         X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
   182         X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8,
   183                    (void **) &pXGetICValues);
   184 #endif
   185 
   186         if (SDL_X11_HAVE_BASEXLIB) {
   187             /* all required symbols loaded. */
   188             SDL_ClearError();
   189         } else {
   190             /* in case something got loaded... */
   191             SDL_X11_UnloadSymbols();
   192             rc = 0;
   193         }
   194     }
   195 #else
   196 #ifdef X_HAVE_UTF8_STRING
   197     pXCreateIC = XCreateIC;
   198     pXGetICValues = XGetICValues;
   199 #endif
   200 #endif
   201 
   202     return rc;
   203 }
   204 
   205 /* vi: set ts=4 sw=4 expandtab: */