changeset 27863:f1799ba16729 v8.2.4457

patch 8.2.4457: the GPM library can only be linked statically Commit: https://github.com/vim/vim/commit/33fc4a63071c03ad46636b345a814e7e6d8f4ae0 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 23 18:07:38 2022 +0000 patch 8.2.4457: the GPM library can only be linked statically Problem: The GPM library can only be linked statically. Solution: Make it possible to load the GPM library dynamically. (Damien)
author Bram Moolenaar <Bram@vim.org>
date Wed, 23 Feb 2022 19:15:03 +0100
parents d61cde8ab682
children dbc9ba82d6fd
files runtime/doc/various.txt src/Makefile src/config.h.in src/configure.ac src/evalfunc.c src/feature.h src/os_unix.c src/proto/os_unix.pro src/version.c
diffstat 9 files changed, 101 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/various.txt
+++ b/runtime/doc/various.txt
@@ -410,6 +410,7 @@ T  *+mouse*		Mouse handling |mouse-using
 N  *+mouseshape*	|'mouseshape'|
 B  *+mouse_dec*		Unix only: Dec terminal mouse handling |dec-mouse|
 N  *+mouse_gpm*		Unix only: Linux console mouse handling |gpm-mouse|
+m  *+mouse_gpm/dyn*	Same as |+mouse_gpm| with optional library dependency |/dyn|
 N  *+mouse_jsbterm*	JSB mouse handling |jsbterm-mouse|
 B  *+mouse_netterm*	Unix only: netterm mouse handling |netterm-mouse|
 N  *+mouse_pterm*	QNX only: pterm mouse handling |qnx-terminal|
--- a/src/Makefile
+++ b/src/Makefile
@@ -526,6 +526,8 @@ CClink = $(CC)
 # though you have gpm libraries and includes.
 # For Debian/Ubuntu gpm support requires the libgpm-dev package.
 #CONF_OPT_GPM = --disable-gpm
+# Use this to enable dynamic loading of the GPM library.
+#CONF_OPT_GPM = --enable-gpm=dynamic
 
 # sysmouse - For mouse support on FreeBSD and DragonFly console via sysmouse
 # Uncomment this when you do not want do include sysmouse support, even
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -507,3 +507,6 @@
 
 /* Define if _SC_SIGSTKSZ is available via sysconf() */
 #undef HAVE_SYSCONF_SIGSTKSZ
+
+/* Define if you want to load libgpm dynamically */
+#undef DYNAMIC_GPM
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -4096,13 +4096,13 @@ if test "x$GTK_CFLAGS" != "x"; then
   LIBS="$ac_save_LIBS"
 fi
 
