SDL  2.0
SDL_dynapi.c File Reference
#include "SDL_config.h"
#include "SDL_dynapi.h"
#include "SDL.h"
#include "SDL_shape.h"
#include "SDL_syswm.h"
#include "SDL_dynapi_procs.h"
#include <windows.h>
+ Include dependency graph for SDL_dynapi.c:

Go to the source code of this file.

Data Structures

struct  SDL_DYNAPI_jump_table
 

Macros

#define SDL_DYNAPI_VERSION   1
 
#define DISABLE_JUMP_MAGIC   1
 
#define SDL_DYNAPI_VARARGS_LOGFN(_static, name, initcall, logname, prio)
 
#define SDL_DYNAPI_VARARGS(_static, name, initcall)
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   SDL_DYNAPIFN_##fn fn;
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   static rc fn##_DEFAULT params;
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   fn##_DEFAULT,
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)
 
#define SDL_DYNAPI_PROC_NO_VARARGS   1
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   rc fn params { ret jump_table.fn args; }
 
#define SDL_DYNAPI_PROC_NO_VARARGS   1
 
#define SDL_DYNAPI_PROC(rc, fn, params, args, ret)   jump_table.fn = fn##_REAL;
 
#define WIN32_LEAN_AND_MEAN   1
 

Typedefs

typedef Sint32(* SDL_DYNAPI_ENTRYFN) (Uint32 apiver, void *table, Uint32 tablesize)
 

Functions

static void SDL_InitDynamicAPI (void)
 
Sint32 SDL_DYNAPI_entry (Uint32, void *, Uint32)
 
static SDL_INLINE voidget_sdlapi_entry (const char *fname, const char *sym)
 
static void SDL_InitDynamicAPILocked (void)
 

Variables

static SDL_DYNAPI_jump_table jump_table
 

Macro Definition Documentation

◆ DISABLE_JUMP_MAGIC

#define DISABLE_JUMP_MAGIC   1

