Files
yellownotes/gtkloader.cpp
2025-11-27 09:46:00 +01:00

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()
{
}