kee

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

commit 1fb3edc5418e38158c53406f617d5588283d692d
parent f8f9c6afd008e6054a4292617fd209e63493ab3a
Author: lash <dev@holbrook.no>
Date:   Tue, 25 Feb 2025 19:03:05 +0000

WIP clarify namespace and separate concents of gobjects

Diffstat:
Msrc/db.c | 35+++++++++++++++++++++++++++++++++++
Msrc/db.h | 40++++++++++++++++++++++++++++++----------
Msrc/gtk/Makefile | 7++++---
Dsrc/gtk/context.c | 41-----------------------------------------
Dsrc/gtk/context.h | 27---------------------------
Asrc/gtk/kee-context.c | 41+++++++++++++++++++++++++++++++++++++++++
Asrc/gtk/kee-context.h | 26++++++++++++++++++++++++++
Dsrc/gtk/kee-entry-item-store.c | 134-------------------------------------------------------------------------------
Dsrc/gtk/kee-entry-item-store.h | 19-------------------
Dsrc/gtk/kee-entry-item.c | 146-------------------------------------------------------------------------------
Dsrc/gtk/kee-entry-item.h | 44--------------------------------------------
Dsrc/gtk/kee-entry-list.c | 99-------------------------------------------------------------------------------
Dsrc/gtk/kee-entry-list.h | 18------------------
Msrc/gtk/kee-entry-store.c | 60++++++++++++++++--------------------------------------------
Msrc/gtk/kee-entry.c | 569+------------------------------------------------------------------------------
Dsrc/gtk/kee-import.c | 464-------------------------------------------------------------------------------
Dsrc/gtk/kee-import.h | 38--------------------------------------
Dsrc/gtk/kee-key.c | 96-------------------------------------------------------------------------------
Dsrc/gtk/kee-key.h | 28----------------------------
Dsrc/gtk/kee-menu.c | 302------------------------------------------------------------------------------
Dsrc/gtk/kee-menu.h | 36------------------------------------
Dsrc/gtk/kee-transport.c | 147-------------------------------------------------------------------------------
Dsrc/gtk/kee-transport.h | 28----------------------------
Dsrc/gtk/kee-uicontext.h | 27---------------------------
Asrc/gtk/kee-win.c | 34++++++++++++++++++++++++++++++++++
Asrc/gtk/kee-win.h | 16++++++++++++++++
Dsrc/gtk/kee.gresource.xml | 6------
Msrc/gtk/main.c | 20++++++--------------
Dsrc/gtk/menu.c | 47-----------------------------------------------
Dsrc/gtk/menu.h | 12------------
Dsrc/gtk/nav.c | 119-------------------------------------------------------------------------------
Dsrc/gtk/nav.h | 32--------------------------------
Dsrc/gtk/scan.c | 119-------------------------------------------------------------------------------
Dsrc/gtk/scan.h | 24------------------------
Dsrc/gtk/tests/Makefile | 24------------------------
Dsrc/gtk/tests/nav.c | 82-------------------------------------------------------------------------------
Dsrc/gtk/ui.c | 140-------------------------------------------------------------------------------
Dsrc/gtk/ui.h | 13-------------
38 files changed, 209 insertions(+), 2951 deletions(-)

