mirror of
https://github.com/fltk/fltk.git
synced 2026-05-23 07:46:09 +08:00
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:
+1
-1
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user