From 154f94d1fd2de8f6510bfebba848a24c60b1ba8b Mon Sep 17 00:00:00 2001 From: bigfoot547 Date: Sat, 24 Jan 2026 16:04:56 -0600 Subject: gtk stuff --- include/util.h | 3 ++ lib/util.c | 97 +++++++++++++++++++++++++++++++++++- meson.build | 1 + ui/main.c | 52 +++++++++++++++++++ ui/meson.build | 8 +++ ui/resources/main.ui | 22 ++++++++ ui/resources/meson.build | 5 ++ ui/resources/progress.ui | 37 ++++++++++++++ ui/resources/vaclaunch.gresource.xml | 6 +++ 9 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 ui/main.c create mode 100644 ui/meson.build create mode 100644 ui/resources/main.ui create mode 100644 ui/resources/meson.build create mode 100644 ui/resources/progress.ui create mode 100644 ui/resources/vaclaunch.gresource.xml diff --git a/include/util.h b/include/util.h index 5ef3c8b..f6599c1 100644 --- a/include/util.h +++ b/include/util.h @@ -1,8 +1,11 @@ #ifndef VL_UTIL_H_INCLUDED #define VL_UTIL_H_INCLUDED +#include "arena.h" #include int vl_mkdir_parents(int fd, char *path, mode_t mode); +int vl_mkdir_parents_open(int fd, char *path, mode_t nmode); +int vl_get_data_dir(vl_arena *alloc, const char *application, char **opath); #endif diff --git a/lib/util.c b/lib/util.c index 6cfcf1f..29423d1 100644 --- a/lib/util.c +++ b/lib/util.c @@ -5,10 +5,54 @@ #include #include #include +#include +#include + +int vl_mkdir_parents_open(int fd, char *path, mode_t nmode) +{ + int last = 0; + int at = fd; + int temp; + char *ch = path; + char *compstart = path; + int ret = -1; + + do { + if (*ch == '/' || (*ch == '\0' && (last = 1))) { + if (ch == path) continue; /* false alarm: we're trying to create / */ + + *ch = '\0'; + + if (mkdirat(at, compstart, nmode) < 0 && errno != EEXIST) { + vl_debug("%s: failed to create directory %s: %s", __func__, path, strerror(errno)); + goto cleanup; + } + + temp = openat(at, compstart, O_RDONLY); + if (temp < 0) { + vl_debug("%s: failed to open new directory %s: %s", __func__, path, strerror(errno)); + goto cleanup; + } + + close(at); + temp = at; + + compstart = ch + 1; + if (!last) *ch = '/'; /* make an effort to unclobber path */ + } + } while (*(ch++)); + + ret = 0; + +cleanup: + if (at != fd) close(at); + return ret; +} /* will clobber path */ -int vl_mkdir_parents(int fd, char *path, mode_t mode) +int vl_mkdir_parents(int fd, char *path, mode_t nmode) { +#if 0 int last = 0; char *ch = path; @@ -25,6 +69,57 @@ int vl_mkdir_parents(int fd, char *path, mode_t mode) if (!last) *ch = '/'; } } while (*(ch++)); +#endif /* old implementation */ + + fd = vl_mkdir_parents_open(fd, path, nmode); + if (fd >= 0) { + close(fd); + return 0; + } + + return -1; +} + +/* def: home-relative default */ +/* https://specifications.freedesktop.org/basedir/latest/ */ +static int open_xdg_dir(vl_arena *scratch, const char *xdg_env, const char *def) +{ + const char *xdg_dir = getenv(xdg_env); + int dfd; + + if (xdg_dir && *xdg_dir == '/') { + char *xdg_dir_mod = vl_arena_strdup(scratch, xdg_dir); + + /* must be an absolute path */ + if ((dfd = vl_mkdir_parents_open(AT_FDCWD, xdg_dir_mod, 0700)) < 0) { + vl_warn("get_xdg_dir: Failed to create %s: %s", xdg_dir, strerror(errno)); + return -1; + } + + return dfd; + } + + /* xdg dir is missing or not absolute (as required) */ + const char *home = getenv("HOME"); + /* TODO: could get passwd entry for home directory */ + + if (!home || *home != '/') { + vl_warn("Missing $HOME (or it is not an absolute path)! Cannot decide launcher data directory."); + return -1; + } + + char *path = vl_arena_sprintf(scratch, "%s/%s", home, def); + + if ((dfd = vl_mkdir_parents_open(AT_FDCWD, path, 0700)) < 0) { + vl_warn("%s: failed to create/open xdg dir %s: %s", __func__, path, strerror(errno)); + return -1; + } return 0; } + +int vl_get_data_dir(vl_arena *alloc, const char *application, char **opath) +{ + /* TODO: not just linux */ + int datadir = open_xdg_dir(alloc, "XDG_DATA_HOME", ".local/share"); +} diff --git a/meson.build b/meson.build index d34bf7d..ec2b878 100644 --- a/meson.build +++ b/meson.build @@ -87,6 +87,7 @@ configure_file( output : 'config.h') subdir('lib') +subdir('ui') executable('vl', files('main.c'), link_with : [ vaclaunch_libs.get_shared_lib() ], diff --git a/ui/main.c b/ui/main.c new file mode 100644 index 0000000..d6d50c4 --- /dev/null +++ b/ui/main.c @@ -0,0 +1,52 @@ +#include "gio/gio.h" +#include + +static void say_hi(GtkWidget *widget, gpointer data) +{ + g_print("Hello, world!\n"); +} + +static void activate(GtkApplication *app, gpointer up) +{ + GtkBuilder *builder = gtk_builder_new_from_resource("/dev/figboot/vaclaunch/progress.ui"); + GObject *window = gtk_builder_get_object(builder, "window"); + + gtk_window_set_application(GTK_WINDOW(window), app); + + g_signal_connect(gtk_builder_get_object(builder, "btn-cancel"), "clicked", G_CALLBACK(say_hi), NULL); + + gtk_window_present(GTK_WINDOW(window)); + g_object_unref(builder); +} + +static void do_work(GTask *task, GObject *src, gpointer task_data, GCancellable *cancellable) +{ + /* do work */ +} + +static GAsyncResult *do_task_async(GObject *self, GAsyncReadyCallback cb, gpointer user_data) +{ + GTask *task = g_task_new(self, NULL, cb, user_data); + + g_task_run_in_thread(task, (GTaskThreadFunc)do_work); + return G_ASYNC_RESULT(task); +} + +static void *do_task_finish(GObject *self, GAsyncResult *res, GError **perror) +{ + g_return_val_if_fail(g_task_is_valid(res, self), NULL); + return g_task_propagate_pointer(G_TASK(res), perror); +} + +int main(int argc, char **argv) +{ + GtkApplication *app; + int status; + + app = gtk_application_new("dev.figboot.vaclaunch", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + + return status; +} diff --git a/ui/meson.build b/ui/meson.build new file mode 100644 index 0000000..c1c4cb8 --- /dev/null +++ b/ui/meson.build @@ -0,0 +1,8 @@ +gtk4_dep = dependency('gtk4', required : true) + +subdir('resources') + +executable('vlui', files('main.c'), main_res, + link_with : [ vaclaunch_libs.get_shared_lib() ], + dependencies : [ curl_dep, jansson_dep, gtk4_dep ], + include_directories : proj_inc) diff --git a/ui/resources/main.ui b/ui/resources/main.ui new file mode 100644 index 0000000..4f4315d --- /dev/null +++ b/ui/resources/main.ui @@ -0,0 +1,22 @@ + + + + + + + + + vertical + + + + + Cancel + + + + + + + + diff --git a/ui/resources/meson.build b/ui/resources/meson.build new file mode 100644 index 0000000..0642a3f --- /dev/null +++ b/ui/resources/meson.build @@ -0,0 +1,5 @@ +gnome = import('gnome') + +main_res = gnome.compile_resources('vl-res', + files('vaclaunch.gresource.xml'), + c_name : 'vl') diff --git a/ui/resources/progress.ui b/ui/resources/progress.ui new file mode 100644 index 0000000..e49d9e0 --- /dev/null +++ b/ui/resources/progress.ui @@ -0,0 +1,37 @@ + + + + + false + true + false + center + center + + + vertical + + + 250 + Doing operation + true + 0.25 + 20 + 20 + 20 + 20 + + + + + + + Cancel + + + + + + + + diff --git a/ui/resources/vaclaunch.gresource.xml b/ui/resources/vaclaunch.gresource.xml new file mode 100644 index 0000000..10c76d5 --- /dev/null +++ b/ui/resources/vaclaunch.gresource.xml @@ -0,0 +1,6 @@ + + + + progress.ui + + -- cgit v1.2.3-70-g09d2