[PATCH] Dynamically load XOpenDisplay, XQueryPointer and XCloseDisplay (2nd try)

Pavel Tsekov ptsekov at gmx.net
Fri Feb 14 10:57:35 UTC 2003


Hello,

I've updated the patch a bit. The previous one would update GLIB_CFLAGS 
and GLIB_LIBS no matter if the gmodule functionality is necessary or not. 
An example for this behaviour is MC configured with --without-x, although 
no dynamic loading is required in this scenario one would end up with a 
binary which has a dependency on the gmodule library. 

This new patch fixes the described problem and updates GLIB_CFLAGS and 
GLIB_LIBS only in the case where gmodule functionality is required i.e.
MC is configured with --with-x, X was found and the configure script 
determined that gmodule is supported on the system.

The new patch also doesn't include a diff for config.h.in since this is 
not needed. The previous time i missed the fact that autoheader will 
generate a good config.h.in.

The patch was tested on Cygwin 1.3.20-1, RH Linux 8.0, OpenBSD 3.2 and 
Solaris 9.

Here is an updated list of changes:

* aclocal.m4 (AC_G_MODULE_SUPPORTED): New macro. Tests if gmodule 
functionality is supported. Sets the variable 'av_g_module_supported' and 
the macros 'HAVE_WORKING_GMODULE'.
* configure.in: Detect if gmodule library is present and can be used. 
(GMODULE_CFLAGS): New variable.
(GMODULE_LIBS): Ditto.
Add necessary X libraries to 'MCLIBS' only if 'av_g_module_supported' 
contains a valued different from 'yes'.
Update GLIB_CFLAGS and GLIB_LIBS contents with the one of GMODULE_CFLAGS 
and GMODULE_LIBS only if 'av_g_module_supported' is set to 'yes'.
* src/key.c: Include gmodule.h if 'HAVE_WORKING_GMODULE' is defined.
(MODULE_DEFAULT_PREFIX): New macro.
(MODULE_DEFUALT_SUFFIX): Ditto.
(MODX11_DEFAULT_NAME): Ditto. Use 'MODULE_DEFAULT_PREFIX' and 
'MODULE_DEFAULT_SUFFIX' macros.
(XOPENDISPLAY): Define new pointer to function type.
(XCLOSEDISPLAY): Ditto.
(XQUERYPOINTER): Ditto.
(x11_module): New static variable.
(func_XOpenDisplay): Ditto.
(func_XCloseDisplay): Ditto.
(func_XQueryPointer): Ditto.
(init_key): Dynamically load XOpenDisplay, XCloseDisplay and XQueryPointer
functions if 'HAVE_WORKING_GMODULE' is defined.
Use 'func_XOpenDisplay'.
(get_modifier): Use 'func_XQueryPointer'.
(done_key): Use 'func_XCloseDisplay'.
Unload the dynamcally loaded library X11 if 'HAVE_WORKING_GMODULE' is 
defined.
-------------- next part --------------
diff -urN -x .build -x .inst -x .sinst mc-4.6.0-orig/aclocal.m4 mc-4.6.0/aclocal.m4
--- mc-4.6.0-orig/aclocal.m4	2003-02-05 19:08:57.000000000 +0100
+++ mc-4.6.0/aclocal.m4	2003-02-13 23:42:35.000000000 +0100
@@ -3881,3 +3881,35 @@
   fi
 ])
 
