summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/various.txt1
-rw-r--r--src/Makefile2
-rw-r--r--src/config.h.in3
-rw-r--r--src/configure.ac16
-rw-r--r--src/evalfunc.c6
-rw-r--r--src/feature.h6
-rw-r--r--src/os_unix.c68
-rw-r--r--src/proto/os_unix.pro1
-rw-r--r--src/version.c6
9 files changed, 101 insertions, 8 deletions
diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt
index 5b35dca923..9ca65170f0 100644
--- 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|
diff --git a/src/Makefile b/src/Makefile
index 8b0b268789..24d39e8d0d 100644
--- 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
diff --git a/src/config.h.in b/src/config.h.in
index 20339de8a7..2653e8dda5 100644
--- 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
diff --git a/src/configure.ac b/src/configure.ac
index 67b376a49e..4dd74fc2a8 100644
--- 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)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index cea002f11c..eb42269cfa 100644
--- 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[]
diff --git a/src/feature.h b/src/feature.h
index 65185a2176..9564f8e100 100644
--- 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)
diff --git a/src/os_unix.c b/src/os_unix.c
index a6f3a6c484..d36eb46a2c 100644
--- 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 *dest)
#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);
diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro
index ee22b4a422..7dd8e231bc 100644
--- a/src/proto/os_unix.pro
+++ b/src/proto/os_unix.pro
@@ -85,4 +85,5 @@ void clip_xterm_set_selection(Clipboard_T *cbd);
int xsmp_handle_requests(void);
void xsmp_init(void);
void xsmp_close(void);
+int gpm_available(void);
/* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index 0bd499131e..85af241730 100644
--- 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,