Initial import

This commit is contained in:
2025-11-18 09:19:15 +01:00
parent 6919487c3d
commit 9c99a01464
6 changed files with 305 additions and 0 deletions

17
CMakeLists.txt Normal file
View File

@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.16)
project(yellownotes LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(yellownotes main.cpp
gtk-imports.h
gtkloader.h gtkloader.cpp
gtk-imports.c)
include(GNUInstallDirs)
install(TARGETS yellownotes
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

15
gtk-imports.c Normal file
View File

@@ -0,0 +1,15 @@
#include <malloc.h>
#define GTK_DECLARE_FUNCS
#include "gtk-imports.h"
void loadGtkFunctions(void (*loader)(const char *funcname, void **func, void *user_data), void *user_data)
{
#undef GTK_IMPORTS_H
#undef GTK_DECLARE_FUNCS
#undef DECL
#define GTK_LOAD_FUNCS
#include "gtk-imports.h"
}

98
gtk-imports.h Normal file
View File

@@ -0,0 +1,98 @@
#ifndef GTK_IMPORTS_H
#define GTK_IMPORTS_H
/*************************************************************************************
* boiler plate code to initialize Gtk functions etc.
*************************************************************************************/
void loadGtkFunctions(void (*loader)(const char *, void **, void *), void *user_data);
/*************************************************************************************
* Gtk Functions to load from shared library
*************************************************************************************/
#ifdef GTK_DECLARE_FUNCS
#define EXTERN
#ifndef NULL
#define NULL 0
#endif
#define DECL(ret, f, arg1) EXTERN ret (*f) arg1 = NULL;
#else
#ifdef GTK_LOAD_FUNCS
#define DECL(ret, f, arg1) loader(#f, (void **) &f, user_data);
#else
#define EXTERN extern
#define DECL(ret, f, arg1) EXTERN ret (*f) arg1;
#endif
#endif
#ifndef GTK_IMPORTS_TYPES
#define GTK_IMPORTS_TYPES
typedef void GtkWidget;
typedef void GtkWindow;
typedef void GtkApplication;
typedef void GApplication;
typedef void GObject;
typedef void *GCallback;
typedef void *gpointer;
typedef int gboolean;
typedef int gint;
typedef char gchar;
typedef void GClosure;
typedef void (*GClosureNotify) (gpointer data, GClosure *closure);
typedef enum {
GTK_WINDOW_TOPLEVEL = 0
} GtkWindowType;
typedef enum {
G_APPLICATION_FLAGS_NONE = 0,
G_APPLICATION_DEFAULT_FLAGS = 0,
G_APPLICATION_IS_SERVICE = 1,
G_APPLICATION_IS_LAUNCHER = 2,
G_APPLICATION_HANDLES_OPEN = 4,
G_APPLICATION_HANDLES_COMMAND_LINE = 8,
G_APPLICATION_SEND_ENVIRONMENT = 16,
G_APPLICATION_NON_UNIQUE = 32,
G_APPLICATION_CAN_OVERRIDE_APP_ID = 64,
G_APPLICATION_ALLOW_REPLACEMENT = 128,
G_APPLICATION_REPLACE = 256
} GApplicationFlags;
typedef enum {
G_CONNECT_DEFAULT = 0,
G_CONNECT_AFTER = 1,
G_CONNECT_SWAPPED = 2
} GConnectFlags;
#endif
DECL(GtkApplication *, gtk_application_new, (const char *name, GApplicationFlags flags))
DECL(int, g_application_run, (GApplication* application, int argc, char** argv))
DECL(GtkWidget*, gtk_application_window_new, ( GtkApplication* application ))
DECL(GtkWidget *, gtk_window_new, (GtkWindowType))
DECL(void, gtk_window_close, (GtkWindow *))
DECL(void, gtk_widget_show_all, (GtkWindow *window))
DECL(void, gtk_window_get_size, (GtkWindow *win, int *width, int *height))
DECL(void, gtk_window_resize, (GtkWindow* window, gint width, gint height))
DECL(void, gtk_window_set_default_size, (GtkWindow *window, gint width, gint height))
DECL(void, gtk_window_get_position, (GtkWindow* window, gint* root_x, gint* root_y))
DECL(void, gtk_window_move, (GtkWindow* window, gint x, gint y))
DECL(gboolean, gtk_window_get_decorated, (GtkWindow* window))
DECL(void, gtk_window_set_title, (GtkWindow* window, const gchar* title))
DECL(const gchar*, gtk_window_get_title, (GtkWindow* window))
DECL(void, gtk_main, (void))
DECL(void, gtk_main_quit, (void))
DECL(unsigned long, g_signal_connect_data, (GObject *obj, const char *signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags))
DECL(void, g_object_unref, (GObject* object))
#define g_signal_connect(instance, signal, c_handler, data) \
g_signal_connect_data(instance, signal, reinterpret_cast<void *>(c_handler), data, NULL, G_CONNECT_DEFAULT)
#endif // GTK_IMPORTS_H

111
gtkloader.cpp Normal file
View File

@@ -0,0 +1,111 @@
#include "gtkloader.h"
extern "C" {
#include "gtk-imports.h"
}
#include <string>
#ifdef _WIN32
#include <windows.h>
#include <direct.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::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::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",
NULL
};
int i;
for(i = 0; libs[i] != NULL; i++) {
void *lib;
loadLibraryWin64(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
}
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()
{
}

26
gtkloader.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef GTKLOADER_H
#define GTKLOADER_H
#include <list>
class GtkLoader
{
private:
std::list<void *> library_handles;
private:
void loadLibraryWin64(const char *lib, void **handle);
void loadFunctionWin64(const char *func, void **func_ptr);
public:
void dlopen();
void loadFunction(const char *func, void **func_ptr);
public:
void loadGtk();
public:
GtkLoader();
};
#endif // GTKLOADER_H

38
main.cpp Normal file
View File

@@ -0,0 +1,38 @@
#include <iostream>
#include "gtkloader.h"
extern "C" {
#include "gtk-imports.h"
}
static void activate (GtkApplication* app, gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (window, "Window");
gtk_window_set_default_size (window, 200, 200);
gtk_widget_show_all (window);
}
int main(int argc, char **argv)
{
GtkLoader l;
try {
l.loadGtk();
} catch(std::string msg) {
std::cerr << msg << std::endl;
}
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", activate, NULL);
status = g_application_run (app, argc, argv);
g_object_unref (app);
return status;
}