Compare commits
17 Commits
a0ac0420da
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| b52d247977 | |||
| 1a33db1bf5 | |||
| 4c6f260bb9 | |||
| b91d093b1f | |||
| c968774e62 | |||
| 441e903c67 | |||
| 28f0fdb520 | |||
| 5023b63a7e | |||
| bf62ec97dc | |||
| f2e3242d82 | |||
| e82038e7cf | |||
| 4c10bb6b9f | |||
| c62a9c7610 | |||
| aaeb793703 | |||
| 9befee44a5 | |||
| 6cfa0d5a2d | |||
| 80ee3fcadf |
@@ -5,12 +5,23 @@ project(yellownotes LANGUAGES CXX C)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(yellownotes main.cpp
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
enable_language("RC")
|
||||
set (WIN32_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/app.rc)
|
||||
endif()
|
||||
|
||||
add_executable(yellownotes WIN32 main.cpp
|
||||
gtk-imports.h
|
||||
gtkloader.h gtkloader.cpp
|
||||
gtk-imports.c
|
||||
yellownotes.h yellownotes.cpp
|
||||
tr.h tr.cpp)
|
||||
tr.h tr.cpp
|
||||
|
||||
utils/whereami.c utils/whereami.h
|
||||
info_over_me.h info_over_me.cpp
|
||||
${WIN32_RESOURCES}
|
||||
)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS yellownotes
|
||||
|
||||
21
Makefile
Normal file
21
Makefile
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
all: release
|
||||
@echo make install
|
||||
|
||||
install: release
|
||||
mkdir -p /opt/yellownotes
|
||||
cp build/release/yellownotes /opt/yellownotes
|
||||
mkdir -p /opt/yellownotes/images
|
||||
cp *.svg *.png /opt/yellownotes/images
|
||||
|
||||
release: build/release/yellownotes
|
||||
|
||||
build/release/yellownotes: info_over_me.cpp gtk-imports.c gtkloader.cpp main.cpp tr.cpp yellownotes.cpp utils/whereami.c \
|
||||
info_over_me.h gtk-imports.h gtkloader.h tr.h yellownotes.h utils/whereami.h
|
||||
cmake -S . -B build/release
|
||||
cmake --build build/release --target all
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf build/release
|
||||
@@ -1,4 +1,8 @@
|
||||
#ifdef TARGET_OS_OSX
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#define GTK_DECLARE_FUNCS
|
||||
#include "gtk-imports.h"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef GTK_IMPORTS_H
|
||||
#define GTK_IMPORTS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/*************************************************************************************
|
||||
* boiler plate code to initialize Gtk functions etc.
|
||||
*************************************************************************************/
|
||||
@@ -68,13 +70,20 @@ typedef void GtkDialog;
|
||||
typedef void GTimer;
|
||||
typedef void GtkComboBoxText;
|
||||
typedef void GtkComboBox;
|
||||
typedef void GtkGrid;
|
||||
typedef void GtkColorButton;
|
||||
typedef void GtkColorChooser;
|
||||
typedef void GtkSpinButton;
|
||||
typedef void GdkMonitor;
|
||||
typedef void GdkScreen;
|
||||
typedef void GtkAboutDialog;
|
||||
|
||||
typedef int gboolean;
|
||||
typedef int gint;
|
||||
typedef char gchar;
|
||||
typedef long glong;
|
||||
typedef unsigned long gulong;
|
||||
typedef unsigned long guint32;
|
||||
typedef unsigned int guint32;
|
||||
typedef unsigned int guint;
|
||||
typedef long long gint64;
|
||||
typedef unsigned long long guint64;
|
||||
@@ -136,14 +145,14 @@ typedef enum {
|
||||
PANGO_ELLIPSIZE_END = 3
|
||||
} PangoEllipsizeMode;
|
||||
|
||||
struct GdkRectangle {
|
||||
typedef struct _GdkRectangle {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
} GdkRectangle;
|
||||
|
||||
typedef struct GdkRectangle GtkAllocation;
|
||||
typedef struct _GdkRectangle GtkAllocation;
|
||||
|
||||
#define G_VALUE_INIT { 0, { { 0 } } }
|
||||
|
||||
@@ -274,7 +283,7 @@ typedef struct _GdkEventMotion
|
||||
gint16 is_hint;
|
||||
GdkDevice *device;
|
||||
gdouble x_root, y_root;
|
||||
} GdkEventMotion;
|
||||
} GdkEventMotion;;
|
||||
|
||||
typedef struct _GdkEventKey
|
||||
{
|
||||
@@ -564,6 +573,42 @@ typedef struct _GdkEventVisibility
|
||||
GdkVisibilityState state;
|
||||
} GdkEventVisibility;
|
||||
|
||||
typedef struct _GList {
|
||||
gpointer data;
|
||||
gpointer next;
|
||||
gpointer prev;
|
||||
} GList;
|
||||
|
||||
typedef void GListModel;
|
||||
|
||||
typedef enum {
|
||||
GTK_LICENSE_UNKNOWN,
|
||||
GTK_LICENSE_CUSTOM,
|
||||
|
||||
GTK_LICENSE_GPL_2_0,
|
||||
GTK_LICENSE_GPL_3_0,
|
||||
|
||||
GTK_LICENSE_LGPL_2_1,
|
||||
GTK_LICENSE_LGPL_3_0,
|
||||
|
||||
GTK_LICENSE_BSD,
|
||||
GTK_LICENSE_MIT_X11,
|
||||
|
||||
GTK_LICENSE_ARTISTIC,
|
||||
|
||||
GTK_LICENSE_GPL_2_0_ONLY,
|
||||
GTK_LICENSE_GPL_3_0_ONLY,
|
||||
GTK_LICENSE_LGPL_2_1_ONLY,
|
||||
GTK_LICENSE_LGPL_3_0_ONLY,
|
||||
|
||||
GTK_LICENSE_AGPL_3_0,
|
||||
GTK_LICENSE_AGPL_3_0_ONLY,
|
||||
|
||||
GTK_LICENSE_BSD_3,
|
||||
GTK_LICENSE_APACHE_2_0,
|
||||
GTK_LICENSE_MPL_2_0
|
||||
} GtkLicense;
|
||||
|
||||
#define G_TYPE_FUNDAMENTAL_SHIFT (2)
|
||||
#define G_TYPE_MAKE_FUNDAMENTAL(x) ((GType) ((x) << G_TYPE_FUNDAMENTAL_SHIFT))
|
||||
#define G_TYPE_INT G_TYPE_MAKE_FUNDAMENTAL (6)
|
||||
@@ -629,6 +674,7 @@ DECL(const gchar*, gtk_window_get_title, (GtkWindow* window))
|
||||
DECL(void, gtk_widget_destroy, (GtkWidget* widget))
|
||||
DECL(void, gtk_container_add, (GtkContainer* container, GtkWidget* widget))
|
||||
DECL(void, gtk_container_remove, (GtkContainer* container, GtkWidget* widget))
|
||||
DECL(void, gtk_container_set_border_width, (GtkContainer *container, guint width));
|
||||
|
||||
DECL(gboolean, gtk_widget_is_visible, (GtkWidget* widget))
|
||||
DECL(GtkWidget*, gtk_label_new, (const char* str))
|
||||
@@ -649,11 +695,24 @@ DECL(void, gtk_widget_set_vexpand, (GtkWidget* widget, gboolean expand ))
|
||||
DECL(void, gtk_widget_set_hexpand, (GtkWidget* widget, gboolean expand ))
|
||||
DECL(void, gtk_widget_set_halign, (GtkWidget* widget, GtkAlign align ))
|
||||
DECL(void, gtk_widget_set_valign, (GtkWidget* widget, GtkAlign align ))
|
||||
DECL(GtkWidget*,gtk_grid_new, (void))
|
||||
DECL(void, gtk_grid_attach, (GtkGrid* grid, GtkWidget* child, gint left, gint top, gint width, gint height ))
|
||||
|
||||
DECL(GtkWidget*, gtk_color_button_new, (void ))
|
||||
DECL(void, gtk_color_chooser_set_rgba, (GtkColorChooser* chooser, const GdkRGBA* color ))
|
||||
DECL(void, gtk_color_chooser_get_rgba, (GtkColorChooser* chooser, GdkRGBA* color ))
|
||||
|
||||
DECL(gboolean, gtk_widget_translate_coordinates, ( GtkWidget* src_widget, GtkWidget* dest_widget, gint src_x, gint src_y, gint* dest_x, gint* dest_y))
|
||||
|
||||
DECL(void, gtk_main, (void))
|
||||
DECL(void, gtk_main_quit, (void))
|
||||
DECL(GdkEvent*, gtk_get_current_event, (void ))
|
||||
DECL(void, gtk_main_do_event, (GdkEvent* event))
|
||||
DECL(void, gdk_event_free, (GdkEvent* event))
|
||||
|
||||
DECL(GtkWidget*, gtk_spin_button_new_with_range, (gdouble min, gdouble max, gdouble step))
|
||||
DECL(void, gtk_spin_button_set_value, (GtkSpinButton* spin_button, gdouble value ))
|
||||
DECL(gint, gtk_spin_button_get_value_as_int, (GtkSpinButton* spin_button ))
|
||||
|
||||
DECL(unsigned long, g_signal_connect_data, (GObject *obj, const char *signal, GCallback c_handler, gpointer data, GClosureNotify destroy_data, GConnectFlags connect_flags))
|
||||
|
||||
@@ -674,6 +733,25 @@ DECL(GtkWidget*, gtk_dialog_get_content_area, (GtkDialog* dialog ))
|
||||
DECL(gboolean, gtk_combo_box_set_active_id, ( GtkComboBox* combo_box, const gchar* active_id ))
|
||||
DECL(const gchar*, gtk_combo_box_get_active_id, (GtkComboBox* combo_box))
|
||||
|
||||
// Gdk Monitor/Screen
|
||||
|
||||
DECL(GdkDisplay*, gdk_display_get_default, (void))
|
||||
DECL(int, gdk_display_get_n_monitors, (GdkDisplay* display))
|
||||
DECL(GdkMonitor*, gdk_display_get_monitor, (GdkDisplay* display, int monitor_num))
|
||||
DECL(void, gdk_monitor_get_geometry, (GdkMonitor* monitor, GdkRectangle* geometry))
|
||||
DECL(GList*, gdk_screen_get_window_stack, (GdkScreen* screen))
|
||||
DECL(GdkScreen*, gdk_screen_get_default, (void))
|
||||
|
||||
// About
|
||||
|
||||
DECL(GtkWidget*, gtk_about_dialog_new, (void))
|
||||
DECL(void, gtk_about_dialog_set_authors, (GtkAboutDialog* about,const gchar** authors))
|
||||
DECL(void, gtk_about_dialog_set_copyright, (GtkAboutDialog* about, const gchar* copyright ))
|
||||
DECL(void, gtk_about_dialog_set_license_type, (GtkAboutDialog* about, GtkLicense license_type))
|
||||
DECL(void, gtk_about_dialog_set_logo, (GtkAboutDialog* about, GdkPixbuf* logo ))
|
||||
DECL(void, gtk_about_dialog_set_program_name, (GtkAboutDialog* about,const gchar* name))
|
||||
DECL(void, gtk_about_dialog_set_version, (GtkAboutDialog* about, const gchar* version))
|
||||
|
||||
// GObject / GValue
|
||||
DECL(void, g_object_unref, (GObject* object))
|
||||
DECL(void, g_object_ref, (GObject* object))
|
||||
|
||||
@@ -11,22 +11,31 @@ extern "C" {
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux
|
||||
#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
|
||||
#define DIR "C:\\devel\\yellownotes\\gtk3\\bin"
|
||||
InfoOverMe info;
|
||||
|
||||
//#define DIR "C:\\devel\\yellownotes\\gtk3\\bin"
|
||||
HMODULE dll = nullptr;
|
||||
std::string dir = DIR;
|
||||
std::string my_dir = info.containingFolder();
|
||||
std::string dir = my_dir + "\\gtk3";
|
||||
|
||||
std::cout << "my folder = " << dir << std::endl;
|
||||
|
||||
*handle = nullptr;
|
||||
|
||||
auto mklibname = [](const char *libname) {
|
||||
auto mklibname = [dir](const char *libname) {
|
||||
std::string dll;
|
||||
dll = std::string(DIR) + "\\" + libname + ".dll";
|
||||
dll = std::string(libname) + ".dll";
|
||||
std::cout << "library: " << dll << std::endl;
|
||||
return dll;
|
||||
};
|
||||
|
||||
@@ -60,6 +69,33 @@ void GtkLoader::loadLibraryLinux(const char *lib, void **handle)
|
||||
#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
|
||||
@@ -123,6 +159,7 @@ void GtkLoader::dlopen()
|
||||
"libgio-2.0.so",
|
||||
"libglib-2.0.so",
|
||||
"libgdk-3.so",
|
||||
"libgdk_pixbuf-2.0.so",
|
||||
NULL
|
||||
};
|
||||
int i;
|
||||
@@ -131,6 +168,23 @@ void GtkLoader::dlopen()
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -143,6 +197,9 @@ void GtkLoader::loadFunction(const char *func, void **func_ptr)
|
||||
#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)
|
||||
|
||||
@@ -13,6 +13,8 @@ private:
|
||||
void loadFunctionWin64(const char *func, void **func_ptr);
|
||||
void loadLibraryLinux(const char *lib, void **handle);
|
||||
void loadFunctionLinux(const char *func, void **func_ptr);
|
||||
void loadLibraryOSX(const char *lib, void **handle);
|
||||
void loadFunctionOSX(const char *func, void **func_ptr);
|
||||
|
||||
public:
|
||||
void dlopen();
|
||||
|
||||
119
info_over_me.cpp
Normal file
119
info_over_me.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include "info_over_me.h"
|
||||
|
||||
#include "utils/whereami.h"
|
||||
|
||||
#include <iostream>
|
||||
#if defined(__linux) || defined(TARGET_OS_OSX)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "gtk-imports.h"
|
||||
}
|
||||
|
||||
#include <list>
|
||||
#include <filesystem>
|
||||
|
||||
std::string InfoOverMe::containingFolder()
|
||||
{
|
||||
int len = wai_getExecutablePath(NULL, 0, NULL);
|
||||
|
||||
char *path = static_cast<char *>(malloc(len + 1));
|
||||
wai_getExecutablePath(path, len, NULL);
|
||||
path[len] = '\0';
|
||||
|
||||
std::filesystem::path p(path);
|
||||
if (std::filesystem::is_regular_file(p)) {
|
||||
std::filesystem::path pp = p.parent_path();
|
||||
return pp.string();
|
||||
} else {
|
||||
return p.string();
|
||||
}
|
||||
}
|
||||
|
||||
std::string InfoOverMe::myHostname()
|
||||
{
|
||||
char buf[10240];
|
||||
#if defined(__linux) || defined(TARGET_OS_OSX)
|
||||
int r = gethostname(buf, 10240);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
DWORD size = 10240;
|
||||
bool r = GetComputerNameA(buf, &size);
|
||||
buf[size] = '\0';
|
||||
if (!r) { sprintf(buf, "unknown"); }
|
||||
#endif
|
||||
std::string name(buf);
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string InfoOverMe::myOsHostname()
|
||||
{
|
||||
std::string os;
|
||||
#ifdef __linux
|
||||
os = "linux";
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
os = "windows";
|
||||
#else
|
||||
#ifdef TARGET_OS_OSX
|
||||
os = "osx";
|
||||
#else
|
||||
os = "unknown";
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return os + "_" + myHostname();
|
||||
}
|
||||
|
||||
std::string InfoOverMe::myId()
|
||||
{
|
||||
|
||||
std::list<GdkRectangle> l;
|
||||
GdkDisplay *d = gdk_display_get_default();
|
||||
int n = gdk_display_get_n_monitors(d);
|
||||
int i;
|
||||
for(i = 0; i < n; i++) {
|
||||
GdkMonitor *m = gdk_display_get_monitor(d, i);
|
||||
GdkRectangle r;
|
||||
gdk_monitor_get_geometry(m, &r);
|
||||
l.push_back(r);
|
||||
//std::cout << r.width << ", " << r.height << ", x = " << r.x << ", y = " << r.y << std::endl;
|
||||
}
|
||||
|
||||
auto compare = [](const GdkRectangle &a, const GdkRectangle &b) {
|
||||
if (a.x < b.x) {
|
||||
return true;
|
||||
} else if (a.x > b. x) {
|
||||
return false;
|
||||
} else if (a.y < b.y) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
l.sort(compare);
|
||||
std::list<GdkRectangle>::iterator it;
|
||||
std::string monitor_id;
|
||||
std::string sep = "";
|
||||
for(it = l.begin(); it != l.end(); it++) {
|
||||
char buf[200];
|
||||
const GdkRectangle &r = *it;
|
||||
sprintf(buf, "%d-%d-%d-%d", r.x, r.y, r.width, r.height);
|
||||
std::string geom(buf);
|
||||
monitor_id += sep;
|
||||
monitor_id += geom;
|
||||
sep = "-";
|
||||
}
|
||||
|
||||
monitor_id = myOsHostname() + "/" + monitor_id;
|
||||
|
||||
return monitor_id;
|
||||
}
|
||||
|
||||
InfoOverMe::InfoOverMe() {}
|
||||
20
info_over_me.h
Normal file
20
info_over_me.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef INFO_OVER_ME_H
|
||||
#define INFO_OVER_ME_H
|
||||
|
||||
#include <string>
|
||||
|
||||
class InfoOverMe
|
||||
{
|
||||
public:
|
||||
std::string containingFolder();
|
||||
|
||||
public:
|
||||
std::string myHostname();
|
||||
std::string myOsHostname();
|
||||
std::string myId();
|
||||
|
||||
public:
|
||||
InfoOverMe();
|
||||
};
|
||||
|
||||
#endif // INFO_OVER_ME_H
|
||||
29
main.cpp
29
main.cpp
@@ -6,9 +6,13 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "yellownotes.h"
|
||||
#include "info_over_me.h"
|
||||
|
||||
SIGNAL(YellowNotes, on_tray_activate, popupTrayMenu)
|
||||
|
||||
#ifndef TARGET_OS_OSX
|
||||
SIGNAL(YellowNotes, on_tray_activate, popupTrayMenu);
|
||||
#else
|
||||
BSIGNAL2(YellowNotes, on_tray_btn, popupTrayMenuBtn, GdkEventButton);
|
||||
#endif
|
||||
static void activate (GtkApplication* app, gpointer user_data)
|
||||
{
|
||||
GtkWidget *window;
|
||||
@@ -16,12 +20,32 @@ static void activate (GtkApplication* app, gpointer user_data)
|
||||
|
||||
std::string img_file = notes->imageFile("yellownotes");
|
||||
GtkStatusIcon *tray = gtk_status_icon_new_from_file(img_file.c_str());
|
||||
#ifdef TARGET_OS_OSX
|
||||
g_signal_connect(tray, "button_press_event", on_tray_btn, notes);
|
||||
#else
|
||||
g_signal_connect(tray, "activate", on_tray_activate, notes);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int runMain(int argc, char **argv);
|
||||
|
||||
#ifdef _WIN32
|
||||
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
return runMain(__argc, __argv);
|
||||
}
|
||||
#else
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
return runMain(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
||||
int runMain(int argc, char **argv)
|
||||
{
|
||||
|
||||
GtkLoader l;
|
||||
InfoOverMe w;
|
||||
|
||||
srand(time(NULL)); // seed with current time
|
||||
|
||||
@@ -29,6 +53,7 @@ int main(int argc, char **argv)
|
||||
l.loadGtk();
|
||||
} catch(std::string msg) {
|
||||
std::cerr << msg << std::endl;
|
||||
exit(2);
|
||||
}
|
||||
|
||||
GtkApplication *app;
|
||||
|
||||
BIN
title_only.png
Normal file
BIN
title_only.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
2
title_only.svg
Normal file
2
title_only.svg
Normal file
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 3H4c-1.103 0-2 .897-2 2v14c0 1.103.897 2 2 2h16c1.103 0 2-.897 2-2V5c0-1.103-.897-2-2-2zm0 2 .001 4H4V5h16zM4 19v-8h16.001l.001 8H4z"/><path d="M14 6h2v2h-2zm3 0h2v2h-2z"/></svg>
|
||||
|
After Width: | Height: | Size: 414 B |
BIN
to_desktop.png
Normal file
BIN
to_desktop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
4
to_desktop.svg
Normal file
4
to_desktop.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M18.3137 0.918778C18.6347 1.36819 18.5307 1.99274 18.0812 2.31375L16.4248 3.49692L17.2572 3.67529C20.0236 4.26809 22 6.71287 22 9.5421V10C22 10.5523 21.5523 11 21 11C20.4477 11 20 10.5523 20 10V9.5421C20 7.65595 18.6824 6.02609 16.8381 5.63089L15.9784 5.44667L16.8682 7.00388C17.1423 7.48339 16.9757 8.09425 16.4961 8.36826C16.0166 8.64227 15.4058 8.47567 15.1318 7.99616L13.1318 4.49616C12.8771 4.05058 13.0012 3.48458 13.4188 3.18629L16.9188 0.686284C17.3682 0.365274 17.9927 0.469365 18.3137 0.918778ZM6 12C6 10.8954 6.89543 10 8 10H16C17.1046 10 18 10.8954 18 12V20C18 21.1046 17.1046 22 16 22H8C6.89543 22 6 21.1046 6 20V12ZM16 20V12H8V20H16ZM4 6.00002C2.89543 6.00002 2 6.89545 2 8.00002V16C2 16.5523 2.44772 17 3 17C3.55228 17 4 16.5523 4 16V8.00002H12C12.5523 8.00002 13 7.5523 13 7.00002C13 6.44773 12.5523 6.00002 12 6.00002H4Z" fill="#000000"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
44
tr.cpp
44
tr.cpp
@@ -1,5 +1,6 @@
|
||||
#include "tr.h"
|
||||
#include <stdarg.h>
|
||||
#include <iostream>
|
||||
|
||||
void tr::add(const char *sentence, ...)
|
||||
{
|
||||
@@ -39,9 +40,12 @@ const char *tr::translate(const char *str)
|
||||
{
|
||||
std::unordered_map<std::string, Translations_t *>::iterator it;
|
||||
|
||||
if (_lang == "en") { return str; }
|
||||
|
||||
it = _translations.find(_lang);
|
||||
|
||||
if (it == _translations.end()) {
|
||||
std::cerr << "No translation for: " << str << std::endl;
|
||||
return str;
|
||||
} else {
|
||||
Translations_t *m = it->second;
|
||||
@@ -49,6 +53,7 @@ const char *tr::translate(const char *str)
|
||||
std::string s(str);
|
||||
n_it = m->find(s);
|
||||
if (n_it == m->end()) {
|
||||
std::cerr << "No translation for: " << str << std::endl;
|
||||
return str;
|
||||
} else {
|
||||
return n_it->second.c_str();
|
||||
@@ -61,14 +66,41 @@ void tr::setLang(const std::string &l)
|
||||
_lang = l;
|
||||
}
|
||||
|
||||
#define nl(a, b) add(a, "nl:" b, nullptr)
|
||||
#define en(a, b) add(a, "en:" b, nullptr)
|
||||
|
||||
tr::tr()
|
||||
{
|
||||
add("Quit", "nl:Beëindigen", nullptr);
|
||||
add("New Note", "nl:Nieuwe Notitie", nullptr);
|
||||
add("Show Notes", "nl:Notities Presenteren", nullptr);
|
||||
add("Hide Notes", "nl:Notities Verbergen", nullptr);
|
||||
add("Reload Notes", "nl:Notities opnieuw laden", nullptr);
|
||||
add("Setup", "nl:Instellingen", nullptr);
|
||||
|
||||
nl("Quit", "Beëindigen");
|
||||
nl("New Note", "Nieuwe Notitie");
|
||||
nl("Show Notes", "Notities Presenteren");
|
||||
nl("Hide Notes", "Notities Verbergen");
|
||||
nl("Reload Notes", "Notities opnieuw laden");
|
||||
nl("Setup", "Instellingen");
|
||||
nl("Notes on desktop", "Noties naar achteren");
|
||||
nl("Language:", "Taalinstelling:");
|
||||
nl("Language:", "Taalinstelling:");
|
||||
nl("Ok", "Ok");
|
||||
nl("Yellownotes Setup", "Yellownotes Instellingen");
|
||||
nl("Foreground Color", "Voorgrond kleur");
|
||||
nl("Background Color", "Achtergrond kleur");
|
||||
nl("Dark", "Donker");
|
||||
nl("Yellow", "Geel");
|
||||
nl("Orange", "Oranje");
|
||||
nl("Blue", "Blauw");
|
||||
nl("Cyan", "Cyaan");
|
||||
nl("Green", "Groen");
|
||||
nl("Red", "Rood");
|
||||
nl("Grey", "Grijs");
|
||||
nl("Font size:", "Lettertype Grootte:");
|
||||
nl("Actual Font Size in Note", "Werkelijke lettertype grootte in de notitie");
|
||||
nl("Reorder Notes", "Notities opnieuw ordenen");
|
||||
nl("About", "Over...");
|
||||
nl("(c) 2025", "(c) 2025");
|
||||
nl("Version %s, file format version: %d", "Versie %s, bestandsformaat versie: %d");
|
||||
nl("Yellow Notes", "Geeltjes");
|
||||
|
||||
_lang = "en";
|
||||
}
|
||||
|
||||
|
||||
815
utils/whereami.c
Normal file
815
utils/whereami.c
Normal file
@@ -0,0 +1,815 @@
|
||||
// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses
|
||||
// without any warranty.
|
||||
// by Gregory Pakosz (@gpakosz)
|
||||
// https://github.com/gpakosz/whereami
|
||||
|
||||
// in case you want to #include "whereami.c" in a larger compilation unit
|
||||
#if !defined(WHEREAMI_H)
|
||||
#include "whereami.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__CYGWIN__)
|
||||
#undef _DEFAULT_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
#elif defined(__APPLE__)
|
||||
#undef _DARWIN_C_SOURCE
|
||||
#define _DARWIN_C_SOURCE
|
||||
#define _DARWIN_BETTER_REALPATH
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_MALLOC) || !defined(WAI_FREE) || !defined(WAI_REALLOC)
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_MALLOC)
|
||||
#define WAI_MALLOC(size) malloc(size)
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_FREE)
|
||||
#define WAI_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_REALLOC)
|
||||
#define WAI_REALLOC(p, size) realloc(p, size)
|
||||
#endif
|
||||
|
||||
#ifndef WAI_NOINLINE
|
||||
#if defined(_MSC_VER)
|
||||
#define WAI_NOINLINE __declspec(noinline)
|
||||
#elif defined(__GNUC__)
|
||||
#define WAI_NOINLINE __attribute__((noinline))
|
||||
#else
|
||||
#error unsupported compiler
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define WAI_RETURN_ADDRESS() _ReturnAddress()
|
||||
#elif defined(__GNUC__)
|
||||
#define WAI_RETURN_ADDRESS() __builtin_extract_return_addr(__builtin_return_address(0))
|
||||
#else
|
||||
#error unsupported compiler
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#if (_MSC_VER >= 1900)
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#define bool int
|
||||
#define false 0
|
||||
#define true 1
|
||||
#endif
|
||||
|
||||
static int WAI_PREFIX(getModulePath_)(HMODULE module, char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
wchar_t buffer1[MAX_PATH];
|
||||
wchar_t buffer2[MAX_PATH];
|
||||
wchar_t* path = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
DWORD size;
|
||||
int length_, length__;
|
||||
|
||||
size = GetModuleFileNameW(module, buffer1, sizeof(buffer1) / sizeof(buffer1[0]));
|
||||
|
||||
if (size == 0)
|
||||
break;
|
||||
else if (size == (DWORD)(sizeof(buffer1) / sizeof(buffer1[0])))
|
||||
{
|
||||
DWORD size_ = size;
|
||||
do
|
||||
{
|
||||
wchar_t* path_;
|
||||
|
||||
path_ = (wchar_t*)WAI_REALLOC(path, sizeof(wchar_t) * size_ * 2);
|
||||
if (!path_)
|
||||
break;
|
||||
size_ *= 2;
|
||||
path = path_;
|
||||
size = GetModuleFileNameW(module, path, size_);
|
||||
}
|
||||
while (size == size_);
|
||||
|
||||
if (size == size_)
|
||||
break;
|
||||
}
|
||||
else
|
||||
path = buffer1;
|
||||
|
||||
if (!_wfullpath(buffer2, path, MAX_PATH))
|
||||
break;
|
||||
length_ = (int)wcslen(buffer2);
|
||||
length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_ , out, capacity, NULL, NULL);
|
||||
|
||||
if (length__ == 0)
|
||||
length__ = WideCharToMultiByte(CP_UTF8, 0, buffer2, length_, NULL, 0, NULL, NULL);
|
||||
if (length__ == 0)
|
||||
break;
|
||||
|
||||
if (length__ <= capacity && dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length__ - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '\\')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = length__;
|
||||
}
|
||||
|
||||
if (path != buffer1)
|
||||
WAI_FREE(path);
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
WAI_NOINLINE WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
return WAI_PREFIX(getModulePath_)(NULL, out, capacity, dirname_length);
|
||||
}
|
||||
|
||||
WAI_NOINLINE WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
HMODULE module;
|
||||
int length = -1;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4054)
|
||||
#endif
|
||||
if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)WAI_RETURN_ADDRESS(), &module))
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
{
|
||||
length = WAI_PREFIX(getModulePath_)(module, out, capacity, dirname_length);
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#elif defined(__linux__) || defined(__CYGWIN__) || defined(__sun) || defined(WAI_USE_PROC_SELF_EXE)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if defined(__linux__)
|
||||
#include <linux/limits.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(WAI_PROC_SELF_EXE)
|
||||
#if defined(__sun)
|
||||
#define WAI_PROC_SELF_EXE "/proc/self/path/a.out"
|
||||
#else
|
||||
#define WAI_PROC_SELF_EXE "/proc/self/exe"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
resolved = realpath(WAI_PROC_SELF_EXE, buffer);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
#if !defined(WAI_PROC_SELF_MAPS_RETRY)
|
||||
#define WAI_PROC_SELF_MAPS_RETRY 5
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_PROC_SELF_MAPS)
|
||||
#if defined(__sun)
|
||||
#define WAI_PROC_SELF_MAPS "/proc/self/map"
|
||||
#else
|
||||
#define WAI_PROC_SELF_MAPS "/proc/self/maps"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(WAI_STRINGIZE)
|
||||
#define WAI_STRINGIZE(s)
|
||||
#define WAI_STRINGIZE_(s) #s
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__) || defined(ANDROID)
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
WAI_NOINLINE WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
int length = -1;
|
||||
FILE* maps = NULL;
|
||||
|
||||
for (int r = 0; r < WAI_PROC_SELF_MAPS_RETRY; ++r)
|
||||
{
|
||||
maps = fopen(WAI_PROC_SELF_MAPS, "r");
|
||||
if (!maps)
|
||||
break;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
char buffer[128 + PATH_MAX];
|
||||
uintptr_t low, high;
|
||||
char perms[5];
|
||||
uint64_t offset;
|
||||
uint32_t major, minor, inode;
|
||||
char path[PATH_MAX + 1];
|
||||
|
||||
if (!fgets(buffer, sizeof(buffer), maps))
|
||||
break;
|
||||
|
||||
if (sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR " %s %" SCNx64 " %x:%x %u %" WAI_STRINGIZE(PATH_MAX) "[^\n]\n", &low, &high, perms, &offset, &major, &minor, &inode, path) == 8)
|
||||
{
|
||||
void* _addr = WAI_RETURN_ADDRESS();
|
||||
uintptr_t addr = (uintptr_t)_addr;
|
||||
if (low <= addr && addr <= high)
|
||||
{
|
||||
char* resolved;
|
||||
|
||||
resolved = realpath(path, buffer);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
#if defined(__ANDROID__) || defined(ANDROID)
|
||||
if (length > 4
|
||||
&&buffer[length - 1] == 'k'
|
||||
&&buffer[length - 2] == 'p'
|
||||
&&buffer[length - 3] == 'a'
|
||||
&&buffer[length - 4] == '.')
|
||||
{
|
||||
int fd = open(path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
length = -1; // retry
|
||||
break;
|
||||
}
|
||||
|
||||
char* begin = (char*)mmap(0, offset, PROT_READ, MAP_SHARED, fd, 0);
|
||||
if (begin == MAP_FAILED)
|
||||
{
|
||||
close(fd);
|
||||
length = -1; // retry
|
||||
break;
|
||||
}
|
||||
|
||||
char* p = begin + offset - 30; // minimum size of local file header
|
||||
while (p >= begin) // scan backwards
|
||||
{
|
||||
if (*((uint32_t*)p) == 0x04034b50UL) // local file header signature found
|
||||
{
|
||||
uint16_t length_ = *((uint16_t*)(p + 26));
|
||||
|
||||
if (length + 2 + length_ < (int)sizeof(buffer))
|
||||
{
|
||||
memcpy(&buffer[length], "!/", 2);
|
||||
memcpy(&buffer[length + 2], p + 30, length_);
|
||||
length += 2 + length_;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
--p;
|
||||
}
|
||||
|
||||
munmap(begin, offset);
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(maps);
|
||||
maps = NULL;
|
||||
|
||||
if (length != -1)
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer1[PATH_MAX];
|
||||
char buffer2[PATH_MAX];
|
||||
char* path = buffer1;
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
uint32_t size = (uint32_t)sizeof(buffer1);
|
||||
if (_NSGetExecutablePath(path, &size) == -1)
|
||||
{
|
||||
path = (char*)WAI_MALLOC(size);
|
||||
if (!_NSGetExecutablePath(path, &size))
|
||||
break;
|
||||
}
|
||||
|
||||
resolved = realpath(path, buffer2);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path != buffer1)
|
||||
WAI_FREE(path);
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
WAI_NOINLINE WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Dl_info info;
|
||||
|
||||
if (dladdr(WAI_RETURN_ADDRESS(), &info))
|
||||
{
|
||||
resolved = realpath(info.dli_fname, buffer);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#elif defined(__QNXNTO__)
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(WAI_PROC_SELF_EXE)
|
||||
#define WAI_PROC_SELF_EXE "/proc/self/exefile"
|
||||
#endif
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer1[PATH_MAX];
|
||||
char buffer2[PATH_MAX];
|
||||
char* resolved = NULL;
|
||||
FILE* self_exe = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
self_exe = fopen(WAI_PROC_SELF_EXE, "r");
|
||||
if (!self_exe)
|
||||
break;
|
||||
|
||||
if (!fgets(buffer1, sizeof(buffer1), self_exe))
|
||||
break;
|
||||
|
||||
resolved = realpath(buffer1, buffer2);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(self_exe);
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Dl_info info;
|
||||
|
||||
if (dladdr(WAI_RETURN_ADDRESS(), &info))
|
||||
{
|
||||
resolved = realpath(info.dli_fname, buffer);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer1[4096];
|
||||
char buffer2[PATH_MAX];
|
||||
char buffer3[PATH_MAX];
|
||||
char** argv = (char**)buffer1;
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
int mib[4] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV };
|
||||
size_t size;
|
||||
|
||||
if (sysctl(mib, 4, NULL, &size, NULL, 0) != 0)
|
||||
break;
|
||||
|
||||
if (size > sizeof(buffer1))
|
||||
{
|
||||
argv = (char**)WAI_MALLOC(size);
|
||||
if (!argv)
|
||||
break;
|
||||
}
|
||||
|
||||
if (sysctl(mib, 4, argv, &size, NULL, 0) != 0)
|
||||
break;
|
||||
|
||||
if (strchr(argv[0], '/'))
|
||||
{
|
||||
resolved = realpath(argv[0], buffer2);
|
||||
if (!resolved)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* PATH = getenv("PATH");
|
||||
if (!PATH)
|
||||
break;
|
||||
|
||||
size_t argv0_length = strlen(argv[0]);
|
||||
|
||||
const char* begin = PATH;
|
||||
while (1)
|
||||
{
|
||||
const char* separator = strchr(begin, ':');
|
||||
const char* end = separator ? separator : begin + strlen(begin);
|
||||
|
||||
if (end - begin > 0)
|
||||
{
|
||||
if (*(end -1) == '/')
|
||||
--end;
|
||||
|
||||
if (((end - begin) + 1 + argv0_length + 1) <= sizeof(buffer2))
|
||||
{
|
||||
memcpy(buffer2, begin, end - begin);
|
||||
buffer2[end - begin] = '/';
|
||||
memcpy(buffer2 + (end - begin) + 1, argv[0], argv0_length + 1);
|
||||
|
||||
resolved = realpath(buffer2, buffer3);
|
||||
if (resolved)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!separator)
|
||||
break;
|
||||
|
||||
begin = ++separator;
|
||||
}
|
||||
|
||||
if (!resolved)
|
||||
break;
|
||||
}
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv != (char**)buffer1)
|
||||
WAI_FREE(argv);
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer1[PATH_MAX];
|
||||
char buffer2[PATH_MAX];
|
||||
char* path = buffer1;
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
bool ok;
|
||||
|
||||
for (ok = false; !ok; ok = true)
|
||||
{
|
||||
#if defined(__NetBSD__)
|
||||
int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME };
|
||||
#else
|
||||
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
|
||||
#endif
|
||||
size_t size = sizeof(buffer1);
|
||||
|
||||
if (sysctl(mib, 4, path, &size, NULL, 0) != 0)
|
||||
break;
|
||||
|
||||
resolved = realpath(path, buffer2);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ok ? length : -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
WAI_NOINLINE WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
|
||||
{
|
||||
char buffer[PATH_MAX];
|
||||
char* resolved = NULL;
|
||||
int length = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
Dl_info info;
|
||||
|
||||
if (dladdr(WAI_RETURN_ADDRESS(), &info))
|
||||
{
|
||||
resolved = realpath(info.dli_fname, buffer);
|
||||
if (!resolved)
|
||||
break;
|
||||
|
||||
length = (int)strlen(resolved);
|
||||
if (length <= capacity)
|
||||
{
|
||||
memcpy(out, resolved, length);
|
||||
|
||||
if (dirname_length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = length - 1; i >= 0; --i)
|
||||
{
|
||||
if (out[i] == '/')
|
||||
{
|
||||
*dirname_length = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error unsupported platform
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
69
utils/whereami.h
Normal file
69
utils/whereami.h
Normal file
@@ -0,0 +1,69 @@
|
||||
// (‑●‑●)> dual licensed under the WTFPL v2 and MIT licenses
|
||||
// without any warranty.
|
||||
// by Gregory Pakosz (@gpakosz)
|
||||
// https://github.com/gpakosz/whereami
|
||||
|
||||
#ifndef WHEREAMI_H
|
||||
#define WHEREAMI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef WAI_FUNCSPEC
|
||||
#define WAI_FUNCSPEC
|
||||
#endif
|
||||
#ifndef WAI_PREFIX
|
||||
#define WAI_PREFIX(function) wai_##function
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the path to the current executable.
|
||||
*
|
||||
* Usage:
|
||||
* - first call `int length = wai_getExecutablePath(NULL, 0, NULL);` to
|
||||
* retrieve the length of the path
|
||||
* - allocate the destination buffer with `path = (char*)malloc(length + 1);`
|
||||
* - call `wai_getExecutablePath(path, length, NULL)` again to retrieve the
|
||||
* path
|
||||
* - add a terminal NUL character with `path[length] = '\0';`
|
||||
*
|
||||
* @param out destination buffer, optional
|
||||
* @param capacity destination buffer capacity
|
||||
* @param dirname_length optional recipient for the length of the dirname part
|
||||
* of the path. Available only when `capacity` is large enough to retrieve the
|
||||
* path.
|
||||
*
|
||||
* @return the length of the executable path on success (without a terminal NUL
|
||||
* character), otherwise `-1`
|
||||
*/
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length);
|
||||
|
||||
/**
|
||||
* Returns the path to the current module
|
||||
*
|
||||
* Usage:
|
||||
* - first call `int length = wai_getModulePath(NULL, 0, NULL);` to retrieve
|
||||
* the length of the path
|
||||
* - allocate the destination buffer with `path = (char*)malloc(length + 1);`
|
||||
* - call `wai_getModulePath(path, length, NULL)` again to retrieve the path
|
||||
* - add a terminal NUL character with `path[length] = '\0';`
|
||||
*
|
||||
* @param out destination buffer, optional
|
||||
* @param capacity destination buffer capacity
|
||||
* @param dirname_length optional recipient for the length of the dirname part
|
||||
* of the path. Available only when `capacity` is large enough to retrieve the
|
||||
* path.
|
||||
*
|
||||
* @return the length of the module path on success (without a terminal NUL
|
||||
* character), otherwise `-1`
|
||||
*/
|
||||
WAI_FUNCSPEC
|
||||
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #ifndef WHEREAMI_H
|
||||
1019
yellownotes.cpp
1019
yellownotes.cpp
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,15 @@ extern "C" {
|
||||
}
|
||||
|
||||
class YellowNote;
|
||||
class SettingContainer;
|
||||
|
||||
#define YELLOWNOTE_MAJOR "1"
|
||||
#define YELLOWNOTE_MINOR "0"
|
||||
#define YELLOWNOTE_PATCH "3"
|
||||
#define YELLOWNOTE_VERSION YELLOWNOTE_MAJOR "." YELLOWNOTE_MINOR "." YELLOWNOTE_PATCH
|
||||
#define YELLOWNOTE_FILE_VERSION 3
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
DARK = 0,
|
||||
@@ -24,6 +33,11 @@ typedef enum {
|
||||
LAST = GREY
|
||||
} ColorType_t;
|
||||
|
||||
class Geom_t {
|
||||
public:
|
||||
int x, y, width, height;
|
||||
};
|
||||
|
||||
class YellowNotes
|
||||
{
|
||||
private:
|
||||
@@ -32,11 +46,14 @@ private:
|
||||
void *_dlg;
|
||||
void *_langs;
|
||||
|
||||
std::list<SettingContainer *> _settings_containers;
|
||||
std::list<YellowNote *> _notes;
|
||||
int _font_size;
|
||||
GtkWindow *_toplevel;
|
||||
std::unordered_map<std::string, std::string> _cfg;
|
||||
|
||||
std::list<Geom_t> _monitors;
|
||||
|
||||
private:
|
||||
void loadConfig();
|
||||
void saveConfig();
|
||||
@@ -53,23 +70,43 @@ public:
|
||||
int fontSize();
|
||||
int iconSize();
|
||||
GtkWindow *topLevel();
|
||||
void colorSet(void *sender);
|
||||
void setFontSize(int size);
|
||||
|
||||
public:
|
||||
void popupTrayMenu(void *sender);
|
||||
bool popupTrayMenuBtn(void *sender, GdkEventButton *evt);
|
||||
void newNote(void *sender);
|
||||
void showNotes(void *sender);
|
||||
void notesToDesktop(void *sender);
|
||||
void notesFromDesktop(void *sender);
|
||||
void reloadNotes(void *sender);
|
||||
void monitorsChanged(void *sender);
|
||||
void quit(void *sender);
|
||||
void topLevelHidden(GtkWidget *sender);
|
||||
void setup(void *sender);
|
||||
void reOrder(void *sender);
|
||||
void setupClose(GtkWidget *sender);
|
||||
void setupCancel(GtkWidget *sender);
|
||||
bool setupDel(GtkWidget *sender, void *evt);
|
||||
void remove(YellowNote *n);
|
||||
void checkMonitors();
|
||||
void about(void *sender);
|
||||
|
||||
|
||||
public:
|
||||
std::string currentLang();
|
||||
void setCurrentLang(const std::string &l);
|
||||
bool cfgOnDesktop();
|
||||
void setCfgOnDesktop(bool y);
|
||||
std::string getFgColor(ColorType_t type);
|
||||
std::string getBgColor(ColorType_t type);
|
||||
void setFgColor(ColorType_t type, const std::string &col);
|
||||
void setBgColor(ColorType_t type, const std::string &col);
|
||||
std::string fromRGBA(const GdkRGBA &rgba);
|
||||
void toRGBA(const std::string &col, GdkRGBA &rgba);
|
||||
void updateWidgetCss(GtkWidget *w, ColorType_t col);
|
||||
GtkWidget *getWindow();
|
||||
|
||||
public:
|
||||
YellowNotes(void *app);
|
||||
@@ -87,6 +124,7 @@ public:
|
||||
static void func(GObject *obj, void *arg, gpointer user_data) { type *o = reinterpret_cast<type *>(user_data); o->member(obj, reinterpret_cast<argtype *>(arg)); }
|
||||
|
||||
#define BSIGNAL2(type, func, member, argtype) \
|
||||
static gboolean func(GObject *obj, void *arg, gpointer user_data) { type *o = reinterpret_cast<type *>(user_data); return o->member(obj, reinterpret_cast<argtype *>(arg)); }
|
||||
static gboolean func(GObject *obj, void *arg, gpointer user_data) { \
|
||||
type *o = reinterpret_cast<type *>(user_data); return o->member(obj, reinterpret_cast<argtype *>(arg)); }
|
||||
|
||||
#endif // YELLOWNOTES_H
|
||||
|
||||
Reference in New Issue
Block a user