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.
--- 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);