|
@@ -28,234 +28,23 @@ static char rcsid = |
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
/* System dependent library loading routines */ |
|
|
|
|
|
#include <stdio.h> |
|
|
#if defined(USE_DLOPEN) |
|
|
# include <dlfcn.h> |
|
|
/* !!! FIXME: includes so I don't have to update all the project files... */ |
|
|
#define SDL_INTERNAL_BUILDING_LOADSO 1 |
|
|
#if defined(USE_DUMMY_LOADSO) |
|
|
# include "loadso/dummy/SDL_loadso.c" |
|
|
#elif defined(MACOSX) |
|
|
# include "loadso/macosx/SDL_loadso.c" |
|
|
#elif defined(macintosh) |
|
|
# include "loadso/macos/SDL_loadso.c" |
|
|
#elif defined(USE_DLOPEN) |
|
|
# include "loadso/dlopen/SDL_loadso.c" |
|
|
#elif defined(WIN32) || defined(_WIN32_WCE) |
|
|
# include <windows.h> |
|
|
# include "loadso/windows/SDL_loadso.c" |
|
|
#elif defined(__BEOS__) |
|
|
# include <be/kernel/image.h> |
|
|
#elif defined(macintosh) |
|
|
# include <string.h> |
|
|
#define OLDP2C 1 |
|
|
# include <Strings.h> |
|
|
# include <CodeFragments.h> |
|
|
# include <Errors.h> |
|
|
# include "loadso/beos/SDL_loadso.c" |
|
|
#elif defined(__MINT__) && defined(ENABLE_LDG) |
|
|
# include <gem.h> |
|
|
# include <ldg.h> |
|
|
# include "loadso/mint/SDL_loadso.c" |
|
|
#else |
|
|
/*#error Unsupported dynamic link environment*/ |
|
|
# include "loadso/dummy/SDL_loadso.c" |
|
|
#endif /* system type */ |
|
|
|
|
|
#include "SDL_types.h" |
|
|
#include "SDL_error.h" |
|
|
#include "SDL_loadso.h" |
|
|
|
|
|
void *SDL_LoadObject(const char *sofile) |
|
|
{ |
|
|
void *handle = NULL; |
|
|
const char *loaderror = "SDL_LoadObject() not implemented"; |
|
|
#if defined(USE_DLOPEN) |
|
|
/* * */ |
|
|
handle = dlopen(sofile, RTLD_NOW); |
|
|
loaderror = (char *)dlerror(); |
|
|
#elif defined(_WIN32_WCE) |
|
|
/* * */ |
|
|
char errbuf[512]; |
|
|
|
|
|
wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t)); |
|
|
wchar_t *sofile_t = malloc((MAX_PATH+1) * sizeof(wchar_t)); |
|
|
|
|
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sofile, -1, sofile_t, MAX_PATH); |
|
|
handle = (void *)LoadLibrary(sofile_t); |
|
|
|
|
|
/* Generate an error message if all loads failed */ |
|
|
if ( handle == NULL ) { |
|
|
FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | |
|
|
FORMAT_MESSAGE_FROM_SYSTEM), |
|
|
NULL, GetLastError(), |
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
|
errbuf_t, SDL_TABLESIZE(errbuf), NULL); |
|
|
WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); |
|
|
loaderror = errbuf; |
|
|
} |
|
|
|
|
|
free(sofile_t); |
|
|
free(errbuf_t); |
|
|
|
|
|
#elif defined(WIN32) |
|
|
/* * */ |
|
|
char errbuf[512]; |
|
|
|
|
|
handle = (void *)LoadLibrary(sofile); |
|
|
|
|
|
/* Generate an error message if all loads failed */ |
|
|
if ( handle == NULL ) { |
|
|
FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | |
|
|
FORMAT_MESSAGE_FROM_SYSTEM), |
|
|
NULL, GetLastError(), |
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
|
errbuf, SDL_TABLESIZE(errbuf), NULL); |
|
|
loaderror = errbuf; |
|
|
} |
|
|
#elif defined(__BEOS__) |
|
|
/* * */ |
|
|
image_id library_id; |
|
|
|
|
|
library_id = load_add_on(sofile); |
|
|
if ( library_id == B_ERROR ) { |
|
|
loaderror = "BeOS error"; |
|
|
} else { |
|
|
handle = (void *)(library_id); |
|
|
} |
|
|
#elif defined(macintosh) |
|
|
/* * */ |
|
|
CFragConnectionID library_id; |
|
|
Ptr mainAddr; |
|
|
Str255 errName; |
|
|
OSErr error; |
|
|
char psofile[512]; |
|
|
|
|
|
strncpy(psofile, sofile, SDL_TABLESIZE(psofile)); |
|
|
psofile[SDL_TABLESIZE(psofile)-1] = '\0'; |
|
|
error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch, |
|
|
kLoadCFrag, &library_id, &mainAddr, errName); |
|
|
switch (error) { |
|
|
case noErr: |
|
|
loaderror = NULL; |
|
|
break; |
|
|
case cfragNoLibraryErr: |
|
|
loaderror = "Library not found"; |
|
|
break; |
|
|
case cfragUnresolvedErr: |
|
|
loaderror = "Unabled to resolve symbols"; |
|
|
break; |
|
|
case cfragNoPrivateMemErr: |
|
|
case cfragNoClientMemErr: |
|
|
loaderror = "Out of memory"; |
|
|
break; |
|
|
default: |
|
|
loaderror = "Unknown Code Fragment Manager error"; |
|
|
break; |
|
|
} |
|
|
if ( loaderror == NULL ) { |
|
|
handle = (void *)(library_id); |
|
|
} |
|
|
#elif defined(__MINT__) && defined(ENABLE_LDG) |
|
|
/* * */ |
|
|
handle = (void *)ldg_open((char *)sofile, ldg_global); |
|
|
#endif /* system type */ |
|
|
|
|
|
if ( handle == NULL ) { |
|
|
SDL_SetError("Failed loading %s: %s", sofile, loaderror); |
|
|
} |
|
|
return(handle); |
|
|
} |
|
|
|
|
|
void *SDL_LoadFunction(void *handle, const char *name) |
|
|
{ |
|
|
void *symbol = NULL; |
|
|
const char *loaderror = "SDL_LoadFunction not implemented"; |
|
|
#if defined(USE_DLOPEN) |
|
|
/* * */ |
|
|
symbol = dlsym(handle, name); |
|
|
if ( symbol == NULL ) { |
|
|
loaderror = (char *)dlerror(); |
|
|
} |
|
|
#elif defined(_WIN32_WCE) |
|
|
/* * */ |
|
|
char errbuf[512]; |
|
|
int length = strlen(name); |
|
|
|
|
|
wchar_t *name_t = malloc((length + 1) * sizeof(wchar_t)); |
|
|
wchar_t *errbuf_t = malloc(512 * sizeof(wchar_t)); |
|
|
|
|
|
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, name_t, length); |
|
|
|
|
|
symbol = (void *)GetProcAddress((HMODULE)handle, name_t); |
|
|
if ( symbol == NULL ) { |
|
|
FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | |
|
|
FORMAT_MESSAGE_FROM_SYSTEM), |
|
|
NULL, GetLastError(), |
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
|
errbuf_t, SDL_TABLESIZE(errbuf), NULL); |
|
|
WideCharToMultiByte(CP_ACP, 0, errbuf_t, -1, errbuf, 511, NULL, NULL); |
|
|
loaderror = errbuf; |
|
|
} |
|
|
|
|
|
free(name_t); |
|
|
free(errbuf_t); |
|
|
|
|
|
#elif defined(WIN32) |
|
|
/* * */ |
|
|
char errbuf[512]; |
|
|
|
|
|
symbol = (void *)GetProcAddress((HMODULE)handle, name); |
|
|
if ( symbol == NULL ) { |
|
|
FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS | |
|
|
FORMAT_MESSAGE_FROM_SYSTEM), |
|
|
NULL, GetLastError(), |
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
|
errbuf, SDL_TABLESIZE(errbuf), NULL); |
|
|
loaderror = errbuf; |
|
|
} |
|
|
#elif defined(__BEOS__) |
|
|
/* * */ |
|
|
image_id library_id = (image_id)handle; |
|
|
if ( get_image_symbol(library_id, |
|
|
name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) { |
|
|
loaderror = "Symbol not found"; |
|
|
} |
|
|
#elif defined(macintosh) |
|
|
/* * */ |
|
|
CFragSymbolClass class; |
|
|
CFragConnectionID library_id = (CFragConnectionID)handle; |
|
|
char pname[512]; |
|
|
|
|
|
strncpy(pname, name, SDL_TABLESIZE(pname)); |
|
|
pname[SDL_TABLESIZE(pname)-1] = '\0'; |
|
|
if ( FindSymbol(library_id, C2PStr(pname), |
|
|
(char **)&symbol, &class) != noErr ) { |
|
|
loaderror = "Symbol not found"; |
|
|
} |
|
|
#elif defined(__MINT__) && defined(ENABLE_LDG) |
|
|
/* * */ |
|
|
symbol = (void *)ldg_find((char *)name, (LDG *)handle); |
|
|
#endif /* system type */ |
|
|
|
|
|
if ( symbol == NULL ) { |
|
|
SDL_SetError("Failed loading %s: %s", name, loaderror); |
|
|
} |
|
|
return(symbol); |
|
|
} |
|
|
|
|
|
void SDL_UnloadObject(void *handle) |
|
|
{ |
|
|
#if defined(__BEOS__) |
|
|
image_id library_id; |
|
|
#elif defined(macintosh) |
|
|
CFragConnectionID library_id; |
|
|
#endif |
|
|
if ( handle == NULL ) { |
|
|
return; |
|
|
} |
|
|
#if defined(USE_DLOPEN) |
|
|
/* * */ |
|
|
dlclose(handle); |
|
|
#elif defined(WIN32) |
|
|
/* * */ |
|
|
FreeLibrary((HMODULE)handle); |
|
|
#elif defined(__BEOS__) |
|
|
/* * */ |
|
|
library_id = (image_id)handle; |
|
|
unload_add_on(library_id); |
|
|
#elif defined(macintosh) |
|
|
/* * */ |
|
|
library_id = (CFragConnectionID)handle; |
|
|
CloseConnection(&library_id); |
|
|
#elif defined(__MINT__) && defined(ENABLE_LDG) |
|
|
/* * */ |
|
|
ldg_close((LDG *)handle, ldg_global); |
|
|
#endif /* system type */ |
|
|
} |