kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

commit b2b434448086b621cf3750525aa918a0da1a90b5
parent bc906dc772de296971d59ffe1644cfb92dc2d7b5
Author: lash <dev@holbrook.no>
Date:   Fri, 31 May 2024 17:45:54 +0100

New beamenu system integrated

Diffstat:
M.gitignore | 4++++
MMakefile | 3+++
Msrc/aux/beamenu/beamenu.h | 10++++++++--
Msrc/aux/beamenu/gen.c | 13+++++++++++++
Msrc/gtk/kee-menu.c | 49++++++++++++++++++++++++++++++++++++++++++-------
Msrc/gtk/kee-menu.h | 2+-
Asrc/gtk/menu.txt | 6++++++
Msrc/gtk/nav.c | 42++++++++++++++++++++++++++++++++++++------
Msrc/gtk/nav.h | 6+++++-
Msrc/gtk/ui.c | 5++++-
10 files changed, 122 insertions(+), 18 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -7,3 +7,7 @@ beamenu_defs.c src/aux/**/*test* src/aux/**/.gitignore src/gtk/resources.c +src/gtk/beamenu_defs.* +src/tests/test_* +src/asn1/schema_entry_asn1_tab.c +src/asn1/generate_asn1 diff --git a/Makefile b/Makefile @@ -46,5 +46,8 @@ testdata: testdata_schema python testdata_asn1.py make -C src/tests testdata +testdata_gtk: gtk testdata + cd testdata && ln -svf ../src/gtk/beamenu.dat beamenu.dat + doc: pandoc -fgfm -tplain README.md > README diff --git a/src/aux/beamenu/beamenu.h b/src/aux/beamenu/beamenu.h @@ -1,8 +1,15 @@ #ifndef BEAMENU_H_ #define BEAMENU_H_ +#define BEAMENU_EXIT_SIZE 1 + #define BEAMENU_INACTIVE 0x0 -#define BEAMENU_ROOT 0xffffffff + +#if BEAMENU_EXIT_SIZE == 1 +#define BEAMENU_ROOT 0xff +#define BEAMENU_DEFAULT 0xfe +#endif + #define BEAMENU_CN_MAXLEN 32 #ifndef BEAMENU_N_DST @@ -13,7 +20,6 @@ #define BEAMENU_N_EXITS 0 #endif -#define BEAMENU_EXIT_SIZE 1 struct beamenu_node { diff --git a/src/aux/beamenu/gen.c b/src/aux/beamenu/gen.c @@ -133,6 +133,18 @@ int set(int c) { fprintf(stderr, "set zero %d %d\n", c, tmpc); } return 0; + } else if (*o.key == '_') { + beamenu_set(c, tmpc, BEAMENU_DEFAULT); + if (debug) { + fprintf(stderr, "set default %d %d\n", c, tmpc); + } + return 0; + } else if (*o.key == '/') { + beamenu_set(c, tmpc, BEAMENU_ROOT); + if (debug) { + fprintf(stderr, "set root %d %d\n", c, tmpc); + } + return 0; } p = hsearch(o, FIND); if (!p) { @@ -163,6 +175,7 @@ int linkscan(int f, int l, int *c) { } } + // add input validator, enforce character ranges if (tmpm == MODE_READ) { while(tmpbi < l) { v = buf[tmpbi]; diff --git a/src/gtk/kee-menu.c b/src/gtk/kee-menu.c @@ -29,7 +29,7 @@ struct _KeeMenuClass { G_DEFINE_TYPE(KeeMenu, kee_menu, GTK_TYPE_APPLICATION_WINDOW); static void kee_menu_act_back(GAction *act, GVariant *param, KeeMenu *menu) { - kee_menu_prev(menu); + kee_menu_prev(menu, 0); } static void kee_menu_act_import(GAction *act, GVariant *param, KeeMenu *menu) { @@ -133,11 +133,15 @@ static void kee_menu_init(KeeMenu *o) { } KeeMenu* kee_menu_new(GtkApplication *gapp, struct kee_context *ctx) { + int r; KeeMenu *o; GtkWidget *butt; GSimpleAction *act; - kee_nav_init((char*)settings_get(ctx->settings, SETTINGS_DATA)); + r = kee_nav_init((char*)settings_get(ctx->settings, SETTINGS_DATA)); + if (r) { + return NULL; + } o = g_object_new(KEE_TYPE_MENU, "application", gapp, NULL); o->ctx = ctx; @@ -190,7 +194,7 @@ KeeMenu* kee_menu_new(GtkApplication *gapp, struct kee_context *ctx) { //static void kee_menu_header_update(KeeMenu *o, const char *label) { -static void kee_menu_header_update(KeeMenu *o, int menu_id) { +static void kee_menu_header_update_explicit(KeeMenu *o, int menu_id) { GAction *act; switch (menu_id) { @@ -216,6 +220,35 @@ static void kee_menu_header_update(KeeMenu *o, int menu_id) { } } +static void kee_menu_header_update(KeeMenu *o) { + GAction *act; + int v; + + v = kee_nav_get_exit(KEE_NAV_EXIT_BACK); + act = g_action_map_lookup_action(G_ACTION_MAP(o), "back"); + if (v) { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); + } else { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); + } + + v = kee_nav_get_exit(KEE_NAV_EXIT_NEW); + act = g_action_map_lookup_action(G_ACTION_MAP(o), "new_entry"); + if (v) { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); + } else { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); + } + + v = kee_nav_get_exit(KEE_NAV_EXIT_IMPORT); + act = g_action_map_lookup_action(G_ACTION_MAP(o), "import"); + if (v) { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); + } else { + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); + } +} + int kee_menu_add(KeeMenu *o, const char *label, GtkWidget *widget) { gtk_stack_add_named(o->stack, widget, label); return ERR_OK; @@ -232,7 +265,8 @@ GtkWidget* kee_menu_next(KeeMenu *o, int menu_id) { kee_nav_set(widget, menu_id); gtk_stack_set_visible_child(o->stack, widget); //kee_menu_header_update(o, label); - kee_menu_header_update(o, menu_id); + //kee_menu_header_update(o, menu_id); + kee_menu_header_update(o); return widget; } @@ -251,13 +285,14 @@ int kee_menu_set(KeeMenu *o, GtkWidget *widget) { return 0; } -int kee_menu_prev(KeeMenu *o) { +int kee_menu_prev(KeeMenu *o, int force) { GtkWidget *widget; - widget = kee_nav_back(); + widget = kee_nav_back(force); gtk_stack_set_visible_child(o->stack, widget); - kee_menu_header_update(o, KEE_NAV_IDX); + //kee_menu_header_update(o, KEE_NAV_IDX); + kee_menu_header_update(o); return ERR_OK; } diff --git a/src/gtk/kee-menu.h b/src/gtk/kee-menu.h @@ -27,7 +27,7 @@ KeeMenu* kee_menu_new(GtkApplication *app, struct kee_context *ctx); int kee_menu_add(KeeMenu *o, const char *k, GtkWidget *v); //GtkWidget* kee_menu_next(KeeMenu *o, const char *k); GtkWidget* kee_menu_next(KeeMenu *o, int menu_id); -int kee_menu_prev(KeeMenu *o); +int kee_menu_prev(KeeMenu *o, int force); int kee_menu_set(KeeMenu *o, GtkWidget *widget); G_END_DECLS diff --git a/src/gtk/menu.txt b/src/gtk/menu.txt @@ -0,0 +1,6 @@ +list,,new,import +key,,, +new,_,, +add,_,, +import,_,, +transport,,, diff --git a/src/gtk/nav.c b/src/gtk/nav.c @@ -5,9 +5,12 @@ #include "nav.h" #include "beamenu_defs.h" +#include "debug.h" static GtkWidget* widgets[KEE_NAV_N_DST]; +static int stack[KEE_NAV_STACK_SIZE]; +static int stack_crsr; int kee_nav_init(const char *path) { char *p; @@ -20,6 +23,7 @@ int kee_nav_init(const char *path) { } p = strcpy(p, "beamenu.dat"); + stack_crsr = 0; return beamenu_load_file(fullpath, 1); } @@ -29,6 +33,8 @@ int kee_nav_set(GtkWidget *widget, int menu_id) { } widgets[menu_id] = widget; beamenu_jump(menu_id); + stack[stack_crsr] = menu_id; + stack_crsr++; return 0; } @@ -40,39 +46,63 @@ int kee_nav_unset(int menu_id) { return 0; } -GtkWidget* kee_nav_back() { +GtkWidget* kee_nav_back(int force) { GtkWidget *widget; int r; + if (stack_crsr == 0) { + return NULL; + } + r = beamenu_use_exit(KEE_NAV_EXIT_BACK); if (r < 0) { - return NULL; + if (!force) { + debug_log(DEBUG_WARNING, "no back action found"); + return NULL; + } + r = 0; } + if (r == 0 || r == BEAMENU_DEFAULT) { + if (stack_crsr < 2) { + debug_log(DEBUG_CRITICAL, "menu stack underrun"); + return NULL; + } + r = stack[stack_crsr-1]; + kee_nav_unset(r); + stack_crsr--; + r = stack[stack_crsr-1]; + } + if (widgets[r] == NULL) { + debug_log(DEBUG_WARNING, "no widget found"); return NULL; } widget = widgets[r]; - widgets[r] = 0x0; + beamenu_jump(r); + return widget; } GtkWidget* kee_nav_get() { struct beamenu_node *o; - o = beamenu_get(-1); return widgets[o->i]; } char *kee_nav_get_label() { struct beamenu_node *o; - o = beamenu_get(-1); return beamenu_dst_r[o->i]; } int kee_nav_get_idx() { struct beamenu_node *o; - o = beamenu_get(-1); return o->i; } + +int kee_nav_get_exit(int exit_id) { + struct beamenu_node *o; + o = beamenu_get(-1); + return o->dst[exit_id]; +} diff --git a/src/gtk/nav.h b/src/gtk/nav.h @@ -13,8 +13,11 @@ #define KEE_NAV_N_DST BEAMENU_N_DST + 1 #endif - #define KEE_NAV_EXIT_BACK 0 +#define KEE_NAV_EXIT_NEW 1 +#define KEE_NAV_EXIT_IMPORT 2 + +#define KEE_NAV_STACK_SIZE 8 int kee_nav_init(const char *path); int kee_nav_set(GtkWidget *, int idx); @@ -23,5 +26,6 @@ GtkWidget* kee_nav_get(); int kee_nav_get_idx(); char* kee_nav_get_label(); GtkWidget* kee_nav_back(); // returns new current widget +int kee_nav_get_exit(); #endif // _KEE_NAV_H diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -30,7 +30,7 @@ static void ui_handle_unlock(KeeKey *o, KeeMenu *menu) { gtk_window_set_title(GTK_WINDOW(menu), fingerprint); g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "key is unlocked"); - kee_menu_prev(menu); + kee_menu_prev(menu, 1); } //static void ui_handle_import(KeeImport *import, GString *v, KeeMenu *menu) { @@ -80,6 +80,9 @@ void ui_build(GtkApplication *gapp, struct kee_context *ctx) { KeeImport *import; win = kee_menu_new(gapp, ctx); + if (!win) { + debug_log(DEBUG_CRITICAL, "menu init fail"); + } widget = GTK_WIDGET(kee_key_new(&ctx->gpg)); //kee_menu_add(win, "unlock", widget);