Files
yellownotes/gtkloader.cpp

163 lines
3.5 KiB
C++

#include "gtkloader.h"
extern "C" {
#include "gtk-imports.h"
}
#include <string>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
#endif
#ifdef __linux
#include <dlfcn.h>
#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<void *>(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<void *>::const_iterator it = library_handles.begin();
while (fp == nullptr && it != library_handles.end()) {
HMODULE handle = reinterpret_cast<HMODULE>(*it);
fp = GetProcAddress(handle, func);
it++;
}
*func_ptr = reinterpret_cast<void *>(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<void *>::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<GtkLoader *>(user_data);
l->loadFunction(func, func_ptr);
}
void GtkLoader::loadGtk()
{
dlopen();
loadGtkFunctions(loader, this);
}
GtkLoader::GtkLoader()
{
}