+dnl
+dnl Check whether the g_module_* family of functions works
+dnl on this system.
+dnl
+AC_DEFUN([AC_G_MODULE_SUPPORTED], [
+av_g_module_supported=no
+AC_MSG_CHECKING([if gmodule functionality is supported on this system])
+ac_save_CFLAGS="$CFLAGS"
+ac_save_LIBS="$LIBS"
+CFLAGS="$CFLAGS $GMODULE_CFLAGS"
+LIBS="$GMODULE_LIBS $LIBS"
+AC_TRY_RUN([
+#include <gmodule.h>
+
+int main ()
+{
+    int ret = (g_module_supported () == TRUE) ? 0 : 1;
+    return ret;
+}
+],[
+AC_DEFINE(HAVE_WORKING_GMODULE, 1,
+	  [Define if gmodule functionality is supported on your system.])
+av_g_module_supported=yes
+],[
+av_g_module_supported=no
+],[
+av_g_module_supported=no
+])
+CFLAGS="$ac_save_CFLAGS"
+LIBS="$ac_save_LIBS"
+AC_MSG_RESULT([$av_g_module_supported])
+])
diff -urN -x .build -x .inst -x .sinst mc-4.6.0-orig/configure.in mc-4.6.0/configure.in
--- mc-4.6.0-orig/configure.in	2003-02-05 19:03:56.000000000 +0100
+++ mc-4.6.0/configure.in	2003-02-13 23:16:47.000000000 +0100
@@ -38,8 +38,26 @@
 	AC_ARG_VAR([GLIB_CONFIG], [Path to glib-config (version 1.2.x only)])
 	AM_PATH_GLIB(1.2.6,,[AC_MSG_ERROR([Test for glib failed.
 GNU Midnight Commander requires glib 1.2.6 or above.])])
+	dnl Save GLIB_CFLAGS and GLIB_LIBS, since the following call to
+	dnl AM_PATH_GLIB will overwrite them.
+	save_GLIB_CFLAGS="$GLIB_CFLAGS"
+        save_GLIB_LIBS="$GLIB_LIBS"
+	dnl Check for gmodule. Store the flags, necessary to compile and link
+	dnl programs, using gmodule functionality, in GMODULE_CFLAGS and
+	dnl GMODULE_LIBS.
+	AM_PATH_GLIB(1.2.6, [gmodule_found=yes], , [gmodule])
+	GMODULE_CFLAGS="$GLIB_CFLAGS"
+	GMODULE_LIBS="$GLIB_LIBS"
+	GLIB_CFLAGS="$save_GLIB_CFLAGS"
+	GLIB_LIBS="$save_GLIB_LIBS"
+else
+    PKG_CHECK_MODULES(GMODULE, [gmodule-2.0], [gmodule_found=yes],)
 fi
 
+if test "x$gmodule_found" = "xyes" ; then
+	dnl Is the gmodule functionality supported on this system.
+	AC_G_MODULE_SUPPORTED
+fi
 
 AC_HEADER_MAJOR
 AC_C_CONST
@@ -214,7 +232,16 @@
     textmode_x11_support="no"
 else
     CPPFLAGS="$CPPFLAGS $X_CFLAGS"
-    MCLIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+    if test "x$av_g_module_supported" = "xyes" ; then
+	dnl Replace the contents of GLIB_CFLAGS and GLIB_LIBS with those of
+	dnl GMODULE_CFLAGS and GMODULE_LIBS, only if X is available and gmodule
+	dnl functionality is supported on the system. This way, MC will be
+	dnl linked against the gmodule library, only when it is really required.
+	GLIB_CFLAGS="$GMODULE_CFLAGS"
+	GLIB_LIBS="$GMODULE_LIBS"
+    else
+        MCLIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS"
+    fi
     AC_DEFINE(HAVE_TEXTMODE_X11_SUPPORT, 1,
 	      [Define to enable getting events from X Window System])
     textmode_x11_support="yes"
diff -urN -x .build -x .inst -x .sinst mc-4.6.0-orig/src/key.c mc-4.6.0/src/key.c
--- mc-4.6.0-orig/src/key.c	2003-01-27 23:37:56.000000000 +0100
+++ mc-4.6.0/src/key.c	2003-02-10 10:06:32.000000000 +0100
@@ -41,6 +41,9 @@
 #include "../vfs/vfs.h"
 
 #ifdef HAVE_TEXTMODE_X11_SUPPORT
+#ifdef HAVE_WORKING_GMODULE
+#include <gmodule.h>
+#endif /* HAVE_WORKING_GMODULE */
 #include <X11/Xlib.h>
 #endif
 
@@ -247,6 +250,30 @@
 }
 
 #ifdef HAVE_TEXTMODE_X11_SUPPORT
