220 lines
5.1 KiB
C++
220 lines
5.1 KiB
C++
#include "gtkloader.h"
|
|
|
|
extern "C" {
|
|
#include "gtk-imports.h"
|
|
}
|
|
|
|
#include <string>
|
|
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <direct.h>
|
|
#endif
|
|
|
|
#if defined(__linux) || defined(TARGET_OS_OSX)
|
|
#include <dlfcn.h>
|
|
#endif
|
|
|
|
#include <iostream>
|
|
#include "info_over_me.h"
|
|
|
|
void GtkLoader::loadLibraryWin64(const char *lib, void **handle)
|
|
{
|
|
#ifdef _WIN32
|
|
InfoOverMe info;
|
|
|
|
//#define DIR "C:\\devel\\yellownotes\\gtk3\\bin"
|
|
HMODULE dll = nullptr;
|
|
std::string my_dir = info.containingFolder();
|
|
std::string dir = my_dir + "\\gtk3";
|
|
|
|
std::cout << "my folder = " << dir << std::endl;
|
|
|
|
*handle = nullptr;
|
|
|
|
auto mklibname = [dir](const char *libname) {
|
|
std::string dll;
|
|
dll = std::string(libname) + ".dll";
|
|
std::cout << "library: " << dll << std::endl;
|
|
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::loadLibraryOSX(const char *lib, void **handle)
|
|
{
|
|
#ifdef TARGET_OS_OSX
|
|
std::string full_lib_path = std::string("/opt/homebrew/lib/") + lib;
|
|
*handle = ::dlopen(full_lib_path.c_str(), RTLD_LAZY);
|
|
if (*handle == NULL) {
|
|
throw std::string("Cannot load library '") + lib + "'";
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void GtkLoader::loadFunctionOSX(const char *func, void **func_ptr)
|
|
{
|
|
#ifdef TARGET_OS_OSX
|
|
*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::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",
|
|
"libgdk_pixbuf-2.0.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
|
|
#ifdef TARGET_OS_OSX
|
|
const char *libs[] = {
|
|
"libgtk-3.0.dylib",
|
|
"libgobject-2.0.dylib",
|
|
"libgio-2.0.dylib",
|
|
"libglib-2.0.dylib",
|
|
"libgdk-3.dylib",
|
|
"libgdk_pixbuf-2.0.dylib",
|
|
NULL
|
|
};
|
|
int i;
|
|
for(i = 0; libs[i] != NULL; i++) {
|
|
void *lib;
|
|
loadLibraryOSX(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
|
|
#ifdef TARGET_OS_OSX
|
|
loadFunctionOSX(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()
|
|
{
|
|
}
|