-AC_MSG_CHECKING(--disable-gpm argument)
+AC_MSG_CHECKING(--enable-gpm argument)
 AC_ARG_ENABLE(gpm,
-	[  --disable-gpm           Don't use gpm (Linux mouse daemon).], ,
+	[  --enable-gpm=OPTS       Use gpm (Linux mouse daemon). default=yes OPTS=yes/no/dynamic], ,
 	[enable_gpm="yes"])
 
-if test "$enable_gpm" = "yes"; then
-  AC_MSG_RESULT(no)
+if test "$enable_gpm" = "yes" -o "$enable_gpm" = "dynamic"; then
+  AC_MSG_RESULT($enable_gpm)
   dnl Checking if gpm support can be compiled
   AC_CACHE_CHECK([for gpm], vi_cv_have_gpm,
 	[olibs="$LIBS" ; LIBS="-lgpm"]
@@ -4117,11 +4117,15 @@ if test "$enable_gpm" = "yes"; then
 	[LIBS="$olibs"]
     )
   if test $vi_cv_have_gpm = yes; then
-    LIBS="$LIBS -lgpm"
+    if test "$enable_gpm" = "yes"; then
+      LIBS="$LIBS -lgpm"
+    else
+      AC_DEFINE(DYNAMIC_GPM)
+    fi
     AC_DEFINE(HAVE_GPM)
   fi
 else
-  AC_MSG_RESULT(yes)
+  AC_MSG_RESULT(no)
 fi
 
 AC_MSG_CHECKING(--disable-sysmouse argument)
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -5786,7 +5786,7 @@ f_has(typval_T *argvars, typval_T *rettv
 #endif
 		},
 	{"mouse_gpm",
-#if (defined(UNIX) || defined(VMS)) && defined(FEAT_MOUSE_GPM)
+#if (defined(UNIX) || defined(VMS)) && defined(FEAT_MOUSE_GPM) && !defined(DYNAMIC_GPM)
 		1
 #else
 		0
@@ -6392,6 +6392,10 @@ f_has(typval_T *argvars, typval_T *rettv
 	else if (STRICMP(name, "terminal") == 0)
 	    n = terminal_enabled();
 #endif
+#ifdef DYNAMIC_GPM
+	else if (STRICMP(name, "mouse_gpm") == 0)
+	    n = gpm_available();
+#endif
     }
 
     // features not in has_list[]
--- a/src/feature.h
+++ b/src/feature.h
@@ -952,6 +952,12 @@
  */
 #if defined(FEAT_NORMAL) && defined(HAVE_GPM)
 # define FEAT_MOUSE_GPM
+/*
+ * +mouse_gpm/dyn   Load libgpm dynamically.
+ */
+# ifndef DYNAMIC_GPM
+// #  define DYNAMIC_GPM
+# endif
 #endif
 
 #if defined(FEAT_NORMAL) && defined(HAVE_SYSMOUSE)
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -55,7 +55,25 @@ static int selinux_enabled = -1;
 #endif
 
 #ifdef FEAT_MOUSE_GPM
+
 # include <gpm.h>
+
+# ifdef DYNAMIC_GPM
+#  define Gpm_Open     (*dll_Gpm_Open)
+#  define Gpm_Close    (*dll_Gpm_Close)
+#  define Gpm_GetEvent (*dll_Gpm_GetEvent)
+#  define gpm_flag     (dll_gpm_flag != NULL ? *dll_gpm_flag :  0)
+#  define gpm_fd       (dll_gpm_fd   != NULL ? *dll_gpm_fd   : -1)
+
+static int (*dll_Gpm_Open)     (Gpm_Connect *, int);
+static int (*dll_Gpm_Close)    (void);
+static int (*dll_Gpm_GetEvent) (Gpm_Event *);
+static int *dll_gpm_flag;
+static int *dll_gpm_fd;
+
+static void *libgpm_hinst;
+# endif
+
 // <linux/keyboard.h> contains defines conflicting with "keymap.h",
 // I just copied relevant defines here. A cleaner solution would be to put gpm
 // code into separate file and include there linux/keyboard.h
@@ -6446,7 +6464,7 @@ select_eintr:
 	}
 # endif
 # ifdef FEAT_MOUSE_GPM
-	if (ret > 0 && gpm_flag && check_for_gpm != NULL && gpm_fd >= 0)
+	if (ret > 0 && check_for_gpm != NULL && gpm_flag && gpm_fd >= 0)
 	{
 	    if (FD_ISSET(gpm_fd, &efds))
 		gpm_close();
@@ -7172,6 +7190,49 @@ mch_rename(const char *src, const char *
 #endif // !HAVE_RENAME
 
 #if defined(FEAT_MOUSE_GPM) || defined(PROTO)
+# if defined(DYNAMIC_GPM) || defined(PROTO)
+/*
+ * Initialize Gpm's symbols for dynamic linking.
+ * Must be called only if libgpm_hinst is NULL.
+ */
+    static int
+load_libgpm(void)
+{
+    libgpm_hinst = dlopen("libgpm.so", RTLD_LAZY|RTLD_GLOBAL);
+
+    if (libgpm_hinst == NULL)
+    {
+	if (p_verbose > 0)
+	    smsg_attr(HL_ATTR(HLF_W),
+		        _("Could not load gpm library: %s"), dlerror());
+	return FAIL;
+    }
+
+    if (
+	    (dll_Gpm_Open     = dlsym(libgpm_hinst, "Gpm_Open"))     == NULL
+	||  (dll_Gpm_Close    = dlsym(libgpm_hinst, "Gpm_Close"))    == NULL
+	||  (dll_Gpm_GetEvent = dlsym(libgpm_hinst, "Gpm_GetEvent")) == NULL
+	||  (dll_gpm_flag     = dlsym(libgpm_hinst, "gpm_flag"))     == NULL
+	||  (dll_gpm_fd       = dlsym(libgpm_hinst, "gpm_fd"))       == NULL
+      )
+    {
+	semsg(_(e_could_not_load_library_str_str), "gpm", dlerror());
+	dlclose(libgpm_hinst);
+	libgpm_hinst = NULL;
+	dll_gpm_flag = NULL;
+	dll_gpm_fd   = NULL;
+	return FAIL;
+    }
+    return OK;
+}
+
+    int
+gpm_available(void)
+{
+    return libgpm_hinst != NULL || load_libgpm() == OK;
+}
+# endif // DYNAMIC_GPM
+
 /*
  * Initializes connection with gpm (if it isn't already opened)
  * Return 1 if succeeded (or connection already opened), 0 if failed
@@ -7181,6 +7242,11 @@ gpm_open(void)
 {
     static Gpm_Connect gpm_connect; // Must it be kept till closing ?
 
+#ifdef DYNAMIC_GPM
+    if (!gpm_available())
+	return 0;
+#endif
+
     if (!gpm_flag)
     {
 	gpm_connect.eventMask = (GPM_UP | GPM_DRAG | GPM_DOWN);
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -85,4 +85,5 @@ void clip_xterm_set_selection(Clipboard_
 int xsmp_handle_requests(void);
 void xsmp_init(void);
 void xsmp_close(void);
+int gpm_available(void);
 /* vim: set ft=c : */
--- a/src/version.c
+++ b/src/version.c
@@ -375,7 +375,11 @@ static char *(features[]) =
 	"-mouse_dec",
 # endif
 # ifdef FEAT_MOUSE_GPM
+#  ifdef DYNAMIC_GPM
+	"+mouse_gpm/dyn",
+#  else
 	"+mouse_gpm",
+#  endif
 # else
 	"-mouse_gpm",
 # endif
@@ -751,6 +755,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4457,
+/**/
     4456,
 /**/
     4455,