diff --git a/src/db.c b/src/db.c @@ -17,6 +17,12 @@ int db_connect(struct db_ctx *ctx, char *conn) { int r; + ctx->seek.last = calloc(2048, 1); + ctx->seek.last_digest = ctx->seek.last + DB_KEY_SIZE_LIMIT; + ctx->seek.last_value_length = 1024; + //debug_log(DEBUG_DEBUG, "max key index is: %d", o->last_idx - 1); + debug_log(DEBUG_DEBUG, "max key index"); + ctx->connstr = conn; db_reset(ctx); r = mdb_env_create(&ctx->env); @@ -81,6 +87,7 @@ int db_finish(struct db_ctx *ctx) { return ERR_FAIL; } ctx->tx = NULL; + free(ctx->seek.last); return ERR_OK; } @@ -278,3 +285,31 @@ void db_reset(struct db_ctx *ctx) { memset(ctx, 0, sizeof(struct db_ctx)); ctx->connstr = s; } + +int db_seek(struct db_ctx *ctx, char *key, size_t *key_len, int offset) { + int i; + int r; + + memset(&ctx->seek, 0, sizeof(ctx->seek)); + ctx->seek.last_key = ctx->seek.last; + memset(ctx->seek.last_key, 0, *key_len); + ctx->seek.last_value = ctx->seek.last_digest + 64; + *ctx->seek.last_key = DbKeyLedgerHead; + ctx->seek.last_value_length = 1024; + i = 0; + ctx->seek.last_state = 2; + while (i <= offset) { + ctx->seek.last_idx = i; + ctx->seek.last_value_length = 1024; + r = db_next(ctx, DbKeyLedgerHead, &ctx->seek.last_key, key_len, &ctx->seek.last_value, &ctx->seek.last_value_length); + if (r) { + db_rewind(ctx); + ctx->seek.last_state = 0; + return i; + } + ctx->seek.last_state = 1; + i++; + } + + return i; +} diff --git a/src/db.h b/src/db.h @@ -38,6 +38,23 @@ enum DbKey { /** * + * \brief Seeking stat + * + */ +struct db_ctx_seek { + int browsing; + int last_idx; + int last_state; + int last_count; + char *last; + char *last_key; + char *last_digest; + char *last_value; + size_t last_value_length; +}; + +/** + * * \brief Interface to persistent storage of data items used in application. * */ @@ -56,23 +73,26 @@ struct db_ctx { enum DbKey current_key; int started; int browsing; + struct db_ctx_seek seek; }; -struct db_ctx_w { - char *connstr; - MDB_env *env; - MDB_dbi dbi; - MDB_txn *tx; - MDB_val *add_k; - MDB_val *add_v; - size_t add_cap; - size_t add_count; -}; + +//struct db_ctx_w { +// char *connstr; +// MDB_env *env; +// MDB_dbi dbi; +// MDB_txn *tx; +// MDB_val *add_k; +// MDB_val *add_v; +// size_t add_cap; +// size_t add_count; +//}; int db_connect(struct db_ctx *ctx, char *conn); void db_disconnect(struct db_ctx *ctx); //int db_put(struct db_ctx *ctx, enum DbKey pfx, char *data, size_t data_len); int db_put(struct db_ctx *ctx, char *key, size_t key_len, char *data, size_t data_len); +int db_seek(struct db_ctx *ctx, char *key, size_t *key_len, int offset); int db_next(struct db_ctx *ctx, enum DbKey pfx, char **key, size_t *key_len, char **value, size_t *value_len); void db_rewind(struct db_ctx *ctx); void db_reset(struct db_ctx *ctx); diff --git a/src/gtk/Makefile b/src/gtk/Makefile @@ -5,7 +5,8 @@ CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 libtasn1 libqrencode zbar` $( LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libtasn1 libqrencode zbar` -L../aux/lib -lb64 -lcmime -llash -lldap LDFLAGS += $(LIBS) -all: menu resource $(OBJS) +#all: menu resource $(OBJS) +all: menu $(OBJS) $(CC) $(CFLAGS) main.c -o a.out $(LINKOBJS) ../aux/beamenu/beamenu.o ../aux/beamenu/import.o beamenu_defs.o $(LDFLAGS) %.o: %.c @@ -23,8 +24,8 @@ clean: rm -vf beamenu.dat make -C tests clean -resource: - glib-compile-resources kee.gresource.xml --target=resources.c --generate-source +#resource: +# glib-compile-resources kee.gresource.xml --target=resources.c --generate-source menu: ../aux/beamenu/beamenu_gen menu.txt diff --git a/src/gtk/context.c b/src/gtk/context.c @@ -1,41 +0,0 @@ -#include <string.h> - -#include "debug.h" -#include "context.h" -#include "settings.h" -#include "camera.h" -#include "err.h" -#include "gpg.h" -#include "db.h" -#include "cadiz.h" -#include "cadir.h" - - -int kee_context_init(struct kee_context *ctx, struct kee_settings *settings) { - int r; - unsigned char *v; - - memset(ctx, 0, sizeof(struct kee_context)); - ctx->state = 1; - ctx->settings = settings; - r = db_connect(&ctx->db, (char*)settings->db); - if (r) { - return ERR_FAIL; - } - v = settings_get(ctx->settings, SETTINGS_KEY); - gpg_store_init(&ctx->gpg, (char*)v); - ctx->entry_store = kee_entry_store_new(&ctx->db); - kee_entry_store_set_resolve(ctx->entry_store, (char*)settings->resource); - - //ctx->resolver.locator = malloc(KEE_LOCATOR_LENGTH); - ctx->resolver.locator = (char*)settings->resource; - return ERR_OK; -} - -int kee_context_state(struct kee_context *ctx) { - return ctx->state; -} - -void kee_context_free(struct kee_context *ctx) { - //free(ctx->resolver.locator); -} diff --git a/src/gtk/context.h b/src/gtk/context.h @@ -1,27 +0,0 @@ -#ifndef _KEE_CONTEXT -#define _KEE_CONTEXT - -#include "kee-entry-store.h" -#include "settings.h" -#include "db.h" -#include "camera.h" -#include "gpg.h" -#include "cadiz.h" - - -struct kee_context { - void *front; - struct kee_settings *settings; - struct kee_camera_devices camera_devices; - struct db_ctx db; - struct gpg_store gpg; - KeeEntryStore *entry_store; - struct Cadiz resolver; - int state; -}; - -int kee_context_init(struct kee_context *ctx, struct kee_settings *settings); -int kee_context_state(struct kee_context *ctx); -void kee_context_free(struct kee_context *ctx); - -#endif // _KEE_CONTEXT diff --git a/src/gtk/kee-context.c b/src/gtk/kee-context.c @@ -0,0 +1,41 @@ +#include <string.h> + +#include "debug.h" +#include "kee-context.h" +#include "settings.h" +#include "camera.h" +#include "err.h" +#include "gpg.h" +#include "db.h" +#include "cadiz.h" +#include "cadir.h" + + +int kee_context_init(struct kee_context *ctx, struct kee_settings *settings) { + int r; + unsigned char *v; + + memset(ctx, 0, sizeof(struct kee_context)); + ctx->state = 1; + ctx->settings = settings; + r = db_connect(&ctx->db, (char*)settings->db); + if (r) { + return ERR_FAIL; + } + v = settings_get(ctx->settings, SETTINGS_KEY); + gpg_store_init(&ctx->gpg, (char*)v); + ctx->entry_store = kee_entry_store_new(&ctx->db); + kee_entry_store_set_resolve(ctx->entry_store, (char*)settings->resource); + + //ctx->resolver.locator = malloc(KEE_LOCATOR_LENGTH); + ctx->resolver.locator = (char*)settings->resource; + return ERR_OK; +} + +int kee_context_state(struct kee_context *ctx) { + return ctx->state; +} + +void kee_context_free(struct kee_context *ctx) { + //free(ctx->resolver.locator); +} diff --git a/src/gtk/kee-context.h b/src/gtk/kee-context.h @@ -0,0 +1,26 @@ +#ifndef _KEE_CONTEXT +#define _KEE_CONTEXT + +#include "kee-entry-store.h" +#include "settings.h" +#include "db.h" +#include "camera.h" +#include "gpg.h" +#include "cadiz.h" + + +struct kee_context { + struct kee_settings *settings; + struct kee_camera_devices camera_devices; + struct db_ctx db; + struct gpg_store gpg; + KeeEntryStore *entry_store; + struct Cadiz resolver; + int state; +}; + +int kee_context_init(struct kee_context *ctx, struct kee_settings *settings); +int kee_context_state(struct kee_context *ctx); +void kee_context_free(struct kee_context *ctx); + +#endif // _KEE_CONTEXT diff --git a/src/gtk/kee-entry-item-store.c b/src/gtk/kee-entry-item-store.c @@ -1,134 +0,0 @@ -#include <stdlib.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-entry-item-store.h" -#include "kee-entry-item.h" -#include "cadiz.h" -#include "db.h" -#include "err.h" - - -const size_t entry_ref_len = 65; -const size_t entry_key_len = 73; - - -typedef struct { -} KeeEntryItemStorePrivate; - -struct _KeeEntryItemStore { - GObject parent; - struct db_ctx *db; - int last_count; - char **ref; - char *ref_mem; - struct Cadiz *resolver; - struct kee_ledger_t *ledger; -}; - - -static void kee_entry_item_store_iface_init(GListModelInterface *ifc); -G_DEFINE_TYPE_WITH_CODE(KeeEntryItemStore, kee_entry_item_store, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, kee_entry_item_store_iface_init)); - -static int kee_entry_item_store_scan(KeeEntryItemStore *o); - -static void kee_entry_item_store_finalize(GObject *o); - -static void kee_entry_item_store_class_init(KeeEntryItemStoreClass *kls) { - GObjectClass *oc = G_OBJECT_CLASS(kls); - oc->finalize = kee_entry_item_store_finalize; -} - -static void kee_entry_item_store_init(KeeEntryItemStore *o) { -} - -static GType kee_entry_item_store_get_item_type(GListModel *list) { - return KEE_TYPE_ENTRY_ITEM; -} - -static guint kee_entry_item_store_get_n_items(GListModel *list) { - return KEE_ENTRY_ITEM_STORE(list)->last_count; -} - - -static gpointer kee_entry_item_store_get_item(GListModel *list, guint index) { - KeeEntryItem *o; - KeeEntryItemStore *store; - - store = KEE_ENTRY_ITEM_STORE(list); - o = kee_entry_item_new(store->db, store->ledger, (int)index); - if (o != NULL) { - kee_entry_item_set_resolver(o, store->resolver); - kee_entry_item_apply_list_item_widget(o); - } - - return o; -} - -static void kee_entry_item_store_iface_init(GListModelInterface *ifc) { - ifc->get_item_type = kee_entry_item_store_get_item_type; - ifc->get_n_items = kee_entry_item_store_get_n_items; - ifc->get_item = kee_entry_item_store_get_item; -} - -KeeEntryItemStore* kee_entry_item_store_new(struct db_ctx *db, struct kee_ledger_t *ledger, Cadiz *resolver) { - KeeEntryItemStore *o; - - o = g_object_new(KEE_TYPE_ENTRY_ITEM_STORE, NULL); - o->db = db; - o->ledger = ledger; - o->resolver = resolver; - - o->last_count = kee_entry_item_store_scan(o); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "max key index is: %d", o->last_count - 1); - return o; -} - -/// \todo always scans from 0, inefficient -/// \todo enum lookup states -static int kee_entry_item_store_scan(KeeEntryItemStore *o) { - struct kee_ledger_item_t *item; - int r; - int i; - size_t key_len; - char *mem[4096]; - char *last_key; - char *entry_key; - char *last_value; - size_t last_value_length; - - key_len = entry_ref_len; - last_key = (char*)mem; - entry_key = last_key + 128; - last_value = entry_key + 128; - *last_key = DbKeyLedgerEntry; - memcpy(last_key+1, o->ledger->digest, key_len - 1); - memcpy(entry_key, last_key, entry_ref_len); - - i = 0; - while (i <= INT_MAX) { - last_value_length = 2048; - r = db_next(o->db, DbKeyLedgerEntry, &last_key, &key_len, &last_value, &last_value_length); - if (r) { - break; - } - if (memcmp(entry_key, last_key, entry_ref_len)) { - break; - } - item = kee_ledger_parse_item_db(o->ledger, last_value, last_value_length); - if (item == NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "corrupt entry!"); - } else { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "adding entry: %d", i); - i++; - } - } - - db_rewind(o->db); - return i; -} - -void kee_entry_item_store_finalize(GObject *go) { - //KeeEntryItemStore *o = KEE_ENTRY_ITEM_STORE(go); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "freeing entry item store"); -} diff --git a/src/gtk/kee-entry-item-store.h b/src/gtk/kee-entry-item-store.h @@ -1,19 +0,0 @@ -#ifndef _GTK_KEE_ENTRY_ITEM_STORE_H -#define _GTK_KEE_ENTRY_ITEM_STORE_H - -#include <glib-object.h> -#include "db.h" -#include "ledger.h" -#include "cadiz.h" - -G_BEGIN_DECLS - -#define KEE_TYPE_ENTRY_ITEM_STORE kee_entry_item_store_get_type() -G_DECLARE_FINAL_TYPE(KeeEntryItemStore, kee_entry_item_store, KEE, ENTRY_ITEM_STORE, GObject); - -KeeEntryItemStore* kee_entry_item_store_new(struct db_ctx *db, struct kee_ledger_t *ledger, Cadiz *resolver); -void kee_entry_item_store_set_resolve(KeeEntryItemStore *o, const char *locator); - -G_END_DECLS - -#endif // _GTK_KEE_ENTRY_ITEM_STORE_H diff --git a/src/gtk/kee-entry-item.c b/src/gtk/kee-entry-item.c @@ -1,146 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-entry-item.h" -#include "ledger.h" -#include "db.h" -#include "err.h" - - -typedef struct { -} KeeEntryItemPrivate; - -struct _KeeEntryItemClass { - GtkWidget parent_class; -}; - -struct _KeeEntryItem { - GtkWidget parent; - int state; - char header[1024]; - struct kee_ledger_t *ledger; - struct kee_ledger_item_t *item; - struct Cadiz *resolver; - int alice_credit_delta; - int bob_credit_delta; - int alice_collateral_delta; - int bob_collateral_delta; - struct db_ctx *db; -}; - -G_DEFINE_TYPE(KeeEntryItem, kee_entry_item, GTK_TYPE_BOX); - - - -static void kee_entry_item_dispose(GObject *o) { -} - -static void kee_entry_item_finalize(GObject *o) { -} - -static void kee_entry_item_class_init(KeeEntryItemClass *kls) { - GObjectClass *object_class = G_OBJECT_CLASS(kls); - object_class->finalize = kee_entry_item_finalize; - object_class->dispose = kee_entry_item_dispose; -} - -static void kee_entry_item_init(KeeEntryItem *o) { - o->state = 2; - o->resolver = NULL; -} - -void kee_entry_item_set_resolver(KeeEntryItem *o, struct Cadiz *resolver) { - o->resolver = resolver; -} - -KeeEntryItem* kee_entry_item_new(struct db_ctx *db, struct kee_ledger_t *ledger, int idx) { - int i; - KeeEntryItem *o; - - o = KEE_ENTRY_ITEM(g_object_new(KEE_TYPE_ENTRY_ITEM, "orientation", GTK_ORIENTATION_VERTICAL, NULL)); - o->db = db; - o->item = ledger->last_item; - if (o->item == NULL) { - return NULL; - } - for (i = 0; i < idx; i++) { - o->item = o->item->prev_item; - } - return o; -} - -void kee_entry_item_set(KeeEntryItem *o, struct kee_ledger_item_t *item) { - o->item = item; -} - -GtkWidget *list_item_widget(KeeEntryItem *o) { - char *subject; - GtkWidget *widget; - - kee_content_resolve(&o->item->content, o->resolver); - subject = o->item->content.subject; - if (subject == NULL) { - subject = "(no description)"; - } - - sprintf(o->header, "%s\nalice: %i\nbob: %i\n", subject, o->item->alice_credit_delta, o->item->bob_credit_delta); - - widget = gtk_label_new(o->header); - - return widget; -} - -void kee_entry_item_apply_list_item_widget(KeeEntryItem *o) { - GtkWidget *widget; - - widget = gtk_widget_get_first_child(GTK_WIDGET(o)); - if (widget) { - gtk_box_remove(GTK_BOX(o), widget); - } - - widget = list_item_widget(o); - - gtk_box_append(GTK_BOX(o), widget); -} - -/// \todo make interface and function name more intuitive to reflect that this is not operating on the KeeEntryItem object. -void kee_entry_item_apply_edit_widget(GtkBox *box, struct kee_entry_item_form_t *form, int first) { - GtkWidget *widget; - - if (first) { - widget = gtk_label_new("Initial credit"); - } else { - widget = gtk_label_new("Credit change"); - } - gtk_box_append(box, widget); - widget = gtk_entry_new(); - form->alice_credit_delta = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(form->alice_credit_delta, GTK_INPUT_PURPOSE_NUMBER); - gtk_box_append(box, widget); - - if (first) { - widget = gtk_label_new("Initial collateral"); - } else { - widget = gtk_label_new("Collateral change"); - } - gtk_box_append(box, widget); - widget = gtk_entry_new(); - form->alice_collateral_delta = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(form->alice_collateral_delta, GTK_INPUT_PURPOSE_NAME); - gtk_box_append(box, widget); - -} - -void kee_entry_item_apply_summary_widget(KeeEntryItem *o, GtkBox *box) { - GtkWidget *widget; - widget = list_item_widget(o); - gtk_box_append(box, widget); -} - -//KeeEntryItem* kee_entry_item_import(const char *data, size_t data_len) { -// KeeEntryItem *item; -// -// item = g_object_new(KEE_TYPE_ENTRY_ITEM, "orientation", GTK_ORIENTATION_VERTICAL, NULL); -// -// return item; -//} diff --git a/src/gtk/kee-entry-item.h b/src/gtk/kee-entry-item.h @@ -1,44 +0,0 @@ -#ifndef _GTK_KEE_ENTRY_ITEM_H -#define _GTK_KEE_ENTRY_ITEM_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "db.h" -#include "cadiz.h" -#include "ledger.h" - -G_BEGIN_DECLS - - -struct kee_entry_item_form_t { - GtkEntry *alice_credit_delta; - GtkEntry *alice_collateral_delta; - GtkEntry *bob_credit_delta; - GtkEntry *bob_collateral_delta; -}; - -enum KEE_ENTRY_ITEM_PROPS { - KEE_P_ENTRY_ITEM_ALICE_CREDIT_DELTA = 1, - KEE_P_ENTRY_ITEM_BOB_CREDIT_DELTA, - KEE_P_ENTRY_ITEM_ALICE_COLLATERAL_DELTA, - KEE_P_ENTRY_ITEM_BOB_COLLATERAL_DELTA, - KEE_N_ENTRY_ITEM_PROPS, -}; - -#define KEE_TYPE_ENTRY_ITEM kee_entry_item_get_type() -G_DECLARE_FINAL_TYPE(KeeEntryItem, kee_entry_item, KEE, ENTRY_ITEM, GtkBox); - -KeeEntryItem* kee_entry_item_new(struct db_ctx *db, struct kee_ledger_t *ledger, int idx); -void kee_entry_item_handle_setup(GtkListItemFactory* o, GtkListItem *item); -void kee_entry_item_handle_bind(GtkListItemFactory *o, GtkListItem *item); -void kee_entry_item_set_resolver(KeeEntryItem *o, struct Cadiz *resolver); -int kee_entry_item_deserialize(KeeEntryItem *o, const char *data, size_t data_len); -void kee_entry_item_apply_list_item_widget(KeeEntryItem *o); -void kee_entry_item_apply_edit_widget(GtkBox *box, struct kee_entry_item_form_t *form, int first); -void kee_entry_item_apply_summary_widget(KeeEntryItem *o, GtkBox *box); -void kee_entry_item_set(KeeEntryItem *o, struct kee_ledger_item_t *item); - -G_END_DECLS - -#endif //_GTK_KEE_ENTRY_ITEM_H diff --git a/src/gtk/kee-entry-list.c b/src/gtk/kee-entry-list.c @@ -1,99 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-entry-list.h" -#include "kee-entry.h" -#include "kee-menu.h" -#include "err.h" -#include "debug.h" - - -typedef struct { -} KeeEntryListPrivate; - -struct _KeeEntryList { - GtkWidget parent; - GListModel *list; - GtkListItemFactory *factory; -}; - -G_DEFINE_TYPE(KeeEntryList, kee_entry_list, GTK_TYPE_BOX); - -static void kee_entry_list_handle_select(GtkListView *view, guint i, KeeMenu *menu) { - GtkSingleSelection *sel; - KeeEntry *o; - - debug_log(DEBUG_DEBUG, "handle select"); - - sel = GTK_SINGLE_SELECTION(gtk_list_view_get_model(view)); - - o = KEE_ENTRY(gtk_single_selection_get_selected_item(sel)); - g_object_take_ref(G_OBJECT(o)); - //kee_menu_next(menu, "entry"); - kee_menu_next(menu, BEAMENU_DST_NEW); - if (kee_entry_modeswitch(o, KEE_ENTRY_VIEWMODE_FULL)) { - kee_menu_set(menu, GTK_WIDGET(o)); - } - - //debug_log(DEBUG_DEBUG, "list item selected %d", i); - debug_log(DEBUG_DEBUG, "list item selected"); -} - - -/// \todo first member is probably not entry list -static void kee_entry_list_handle_setup(GtkListItemFactory* o, GtkListItem *item) { - debug_log(DEBUG_DEBUG, "entry list setup"); -} - -static void kee_entry_list_handle_bind(GtkListItemFactory *o, GtkListItem *item) { - KeeEntry *go; - //GtkGesture *ctrl; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list bind"); - go = gtk_list_item_get_item(item); - g_object_take_ref(G_OBJECT(go)); - gtk_list_item_set_child(item, GTK_WIDGET(go)); - //ctrl = gtk_gesture_long_press_new(); - //gtk_widget_add_controller(item, GtkEventController(ctrl)); -} - -static void kee_entry_list_handle_unbind(GtkListItemFactory* o, GtkListItem *item) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list unbind"); - //GObject *go; - //go = gtk_list_item_get_child(item); - gtk_list_item_set_child(item, NULL); - //g_object_unref(go); -} - -static void kee_entry_list_handle_teardown(GtkListItemFactory* o, GtkListItem *item) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list teardown"); -} - -static void kee_entry_list_class_init(KeeEntryListClass *kls) { -} - -static void kee_entry_list_init(KeeEntryList *o) { - o->factory = gtk_signal_list_item_factory_new(); - g_signal_connect(o->factory, "setup", G_CALLBACK(kee_entry_list_handle_setup), NULL); - g_signal_connect(o->factory, "bind", G_CALLBACK(kee_entry_list_handle_bind), NULL); - g_signal_connect(o->factory, "unbind", G_CALLBACK(kee_entry_list_handle_unbind), NULL); - g_signal_connect(o->factory, "teardown", G_CALLBACK(kee_entry_list_handle_teardown), NULL); -} - -GtkWidget* kee_entry_list_new(GListModel *model, KeeMenu *win) { - KeeEntryList *o; - GtkSingleSelection *sel; - GtkWidget *view; - - o = g_object_new(KEE_TYPE_ENTRY_LIST, "orientation", GTK_ORIENTATION_VERTICAL, NULL); - - sel = gtk_single_selection_new(model); - - view = gtk_list_view_new(GTK_SELECTION_MODEL(sel), o->factory); - gtk_list_view_set_single_click_activate(GTK_LIST_VIEW(view), 1); - g_signal_connect(view, "activate", G_CALLBACK(kee_entry_list_handle_select), win); - - gtk_box_append(GTK_BOX(o), view); - - return GTK_WIDGET(o); -} diff --git a/src/gtk/kee-entry-list.h b/src/gtk/kee-entry-list.h @@ -1,18 +0,0 @@ -#ifndef _GTK_KEE_ENTRY_LIST_H -#define _GTK_KEE_ENTRY_LIST_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-menu.h" - -G_BEGIN_DECLS - -#define KEE_TYPE_ENTRY_LIST kee_entry_list_get_type() -G_DECLARE_FINAL_TYPE(KeeEntryList, kee_entry_list, KEE, ENTRY_LIST, GtkBox); - -GtkWidget* kee_entry_list_new(GListModel *model, KeeMenu *menu); - -G_END_DECLS - -#endif // _GTK_KEE_ENTRY_LIST_H diff --git a/src/gtk/kee-entry-store.c b/src/gtk/kee-entry-store.c @@ -6,8 +6,9 @@ #include "kee-entry-store.h" #include "kee-entry.h" -#include "kee-menu.h" // remove when add handler is removed +//#include "kee-menu.h" // remove when add handler is removed #include "err.h" +#include "db.h" #include "cadiz.h" #include "ledger.h" @@ -18,14 +19,14 @@ typedef struct { struct _KeeEntryStore { GObject parent; struct db_ctx *db; - int last_idx; - int last_state; - int last_count; - char *last; - char *last_key; - char *last_digest; - char *last_value; - size_t last_value_length; +// int last_idx; +// int last_state; +// int last_count; +// char *last; +// char *last_key; +// char *last_digest; +// char *last_value; +// size_t last_value_length; struct Cadiz resolver; }; @@ -53,16 +54,14 @@ void kee_entry_store_set_resolve(KeeEntryStore *o, const char *locator) { strcpy(o->resolver.locator, locator); } - static GType kee_entry_store_get_item_type(GListModel *list) { return KEE_TYPE_ENTRY; } static guint kee_entry_store_get_n_items(GListModel *list) { - return KEE_ENTRY_STORE(list)->last_count; + return KEE_ENTRY_STORE(list)->db->seek.last_count; } - static gpointer kee_entry_store_get_item(GListModel *list, guint index) { int r; KeeEntry *o; @@ -72,7 +71,7 @@ static gpointer kee_entry_store_get_item(GListModel *list, guint index) { o = kee_entry_new(store->db); kee_entry_set_resolver(o, &store->resolver); kee_entry_store_seek(store, index); - r = kee_entry_deserialize(o, store->last_value, store->last_value_length); + r = kee_entry_deserialize(o, store->db->seek.last_value, store->db->seek.last_value_length); if (r) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry index %d malformed", index); } @@ -90,33 +89,13 @@ static void kee_entry_store_iface_init(GListModelInterface *ifc) { /// \todo always scans from 0, inefficient /// \todo enum lookup states -static int kee_entry_store_seek(KeeEntryStore *o, int idx) { - int r; - int i; +static int kee_entry_store_seek(KeeEntryStore *o, int offset) { size_t key_len; + char pfx; key_len = 9; - o->last_key = o->last; - memset(o->last_key, 0, key_len); - o->last_value = o->last_digest + 64; - *o->last_key = DbKeyLedgerHead; - o->last_value_length = 1024; - i = 0; - o->last_state = 2; - while (i <= idx) { - o->last_idx = i; - o->last_value_length = 1024; - r = db_next(o->db, DbKeyLedgerHead, &o->last_key, &key_len, &o->last_value, &o->last_value_length); - if (r) { - db_rewind(o->db); - o->last_state = 0; - return i; - } - o->last_state = 1; - i++; - } - - return i; + pfx = DbKeyLedgerHead; + return db_seek(o->db, &pfx, &key_len, offset); } KeeEntryStore* kee_entry_store_new(struct db_ctx *db) { @@ -124,12 +103,6 @@ KeeEntryStore* kee_entry_store_new(struct db_ctx *db) { o = g_object_new(KEE_TYPE_ENTRY_STORE, NULL); o->db = db; - o->last = calloc(2048, 1); - o->last_digest = o->last + DB_KEY_SIZE_LIMIT; - o->last_value_length = 1024; - - o->last_count = kee_entry_store_seek(o, INT_MAX); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "max key index is: %d", o->last_idx - 1); return o; } @@ -138,6 +111,5 @@ void kee_entry_store_finalize(GObject *go) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "freeing entry store"); free(o->resolver.locator); - free(o->last); } diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c @@ -1,33 +1,7 @@ -#include <gcrypt.h> -#include <stddef.h> -#include <stdlib.h> - #include <glib-object.h> #include <gtk/gtk.h> -#include <libtasn1.h> - -#include "cmime.h" - #include "kee-entry.h" -#include "kee-entry-item.h" -#include "kee-entry-item-store.h" -#include "kee-transport.h" -#include "db.h" -#include "err.h" -#include "hex.h" -#include "cadiz.h" -#include "db.h" -#include "digest.h" -#include "debug.h" -#include "endian.h" -#include "strip.h" -#include "ledger.h" -#include "dn.h" -#include "gpg.h" -#include "transport.h" -#include "qr.h" - typedef struct { } KeeEntryPrivate; @@ -36,559 +10,18 @@ struct _KeeEntryClass { GtkWidget parent_class; }; -#define ENTRYSTATE_LOAD 0x01 -#define ENTRYSTATE_SHORT 0x02 -#define ENTRYSTATE_EDIT 0x04 -#define ENTRYSTATE_CONFIRM 0x08 - -extern const asn1_static_node schema_entry_asn1_tab[]; - -struct kee_entry_form_t { - GtkEntry *bob_name; - GtkEntry *bob_pubkey; - GtkEntry *subject; - GtkEntry *uoa; - GtkEntry *uoa_decimals; - GtkEntry *passphrase; - struct kee_entry_item_form_t item_form; -}; - /// \todo factor out separate struct for listitem struct _KeeEntry { GtkWidget parent; - GtkWidget *display; - GtkWidget *edit; - GtkWidget *sign; - GtkWidget *entry_list; - GtkWidget *showing; - int state; - char header[1024]; - struct kee_dn_t bob_dn; - char current_id[64]; struct kee_ledger_t ledger; - struct Cadiz *resolver; - struct db_ctx *db; - struct kee_entry_form_t *form; - struct gpg_store *gpg; }; - G_DEFINE_TYPE(KeeEntry, kee_entry, GTK_TYPE_BOX); -static void kee_entry_handle_confirm(GtkButton *butt, KeeEntry *o) { - int r; - GtkApplication *gapp; - GtkWindow *win; - GtkWidget *widget; - GAction *act; - GtkEntryBuffer *buf; - char *b; - char *out; - char passphrase_hash[DIGEST_LENGTH]; - size_t out_len; - //struct kee_ledger_t *ledger; - struct kee_transport_t trans; - GVariant *transport_data; - - //ledger = &o->ledger; - - out_len = 1024; - out = malloc(out_len); -// kee_ledger_serialize_open(ledger, out, &out_len); - - buf = gtk_entry_get_buffer(o->form->passphrase); - b = (char*)gtk_entry_buffer_get_text(buf); - gpg_store_digest(o->gpg, passphrase_hash, b); - - memcpy(o->ledger.pubkey_alice, o->gpg->public_key, PUBKEY_LENGTH); - r = kee_ledger_sign(&o->ledger, o->ledger.last_item, o->gpg, passphrase_hash); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail entry sign"); - return; - } - - r = kee_ledger_put(&o->ledger, o->db); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail entry db commit"); - return; - } - - r = kee_ledger_serialize_open(&o->ledger, out, &out_len, KEE_LEDGER_STATE_RESPONSE); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); - return; - } - - r = kee_transport_single(&trans, KEE_TRANSPORT_BASE64, KEE_CMD_LEDGER, out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); - return; - } - - r = kee_transport_write(&trans, out, out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "write to qr transport renderer failed"); - return; - } - - r = kee_transport_next(&trans, out, &out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "read from qr transport renderer failed"); - return; - } - /// \todo verify that this frees the buffer - transport_data = g_variant_new_take_string(out); - - widget = gtk_widget_get_ancestor(GTK_WIDGET(o), GTK_TYPE_WINDOW); - win = GTK_WINDOW(widget); - gapp = gtk_window_get_application(win); - act = g_action_map_lookup_action(G_ACTION_MAP(gapp), "commit"); - g_action_activate(act, transport_data); -} - - -/// \todo analyze is travering ancestor better that including context in object? -static void kee_entry_handle_add(GtkButton *butt, KeeEntry *o) { - int r; - GtkWindow *win; - GtkWidget *widget; - GtkApplication *gapp; - GAction *act; - struct kee_ledger_item_t *item; - GtkEntryBuffer *buf; - char *b; - struct kee_transport_t trans; - char *out; - size_t out_len; - size_t c; - char passphrase_hash[DIGEST_LENGTH]; - GVariant *transport_data; - - buf = gtk_entry_get_buffer(o->form->uoa); - b = (char*)gtk_entry_buffer_get_text(buf); - strcpy(o->ledger.uoa, b); - - buf = gtk_entry_get_buffer(o->form->uoa_decimals); - b = (char*)gtk_entry_buffer_get_text(buf); - o->ledger.uoa_decimals = (char)atoi(b); - - item = kee_ledger_add_item(&o->ledger); - item->initiator = ALICE; - - buf = gtk_entry_get_buffer(o->form->item_form.alice_credit_delta); - b = (char*)gtk_entry_buffer_get_text(buf); - item->alice_credit_delta = atoi(b); - - buf = gtk_entry_get_buffer(o->form->item_form.alice_collateral_delta); - b = (char*)gtk_entry_buffer_get_text(buf); - item->alice_collateral_delta = atoi(b); - - buf = gtk_entry_get_buffer(o->form->bob_pubkey); - b = (char*)gtk_entry_buffer_get_text(buf); - //c = hex2bin(b, (unsigned char*)o->ledger.pubkey_bob); - c = h2b(b, (unsigned char*)o->ledger.pubkey_bob); - if (c == 0) { -// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "invalid counterparty public key data"); -// return; -// } else if (c != PUBKEY_LENGTH) { -// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "wrong size for counterparty public key"); -// return; - } - - o->state |= ENTRYSTATE_LOAD; - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "adding ledger entry"); - - out_len = 1024; - out = malloc(out_len); - if (out == NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "memory for item serialization buffer for qr transport fail"); - return; - } - - buf = gtk_entry_get_buffer(o->form->passphrase); - b = (char*)gtk_entry_buffer_get_text(buf); - gpg_store_digest(o->gpg, passphrase_hash, b); - - memcpy(o->ledger.pubkey_alice, o->gpg->public_key, PUBKEY_LENGTH); - r = kee_ledger_sign(&o->ledger, o->ledger.last_item, o->gpg, passphrase_hash); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail entry sign"); - return; - } - - r = kee_ledger_serialize_open(&o->ledger, out, &out_len, KEE_LEDGER_STATE_RESPONSE); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); - return; - } - - r = kee_transport_single(&trans, KEE_TRANSPORT_BASE64, KEE_CMD_LEDGER, out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "qr transport renderer failed"); - return; - } - - r = kee_transport_write(&trans, out, out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "write to qr transport renderer failed"); - return; - } - - r = kee_transport_next(&trans, out, &out_len); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "read from qr transport renderer failed"); - return; - } - /// \todo verify that this frees the buffer - transport_data = g_variant_new_take_string(out); - - widget = gtk_widget_get_ancestor(GTK_WIDGET(o), GTK_TYPE_WINDOW); - win = GTK_WINDOW(widget); - gapp = gtk_window_get_application(win); - act = g_action_map_lookup_action(G_ACTION_MAP(gapp), "qr"); - g_action_activate(act, transport_data); -} - -static void kee_entry_handle_item_select(GtkListView *view, guint i, void *v) { - debug_log(DEBUG_DEBUG, "entry item selected"); -} - -static void kee_entry_handle_item_setup(GtkListItemFactory* o, GtkListItem *item) { - GtkWidget *box; - - box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - gtk_list_item_set_child(item, box); -} - -static void kee_entry_handle_item_bind(GtkListItemFactory *o, GtkListItem *item) { - GtkWidget *box; - GtkWidget *box_item; - - debug_log(DEBUG_DEBUG, "handle item bind"); - - box = gtk_list_item_get_child(item); - box_item = gtk_list_item_get_item(item); - if (gtk_widget_get_parent(box_item) != NULL) { - return; - } - g_object_take_ref(G_OBJECT(box_item)); - gtk_box_append(GTK_BOX(box), box_item); -} - -/// \todo free reference to self from parent box necessary..? -static void kee_entry_dispose(GObject *o) { - debug_log(DEBUG_DEBUG, "disposing entry"); -} - -static void kee_entry_finalize(GObject *o) { - KeeEntry *entry = KEE_ENTRY(o); - - kee_ledger_free(&entry->ledger); - - kee_dn_free(&entry->bob_dn); - - if (entry->form != NULL) { - free(entry->form); - } - - debug_log(DEBUG_DEBUG, "tearing down entry"); - //G_OBJECT_CLASS(kee_entry_parent_class)->finalize(o); -} - static void kee_entry_class_init(KeeEntryClass *kls) { - GObjectClass *object_class = G_OBJECT_CLASS(kls); - object_class->finalize = kee_entry_finalize; - object_class->dispose = kee_entry_dispose; + //GObjectClass *object_class = G_OBJECT_CLASS(kls); } static void kee_entry_init(KeeEntry *o) { - o->state = 0; - o->resolver = NULL; - o->showing = NULL; - o->form = NULL; - o->display = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);; - o->edit = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); kee_ledger_init(&o->ledger); - kee_ledger_reset_cache(&o->ledger); -} - -static int kee_entry_apply_list_item_widget(KeeEntry *o) { - char mask; - - mask = ENTRYSTATE_LOAD; - if (!(o->state & mask)) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "entry must be loaded first"); - return -1; - } - mask |= ENTRYSTATE_SHORT; - if ((o->state & mask) == mask) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "entry already in short mode"); - return 0; - } - - sprintf(o->header, "%s [%s]\n%s (%s)\nalice: %d\nbob: %d", o->ledger.content.subject, o->ledger.uoa, o->bob_dn.cn, o->bob_dn.uid, o->ledger.cache->alice_credit_balance, o->ledger.cache->bob_credit_balance); - o->entry_list = gtk_label_new(o->header); - o->state |= ENTRYSTATE_SHORT; - o->state &= mask; - o->showing = o->entry_list; - return 1; -} - -/// \todo DRY with add entry -static int kee_entry_apply_summary_widget(KeeEntry *o) { - char b[1024]; - GtkWidget *widget; - KeeEntryItem *item; - - sprintf(b, "Ledger with %s", o->bob_dn.cn); - widget = gtk_label_new(b); - gtk_box_append(GTK_BOX(o->display), widget); - - item = kee_entry_item_new(o->db, &o->ledger, 0); - kee_entry_item_set(item, o->ledger.last_item); - kee_entry_item_set_resolver(item, o->resolver); - kee_entry_item_apply_summary_widget(item, GTK_BOX(o->display)); - - o->form = calloc(sizeof(struct kee_entry_form_t), 1); - /// \todo DRY - kee-key.c - widget = gtk_label_new("private key passphrase"); - gtk_box_append(GTK_BOX(o->display), widget); - widget = gtk_entry_new(); - o->form->passphrase = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(o->form->passphrase, GTK_INPUT_PURPOSE_PASSWORD); - gtk_box_append(GTK_BOX(o->display), widget); - - widget = gtk_button_new_with_label("confirm"); - gtk_box_append(GTK_BOX(o->display), widget); - g_signal_connect (widget, "clicked", G_CALLBACK(kee_entry_handle_confirm), o); - - return 1; -} - -static int kee_entry_apply_display_widget(KeeEntry *o) { - char mask; - - mask = ENTRYSTATE_SHORT | ENTRYSTATE_EDIT | ENTRYSTATE_CONFIRM; - if ((o->state & mask) == 0) { - return 0; - } - o->state &= ~mask; - o->showing = o->display; - return 1; -} - -/// \todo free form - why does it have to be heap? -static void kee_entry_setup_edit_widget(KeeEntry *o) { - GtkWidget *widget; - - if (o->form) { - return; - } - - o->form = calloc(sizeof(struct kee_entry_form_t), 1); - - widget = gtk_label_new("counterparty name"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->bob_name = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(o->form->bob_name, GTK_INPUT_PURPOSE_NAME); - gtk_box_append(GTK_BOX(o->edit), widget); - - widget = gtk_label_new("counterparty public key"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->bob_pubkey = GTK_ENTRY(widget); - gtk_entry_set_max_length(o->form->bob_pubkey, PUBKEY_LENGTH * 2); - gtk_box_append(GTK_BOX(o->edit), widget); - - widget = gtk_label_new("subject"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->subject = GTK_ENTRY(widget); - gtk_box_append(GTK_BOX(o->edit), widget); - - widget = gtk_label_new("unit of account"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->uoa = GTK_ENTRY(widget); - gtk_box_append(GTK_BOX(o->edit), widget); - - widget = gtk_label_new("unit decimals"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->uoa_decimals = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(o->form->uoa_decimals, GTK_INPUT_PURPOSE_DIGITS); - gtk_entry_set_max_length(o->form->uoa_decimals, 2); - gtk_box_append(GTK_BOX(o->edit), widget); - - kee_entry_item_apply_edit_widget(GTK_BOX(o->edit), &o->form->item_form, 1); - - /// \todo DRY - kee-key.c - widget = gtk_label_new("private key passphrase"); - gtk_box_append(GTK_BOX(o->edit), widget); - widget = gtk_entry_new(); - o->form->passphrase = GTK_ENTRY(widget); - gtk_entry_set_input_purpose(o->form->passphrase, GTK_INPUT_PURPOSE_PASSWORD); - gtk_box_append(GTK_BOX(o->edit), widget); - - widget = gtk_button_new_with_label("add"); - gtk_box_append(GTK_BOX(o->edit), widget); - g_signal_connect (widget, "clicked", G_CALLBACK(kee_entry_handle_add), o); -} - -static int kee_entry_apply_edit_widget(KeeEntry *o) { - kee_entry_setup_edit_widget(o); - o->showing = o->edit; - return 1; -} - -static void kee_entry_init_list_widget(KeeEntry *o) { - GtkSingleSelection *sel; - GtkListItemFactory *factory; - KeeEntryItemStore *model; - GtkWidget *view; - - factory = gtk_signal_list_item_factory_new(); - g_signal_connect(factory, "setup", G_CALLBACK(kee_entry_handle_item_setup), NULL); - g_signal_connect(factory, "bind", G_CALLBACK(kee_entry_handle_item_bind), NULL); - - model = kee_entry_item_store_new(o->db, &o->ledger, o->resolver); - sel = gtk_single_selection_new(G_LIST_MODEL(model)); - view = gtk_list_view_new(GTK_SELECTION_MODEL(sel), GTK_LIST_ITEM_FACTORY(factory)); - g_signal_connect(view, "activate", G_CALLBACK(kee_entry_handle_item_select), NULL); - gtk_box_append(GTK_BOX(o->display), GTK_WIDGET(view)); - -} -static int process_entry_ledger(KeeEntry *o) { - int r; - size_t key_len; - size_t last_value_length; - char mem[33 + 1024]; - char *last_key; - char *last_value = mem + 33; - - last_key = mem; - key_len = 33; - last_value_length = 1024; - - kee_content_resolve(&o->ledger.content, o->resolver); - - last_value_length = 2048; - *last_key = DbKeyDN; - memcpy(last_key+1, o->ledger.pubkey_bob, 32); - key_len = 32; - db_rewind(o->db); - r = db_next(o->db, DbKeyDN, &last_key, &key_len, &last_value, &last_value_length); - if (r == ERR_DB_NOMATCH) { - strcpy(last_value, "cn=johndoe"); - last_value_length = strlen(last_value); - } else if (r) { - return ERR_FAIL; - } - r = kee_dn_from_str(&o->bob_dn, last_value, last_value_length); - if (r) { - return ERR_FAIL; - } - db_rewind(o->db); - - last_value_length = 129; - strcpy(last_value, "uid="); - if (o->bob_dn.uid == NULL) { - b2h((unsigned char*)o->ledger.pubkey_bob, 32, (unsigned char*)last_value+4); - last_value_length = 65; - r = kee_dn_from_str(&o->bob_dn, last_value, last_value_length+4); - if (r) { - return ERR_FAIL; - } - } - - o->state = ENTRYSTATE_LOAD; - - kee_entry_init_list_widget(o); - - return ERR_OK; -} - -/// \todo returns 1 on success, investigate why and change if possible! -int kee_entry_modeswitch(KeeEntry *o, enum kee_entry_viewmode_e mode) { - int r; - - if (o->showing != NULL) { - gtk_widget_set_visible(o->showing, false); - gtk_box_remove(GTK_BOX(o), o->showing); - } - switch(mode) { - case KEE_ENTRY_VIEWMODE_SHORT: - r = kee_entry_apply_list_item_widget(o); - break; - case KEE_ENTRY_VIEWMODE_EDIT: - r = kee_entry_apply_edit_widget(o); - break; - case KEE_ENTRY_VIEWMODE_SIGN: - o->state |= ENTRYSTATE_CONFIRM; - r = kee_entry_apply_display_widget(o); - if (!r) { - return r; - } - r = kee_entry_apply_summary_widget(o); - break; - default: - r = kee_entry_apply_display_widget(o); - } - gtk_box_append(GTK_BOX(o), o->showing); - gtk_widget_set_visible(o->showing, true); - return r; -} - -KeeEntry* kee_entry_new(struct db_ctx *db) { - KeeEntry *o; - o = KEE_ENTRY(g_object_new(KEE_TYPE_ENTRY, "orientation", GTK_ORIENTATION_VERTICAL, NULL)); - o->db = db; - kee_dn_init(&o->bob_dn, 0); - return o; -} - -void kee_entry_set_resolver(KeeEntry *o, struct Cadiz *resolver) { - o->resolver = resolver; -} - -void kee_entry_set_signer(KeeEntry *o, struct gpg_store *gpg) { - o->gpg = gpg; -} - -/// \todo rename "from" to indicate not return new entry but apply on existing -int kee_entry_from_ledger(KeeEntry *o, struct kee_ledger_t *ledger) { - int r; - - memcpy(&o->ledger, ledger, sizeof(struct kee_ledger_t)); - r = process_entry_ledger(o); - if (r) { - return ERR_FAIL; - } - - memcpy(o->current_id, ledger->digest, DIGEST_LENGTH); - - return ERR_OK; -} - -int kee_entry_deserialize(KeeEntry *o, const char *data, size_t data_len) { - int r; - - - r = kee_ledger_parse(&o->ledger, data, data_len); - if (r) { - return ERR_FAIL; - } - - r = calculate_digest_algo(data, data_len, o->current_id, GCRY_MD_SHA512); - if (r) { - return ERR_DIGESTFAIL; - } - - r = process_entry_ledger(o); - if (r) { - return ERR_FAIL; - } - - return ERR_OK; } diff --git a/src/gtk/kee-import.c b/src/gtk/kee-import.c @@ -1,464 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> -#include <gst/gst.h> - -#include "kee-import.h" -#include "kee-menu.h" -//#include "kee-entry-list.h" -#include "kee-entry-store.h" -#include "camera.h" -#include "scan.h" -#include "err.h" -#include "transport.h" -#include "ledger.h" -#include "defs.h" -#include "debug.h" - - -typedef struct { -} KeeImportPrivate; - -struct _KeeImportClass { - GtkWidget parent_class; -}; - -struct _KeeImport { - GtkWidget parent; - char cmd_accept; - char cmd_count; - KeeMenu *win; - GListModel *camera_list; - struct kee_camera_devices camera_device; - struct kee_scanner scan; - GtkStack *stack; - GtkBox *viewbox; - GtkWidget *toggler_text; - GtkTextBuffer *import_content; -}; - -G_DEFINE_TYPE(KeeImport, kee_import, GTK_TYPE_BOX); - - -static GParamSpec *kee_props[KEE_N_IMPORT_PROPS] = {NULL,}; -static guint kee_sigs[KEE_N_IMPORT_SIGS] = {0,}; - -static void kee_import_set_property(GObject *oo, guint property_id, const GValue *value, GParamSpec *pspec) { - KeeImport *o = KEE_IMPORT(oo); - - switch((enum KEE_IMPORT_PROPS)property_id) { - case KEE_P_IMPORT_WIN: - o->win = g_value_get_object(value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(oo, property_id, pspec); - } - -} - -static void kee_import_class_init(KeeImportClass *kls) { - GObjectClass *o = G_OBJECT_CLASS(kls); - - kee_sigs[KEE_S_IMPORT_SCAN_CHANGE] = g_signal_newv("scan", - G_TYPE_FROM_CLASS(o), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - NULL, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0, - NULL - ); - - kee_sigs[KEE_S_IMPORT_DATA] = g_signal_new("data_available", - G_TYPE_FROM_CLASS(o), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_STRING - ); - - o->set_property = kee_import_set_property; - - kee_props[KEE_P_IMPORT_WIN] = g_param_spec_object( - "window", - "Window", - "Application window", - KEE_TYPE_MENU, - G_PARAM_WRITABLE); - - - g_object_class_install_properties(o, KEE_N_IMPORT_PROPS, kee_props); -} - -static void kee_import_init(KeeImport *o) { - o->camera_list = G_LIST_MODEL(g_list_store_new(GTK_TYPE_LABEL)); - kee_import_refresh(o); - memset(&o->scan, 0, sizeof(struct kee_scanner)); - o->stack = GTK_STACK(gtk_stack_new()); - o->viewbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_VERTICAL, 0)); - /// \todo remember to reset this - o->cmd_accept = 0xff; - o->import_content = gtk_text_buffer_new(NULL); -} - -static void kee_import_handle_camera_change(GtkDropDown *chooser, GParamSpec *spec, KeeImport *import) { - GtkLabel *label; - char *s; - - label = gtk_drop_down_get_selected_item(chooser); - s = g_object_get_data(G_OBJECT(label), "devpath"); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "dropdown changed: %s -> %s", spec->name, s); - - kee_import_scanchange(import, s); -} - -static void kee_import_handle_import_data_focus(KeeImport *o, const char *data, GtkStack *stack) { - gtk_widget_activate(o->toggler_text); -} - -//static void kee_import_handle_import_data_text(KeeImport *o, const char *data, GtkTextBuffer *buf) { -static void kee_import_handle_import_data_text(KeeImport *o, GString *v, GtkTextBuffer *buf) { - GAction *act; - GActionMap *am; - char *s; - - s = (char*)v->str; - //gtk_text_buffer_set_text(buf, data, strlen(data)); - /// \todo s is invalid on first run after compile - segfaults - probably string not taken - gtk_text_buffer_set_text(buf, s, strlen(s)); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "import data %s", s); - - am = G_ACTION_MAP(gtk_window_get_application(GTK_WINDOW(o->win))); - act = g_action_map_lookup_action(am, "import_data_accept"); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); - g_action_activate(act, NULL); -} -// -//static void accept_cmd(KeeImport *o, char cmd) { -// o->cmd_accept = cmd; -//} -// -//static int check_cmd(KeeImport *o, char cmd) { -// return 1; -//} - - -/// \todo too long, split up -static void kee_import_handle_import_data_accept(GtkActionable *actn, void *null, KeeImport *o) { - int r; - char *s; - size_t c; - struct kee_transport_t trans; - GtkTextIter start; - GtkTextIter end; - char b[1024]; - GVariant *v; - GAction *act; - - gtk_text_buffer_get_start_iter(o->import_content, &start); - gtk_text_buffer_get_end_iter(o->import_content, &end); - s = gtk_text_buffer_get_text(o->import_content, &start, &end, false); - - //s = (char*)v->str; - - //c = strlen(s) + 1; - c = strlen(s); - //r = kee_transport_import(&trans, KEE_TRANSPORT_BASE64, s, c); - r = kee_transport_single(&trans, KEE_TRANSPORT_BASE64, KEE_CMD_IMPORT, 0); - if (r) { - return; - } - - //r = kee_transport_read(&trans, b, &c); - r = kee_transport_write(&trans, s, c); - if (r) { - return; - } - - c = 1024; - r = kee_transport_read(&trans, b, &c); - if (r) { - return; - } - - switch(*trans.cmd) { - case KEE_CMD_LEDGER: - v = g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, b, c, 1); - act = g_action_map_lookup_action(G_ACTION_MAP(o->win), "ledger"); - g_action_activate(act, v); - break; - default: - r = ERR_FAIL; - } - - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "failed import"); - } else { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "accepted import"); - } -} - -//static void kee_import_handle_import_data_check(KeeImport *o, const char *data, GtkActionable *act) { -// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "checking import data"); -//} - - /// \todo this fires when unfocusing the import page and creates a warning because stack is not valid. -static void kee_import_handle_scan_select(GActionGroup *act, char *action_name, gpointer user_data, GtkStack *stack) { - GVariant *v; - const char *s; - - v = g_action_group_get_action_state(act, action_name); - s = g_variant_get_string(v, NULL); - gtk_stack_set_visible_child_name(stack, s); -} - -static GtkWidget* kee_import_build_scan_footer(KeeImport *import, GtkStack *stack) { - GtkWidget *foot; - GtkWidget *butt; - GtkToggleButton *butt_prev; - GActionGroup *ag; - GAction *act; - GVariant *v; - - foot = gtk_action_bar_new(); - - v = g_variant_new_string(""); - ag = G_ACTION_GROUP(g_simple_action_group_new()); - act = G_ACTION(g_simple_action_new_stateful("src", G_VARIANT_TYPE_STRING, v)); - g_action_map_add_action(G_ACTION_MAP(ag), act); - - v = g_variant_new_string(KEE_ACT_SCAN_QR); - butt = gtk_toggle_button_new(); - gtk_button_set_icon_name(GTK_BUTTON(butt), "insert-image"); - gtk_action_bar_pack_start(GTK_ACTION_BAR(foot), butt); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "import.src"); - gtk_actionable_set_action_target_value(GTK_ACTIONABLE(butt), v); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(butt), true); - - butt_prev = GTK_TOGGLE_BUTTON(butt); - v = g_variant_new_string(KEE_ACT_SCAN_TEXT); - butt = gtk_toggle_button_new(); - gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(butt), butt_prev); - gtk_button_set_icon_name(GTK_BUTTON(butt), "document-new"); - gtk_action_bar_pack_start(GTK_ACTION_BAR(foot), butt); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "import.src"); - gtk_actionable_set_action_target_value(GTK_ACTIONABLE(butt), v); - import->toggler_text = butt; - - butt_prev = GTK_TOGGLE_BUTTON(butt); - v = g_variant_new_string(KEE_ACT_SCAN_FILE); - butt = gtk_toggle_button_new(); - gtk_toggle_button_set_group(GTK_TOGGLE_BUTTON(butt), butt_prev); - gtk_button_set_icon_name(GTK_BUTTON(butt), "document-save"); - gtk_action_bar_pack_start(GTK_ACTION_BAR(foot), butt); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "import.src"); - gtk_actionable_set_action_target_value(GTK_ACTIONABLE(butt), v); - - g_signal_connect(ag, "action-state-changed", G_CALLBACK(kee_import_handle_scan_select), stack); - - gtk_widget_insert_action_group(foot, "import", ag); - - return foot; -} -static GtkWidget* kee_import_build_scan_videochooser(KeeImport *o) { - GtkWidget *chooser; - GtkExpression *exp_label; - - exp_label = gtk_property_expression_new(GTK_TYPE_LABEL, NULL, "label"); - - chooser = gtk_drop_down_new(o->camera_list, exp_label); - - g_signal_connect(chooser, "notify::selected-item", G_CALLBACK (kee_import_handle_camera_change), o); - return chooser; -} - -static GtkWidget* kee_import_build_import_text(KeeImport *o, GtkStack *stack) { - GtkWidget *box; - GtkTextView *txt; - GtkWidget *butt; - GAction *act; - GtkApplication *gapp; - GtkTextBuffer *buf; - - box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - - gapp = gtk_window_get_application(GTK_WINDOW(o->win)); - - //txt = GTK_TEXT_VIEW(gtk_text_view_new()); - txt = GTK_TEXT_VIEW(gtk_text_view_new_with_buffer(o->import_content)); - gtk_widget_set_vexpand(GTK_WIDGET(txt), true); - gtk_box_append(GTK_BOX(box), GTK_WIDGET(txt)); - - act = G_ACTION(g_simple_action_new("import_data_accept", NULL)); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); - g_action_map_add_action(G_ACTION_MAP(gapp), act); - - butt = gtk_button_new_with_label("import"); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "app.import_data_accept"); - gtk_box_append(GTK_BOX(box), butt); - - buf = gtk_text_view_get_buffer(txt); - g_signal_connect(o, "data_available", G_CALLBACK(kee_import_handle_import_data_text), buf); - //g_signal_connect(o, "data_available", G_CALLBACK(kee_import_handle_import_data_accept), stack); - g_signal_connect(o, "data_available", G_CALLBACK(kee_import_handle_import_data_focus), stack); - //g_signal_connect(o, "data_available", G_CALLBACK(kee_import_handle_import_data_check), butt); - //g_signal_connect(butt, "clicked", G_CALLBACK(kee_import_handle_import_data_accept), o); - g_signal_connect(act, "activate", G_CALLBACK(kee_import_handle_import_data_accept), o); - - return box; -} - -KeeImport* kee_import_new(KeeMenu *win) { - KeeImport *o; - GtkWidget *widget; - GtkWidget *chooser; - GValue v = G_VALUE_INIT; - - o = g_object_new(KEE_TYPE_IMPORT, "orientation", GTK_ORIENTATION_VERTICAL, NULL); - g_value_init(&v, G_TYPE_OBJECT); - g_value_set_object(&v, win); - g_object_set_property(G_OBJECT(o), "window", &v); - - gtk_box_append(GTK_BOX(o), GTK_WIDGET(o->stack)); - - widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10); - chooser = kee_import_build_scan_videochooser(o); - gtk_box_append(GTK_BOX(widget), chooser); - gtk_box_append(GTK_BOX(widget), GTK_WIDGET(o->viewbox)); - - gtk_stack_add_named(o->stack, widget, KEE_ACT_SCAN_QR); - - widget = kee_import_build_import_text(o, o->stack); - gtk_stack_add_named(o->stack, widget, KEE_ACT_SCAN_TEXT); - - gtk_stack_set_visible_child_name(o->stack, KEE_ACT_SCAN_QR); - - widget = kee_import_build_scan_footer(o, o->stack); - gtk_box_append(GTK_BOX(o), widget); - - return o; -} - -static void kee_import_scanadd(KeeImport *o, GtkLabel *label) { - g_list_store_append(G_LIST_STORE(o->camera_list), label); -} - -int kee_import_refresh(KeeImport *o) { - int r; - GtkWidget *label; - struct kee_camera_devices *p; - - p = &o->camera_device; - r = kee_camera_scan(p); - if (r) { - return ERR_FAIL; - } - - while(strcmp(p->path, "")) { - label = gtk_label_new(p->label); - g_object_set_data(G_OBJECT(label), "devpath", p->path); - kee_import_scanadd(o, GTK_LABEL(label)); - if (p->next == NULL) { - break; - } - p = p->next; - } - - return ERR_OK; -} - -static void kee_import_apply_viewfinder(KeeImport *o) { - GtkWidget *p; - - p = gtk_widget_get_first_child(GTK_WIDGET(o->viewbox)); - if (p) { - gtk_box_remove(GTK_BOX(o->viewbox), p); - } - - p = GTK_WIDGET(o->scan.video_view); - gtk_box_append(GTK_BOX(o->viewbox), p); - gtk_widget_set_visible(GTK_WIDGET(o), true); -} - -static gboolean kee_import_scan_code_handler(GstBus *bus, GstMessage *msg, gpointer user_data) { - GError *err; - gchar *debug_info; - GstState oldstate; - GstState newstate; - GstState pendingstate; - const gchar *src; - const gchar *code; - const GstStructure *strctr; - const GString *code_str; - KeeImport *import; - - import = KEE_IMPORT(user_data); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "scan msg got"); - - switch (GST_MESSAGE_TYPE (msg)) { - case GST_MESSAGE_ERROR: - gst_message_parse_error(msg, &err, &debug_info); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "logg %s: %s", GST_OBJECT_NAME(msg->src), err->message); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "debug %s", debug_info ? debug_info : "none"); - g_clear_error(&err); - g_free(debug_info); - break; - case GST_MESSAGE_EOS: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "eos"); - break; - case GST_MESSAGE_STATE_CHANGED: - gst_message_parse_state_changed(msg, &oldstate, &newstate, &pendingstate); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "state change: %s -> %s", gst_element_state_get_name(oldstate), gst_element_state_get_name(newstate)); - break; - case GST_MESSAGE_ELEMENT: - src = gst_object_get_name(msg->src); - if (strcmp(src, "zbar")) { - break; - } - strctr = gst_message_get_structure(msg); - /// \todo segfaults occasionally, find out how to persist the buffer across signal - code = gst_structure_get_string(strctr, "symbol"); - code_str = g_string_new((char*)code); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "message %s: %d (%s) - decoded: %s", src, msg->type, gst_message_type_get_name(msg->type), code); - g_signal_emit(import, kee_sigs[KEE_S_IMPORT_DATA], 0, code_str); - return false; - default: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "unhandled message (ext %d): %s", GST_MESSAGE_TYPE_IS_EXTENDED(msg), GST_MESSAGE_TYPE_NAME(msg)); - break; - } - - return true; -} - -int kee_import_scanchange(KeeImport *o, const char *device) { - if (!(strcmp(device, ""))) { - return ERR_FAIL; - } - - if (o->scan.pipeline) { - scan_free(&o->scan); - } - scan_init(&o->scan, device); - scan_begin(&o->scan); - - kee_import_apply_viewfinder(o); - - o->scan.bus = gst_element_get_bus(o->scan.pipeline); - gst_bus_add_watch(o->scan.bus, kee_import_scan_code_handler, o); - return ERR_OK; -} - -void kee_import_free(KeeImport *o) { - kee_camera_free(&o->camera_device); - scan_free(&o->scan); -} - -GtkStack* kee_import_get_stack(KeeImport *o) { - return o->stack; -} diff --git a/src/gtk/kee-import.h b/src/gtk/kee-import.h @@ -1,38 +0,0 @@ -#ifndef _GTK_KEE_IMPORT_H -#define _GTK_KEE_IMPORT_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-menu.h" - -G_BEGIN_DECLS - -#define KEE_TYPE_IMPORT kee_import_get_type() -G_DECLARE_FINAL_TYPE(KeeImport, kee_import, KEE, IMPORT, GtkBox) - -#define KEE_ACT_SCAN_QR "import_scan" -#define KEE_ACT_SCAN_FILE "import_file" -#define KEE_ACT_SCAN_TEXT "import_text" - - -enum KEE_IMPORT_PROPS { - KEE_P_IMPORT_WIN = 1, - KEE_N_IMPORT_PROPS, -}; - -enum KEE_IMPORT_SIGS { - KEE_S_IMPORT_SCAN_CHANGE, - KEE_S_IMPORT_DATA, - KEE_N_IMPORT_SIGS, -}; - -KeeImport* kee_import_new(KeeMenu *win); -int kee_import_refresh(KeeImport *im); -GListModel* kee_import_get_camera_list(KeeImport *o); -int kee_import_scanchange(KeeImport *o, const char *device); -GtkStack* kee_import_get_stack(KeeImport *o); - -G_END_DECLS - -#endif //_GTK_KEE_IMPORT_H diff --git a/src/gtk/kee-key.c b/src/gtk/kee-key.c @@ -1,96 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-key.h" -#include "gpg.h" -#include "err.h" -#include "hex.h" -#include "debug.h" - - -typedef struct { -} KeeKeyPrivate; - -struct _KeeKeyClass { - GtkWidget parent_class; -}; - -struct _KeeKey { - GtkWidget parent; - struct gpg_store *gpg; -}; - -G_DEFINE_TYPE(KeeKey, kee_key, GTK_TYPE_BOX); - -static guint kee_sigs[KEE_N_KEY_SIGS] = {0,}; - -static void kee_key_class_init(KeeKeyClass *kls) { - GObjectClass *o = G_OBJECT_CLASS(kls); - - kee_sigs[KEE_S_KEY_UNLOCKED] = g_signal_new("unlock", - G_TYPE_FROM_CLASS(o), - G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 0, - NULL); -} - -static void kee_key_init(KeeKey *o) { -} - -//static void kee_key_finalize(KeeKey *o) { -//} - -static void kee_key_handle_unlock_click(GtkWidget *button, KeeKey *o) { - int r; - GtkEntryBuffer *buf; - GValue v = G_VALUE_INIT; - char passphrase[1024]; - - g_value_init(&v, G_TYPE_POINTER); - buf = g_object_get_data(G_OBJECT(o), "passphrase"); - strcpy(passphrase, gtk_entry_buffer_get_text(buf)); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "click"); - - r = gpg_store_check(o->gpg, passphrase); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "wrong passphrase"); - return; - } - - g_signal_emit(o, kee_sigs[KEE_S_KEY_UNLOCKED], 0); - gtk_entry_buffer_delete_text(buf, 0, gtk_entry_buffer_get_length(buf)); -} - -KeeKey* kee_key_new(struct gpg_store *gpg) { - KeeKey *o; - GtkWidget *entry; - GtkWidget *button; - GtkEntryBuffer *buf; - - o = g_object_new(KEE_TYPE_KEY, "orientation", GTK_ORIENTATION_VERTICAL, NULL); - o->gpg = gpg; - - entry = gtk_entry_new(); - gtk_box_append(GTK_BOX(o), entry); - buf = gtk_entry_get_buffer(GTK_ENTRY(entry)); - gtk_entry_set_input_purpose(GTK_ENTRY(entry), GTK_INPUT_PURPOSE_PASSWORD); - gtk_entry_set_visibility(GTK_ENTRY(entry), false); - g_object_set_data(G_OBJECT(o), "passphrase", buf); - - button = gtk_button_new_with_label("create"); - gtk_box_append(GTK_BOX(o), button); - g_signal_connect (button, "clicked", G_CALLBACK (kee_key_handle_unlock_click), o); - - return o; -} - -const char *kee_key_get_fingerprint(KeeKey *o, char *fingerprint) { - b2h((unsigned char*)o->gpg->fingerprint, 20, (unsigned char*)fingerprint); - //strcpy(fingerprint, o->gpg->fingerprint); - return fingerprint; -} diff --git a/src/gtk/kee-key.h b/src/gtk/kee-key.h @@ -1,28 +0,0 @@ -#ifndef _GTK_KEE_KEY_H -#define _GTK_KEE_KEY_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "gpg.h" - -G_BEGIN_DECLS - -#define KEE_TYPE_KEY kee_key_get_type() -G_DECLARE_FINAL_TYPE(KeeKey, kee_key, KEE, KEY, GtkBox) - -enum KEE_KEY_PROPS { - KEE_N_KEY_PROPS, -}; - -enum KEE_KEY_SIGS { - KEE_S_KEY_UNLOCKED, - KEE_N_KEY_SIGS, -}; - -G_END_DECLS - -KeeKey* kee_key_new(struct gpg_store *gpg); -const char *kee_key_get_fingerprint(KeeKey *o, char *fingerprint); - -#endif // _GTK_KEE_KEY_H diff --git a/src/gtk/kee-menu.c b/src/gtk/kee-menu.c @@ -1,302 +0,0 @@ -#include <string.h> -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-menu.h" -#include "kee-entry.h" -#include "menu.h" -#include "nav.h" -#include "err.h" -#include "context.h" -#include "debug.h" - - -typedef struct { -} KeeMenuPrivate; - -struct _KeeMenu { - GtkApplicationWindow parent; - GtkHeaderBar *head; - GtkStack *stack; - //struct KeeNav nav; - struct kee_context *ctx; -}; - -struct _KeeMenuClass { - GtkApplicationWindowClass parent_class; -}; - -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, 0); -} - -static void kee_menu_act_import(GAction *act, GVariant *param, KeeMenu *menu) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "act import"); - //gtk_stack_set_visible_child_name(stack, "import"); - //kee_menu_next(menu, "import"); - kee_menu_next(menu, BEAMENU_DST_IMPORT); -} - -static void kee_menu_act_new_entry(GAction *act, GVariant *param, KeeMenu *menu) { - KeeEntry *o; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "act new entry"); - //gtk_stack_set_visible_child_name(stack, "import"); - //kee_menu_next(menu, "entry"); - kee_menu_next(menu, BEAMENU_DST_NEW); - - o = g_object_new(KEE_TYPE_ENTRY, "orientation", GTK_ORIENTATION_VERTICAL, NULL); - kee_entry_set_signer(o, &menu->ctx->gpg); - kee_menu_set(menu, GTK_WIDGET(o)); - kee_entry_modeswitch(o, KEE_ENTRY_VIEWMODE_EDIT); -} - -static void kee_menu_act_import_entry(GAction *act, GVariant *param, KeeMenu *menu) { - int r; - struct kee_ledger_t ledger; - const char *b; - enum kee_ledger_state_e item_state; - size_t c; - KeeEntry *entry; - - c = (size_t)g_variant_n_children(param); - b = (const char*)g_variant_get_data(param); - r = kee_ledger_parse_open(&ledger, &menu->ctx->gpg, b, c); - if (r) { - debug_log(DEBUG_WARNING, "failed ledger import"); - return; - } - - item_state = kee_ledger_item_state(ledger.last_item); - - switch (item_state) { - case KEE_LEDGER_STATE_FINAL: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "detected final state"); - r = kee_ledger_put(&ledger, &menu->ctx->db); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail put entry"); - return; - } - break; - case KEE_LEDGER_STATE_RESPONSE: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "detected response state"); - entry = kee_entry_new(&menu->ctx->db); - if (entry == NULL) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail create entry"); - return; - } - kee_entry_set_signer(entry, &menu->ctx->gpg); - kee_entry_set_resolver(entry, &menu->ctx->resolver); - r = kee_entry_from_ledger(entry, &ledger); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail load entry from ledger"); - return; - } - r = kee_entry_modeswitch(entry, KEE_ENTRY_VIEWMODE_SIGN); - if (!r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail set entry widget view mode"); - return; - } - //kee_menu_next(menu, "entry"); - kee_menu_next(menu, BEAMENU_DST_NEW); - r = kee_menu_set(menu, GTK_WIDGET(entry)); - if (r) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail replace menu entry content"); - return; - } - break; - case KEE_LEDGER_STATE_REQUEST: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "detected request state, ignoring"); - break; - default: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "invalid item state after parse"); - return; - } -} - -//static GParamSpec *kee_props[KEE_N_MENU_PROPS] = {NULL,}; -//static guint kee_sigs[KEE_N_MENU_SIGS] = {0,}; - -static void kee_menu_class_init(KeeMenuClass *kls) { -// GObjectClass *o = G_OBJECT_CLASS(kls); -} - -static void kee_menu_init(KeeMenu *o) { - //memset(&o->nav, 0, sizeof(struct KeeNav)); - //o->nav.c = 0; - //o->nav.widgets[0] = 0; - //o->nav.now = 0; - o->head = GTK_HEADER_BAR(gtk_header_bar_new()); - o->stack = GTK_STACK(gtk_stack_new()); -} - -KeeMenu* kee_menu_new(GtkApplication *gapp, struct kee_context *ctx) { - int r; - KeeMenu *o; - GtkWidget *butt; - GSimpleAction *act; - - 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; - gtk_widget_set_vexpand(GTK_WIDGET(o->stack), true); - - gapp = gtk_window_get_application(GTK_WINDOW(o)); - - butt = menu_button_setup(G_OBJECT(o->head), gapp); - gtk_header_bar_pack_end(GTK_HEADER_BAR(o->head), butt); - - act = g_simple_action_new("back", NULL); - g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); - g_simple_action_set_enabled(act, false); - butt = gtk_button_new_from_icon_name("go-previous"); - gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); - //gtk_widget_set_visible(butt, false); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.back"); - g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_back), o); - gtk_widget_set_tooltip_text(butt, "back"); - - act = g_simple_action_new("import", NULL); - g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); - g_simple_action_set_enabled(act, false); - butt = gtk_button_new_from_icon_name("insert-object"); - gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.import"); - g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_import), o); - - act = g_simple_action_new("new_entry", NULL); - g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); - g_simple_action_set_enabled(act, false); - butt = gtk_button_new_from_icon_name("document-new"); - gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); - gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.new_entry"); - g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_new_entry), o); - - act = g_simple_action_new("ledger", g_variant_type_new_array(G_VARIANT_TYPE_BYTE)); - g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_import_entry), o); - - gtk_window_set_titlebar(GTK_WINDOW(o), GTK_WIDGET(o->head)); - - gtk_window_set_title (GTK_WINDOW (o), "kee"); - gtk_window_set_default_size (GTK_WINDOW (o), 720, 1440); - - gtk_window_set_child(GTK_WINDOW(o), GTK_WIDGET(o->stack)); - - return o; -} - - -//static void kee_menu_header_update(KeeMenu *o, const char *label) { -static void kee_menu_header_update_explicit(KeeMenu *o, int menu_id) { - GAction *act; - - switch (menu_id) { - case BEAMENU_DST_KEY: - break; - case BEAMENU_DST_LIST: - act = g_action_map_lookup_action(G_ACTION_MAP(o), "import"); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); - act = g_action_map_lookup_action(G_ACTION_MAP(o), "back"); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), false); - act = g_action_map_lookup_action(G_ACTION_MAP(o), "new_entry"); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); - break; - case BEAMENU_DST_NEW: - act = g_action_map_lookup_action(G_ACTION_MAP(o), "back"); - g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); - case BEAMENU_DST_IMPORT: - break; - case BEAMENU_DST_TRANSPORT: - break; - default: - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "unknown nav label: %s", beamenu_dst_r[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; -} - -//GtkWidget* kee_menu_next(KeeMenu *o, const char *label) { -GtkWidget* kee_menu_next(KeeMenu *o, int menu_id) { - GtkWidget *widget; - char *label; - - label = beamenu_dst_r[menu_id]; - widget = gtk_stack_get_child_by_name(o->stack, label); - //kee_nav_push(&o->nav, widget); - 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); - return widget; -} - -int kee_menu_set(KeeMenu *o, GtkWidget *widget) { - GtkBox *container; - GtkWidget *widget_old; - - //container = GTK_BOX(o->nav.now); - container = GTK_BOX(KEE_NAV_NOW); - - widget_old = gtk_widget_get_first_child(GTK_WIDGET(container)); - if (widget_old) { - gtk_box_remove(container, widget_old); - } - gtk_box_append(container, widget); - return 0; -} - -int kee_menu_prev(KeeMenu *o, int force) { - GtkWidget *widget; - - 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); - - return ERR_OK; -} - -int kee_menu_peek(int ridx) { - return kee_nav_get_stack_idx(ridx+1); -} diff --git a/src/gtk/kee-menu.h b/src/gtk/kee-menu.h @@ -1,36 +0,0 @@ -#ifndef _GTK_KEE_MENU_H -#define _GTK_KEE_MENU_H - -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "beamenu_defs.h" -#include "context.h" - -/// \todo rename to kee-win - -enum KEE_MENU_PROPS { - KEE_N_MENU_PROPS, -}; - -enum KEE_MENU_SIGS { - KEE_N_MENU_CHANGE, - KEE_N_MENU_SIGS, -}; - -G_BEGIN_DECLS - -#define KEE_TYPE_MENU kee_menu_get_type() -G_DECLARE_FINAL_TYPE(KeeMenu, kee_menu, KEE, MENU, GtkApplicationWindow); - -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 force); -int kee_menu_set(KeeMenu *o, GtkWidget *widget); -int kee_menu_peek(int reverse_idx); - -G_END_DECLS - -#endif //_GTK_KEE_MENU_H diff --git a/src/gtk/kee-transport.c b/src/gtk/kee-transport.c @@ -1,147 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> -#include <gdk/gdk.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -#include "kee-transport.h" -#include "kee-menu.h" -#include "err.h" -#include "qr.h" -#include "debug.h" - - -typedef struct { -} KeeTransportPrivate; - -struct _KeeTransportClass { - GtkWidget parent_class; -}; - -struct _KeeTransport { - GtkWidget parent; - char *image_data; - size_t image_width; - size_t image_size; - GdkPixbuf *pixbuf; -}; - -G_DEFINE_TYPE(KeeTransport, kee_transport, GTK_TYPE_BOX); - -static void kee_transport_finalize(GObject *o) { - KeeTransport *trans = KEE_TRANSPORT(o); - free(trans->image_data); -} - -static void kee_transport_class_init(KeeTransportClass *kls) { - GObjectClass *object_class = G_OBJECT_CLASS(kls); - object_class->finalize = kee_transport_finalize; -} - -/// \todo >6MB at module size 7, later copied to gbytes. improve if possible. -static void kee_transport_init(KeeTransport *o) { - o->image_data = malloc(QR_IMAGE_SIZE); -} - -static void kee_transport_handle_continue(GAction *act, GVariant *v, KeeMenu *o) { - int menu_id; - debug_log(DEBUG_DEBUG, "continue"); - - menu_id = kee_menu_peek(1); - switch(menu_id) { - case BEAMENU_DST_NEW: - kee_menu_next(o, BEAMENU_DST_IMPORT); - break; - default: - debug_log(DEBUG_CRITICAL, "you should check in to see what condition my condition is in"); - } -} - -/// \todo find a way to modify underlying bytes and keep the stack from pixbuf to widget -static void kee_transport_render(KeeTransport *o, const gchar *mode) { - KeeMenu *menu; - GtkWidget *widget; - GdkTexture *texture; - GdkPixbuf *pixbuf; - GSimpleAction *act; - GBytes *bytes; - size_t width_bytes; - size_t width_pixels; - - width_pixels = o->image_width * QR_IMAGE_MODULE_SIZE; - width_bytes = width_pixels * QR_IMAGE_COMPONENTS; - - bytes = g_bytes_new(o->image_data, o->image_size); - pixbuf = gdk_pixbuf_new_from_bytes(bytes, GDK_COLORSPACE_RGB, false, QR_IMAGE_BIT_DEPTH, width_pixels, width_pixels, width_bytes); - texture = gdk_texture_new_for_pixbuf(pixbuf); - widget = gtk_widget_get_first_child(GTK_WIDGET(o)); - if (widget) { - gtk_box_remove(GTK_BOX(o), widget); - } - - widget = gtk_picture_new_for_paintable(GDK_PAINTABLE(texture)); - gtk_picture_set_content_fit(GTK_PICTURE(widget), GTK_CONTENT_FIT_SCALE_DOWN); - gtk_box_append(GTK_BOX(o), widget); - - widget = gtk_widget_get_ancestor(GTK_WIDGET(o), KEE_TYPE_MENU); - menu = KEE_MENU(widget); - - widget = gtk_button_new_with_label("continue"); - gtk_box_append(GTK_BOX(o), widget); - - act = g_simple_action_new("transport_continue", NULL); - gtk_actionable_set_action_name(GTK_ACTIONABLE(widget), "win.transport_continue"); - g_action_map_add_action(G_ACTION_MAP(menu), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(kee_transport_handle_continue), menu); - g_simple_action_set_enabled(act, true); - - kee_menu_next(menu, BEAMENU_DST_TRANSPORT); -} - -/// \todo share buffer with image data? -void kee_transport_handle_qr(GAction *act, GVariant *v, KeeTransport *o) { - char *p; - char *pp; - int i; - int ii; - int iii; - char r; - char *b; - char out[QR_CAP * QR_CAP]; - size_t width_pixels; - - b = (char*)g_variant_get_string(v, NULL); - if (b == NULL) { - return; - } - - o->image_width = QR_CAP * QR_CAP; - r = (char)qr_encode(b, out, &o->image_width); - if (r) { - return; - } - - // make rectangles in module size from qr data - p = o->image_data; - width_pixels = o->image_width * QR_IMAGE_COMPONENTS * QR_IMAGE_MODULE_SIZE; - for (i = 0; i < (int)(o->image_width * o->image_width); i++) { - if (i != 0 && i % o->image_width == 0) { - p += (width_pixels * (QR_IMAGE_MODULE_SIZE - 1)); - } - if (*(out+i) & 0x01) { - r = 0x00; - } else { - r = 0xff; - } - for (ii = 0; ii < QR_IMAGE_MODULE_SIZE * QR_IMAGE_COMPONENTS; ii++) { - *p = r; - pp = p; - for (iii = 0; iii < QR_IMAGE_MODULE_SIZE; iii++) { - pp += width_pixels; - *pp = r; - } - p++; - } - } - o->image_size = width_pixels * width_pixels; - kee_transport_render(o, g_action_get_name(act)); -} diff --git a/src/gtk/kee-transport.h b/src/gtk/kee-transport.h @@ -1,28 +0,0 @@ -#ifndef _GTK_KEE_TRANSPORT_H -#define _GTK_KEE_TRANSPORT_H - -#include "qr.h" - -#ifndef QR_IMAGE_MODULE_SIZE -#define QR_IMAGE_MODULE_SIZE 7 -#endif - -#define QR_IMAGE_COMPONENTS 3 -#define QR_IMAGE_BIT_DEPTH 8 -#define QR_IMAGE_WIDTH QR_CAP * QR_IMAGE_MODULE_SIZE -#define QR_IMAGE_SIZE (QR_IMAGE_WIDTH * QR_IMAGE_COMPONENTS) * (QR_IMAGE_WIDTH * QR_IMAGE_COMPONENTS) -#define QR_IMAGE_PIXELS QR_IMAGE_SIZE - -#include <glib-object.h> -#include <gtk/gtk.h> - -G_BEGIN_DECLS - -#define KEE_TYPE_TRANSPORT kee_transport_get_type() -G_DECLARE_FINAL_TYPE(KeeTransport, kee_transport, KEE, TRANSPORT, GtkBox); - -void kee_transport_handle_qr(GAction *Act, GVariant *v, KeeTransport *o); - -G_END_DECLS - -#endif //_GTK_KEE_TRANSPORT_H diff --git a/src/gtk/kee-uicontext.h b/src/gtk/kee-uicontext.h @@ -1,27 +0,0 @@ -#ifndef _GTK_KEE_UICONTEXT_H -#define _GTK_KEE_UICONTEXT_H - -#include <glib-object.h> - -#include "context.h" -#include "state.h" - -G_BEGIN_DECLS - -// -//enum KEE_SIGS { -// KEE_S_STATE_CHANGE, -// KEE_S_KEY_UNLOCKED, -// KEE_N_SIGS, -//}; - -#define KEE_TYPE_UICONTEXT kee_uicontext_get_type() -G_DECLARE_FINAL_TYPE(KeeUicontext, kee_uicontext, KEE, UICONTEXT, GObject) - -KeeUicontext* kee_uicontext_new(void); -kee_state_t kee_uicontext_state(KeeUicontext *o); -void kee_uicontext_unlock(KeeUicontext *o); - -G_END_DECLS - -#endif diff --git a/src/gtk/kee-win.c b/src/gtk/kee-win.c @@ -0,0 +1,34 @@ +#include <gtk/gtk.h> + +#include "kee-win.h" +#include "kee-context.h" + +typedef struct { +} KeeWinPrivate; + +struct _KeeWinClass { + GtkWidget parent_class; +}; + +struct _KeeWin { + GtkWidget parent; + struct kee_context *ctx; +}; + +G_DEFINE_TYPE(KeeWin, kee_win, GTK_TYPE_APPLICATION_WINDOW); + +static void kee_win_class_init(KeeWinClass *kls) { +// GObjectClass *object_class = G_OBJECT_CLASS(kls); +} + +static void kee_win_init(KeeWin *o) { +} + +KeeWin* kee_win_new(GtkApplication *gapp, struct kee_context *ctx) { + KeeWin *o; + + o = KEE_WIN(gtk_application_window_new(gapp)); + o->ctx = ctx; + + return o; +} diff --git a/src/gtk/kee-win.h b/src/gtk/kee-win.h @@ -0,0 +1,16 @@ +#ifndef _GTK_KEE_WIN_H +#define _GTK_KEE_WIN_H + +#include <gtk/gtk.h> + +#include "kee-context.h" + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(KeeWin, kee_win, KEE, WIN, GtkApplicationWindow); + +KeeWin* kee_win_new(GtkApplication *gapp, struct kee_context *ctx); + +G_END_DECLS + +#endif //_GTK_KEE_WIN_H diff --git a/src/gtk/kee.gresource.xml b/src/gtk/kee.gresource.xml @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<gresources> - <gresource prefix="/org/defalsify/Kee"> - <file preprocess="xml-stripblanks">main.ui</file> - </gresource> -</gresources> diff --git a/src/gtk/main.c b/src/gtk/main.c @@ -3,30 +3,23 @@ #include <glib-object.h> #include <gst/gst.h> -#include "ui.h" +//#include "ui.h" //#include "menu.h" #include "settings.h" -#include "context.h" +#include "kee-context.h" #include "kee-entry-store.h" #include "cadir.h" +#include "kee-win.h" -//static void state_log(KeeUicontext *uctx, char state_hint, kee_state_t *new_state, kee_state_t *old_state) { -// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "new state hint: %d", state_hint); -//} - static void startup(GtkApplication *app, struct kee_context *ctx) { -// kee_uicontext_scaninit(uctx); } -//static void activate(GtkApplication *app, KeeEntryStore *store) { //struct kee_context *ctx) { static void activate(GtkApplication *app, struct kee_context *ctx) { - //ui_build(app, store); - ui_build(app, ctx); + kee_win_new(app, ctx); } -static void deactivate(GtkApplication *app, gpointer user_data) { - //g_object_unref(user_data); +static void deactivate(GtkApplication *app, struct kee_context *ctx) { } int main(int argc, char **argv) { @@ -53,8 +46,7 @@ int main(int argc, char **argv) { g_signal_connect (gapp, "startup", G_CALLBACK (startup), &ctx); g_signal_connect (gapp, "activate", G_CALLBACK (activate), &ctx); - g_signal_connect (gapp, "shutdown", G_CALLBACK (deactivate), NULL); - //g_signal_connect (uctx, "state", G_CALLBACK(state_log), NULL); + g_signal_connect (gapp, "shutdown", G_CALLBACK (deactivate), &ctx); r = g_application_run (G_APPLICATION (gapp), argc, argv); diff --git a/src/gtk/menu.c b/src/gtk/menu.c @@ -1,47 +0,0 @@ -#include <glib-object.h> -#include <gtk/gtk.h> - -#include "kee-menu.h" -#include "scan.h" -#include "context.h" -#include "state.h" -#include "menu.h" -#include "debug.h" - - -static void act_quit(GAction *act, GVariant *param, GApplication *gapp) { - g_application_quit(gapp); -} - - -//static void menu_handle_state(KeeUicontext *uctx, char state_hint, kee_state_t *new_state, kee_state_t *old_state, GObject *head) { -//} - - -GtkWidget* menu_button_setup(GObject *head, GtkApplication *gapp) { - GMenu *menu; - GMenuItem *menu_item; - GtkWidget *butt; - GSimpleAction *act; - - menu = g_menu_new(); - menu_item = g_menu_item_new("Import", "app.import"); - g_menu_append_item(menu, menu_item); - g_object_unref(menu_item); - - menu_item = g_menu_item_new("Quit", "app.quit"); - g_menu_append_item(menu, menu_item); - g_object_unref(menu_item); - - 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), gapp); - - 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"); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "set up menus"); - return butt; -} diff --git a/src/gtk/menu.h b/src/gtk/menu.h @@ -1,12 +0,0 @@ -#ifndef _KEE_GTK_MENU_H -#define _KEE_GTK_MENU_H - -#define KEE_W_HEADER "header" -#define KEE_W_FOOTER "footer" - -#define KEE_W_UI_MENU_QUICK_ADD "quick_add" -#define KEE_W_UI_MENU_ACT_IMPORT "act_import" - -GtkWidget* menu_button_setup(GObject *head, GtkApplication *gapp); - -#endif // _KEE_GTK_MENU_H diff --git a/src/gtk/nav.c b/src/gtk/nav.c @@ -1,119 +0,0 @@ -#include <string.h> - -#include <gtk/gtk.h> -#include <beamenu.h> - -#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; - char fullpath[1024]; - - p = stpcpy(fullpath, path); - if (*(p-1) != '/') { - *p = '/'; - p++; - } - p = strcpy(p, "beamenu.dat"); - - stack_crsr = 0; - return beamenu_load_file(fullpath, 1); -} - -int kee_nav_set(GtkWidget *widget, int menu_id) { - char s[256]; - - if (widgets[menu_id]) { - return 1; - } - widgets[menu_id] = widget; - beamenu_jump(menu_id); - stack[stack_crsr] = menu_id; - stack_crsr++; - sprintf(s, "set nav menu_id %d (%s)", menu_id, beamenu_dst_r[menu_id]); - debug_log(DEBUG_INFO, s); - return 0; -} - -int kee_nav_unset(int menu_id) { - if (widgets[menu_id] == NULL) { - return 1; - } - widgets[menu_id] = 0x0; - return 0; -} - -GtkWidget* kee_nav_back(int force) { - char s[64]; - GtkWidget *widget; - int r; - - if (stack_crsr == 0) { - return NULL; - } - - r = beamenu_use_exit(KEE_NAV_EXIT_BACK); - if (r < 0) { - 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_WARNING, "menu stack underrun"); - return NULL; - } - r = stack[stack_crsr-1]; - kee_nav_unset(r); - stack_crsr--; - r = stack[stack_crsr-1]; - sprintf(s, "back nav menu_id %d (%s)", r, beamenu_dst_r[r]); - debug_log(DEBUG_INFO, s); - } - - if (widgets[r] == NULL) { - debug_log(DEBUG_WARNING, "no widget found"); - return NULL; - } - widget = widgets[r]; - 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_stack_idx(int idx) { - return stack[stack_crsr-idx]; -} - -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 @@ -1,32 +0,0 @@ -#ifndef _KEE_NAV_H -#define _KEE_NAV_H - -#include <gtk/gtk.h> - -#include <beamenu_defs.h> - -#define KEE_NAV_NOW kee_nav_get() -#define KEE_NAV_LABEL kee_nav_get_label() -#define KEE_NAV_IDX kee_nav_get_idx() - -#ifndef KEE_NAV_N_DST -#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); -int kee_nav_unset(int idx); -GtkWidget* kee_nav_get(); -int kee_nav_get_stack_idx(int idx); -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/scan.c b/src/gtk/scan.c @@ -1,119 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <gtk/gtk.h> -#include <gst/gst.h> - -#include "debug.h" -#include "scan.h" - - -void scan_init(struct kee_scanner *scan, const char *device) { - memset(scan, 0, sizeof(struct kee_scanner)); - scan->device = malloc(strlen(device) + 1); - strcpy(scan->device, device); -} - -/// \todo determine caps from environment -int scan_begin(struct kee_scanner *scan) { - GstElement *tee; - GstElement *zbar; - GstElement *queue_display; - GstElement *queue_scan; - GstPad *queue_display_pad; - GstPad *queue_scan_pad; - GstPad *tee_display; - GstPad *tee_scan; - GstStateChangeReturn rsc; - GstElement *convert_display; - GstElement *convert_scan; - GstElement *filter; - GstElement *devnull; - GstCaps *caps; - GdkPaintable *img; - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "starting scan with video device %s", scan->device); - - scan->pipeline = gst_pipeline_new("webcam-zbar"); - scan->source = gst_element_factory_make("v4l2src", "v4l2src"); - filter = gst_element_factory_make("capsfilter", "capsfilter"); - convert_display = gst_element_factory_make("videoconvert", "videoconvert_display"); - convert_scan = gst_element_factory_make("videoconvert", "videoconvert_scan"); - scan->video_sink = gst_element_factory_make("gtk4paintablesink", "gtk4paintablesink"); - tee = gst_element_factory_make("tee", "split-view-zbar"); - zbar = gst_element_factory_make("zbar", "zbar"); - devnull = gst_element_factory_make("fakesink", "fakesink"); - queue_display = gst_element_factory_make("queue", "queue-display"); - queue_scan = gst_element_factory_make("queue", "queue-scan"); - - caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "RGB", "width", G_TYPE_INT, 640, "height", G_TYPE_INT, 360, "framerate", GST_TYPE_FRACTION, 30, 1, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); - g_object_set(G_OBJECT(filter), "caps", caps, NULL); - - gst_bin_add_many(GST_BIN(scan->pipeline), scan->source, scan->video_sink, convert_display, convert_scan, filter, tee, zbar, queue_display, queue_scan, devnull, NULL); - if (gst_element_link_many(scan->source, tee, NULL) != TRUE) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail link src to muxer"); - gst_object_unref(scan->pipeline); - return 1; - } - - if (gst_element_link_many(queue_display, convert_display, filter, scan->video_sink, NULL) != TRUE) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail link muxer to display"); - gst_object_unref(scan->pipeline); - return 1; - } - - if (gst_element_link_many(queue_scan, convert_scan, zbar, devnull, NULL) != TRUE) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail link muxer to scanner"); - gst_object_unref(scan->pipeline); - return 1; - } - - tee_display = gst_element_request_pad_simple(tee, "src_%u"); - queue_display_pad = gst_element_get_static_pad(queue_display, "sink"); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "display queue linked with %s", gst_pad_get_name(tee_display)); - tee_scan = gst_element_request_pad_simple(tee, "src_%u"); - queue_scan_pad = gst_element_get_static_pad(queue_scan, "sink"); - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "scan queue linked with %s", gst_pad_get_name(tee_scan)); - - g_object_set(G_OBJECT(scan->source), "device", scan->device, NULL); - g_object_get(scan->video_sink, "paintable", &img, NULL); - if (!img) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "failed getting paintable"); - return 1; - } - scan->video_view = GTK_PICTURE(gtk_picture_new_for_paintable(img)); - gtk_picture_set_content_fit(scan->video_view, GTK_CONTENT_FIT_CONTAIN); - - if (gst_pad_link(tee_display, queue_display_pad) != GST_PAD_LINK_OK) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "mux link fail for display"); - gst_object_unref(scan->pipeline); - return 1; - } - - if (gst_pad_link(tee_scan, queue_scan_pad) != GST_PAD_LINK_OK) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "mux link fail for scan"); - gst_object_unref(scan->pipeline); - return 1; - } - - g_object_unref(queue_display_pad); - g_object_unref(queue_scan_pad); - - rsc = gst_element_set_state(scan->pipeline, GST_STATE_PLAYING); - if (rsc == GST_STATE_CHANGE_FAILURE) { - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "fail set pipeline to pause"); - gst_object_unref(scan->pipeline); - return 1; - } - - return ERR_OK; -} - -void scan_free(struct kee_scanner *scan) { - if (scan->bus) { - gst_object_unref(scan->bus); - } - gst_element_set_state(scan->pipeline, GST_STATE_NULL); - gst_object_unref(scan->pipeline); - free(scan->device); -} - diff --git a/src/gtk/scan.h b/src/gtk/scan.h @@ -1,24 +0,0 @@ -#ifndef _KEE_GTK_SCAN_H -#define _KEE_GTK_SCAN_H - -#include <gst/gst.h> -#include <gtk/gtk.h> - - -struct kee_scanner { - GtkPicture *video_view; - GstElement *pipeline; - GstElement *source; - GstElement *video_sink; - GtkImage *snap; - GstBus *bus; - char *device; -}; - -void scan_init(struct kee_scanner *scan, const char *device); -int scan_begin(struct kee_scanner *scan); -void scan_free(struct kee_scanner *scan); -void scan_set_handler(struct kee_scanner *scan, gboolean(*fn)(GstBus *bus, GstMessage *msg, gpointer user_data)); -//void scan_act(GSimpleAction *act, GVariant *param, KeeUicontext *ui); - -#endif // _KEE_GTK_SCAN_H diff --git a/src/gtk/tests/Makefile b/src/gtk/tests/Makefile @@ -1,24 +0,0 @@ -# TODO: test files are only generated on second run - -OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) -LINKOBJS := $(wildcard ../../*.o) $(wildcard ../*.o) -INCLUDES := -I../.. -I.. -CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0 libqrencode` $(INCLUDES) -Wall -#LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lvarint -lcmime -llash -LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0 libqrencode` -L../../aux/lib -lb64 -lcmime -llash -ltasn1 -lldap -LDFLAGS += $(LIBS) -#AUXLIBS := `pkg-config --libs kee` - -all: $(OBJS) - -%.o: %.c -# $(CC) $(CFLAGS) $< -o test_$* $(LINKOBJS) $(LDFLAGS) $(AUXLIBS) - $(CC) $(CFLAGS) $< -o test_$* $(LINKOBJS) $(LDFLAGS) ../../aux/beamenu/beamenu.o ../../aux/beamenu/import.o - -test_run: $(wildcard test_*) - ./$< - -test: all test_run - -clean: - rm -vf test_* diff --git a/src/gtk/tests/nav.c b/src/gtk/tests/nav.c @@ -1,82 +0,0 @@ -#include <gtk/gtk.h> - -#include "nav.h" - - -int test_stack() { - //struct KeeNav nav; - int r; - GtkWidget *a; - GtkWidget *b; - GtkWidget *c; - GtkWidget *o; - - gtk_init(); - a = gtk_label_new("foo"); - b = gtk_label_new("bar"); - c = gtk_label_new("baz"); - - r = kee_nav_init(".."); - if (r) { - return 1; - } - r = kee_nav_set(a, 0); - if (r) { - return 1; - } - o = kee_nav_get(); - if (!o) { - return 1; - } - r = kee_nav_set(b, 1); - if (r) { - return 1; - } - o = kee_nav_get(); - if (!o) { - return 1; - } - o = kee_nav_back(1); - if (o != a) { - return 1; - } - kee_nav_set(b, 1); - o = kee_nav_back(1); - if (o != a) { - return 1; - } - - o = kee_nav_back(1); - if (o) { - return 1; - } - - kee_nav_set(c, 2); - o = kee_nav_back(1); - if (o == NULL) { - return 1; - } - - o = kee_nav_back(1); - if (o) { - return 1; - } - - o = kee_nav_back(1); - if (o) { - return 1; - } - - return 0; -} - -int main(int argc, char **argv) { - int r; - - r = test_stack(); - if (r) { - return 1; - } - - return 0; -} diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -1,140 +0,0 @@ -#include <string.h> - -#include <gtk/gtk.h> -#include <gst/gst.h> - -#include "ui.h" -#include "err.h" -#include "scan.h" -#include "settings.h" -#include "context.h" -#include "state.h" -//#include "view.h" -#include "menu.h" -#include "kee-import.h" -#include "kee-entry-list.h" -#include "kee-entry-store.h" -#include "kee-menu.h" -#include "kee-key.h" -#include "kee-transport.h" -#include "transport.h" -#include "debug.h" - - -static void ui_handle_unlock(KeeKey *o, KeeMenu *menu) { - kee_state_t state_delta; - char fingerprint[41]; - - kee_state_zero(&state_delta); - kee_key_get_fingerprint(o, fingerprint); - gtk_window_set_title(GTK_WINDOW(menu), fingerprint); - - g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "key is unlocked"); - kee_menu_prev(menu, 1); -} - -//static void ui_handle_import(KeeImport *import, GString *v, KeeMenu *menu) { -// //GtkWidget *widget; -// int r; -// struct kee_transport_t trans; -// char *s; -// -// s = (char*)v->str; -// r = kee_transport_import(&trans, KEE_TRANSPORT_BASE64, s, strlen(s) + 1); -// if (r) { -// debug_log(DEBUG_INFO, "invalid input for transport"); -// return; -// } -// //kee_transport_read(&trans); -// -// //switch(kee_transport_cmd(&trans)) { -// // case KEE_CMD_DELTA: -// // widget = kee_menu_next("item"); -// //} -// -//} - -//static GtkWidget* ui_build_view(KeeMenu *menu) { -// GtkListItemFactory *factory; -// GtkSelectionModel *sel; -// GListModel *front_list; -// GtkListView *front_view; -// -// factory = gtk_signal_list_item_factory_new(); -// g_signal_connect(factory, "setup", G_CALLBACK(new_item), NULL); -// -// front_list = G_LIST_MODEL(gtk_string_list_new(NULL)); -// -// sel = GTK_SELECTION_MODEL(gtk_single_selection_new(front_list)); -// front_view = GTK_LIST_VIEW(gtk_list_view_new(GTK_SELECTION_MODEL(sel), factory)); -// -// return GTK_WIDGET(front_view); -//} - - -void ui_build(GtkApplication *gapp, struct kee_context *ctx) { - KeeTransport *trans; - GSimpleAction *act; - GtkWidget *widget; - KeeMenu *win; - 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); - kee_menu_add(win, beamenu_dst_r[BEAMENU_DST_KEY], widget); - g_signal_connect (widget, "unlock", G_CALLBACK(ui_handle_unlock), win); - - widget = kee_entry_list_new(G_LIST_MODEL(ctx->entry_store), win); - //kee_menu_add(win, "view", widget); - kee_menu_add(win, beamenu_dst_r[BEAMENU_DST_LIST], widget); - - //kee_menu_next(win, "view"); - kee_menu_next(win, BEAMENU_DST_LIST); - kee_menu_next(win, BEAMENU_DST_KEY); - - import = kee_import_new(win); - //kee_menu_add(win, "import", GTK_WIDGET(import)); - kee_menu_add(win, beamenu_dst_r[BEAMENU_DST_IMPORT], GTK_WIDGET(import)); - //g_signal_connect(import, "data_available", G_CALLBACK(ui_handle_import), win); - - widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); - //kee_menu_add(win, "entry", widget); - kee_menu_add(win, beamenu_dst_r[BEAMENU_DST_NEW], widget); - - trans = g_object_new(KEE_TYPE_TRANSPORT, "orientation", GTK_ORIENTATION_VERTICAL, NULL); - //kee_menu_add(win, "transport", GTK_WIDGET(trans)); - kee_menu_add(win, beamenu_dst_r[BEAMENU_DST_TRANSPORT], GTK_WIDGET(trans)); - - /// \todo make kee-entry action map/group? - act = g_simple_action_new("qr", G_VARIANT_TYPE_STRING); - g_action_map_add_action(G_ACTION_MAP(gapp), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(kee_transport_handle_qr), trans); - - act = g_simple_action_new("commit", G_VARIANT_TYPE_STRING); - g_action_map_add_action(G_ACTION_MAP(gapp), G_ACTION(act)); - g_signal_connect(act, "activate", G_CALLBACK(kee_transport_handle_qr), trans); - - gtk_window_present(GTK_WINDOW (win)); -} - -//void ui_build_from_resource(GtkApplication *app, struct ui_container *ui) { -// GtkBuilder *build; -// GtkWidget *unlock; -// -// build = gtk_builder_new_from_resource("/org/defalsify/Kee/main.ui"); -// //ui->view = GTK_WINDOW(gtk_builder_get_object(build, "keechoose")); -// unlock = GTK_WINDOW(gtk_builder_get_object(build, "keeunlock")); -// if (!unlock) { -// g_log(G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, "unlock widget could not load"); -// } -// -// ui->win = GTK_APPLICATION_WINDOW(gtk_application_window_new (app)); -// gtk_window_set_child(GTK_WINDOW(ui->win), GTK_WIDGET(unlock)); -// -// gtk_window_present(GTK_WINDOW (ui->win)); -//} diff --git a/src/gtk/ui.h b/src/gtk/ui.h @@ -1,13 +0,0 @@ -#ifndef _UI_H -#define _UI_H - -#include <gtk/gtk.h> -#include "context.h" -//#include "kee-entry-store.h" - - -//void ui_build(GtkApplication *app, KeeUicontext *uctx); -void ui_build(GtkApplication *app, struct kee_context *ctx); -//void ui_build(GtkApplication *app, KeeEntryStore *store); - -#endif // _UI_H