# HG changeset patch # User Bram Moolenaar # Date 1645640103 -3600 # Node ID f1799ba167291d86a3dd48a55a43ba60111829ff # Parent d61cde8ab682b022353fa84644a7aac847223c58 patch 8.2.4457: the GPM library can only be linked statically Commit: https://github.com/vim/vim/commit/33fc4a63071c03ad46636b345a814e7e6d8f4ae0 Author: Bram Moolenaar 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) diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt --- 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 --- 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 --- 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 --- 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 --- 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 --- 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 --- 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 + +# 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 + // 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); diff --git a/src/proto/os_unix.pro b/src/proto/os_unix.pro --- 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 : */ diff --git a/src/version.c b/src/version.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,