diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2020-10-04 08:20:50 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2020-10-04 08:21:07 +0200 |
| commit | 0c55cd1aca19b57a9b8837d1672ae260cfca4d78 (patch) | |
| tree | a9f5b10b3ec558d7525f24037cafc86ce796d9e5 | |
| parent | 46598229a9605b25e3da5e0d7ad41343cf429497 (diff) | |
Create Fl_X11_System_Driver::dlopen_or_dlsym() for run-time addresses.
The intent is to gather in a single place of the X11 platform source code
all variable elements when using dlopen() and dlsym() system functions
(e.g., .so vs .dylib extension name, is RTLD_DEFAULT available, locations
to be sought).
Member function Fl_System_Driver::load() is created only to support
Fl_Plugin_Manager::load().
| -rw-r--r-- | src/Fl_Preferences.cxx | 2 | ||||
| -rw-r--r-- | src/Fl_System_Driver.H | 2 | ||||
| -rw-r--r-- | src/Fl_x.cxx | 3 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.H | 4 | ||||
| -rw-r--r-- | src/drivers/Posix/Fl_Posix_System_Driver.cxx | 47 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_System_Driver.H | 2 | ||||
| -rw-r--r-- | src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx | 2 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_Screen_Driver.cxx | 9 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.H | 1 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.cxx | 80 |
10 files changed, 84 insertions, 68 deletions
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx index 11851c0de..454b0f759 100644 --- a/src/Fl_Preferences.cxx +++ b/src/Fl_Preferences.cxx @@ -1652,7 +1652,7 @@ void Fl_Plugin_Manager::removePlugin(Fl_Preferences::ID id) { int Fl_Plugin_Manager::load(const char *filename) { // the functions below will automatically load plugins that are defined: // Fl_My_Plugin plugin(); - void *dl = Fl::system_driver()->dlopen(filename); + void *dl = Fl::system_driver()->load(filename); // There is no way of unloading a plugin! return (dl != 0) ? 0 : -1; } diff --git a/src/Fl_System_Driver.H b/src/Fl_System_Driver.H index 73f197f95..44b2333c0 100644 --- a/src/Fl_System_Driver.H +++ b/src/Fl_System_Driver.H @@ -178,7 +178,7 @@ public: // the default implementation of preferences_need_protection_check() may be enough virtual int preferences_need_protection_check() {return 0;} // implement to support Fl_Plugin_Manager::load() - virtual void *dlopen(const char *filename) {return NULL;} + virtual void *load(const char *filename) {return NULL;} // the default implementation is most probably enough virtual void png_extra_rgba_processing(unsigned char *array, int w, int h) {} // the default implementation is most probably enough diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx index a046cde65..947203679 100644 --- a/src/Fl_x.cxx +++ b/src/Fl_x.cxx @@ -699,8 +699,7 @@ void open_display_i(Display* d) { #endif #if USE_XRANDR - void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY); - if (!libxrandr_addr) libxrandr_addr = Fl::system_driver()->dlopen("libXrandr.so"); + void *libxrandr_addr = Fl_X11_System_Driver::dlopen_or_dlsym("libXrandr"); if (libxrandr_addr) { int error_base; typedef Bool (*XRRQueryExtension_type)(Display*, int*, int*); diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 3f4cf72c8..3de26e5aa 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -65,7 +65,9 @@ public: virtual int rename(const char* f, const char *n) {return ::rename(f, n);} virtual const char *getpwnam(const char *login); virtual int need_menu_handle_part2() {return 1;} - virtual void *dlopen(const char *filename); +#if HAVE_DLFCN_H + virtual void *load(const char *filename); +#endif // these 4 are implemented in Fl_lock.cxx virtual void awake(void*); virtual int lock(); diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index a05781d1b..20b7aef28 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -1,7 +1,7 @@ // // Definition of Apple Darwin system driver. // -// Copyright 1998-2017 by Bill Spitzak and others. +// Copyright 1998-2020 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -47,52 +47,11 @@ #if HAVE_DLFCN_H -static void* triple_dlopen(const char *filename1) -{ - void *ptr = ::dlopen(filename1, RTLD_LAZY | RTLD_GLOBAL); - if (!ptr) { - char filename2[FL_PATH_MAX]; - sprintf(filename2, "%s.1", filename1); - ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); - if (!ptr) { - sprintf(filename2, "%s.0", filename1); - ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); - } - } - return ptr; +void *Fl_Posix_System_Driver::load(const char *filename) { + return ::dlopen(filename, RTLD_LAZY); } #endif -void *Fl_Posix_System_Driver::dlopen(const char *filename) -{ - void *ptr = NULL; -#if HAVE_DLFCN_H - ptr = triple_dlopen(filename); -# ifdef __APPLE_CC__ // allows testing on Darwin + XQuartz + fink - if (!ptr) { - char *f_dylib = (char*)malloc(strlen(filename)+7); - strcpy(f_dylib, filename); - char *p = strrchr(f_dylib, '.'); - if (!p) p = f_dylib + strlen(f_dylib); - strcpy(p, ".dylib"); - char path[FL_PATH_MAX]; - sprintf(path, "/sw/lib/%s", f_dylib); - ptr = ::dlopen(path, RTLD_LAZY | RTLD_GLOBAL); - if (!ptr) { - sprintf(path, "/opt/sw/lib/%s", f_dylib); - ptr = ::dlopen(path, RTLD_LAZY | RTLD_GLOBAL); - } - if (!ptr) { - sprintf(path, "/opt/X11/lib/%s", f_dylib); - ptr = ::dlopen(path, RTLD_LAZY | RTLD_GLOBAL); - } - free(f_dylib); - } -# endif // __APPLE_CC__ -#endif // HAVE_DLFCN_H - return ptr; -} - int Fl_Posix_System_Driver::file_type(const char *filename) { int filetype; diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H index 0dd12ca17..1860bc8b3 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.H @@ -88,7 +88,7 @@ public: virtual void newUUID(char *uuidBuffer); virtual char *preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, const char *application); - virtual void *dlopen(const char *filename); + virtual void *load(const char *filename); virtual void png_extra_rgba_processing(unsigned char *array, int w, int h); virtual const char *next_dir_sep(const char *start); // these 3 are implemented in Fl_lock.cxx diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx index 025d4ee37..518b32845 100644 --- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx +++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx @@ -912,7 +912,7 @@ char *Fl_WinAPI_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre return filename; } -void *Fl_WinAPI_System_Driver::dlopen(const char *filename) { +void *Fl_WinAPI_System_Driver::load(const char *filename) { return LoadLibraryW(utf8_to_wchar(filename, wbuf)); } diff --git a/src/drivers/X11/Fl_X11_Screen_Driver.cxx b/src/drivers/X11/Fl_X11_Screen_Driver.cxx index a09768975..30482cf8f 100644 --- a/src/drivers/X11/Fl_X11_Screen_Driver.cxx +++ b/src/drivers/X11/Fl_X11_Screen_Driver.cxx @@ -1,7 +1,7 @@ // // Definition of X11 Screen interface // -// Copyright 1998-2018 by Bill Spitzak and others. +// Copyright 1998-2020 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -19,7 +19,8 @@ #include "Fl_X11_Screen_Driver.H" #include "../Xlib/Fl_Font.H" #include "Fl_X11_Window_Driver.H" -#include "../../Fl_System_Driver.H" +#include "Fl_X11_System_Driver.H" +#include "../Posix/Fl_Posix_System_Driver.H" #include "../Xlib/Fl_Xlib_Graphics_Driver.H" #include <FL/Fl.H> #include <FL/platform.H> @@ -285,9 +286,7 @@ void Fl_X11_Screen_Driver::init() { static XRRSizes_type XRRSizes_f = NULL; if (!XRRSizes_f) { - void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY); - if (!libxrandr_addr) libxrandr_addr = Fl::system_driver()->dlopen("libXrandr.so"); - if (libxrandr_addr) XRRSizes_f = (XRRSizes_type)dlsym(libxrandr_addr, "XRRSizes"); + XRRSizes_f = (XRRSizes_type)Fl_X11_System_Driver::dlopen_or_dlsym("libXrandr", "XRRSizes"); } if (XRRSizes_f) { int nscreens; diff --git a/src/drivers/X11/Fl_X11_System_Driver.H b/src/drivers/X11/Fl_X11_System_Driver.H index f8fddc741..004e474ae 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.H +++ b/src/drivers/X11/Fl_X11_System_Driver.H @@ -67,6 +67,7 @@ public: #if HAVE_DLSYM && HAVE_DLFCN_H static bool probe_for_GTK(int major, int minor, void **ptr_gtk); #endif + static void *dlopen_or_dlsym(const char *lib_name, const char *func_name = NULL); }; #endif /* FL_X11_SYSTEM_DRIVER_H */ diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx index c99f31f86..88fa416f5 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.cxx +++ b/src/drivers/X11/Fl_X11_System_Driver.cxx @@ -2,7 +2,7 @@ // Definition of Posix system driver // for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2017 by Bill Spitzak and others. +// Copyright 2010-2020 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -365,15 +365,7 @@ void Fl_X11_System_Driver::newUUID(char *uuidBuffer) static gener_f_type uuid_generate_f = NULL; if (!looked_for_uuid_generate) { looked_for_uuid_generate = true; -# ifdef RTLD_DEFAULT - uuid_generate_f = (gener_f_type)dlsym(RTLD_DEFAULT, "uuid_generate"); -# endif - if (!uuid_generate_f) { - void *libuuid = this->dlopen("libuuid.so"); - if (libuuid) { - uuid_generate_f = (gener_f_type)dlsym(libuuid, "uuid_generate"); - } - } + uuid_generate_f = (gener_f_type)Fl_X11_System_Driver::dlopen_or_dlsym("libuuid", "uuid_generate"); } if (uuid_generate_f) { uuid_generate_f(b); @@ -572,6 +564,70 @@ int Fl_X11_System_Driver::utf8locale() { return ret; } +#if HAVE_DLSYM && HAVE_DLFCN_H +static void* quadruple_dlopen(const char *libname) +{ + char filename2[FL_PATH_MAX]; + sprintf(filename2, "%s.so", libname); + void *ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); + if (!ptr) { + sprintf(filename2, "%s.so.2", libname); + ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); + if (!ptr) { + sprintf(filename2, "%s.so.1", libname); + ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); + if (!ptr) { + sprintf(filename2, "%s.so.0", libname); + ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL); + } + } + } + return ptr; +} +#endif + +/** + Returns the run-time address of a function or of a shared library. + \param lib_name shared library name (without its extension) or NULL to search the function in the running program + \param func_name function name or NULL + \return the address of the function (when func_name != NULL) or of the shared library, or NULL if not found. + */ +void *Fl_X11_System_Driver::dlopen_or_dlsym(const char *lib_name, const char *func_name) +{ + void *lib_address = NULL; +#if HAVE_DLSYM && HAVE_DLFCN_H + void *func_ptr = NULL; + if (func_name) { +#ifdef RTLD_DEFAULT + func_ptr = dlsym(RTLD_DEFAULT, func_name); +#else + void *p = dlopen(NULL, RTLD_LAZY); + func_ptr = dlsym(p, func_name); +#endif + if (func_ptr) return func_ptr; + } +#ifdef __APPLE_CC__ // allows testing on Darwin + XQuartz + fink + if (lib_name) { + char path[FL_PATH_MAX]; + sprintf(path, "/opt/X11/lib/%s.dylib", lib_name); + lib_address = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); + if (!lib_address) { + sprintf(path, "/opt/sw/lib/%s.dylib", lib_name); + lib_address = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); + if (!lib_address) { + sprintf(path, "/sw/lib/%s.dylib", lib_name); + lib_address = dlopen(path, RTLD_LAZY | RTLD_GLOBAL); + } + } + } +#else + if (lib_name) lib_address = quadruple_dlopen(lib_name); +#endif // __APPLE_CC__ + if (func_name && lib_address) return ::dlsym(lib_address, func_name); +#endif // HAVE_DLFCN_H + return lib_address; +} + #if HAVE_DLSYM && HAVE_DLFCN_H && defined(RTLD_DEFAULT) bool Fl_X11_System_Driver::probe_for_GTK(int major, int minor, void **ptr_gtk) { @@ -583,14 +639,14 @@ bool Fl_X11_System_Driver::probe_for_GTK(int major, int minor, void **ptr_gtk) { *ptr_gtk = RTLD_DEFAULT; // Caution: NULL under linux, not-NULL under Darwin } else { // Try first with GTK3 - *ptr_gtk = Fl::system_driver()->dlopen("libgtk-3.so"); + *ptr_gtk = Fl_X11_System_Driver::dlopen_or_dlsym("libgtk-3"); if (*ptr_gtk) { #ifdef DEBUG puts("selected GTK-3\n"); #endif } else { // Try then with GTK2 - *ptr_gtk = Fl::system_driver()->dlopen("libgtk-x11-2.0.so"); + *ptr_gtk = Fl_X11_System_Driver::dlopen_or_dlsym("libgtk-x11-2.0"); #ifdef DEBUG if (*ptr_gtk) { puts("selected GTK-2\n"); |
