Move probe_for_GTK() to class Fl_Posix_System_Driver from Fl_X11_System_Driver.

Similarly move dlopen_or_dlsym().
This move is because GTK is not X11-specific.
This commit is contained in:
ManoloFLTK
2021-03-31 09:51:10 +02:00
parent ef41409759
commit ba03dde15c
6 changed files with 113 additions and 107 deletions
+1 -1
View File
@@ -789,7 +789,7 @@ void open_display_i(Display* d) {
#endif
#if USE_XRANDR
void *libxrandr_addr = Fl_X11_System_Driver::dlopen_or_dlsym("libXrandr");
void *libxrandr_addr = Fl_Posix_System_Driver::dlopen_or_dlsym("libXrandr");
if (libxrandr_addr) {
int error_base;
typedef Bool (*XRRQueryExtension_type)(Display*, int*, int*);
@@ -68,7 +68,12 @@ public:
virtual int need_menu_handle_part2() {return 1;}
#if HAVE_DLFCN_H
virtual void *load(const char *filename);
#if HAVE_DLSYM
static void *ptr_gtk;
static bool probe_for_GTK(int major, int minor, void **ptr_gtk);
#endif
#endif
static void *dlopen_or_dlsym(const char *lib_name, const char *func_name = NULL);
// these 4 are implemented in Fl_lock.cxx
virtual void awake(void*);
virtual int lock();
@@ -171,6 +171,111 @@ int Fl_Posix_System_Driver::run_program(const char *program, char **argv, char *
return 1;
}
/**
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_Posix_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
void *Fl_Posix_System_Driver::ptr_gtk = NULL;
bool Fl_Posix_System_Driver::probe_for_GTK(int major, int minor, void **p_ptr_gtk) {
typedef void (*init_t)(int*, void*);
init_t init_f = NULL;
// was GTK previously loaded?
if (Fl_Posix_System_Driver::ptr_gtk) { // yes, it was.
*p_ptr_gtk = Fl_Posix_System_Driver::ptr_gtk;
return true;
}
// Try first with GTK3
Fl_Posix_System_Driver::ptr_gtk = Fl_Posix_System_Driver::dlopen_or_dlsym("libgtk-3");
if (Fl_Posix_System_Driver::ptr_gtk) {
#ifdef DEBUG
puts("selected GTK-3\n");
#endif
} else {
// Try then with GTK2
Fl_Posix_System_Driver::ptr_gtk = Fl_Posix_System_Driver::dlopen_or_dlsym("libgtk-x11-2.0");
#ifdef DEBUG
if (Fl_Posix_System_Driver::ptr_gtk) {
puts("selected GTK-2\n");
}
#endif
}
if (!Fl_Posix_System_Driver::ptr_gtk) {
#ifdef DEBUG
puts("Failure to load libgtk");
#endif
return false;
}
init_f = (init_t)dlsym(Fl_Posix_System_Driver::ptr_gtk, "gtk_init_check");
if (!init_f) return false;
*p_ptr_gtk = Fl_Posix_System_Driver::ptr_gtk;
// The point here is that after running gtk_init_check, the calling program's current locale can be modified.
// To avoid that, we memorize the calling program's current locale and restore the locale
// before returning.
char *before = NULL;
// record in "before" the calling program's current locale
char *p = setlocale(LC_ALL, NULL);
if (p) before = fl_strdup(p);
int ac = 0;
init_f(&ac, NULL); // may change the locale
if (before) {
setlocale(LC_ALL, before); // restore calling program's current locale
free(before);
}
// now check if running version is high enough
if (dlsym(Fl_Posix_System_Driver::ptr_gtk, "gtk_get_major_version") == NULL) { // YES indicates V 3
typedef const char* (*check_t)(int, int, int);
check_t check_f = (check_t)dlsym(Fl_Posix_System_Driver::ptr_gtk, "gtk_check_version");
if (!check_f || check_f(major, minor, 0) ) return false;
}
return true;
}
#endif // HAVE_DLSYM && HAVE_DLFCN_H
////////////////////////////////////////////////////////////////
// POSIX threading...
#if defined(HAVE_PTHREAD)
+1 -1
View File
@@ -286,7 +286,7 @@ void Fl_X11_Screen_Driver::init() {
static XRRSizes_type XRRSizes_f = NULL;
if (!XRRSizes_f) {
XRRSizes_f = (XRRSizes_type)Fl_X11_System_Driver::dlopen_or_dlsym("libXrandr", "XRRSizes");
XRRSizes_f = (XRRSizes_type)Fl_Posix_System_Driver::dlopen_or_dlsym("libXrandr", "XRRSizes");
}
if (XRRSizes_f) {
int nscreens;
-4
View File
@@ -64,10 +64,6 @@ public:
virtual void add_fd(int fd, Fl_FD_Handler cb, void* = 0);
virtual void remove_fd(int, int when);
virtual void remove_fd(int);
#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 */
+1 -101
View File
@@ -366,7 +366,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;
uuid_generate_f = (gener_f_type)Fl_X11_System_Driver::dlopen_or_dlsym("libuuid", "uuid_generate");
uuid_generate_f = (gener_f_type)Fl_Posix_System_Driver::dlopen_or_dlsym("libuuid", "uuid_generate");
}
if (uuid_generate_f) {
uuid_generate_f(b);
@@ -591,106 +591,6 @@ static void* quadruple_dlopen(const char *libname)
}
#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) {
typedef void (*init_t)(int*, void*);
*ptr_gtk = NULL;
// was GTK previously loaded?
init_t init_f = (init_t)dlsym(RTLD_DEFAULT, "gtk_init_check");
if (init_f) { // yes it was.
*ptr_gtk = RTLD_DEFAULT; // Caution: NULL under linux, not-NULL under Darwin
} else {
// Try first with GTK3
*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_X11_System_Driver::dlopen_or_dlsym("libgtk-x11-2.0");
#ifdef DEBUG
if (*ptr_gtk) {
puts("selected GTK-2\n");
}
#endif
}
if (!(*ptr_gtk)) {
#ifdef DEBUG
puts("Failure to load libgtk");
#endif
return false;
}
init_f = (init_t)dlsym(*ptr_gtk, "gtk_init_check");
if (!init_f) return false;
}
// The point here is that after running gtk_init_check, the calling program's current locale can be modified.
// To avoid that, we memorize the calling program's current locale and restore the locale
// before returning.
char *before = NULL;
// record in "before" the calling program's current locale
char *p = setlocale(LC_ALL, NULL);
if (p) before = fl_strdup(p);
int ac = 0;
init_f(&ac, NULL); // may change the locale
if (before) {
setlocale(LC_ALL, before); // restore calling program's current locale
free(before);
}
// now check if running version is high enough
if (dlsym(*ptr_gtk, "gtk_get_major_version") == NULL) { // YES indicates V 3
typedef const char* (*check_t)(int, int, int);
check_t check_f = (check_t)dlsym(*ptr_gtk, "gtk_check_version");
if (!check_f || check_f(major, minor, 0) ) return false;
}
return true;
}
#endif // HAVE_DLSYM && HAVE_DLFCN_H && defined(RTLD_DEFAULT)
#if !defined(FL_DOXYGEN)