Mercurial > sdl-ios-xcode
changeset 294:d2d48e10f370
Added a new header file: SDL_loadso.h
It contains the following functions:
SDL_LoadObject(), SDL_LoadFunction(), SDL_UnloadObject()
The UNIX esd and arts audio code use these to dynamically load
their respective audio libraries.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 06 Mar 2002 05:20:11 +0000 |
parents | 585a7e1285ae |
children | 54ad1d2f1325 |
files | WhatsNew configure.in docs.html include/Makefile.am include/SDL.h include/SDL_loadso.h include/SDL_name.h src/Makefile.am src/SDL_loadso.c src/audio/arts/Makefile.am src/audio/arts/SDL_artsaudio.c src/audio/esd/Makefile.am src/audio/esd/SDL_esdaudio.c |
diffstat | 13 files changed, 516 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/WhatsNew Tue Mar 05 23:19:37 2002 +0000 +++ b/WhatsNew Wed Mar 06 05:20:11 2002 +0000 @@ -4,6 +4,12 @@ Version 1.0: 1.2.4: + Added a new header file: SDL_loadso.h + It contains the following functions: + SDL_LoadObject(), SDL_LoadFunction(), SDL_UnloadObject() + The UNIX esd and arts audio code use these to dynamically load + their respective audio libraries. + Added SDL_LockRect() and SDL_UnlockRect() to lock a portion of a surface. This may be more efficient than a full lock if you are using a hardware surface and plan to make a few changes to small
--- a/configure.in Tue Mar 05 23:19:37 2002 +0000 +++ b/configure.in Wed Mar 06 05:20:11 2002 +0000 @@ -324,12 +324,26 @@ [ --enable-esd support the Enlightened Sound Daemon [default=yes]], , enable_esd=yes) if test x$enable_audio = xyes -a x$enable_esd = xyes; then - AM_PATH_ESD(0.2.8, [ - CFLAGS="$CFLAGS -DESD_SUPPORT $ESD_CFLAGS" - SYSTEM_LIBS="$SYSTEM_LIBS $ESD_LIBS" + use_esd=no + AM_PATH_ESD(0.2.8, use_esd=yes) + if test x$use_esd = xyes; then + AC_ARG_ENABLE(esd-shared, +[ --enable-esd-shared dynamically load ESD support [default=yes]], + , enable_esd_shared=yes) + esd_lib_spec=`echo $ESD_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libesd.so.*/'` + esd_lib=`ls $esd_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` + echo "-- $esd_lib_spec -> $esd_lib" + if test x$enable_dlopen = xyes && \ + test x$enable_esd_shared = xyes && test x$esd_lib != x; then + CFLAGS="$CFLAGS -DESD_SUPPORT -DESD_DYNAMIC=\$(esd_lib) $ESD_CFLAGS" + AC_SUBST(esd_lib) + else + CFLAGS="$CFLAGS -DESD_SUPPORT $ESD_CFLAGS" + SYSTEM_LIBS="$SYSTEM_LIBS $ESD_LIBS" + fi AUDIO_SUBDIRS="$AUDIO_SUBDIRS esd" AUDIO_DRIVERS="$AUDIO_DRIVERS esd/libaudio_esd.la" - ]) + fi fi } @@ -359,8 +373,20 @@ CFLAGS="$save_CFLAGS" AC_MSG_RESULT($audio_arts) if test x$audio_arts = xyes; then - CFLAGS="$CFLAGS -DARTSC_SUPPORT $ARTSC_CFLAGS" - SYSTEM_LIBS="$SYSTEM_LIBS $ARTSC_LIBS" + AC_ARG_ENABLE(arts-shared, +[ --enable-arts-shared dynamically load ESD support [default=yes]], + , enable_arts_shared=yes) + arts_lib_spec=`echo $ARTSC_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libarts.so.*/'` + arts_lib=`ls $arts_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'` + echo "-- $arts_lib_spec -> $arts_lib" + if test x$enable_dlopen = xyes && \ + test x$enable_arts_shared = xyes && test x$arts_lib != x; then + CFLAGS="$CFLAGS -DARTSC_SUPPORT -DARTSC_DYNAMIC=\$(arts_lib) $ARTSC_CFLAGS" + AC_SUBST(arts_lib) + else + CFLAGS="$CFLAGS -DARTSC_SUPPORT $ARTSC_CFLAGS" + SYSTEM_LIBS="$SYSTEM_LIBS $ARTSC_LIBS" + fi AUDIO_SUBDIRS="$AUDIO_SUBDIRS arts" AUDIO_DRIVERS="$AUDIO_DRIVERS arts/libaudio_arts.la" fi @@ -1353,11 +1379,36 @@ VIDEO_DRIVERS="$VIDEO_DRIVERS quartz/libvideo_quartz.la" } +dnl Check for the dlfcn.h interface for dynamically loading objects +CheckDLOPEN() +{ + AC_ARG_ENABLE(dlopen, +[ --enable-dlopen use dlopen for shared object loading [default=yes]], + , enable_dlopen=yes) + if test x$enable_dlopen = xyes; then + AC_MSG_CHECKING(for dlopen) + use_dlopen=no + AC_TRY_COMPILE([ + #include <dlfcn.h> + ],[ + ],[ + use_dlopen=yes + ]) + AC_MSG_RESULT($use_dlopen) + + if test x$use_dlopen = xyes; then + CFLAGS="$CFLAGS -DUSE_DLOPEN" + SYSTEM_LIBS="$SYSTEM_LIBS -ldl" + fi + fi +} + case "$target" in *-*-linux*) ARCH=linux CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNASM CheckOSS CheckALSA @@ -1429,6 +1480,7 @@ ARCH=bsdi CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1480,6 +1532,7 @@ ARCH=freebsd CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckVGL CheckNASM CheckOSS @@ -1535,6 +1588,7 @@ ARCH=netbsd CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1588,6 +1642,7 @@ ARCH=openbsd CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckOPENBSDAUDIO CheckNASM CheckOSS @@ -1647,6 +1702,7 @@ ARCH=sysv5 CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1696,6 +1752,7 @@ CFLAGS="$CFLAGS -D__ELF__" # Fix for nasm on Solaris x86 CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNASM CheckOSS CheckARTSC @@ -1744,6 +1801,7 @@ ARCH=irix CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckDMEDIA CheckESD CheckNAS @@ -1806,6 +1864,7 @@ ARCH=hpux CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckOSS CheckNAS CheckX11 @@ -1853,6 +1912,7 @@ ARCH=aix CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckOSS CheckNAS CheckX11 @@ -1898,6 +1958,7 @@ ARCH=osf CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNAS CheckX11 CheckGGI @@ -1944,6 +2005,7 @@ ARCH=qnx CheckDummyVideo CheckDiskAudio + CheckDLOPEN CheckNAS CheckPHOTON CheckX11
--- a/docs.html Tue Mar 05 23:19:37 2002 +0000 +++ b/docs.html Wed Mar 06 05:20:11 2002 +0000 @@ -16,6 +16,7 @@ Major changes since SDL 1.0.0: </H2> <UL> + <LI> 1.2.4: Added shared object loading functions in SDL_loadso.h <LI> 1.2.4: Added SDL_LockRect() and SDL_UnlockRect() <LI> 1.2.4: Incorporated XFree86 extension libraries into the source <LI> 1.2.4: Added initial support for Atari (thanks Patrice!)
--- a/include/Makefile.am Tue Mar 05 23:19:37 2002 +0000 +++ b/include/Makefile.am Wed Mar 06 05:20:11 2002 +0000 @@ -18,6 +18,7 @@ SDL_joystick.h \ SDL_keyboard.h \ SDL_keysym.h \ + SDL_loadso.h \ SDL_main.h \ SDL_mouse.h \ SDL_mutex.h \
--- a/include/SDL.h Tue Mar 05 23:19:37 2002 +0000 +++ b/include/SDL.h Wed Mar 06 05:20:11 2002 +0000 @@ -34,6 +34,7 @@ #include "SDL_types.h" #include "SDL_getenv.h" #include "SDL_error.h" +#include "SDL_loadso.h" #include "SDL_rwops.h" #include "SDL_timer.h" #include "SDL_audio.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/SDL_loadso.h Wed Mar 06 05:20:11 2002 +0000 @@ -0,0 +1,61 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#ifndef _SDL_loadso_h +#define _SDL_loadso_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This function dynamically loads a shared object and returns a pointer + * to the object handle (or NULL if there was an error). + * The 'sofile' parameter is a system dependent name of the object file. + */ +extern DECLSPEC void *SDL_LoadObject(const char *sofile); + +/* Given an object handle, this function looks up the address of the + * named function in the shared object and returns it. This address + * is no longer valid after calling SDL_UnloadObject(). + */ +extern DECLSPEC void *SDL_LoadFunction(void *handle, const char *name); + +/* Unload a shared object from memory */ +extern DECLSPEC void SDL_UnloadObject(void *handle); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_loadso_h */
--- a/include/SDL_name.h Tue Mar 05 23:19:37 2002 +0000 +++ b/include/SDL_name.h Wed Mar 06 05:20:11 2002 +0000 @@ -6,8 +6,6 @@ #define NeedFunctionPrototypes 1 #endif -#ifndef SDL_NAME #define SDL_NAME(X) SDL_##X -#endif #endif /* _SDLname_h_ */
--- a/src/Makefile.am Tue Mar 05 23:19:37 2002 +0000 +++ b/src/Makefile.am Wed Mar 06 05:20:11 2002 +0000 @@ -37,5 +37,6 @@ SDL_error_c.h \ SDL_fatal.c \ SDL_fatal.h \ - SDL_getenv.c + SDL_getenv.c \ + SDL_loadso.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/SDL_loadso.c Wed Mar 06 05:20:11 2002 +0000 @@ -0,0 +1,193 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id$"; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* System dependent library loading routines */ + +#include <stdio.h> +#if defined(USE_DLOPEN) +# include <dlfcn.h> +#elif defined(WIN32) +# include <windows.h> +#elif defined(__BEOS__) +# include <be/kernel/image.h> +#elif defined(macintosh) +# include <string.h> +# include <Strings.h> +# include <CodeFragments.h> +# include <Errors.h> +#else +/*#error Unsupported dynamic link environment*/ +#endif /* system type */ + +#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) +/* * */ + 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: + 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); + } +#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) +/* * */ + 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"; + } +#endif /* system type */ + + if ( symbol == NULL ) { + SDL_SetError("Failed loading %s: %s", name, loaderror); + } + return(symbol); +} + +void SDL_UnloadObject(void *handle) +{ + if ( handle == NULL ) { + return; + } +#if defined(USE_DLOPEN) +/* * */ + dlclose(handle); +#elif defined(WIN32) +/* * */ + FreeLibrary((HMODULE)handle); +#elif defined(__BEOS__) +/* * */ + image_id library_id = (image_id)handle; + unload_add_on(library_id); +#elif defined(macintosh) +/* * */ + CFragConnectionID library_id = (CFragConnectionID)handle; + CloseConnection(library_id); +#endif /* system type */ +}
--- a/src/audio/arts/Makefile.am Tue Mar 05 23:19:37 2002 +0000 +++ b/src/audio/arts/Makefile.am Wed Mar 06 05:20:11 2002 +0000 @@ -4,6 +4,8 @@ noinst_LTLIBRARIES = libaudio_arts.la libaudio_arts_la_SOURCES = $(SRCS) +arts_lib = \"@arts_lib@\" + # The SDL audio driver sources SRCS = SDL_artsaudio.c \ SDL_artsaudio.h
--- a/src/audio/arts/SDL_artsaudio.c Tue Mar 05 23:19:37 2002 +0000 +++ b/src/audio/arts/SDL_artsaudio.c Wed Mar 06 05:20:11 2002 +0000 @@ -43,6 +43,13 @@ #include "SDL_audiodev_c.h" #include "SDL_artsaudio.h" +#ifdef ARTSC_DYNAMIC +#include "SDL_name.h" +#include "SDL_loadso.h" +#else +#define SDL_NAME(X) X +#endif + /* The tag name used by artsc audio */ #define ARTSC_DRIVER_NAME "artsc" @@ -53,20 +60,96 @@ static Uint8 *ARTSC_GetAudioBuf(_THIS); static void ARTSC_CloseAudio(_THIS); +#ifdef ARTSC_DYNAMIC + +static const char *arts_library = ARTSC_DYNAMIC; +static void *arts_handle = NULL; +static int arts_loaded = 0; + +static int (*SDL_NAME(arts_init))(); +static int (*SDL_NAME(arts_free))(); +static int (*SDL_NAME(arts_play_stream))(); +static int (*SDL_NAME(arts_stream_set))(); +static int (*SDL_NAME(arts_stream_get))(); +static int (*SDL_NAME(arts_write))(); +static int (*SDL_NAME(arts_close_stream))(); +static struct { + const char *name; + void **func; +} arts_functions[] = { + { "arts_init", (void **)&SDL_NAME(arts_init) }, + { "arts_free", (void **)&SDL_NAME(arts_free) }, + { "arts_play_stream", (void **)&SDL_NAME(arts_play_stream) }, + { "arts_stream_set", (void **)&SDL_NAME(arts_stream_set) }, + { "arts_stream_get", (void **)&SDL_NAME(arts_stream_get) }, + { "arts_write", (void **)&SDL_NAME(arts_write) }, + { "arts_close_stream", (void **)&SDL_NAME(arts_close_stream) }, +}; + +static void UnloadARTSLibrary() +{ + if ( arts_loaded ) { + SDL_UnloadObject(arts_handle); + arts_handle = NULL; + arts_loaded = 0; + } +} + +static int LoadARTSLibrary(void) +{ + int i, retval = -1; + + arts_handle = SDL_LoadObject(arts_library); + if ( arts_handle ) { + arts_loaded = 1; + retval = 0; + for ( i=0; i<SDL_TABLESIZE(arts_functions); ++i ) { + *arts_functions[i].func = SDL_LoadFunction(arts_handle, arts_functions[i].name); + if ( ! arts_functions[i].func ) { + retval = -1; + UnloadARTSLibrary(); + break; + } + } + } + return retval; +} + +#else + +static void UnloadARTSLibrary() +{ + return; +} + +static int LoadARTSLibrary(void) +{ + return 0; +} + +#endif /* ARTSC_DYNAMIC */ + /* Audio driver bootstrap functions */ static int Audio_Available(void) { - if(arts_init()) - return 0; - else - return 1; + int available = 0; + + if ( LoadARTSLibrary() < 0 ) { + return available; + } + if ( SDL_NAME(arts_init)() == 0 ) { + available = 1; + SDL_NAME(arts_free)(); + } + UnloadARTSLibrary(); } static void Audio_DeleteDevice(SDL_AudioDevice *device) { free(device->hidden); free(device); + UnloadARTSLibrary(); } static SDL_AudioDevice *Audio_CreateDevice(int devindex) @@ -74,6 +157,7 @@ SDL_AudioDevice *this; /* Initialize all variables that we clean on shutdown */ + LoadARTSLibrary(); this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); if ( this ) { memset(this, 0, (sizeof *this)); @@ -136,7 +220,7 @@ int written; /* Write the audio data */ - written = arts_write(stream, mixbuf, mixlen); + written = SDL_NAME(arts_write)(stream, mixbuf, mixlen); /* If timer synchronization is enabled, set the next write frame */ if ( frame_ticks ) { @@ -164,9 +248,10 @@ mixbuf = NULL; } if ( stream ) { - arts_close_stream(stream); + SDL_NAME(arts_close_stream)(stream); stream = 0; } + SDL_NAME(arts_free)(); } static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec) @@ -210,7 +295,11 @@ } spec->format = test_format; - stream = arts_play_stream(spec->freq, bits, spec->channels, "SDL"); + if ( SDL_NAME(arts_init)() != 0 ) { + SDL_SetError("Unable to initialize ARTS"); + return(-1); + } + stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL"); /* Calculate the final parameters for this audio specification */ SDL_CalculateAudioSpec(spec); @@ -224,12 +313,12 @@ frag_spec |= 0x00020000; /* two fragments, for low latency */ #ifdef ARTS_P_PACKET_SETTINGS - arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec); + SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SETTINGS, frag_spec); #else - arts_stream_set(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff); - arts_stream_set(stream, ARTS_P_PACKET_COUNT, frag_spec>>16); + SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff); + SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_COUNT, frag_spec>>16); #endif - spec->size = arts_stream_get(stream, ARTS_P_PACKET_SIZE); + spec->size = SDL_NAME(arts_stream_get)(stream, ARTS_P_PACKET_SIZE); /* Allocate mixing buffer */ mixlen = spec->size;
--- a/src/audio/esd/Makefile.am Tue Mar 05 23:19:37 2002 +0000 +++ b/src/audio/esd/Makefile.am Wed Mar 06 05:20:11 2002 +0000 @@ -4,6 +4,8 @@ noinst_LTLIBRARIES = libaudio_esd.la libaudio_esd_la_SOURCES = $(SRCS) +esd_lib = \"@esd_lib@\" + # The SDL audio driver sources SRCS = SDL_esdaudio.c \ SDL_esdaudio.h
--- a/src/audio/esd/SDL_esdaudio.c Tue Mar 05 23:19:37 2002 +0000 +++ b/src/audio/esd/SDL_esdaudio.c Wed Mar 06 05:20:11 2002 +0000 @@ -46,6 +46,13 @@ #include "SDL_audiodev_c.h" #include "SDL_esdaudio.h" +#ifdef ESD_DYNAMIC +#include "SDL_name.h" +#include "SDL_loadso.h" +#else +#define SDL_NAME(X) X +#endif + /* The tag name used by ESD audio */ #define ESD_DRIVER_NAME "esd" @@ -56,6 +63,68 @@ static Uint8 *ESD_GetAudioBuf(_THIS); static void ESD_CloseAudio(_THIS); +#ifdef ESD_DYNAMIC + +static const char *esd_library = ESD_DYNAMIC; +static void *esd_handle = NULL; +static int esd_loaded = 0; + +static int (*SDL_NAME(esd_open_sound))( const char *host ); +static int (*SDL_NAME(esd_close))( int esd ); +static int (*SDL_NAME(esd_play_stream))( esd_format_t format, int rate, + const char *host, const char *name ); +static struct { + const char *name; + void **func; +} esd_functions[] = { + { "esd_open_sound", (void **)&SDL_NAME(esd_open_sound) }, + { "esd_close", (void **)&SDL_NAME(esd_close) }, + { "esd_play_stream", (void **)&SDL_NAME(esd_play_stream) }, +}; + +static void UnloadESDLibrary() +{ + if ( esd_loaded ) { + SDL_UnloadObject(esd_handle); + esd_handle = NULL; + esd_loaded = 0; + } +} + +static int LoadESDLibrary(void) +{ + int i, retval = -1; + + esd_handle = SDL_LoadObject(esd_library); + if ( esd_handle ) { + esd_loaded = 1; + retval = 0; + for ( i=0; i<SDL_TABLESIZE(esd_functions); ++i ) { + *esd_functions[i].func = SDL_LoadFunction(esd_handle, esd_functions[i].name); + if ( ! esd_functions[i].func ) { + retval = -1; + UnloadESDLibrary(); + break; + } + } + } + return retval; +} + +#else + +static void UnloadESDLibrary() +{ + return; +} + +static int LoadESDLibrary(void) +{ + return 0; +} + +#endif /* ESD_DYNAMIC */ + /* Audio driver bootstrap functions */ static int Audio_Available(void) @@ -64,11 +133,15 @@ int available; available = 0; - connection = esd_open_sound(NULL); + if ( LoadESDLibrary() < 0 ) { + return available; + } + connection = SDL_NAME(esd_open_sound)(NULL); if ( connection >= 0 ) { available = 1; - esd_close(connection); + SDL_NAME(esd_close)(connection); } + UnloadESDLibrary(); return(available); } @@ -76,6 +149,7 @@ { free(device->hidden); free(device); + UnloadESDLibrary(); } static SDL_AudioDevice *Audio_CreateDevice(int devindex) @@ -83,6 +157,7 @@ SDL_AudioDevice *this; /* Initialize all variables that we clean on shutdown */ + LoadESDLibrary(); this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice)); if ( this ) { memset(this, 0, (sizeof *this)); @@ -174,7 +249,7 @@ mixbuf = NULL; } if ( audio_fd >= 0 ) { - close(audio_fd); + SDL_NAME(esd_close)(audio_fd); audio_fd = -1; } } @@ -231,7 +306,7 @@ #endif /* Open a connection to the ESD audio server */ - audio_fd = esd_play_stream(format, spec->freq, NULL, get_progname()); + audio_fd = SDL_NAME(esd_play_stream)(format, spec->freq, NULL, get_progname()); if ( audio_fd < 0 ) { SDL_SetError("Couldn't open ESD connection"); return(-1);