Definition at line 54 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [1/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)
Value:
typedef rc (*SDL_DYNAPIFN_##fn) params; \
static rc fn##_DEFAULT params; \
extern rc fn##_REAL params;
const GLfloat * params

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [2/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    SDL_DYNAPIFN_##fn fn;

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [3/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    static rc fn##_DEFAULT params;

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [4/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    fn##_DEFAULT,

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [5/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)
Value:
static rc fn##_DEFAULT params { \
SDL_InitDynamicAPI(); \
ret jump_table.fn args; \
}
const GLfloat * params
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:127

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [6/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    rc fn params { ret jump_table.fn args; }

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC [7/7]

#define SDL_DYNAPI_PROC (   rc,
  fn,
  params,
  args,
  ret 
)    jump_table.fn = fn##_REAL;

Definition at line 152 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC_NO_VARARGS [1/2]

#define SDL_DYNAPI_PROC_NO_VARARGS   1

Definition at line 154 of file SDL_dynapi.c.

◆ SDL_DYNAPI_PROC_NO_VARARGS [2/2]

#define SDL_DYNAPI_PROC_NO_VARARGS   1

Definition at line 154 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VARARGS

#define SDL_DYNAPI_VARARGS (   _static,
  name,
  initcall 
)

Definition at line 65 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VARARGS_LOGFN

#define SDL_DYNAPI_VARARGS_LOGFN (   _static,
  name,
  initcall,
  logname,
  prio 
)
Value:
_static void SDL_Log##logname##name(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...) { \
va_list ap; initcall; va_start(ap, fmt); \
jump_table.SDL_LogMessageV(category, SDL_LOG_PRIORITY_##prio, fmt, ap); \
va_end(ap); \
}
GLuint const GLchar * name
#define SDL_Log
#define SDL_PRINTF_FORMAT_STRING
Definition: SDL_stdinc.h:254

Definition at line 58 of file SDL_dynapi.c.

◆ SDL_DYNAPI_VERSION

#define SDL_DYNAPI_VERSION   1

Definition at line 42 of file SDL_dynapi.c.

◆ WIN32_LEAN_AND_MEAN

#define WIN32_LEAN_AND_MEAN   1

Definition at line 203 of file SDL_dynapi.c.

Typedef Documentation

◆ SDL_DYNAPI_ENTRYFN

typedef Sint32( * SDL_DYNAPI_ENTRYFN) (Uint32 apiver, void *table, Uint32 tablesize)

Definition at line 168 of file SDL_dynapi.c.

Function Documentation

◆ get_sdlapi_entry()

static SDL_INLINE void* get_sdlapi_entry ( const char *  fname,
const char *  sym 
)
static

Definition at line 206 of file SDL_dynapi.c.

207 {
208  HANDLE lib = LoadLibraryA(fname);
209  void *retval = NULL;
210  if (lib) {
211  retval = GetProcAddress(lib, sym);
212  if (retval == NULL) {
213  FreeLibrary(lib);
214  }
215  }
216  return retval;
217 }
SDL_bool retval
#define NULL
Definition: begin_code.h:143

◆ SDL_DYNAPI_entry()

Sint32 SDL_DYNAPI_entry ( Uint32  apiver,
void table,
Uint32  tablesize 
)

Definition at line 172 of file SDL_dynapi.c.

173 {
174  SDL_DYNAPI_jump_table *output_jump_table = (SDL_DYNAPI_jump_table *) table;
175 
176  if (apiver != SDL_DYNAPI_VERSION) {
177  /* !!! FIXME: can maybe handle older versions? */
178  return -1; /* not compatible. */
179  } else if (tablesize > sizeof (jump_table)) {
180  return -1; /* newer version of SDL with functions we can't provide. */
181  }
182 
183  /* Init our jump table first. */
184  #define SDL_DYNAPI_PROC(rc,fn,params,args,ret) jump_table.fn = fn##_REAL;
185  #include "SDL_dynapi_procs.h"
186  #undef SDL_DYNAPI_PROC
187 
188  /* Then the external table... */
189  if (output_jump_table != &jump_table) {
190  jump_table.SDL_memcpy(output_jump_table, &jump_table, tablesize);
191  }
192 
193  /* Safe to call SDL functions now; jump table is initialized! */
194 
195  return 0; /* success! */
196 }
GLenum GLsizei GLenum GLenum const void * table
#define SDL_DYNAPI_VERSION
Definition: SDL_dynapi.c:42
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:127

◆ SDL_InitDynamicAPI()

static void SDL_InitDynamicAPI ( void  )
static

Definition at line 283 of file SDL_dynapi.c.

284 {
285  /* So the theory is that every function in the jump table defaults to
286  * calling this function, and then replaces itself with a version that
287  * doesn't call this function anymore. But it's possible that, in an
288  * extreme corner case, you can have a second thread hit this function
289  * while the jump table is being initialized by the first.
290  * In this case, a spinlock is really painful compared to what spinlocks
291  * _should_ be used for, but this would only happen once, and should be
292  * insanely rare, as you would have to spin a thread outside of SDL (as
293  * SDL_CreateThread() would also call this function before building the
294  * new thread).
295  */
296  static SDL_bool already_initialized = SDL_FALSE;
297 
298  /* SDL_AtomicLock calls SDL mutex functions to emulate if
299  SDL_ATOMIC_DISABLED, which we can't do here, so in such a
300  configuration, you're on your own. */
301  #if !SDL_ATOMIC_DISABLED
302  static SDL_SpinLock lock = 0;
303  SDL_AtomicLock_REAL(&lock);
304  #endif
305 
306  if (!already_initialized) {
308  already_initialized = SDL_TRUE;
309  }
310 
311  #if !SDL_ATOMIC_DISABLED
312  SDL_AtomicUnlock_REAL(&lock);
313  #endif
314 }
static void SDL_InitDynamicAPILocked(void)
Definition: SDL_dynapi.c:253
SDL_bool
Definition: SDL_stdinc.h:130
SDL_mutex * lock
Definition: SDL_events.c:75
int SDL_SpinLock
Definition: SDL_atomic.h:89

◆ SDL_InitDynamicAPILocked()

static void SDL_InitDynamicAPILocked ( void  )
static

Definition at line 253 of file SDL_dynapi.c.

254 {
255  const char *libname = SDL_getenv_REAL("SDL_DYNAMIC_API");
256  SDL_DYNAPI_ENTRYFN entry = SDL_DYNAPI_entry; /* funcs from here by default. */
257 
258  if (libname) {
259  entry = (SDL_DYNAPI_ENTRYFN) get_sdlapi_entry(libname, "SDL_DYNAPI_entry");
260  if (!entry) {
261  /* !!! FIXME: fail to startup here instead? */
262  /* !!! FIXME: definitely warn user. */
263  /* Just fill in the function pointers from this library. */
264  entry = SDL_DYNAPI_entry;
265  }
266  }
267 
268  if (entry(SDL_DYNAPI_VERSION, &jump_table, sizeof (jump_table)) < 0) {
269  /* !!! FIXME: fail to startup here instead? */
270  /* !!! FIXME: definitely warn user. */
271  /* Just fill in the function pointers from this library. */
272  if (entry != SDL_DYNAPI_entry) {
274  /* !!! FIXME: now we're screwed. Should definitely abort now. */
275  }
276  }
277  }
278 
279  /* we intentionally never close the newly-loaded lib, of course. */
280 }
static SDL_INLINE void * get_sdlapi_entry(const char *fname, const char *sym)
Definition: SDL_dynapi.c:206
Sint32(* SDL_DYNAPI_ENTRYFN)(Uint32 apiver, void *table, Uint32 tablesize)
Definition: SDL_dynapi.c:168
#define SDL_DYNAPI_VERSION
Definition: SDL_dynapi.c:42
static SDL_DYNAPI_jump_table jump_table
Definition: SDL_dynapi.c:127
Sint32 SDL_DYNAPI_entry(Uint32, void *, Uint32)
Definition: SDL_dynapi.c:172

Variable Documentation

◆ jump_table

SDL_DYNAPI_jump_table jump_table
static

Definition at line 127 of file SDL_dynapi.c.