Added a new header file: SDL_loadso.h
authorSam Lantinga <slouken@libsdl.org>
Wed, 06 Mar 2002 05:20:11 +0000
changeset 294d2d48e10f370
parent 293 585a7e1285ae
child 295 54ad1d2f1325
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.
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
     1.1 --- a/WhatsNew	Tue Mar 05 23:19:37 2002 +0000
     1.2 +++ b/WhatsNew	Wed Mar 06 05:20:11 2002 +0000
     1.3 @@ -4,6 +4,12 @@
     1.4  Version 1.0:
     1.5  
     1.6  1.2.4:
     1.7 +	Added a new header file: SDL_loadso.h
     1.8 +	It contains the following functions:
     1.9 +		SDL_LoadObject(), SDL_LoadFunction(), SDL_UnloadObject()
    1.10 +	The UNIX esd and arts audio code use these to dynamically load
    1.11 +	their respective audio libraries.
    1.12 +
    1.13  	Added SDL_LockRect() and SDL_UnlockRect() to lock a portion of a
    1.14  	surface.  This may be more efficient than a full lock if you are
    1.15  	using a hardware surface and plan to make a few changes to small
     2.1 --- a/configure.in	Tue Mar 05 23:19:37 2002 +0000
     2.2 +++ b/configure.in	Wed Mar 06 05:20:11 2002 +0000
     2.3 @@ -324,12 +324,26 @@
     2.4  [  --enable-esd            support the Enlightened Sound Daemon [default=yes]],
     2.5                    , enable_esd=yes)
     2.6      if test x$enable_audio = xyes -a x$enable_esd = xyes; then
     2.7 -        AM_PATH_ESD(0.2.8, [
     2.8 -            CFLAGS="$CFLAGS -DESD_SUPPORT $ESD_CFLAGS"
     2.9 -            SYSTEM_LIBS="$SYSTEM_LIBS $ESD_LIBS"
    2.10 +	use_esd=no
    2.11 +        AM_PATH_ESD(0.2.8, use_esd=yes)
    2.12 +	if test x$use_esd = xyes; then
    2.13 +            AC_ARG_ENABLE(esd-shared,
    2.14 +[  --enable-esd-shared     dynamically load ESD support [default=yes]],
    2.15 +                          , enable_esd_shared=yes)
    2.16 +            esd_lib_spec=`echo $ESD_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libesd.so.*/'`
    2.17 +	    esd_lib=`ls $esd_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'`
    2.18 +	    echo "-- $esd_lib_spec -> $esd_lib"
    2.19 +            if test x$enable_dlopen = xyes && \
    2.20 +               test x$enable_esd_shared = xyes && test x$esd_lib != x; then
    2.21 +                CFLAGS="$CFLAGS -DESD_SUPPORT -DESD_DYNAMIC=\$(esd_lib) $ESD_CFLAGS"
    2.22 +		AC_SUBST(esd_lib)
    2.23 +            else
    2.24 +                CFLAGS="$CFLAGS -DESD_SUPPORT $ESD_CFLAGS"
    2.25 +                SYSTEM_LIBS="$SYSTEM_LIBS $ESD_LIBS"
    2.26 +            fi
    2.27              AUDIO_SUBDIRS="$AUDIO_SUBDIRS esd"
    2.28              AUDIO_DRIVERS="$AUDIO_DRIVERS esd/libaudio_esd.la"
    2.29 -        ])
    2.30 +        fi
    2.31      fi
    2.32  }
    2.33  
    2.34 @@ -359,8 +373,20 @@
    2.35              CFLAGS="$save_CFLAGS"
    2.36              AC_MSG_RESULT($audio_arts)
    2.37              if test x$audio_arts = xyes; then
    2.38 -                CFLAGS="$CFLAGS -DARTSC_SUPPORT $ARTSC_CFLAGS"
    2.39 -                SYSTEM_LIBS="$SYSTEM_LIBS $ARTSC_LIBS"
    2.40 +                AC_ARG_ENABLE(arts-shared,
    2.41 +[  --enable-arts-shared     dynamically load ESD support [default=yes]],
    2.42 +                              , enable_arts_shared=yes)
    2.43 +                arts_lib_spec=`echo $ARTSC_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libarts.so.*/'`
    2.44 +	        arts_lib=`ls $arts_lib_spec | head -1 | sed 's/.*\/\(.*\)/\1/'`
    2.45 +	        echo "-- $arts_lib_spec -> $arts_lib"
    2.46 +                if test x$enable_dlopen = xyes && \
    2.47 +                   test x$enable_arts_shared = xyes && test x$arts_lib != x; then
    2.48 +                    CFLAGS="$CFLAGS -DARTSC_SUPPORT -DARTSC_DYNAMIC=\$(arts_lib) $ARTSC_CFLAGS"
    2.49 +		    AC_SUBST(arts_lib)
    2.50 +                else
    2.51 +                    CFLAGS="$CFLAGS -DARTSC_SUPPORT $ARTSC_CFLAGS"
    2.52 +                    SYSTEM_LIBS="$SYSTEM_LIBS $ARTSC_LIBS"
    2.53 +                fi
    2.54                  AUDIO_SUBDIRS="$AUDIO_SUBDIRS arts"
    2.55                  AUDIO_DRIVERS="$AUDIO_DRIVERS arts/libaudio_arts.la"
    2.56              fi
    2.57 @@ -1353,11 +1379,36 @@
    2.58      VIDEO_DRIVERS="$VIDEO_DRIVERS quartz/libvideo_quartz.la"
    2.59  }
    2.60  
    2.61 +dnl Check for the dlfcn.h interface for dynamically loading objects
    2.62 +CheckDLOPEN()
    2.63 +{
    2.64 +    AC_ARG_ENABLE(dlopen,
    2.65 +[  --enable-dlopen         use dlopen for shared object loading [default=yes]],
    2.66 +                  , enable_dlopen=yes)
    2.67 +    if test x$enable_dlopen = xyes; then
    2.68 +        AC_MSG_CHECKING(for dlopen)
    2.69 +        use_dlopen=no
    2.70 +        AC_TRY_COMPILE([
    2.71 +         #include <dlfcn.h>
    2.72 +        ],[
    2.73 +        ],[
    2.74 +        use_dlopen=yes
    2.75 +        ])
    2.76 +        AC_MSG_RESULT($use_dlopen)
    2.77 +
    2.78 +        if test x$use_dlopen = xyes; then
    2.79 +            CFLAGS="$CFLAGS -DUSE_DLOPEN"
    2.80 +            SYSTEM_LIBS="$SYSTEM_LIBS -ldl"
    2.81 +        fi
    2.82 +    fi
    2.83 +}
    2.84 +
    2.85  case "$target" in
    2.86      *-*-linux*)
    2.87          ARCH=linux
    2.88          CheckDummyVideo
    2.89          CheckDiskAudio
    2.90 +	CheckDLOPEN
    2.91          CheckNASM
    2.92          CheckOSS
    2.93          CheckALSA
    2.94 @@ -1429,6 +1480,7 @@
    2.95          ARCH=bsdi
    2.96          CheckDummyVideo
    2.97          CheckDiskAudio
    2.98 +	CheckDLOPEN
    2.99          CheckNASM
   2.100          CheckOSS
   2.101          CheckARTSC
   2.102 @@ -1480,6 +1532,7 @@
   2.103          ARCH=freebsd
   2.104          CheckDummyVideo
   2.105          CheckDiskAudio
   2.106 +	CheckDLOPEN
   2.107          CheckVGL
   2.108          CheckNASM
   2.109          CheckOSS
   2.110 @@ -1535,6 +1588,7 @@
   2.111          ARCH=netbsd
   2.112          CheckDummyVideo
   2.113          CheckDiskAudio
   2.114 +	CheckDLOPEN
   2.115          CheckNASM
   2.116          CheckOSS
   2.117          CheckARTSC
   2.118 @@ -1588,6 +1642,7 @@
   2.119          ARCH=openbsd
   2.120          CheckDummyVideo
   2.121          CheckDiskAudio
   2.122 +	CheckDLOPEN
   2.123          CheckOPENBSDAUDIO
   2.124          CheckNASM
   2.125          CheckOSS
   2.126 @@ -1647,6 +1702,7 @@
   2.127          ARCH=sysv5
   2.128          CheckDummyVideo
   2.129          CheckDiskAudio
   2.130 +	CheckDLOPEN
   2.131          CheckNASM
   2.132          CheckOSS
   2.133          CheckARTSC
   2.134 @@ -1696,6 +1752,7 @@
   2.135          CFLAGS="$CFLAGS -D__ELF__" # Fix for nasm on Solaris x86
   2.136          CheckDummyVideo
   2.137          CheckDiskAudio
   2.138 +	CheckDLOPEN
   2.139          CheckNASM
   2.140          CheckOSS
   2.141          CheckARTSC
   2.142 @@ -1744,6 +1801,7 @@
   2.143          ARCH=irix
   2.144          CheckDummyVideo
   2.145          CheckDiskAudio
   2.146 +	CheckDLOPEN
   2.147          CheckDMEDIA
   2.148          CheckESD
   2.149          CheckNAS
   2.150 @@ -1806,6 +1864,7 @@
   2.151          ARCH=hpux
   2.152          CheckDummyVideo
   2.153          CheckDiskAudio
   2.154 +	CheckDLOPEN
   2.155          CheckOSS
   2.156          CheckNAS
   2.157          CheckX11
   2.158 @@ -1853,6 +1912,7 @@
   2.159          ARCH=aix
   2.160          CheckDummyVideo
   2.161          CheckDiskAudio
   2.162 +	CheckDLOPEN
   2.163          CheckOSS
   2.164          CheckNAS
   2.165          CheckX11
   2.166 @@ -1898,6 +1958,7 @@
   2.167          ARCH=osf
   2.168          CheckDummyVideo
   2.169          CheckDiskAudio
   2.170 +	CheckDLOPEN
   2.171          CheckNAS
   2.172          CheckX11
   2.173          CheckGGI
   2.174 @@ -1944,6 +2005,7 @@
   2.175          ARCH=qnx
   2.176          CheckDummyVideo
   2.177          CheckDiskAudio
   2.178 +	CheckDLOPEN
   2.179          CheckNAS
   2.180          CheckPHOTON
   2.181          CheckX11
     3.1 --- a/docs.html	Tue Mar 05 23:19:37 2002 +0000
     3.2 +++ b/docs.html	Wed Mar 06 05:20:11 2002 +0000
     3.3 @@ -16,6 +16,7 @@
     3.4  Major changes since SDL 1.0.0:
     3.5  </H2>
     3.6  <UL>
     3.7 +	<LI> 1.2.4: Added shared object loading functions in SDL_loadso.h
     3.8  	<LI> 1.2.4: Added SDL_LockRect() and SDL_UnlockRect()
     3.9  	<LI> 1.2.4: Incorporated XFree86 extension libraries into the source
    3.10  	<LI> 1.2.4: Added initial support for Atari (thanks Patrice!)
     4.1 --- a/include/Makefile.am	Tue Mar 05 23:19:37 2002 +0000
     4.2 +++ b/include/Makefile.am	Wed Mar 06 05:20:11 2002 +0000
     4.3 @@ -18,6 +18,7 @@
     4.4  	SDL_joystick.h		\
     4.5  	SDL_keyboard.h		\
     4.6  	SDL_keysym.h		\
     4.7 +	SDL_loadso.h		\
     4.8  	SDL_main.h		\
     4.9  	SDL_mouse.h		\
    4.10  	SDL_mutex.h		\
     5.1 --- a/include/SDL.h	Tue Mar 05 23:19:37 2002 +0000
     5.2 +++ b/include/SDL.h	Wed Mar 06 05:20:11 2002 +0000
     5.3 @@ -34,6 +34,7 @@
     5.4  #include "SDL_types.h"
     5.5  #include "SDL_getenv.h"
     5.6  #include "SDL_error.h"
     5.7 +#include "SDL_loadso.h"
     5.8  #include "SDL_rwops.h"
     5.9  #include "SDL_timer.h"
    5.10  #include "SDL_audio.h"
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/include/SDL_loadso.h	Wed Mar 06 05:20:11 2002 +0000
     6.3 @@ -0,0 +1,61 @@
     6.4 +/*
     6.5 +    SDL - Simple DirectMedia Layer
     6.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     6.7 +
     6.8 +    This library is free software; you can redistribute it and/or
     6.9 +    modify it under the terms of the GNU Library General Public
    6.10 +    License as published by the Free Software Foundation; either
    6.11 +    version 2 of the License, or (at your option) any later version.
    6.12 +
    6.13 +    This library is distributed in the hope that it will be useful,
    6.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.16 +    Library General Public License for more details.
    6.17 +
    6.18 +    You should have received a copy of the GNU Library General Public
    6.19 +    License along with this library; if not, write to the Free
    6.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.21 +
    6.22 +    Sam Lantinga
    6.23 +    slouken@libsdl.org
    6.24 +*/
    6.25 +
    6.26 +#ifdef SAVE_RCSID
    6.27 +static char rcsid =
    6.28 + "@(#) $Id$";
    6.29 +#endif
    6.30 +
    6.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    6.32 +/* System dependent library loading routines                           */
    6.33 +
    6.34 +#ifndef _SDL_loadso_h
    6.35 +#define _SDL_loadso_h
    6.36 +
    6.37 +#include "begin_code.h"
    6.38 +/* Set up for C function definitions, even when using C++ */
    6.39 +#ifdef __cplusplus
    6.40 +extern "C" {
    6.41 +#endif
    6.42 +
    6.43 +/* This function dynamically loads a shared object and returns a pointer
    6.44 + * to the object handle (or NULL if there was an error).
    6.45 + * The 'sofile' parameter is a system dependent name of the object file.
    6.46 + */
    6.47 +extern DECLSPEC void *SDL_LoadObject(const char *sofile);
    6.48 +
    6.49 +/* Given an object handle, this function looks up the address of the
    6.50 + * named function in the shared object and returns it.  This address
    6.51 + * is no longer valid after calling SDL_UnloadObject().
    6.52 + */
    6.53 +extern DECLSPEC void *SDL_LoadFunction(void *handle, const char *name);
    6.54 +
    6.55 +/* Unload a shared object from memory */
    6.56 +extern DECLSPEC void SDL_UnloadObject(void *handle);
    6.57 +
    6.58 +/* Ends C function definitions when using C++ */
    6.59 +#ifdef __cplusplus
    6.60 +}
    6.61 +#endif
    6.62 +#include "close_code.h"
    6.63 +
    6.64 +#endif /* _SDL_loadso_h */
     7.1 --- a/include/SDL_name.h	Tue Mar 05 23:19:37 2002 +0000
     7.2 +++ b/include/SDL_name.h	Wed Mar 06 05:20:11 2002 +0000
     7.3 @@ -6,8 +6,6 @@
     7.4  #define NeedFunctionPrototypes 1
     7.5  #endif
     7.6  
     7.7 -#ifndef SDL_NAME
     7.8  #define SDL_NAME(X)	SDL_##X
     7.9 -#endif
    7.10  
    7.11  #endif /* _SDLname_h_ */
     8.1 --- a/src/Makefile.am	Tue Mar 05 23:19:37 2002 +0000
     8.2 +++ b/src/Makefile.am	Wed Mar 06 05:20:11 2002 +0000
     8.3 @@ -37,5 +37,6 @@
     8.4  	SDL_error_c.h		\
     8.5  	SDL_fatal.c		\
     8.6  	SDL_fatal.h		\
     8.7 -	SDL_getenv.c
     8.8 +	SDL_getenv.c		\
     8.9 +	SDL_loadso.c
    8.10  
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/SDL_loadso.c	Wed Mar 06 05:20:11 2002 +0000
     9.3 @@ -0,0 +1,193 @@
     9.4 +/*
     9.5 +    SDL - Simple DirectMedia Layer
     9.6 +    Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
     9.7 +
     9.8 +    This library is free software; you can redistribute it and/or
     9.9 +    modify it under the terms of the GNU Library General Public
    9.10 +    License as published by the Free Software Foundation; either
    9.11 +    version 2 of the License, or (at your option) any later version.
    9.12 +
    9.13 +    This library is distributed in the hope that it will be useful,
    9.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    9.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    9.16 +    Library General Public License for more details.
    9.17 +
    9.18 +    You should have received a copy of the GNU Library General Public
    9.19 +    License along with this library; if not, write to the Free
    9.20 +    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    9.21 +
    9.22 +    Sam Lantinga
    9.23 +    slouken@libsdl.org
    9.24 +*/
    9.25 +
    9.26 +#ifdef SAVE_RCSID
    9.27 +static char rcsid =
    9.28 + "@(#) $Id$";
    9.29 +#endif
    9.30 +
    9.31 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
    9.32 +/* System dependent library loading routines                           */
    9.33 +
    9.34 +#include <stdio.h>
    9.35 +#if defined(USE_DLOPEN)
    9.36 +# include <dlfcn.h>
    9.37 +#elif defined(WIN32)
    9.38 +# include <windows.h>
    9.39 +#elif defined(__BEOS__)
    9.40 +# include <be/kernel/image.h>
    9.41 +#elif defined(macintosh)
    9.42 +# include <string.h>
    9.43 +# include <Strings.h>
    9.44 +# include <CodeFragments.h>
    9.45 +# include <Errors.h>
    9.46 +#else
    9.47 +/*#error Unsupported dynamic link environment*/
    9.48 +#endif /* system type */
    9.49 +
    9.50 +#include "SDL_error.h"
    9.51 +#include "SDL_loadso.h"
    9.52 +
    9.53 +void *SDL_LoadObject(const char *sofile)
    9.54 +{
    9.55 +	void *handle = NULL;
    9.56 +	const char *loaderror = "SDL_LoadObject() not implemented";
    9.57 +#if defined(USE_DLOPEN)
    9.58 +/* * */
    9.59 +	handle = dlopen(sofile, RTLD_NOW);
    9.60 +	loaderror = (char *)dlerror();
    9.61 +#elif defined(WIN32)
    9.62 +/* * */
    9.63 +	char errbuf[512];
    9.64 +
    9.65 +	handle = (void *)LoadLibrary(sofile);
    9.66 +
    9.67 +	/* Generate an error message if all loads failed */
    9.68 +	if ( handle == NULL ) {
    9.69 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
    9.70 +					FORMAT_MESSAGE_FROM_SYSTEM),
    9.71 +				NULL, GetLastError(), 
    9.72 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    9.73 +				errbuf, SDL_TABLESIZE(errbuf), NULL);
    9.74 +		loaderror = errbuf;
    9.75 +	}
    9.76 +#elif defined(__BEOS__)
    9.77 +/* * */
    9.78 +	image_id library_id;
    9.79 +
    9.80 +	library_id = load_add_on(sofile);
    9.81 +	if ( library_id == B_ERROR ) {
    9.82 +		loaderror = "BeOS error";
    9.83 +	} else {
    9.84 +		handle = (void *)(library_id);
    9.85 +	}
    9.86 +#elif defined(macintosh)
    9.87 +/* * */
    9.88 +	CFragConnectionID library_id;
    9.89 +	Ptr mainAddr;
    9.90 +	Str255 errName;
    9.91 +	OSErr error;
    9.92 +	char psofile[512];
    9.93 +
    9.94 +	strncpy(psofile, sofile, SDL_TABLESIZE(psofile));
    9.95 +	psofile[SDL_TABLESIZE(psofile)-1] = '\0';
    9.96 +	error = GetSharedLibrary(C2PStr(psofile), kCompiledCFragArch,
    9.97 +			kLoadCFrag, &library_id, &mainAddr, errName);
    9.98 +	switch (error) {
    9.99 +		case noErr:
   9.100 +			break;
   9.101 +		case cfragNoLibraryErr:
   9.102 +			loaderror = "Library not found";
   9.103 +			break;
   9.104 +		case cfragUnresolvedErr:
   9.105 +			loaderror = "Unabled to resolve symbols";
   9.106 +			break;
   9.107 +		case cfragNoPrivateMemErr:
   9.108 +		case cfragNoClientMemErr:
   9.109 +			loaderror = "Out of memory";
   9.110 +			break;
   9.111 +		default:
   9.112 +			loaderror = "Unknown Code Fragment Manager error";
   9.113 +			break;
   9.114 +	}
   9.115 +	if ( loaderror == NULL ) {
   9.116 +		handle = (void *)(library_id);
   9.117 +	}
   9.118 +#endif /* system type */
   9.119 +
   9.120 +	if ( handle == NULL ) {
   9.121 +		SDL_SetError("Failed loading %s: %s", sofile, loaderror);
   9.122 +	}
   9.123 +	return(handle);
   9.124 +}
   9.125 +
   9.126 +void *SDL_LoadFunction(void *handle, const char *name)
   9.127 +{
   9.128 +	void *symbol = NULL;
   9.129 +	const char *loaderror = "SDL_LoadFunction not implemented";
   9.130 +#if defined(USE_DLOPEN)
   9.131 +/* * */
   9.132 +	symbol = dlsym(handle, name);
   9.133 +	if ( symbol == NULL ) {
   9.134 +		loaderror = (char *)dlerror();
   9.135 +	}
   9.136 +#elif defined(WIN32)
   9.137 +/* * */
   9.138 +	char errbuf[512];
   9.139 +
   9.140 +	symbol = (void *)GetProcAddress((HMODULE)handle, name);
   9.141 +	if ( symbol == NULL ) {
   9.142 +		FormatMessage((FORMAT_MESSAGE_IGNORE_INSERTS |
   9.143 +					FORMAT_MESSAGE_FROM_SYSTEM),
   9.144 +				NULL, GetLastError(), 
   9.145 +				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
   9.146 +				errbuf, SDL_TABLESIZE(errbuf), NULL);
   9.147 +		loaderror = errbuf;
   9.148 +	}
   9.149 +#elif defined(__BEOS__)
   9.150 +/* * */
   9.151 +	image_id library_id = (image_id)handle;
   9.152 +	if ( get_image_symbol(library_id,
   9.153 +		name, B_SYMBOL_TYPE_TEXT, &symbol) != B_NO_ERROR ) {
   9.154 +		loaderror = "Symbol not found";
   9.155 +	}
   9.156 +#elif defined(macintosh)
   9.157 +/* * */
   9.158 +	CFragSymbolClass class;
   9.159 +	CFragConnectionID library_id = (CFragConnectionID)handle;
   9.160 +	char pname[512];
   9.161 +
   9.162 +	strncpy(pname, name, SDL_TABLESIZE(pname));
   9.163 +	pname[SDL_TABLESIZE(pname)-1] = '\0';
   9.164 +	if ( FindSymbol(library_id, C2PStr(pname),
   9.165 +	                (char **)&symbol, &class) != noErr ) {
   9.166 +		loaderror = "Symbol not found";
   9.167 +	}
   9.168 +#endif /* system type */
   9.169 +
   9.170 +	if ( symbol == NULL ) {
   9.171 +		SDL_SetError("Failed loading %s: %s", name, loaderror);
   9.172 +	}
   9.173 +	return(symbol);
   9.174 +}
   9.175 +
   9.176 +void SDL_UnloadObject(void *handle)
   9.177 +{
   9.178 +	if ( handle == NULL ) {
   9.179 +		return;
   9.180 +	}
   9.181 +#if defined(USE_DLOPEN)
   9.182 +/* * */
   9.183 +	dlclose(handle);
   9.184 +#elif defined(WIN32)
   9.185 +/* * */
   9.186 +	FreeLibrary((HMODULE)handle);
   9.187 +#elif defined(__BEOS__)
   9.188 +/* * */
   9.189 +	image_id library_id = (image_id)handle;
   9.190 +	unload_add_on(library_id);
   9.191 +#elif defined(macintosh)
   9.192 +/* * */
   9.193 +	CFragConnectionID library_id = (CFragConnectionID)handle;
   9.194 +	CloseConnection(library_id);
   9.195 +#endif /* system type */
   9.196 +}
    10.1 --- a/src/audio/arts/Makefile.am	Tue Mar 05 23:19:37 2002 +0000
    10.2 +++ b/src/audio/arts/Makefile.am	Wed Mar 06 05:20:11 2002 +0000
    10.3 @@ -4,6 +4,8 @@
    10.4  noinst_LTLIBRARIES = libaudio_arts.la
    10.5  libaudio_arts_la_SOURCES = $(SRCS)
    10.6  
    10.7 +arts_lib = \"@arts_lib@\"
    10.8 +
    10.9  # The SDL audio driver sources
   10.10  SRCS =	SDL_artsaudio.c	\
   10.11  	SDL_artsaudio.h
    11.1 --- a/src/audio/arts/SDL_artsaudio.c	Tue Mar 05 23:19:37 2002 +0000
    11.2 +++ b/src/audio/arts/SDL_artsaudio.c	Wed Mar 06 05:20:11 2002 +0000
    11.3 @@ -43,6 +43,13 @@
    11.4  #include "SDL_audiodev_c.h"
    11.5  #include "SDL_artsaudio.h"
    11.6  
    11.7 +#ifdef ARTSC_DYNAMIC
    11.8 +#include "SDL_name.h"
    11.9 +#include "SDL_loadso.h"
   11.10 +#else
   11.11 +#define SDL_NAME(X)	X
   11.12 +#endif
   11.13 +
   11.14  /* The tag name used by artsc audio */
   11.15  #define ARTSC_DRIVER_NAME         "artsc"
   11.16  
   11.17 @@ -53,20 +60,96 @@
   11.18  static Uint8 *ARTSC_GetAudioBuf(_THIS);
   11.19  static void ARTSC_CloseAudio(_THIS);
   11.20  
   11.21 +#ifdef ARTSC_DYNAMIC
   11.22 +
   11.23 +static const char *arts_library = ARTSC_DYNAMIC;
   11.24 +static void *arts_handle = NULL;
   11.25 +static int arts_loaded = 0;
   11.26 +
   11.27 +static int (*SDL_NAME(arts_init))();
   11.28 +static int (*SDL_NAME(arts_free))();
   11.29 +static int (*SDL_NAME(arts_play_stream))();
   11.30 +static int (*SDL_NAME(arts_stream_set))();
   11.31 +static int (*SDL_NAME(arts_stream_get))();
   11.32 +static int (*SDL_NAME(arts_write))();
   11.33 +static int (*SDL_NAME(arts_close_stream))();
   11.34 +static struct {
   11.35 +	const char *name;
   11.36 +	void **func;
   11.37 +} arts_functions[] = {
   11.38 +	{ "arts_init",		(void **)&SDL_NAME(arts_init)		},
   11.39 +	{ "arts_free",		(void **)&SDL_NAME(arts_free)		},
   11.40 +	{ "arts_play_stream",	(void **)&SDL_NAME(arts_play_stream)	},
   11.41 +	{ "arts_stream_set",	(void **)&SDL_NAME(arts_stream_set)	},
   11.42 +	{ "arts_stream_get",	(void **)&SDL_NAME(arts_stream_get)	},
   11.43 +	{ "arts_write",		(void **)&SDL_NAME(arts_write)		},
   11.44 +	{ "arts_close_stream",	(void **)&SDL_NAME(arts_close_stream)	},
   11.45 +};
   11.46 +
   11.47 +static void UnloadARTSLibrary()
   11.48 +{
   11.49 +	if ( arts_loaded ) {
   11.50 +		SDL_UnloadObject(arts_handle);
   11.51 +		arts_handle = NULL;
   11.52 +		arts_loaded = 0;
   11.53 +	}
   11.54 +}
   11.55 +
   11.56 +static int LoadARTSLibrary(void)
   11.57 +{
   11.58 +	int i, retval = -1;
   11.59 +
   11.60 +	arts_handle = SDL_LoadObject(arts_library);
   11.61 +	if ( arts_handle ) {
   11.62 +		arts_loaded = 1;
   11.63 +		retval = 0;
   11.64 +		for ( i=0; i<SDL_TABLESIZE(arts_functions); ++i ) {
   11.65 +			*arts_functions[i].func = SDL_LoadFunction(arts_handle, arts_functions[i].name);
   11.66 +			if ( ! arts_functions[i].func ) {
   11.67 +				retval = -1;
   11.68 +				UnloadARTSLibrary();
   11.69 +				break;
   11.70 +			}
   11.71 +		}
   11.72 +	}
   11.73 +	return retval;
   11.74 +}
   11.75 +
   11.76 +#else
   11.77 +
   11.78 +static void UnloadARTSLibrary()
   11.79 +{
   11.80 +	return;
   11.81 +}
   11.82 +
   11.83 +static int LoadARTSLibrary(void)
   11.84 +{
   11.85 +	return 0;
   11.86 +}
   11.87 +
   11.88 +#endif /* ARTSC_DYNAMIC */
   11.89 +
   11.90  /* Audio driver bootstrap functions */
   11.91  
   11.92  static int Audio_Available(void)
   11.93  {
   11.94 -	if(arts_init())
   11.95 -		return 0;
   11.96 -	else
   11.97 -		return 1;
   11.98 +	int available = 0;
   11.99 +
  11.100 +	if ( LoadARTSLibrary() < 0 ) {
  11.101 +		return available;
  11.102 +	}
  11.103 +	if ( SDL_NAME(arts_init)() == 0 ) {
  11.104 +		available = 1;
  11.105 +		SDL_NAME(arts_free)();
  11.106 +	}
  11.107 +	UnloadARTSLibrary();
  11.108  }
  11.109  
  11.110  static void Audio_DeleteDevice(SDL_AudioDevice *device)
  11.111  {
  11.112  	free(device->hidden);
  11.113  	free(device);
  11.114 +	UnloadARTSLibrary();
  11.115  }
  11.116  
  11.117  static SDL_AudioDevice *Audio_CreateDevice(int devindex)
  11.118 @@ -74,6 +157,7 @@
  11.119  	SDL_AudioDevice *this;
  11.120  
  11.121  	/* Initialize all variables that we clean on shutdown */
  11.122 +	LoadARTSLibrary();
  11.123  	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
  11.124  	if ( this ) {
  11.125  		memset(this, 0, (sizeof *this));
  11.126 @@ -136,7 +220,7 @@
  11.127  	int written;
  11.128  
  11.129  	/* Write the audio data */
  11.130 -	written = arts_write(stream, mixbuf, mixlen);
  11.131 +	written = SDL_NAME(arts_write)(stream, mixbuf, mixlen);
  11.132  	
  11.133  	/* If timer synchronization is enabled, set the next write frame */
  11.134  	if ( frame_ticks ) {
  11.135 @@ -164,9 +248,10 @@
  11.136  		mixbuf = NULL;
  11.137  	}
  11.138  	if ( stream ) {
  11.139 -		arts_close_stream(stream);
  11.140 +		SDL_NAME(arts_close_stream)(stream);
  11.141  		stream = 0;
  11.142  	}
  11.143 +	SDL_NAME(arts_free)();
  11.144  }
  11.145  
  11.146  static int ARTSC_OpenAudio(_THIS, SDL_AudioSpec *spec)
  11.147 @@ -210,7 +295,11 @@
  11.148  	}
  11.149  	spec->format = test_format;
  11.150  
  11.151 -	stream = arts_play_stream(spec->freq, bits, spec->channels, "SDL");
  11.152 +	if ( SDL_NAME(arts_init)() != 0 ) {
  11.153 +		SDL_SetError("Unable to initialize ARTS");
  11.154 +		return(-1);
  11.155 +	}
  11.156 +	stream = SDL_NAME(arts_play_stream)(spec->freq, bits, spec->channels, "SDL");
  11.157  
  11.158  	/* Calculate the final parameters for this audio specification */
  11.159  	SDL_CalculateAudioSpec(spec);
  11.160 @@ -224,12 +313,12 @@
  11.161  	frag_spec |= 0x00020000;	/* two fragments, for low latency */
  11.162  
  11.163  #ifdef ARTS_P_PACKET_SETTINGS
  11.164 -	arts_stream_set(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
  11.165 +	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SETTINGS, frag_spec);
  11.166  #else
  11.167 -	arts_stream_set(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
  11.168 -	arts_stream_set(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
  11.169 +	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_SIZE, frag_spec&0xffff);
  11.170 +	SDL_NAME(arts_stream_set)(stream, ARTS_P_PACKET_COUNT, frag_spec>>16);
  11.171  #endif
  11.172 -	spec->size = arts_stream_get(stream, ARTS_P_PACKET_SIZE);
  11.173 +	spec->size = SDL_NAME(arts_stream_get)(stream, ARTS_P_PACKET_SIZE);
  11.174  
  11.175  	/* Allocate mixing buffer */
  11.176  	mixlen = spec->size;
    12.1 --- a/src/audio/esd/Makefile.am	Tue Mar 05 23:19:37 2002 +0000
    12.2 +++ b/src/audio/esd/Makefile.am	Wed Mar 06 05:20:11 2002 +0000
    12.3 @@ -4,6 +4,8 @@
    12.4  noinst_LTLIBRARIES = libaudio_esd.la
    12.5  libaudio_esd_la_SOURCES = $(SRCS)
    12.6  
    12.7 +esd_lib = \"@esd_lib@\"
    12.8 +
    12.9  # The SDL audio driver sources
   12.10  SRCS =	SDL_esdaudio.c	\
   12.11  	SDL_esdaudio.h
    13.1 --- a/src/audio/esd/SDL_esdaudio.c	Tue Mar 05 23:19:37 2002 +0000
    13.2 +++ b/src/audio/esd/SDL_esdaudio.c	Wed Mar 06 05:20:11 2002 +0000
    13.3 @@ -46,6 +46,13 @@
    13.4  #include "SDL_audiodev_c.h"
    13.5  #include "SDL_esdaudio.h"
    13.6  
    13.7 +#ifdef ESD_DYNAMIC
    13.8 +#include "SDL_name.h"
    13.9 +#include "SDL_loadso.h"
   13.10 +#else
   13.11 +#define SDL_NAME(X)	X
   13.12 +#endif
   13.13 +
   13.14  /* The tag name used by ESD audio */
   13.15  #define ESD_DRIVER_NAME		"esd"
   13.16  
   13.17 @@ -56,6 +63,68 @@
   13.18  static Uint8 *ESD_GetAudioBuf(_THIS);
   13.19  static void ESD_CloseAudio(_THIS);
   13.20  
   13.21 +#ifdef ESD_DYNAMIC
   13.22 +
   13.23 +static const char *esd_library = ESD_DYNAMIC;
   13.24 +static void *esd_handle = NULL;
   13.25 +static int esd_loaded = 0;
   13.26 +
   13.27 +static int (*SDL_NAME(esd_open_sound))( const char *host );
   13.28 +static int (*SDL_NAME(esd_close))( int esd );
   13.29 +static int (*SDL_NAME(esd_play_stream))( esd_format_t format, int rate,
   13.30 +                                         const char *host, const char *name );
   13.31 +static struct {
   13.32 +	const char *name;
   13.33 +	void **func;
   13.34 +} esd_functions[] = {
   13.35 +	{ "esd_open_sound",	(void **)&SDL_NAME(esd_open_sound)	},
   13.36 +	{ "esd_close",		(void **)&SDL_NAME(esd_close)		},
   13.37 +	{ "esd_play_stream",	(void **)&SDL_NAME(esd_play_stream)	},
   13.38 +};
   13.39 +
   13.40 +static void UnloadESDLibrary()
   13.41 +{
   13.42 +	if ( esd_loaded ) {
   13.43 +		SDL_UnloadObject(esd_handle);
   13.44 +		esd_handle = NULL;
   13.45 +		esd_loaded = 0;
   13.46 +	}
   13.47 +}
   13.48 +
   13.49 +static int LoadESDLibrary(void)
   13.50 +{
   13.51 +	int i, retval = -1;
   13.52 +
   13.53 +	esd_handle = SDL_LoadObject(esd_library);
   13.54 +	if ( esd_handle ) {
   13.55 +		esd_loaded = 1;
   13.56 +		retval = 0;
   13.57 +		for ( i=0; i<SDL_TABLESIZE(esd_functions); ++i ) {
   13.58 +			*esd_functions[i].func = SDL_LoadFunction(esd_handle, esd_functions[i].name);
   13.59 +			if ( ! esd_functions[i].func ) {
   13.60 +				retval = -1;
   13.61 +				UnloadESDLibrary();
   13.62 +				break;
   13.63 +			}
   13.64 +		}
   13.65 +	}
   13.66 +	return retval;
   13.67 +}
   13.68 +
   13.69 +#else
   13.70 +
   13.71 +static void UnloadESDLibrary()
   13.72 +{
   13.73 +	return;
   13.74 +}
   13.75 +
   13.76 +static int LoadESDLibrary(void)
   13.77 +{
   13.78 +	return 0;
   13.79 +}
   13.80 +
   13.81 +#endif /* ESD_DYNAMIC */
   13.82 +
   13.83  /* Audio driver bootstrap functions */
   13.84  
   13.85  static int Audio_Available(void)
   13.86 @@ -64,11 +133,15 @@
   13.87  	int available;
   13.88  
   13.89  	available = 0;
   13.90 -	connection = esd_open_sound(NULL);
   13.91 +	if ( LoadESDLibrary() < 0 ) {
   13.92 +		return available;
   13.93 +	}
   13.94 +	connection = SDL_NAME(esd_open_sound)(NULL);
   13.95  	if ( connection >= 0 ) {
   13.96  		available = 1;
   13.97 -		esd_close(connection);
   13.98 +		SDL_NAME(esd_close)(connection);
   13.99  	}
  13.100 +	UnloadESDLibrary();
  13.101  	return(available);
  13.102  }
  13.103  
  13.104 @@ -76,6 +149,7 @@
  13.105  {
  13.106  	free(device->hidden);
  13.107  	free(device);
  13.108 +	UnloadESDLibrary();
  13.109  }
  13.110  
  13.111  static SDL_AudioDevice *Audio_CreateDevice(int devindex)
  13.112 @@ -83,6 +157,7 @@
  13.113  	SDL_AudioDevice *this;
  13.114  
  13.115  	/* Initialize all variables that we clean on shutdown */
  13.116 +	LoadESDLibrary();
  13.117  	this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
  13.118  	if ( this ) {
  13.119  		memset(this, 0, (sizeof *this));
  13.120 @@ -174,7 +249,7 @@
  13.121  		mixbuf = NULL;
  13.122  	}
  13.123  	if ( audio_fd >= 0 ) {
  13.124 -		close(audio_fd);
  13.125 +		SDL_NAME(esd_close)(audio_fd);
  13.126  		audio_fd = -1;
  13.127  	}
  13.128  }
  13.129 @@ -231,7 +306,7 @@
  13.130  #endif
  13.131  
  13.132  	/* Open a connection to the ESD audio server */
  13.133 -	audio_fd = esd_play_stream(format, spec->freq, NULL, get_progname());
  13.134 +	audio_fd = SDL_NAME(esd_play_stream)(format, spec->freq, NULL, get_progname());
  13.135  	if ( audio_fd < 0 ) {
  13.136  		SDL_SetError("Couldn't open ESD connection");
  13.137  		return(-1);