#include "gtkloader.h" extern "C" { #include "gtk-imports.h" } #include #ifdef _WIN32 #include #include #endif #ifdef __linux #include #endif void GtkLoader::loadLibraryWin64(const char *lib, void **handle) { #ifdef _WIN32 #define DIR "C:\\devel\\yellownotes\\gtk3\\bin" HMODULE dll = nullptr; std::string dir = DIR; *handle = nullptr; auto mklibname = [](const char *libname) { std::string dll; dll = std::string(DIR) + "\\" + libname + ".dll"; return dll; }; std::string library; library = mklibname(lib); char *cwd = _getcwd(NULL, 0); if (cwd == nullptr) { throw std::string("Cannot get current working directory"); } _chdir(dir.c_str()); dll = LoadLibraryA(library.c_str()); _chdir(cwd); free(cwd); if (dll == nullptr) { throw std::string("Cannot load library '") + lib + "'"; } *handle = reinterpret_cast(dll); #endif } void GtkLoader::loadLibraryLinux(const char *lib, void **handle) { #ifdef __linux *handle = ::dlopen(lib, RTLD_LAZY); if (*handle == NULL) { throw std::string("Cannot load library '") + lib + "'"; } #endif } void GtkLoader::loadFunctionWin64(const char *func, void **func_ptr) { #ifdef _WIN32 FARPROC fp = nullptr; std::list::const_iterator it = library_handles.begin(); while (fp == nullptr && it != library_handles.end()) { HMODULE handle = reinterpret_cast(*it); fp = GetProcAddress(handle, func); it++; } *func_ptr = reinterpret_cast(fp); if (fp == nullptr) { throw std::string("Cannot load function '") + func; } #endif } void GtkLoader::loadFunctionLinux(const char *func, void **func_ptr) { #ifdef __linux *func_ptr = nullptr; std::list::const_iterator it = library_handles.begin(); while(*func_ptr == nullptr && it != library_handles.end()) { void *handle = *it; *func_ptr = dlsym(handle, func); it++; } if (*func_ptr == nullptr) { throw std::string("Cannot load function '") + func; } #endif } void GtkLoader::dlopen() { if (library_handles.size() == 0) { #ifdef _WIN32 const char *libs[] = { "gobject-2.0-0", "gtk-3-vs17", "glib-2.0-0", "gio-2.0-0", "gdk-3-vs17", "gdk_pixbuf-2.0-0", NULL }; int i; for(i = 0; libs[i] != NULL; i++) { void *lib; loadLibraryWin64(libs[i], &lib); if (lib) { library_handles.push_back(lib); } } #endif #ifdef __linux const char *libs[] = { "libgtk-3.so", "libgobject-2.0.so", "libgio-2.0.so", "libglib-2.0.so", "libgdk-3.so", NULL }; int i; for(i = 0; libs[i] != NULL; i++) { void *lib; loadLibraryLinux(libs[i], &lib); if (lib) { library_handles.push_back(lib); } } #endif } } void GtkLoader::loadFunction(const char *func, void **func_ptr) { #ifdef _WIN32 loadFunctionWin64(func, func_ptr); #endif #ifdef __linux loadFunctionLinux(func, func_ptr); #endif } static void loader(const char *func, void **func_ptr, void *user_data) { GtkLoader *l = reinterpret_cast(user_data); l->loadFunction(func, func_ptr); } void GtkLoader::loadGtk() { dlopen(); loadGtkFunctions(loader, this); } GtkLoader::GtkLoader() { }