diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index dc577f7b0ea47aaa6bd83d3bff6a454b51c46d26..13932460e085dc5a55e5a1c169d95cd08ac3b44d 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -6,15 +6,15 @@
 #include <stdio.h>		/* NULL */
 #include <stdlib.h>
 #include <string.h>
-#ifdef __unix__
-#include <dlfcn.h>
-#endif
 
 #include "gen_defs.h"
 #include "genwrap.h"
 #include "dirwrap.h"
 #include "xpbeep.h"
 #include "threadwrap.h"
+#ifdef __unix__
+#include <xp_dl.h>
+#endif
 
 #if (defined CIOLIB_IMPORTS)
  #undef CIOLIB_IMPORTS
@@ -588,7 +588,8 @@ int sdl_init_mode(int mode)
 int sdl_init(int mode)
 {
 #if !defined(NO_X) && defined(__unix__)
-	void *dl;
+	dll_handle	dl;
+	const char *libnames[2]={"X11", NULL};
 #endif
 
 	if(init_sdl_video())
@@ -622,42 +623,35 @@ int sdl_init(int mode)
 		FreeConsole();
 #endif
 #if !defined(NO_X) && defined(__unix__)
-	#if defined(__APPLE__) && defined(__MACH__) && defined(__POWERPC__)
-		dl=dlopen("/usr/X11R6/lib/libX11.dylib",RTLD_LAZY|RTLD_GLOBAL);
-	#else
-		if((dl=dlopen("libX11.so",RTLD_LAZY))==NULL)
-			if((dl=dlopen("libX11.so.7",RTLD_LAZY))==NULL)
-				if((dl=dlopen("libX11.so.6",RTLD_LAZY))==NULL)
-					dl=dlopen("libX11.so.5",RTLD_LAZY);
-	#endif
+		dl=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,7);
 		if(dl!=NULL) {
 			sdl_x11available=TRUE;
-			if(sdl_x11available && (sdl_x11.XFree=dlsym(dl,"XFree"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XFree=xp_dlsym(dl,XFree))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XGetSelectionOwner=dlsym(dl,"XGetSelectionOwner"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XGetSelectionOwner=xp_dlsym(dl,XGetSelectionOwner))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XConvertSelection=dlsym(dl,"XConvertSelection"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XConvertSelection=xp_dlsym(dl,XConvertSelection))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XGetWindowProperty=dlsym(dl,"XGetWindowProperty"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XGetWindowProperty=xp_dlsym(dl,XGetWindowProperty))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XChangeProperty=dlsym(dl,"XChangeProperty"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XChangeProperty=xp_dlsym(dl,XChangeProperty))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XSendEvent=dlsym(dl,"XSendEvent"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XSendEvent=xp_dlsym(dl,XSendEvent))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
-			if(sdl_x11available && (sdl_x11.XSetSelectionOwner=dlsym(dl,"XSetSelectionOwner"))==NULL) {
-				dlclose(dl);
+			if(sdl_x11available && (sdl_x11.XSetSelectionOwner=xp_dlsym(dl,XSetSelectionOwner))==NULL) {
+				xp_dlclose(dl);
 				sdl_x11available=FALSE;
 			}
 		}
diff --git a/src/conio/sdlfuncs.c b/src/conio/sdlfuncs.c
index 6d73605da9dc1c3327f59ffefbe974d6548f823e..bade798746bb6478f4730b69102618a835f8d968 100644
--- a/src/conio/sdlfuncs.c
+++ b/src/conio/sdlfuncs.c
@@ -1,8 +1,5 @@
 #include <stdlib.h>	/* getenv()/exit()/atexit() */
 #include <stdio.h>	/* NULL */
-#ifdef __unix__
-#include <dlfcn.h>
-#endif
 
 #include <SDL.h>
 #ifndef main
@@ -18,6 +15,12 @@
 struct sdlfuncs sdl;
 #endif
 
+/* Make xp_dl do static linking */
+#ifdef STATIC_SDL
+#define STATIC_LINK
+#endif
+#include <xp_dl.h>
+
 static int sdl_funcs_loaded=0;
 static int sdl_initialized=0;
 static int sdl_audio_initialized=0;
@@ -30,538 +33,237 @@ SDL_sem *sdl_exit_sem;
 
 int CIOLIB_main(int argc, char **argv, char **enviro);
 
-#ifdef STATIC_SDL
-int load_sdl_funcs(struct sdlfuncs *sdlf)
-{
-	sdlf->gotfuncs=0;
-	sdlf->Init=SDL_Init;
-	sdlf->Quit=SDL_Quit;
-#ifdef _WIN32
-	sdlf->SetModuleHandle=SDL_SetModuleHandle;
-#endif
-	sdlf->mutexP=SDL_mutexP;
-	sdlf->mutexV=SDL_mutexV;
-	sdlf->PeepEvents=SDL_PeepEvents;
-	sdlf->VideoDriverName=SDL_VideoDriverName;
-	sdlf->SemWait=SDL_SemWait;
-	sdlf->SemPost=SDL_SemPost;
-	sdlf->EventState=SDL_EventState;
-	sdlf->CreateRGBSurface=SDL_CreateRGBSurface;
-	sdlf->CreateRGBSurfaceFrom=SDL_CreateRGBSurfaceFrom;
-	sdlf->FillRect=SDL_FillRect;
-	sdlf->SetColors=SDL_SetColors;
-	sdlf->BlitSurface=SDL_UpperBlit;
-	sdlf->UpdateRects=SDL_UpdateRects;
-	sdlf->UpdateRect=SDL_UpdateRect;
-	sdlf->SDL_CreateSemaphore=SDL_CreateSemaphore;
-	sdlf->SDL_DestroySemaphore=SDL_DestroySemaphore;
-	sdlf->SDL_CreateMutex=SDL_CreateMutex;
-	sdlf->CreateThread=SDL_CreateThread;
-	sdlf->KillThread=SDL_KillThread;
-	sdlf->WaitThread=SDL_WaitThread;
-	sdlf->WaitEvent=SDL_WaitEvent;
-	sdlf->SetVideoMode=SDL_SetVideoMode;
-	sdlf->FreeSurface=SDL_FreeSurface;
-	sdlf->WM_SetCaption=SDL_WM_SetCaption;
-	sdlf->WM_SetIcon=SDL_WM_SetIcon;
-	sdlf->ShowCursor=SDL_ShowCursor;
-	sdlf->WasInit=SDL_WasInit;
-	sdlf->EnableUNICODE=SDL_EnableUNICODE;
-	sdlf->EnableKeyRepeat=SDL_EnableKeyRepeat;
-	sdlf->GetWMInfo=SDL_GetWMInfo;
-	sdlf->GetError=SDL_GetError;
-	sdlf->InitSubSystem=SDL_InitSubSystem;
-	sdlf->QuitSubSystem=SDL_QuitSubSystem;
-	sdlf->OpenAudio=SDL_OpenAudio;
-	sdlf->CloseAudio=SDL_CloseAudio;
-	sdlf->PauseAudio=SDL_PauseAudio;
-	sdlf->LockAudio=SDL_LockAudio;
-	sdlf->UnlockAudio=SDL_UnlockAudio;
-	sdlf->GetAudioStatus=SDL_GetAudioStatus;
-	sdlf->MapRGB=SDL_MapRGB;
-	sdlf->LockSurface=SDL_LockSurface;
-	sdlf->UnlockSurface=SDL_UnlockSurface;
-	sdlf->DisplayFormat=SDL_DisplayFormat;
-	sdlf->Flip=SDL_Flip;
-	sdlf->CreateYUVOverlay=SDL_CreateYUVOverlay;
-	sdlf->DisplayYUVOverlay=SDL_DisplayYUVOverlay;
-	sdlf->FreeYUVOverlay=SDL_FreeYUVOverlay;
-	sdlf->LockYUVOverlay=SDL_LockYUVOverlay;
-	sdlf->UnlockYUVOverlay=SDL_UnlockYUVOverlay;
-	sdlf->GetVideoInfo=SDL_GetVideoInfo;
-	sdlf->Linked_Version=SDL_Linked_Version;
-	sdlf->gotfuncs=1;
-	sdl_funcs_loaded=1;
-	return(0);
-}
-#else
-
-#if defined(_WIN32)
-#include <Windows.h>
-
 int load_sdl_funcs(struct sdlfuncs *sdlf)
 {
-	HMODULE	sdl_dll;
+	dll_handle	sdl_dll;
+	const char *libnames[]={"SDL", "SDL-1.2", "SDL-1.1", NULL};
 
 	sdlf->gotfuncs=0;
-	if((sdl_dll=LoadLibrary("SDL.dll"))==NULL)
-		if((sdl_dll=LoadLibrary("SDL-1.2.dll"))==NULL)
-			if((sdl_dll=LoadLibrary("SDL-1.1.dll"))==NULL)
-				return(-1);
-
-	if((sdlf->Init=(void *)GetProcAddress(sdl_dll, "SDL_Init"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Quit=(void *)GetProcAddress(sdl_dll, "SDL_Quit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetModuleHandle=(void *)GetProcAddress(sdl_dll, "SDL_SetModuleHandle"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->mutexP=(void *)GetProcAddress(sdl_dll, "SDL_mutexP"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->mutexV=(void *)GetProcAddress(sdl_dll, "SDL_mutexV"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->PeepEvents=(void *)GetProcAddress(sdl_dll, "SDL_PeepEvents"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->VideoDriverName=(void *)GetProcAddress(sdl_dll, "SDL_VideoDriverName"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SemWait=(void *)GetProcAddress(sdl_dll, "SDL_SemWait"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SemPost=(void *)GetProcAddress(sdl_dll, "SDL_SemPost"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EventState=(void *)GetProcAddress(sdl_dll, "SDL_EventState"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateRGBSurface=(void *)GetProcAddress(sdl_dll, "SDL_CreateRGBSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateRGBSurfaceFrom=(void *)GetProcAddress(sdl_dll, "SDL_CreateRGBSurfaceFrom"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FillRect=(void *)GetProcAddress(sdl_dll, "SDL_FillRect"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetColors=(void *)GetProcAddress(sdl_dll, "SDL_SetColors"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->BlitSurface=(void *)GetProcAddress(sdl_dll, "SDL_UpperBlit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UpdateRects=(void *)GetProcAddress(sdl_dll, "SDL_UpdateRects"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UpdateRect=(void *)GetProcAddress(sdl_dll, "SDL_UpdateRect"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_CreateSemaphore=(void *)GetProcAddress(sdl_dll, "SDL_CreateSemaphore"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_DestroySemaphore=(void *)GetProcAddress(sdl_dll, "SDL_DestroySemaphore"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_CreateMutex=(void *)GetProcAddress(sdl_dll, "SDL_CreateMutex"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateThread=(void *)GetProcAddress(sdl_dll, "SDL_CreateThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->KillThread=(void *)GetProcAddress(sdl_dll, "SDL_KillThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WaitThread=(void *)GetProcAddress(sdl_dll, "SDL_WaitThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WaitEvent=(void *)GetProcAddress(sdl_dll, "SDL_WaitEvent"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetVideoMode=(void *)GetProcAddress(sdl_dll, "SDL_SetVideoMode"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FreeSurface=(void *)GetProcAddress(sdl_dll, "SDL_FreeSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WM_SetCaption=(void *)GetProcAddress(sdl_dll, "SDL_WM_SetCaption"))==NULL) {
-		FreeLibrary(sdl_dll);
+	if((sdl_dll=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,SDL_PATCHLEVEL))==NULL)
 		return(-1);
-	}
-	if((sdlf->WM_SetIcon=(void *)GetProcAddress(sdl_dll, "SDL_WM_SetIcon"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->ShowCursor=(void *)GetProcAddress(sdl_dll, "SDL_ShowCursor"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WasInit=(void *)GetProcAddress(sdl_dll, "SDL_WasInit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EnableUNICODE=(void *)GetProcAddress(sdl_dll, "SDL_EnableUNICODE"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EnableKeyRepeat=(void *)GetProcAddress(sdl_dll, "SDL_EnableKeyRepeat"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetWMInfo=(void *)GetProcAddress(sdl_dll, "SDL_GetWMInfo"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetError=(void *)GetProcAddress(sdl_dll, "SDL_GetError"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->InitSubSystem=(void *)GetProcAddress(sdl_dll, "SDL_InitSubSystem"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->QuitSubSystem=(void *)GetProcAddress(sdl_dll, "SDL_QuitSubSystem"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->OpenAudio=(void *)GetProcAddress(sdl_dll, "SDL_OpenAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CloseAudio=(void *)GetProcAddress(sdl_dll, "SDL_CloseAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->PauseAudio=(void *)GetProcAddress(sdl_dll, "SDL_PauseAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockAudio=(void *)GetProcAddress(sdl_dll, "SDL_LockAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockAudio=(void *)GetProcAddress(sdl_dll, "SDL_UnlockAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetAudioStatus=(void *)GetProcAddress(sdl_dll, "SDL_GetAudioStatus"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->MapRGB=(void *)GetProcAddress(sdl_dll, "SDL_MapRGB"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockSurface=(void *)GetProcAddress(sdl_dll, "SDL_LockSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockSurface=(void *)GetProcAddress(sdl_dll, "SDL_UnlockSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->DisplayFormat=(void *)GetProcAddress(sdl_dll, "SDL_DisplayFormat"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Flip=(void *)GetProcAddress(sdl_dll, "SDL_Flip"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_CreateYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->DisplayYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_DisplayYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FreeYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_FreeYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_LockYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_UnlockYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetVideoInfo=(void *)GetProcAddress(sdl_dll, "SDL_GetVideoInfo"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Linked_Version=(void *)GetProcAddress(sdl_dll, "SDL_Linked_Version"))==NULL) {
-		FreeLibrary(sdl_dll);
+
+#ifdef _WIN32
+	if((sdlf->SetModuleHandle=xp_dlsym(sdl_dll, SDL_SetModuleHandle))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-
-	sdlf->gotfuncs=1;
-	sdl_funcs_loaded=1;
-	return(0);
-}
-#elif defined(__unix__)
-#include <dlfcn.h>
-
-int load_sdl_funcs(struct sdlfuncs *sdlf)
-{
-	void	*sdl_dll;
-
-	sdlf->gotfuncs=0;
-	if((sdl_dll=dlopen("libSDL.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-		if((sdl_dll=dlopen("libSDL-1.2.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-			if((sdl_dll=dlopen("libSDL-1.1.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-				return(-1);
-
-	if((sdlf->Init=dlsym(sdl_dll, "SDL_Init"))==NULL) {
-		dlclose(sdl_dll);
+#endif
+	if((sdlf->Init=xp_dlsym(sdl_dll, SDL_Init))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Quit=dlsym(sdl_dll, "SDL_Quit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Quit=xp_dlsym(sdl_dll, SDL_Quit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->mutexP=dlsym(sdl_dll, "SDL_mutexP"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->mutexP=xp_dlsym(sdl_dll, SDL_mutexP))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->mutexV=dlsym(sdl_dll, "SDL_mutexV"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->mutexV=xp_dlsym(sdl_dll, SDL_mutexV))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->PeepEvents=dlsym(sdl_dll, "SDL_PeepEvents"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->PeepEvents=xp_dlsym(sdl_dll, SDL_PeepEvents))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->VideoDriverName=dlsym(sdl_dll, "SDL_VideoDriverName"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->VideoDriverName=xp_dlsym(sdl_dll, SDL_VideoDriverName))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SemWait=dlsym(sdl_dll, "SDL_SemWait"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SemWait=xp_dlsym(sdl_dll, SDL_SemWait))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SemPost=dlsym(sdl_dll, "SDL_SemPost"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SemPost=xp_dlsym(sdl_dll, SDL_SemPost))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EventState=dlsym(sdl_dll, "SDL_EventState"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EventState=xp_dlsym(sdl_dll, SDL_EventState))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateRGBSurface=dlsym(sdl_dll, "SDL_CreateRGBSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateRGBSurface=xp_dlsym(sdl_dll, SDL_CreateRGBSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateRGBSurfaceFrom=dlsym(sdl_dll, "SDL_CreateRGBSurfaceFrom"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateRGBSurfaceFrom=xp_dlsym(sdl_dll, SDL_CreateRGBSurfaceFrom))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FillRect=dlsym(sdl_dll, "SDL_FillRect"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FillRect=xp_dlsym(sdl_dll, SDL_FillRect))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SetColors=dlsym(sdl_dll, "SDL_SetColors"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SetColors=xp_dlsym(sdl_dll, SDL_SetColors))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->BlitSurface=dlsym(sdl_dll, "SDL_UpperBlit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->BlitSurface=xp_dlsym(sdl_dll, SDL_UpperBlit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UpdateRects=dlsym(sdl_dll, "SDL_UpdateRects"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UpdateRects=xp_dlsym(sdl_dll, SDL_UpdateRects))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UpdateRect=dlsym(sdl_dll, "SDL_UpdateRect"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UpdateRect=xp_dlsym(sdl_dll, SDL_UpdateRect))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_CreateSemaphore=dlsym(sdl_dll, "SDL_CreateSemaphore"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_CreateSemaphore=xp_dlsym(sdl_dll, SDL_CreateSemaphore))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_DestroySemaphore=dlsym(sdl_dll, "SDL_DestroySemaphore"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_DestroySemaphore=xp_dlsym(sdl_dll, SDL_DestroySemaphore))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_CreateMutex=dlsym(sdl_dll, "SDL_CreateMutex"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_CreateMutex=xp_dlsym(sdl_dll, SDL_CreateMutex))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateThread=dlsym(sdl_dll, "SDL_CreateThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateThread=xp_dlsym(sdl_dll, SDL_CreateThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->KillThread=dlsym(sdl_dll, "SDL_KillThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->KillThread=xp_dlsym(sdl_dll, SDL_KillThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WaitThread=dlsym(sdl_dll, "SDL_WaitThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WaitThread=xp_dlsym(sdl_dll, SDL_WaitThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WaitEvent=dlsym(sdl_dll, "SDL_WaitEvent"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WaitEvent=xp_dlsym(sdl_dll, SDL_WaitEvent))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SetVideoMode=dlsym(sdl_dll, "SDL_SetVideoMode"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SetVideoMode=xp_dlsym(sdl_dll, SDL_SetVideoMode))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FreeSurface=dlsym(sdl_dll, "SDL_FreeSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FreeSurface=xp_dlsym(sdl_dll, SDL_FreeSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WM_SetCaption=dlsym(sdl_dll, "SDL_WM_SetCaption"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WM_SetCaption=xp_dlsym(sdl_dll, SDL_WM_SetCaption))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WM_SetIcon=dlsym(sdl_dll, "SDL_WM_SetIcon"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WM_SetIcon=xp_dlsym(sdl_dll, SDL_WM_SetIcon))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->ShowCursor=dlsym(sdl_dll, "SDL_ShowCursor"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->ShowCursor=xp_dlsym(sdl_dll, SDL_ShowCursor))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WasInit=dlsym(sdl_dll, "SDL_WasInit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WasInit=xp_dlsym(sdl_dll, SDL_WasInit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EnableUNICODE=dlsym(sdl_dll, "SDL_EnableUNICODE"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EnableUNICODE=xp_dlsym(sdl_dll, SDL_EnableUNICODE))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EnableKeyRepeat=dlsym(sdl_dll, "SDL_EnableKeyRepeat"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EnableKeyRepeat=xp_dlsym(sdl_dll, SDL_EnableKeyRepeat))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetWMInfo=dlsym(sdl_dll, "SDL_GetWMInfo"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetWMInfo=xp_dlsym(sdl_dll, SDL_GetWMInfo))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetError=dlsym(sdl_dll, "SDL_GetError"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetError=xp_dlsym(sdl_dll, SDL_GetError))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->InitSubSystem=dlsym(sdl_dll, "SDL_InitSubSystem"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->InitSubSystem=xp_dlsym(sdl_dll, SDL_InitSubSystem))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->QuitSubSystem=dlsym(sdl_dll, "SDL_QuitSubSystem"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->QuitSubSystem=xp_dlsym(sdl_dll, SDL_QuitSubSystem))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->OpenAudio=dlsym(sdl_dll, "SDL_OpenAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->OpenAudio=xp_dlsym(sdl_dll, SDL_OpenAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CloseAudio=dlsym(sdl_dll, "SDL_CloseAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CloseAudio=xp_dlsym(sdl_dll, SDL_CloseAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->PauseAudio=dlsym(sdl_dll, "SDL_PauseAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->PauseAudio=xp_dlsym(sdl_dll, SDL_PauseAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockAudio=dlsym(sdl_dll, "SDL_LockAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockAudio=xp_dlsym(sdl_dll, SDL_LockAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockAudio=dlsym(sdl_dll, "SDL_UnlockAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockAudio=xp_dlsym(sdl_dll, SDL_UnlockAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetAudioStatus=dlsym(sdl_dll, "SDL_GetAudioStatus"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetAudioStatus=xp_dlsym(sdl_dll, SDL_GetAudioStatus))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->MapRGB=dlsym(sdl_dll, "SDL_MapRGB"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->MapRGB=xp_dlsym(sdl_dll, SDL_MapRGB))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockSurface=dlsym(sdl_dll, "SDL_LockSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockSurface=xp_dlsym(sdl_dll, SDL_LockSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockSurface=dlsym(sdl_dll, "SDL_UnlockSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockSurface=xp_dlsym(sdl_dll, SDL_UnlockSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->DisplayFormat=dlsym(sdl_dll, "SDL_DisplayFormat"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->DisplayFormat=xp_dlsym(sdl_dll, SDL_DisplayFormat))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Flip=dlsym(sdl_dll, "SDL_Flip"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Flip=xp_dlsym(sdl_dll, SDL_Flip))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateYUVOverlay=dlsym(sdl_dll, "SDL_CreateYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateYUVOverlay=xp_dlsym(sdl_dll, SDL_CreateYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->DisplayYUVOverlay=dlsym(sdl_dll, "SDL_DisplayYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->DisplayYUVOverlay=xp_dlsym(sdl_dll, SDL_DisplayYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FreeYUVOverlay=dlsym(sdl_dll, "SDL_FreeYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FreeYUVOverlay=xp_dlsym(sdl_dll, SDL_FreeYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockYUVOverlay=dlsym(sdl_dll, "SDL_LockYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockYUVOverlay=xp_dlsym(sdl_dll, SDL_LockYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockYUVOverlay=dlsym(sdl_dll, "SDL_UnlockYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockYUVOverlay=xp_dlsym(sdl_dll, SDL_UnlockYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetVideoInfo=dlsym(sdl_dll, "SDL_GetVideoInfo"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetVideoInfo=xp_dlsym(sdl_dll, SDL_GetVideoInfo))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Linked_Version=dlsym(sdl_dll, "SDL_Linked_Version"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Linked_Version=xp_dlsym(sdl_dll, SDL_Linked_Version))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
 	sdlf->gotfuncs=1;
 	sdl_funcs_loaded=1;
 	return(0);
 }
-#endif
-
-#endif
 
 int init_sdl_video(void)
 {
diff --git a/src/conio/x_cio.c b/src/conio/x_cio.c
index 4a38fa524ad3ec84a5ba8dadd964be8defced304..c46587208741cace1130f0b3690d60228efcdd8a 100644
--- a/src/conio/x_cio.c
+++ b/src/conio/x_cio.c
@@ -35,13 +35,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#ifndef STATIC_LINK
-#include <dlfcn.h>
-#endif
 #include <sys/types.h>
 #include <sys/socket.h>
 
 #include <threadwrap.h>
+#include <xp_dl.h>
 
 #if (defined CIOLIB_IMPORTS)
  #undef CIOLIB_IMPORTS
@@ -156,7 +154,8 @@ int x_get_window_info(int *width, int *height, int *xpos, int *ypos)
 
 int x_init(void)
 {
-	void *dl;
+	dll_handle	dl;
+	const char *libnames[]={"X11",NULL};
 
 	/* Ensure we haven't already initialized */
 	if(x11_initialized)
@@ -171,211 +170,160 @@ int x_init(void)
 		return(-1);
 
 	/* Load X11 functions */
-#ifdef STATIC_LINK
-	x11.XChangeGC=XChangeGC;
-	x11.XCopyPlane=XCopyPlane;
-	x11.XFillRectangle=XFillRectangle;
-	x11.XDrawPoint=XDrawPoint;
-	x11.XFlush=XFlush;
-	x11.XSync=XSync;
-	x11.XBell=XBell;
-	x11.XLookupString=XLookupString;
-	x11.XNextEvent=XNextEvent;
-	x11.XAllocSizeHints=XAllocSizeHints;
-	x11.XSetWMNormalHints=XSetWMNormalHints;
-	x11.XResizeWindow=XResizeWindow;
-	x11.XMapWindow=XMapWindow;
-	x11.XFree=XFree;
-	x11.XFreePixmap=XFreePixmap;
-	x11.XCreatePixmap=XCreatePixmap;
-	x11.XCopyArea=XCopyArea;
-	x11.XCreateBitmapFromData=XCreateBitmapFromData;
-	x11.XAllocColor=XAllocColor;
-	x11.XOpenDisplay=XOpenDisplay;
-	x11.XCreateSimpleWindow=XCreateSimpleWindow;
-	x11.XCreateGC=XCreateGC;
-	x11.XSelectInput=XSelectInput;
-	x11.XStoreName=XStoreName;
-	x11.XGetSelectionOwner=XGetSelectionOwner;
-	x11.XConvertSelection=XConvertSelection;
-	x11.XGetWindowProperty=XGetWindowProperty;
-	x11.XChangeProperty=XChangeProperty;
-	x11.XSendEvent=XSendEvent;
-	x11.XPutImage=XPutImage;
-#ifndef XPutPixel
-	x11.XPutPixel=XPutPixel;
-#endif
-#ifndef XDestroyImage
-	x11.XDestroyImage=XDestroyImage;
-#endif
-	x11.XCreateImage=XCreateImage;
-	x11.XSetSelectionOwner=XSetSelectionOwner;
-	x11.XSetIconName=XSetIconName;
-	x11.XSynchronize=XSynchronize;
-	x11.XGetWindowAttributes=XGetWindowAttributes;
-#else
-#if defined(__APPLE__) && defined(__MACH__) && defined(__POWERPC__)
-	if((dl=dlopen("/usr/X11R6/lib/libX11.dylib",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-#else
-	if((dl=dlopen("libX11.so",RTLD_LAZY))==NULL)
-	if((dl=dlopen("libX11.so.7",RTLD_LAZY))==NULL)
-	if((dl=dlopen("libX11.so.6",RTLD_LAZY))==NULL)
-	if((dl=dlopen("libX11.so.5",RTLD_LAZY))==NULL)
-#endif
+	if((dl=xp_dlopen(libnames,RTLD_LAZY,7))==NULL)
 		return(-1);
-	if((x11.XChangeGC=dlsym(dl,"XChangeGC"))==NULL) {
-		dlclose(dl);
+	if((x11.XChangeGC=xp_dlsym(dl,XChangeGC))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCopyPlane=dlsym(dl,"XCopyPlane"))==NULL) {
-		dlclose(dl);
+	if((x11.XCopyPlane=xp_dlsym(dl,XCopyPlane))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XFillRectangle=dlsym(dl,"XFillRectangle"))==NULL) {
-		dlclose(dl);
+	if((x11.XFillRectangle=xp_dlsym(dl,XFillRectangle))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XDrawPoint=dlsym(dl,"XDrawPoint"))==NULL) {
-		dlclose(dl);
+	if((x11.XDrawPoint=xp_dlsym(dl,XDrawPoint))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XFlush=dlsym(dl,"XFlush"))==NULL) {
-		dlclose(dl);
+	if((x11.XFlush=xp_dlsym(dl,XFlush))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSync=dlsym(dl,"XSync"))==NULL) {
-		dlclose(dl);
+	if((x11.XSync=xp_dlsym(dl,XSync))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XBell=dlsym(dl,"XBell"))==NULL) {
-		dlclose(dl);
+	if((x11.XBell=xp_dlsym(dl,XBell))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XLookupString=dlsym(dl,"XLookupString"))==NULL) {
-		dlclose(dl);
+	if((x11.XLookupString=xp_dlsym(dl,XLookupString))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XNextEvent=dlsym(dl,"XNextEvent"))==NULL) {
-		dlclose(dl);
+	if((x11.XNextEvent=xp_dlsym(dl,XNextEvent))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XAllocSizeHints=dlsym(dl,"XAllocSizeHints"))==NULL) {
-		dlclose(dl);
+	if((x11.XAllocSizeHints=xp_dlsym(dl,XAllocSizeHints))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSetWMNormalHints=dlsym(dl,"XSetWMNormalHints"))==NULL) {
-		dlclose(dl);
+	if((x11.XSetWMNormalHints=xp_dlsym(dl,XSetWMNormalHints))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XResizeWindow=dlsym(dl,"XResizeWindow"))==NULL) {
-		dlclose(dl);
+	if((x11.XResizeWindow=xp_dlsym(dl,XResizeWindow))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XMapWindow=dlsym(dl,"XMapWindow"))==NULL) {
-		dlclose(dl);
+	if((x11.XMapWindow=xp_dlsym(dl,XMapWindow))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XFree=dlsym(dl,"XFree"))==NULL) {
-		dlclose(dl);
+	if((x11.XFree=xp_dlsym(dl,XFree))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XFreePixmap=dlsym(dl,"XFreePixmap"))==NULL) {
-		dlclose(dl);
+	if((x11.XFreePixmap=xp_dlsym(dl,XFreePixmap))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCreatePixmap=dlsym(dl,"XCreatePixmap"))==NULL) {
-		dlclose(dl);
+	if((x11.XCreatePixmap=xp_dlsym(dl,XCreatePixmap))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCopyArea=dlsym(dl,"XCopyArea"))==NULL) {
-		dlclose(dl);
+	if((x11.XCopyArea=xp_dlsym(dl,XCopyArea))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCreateBitmapFromData=dlsym(dl,"XCreateBitmapFromData"))==NULL) {
-		dlclose(dl);
+	if((x11.XCreateBitmapFromData=xp_dlsym(dl,XCreateBitmapFromData))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XAllocColor=dlsym(dl,"XAllocColor"))==NULL) {
-		dlclose(dl);
+	if((x11.XAllocColor=xp_dlsym(dl,XAllocColor))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XOpenDisplay=dlsym(dl,"XOpenDisplay"))==NULL) {
-		dlclose(dl);
+	if((x11.XOpenDisplay=xp_dlsym(dl,XOpenDisplay))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCreateSimpleWindow=dlsym(dl,"XCreateSimpleWindow"))==NULL) {
-		dlclose(dl);
+	if((x11.XCreateSimpleWindow=xp_dlsym(dl,XCreateSimpleWindow))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XCreateGC=dlsym(dl,"XCreateGC"))==NULL) {
-		dlclose(dl);
+	if((x11.XCreateGC=xp_dlsym(dl,XCreateGC))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSelectInput=dlsym(dl,"XSelectInput"))==NULL) {
-		dlclose(dl);
+	if((x11.XSelectInput=xp_dlsym(dl,XSelectInput))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XStoreName=dlsym(dl,"XStoreName"))==NULL) {
-		dlclose(dl);
+	if((x11.XStoreName=xp_dlsym(dl,XStoreName))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XGetSelectionOwner=dlsym(dl,"XGetSelectionOwner"))==NULL) {
-		dlclose(dl);
+	if((x11.XGetSelectionOwner=xp_dlsym(dl,XGetSelectionOwner))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XConvertSelection=dlsym(dl,"XConvertSelection"))==NULL) {
-		dlclose(dl);
+	if((x11.XConvertSelection=xp_dlsym(dl,XConvertSelection))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XGetWindowProperty=dlsym(dl,"XGetWindowProperty"))==NULL) {
-		dlclose(dl);
+	if((x11.XGetWindowProperty=xp_dlsym(dl,XGetWindowProperty))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XChangeProperty=dlsym(dl,"XChangeProperty"))==NULL) {
-		dlclose(dl);
+	if((x11.XChangeProperty=xp_dlsym(dl,XChangeProperty))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSendEvent=dlsym(dl,"XSendEvent"))==NULL) {
-		dlclose(dl);
+	if((x11.XSendEvent=xp_dlsym(dl,XSendEvent))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XPutImage=dlsym(dl,"XPutImage"))==NULL) {
-		dlclose(dl);
+	if((x11.XPutImage=xp_dlsym(dl,XPutImage))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
 #ifndef XDestroyImage
-	if((x11.XDestroyImage=dlsym(dl,"XDestroyImage"))==NULL) {
-		dlclose(dl);
+	if((x11.XDestroyImage=xp_dlsym(dl,XDestroyImage))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
 #endif
 #ifndef XPutPixel
-	if((x11.XPutPixel=dlsym(dl,"XPutPixel"))==NULL) {
-		dlclose(dl);
+	if((x11.XPutPixel=xp_dlsym(dl,XPutPixel))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
 #endif
-	if((x11.XCreateImage=dlsym(dl,"XCreateImage"))==NULL) {
-		dlclose(dl);
+	if((x11.XCreateImage=xp_dlsym(dl,XCreateImage))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSetSelectionOwner=dlsym(dl,"XSetSelectionOwner"))==NULL) {
-		dlclose(dl);
+	if((x11.XSetSelectionOwner=xp_dlsym(dl,XSetSelectionOwner))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSetIconName=dlsym(dl,"XSetIconName"))==NULL) {
-		dlclose(dl);
+	if((x11.XSetIconName=xp_dlsym(dl,XSetIconName))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XSynchronize=dlsym(dl,"XSynchronize"))==NULL) {
-		dlclose(dl);
+	if((x11.XSynchronize=xp_dlsym(dl,XSynchronize))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-	if((x11.XGetWindowAttributes=dlsym(dl,"XGetWindowAttributes"))==NULL) {
-		dlclose(dl);
+	if((x11.XGetWindowAttributes=xp_dlsym(dl,XGetWindowAttributes))==NULL) {
+		xp_dlclose(dl);
 		return(-1);
 	}
-#endif
 
 	if(sem_init(&pastebuf_set, 0, 0))
 		return(-1);
diff --git a/src/syncterm/GNUmakefile b/src/syncterm/GNUmakefile
index a85546756a1531c27aff5ef20e7dc075b216e7d6..7499d8a27580f8df489038d70a53d2ce3d09c24c 100644
--- a/src/syncterm/GNUmakefile
+++ b/src/syncterm/GNUmakefile
@@ -65,6 +65,10 @@ else
  OBJS += $(MTOBJODIR)$(DIRSEP)ssh$(OFILE)
 endif
 
+ifdef STATIC
+ STATIC_CRYPTLIB	:= true
+endif
+
 ifdef STATIC_CRYPTLIB
  CFLAGS += -DSTATIC_CRYPTLIB
  LDFLAGS += -lz
diff --git a/src/syncterm/st_crypt.c b/src/syncterm/st_crypt.c
index 105935b773a929ae41b6863da661d69c78f920cb..2a57e4fb4cd68f284410cdd439281738ff9667b4 100644
--- a/src/syncterm/st_crypt.c
+++ b/src/syncterm/st_crypt.c
@@ -1,9 +1,7 @@
 /* Copyright (C), 2007 by Stephen Hurd */
 
-#ifndef _WIN32
- #include <dlfcn.h>
-#endif
 #include <stdio.h>	/* NULL */
+#include <xp_dl.h>
 
 #include "st_crypt.h"
 
@@ -26,138 +24,63 @@ struct crypt_funcs cl;
 
 int init_crypt(void)
 {
-#ifdef STATIC_CRYPTLIB
-	cl.PopData=cryptPopData;
-	cl.PushData=cryptPushData;
-	cl.FlushData=cryptFlushData;
-	cl.Init=cryptInit;
-	cl.End=cryptEnd;
-	cl.CreateSession=cryptCreateSession;
-	cl.GetAttribute=cryptGetAttribute;
-	cl.GetAttributeString=cryptGetAttributeString;
-	cl.SetAttribute=cryptSetAttribute;
-	cl.SetAttributeString=cryptSetAttributeString;
-	cl.DestroySession=cryptDestroySession;
-	cl.AddRandom=cryptAddRandom;
-#else
-#ifdef _WIN32
-	HMODULE cryptlib;
+	dll_handle	cryptlib;
+	const char *libnames[2]={ "cl", NULL };
 
 	if(crypt_loaded)
 		return(0);
 
-	cryptlib=LoadLibrary("cl32.dll");
+	cryptlib=xp_dlopen(libnames,RTLD_LAZY, CRYPTLIB_VERSION/1000);
 	if(cryptlib==NULL)
 		return(-1);
-
-	if((cl.PopData=(void*)GetProcAddress(cryptlib,"cryptPopData"))==NULL) {
-		FreeLibrary(cryptlib);
-		return(-1);
-	}
-	if((cl.PushData=(void*)GetProcAddress(cryptlib,"cryptPushData"))==NULL) {
-		FreeLibrary(cryptlib);
-		return(-1);
-	}
-	if((cl.FlushData=(void*)GetProcAddress(cryptlib,"cryptFlushData"))==NULL) {
-		FreeLibrary(cryptlib);
-		return(-1);
-	}
-	if((cl.Init=(void*)GetProcAddress(cryptlib,"cryptInit"))==NULL) {
-		FreeLibrary(cryptlib);
-		return(-1);
-	}
-	if((cl.End=(void*)GetProcAddress(cryptlib,"cryptEnd"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.PopData=xp_dlsym(cryptlib,cryptPopData))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.CreateSession=(void*)GetProcAddress(cryptlib,"cryptCreateSession"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.PushData=xp_dlsym(cryptlib,cryptPushData))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.GetAttribute=(void*)GetProcAddress(cryptlib,"cryptGetAttribute"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.FlushData=xp_dlsym(cryptlib,cryptFlushData))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.GetAttributeString=(void*)GetProcAddress(cryptlib,"cryptGetAttributeString"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.Init=xp_dlsym(cryptlib,cryptInit))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.SetAttribute=(void*)GetProcAddress(cryptlib,"cryptSetAttribute"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.End=xp_dlsym(cryptlib,cryptEnd))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.SetAttributeString=(void*)GetProcAddress(cryptlib,"cryptSetAttributeString"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.CreateSession=xp_dlsym(cryptlib,cryptCreateSession))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.DestroySession=(void*)GetProcAddress(cryptlib,"cryptDestroySession"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.GetAttribute=xp_dlsym(cryptlib,cryptGetAttribute))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.AddRandom=(void*)GetProcAddress(cryptlib,"cryptAddRandom"))==NULL) {
-		FreeLibrary(cryptlib);
+	if((cl.GetAttributeString=xp_dlsym(cryptlib,cryptGetAttributeString))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-#else
-	void *cryptlib;
-
-	if(crypt_loaded)
-		return(0);
-
-	if((cryptlib=dlopen("libcl.so",RTLD_LAZY))==NULL)
-		cryptlib=dlopen("libcl.so.3",RTLD_LAZY);
-	if(cryptlib==NULL)
-		return(-1);
-	if((cl.PopData=dlsym(cryptlib,"cryptPopData"))==NULL) {
-		dlclose(cryptlib);
+	if((cl.SetAttribute=xp_dlsym(cryptlib,cryptSetAttribute))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.PushData=dlsym(cryptlib,"cryptPushData"))==NULL) {
-		dlclose(cryptlib);
+	if((cl.SetAttributeString=xp_dlsym(cryptlib,cryptSetAttributeString))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.FlushData=dlsym(cryptlib,"cryptFlushData"))==NULL) {
-		dlclose(cryptlib);
+	if((cl.DestroySession=xp_dlsym(cryptlib,cryptDestroySession))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.Init=dlsym(cryptlib,"cryptInit"))==NULL) {
-		dlclose(cryptlib);
+	if((cl.AddRandom=xp_dlsym(cryptlib,cryptAddRandom))==NULL) {
+		xp_dlclose(cryptlib);
 		return(-1);
 	}
-	if((cl.End=dlsym(cryptlib,"cryptEnd"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.CreateSession=dlsym(cryptlib,"cryptCreateSession"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.GetAttribute=dlsym(cryptlib,"cryptGetAttribute"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.GetAttributeString=dlsym(cryptlib,"cryptGetAttributeString"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.SetAttribute=dlsym(cryptlib,"cryptSetAttribute"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.SetAttributeString=dlsym(cryptlib,"cryptSetAttributeString"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.DestroySession=dlsym(cryptlib,"cryptDestroySession"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-	if((cl.AddRandom=dlsym(cryptlib,"cryptAddRandom"))==NULL) {
-		dlclose(cryptlib);
-		return(-1);
-	}
-#endif
-#endif	/* !STATIC_LINK */
 	if(cryptStatusOK(cl.Init())) {
 		if(cryptStatusOK(cl.AddRandom(NULL, CRYPT_RANDOM_SLOWPOLL))) {
 			crypt_loaded=1;
diff --git a/src/xpdev/Common.gmake b/src/xpdev/Common.gmake
index dc6ab97ba855ba732bfbf0c91457ea2307c9de6c..52612639d8d3f298532d5fd33927055c290d653a 100644
--- a/src/xpdev/Common.gmake
+++ b/src/xpdev/Common.gmake
@@ -107,6 +107,10 @@ ifdef USE_SDL_AUDIO
  endif
 endif
 
+ifdef STATIC
+ STATIC_SDL := true
+endif
+
 ifdef WITH_SDL_AUDIO
  ifdef SDL_CONFIG
   ifeq ($(shell ${SDL_CONFIG} --cflags > /dev/null 2>&1 && echo YES),YES)
@@ -173,8 +177,5 @@ ifndef WITHOUT_PORTAUDIO
 
  ifneq ($(PORTAUDIO_PATH),NOTFOUND)
   XPDEV_CFLAGS += -DWITH_PORTAUDIO
-  XPDEV_LDFLAGS += -L$(PORTAUDIO_PATH)/lib
-  XPDEV_LIBS	+=	-lportaudio
-  XPDEV-MT_LIBS	+=	-lportaudio
  endif
 endif
diff --git a/src/xpdev/objects.mk b/src/xpdev/objects.mk
index 3338504b52ca5e42ee2a7159783c70325b91e9e4..17b032aa4cb1bf85848107d6f2ee7988ef0f3f5b 100644
--- a/src/xpdev/objects.mk
+++ b/src/xpdev/objects.mk
@@ -20,6 +20,7 @@ OBJS	= \
 	$(OBJODIR)$(DIRSEP)semfile$(OFILE) \
 	$(OBJODIR)$(DIRSEP)str_list$(OFILE) \
 	$(OBJODIR)$(DIRSEP)strwrap$(OFILE) \
+	$(OBJODIR)$(DIRSEP)xp_dl$(OFILE) \
 	$(OBJODIR)$(DIRSEP)xpbeep$(OFILE) \
 	$(OBJODIR)$(DIRSEP)xpdatetime$(OFILE) \
 	$(OBJODIR)$(DIRSEP)xpprintf$(OFILE)
@@ -42,6 +43,7 @@ MTOBJS	= \
 	$(MTOBJODIR)$(DIRSEP)str_list$(OFILE) \
 	$(MTOBJODIR)$(DIRSEP)strwrap$(OFILE) \
 	$(MTOBJODIR)$(DIRSEP)threadwrap$(OFILE) \
+	$(MTOBJODIR)$(DIRSEP)xp_dl$(OFILE) \
 	$(MTOBJODIR)$(DIRSEP)xpbeep$(OFILE) \
 	$(MTOBJODIR)$(DIRSEP)xpdatetime$(OFILE) \
 	$(MTOBJODIR)$(DIRSEP)xpprintf$(OFILE)
diff --git a/src/xpdev/sdlfuncs.c b/src/xpdev/sdlfuncs.c
index 9d30bb011d7bcc76a8d014e6da858be0b0950799..c85aee027a8be35d5a1226c141f2b110043e34eb 100644
--- a/src/xpdev/sdlfuncs.c
+++ b/src/xpdev/sdlfuncs.c
@@ -1,8 +1,5 @@
 #include <stdlib.h>	/* getenv()/exit()/atexit() */
 #include <stdio.h>	/* NULL */
-#ifdef __unix__
-#include <dlfcn.h>
-#endif
 
 #include <SDL.h>
 #ifndef main
@@ -18,6 +15,12 @@
 struct sdlfuncs sdl;
 #endif
 
+/* Make xp_dl do static linking */
+#ifdef STATIC_SDL
+#define STATIC_LINK
+#endif
+#include <xp_dl.h>
+
 static int sdl_funcs_loaded=0;
 static int sdl_initialized=0;
 static int sdl_audio_initialized=0;
@@ -30,538 +33,237 @@ SDL_sem *sdl_exit_sem;
 
 int XPDEV_main(int argc, char **argv, char **enviro);
 
-#ifdef STATIC_SDL
-int load_sdl_funcs(struct sdlfuncs *sdlf)
-{
-	sdlf->gotfuncs=0;
-	sdlf->Init=SDL_Init;
-	sdlf->Quit=SDL_Quit;
-#ifdef _WIN32
-	sdlf->SetModuleHandle=SDL_SetModuleHandle;
-#endif
-	sdlf->mutexP=SDL_mutexP;
-	sdlf->mutexV=SDL_mutexV;
-	sdlf->PeepEvents=SDL_PeepEvents;
-	sdlf->VideoDriverName=SDL_VideoDriverName;
-	sdlf->SemWait=SDL_SemWait;
-	sdlf->SemPost=SDL_SemPost;
-	sdlf->EventState=SDL_EventState;
-	sdlf->CreateRGBSurface=SDL_CreateRGBSurface;
-	sdlf->CreateRGBSurfaceFrom=SDL_CreateRGBSurfaceFrom;
-	sdlf->FillRect=SDL_FillRect;
-	sdlf->SetColors=SDL_SetColors;
-	sdlf->BlitSurface=SDL_UpperBlit;
-	sdlf->UpdateRects=SDL_UpdateRects;
-	sdlf->UpdateRect=SDL_UpdateRect;
-	sdlf->SDL_CreateSemaphore=SDL_CreateSemaphore;
-	sdlf->SDL_DestroySemaphore=SDL_DestroySemaphore;
-	sdlf->SDL_CreateMutex=SDL_CreateMutex;
-	sdlf->CreateThread=SDL_CreateThread;
-	sdlf->KillThread=SDL_KillThread;
-	sdlf->WaitThread=SDL_WaitThread;
-	sdlf->WaitEvent=SDL_WaitEvent;
-	sdlf->SetVideoMode=SDL_SetVideoMode;
-	sdlf->FreeSurface=SDL_FreeSurface;
-	sdlf->WM_SetCaption=SDL_WM_SetCaption;
-	sdlf->WM_SetIcon=SDL_WM_SetIcon;
-	sdlf->ShowCursor=SDL_ShowCursor;
-	sdlf->WasInit=SDL_WasInit;
-	sdlf->EnableUNICODE=SDL_EnableUNICODE;
-	sdlf->EnableKeyRepeat=SDL_EnableKeyRepeat;
-	sdlf->GetWMInfo=SDL_GetWMInfo;
-	sdlf->GetError=SDL_GetError;
-	sdlf->InitSubSystem=SDL_InitSubSystem;
-	sdlf->QuitSubSystem=SDL_QuitSubSystem;
-	sdlf->OpenAudio=SDL_OpenAudio;
-	sdlf->CloseAudio=SDL_CloseAudio;
-	sdlf->PauseAudio=SDL_PauseAudio;
-	sdlf->LockAudio=SDL_LockAudio;
-	sdlf->UnlockAudio=SDL_UnlockAudio;
-	sdlf->GetAudioStatus=SDL_GetAudioStatus;
-	sdlf->MapRGB=SDL_MapRGB;
-	sdlf->LockSurface=SDL_LockSurface;
-	sdlf->UnlockSurface=SDL_UnlockSurface;
-	sdlf->DisplayFormat=SDL_DisplayFormat;
-	sdlf->Flip=SDL_Flip;
-	sdlf->CreateYUVOverlay=SDL_CreateYUVOverlay;
-	sdlf->DisplayYUVOverlay=SDL_DisplayYUVOverlay;
-	sdlf->FreeYUVOverlay=SDL_FreeYUVOverlay;
-	sdlf->LockYUVOverlay=SDL_LockYUVOverlay;
-	sdlf->UnlockYUVOverlay=SDL_UnlockYUVOverlay;
-	sdlf->GetVideoInfo=SDL_GetVideoInfo;
-	sdlf->Linked_Version=SDL_Linked_Version;
-	sdlf->gotfuncs=1;
-	sdl_funcs_loaded=1;
-	return(0);
-}
-#else
-
-#if defined(_WIN32)
-#include <Windows.h>
-
 int load_sdl_funcs(struct sdlfuncs *sdlf)
 {
-	HMODULE	sdl_dll;
+	dll_handle	sdl_dll;
+	const char *libnames[]={"SDL", "SDL-1.2", "SDL-1.1", NULL};
 
 	sdlf->gotfuncs=0;
-	if((sdl_dll=LoadLibrary("SDL.dll"))==NULL)
-		if((sdl_dll=LoadLibrary("SDL-1.2.dll"))==NULL)
-			if((sdl_dll=LoadLibrary("SDL-1.1.dll"))==NULL)
-				return(-1);
-
-	if((sdlf->Init=(void *)GetProcAddress(sdl_dll, "SDL_Init"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Quit=(void *)GetProcAddress(sdl_dll, "SDL_Quit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetModuleHandle=(void *)GetProcAddress(sdl_dll, "SDL_SetModuleHandle"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->mutexP=(void *)GetProcAddress(sdl_dll, "SDL_mutexP"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->mutexV=(void *)GetProcAddress(sdl_dll, "SDL_mutexV"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->PeepEvents=(void *)GetProcAddress(sdl_dll, "SDL_PeepEvents"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->VideoDriverName=(void *)GetProcAddress(sdl_dll, "SDL_VideoDriverName"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SemWait=(void *)GetProcAddress(sdl_dll, "SDL_SemWait"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SemPost=(void *)GetProcAddress(sdl_dll, "SDL_SemPost"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EventState=(void *)GetProcAddress(sdl_dll, "SDL_EventState"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateRGBSurface=(void *)GetProcAddress(sdl_dll, "SDL_CreateRGBSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateRGBSurfaceFrom=(void *)GetProcAddress(sdl_dll, "SDL_CreateRGBSurfaceFrom"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FillRect=(void *)GetProcAddress(sdl_dll, "SDL_FillRect"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetColors=(void *)GetProcAddress(sdl_dll, "SDL_SetColors"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->BlitSurface=(void *)GetProcAddress(sdl_dll, "SDL_UpperBlit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UpdateRects=(void *)GetProcAddress(sdl_dll, "SDL_UpdateRects"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UpdateRect=(void *)GetProcAddress(sdl_dll, "SDL_UpdateRect"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_CreateSemaphore=(void *)GetProcAddress(sdl_dll, "SDL_CreateSemaphore"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_DestroySemaphore=(void *)GetProcAddress(sdl_dll, "SDL_DestroySemaphore"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SDL_CreateMutex=(void *)GetProcAddress(sdl_dll, "SDL_CreateMutex"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateThread=(void *)GetProcAddress(sdl_dll, "SDL_CreateThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->KillThread=(void *)GetProcAddress(sdl_dll, "SDL_KillThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WaitThread=(void *)GetProcAddress(sdl_dll, "SDL_WaitThread"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WaitEvent=(void *)GetProcAddress(sdl_dll, "SDL_WaitEvent"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->SetVideoMode=(void *)GetProcAddress(sdl_dll, "SDL_SetVideoMode"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FreeSurface=(void *)GetProcAddress(sdl_dll, "SDL_FreeSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WM_SetCaption=(void *)GetProcAddress(sdl_dll, "SDL_WM_SetCaption"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WM_SetIcon=(void *)GetProcAddress(sdl_dll, "SDL_WM_SetIcon"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->ShowCursor=(void *)GetProcAddress(sdl_dll, "SDL_ShowCursor"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->WasInit=(void *)GetProcAddress(sdl_dll, "SDL_WasInit"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EnableUNICODE=(void *)GetProcAddress(sdl_dll, "SDL_EnableUNICODE"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->EnableKeyRepeat=(void *)GetProcAddress(sdl_dll, "SDL_EnableKeyRepeat"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetWMInfo=(void *)GetProcAddress(sdl_dll, "SDL_GetWMInfo"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetError=(void *)GetProcAddress(sdl_dll, "SDL_GetError"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->InitSubSystem=(void *)GetProcAddress(sdl_dll, "SDL_InitSubSystem"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->QuitSubSystem=(void *)GetProcAddress(sdl_dll, "SDL_QuitSubSystem"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->OpenAudio=(void *)GetProcAddress(sdl_dll, "SDL_OpenAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CloseAudio=(void *)GetProcAddress(sdl_dll, "SDL_CloseAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->PauseAudio=(void *)GetProcAddress(sdl_dll, "SDL_PauseAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockAudio=(void *)GetProcAddress(sdl_dll, "SDL_LockAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockAudio=(void *)GetProcAddress(sdl_dll, "SDL_UnlockAudio"))==NULL) {
-		FreeLibrary(sdl_dll);
+	if((sdl_dll=xp_dlopen(libnames,RTLD_LAZY|RTLD_GLOBAL,SDL_PATCHLEVEL))==NULL)
 		return(-1);
-	}
-	if((sdlf->GetAudioStatus=(void *)GetProcAddress(sdl_dll, "SDL_GetAudioStatus"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->MapRGB=(void *)GetProcAddress(sdl_dll, "SDL_MapRGB"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockSurface=(void *)GetProcAddress(sdl_dll, "SDL_LockSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockSurface=(void *)GetProcAddress(sdl_dll, "SDL_UnlockSurface"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->DisplayFormat=(void *)GetProcAddress(sdl_dll, "SDL_DisplayFormat"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Flip=(void *)GetProcAddress(sdl_dll, "SDL_Flip"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->CreateYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_CreateYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->DisplayYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_DisplayYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->FreeYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_FreeYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->LockYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_LockYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->UnlockYUVOverlay=(void *)GetProcAddress(sdl_dll, "SDL_UnlockYUVOverlay"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->GetVideoInfo=(void *)GetProcAddress(sdl_dll, "SDL_GetVideoInfo"))==NULL) {
-		FreeLibrary(sdl_dll);
-		return(-1);
-	}
-	if((sdlf->Linked_Version=(void *)GetProcAddress(sdl_dll, "SDL_Linked_Version"))==NULL) {
-		FreeLibrary(sdl_dll);
+
+#ifdef _WIN32
+	if((sdlf->SetModuleHandle=xp_dlsym(sdl_dll, SDL_SetModuleHandle))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-
-	sdlf->gotfuncs=1;
-	sdl_funcs_loaded=1;
-	return(0);
-}
-#elif defined(__unix__)
-#include <dlfcn.h>
-
-int load_sdl_funcs(struct sdlfuncs *sdlf)
-{
-	void	*sdl_dll;
-
-	sdlf->gotfuncs=0;
-	if((sdl_dll=dlopen("libSDL.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-		if((sdl_dll=dlopen("libSDL-1.2.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-			if((sdl_dll=dlopen("libSDL-1.1.so",RTLD_LAZY|RTLD_GLOBAL))==NULL)
-				return(-1);
-
-	if((sdlf->Init=dlsym(sdl_dll, "SDL_Init"))==NULL) {
-		dlclose(sdl_dll);
+#endif
+	if((sdlf->Init=xp_dlsym(sdl_dll, SDL_Init))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Quit=dlsym(sdl_dll, "SDL_Quit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Quit=xp_dlsym(sdl_dll, SDL_Quit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->mutexP=dlsym(sdl_dll, "SDL_mutexP"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->mutexP=xp_dlsym(sdl_dll, SDL_mutexP))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->mutexV=dlsym(sdl_dll, "SDL_mutexV"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->mutexV=xp_dlsym(sdl_dll, SDL_mutexV))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->PeepEvents=dlsym(sdl_dll, "SDL_PeepEvents"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->PeepEvents=xp_dlsym(sdl_dll, SDL_PeepEvents))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->VideoDriverName=dlsym(sdl_dll, "SDL_VideoDriverName"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->VideoDriverName=xp_dlsym(sdl_dll, SDL_VideoDriverName))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SemWait=dlsym(sdl_dll, "SDL_SemWait"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SemWait=xp_dlsym(sdl_dll, SDL_SemWait))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SemPost=dlsym(sdl_dll, "SDL_SemPost"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SemPost=xp_dlsym(sdl_dll, SDL_SemPost))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EventState=dlsym(sdl_dll, "SDL_EventState"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EventState=xp_dlsym(sdl_dll, SDL_EventState))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateRGBSurface=dlsym(sdl_dll, "SDL_CreateRGBSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateRGBSurface=xp_dlsym(sdl_dll, SDL_CreateRGBSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateRGBSurfaceFrom=dlsym(sdl_dll, "SDL_CreateRGBSurfaceFrom"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateRGBSurfaceFrom=xp_dlsym(sdl_dll, SDL_CreateRGBSurfaceFrom))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FillRect=dlsym(sdl_dll, "SDL_FillRect"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FillRect=xp_dlsym(sdl_dll, SDL_FillRect))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SetColors=dlsym(sdl_dll, "SDL_SetColors"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SetColors=xp_dlsym(sdl_dll, SDL_SetColors))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->BlitSurface=dlsym(sdl_dll, "SDL_UpperBlit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->BlitSurface=xp_dlsym(sdl_dll, SDL_UpperBlit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UpdateRects=dlsym(sdl_dll, "SDL_UpdateRects"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UpdateRects=xp_dlsym(sdl_dll, SDL_UpdateRects))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UpdateRect=dlsym(sdl_dll, "SDL_UpdateRect"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UpdateRect=xp_dlsym(sdl_dll, SDL_UpdateRect))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_CreateSemaphore=dlsym(sdl_dll, "SDL_CreateSemaphore"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_CreateSemaphore=xp_dlsym(sdl_dll, SDL_CreateSemaphore))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_DestroySemaphore=dlsym(sdl_dll, "SDL_DestroySemaphore"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_DestroySemaphore=xp_dlsym(sdl_dll, SDL_DestroySemaphore))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SDL_CreateMutex=dlsym(sdl_dll, "SDL_CreateMutex"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SDL_CreateMutex=xp_dlsym(sdl_dll, SDL_CreateMutex))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateThread=dlsym(sdl_dll, "SDL_CreateThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateThread=xp_dlsym(sdl_dll, SDL_CreateThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->KillThread=dlsym(sdl_dll, "SDL_KillThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->KillThread=xp_dlsym(sdl_dll, SDL_KillThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WaitThread=dlsym(sdl_dll, "SDL_WaitThread"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WaitThread=xp_dlsym(sdl_dll, SDL_WaitThread))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WaitEvent=dlsym(sdl_dll, "SDL_WaitEvent"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WaitEvent=xp_dlsym(sdl_dll, SDL_WaitEvent))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->SetVideoMode=dlsym(sdl_dll, "SDL_SetVideoMode"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->SetVideoMode=xp_dlsym(sdl_dll, SDL_SetVideoMode))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FreeSurface=dlsym(sdl_dll, "SDL_FreeSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FreeSurface=xp_dlsym(sdl_dll, SDL_FreeSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WM_SetCaption=dlsym(sdl_dll, "SDL_WM_SetCaption"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WM_SetCaption=xp_dlsym(sdl_dll, SDL_WM_SetCaption))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WM_SetIcon=dlsym(sdl_dll, "SDL_WM_SetIcon"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WM_SetIcon=xp_dlsym(sdl_dll, SDL_WM_SetIcon))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->ShowCursor=dlsym(sdl_dll, "SDL_ShowCursor"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->ShowCursor=xp_dlsym(sdl_dll, SDL_ShowCursor))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->WasInit=dlsym(sdl_dll, "SDL_WasInit"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->WasInit=xp_dlsym(sdl_dll, SDL_WasInit))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EnableUNICODE=dlsym(sdl_dll, "SDL_EnableUNICODE"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EnableUNICODE=xp_dlsym(sdl_dll, SDL_EnableUNICODE))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->EnableKeyRepeat=dlsym(sdl_dll, "SDL_EnableKeyRepeat"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->EnableKeyRepeat=xp_dlsym(sdl_dll, SDL_EnableKeyRepeat))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetWMInfo=dlsym(sdl_dll, "SDL_GetWMInfo"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetWMInfo=xp_dlsym(sdl_dll, SDL_GetWMInfo))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetError=dlsym(sdl_dll, "SDL_GetError"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetError=xp_dlsym(sdl_dll, SDL_GetError))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->InitSubSystem=dlsym(sdl_dll, "SDL_InitSubSystem"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->InitSubSystem=xp_dlsym(sdl_dll, SDL_InitSubSystem))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->QuitSubSystem=dlsym(sdl_dll, "SDL_QuitSubSystem"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->QuitSubSystem=xp_dlsym(sdl_dll, SDL_QuitSubSystem))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->OpenAudio=dlsym(sdl_dll, "SDL_OpenAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->OpenAudio=xp_dlsym(sdl_dll, SDL_OpenAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CloseAudio=dlsym(sdl_dll, "SDL_CloseAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CloseAudio=xp_dlsym(sdl_dll, SDL_CloseAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->PauseAudio=dlsym(sdl_dll, "SDL_PauseAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->PauseAudio=xp_dlsym(sdl_dll, SDL_PauseAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockAudio=dlsym(sdl_dll, "SDL_LockAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockAudio=xp_dlsym(sdl_dll, SDL_LockAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockAudio=dlsym(sdl_dll, "SDL_UnlockAudio"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockAudio=xp_dlsym(sdl_dll, SDL_UnlockAudio))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetAudioStatus=dlsym(sdl_dll, "SDL_GetAudioStatus"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetAudioStatus=xp_dlsym(sdl_dll, SDL_GetAudioStatus))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->MapRGB=dlsym(sdl_dll, "SDL_MapRGB"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->MapRGB=xp_dlsym(sdl_dll, SDL_MapRGB))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockSurface=dlsym(sdl_dll, "SDL_LockSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockSurface=xp_dlsym(sdl_dll, SDL_LockSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockSurface=dlsym(sdl_dll, "SDL_UnlockSurface"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockSurface=xp_dlsym(sdl_dll, SDL_UnlockSurface))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->DisplayFormat=dlsym(sdl_dll, "SDL_DisplayFormat"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->DisplayFormat=xp_dlsym(sdl_dll, SDL_DisplayFormat))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Flip=dlsym(sdl_dll, "SDL_Flip"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Flip=xp_dlsym(sdl_dll, SDL_Flip))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->CreateYUVOverlay=dlsym(sdl_dll, "SDL_CreateYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->CreateYUVOverlay=xp_dlsym(sdl_dll, SDL_CreateYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->DisplayYUVOverlay=dlsym(sdl_dll, "SDL_DisplayYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->DisplayYUVOverlay=xp_dlsym(sdl_dll, SDL_DisplayYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->FreeYUVOverlay=dlsym(sdl_dll, "SDL_FreeYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->FreeYUVOverlay=xp_dlsym(sdl_dll, SDL_FreeYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->LockYUVOverlay=dlsym(sdl_dll, "SDL_LockYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->LockYUVOverlay=xp_dlsym(sdl_dll, SDL_LockYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->UnlockYUVOverlay=dlsym(sdl_dll, "SDL_UnlockYUVOverlay"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->UnlockYUVOverlay=xp_dlsym(sdl_dll, SDL_UnlockYUVOverlay))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->GetVideoInfo=dlsym(sdl_dll, "SDL_GetVideoInfo"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->GetVideoInfo=xp_dlsym(sdl_dll, SDL_GetVideoInfo))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
-	if((sdlf->Linked_Version=dlsym(sdl_dll, "SDL_Linked_Version"))==NULL) {
-		dlclose(sdl_dll);
+	if((sdlf->Linked_Version=xp_dlsym(sdl_dll, SDL_Linked_Version))==NULL) {
+		xp_dlclose(sdl_dll);
 		return(-1);
 	}
 	sdlf->gotfuncs=1;
 	sdl_funcs_loaded=1;
 	return(0);
 }
-#endif
-
-#endif
 
 int init_sdl_video(void)
 {
@@ -624,7 +326,9 @@ int SDL_main_env(int argc, char **argv, char **env)
 	SDL_Thread	*main_thread;
 	int		main_ret;
 	int		use_sdl_video=FALSE;
+#ifdef _WIN32
 	char		*driver_env=NULL;
+#endif
 
 	ma.argc=argc;
 	ma.argv=argv;
@@ -661,7 +365,7 @@ int SDL_main_env(int argc, char **argv, char **env)
 		 * This ugly hack attempts to prevent this... of course, remote X11
 		 * connections must still be allowed.
 		 */
-		if((!use_sdl_video) || (getenv("REMOTEHOST")!=NULL && getenv("DISPLAY")==NULL)) {
+		if((!use_sdl_video) || ((getenv("REMOTEHOST")!=NULL || getenv("SSH_CLIENT")!=NULL) && getenv("DISPLAY")==NULL)) {
 			/* Sure ,we can't use video, but audio is still valid! */
 			if(sdl.Init(0)==0)
 				sdl_initialized=TRUE;
diff --git a/src/xpdev/xp_dl.c b/src/xpdev/xp_dl.c
index 31cfcf8387bd004ea2ee26490e1e5a882d1848f8..c19961eea52c7bf97bb51cc7f4f7ee23de23bd5e 100644
--- a/src/xpdev/xp_dl.c
+++ b/src/xpdev/xp_dl.c
@@ -1,38 +1,75 @@
+#include <stdio.h>
 #include "dirwrap.h"
 #include "xp_dl.h"
 
 #ifndef STATIC_LINK
 #if defined(__unix__)
-xp_dlopen(const char *name, int mode, int major, int minor)
+
+DLLEXPORT dll_handle DLLCALL xp_dlopen(const char **names, int mode, int major)
 {
+	const char	*name;
 	char		fname[MAX_PATH+1];
 	dll_handle	ret=NULL;
 	int			i;
 
-	/* Try for exact version match */
-	sprintf(fname, "%s.%d.%d", name, major, minor);
-	if((dll_handle=dlopen(fname, mode))!=NULL)
-		return(ret);
+	for(; *names && (*names)[0]; names++) {
+		name=*names;
+		/* Try for version match */
+		sprintf(fname, "lib%s.so.%d", name, major);
+		if((ret=dlopen(fname, mode))!=NULL)
+			return(ret);
+
+		/* Try for name match */
+		sprintf(fname, "lib%s.so", name, major);
+		if((ret=dlopen(fname, mode))!=NULL)
+			return(ret);
+
+		/* Try for name match without the prefix */
+		sprintf(fname, "%s.so", name, major);
+		if((ret=dlopen(fname, mode))!=NULL)
+			return(ret);
 
-	/* Try for major version match */
-	sprintf(fname, "%s.%d", name, major);
-	if((dll_handle=dlopen(fname, mode))!=NULL)
-		return(ret);
+		/* Try all previous major versions */
+		for(i=major-1; i>=0; i--) {
+			sprintf(fname, "lib%s.so.%d", name, i);
+			if((ret=dlopen(fname, mode))!=NULL)
+				return(ret);
+		}
 
-	/* Try for preferred match (symlink) */
-	if((dll_handle=dlopen(name, mode))!=NULL)
-		return(ret);
+#if defined(__APPLE__) && defined(__MACH__)
+		/* Try for version match */
+		sprintf(fname, "lib%s.%d.dylib", name, major);
+		if((ret=dlopen(fname, mode))!=NULL)
+			return(ret);
 
-	/* Try all previous major versions */
-	for(i=major-1; i>=0; i--) {
-		sprintf(fname, "%s.%d", name, i);
-		if((dll_handle=dlopen(fname, mode))!=NULL)
+		/* Try for name match */
+		sprintf(fname, "lib%s.dylib", name, major);
+		if((ret=dlopen(fname, mode))!=NULL)
 			return(ret);
+
+		/* Try all previous major versions */
+		for(i=major-1; i>=0; i--) {
+			sprintf(fname, "lib%s.%d.dylib", name, i);
+			if((ret=dlopen(fname, mode))!=NULL)
+				return(ret);
+		}
+#endif	/* OS X */
 	}
 
 	return(NULL);
 }
-#endif
-#endif
+#elif defined(_WIN32)
+xp_dlopen(const char **name, int mode, int major)
+{
+	char		fname[MAX_PATH+1];
+	dll_handle	ret=NULL;
+
+	for(; *names && (*names)[0]; names++) {
+		sprintf(fname, "%s.dll", *names);
+		if((ret=LoadLibrary(fname))!=NULL)
+			return(ret);
+	}
+}
+#endif	/* __unix__,_WIN32 */
 
-#endif
+#endif	/* STATIC_LINK */
diff --git a/src/xpdev/xp_dl.h b/src/xpdev/xp_dl.h
index 6fd8c0619ba054464a0e4fbd56a440298fbcd2f3..e285550da5d123f62d27d98d3f13cbe2ca0afdee 100644
--- a/src/xpdev/xp_dl.h
+++ b/src/xpdev/xp_dl.h
@@ -8,14 +8,14 @@
 	#include <dlfcn.h>
 
 	typedef void * dll_handle;
-	DLLEXPORT void* DLLCALL xp_dlopen(const char *name, int mode, int major, int minor);
+	DLLEXPORT dll_handle DLLCALL xp_dlopen(const char **name, int mode, int major);
 	#define xp_dlsym(handle, name)				dlsym(handle, #name)
 	#define xp_dlclose(handle)					dlclose(handle)
 #elif defined(_WIN32)
 	#include <Winbase.h>
 
 	typedef HMODULE WINAPI dll_handle;
-	#define xp_dlopen(name, mode, major, minor)	LoadLibrary(name)
+	DLLEXPORT dll_handle DLLCALL xp_dlopen(const char **name, int mode, int major);
 	#define xp_dlsym(handle, name)				((void *)GetProcAddress(handle, #name))
 	#define xp_dlclose(handle)					(FreeLibrary(handle)?0:-1)
 
@@ -31,9 +31,9 @@
 #else
 	typedef void* dll_handle;
 
-	#define xp_dlopen(name, mode, major, minor)	(name)
-	#define xp_dlsym(handle, name)				(name)
-	#define xp_dlclose(handle)					(0)
+	#define xp_dlopen(name, mode, major)	(name)
+	#define xp_dlsym(handle, name)			(name)
+	#define xp_dlclose(handle)				(0)
 #endif
 
 #endif
diff --git a/src/xpdev/xpbeep.c b/src/xpdev/xpbeep.c
index e075fe70a3587d04aa2ef68befd190bce41713ff..37b72855e4c14509802ad2410da928ffe165d537 100644
--- a/src/xpdev/xpbeep.c
+++ b/src/xpdev/xpbeep.c
@@ -4,6 +4,8 @@
 
 /* standard headers */
 #include <math.h>
+#include <stdlib.h>
+#include "xp_dl.h"
 
 #if defined(_WIN32)
 	#include <windows.h>
@@ -93,6 +95,23 @@ static int				portaudio_buf_len=0;
 static int				portaudio_buf_pos=0;
 static const unsigned char	*pawave;
 static int				portaudio_initialized=FALSE;
+struct portaudio_api_struct {
+	PaError (*init)( void );
+	PaError (*open)( PortAudioStream** stream,
+                              int numInputChannels,
+                              int numOutputChannels,
+                              PaSampleFormat sampleFormat,
+                              double sampleRate,
+                              unsigned long framesPerBuffer,
+                              unsigned long numberOfBuffers,
+                              PortAudioCallback *callback,
+                              void *userData );
+	PaError (*close)( PortAudioStream* );
+	PaError (*start)( PortAudioStream *stream );
+	PaError (*stop)( PortAudioStream *stream );
+	PaError (*active)( PortAudioStream *stream );
+};
+struct portaudio_api_struct *pa_api=NULL;
 #endif
 
 #ifdef WITH_SDL_AUDIO
@@ -288,11 +307,31 @@ BOOL xptone_open(void)
 
 #ifdef WITH_PORTAUDIO
 	if(!portaudio_device_open_failed) {
-		if(portaudio_initialized || (Pa_Initialize() != paNoError))
+		if(pa_api==NULL) {
+			dll_handle dl;
+			const char *libnames[]={"portaudio",NULL};
+			if(((pa_api=(struct portaudio_api_struct *)malloc(sizeof(struct portaudio_api_struct)))==NULL)
+					|| ((dl=xp_dlopen(libnames,RTLD_LAZY,0))==NULL)
+					|| ((pa_api->init=xp_dlsym(dl,"Pa_Initialize"))==NULL)
+					|| ((pa_api->open=xp_dlsym(dl,"Pa_OpenDefaultStream"))==NULL)
+					|| ((pa_api->close=xp_dlsym(dl,"Pa_CloseStream"))==NULL)
+					|| ((pa_api->start=xp_dlsym(dl,"Pa_StartStream"))==NULL)
+					|| ((pa_api->active=xp_dlsym(dl,"Pa_StreamActive"))==NULL)
+					|| ((pa_api->stop=xp_dlsym(dl,"Pa_StopStream"))==NULL)
+					) {
+				if(dl)
+					xp_dlclose(dl);
+				portaudio_device_open_failed=TRUE;
+            }
+            if(pa_api==NULL) {
+                portaudio_device_open_failed=TRUE;
+			}
+		}
+		if(portaudio_initialized || (pa_api->init() != paNoError))
 			portaudio_device_open_failed=TRUE;
 		else {
 			portaudio_initialized=TRUE;
-			if(Pa_OpenDefaultStream(&portaudio_stream
+			if(pa_api->open(&portaudio_stream
 					, 0	/* No input */
 					, 1	/* Mono output */
 					, paUInt8
@@ -362,22 +401,25 @@ BOOL xptone_open(void)
 #ifdef USE_ALSA_SOUND
 	if(!alsa_device_open_failed) {
 		if(alsa_api==NULL) {
-			void *dl;
+			dll_handle dl;
+			const char libnames[]={"asound", NULL};
 			if(((alsa_api=(struct alsa_api_struct *)malloc(sizeof(struct alsa_api_struct)))==NULL)
-					|| ((dl=dlopen("libasound.so",RTLD_LAZY))==NULL)
-					|| ((alsa_api->snd_pcm_open=dlsym(dl,"snd_pcm_open"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_malloc=dlsym(dl,"snd_pcm_hw_params_malloc"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_any=dlsym(dl,"snd_pcm_hw_params_any"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_set_access=dlsym(dl,"snd_pcm_hw_params_set_access"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_set_format=dlsym(dl,"snd_pcm_hw_params_set_format"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_set_rate_near=dlsym(dl,"snd_pcm_hw_params_set_rate_near"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_set_channels=dlsym(dl,"snd_pcm_hw_params_set_channels"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params=dlsym(dl,"snd_pcm_hw_params"))==NULL)
-					|| ((alsa_api->snd_pcm_prepare=dlsym(dl,"snd_pcm_prepare"))==NULL)
-					|| ((alsa_api->snd_pcm_hw_params_free=dlsym(dl,"snd_pcm_hw_params_free"))==NULL)
-					|| ((alsa_api->snd_pcm_close=dlsym(dl,"snd_pcm_close"))==NULL)
-					|| ((alsa_api->snd_pcm_writei=dlsym(dl,"snd_pcm_writei"))==NULL)
+					|| ((dl=xp_dlopen("libasound.so",RTLD_LAZY,2))==NULL)
+					|| ((alsa_api->snd_pcm_open=xp_dlsym(dl,"snd_pcm_open"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_malloc=xp_dlsym(dl,"snd_pcm_hw_params_malloc"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_any=xp_dlsym(dl,"snd_pcm_hw_params_any"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_set_access=xp_dlsym(dl,"snd_pcm_hw_params_set_access"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_set_format=xp_dlsym(dl,"snd_pcm_hw_params_set_format"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_set_rate_near=xp_dlsym(dl,"snd_pcm_hw_params_set_rate_near"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_set_channels=xp_dlsym(dl,"snd_pcm_hw_params_set_channels"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params=xp_dlsym(dl,"snd_pcm_hw_params"))==NULL)
+					|| ((alsa_api->snd_pcm_prepare=xp_dlsym(dl,"snd_pcm_prepare"))==NULL)
+					|| ((alsa_api->snd_pcm_hw_params_free=xp_dlsym(dl,"snd_pcm_hw_params_free"))==NULL)
+					|| ((alsa_api->snd_pcm_close=xp_dlsym(dl,"snd_pcm_close"))==NULL)
+					|| ((alsa_api->snd_pcm_writei=xp_dlsym(dl,"snd_pcm_writei"))==NULL)
 					) {
+				if(dl)
+					xp_dlclose(dl);
 				alsa_device_open_failed=TRUE;
 			}
 			if(alsa_api==NULL)
@@ -444,7 +486,7 @@ BOOL xptone_close(void)
 {
 #ifdef WITH_PORTAUDIO
 	if(handle_type==SOUND_DEVICE_PORTAUDIO) {
-		Pa_CloseStream(portaudio_stream);
+		pa_api->close(portaudio_stream);
 	}
 #endif
 
@@ -511,10 +553,10 @@ void xp_play_sample_thread(void *data)
 			pawave=sample_buffer;
 			portaudio_buf_pos=0;
 			portaudio_buf_len=sample_size;
-			Pa_StartStream(portaudio_stream);
-			while(Pa_StreamActive(portaudio_stream))
+			pa_api->start(portaudio_stream);
+			while(pa_api->active(portaudio_stream))
 				SLEEP(1);
-			Pa_StopStream(portaudio_stream);
+			pa_api->stop(portaudio_stream);
 		}
 	#endif
 
@@ -637,10 +679,10 @@ BOOL DLLCALL xp_play_sample(const unsigned char *sample, size_t sample_size, BOO
 		pawave=sample;
 		portaudio_buf_pos=0;
 		portaudio_buf_len=sample_size;
-		Pa_StartStream(portaudio_stream);
-		while(Pa_StreamActive(portaudio_stream))
+		pa_api->start(portaudio_stream);
+		while(pa_api->active(portaudio_stream))
 			SLEEP(1);
-		Pa_StopStream(portaudio_stream);
+		pa_api->stop(portaudio_stream);
 	}
 #endif