diff src/video/x11/SDL_x11dyn.c @ 1575:3ba88cb7eb1b

Updated dynamic X11 code. See details in Bugzilla #170.
author Ryan C. Gordon <icculus@icculus.org>
date Wed, 22 Mar 2006 05:00:59 +0000
parents d910939febfa
children 7fd9fc1f2be5
line wrap: on
line diff
--- a/src/video/x11/SDL_x11dyn.c	Wed Mar 22 04:51:44 2006 +0000
+++ b/src/video/x11/SDL_x11dyn.c	Wed Mar 22 05:00:59 2006 +0000
@@ -21,11 +21,10 @@
 */
 #include "SDL_config.h"
 
-#if 0
+#if 1
 #define DEBUG_DYNAMIC_X11 1
 #endif
 
-#define __SDL_NO_REDEFINE_X11_HEADER_SYMS 1
 #include "SDL_x11dyn.h"
 
 #ifdef DEBUG_DYNAMIC_X11
@@ -41,51 +40,88 @@
 static const char *x11ext_library = SDL_VIDEO_DRIVER_X11_DYNAMIC_XEXT;
 static void *x11ext_handle = NULL;
 
-static void *X11_GetSym(int required, const char *fnname, int *rc)
+typedef struct
 {
+    void *lib;
+    const char *libname;
+} x11libitem;
+
+static void *X11_GetSym(const char *fnname, int *rc)
+{
+	int i;
 	void *fn = NULL;
-	if (*rc) {  /* haven't already failed on a previous lookup? */
-		fn = SDL_LoadFunction(x11_handle, fnname);
-		#if DEBUG_DYNAMIC_X11
-		if (fn != NULL)
-			printf("X11: Found '%s' in libX11 (%p)\n", fnname, fn);
-		#endif
+	const x11libitem libs[] =
+	{
+		{ x11_handle, "libX11" },
+		{ x11ext_handle, "libX11ext" },
+	};
 
-		if (fn == NULL) {  /* not found? Check libX11ext ... */
-			fn = SDL_LoadFunction(x11ext_handle, fnname);
-			#if DEBUG_DYNAMIC_X11
+	for (i = 0; i < (sizeof (libs) / sizeof (libs[0])); i++)
+	{
+		if (libs[i].lib != NULL)
+		{
+			fn = SDL_LoadFunction(libs[i].lib, fnname);
 			if (fn != NULL)
-				printf("X11: Found '%s' in libXext (%p)\n", fnname, fn);
-			else
-				printf("X11: Symbol '%s' NOT FOUND!%s\n", fnname,
-				       required ? "" : " (...but not required!)");
-			#endif
+				break;
 		}
-		*rc = ((fn != NULL) || (!required));
 	}
 
+	#if DEBUG_DYNAMIC_X11
+	if (fn != NULL)
+	    printf("X11: Found '%s' in %s (%p)\n", fnname, libs[i].libname, fn);
+	else
+		printf("X11: Symbol '%s' NOT FOUND!\n", fnname);
+	#endif
+
+	if (fn == NULL)
+		*rc = 0;  /* kill this module. */
+
 	return fn;
 }
+
+
+/* Define all the function pointers and wrappers... */
+#define SDL_X11_MODULE(modname)
+#define SDL_X11_SYM(rc,fn,params,args,ret) \
+	static rc (*p##fn) params = NULL; \
+	rc fn params { ret p##fn args ; }
+#include "SDL_x11sym.h"
+#undef SDL_X11_MODULE
+#undef SDL_X11_SYM
 #endif  /* SDL_VIDEO_DRIVER_X11_DYNAMIC */
 
-/* Define all the function pointers... */
-#define SDL_X11_SYM(req,ret,fn,params) ret (*p##fn) params = NULL;
+/* Annoying varargs entry point... */
+#ifdef X_HAVE_UTF8_STRING
+XIC (*pXCreateIC)(XIM,...) = NULL;
+#endif
+
+/* These SDL_X11_HAVE_* flags are here whether you have dynamic X11 or not. */
+#define SDL_X11_MODULE(modname) int SDL_X11_HAVE_##modname = 1;
+#define SDL_X11_SYM(rc,fn,params,args,ret)
 #include "SDL_x11sym.h"
+#undef SDL_X11_MODULE
 #undef SDL_X11_SYM
 
+
 static int x11_load_refcount = 0;
 
 void SDL_X11_UnloadSymbols(void)
 {
+	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
 	/* Don't actually unload if more than one module is using the libs... */
 	if (x11_load_refcount > 0) {
 		if (--x11_load_refcount == 0) {
 			/* set all the function pointers to NULL. */
-			#define SDL_X11_SYM(req,ret,fn,params) p##fn = NULL;
+			#define SDL_X11_MODULE(modname) SDL_X11_HAVE_##modname = 1;
+			#define SDL_X11_SYM(rc,fn,params,args,ret) p##fn = NULL;
 			#include "SDL_x11sym.h"
+			#undef SDL_X11_MODULE
 			#undef SDL_X11_SYM
 
-			#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+            #ifdef X_HAVE_UTF8_STRING
+            pXCreateIC = NULL;
+            #endif
+
 			if (x11_handle != NULL) {
 				SDL_UnloadObject(x11_handle);
 				x11_handle = NULL;
@@ -94,35 +130,41 @@
 				SDL_UnloadObject(x11ext_handle);
 				x11ext_handle = NULL;
 			}
-			#endif
 		}
 	}
+	#endif
 }
 
 /* returns non-zero if all needed symbols were loaded. */
 int SDL_X11_LoadSymbols(void)
 {
-	int rc = 1;
+	int rc = 1;  /* always succeed if not using Dynamic X11 stuff. */
 
-    /* deal with multiple modules (dga, x11, etc) needing these symbols... */
+	#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
+	/* deal with multiple modules (dga, x11, etc) needing these symbols... */
 	if (x11_load_refcount++ == 0) {
-		#ifdef SDL_VIDEO_DRIVER_X11_DYNAMIC
-			x11_handle = SDL_LoadObject(x11_library);
-			x11ext_handle = SDL_LoadObject(x11ext_library);
-			rc = ((x11_handle != NULL) && (x11ext_handle != NULL));
-			#define SDL_X11_SYM(req,r,fn,arg) p##fn = X11_GetSym(req,#fn, &rc);
-			#include "SDL_x11sym.h"
-			#undef SDL_X11_SYM
+		int *thismod = NULL;
+		x11_handle = SDL_LoadObject(x11_library);
+		x11ext_handle = SDL_LoadObject(x11ext_library);
+		#define SDL_X11_MODULE(modname) thismod = &SDL_X11_HAVE_##modname;
+		#define SDL_X11_SYM(a,fn,x,y,z) p##fn = X11_GetSym(#fn,thismod);
+		#include "SDL_x11sym.h"
+		#undef SDL_X11_MODULE
+		#undef SDL_X11_SYM
 
-			if (!rc)
-				SDL_X11_UnloadSymbols();  /* in case one of these loaded... */
+		#ifdef X_HAVE_UTF8_STRING
+		pXCreateIC = X11_GetSym("XCreateIC",&SDL_X11_HAVE_UTF8);
+		#endif
 
-		#else
-			#define SDL_X11_SYM(req,r,fn,arg) p##fn = fn;
-			#include "SDL_x11sym.h"
-			#undef SDL_X11_SYM
+		if (!SDL_X11_HAVE_BASEXLIB) {  /* some required symbol didn't load. */
+			SDL_X11_UnloadSymbols();  /* in case something got loaded... */
+		}
+	}
+	#else
+		#ifdef X_HAVE_UTF8_STRING
+		pXCreateIC = XCreateIC;
 		#endif
-	}
+	#endif
 
 	return rc;
 }