src/video/x11/SDL_x11dyn.c
author Ryan C. Gordon <icculus@icculus.org>
Wed, 17 Sep 2008 08:20:57 +0000
changeset 2763 6fc50bdd88c0
parent 2325 c7bcf84ba1b9
child 2859 99210400e8b9
permissions -rw-r--r--
Some cleanups on the new XInput code.

One or two things got moved around, but largely this is hooked up correctly
in the Unix configure system now: it can be dynamically loaded and fallback
gracefully if not available, or libXi can be directly linked to libSDL.

XInput support can be --disable'd from the configure script, too (defaults to
enabled).

Please note that while the framework is in place to gracefully fallback, the
current state of the source requires XInput. We'll need to adjust a few
things still to correct this.
     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 #ifndef SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT
    56 #define SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT NULL
    57 #endif
    58 
    59 static x11dynlib x11libs[] = {
    60     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC},
    61     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT},
    62     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRENDER},
    63     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XRANDR},
    64     {NULL, SDL_VIDEO_DRIVER_X11_DYNAMIC_XINPUT},
    65 };
    66 
    67 static void
    68 X11_GetSym(const char *fnname, int *rc, void **fn)
    69 {
    70     int i;
    71     for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
    72         if (x11libs[i].lib != NULL) {
    73             *fn = SDL_LoadFunction(x11libs[i].lib, fnname);
    74             if (*fn != NULL)
    75                 break;
    76         }
    77     }
    78 
    79 #if DEBUG_DYNAMIC_X11
    80     if (*fn != NULL)
    81         printf("X11: Found '%s' in %s (%p)\n", fnname, x11libs[i].libname,
    82                *fn);
    83     else
    84         printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
    85 #endif
    86 
    87     if (*fn == NULL)
    88         *rc = 0;                /* kill this module. */
    89 }
    90 
    91 
    92 /* Define all the function pointers and wrappers... */
    93 #define SDL_X11_MODULE(modname)
    94 #define SDL_X11_SYM(rc,fn,params,args,ret) \
    95 	static rc (*p##fn) params = NULL; \
    96 	rc fn params { ret p##fn args ; }
    97 #include "SDL_x11sym.h"
    98 #undef SDL_X11_MODULE
    99 #undef SDL_X11_SYM
   100 #endif /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
   101 
   102 /* Annoying varargs entry point... */
   103 #ifdef X_HAVE_UTF8_STRING
   104 XIC(*pXCreateIC) (XIM,...) = NULL;
   105 char *(*pXGetICValues) (XIC, ...) = NULL;
   106 #endif
   107 
   108 /* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
   109 #define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
   110 #define SDL_X11_SYM(rc,fn,params,args,ret)
   111 #include "SDL_x11sym.h"
   112 #undef SDL_X11_MODULE
   113 #undef SDL_X11_SYM
   114 
   115 
   116 static int x11_load_refcount = 0;
   117 
   118 void
   119 SDL_X11_UnloadSymbols(void)
   120 {
   121 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   122     /* Don't actually unload if more than one module is using the libs... */
   123     if (x11_load_refcount > 0) {
   124         if (--x11_load_refcount == 0) {
   125             int i;
   126 
   127             /* set all the function pointers to NULL. */
   128 #define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
   129 #define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
   130 #include "SDL_x11sym.h"
   131 #undef SDL_X11_MODULE
   132 #undef SDL_X11_SYM
   133 
   134 #ifdef X_HAVE_UTF8_STRING
   135             pXCreateIC = NULL;
   136             pXGetICValues = NULL;
   137 #endif
   138 
   139             for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   140                 if (x11libs[i].lib != NULL) {
   141                     SDL_UnloadObject(x11libs[i].lib);
   142                     x11libs[i].lib = NULL;
   143                 }
   144             }
   145         }
   146     }
   147 #endif
   148 }
   149 
   150 /* returns non-zero if all needed symbols were loaded. */
   151 int
   152 SDL_X11_LoadSymbols(void)
   153 {
   154     int rc = 1;                 /* always succeed if not using Dynamic X11 stuff. */
   155 
   156 #ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
   157     /* deal with multiple modules (dga, x11, etc) needing these symbols... */
   158     if (x11_load_refcount++ == 0) {
   159         int i;
   160         int *thismod = NULL;
   161         for (i = 0; i < SDL_TABLESIZE(x11libs); i++) {
   162             if (x11libs[i].libname != NULL) {
   163                 x11libs[i].lib = SDL_LoadObject(x11libs[i].libname);
   164             }
   165         }
   166 #define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
   167 #define SDL_X11_SYM(a,fn,x,y,z) X11_GetSym(#fn,thismod,(void**)&p##fn);
   168 #include "SDL_x11sym.h"
   169 #undef SDL_X11_MODULE
   170 #undef SDL_X11_SYM
   171 
   172 #ifdef X_HAVE_UTF8_STRING
   173         X11_GetSym("XCreateIC", &SDL_X11_HAVE_UTF8, (void **) &pXCreateIC);
   174         X11_GetSym("XGetICValues", &SDL_X11_HAVE_UTF8,
   175                    (void **) &pXGetICValues);
   176 #endif
   177 
   178         if (SDL_X11_HAVE_BASEXLIB) {
   179             /* all required symbols loaded. */
   180             SDL_ClearError();
   181         } else {
   182             /* in case something got loaded... */
   183             SDL_X11_UnloadSymbols();
   184             rc = 0;
   185         }
   186     }
   187 #else
   188 #ifdef X_HAVE_UTF8_STRING
   189     pXCreateIC = XCreateIC;
   190     pXGetICValues = XGetICValues;
   191 #endif
   192 #endif
   193 
   194     return rc;
   195 }
   196 
   197 /* vi: set ts=4 sw=4 expandtab: */