+#ifdef HAVE_WORKING_GMODULE
+#define MODULE_DEFAULT_PREFIX "lib"
+#if GLIB_CHECK_VERSION(2,0,0)
+#    define MODULE_DEFAULT_SUFFIX "." G_MODULE_SUFFIX
+#else /* glib < 2.x.x */
+#    ifndef __CYGWIN__
+#       define MODULE_DEFAULT_SUFFIX ".so"
+#    else /* __CYGWIN__ */
+#       define MODULE_DEFAULT_SUFFIX ".dll"
+#    endif
+#endif
+
+#define MODX11_DEFAULT_NAME MODULE_DEFAULT_PREFIX "X11" MODULE_DEFAULT_SUFFIX
+
+typedef Display * (* XOPENDISPLAY) (_Xconst char *);
+typedef int (* XCLOSEDISPLAY) (Display *);
+typedef Bool (* XQUERYPOINTER) (Display *, Window, Window *, Window*,
+				int *, int *, int *, int *, unsigned int *);
+
+static GModule *x11_module;
+static XOPENDISPLAY func_XOpenDisplay;
+static XCLOSEDISPLAY func_XCloseDisplay;
+static XQUERYPOINTER func_XQueryPointer;
+#endif /* HAVE_WORKING_GMODULE */
 static Display *x11_display;
 static Window x11_window;
 #endif /* HAVE_TEXTMODE_X11_SUPPORT */
@@ -255,6 +282,9 @@
    calls any define_sequence */
 void init_key (void)
 {
+#if defined(HAVE_TEXTMODE_X11_SUPPORT) && defined(HAVE_WORKING_GMODULE)
+    gchar *x11_module_fname;
+#endif /* HAVE_TEXTMODE_X11_SUPPORT && HAVE_WORKING_GMODULE */
     char *term = (char *) getenv ("TERM");
     
     /* This has to be the first define_sequence */
@@ -290,9 +320,32 @@
 #endif /* __QNX__ */
 
 #ifdef HAVE_TEXTMODE_X11_SUPPORT
+#ifdef HAVE_WORKING_GMODULE
+    x11_module_fname = g_module_build_path (NULL, "X11");
+    if (x11_module_fname == NULL)
+	x11_module_fname = g_strdup (MODX11_DEFAULT_NAME);
+
+    if (x11_module_fname != NULL) {
+	x11_module = g_module_open (x11_module_fname, G_MODULE_BIND_LAZY);
+	g_free (x11_module_fname);
+	if (x11_module != NULL) {
+	    if (g_module_symbol (x11_module, "XOpenDisplay",
+				 (gpointer *) &func_XOpenDisplay) &&
+		g_module_symbol (x11_module, "XCloseDisplay",
+				 (gpointer *) &func_XCloseDisplay) &&
+		g_module_symbol (x11_module, "XQueryPointer",
+				 (gpointer *) &func_XQueryPointer)) {
+		x11_display = (*func_XOpenDisplay) (0);
+		if (x11_display)
+		    x11_window = DefaultRootWindow (x11_display);
+	    }
+	}
+    }
+#else
     x11_display = XOpenDisplay (0);
     if (x11_display)
         x11_window = DefaultRootWindow (x11_display);
+#endif /* HAVE_WORKING_GMODULE */
 #endif /* HAVE_TEXTMODE_X11_SUPPORT */
 }
 
@@ -1049,8 +1102,13 @@
 	int win_x, win_y;
 	unsigned int mask;
 
+#ifdef HAVE_WORKING_GMODULE
+	(*func_XQueryPointer) (x11_display, x11_window, &root, &child,
+			       &root_x, &root_y, &win_x, &win_y, &mask);
+#else
 	XQueryPointer (x11_display, x11_window, &root, &child, &root_x,
 		       &root_y, &win_x, &win_y, &mask);
+#endif /* HAVE_WORKING_GMODULE */
 
 	if (mask & ShiftMask)
 	    result |= KEY_M_SHIFT;
@@ -1105,7 +1163,14 @@
     s_dispose (select_list);
 
 #ifdef HAVE_TEXTMODE_X11_SUPPORT
+#ifdef HAVE_WORKING_GMODULE
+    if (x11_display)
+	(*func_XCloseDisplay) (x11_display);
+    if (x11_module != NULL)
+	g_module_close (x11_module);
+#else
     if (x11_display)
 	XCloseDisplay (x11_display);
+#endif /* HAVE_WORKING_GMODULE */
 #endif /* HAVE_TEXTMODE_X11_SUPPORT */
 }


More information about the mc-devel mailing list