kee

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

commit 61e705e4a0867077565b07d7cccfd38cbda52ee1
parent 8c0ed97c77d435c4c4dab8901d80f677e7edfe1c
Author: lash <dev@holbrook.no>
Date:   Sun, 17 Mar 2024 05:20:07 +0000

WIP all ui context to gobject

Diffstat:
Msrc/db.c | 1+
Msrc/db.h | 6++++++
Msrc/digest.h | 4++++
Msrc/err.h | 23+++++++++++++----------
Msrc/gtk/kee-uicontext.c | 43++++++++++++++++++++++++++++++++++---------
Msrc/gtk/kee-uicontext.h | 3+++
Msrc/gtk/main.c | 12++++++------
Msrc/gtk/menu.c | 35+++++++++++++++++++++--------------
Msrc/gtk/ui.c | 111++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/gtk/ui.h | 13+++----------
Asrc/state.h | 14++++++++++++++
11 files changed, 161 insertions(+), 104 deletions(-)

diff --git a/src/db.c b/src/db.c @@ -4,6 +4,7 @@ #include <gcrypt.h> #include <time.h> #include "db.h" +#include "digest.h" #include "err.h" #include "endian.h" diff --git a/src/db.h b/src/db.h @@ -11,6 +11,12 @@ #define DB_VALUE_SIZE_LIMIT 1048576 #endif +enum DbErr { + ERR_DB_FAIL = 1, + ERR_DB_NOMATCH, + ERR_DB_INVALID, +}; + /** * \brief Key prefixes used for database storage. * diff --git a/src/digest.h b/src/digest.h @@ -1,6 +1,10 @@ #ifndef _KEE_DIGEST_H #define _KEE_DIGEST_H +enum DigestErr { + ERR_DIGESTFAIL = 1, +}; + #ifdef __cplusplus extern "C" { #endif diff --git a/src/err.h b/src/err.h @@ -4,16 +4,19 @@ * */ enum keeError { + /// No error so far within current context ERR_OK, + /// General failure code ERR_FAIL, - ERR_SPACE, - ERR_NOCRYPTO, - ERR_NOKEY, - ERR_KEYFAIL, - ERR_DIGESTFAIL, - ERR_DB_FAIL, - ERR_DB_NOMATCH, - ERR_DB_INVALID, - ERR_QR_MISSING, - ERR_QR_INVALID, + /// Last attempt to unlock key failed + ERR_KEY_UNLOCK, + /// Usage of key for signature has been rejected (by user) + ERR_KEY_REJECT, + /// Last input matches entry that already exists in storage + ERR_INPUT_CORRUPT, + /// Last input changes entry that already exists in storage, but was not allowed + ERR_INPUT_DUP, + /// Last input changes entry that already exists in storage, but was not allowed + ERR_INPUT_PROTECT, + }; diff --git a/src/gtk/kee-uicontext.c b/src/gtk/kee-uicontext.c @@ -1,8 +1,10 @@ #include <glib-object.h> +#include <gtk/gtk.h> #include "kee-uicontext.h" #include "ui.h" #include "context.h" +#include "state.h" typedef struct { @@ -25,14 +27,25 @@ static guint kee_sigs[KEE_N_SIGS] = {0,}; static void kee_uicontext_set_property(GObject *oo, guint property_id, const GValue *value, GParamSpec *pspec) { KeeUicontext *o = KEE_UICONTEXT(oo); + struct ui_container *ui; switch ((enum KEE_PROPS) property_id) { case CORE_CONTEXT: o->ctx = g_value_get_pointer(value); break; case UI_CONTAINER: - o->ui = g_value_get_pointer(value); - o->app = (GApplication*)o->ui->gapp; + ui = g_value_get_pointer(value); + o->app = (GApplication*)ui->gapp; + o->ctx->front = ui; + break; + case UI_HEADER: + ui = (struct ui_container*)o->ctx->front; + ui->head = g_value_get_object(value); + break; + case UI_WINDOW: + ui = (struct ui_container*)o->ctx->front; + ui->win = g_value_get_object(value); + gtk_window_set_titlebar(GTK_WINDOW(ui->win), GTK_WIDGET(ui->head)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec); @@ -43,10 +56,15 @@ static void kee_uicontext_set_property(GObject *oo, guint property_id, const GVa static void kee_uicontext_get_property(GObject *oo, guint property_id, GValue *value, GParamSpec *pspec) { KeeUicontext *o = KEE_UICONTEXT(oo); + struct ui_container *ui; + switch ((enum KEE_PROPS) property_id) { case GAPP: g_value_set_pointer(value, o->app); break; + case UI_WINDOW: + ui = (struct ui_container*)o->ctx->front; + g_value_set_pointer(value, ui->win); default: G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec); break; @@ -81,13 +99,24 @@ static void kee_uicontext_class_init(KeeUicontextClass *kls) { "Ui Container", "UI container to connect", G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE); + kee_props[UI_HEADER] = g_param_spec_object( + "ui_header", + "UI header", + "UI header bar", + GTK_TYPE_HEADER_BAR, + G_PARAM_WRITABLE); + kee_props[UI_WINDOW] = g_param_spec_object( + "ui_window", + "UI window", + "UI application window", + GTK_TYPE_WINDOW, + G_PARAM_WRITABLE | G_PARAM_READABLE); kee_props[GAPP] = g_param_spec_pointer( "app", "Gapplication object", "Gapplication object attached to ui", G_PARAM_READABLE); - g_object_class_install_properties(o, KEE_N_PROPS, kee_props); } @@ -96,11 +125,11 @@ static void kee_uicontext_init(KeeUicontext *self) { } void kee_uicontext_scanstart(KeeUicontext *o) { - if (KEE_UI_STATE_IS_SCANNING(o->ui)) { + if (KEE_IS_SCANNING(o->ui)) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "already in scanning state"); return; } - ui_state_change(o->ui, KEE_UI_STATE_SCANNING, 0); + ui_state_change(o->ui, KEE_ST_SCAN_SEARCH, 0); g_signal_emit(o, kee_sigs[SCAN_WANT], 0); } @@ -112,7 +141,3 @@ KeeState kee_uicontext_state(KeeUicontext *o) { return state; } - -GApplication* kee_uicontext_get_application(KeeUicontext *o) { - return o->app; -} diff --git a/src/gtk/kee-uicontext.h b/src/gtk/kee-uicontext.h @@ -2,6 +2,7 @@ #define _GTK_KEE_UICONTEXT_H #include <glib-object.h> +#include "context.h" G_BEGIN_DECLS @@ -18,6 +19,8 @@ enum KEE_SIGS { enum KEE_PROPS { CORE_CONTEXT = 1, UI_CONTAINER, + UI_HEADER, + UI_WINDOW, GAPP, KEE_N_PROPS, }; diff --git a/src/gtk/main.c b/src/gtk/main.c @@ -10,12 +10,12 @@ #include "camera.h" -static void startup(GtkApplication *app, KeeUicontext *ctx) { - menu_setup(ctx); +static void startup(GtkApplication *app, KeeUicontext *uctx) { + menu_setup(uctx); } -static void activate(GtkApplication *app, struct kee_context *ctx) { - ui_build(app, ctx); +static void activate(GtkApplication *app, KeeUicontext *uctx) { + ui_build(app, uctx); } static void deactivate(GtkApplication *app, gpointer user_data) { @@ -42,10 +42,10 @@ int main(int argc, char **argv) { kee_context_new(&ctx, &ui, &settings); uctx = g_object_new(KEE_TYPE_UICONTEXT, "ui_container", &ui, "core_context", &ctx, NULL); - db_connect(&ctx.db, "./testdata_mdb"); + //db_connect(&ctx.db, "./testdata_mdb"); g_signal_connect (ui.gapp, "startup", G_CALLBACK (startup), uctx); - g_signal_connect (ui.gapp, "activate", G_CALLBACK (activate), &ctx); + g_signal_connect (ui.gapp, "activate", G_CALLBACK (activate), uctx); g_signal_connect (ui.gapp, "shutdown", G_CALLBACK (deactivate), uctx); g_signal_connect (uctx, "scan_want", G_CALLBACK( ui_handle_scan) , &ctx); diff --git a/src/gtk/menu.c b/src/gtk/menu.c @@ -1,7 +1,9 @@ #include <gtk/gtk.h> #include "kee-uicontext.h" +#include "ui.h" #include "scan.h" +#include "context.h" static void act_quit(GSimpleAction *act, GVariant *param, KeeUicontext *ui) { @@ -11,19 +13,17 @@ static void act_quit(GSimpleAction *act, GVariant *param, KeeUicontext *ui) { g_application_quit(gapp); } -//void menu_setup(struct ui_container *ui) { -void menu_setup(KeeUicontext *ui) { - GMenu *menu_bar; +void menu_setup(KeeUicontext *ctx_ui) { GMenu *menu; GMenuItem *menu_item; - GMenuItem *menu_item_menu; + GtkWidget *butt; + GtkWidget *butt_back; GSimpleAction *act; GApplication *gapp; + GtkWidget *head; - g_object_get(ui, "app", &gapp, NULL); + g_object_get(ctx_ui, "app", &gapp, NULL); - menu_bar = g_menu_new(); - menu_item_menu = g_menu_item_new("Menu", NULL); menu = g_menu_new(); menu_item = g_menu_item_new("Scan", "app.scan"); g_menu_append_item(menu, menu_item); @@ -35,18 +35,25 @@ void menu_setup(KeeUicontext *ui) { act = g_simple_action_new("quit", NULL); g_action_map_add_action(G_ACTION_MAP(gapp), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(act_quit), ui); + g_signal_connect(act, "activate", G_CALLBACK(act_quit), ctx_ui); act = g_simple_action_new("scan", NULL); g_action_map_add_action(G_ACTION_MAP(gapp), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(scan_act), ui); + g_signal_connect(act, "activate", G_CALLBACK(scan_act), ctx_ui); + + head = gtk_header_bar_new(); + + butt = gtk_menu_button_new(); + gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(butt), G_MENU_MODEL(menu)); + gtk_menu_button_set_primary(GTK_MENU_BUTTON(butt), true); + gtk_menu_button_set_icon_name(GTK_MENU_BUTTON(butt), "preferences-system"); + gtk_header_bar_pack_end(GTK_HEADER_BAR(head), butt); - g_menu_item_set_submenu(menu_item_menu, G_MENU_MODEL(menu)); - g_object_unref(menu); + butt_back = gtk_button_new_from_icon_name("go-previous"); + gtk_header_bar_pack_start(GTK_HEADER_BAR(head), butt_back); + gtk_widget_set_visible(butt_back, false); - g_menu_append_item(menu_bar, menu_item_menu); - g_object_unref(menu_item_menu); + g_object_set(ctx_ui, "ui_header", GTK_HEADER_BAR(head), NULL); - gtk_application_set_menubar(GTK_APPLICATION(gapp), G_MENU_MODEL(menu_bar)); g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "set up menus"); } diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -7,6 +7,7 @@ #include "scan.h" #include "settings.h" #include "context.h" +#include "state.h" int ui_init(struct ui_container *ui) { @@ -20,8 +21,8 @@ int ui_init(struct ui_container *ui) { return ERR_OK; } -static void new_item(GtkListItemFactory *factory, GtkListItem *item, gpointer user_data) { -} +//static void new_item(GtkListItemFactory *factory, GtkListItem *item, gpointer user_data) { +//} static void ui_handle_unlock_click(GtkWidget *button, gpointer user_data) { struct ui_container *ui; @@ -47,7 +48,7 @@ static void ui_handle_camera_change(GtkDropDown *chooser, GParamSpec *spec, stru } -GtkWidget* ui_build_unlock(struct ui_container *ui) { +GtkWidget* ui_build_unlock(KeeUicontext *uctx) { GtkWidget *box; GtkWidget *entry; GtkWidget *button; @@ -59,7 +60,7 @@ GtkWidget* ui_build_unlock(struct ui_container *ui) { button = gtk_button_new_with_label("create"); gtk_box_append(GTK_BOX(box), button); - g_signal_connect (button, "clicked", G_CALLBACK (ui_handle_unlock_click), ui); + g_signal_connect (button, "clicked", G_CALLBACK (ui_handle_unlock_click), uctx); return GTK_WIDGET(box); } @@ -95,61 +96,61 @@ static GtkWidget* ui_build_scan_videochooser(struct kee_context *ctx) { return chooser; } -//static GtkWidget* ui_build_scan(struct ui_container *ui) { -static GtkWidget* ui_build_scan(struct kee_context *ctx) { - GtkWidget *chooser; - struct ui_container *ui; - - ui = (struct ui_container*)ctx->front; - ui->front_scan = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10)); - - chooser = ui_build_scan_videochooser(ctx); - gtk_box_append(GTK_BOX(ui->front_scan), chooser); - - return GTK_WIDGET(ui->front_scan); -} - - -static GtkWidget* ui_build_view(struct ui_container *ui) { - GtkSelectionModel *sel; - GtkListItemFactory *factory; - - ui->front_list = G_LIST_MODEL(gtk_string_list_new(NULL)); - sel = GTK_SELECTION_MODEL(gtk_single_selection_new(ui->front_list)); - factory = gtk_signal_list_item_factory_new(); - g_signal_connect(factory, "setup", G_CALLBACK(new_item), NULL); - ui->front_view = GTK_LIST_VIEW(gtk_list_view_new(GTK_SELECTION_MODEL(sel), factory)); - - return GTK_WIDGET(ui->front_view); -} +////static GtkWidget* ui_build_scan(struct ui_container *ui) { +////static GtkWidget* ui_build_scan(struct kee_context *ctx) { +//static GtkWidget* ui_build_scan(KeeUicontext *uctx) { +// GtkWidget *chooser; +// struct ui_container *ui; +// +// ui = (struct ui_container*)ctx->front; +// ui->front_scan = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 10)); +// +// chooser = ui_build_scan_videochooser(ctx); +// gtk_box_append(GTK_BOX(ui->front_scan), chooser); +// +// return GTK_WIDGET(ui->front_scan); +//} +// +// +////static GtkWidget* ui_build_view(struct ui_container *ui) { +//static GtkWidget* ui_build_view(KeeUicontext *uctx) { +// GtkSelectionModel *sel; +// GtkListItemFactory *factory; +// +// ui->front_list = G_LIST_MODEL(gtk_string_list_new(NULL)); +// sel = GTK_SELECTION_MODEL(gtk_single_selection_new(ui->front_list)); +// factory = gtk_signal_list_item_factory_new(); +// g_signal_connect(factory, "setup", G_CALLBACK(new_item), NULL); +// ui->front_view = GTK_LIST_VIEW(gtk_list_view_new(GTK_SELECTION_MODEL(sel), factory)); +// +// return GTK_WIDGET(ui->front_view); +//} -void ui_build(GtkApplication *app, struct kee_context *ctx) { +void ui_build(GtkApplication *app, KeeUicontext *uctx) { GtkWidget *widget; - struct ui_container *ui; - - ui = (struct ui_container*)ctx->front; + GtkWidget *win; + GtkWidget *stack; - ui->win = GTK_APPLICATION_WINDOW(gtk_application_window_new (app)); - ui->stack = GTK_STACK(gtk_stack_new()); + win = gtk_application_window_new (app); + stack = gtk_stack_new(); - gtk_window_set_title (GTK_WINDOW (ui->win), "kee"); - gtk_window_set_default_size (GTK_WINDOW (ui->win), 800, 600); + gtk_window_set_title (GTK_WINDOW (win), "kee"); + gtk_window_set_default_size (GTK_WINDOW (win), 800, 600); - gtk_window_set_child(GTK_WINDOW(ui->win), GTK_WIDGET(ui->stack)); - gtk_application_window_set_show_menubar(GTK_APPLICATION_WINDOW(ui->win), TRUE); - - widget = ui_build_unlock(ui); - gtk_stack_add_child(ui->stack, widget); - gtk_stack_set_visible_child(GTK_STACK(ui->stack), widget); - widget = ui_build_view(ui); - gtk_stack_add_child(ui->stack, widget); - widget = ui_build_scan(ctx); - gtk_stack_add_child(ui->stack, widget); - - //gtk_stack_set_visible_child(GTK_STACK(ui->stack), view); - - gtk_window_present(GTK_WINDOW (ui->win)); + widget = ui_build_unlock(uctx); + gtk_stack_add_child(GTK_STACK(stack), widget); + //widget = ui_build_view(uctx); + //gtk_stack_add_child(GTK_STACK(stack), widget); + //widget = ui_build_scan(uctx); + //gtk_stack_add_child(stack, widget); + + //g_object_get(uctx, "ui_window", win, NULL); + gtk_stack_set_visible_child(GTK_STACK(stack), widget); + gtk_window_set_child(GTK_WINDOW(win), GTK_WIDGET(stack)); + g_object_set(uctx, "ui_window", GTK_WINDOW(win), NULL); + + gtk_window_present(GTK_WINDOW (win)); } //void ui_build_from_resource(GtkApplication *app, struct ui_container *ui) { @@ -257,12 +258,12 @@ void ui_handle_scan(GtkApplication *app, struct kee_context *ctx) { s = settings_get(ctx->settings, SETTINGS_VIDEO); scan = &ui->scan; - if (ui->state & KEE_UI_STATE_SCAN_INIT) { + if (ui->state & KEE_ST_SCAN_INIT) { gtk_box_remove(ui->front_scan, GTK_WIDGET(scan->video_view)); scan_free(scan); } ui_build_scan_attach(ui, (const char*)s); - ui_state_change(ui, KEE_UI_STATE_SCANNING | KEE_UI_STATE_SCAN_INIT, 0); + ui_state_change(ui, KEE_ST_SCAN_INIT, 0); gtk_stack_set_visible_child(GTK_STACK(ui->stack), GTK_WIDGET(ui->front_scan)); } diff --git a/src/gtk/ui.h b/src/gtk/ui.h @@ -5,15 +5,7 @@ #include "scan.h" #include "settings.h" - - -typedef enum { - KEE_UI_STATE_INIT = 1, - KEE_UI_STATE_SCAN_INIT = 2, - KEE_UI_STATE_SCANNING = 4, -} UiState; - -#define KEE_UI_STATE_IS_SCANNING(c) c->state & KEE_UI_STATE_SCANNING +#include "kee-uicontext.h" struct ui_container { GtkApplication *gapp; @@ -23,13 +15,14 @@ struct ui_container { GListModel *camera_list; GtkListView *front_view; GtkBox *front_scan; + GtkHeaderBar *head; struct kee_scanner scan; struct kee_context *ctx; int state; }; int ui_init(struct ui_container *ui); -void ui_build(GtkApplication *app, struct kee_context *ctx); +void ui_build(GtkApplication *app, KeeUicontext *uctx); int ui_state_change(struct ui_container *ui, int set, int reset); void ui_free(struct ui_container *ui); diff --git a/src/state.h b/src/state.h @@ -0,0 +1,14 @@ +#ifndef _KEE_STATE_H +#define _KEE_STATE_H + +#define KEE_ST_CTRL 0x0100 +#define KEE_ST_CTRL_MAN 0x0101 +#define KEE_ST_CTRL_MACHINE 0x0102 +#define KEE_ST_CTRL_TRANSPORT 0x0104 + +#define KEE_ST_SCAN 0x0200 +#define KEE_ST_SCAN_INIT 0x0201 +#define KEE_ST_SCAN_SEARCH 0x0202 + +#define KEE_IS_SCANNING(c) c->state & KEE_ST_SCAN_SEARCH +#endif // _KEE_STATE_H