From 63a2fe4d4034a0cb85b46512863b9d7af9cd466f Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Mon, 2 Dec 2019 10:32:29 -0300 Subject: [PATCH] Loading accelerators from keyfile. Fixing memory leaks. --- src/include/v3270/actions.h | 1 + src/terminal/keyboard/accelerator.c | 22 +++++++++++++++++++++- src/terminal/keyboard/keyfile.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/terminal/keyboard/private.h | 3 ++- src/terminal/keyfile.c | 5 ++++- src/terminal/properties/get.c | 4 +++- src/testprogram/testprogram.c | 7 +++++-- 7 files changed, 127 insertions(+), 6 deletions(-) diff --git a/src/include/v3270/actions.h b/src/include/v3270/actions.h index c3be7e2..0be25dd 100644 --- a/src/include/v3270/actions.h +++ b/src/include/v3270/actions.h @@ -85,6 +85,7 @@ LIB3270_EXPORT void v3270_accelerator_map_reset(GtkWidget *widget); LIB3270_EXPORT void v3270_accelerator_map_foreach(GtkWidget *widget,void (*call)(const V3270Accelerator * accel, const char *keys, gpointer ptr), gpointer ptr); LIB3270_EXPORT void v3270_accelerator_map_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name); + LIB3270_EXPORT gboolean v3270_accelerator_map_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name); LIB3270_EXPORT V3270Accelerator * v3270_accelerator_map_add_entry(GtkWidget *widget, const gchar *name, guint accel_key, GdkModifierType accel_mods, GCallback callback, gpointer data); LIB3270_EXPORT const V3270Accelerator * v3270_get_accelerator(GtkWidget *widget, guint keyval, GdkModifierType state); diff --git a/src/terminal/keyboard/accelerator.c b/src/terminal/keyboard/accelerator.c index edddde1..c7d7669 100644 --- a/src/terminal/keyboard/accelerator.c +++ b/src/terminal/keyboard/accelerator.c @@ -43,6 +43,26 @@ return a->arg - b->arg; } + V3270Accelerator * v3270_accelerator_copy(const V3270Accelerator *accel) + { + V3270Accelerator * rc = NULL; + + if(accel->type == V3270_ACCELERATOR_TYPE_CUSTOM) + { + V3270CustomAccelerator * customAccel = g_new0(V3270CustomAccelerator,1); + *customAccel = *((V3270CustomAccelerator *) accel); + rc = (V3270Accelerator *) customAccel; + } + else + { + rc = g_new0(V3270Accelerator,1); + *rc = *accel; + } + + return rc; + } + + void v3270_accelerator_map_reset(GtkWidget *widget) { v3270 * terminal = GTK_V3270(widget); @@ -166,7 +186,7 @@ } - g_string_free(str,FALSE); + g_string_free(str,TRUE); } diff --git a/src/terminal/keyboard/keyfile.c b/src/terminal/keyboard/keyfile.c index 3be1c59..e630e82 100644 --- a/src/terminal/keyboard/keyfile.c +++ b/src/terminal/keyboard/keyfile.c @@ -29,6 +29,7 @@ #include #include + #include #include "private.h" //#include @@ -66,3 +67,93 @@ v3270_accelerator_map_foreach(GTK_WIDGET(widget),save_accelerator,&args); } + + void v3270_accelerator_map_set_entry(v3270 *terminal, const gchar *name, const gchar *keys) + { + V3270Accelerator * accel = NULL; + + // Find accelerator by name + { + GSList * ix = terminal->accelerators; + + while(ix) + { + const gchar *accel_name = v3270_accelerator_get_name((V3270Accelerator *) ix->data); + + if(accel_name && !g_ascii_strcasecmp(accel_name,name)) + { + // It's the same name, steal it. + if(!accel) + accel = (V3270Accelerator *) ix->data; + else + g_free(ix->data); + + terminal->accelerators = g_slist_remove_link(terminal->accelerators, ix); + ix = terminal->accelerators; + + } + else + { + // Not the same name, get the next one. + ix = g_slist_next(ix); + } + } + + } + + if(!accel) + { + debug("Can't find accelerator \"%s\"",name); + g_warning("Can't find accelerator \"%s\"",name); + return; + } + + debug("Recreating accelerators for action \"%s\"",v3270_accelerator_get_name(accel)); + + { + size_t ix; + gchar ** keycodes = g_strsplit(keys,",",-1); + + for(ix=0;keycodes[ix];ix++) + { + V3270Accelerator * acc = v3270_accelerator_copy(accel); + gtk_accelerator_parse(keycodes[ix],&acc->key,&acc->mods); + terminal->accelerators = g_slist_prepend(terminal->accelerators,acc); + } + + g_strfreev(keycodes); + } + + g_free(accel); + } + + gboolean v3270_accelerator_map_load_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name) + { + g_return_val_if_fail(GTK_IS_V3270(widget),FALSE); + + if(!group_name) + group_name = "accelerators"; + + v3270 * terminal = GTK_V3270(widget); + + gchar **keys = g_key_file_get_keys(key_file,group_name,NULL,NULL); + + if(!keys) + return FALSE; + + size_t ix; + for(ix = 0; keys[ix]; ix++) + { + g_autofree gchar * value = g_key_file_get_string(key_file, group_name, keys[ix],NULL); + + if(value) + v3270_accelerator_map_set_entry(terminal,keys[ix],value); + + } + + g_strfreev(keys); + + v3270_accelerator_map_sort(terminal); + + return TRUE; + } diff --git a/src/terminal/keyboard/private.h b/src/terminal/keyboard/private.h index 979c6bf..1acd3a9 100644 --- a/src/terminal/keyboard/private.h +++ b/src/terminal/keyboard/private.h @@ -32,6 +32,7 @@ #include #include - G_GNUC_INTERNAL void v3270_accelerator_map_sort(v3270 *widget); + G_GNUC_INTERNAL void v3270_accelerator_map_sort(v3270 *widget); + G_GNUC_INTERNAL V3270Accelerator * v3270_accelerator_copy(const V3270Accelerator *accel); diff --git a/src/terminal/keyfile.c b/src/terminal/keyfile.c index db60105..f037658 100644 --- a/src/terminal/keyfile.c +++ b/src/terminal/keyfile.c @@ -195,7 +195,7 @@ switch(pspec->value_type) { case G_TYPE_STRING: - g_value_set_string(&value, g_key_file_get_string(key_file,group_name,name,NULL)); + g_value_take_string(&value, g_key_file_get_string(key_file,group_name,name,NULL)); break; case G_TYPE_BOOLEAN: @@ -255,6 +255,9 @@ v3270 * terminal = GTK_V3270(widget); v3270Class * klass = GTK_V3270_GET_CLASS(widget); + if(!group_name) + group_name = "terminal"; + g_object_freeze_notify(G_OBJECT(widget)); // Load Toggles diff --git a/src/terminal/properties/get.c b/src/terminal/properties/get.c index d503843..2211e56 100644 --- a/src/terminal/properties/get.c +++ b/src/terminal/properties/get.c @@ -129,7 +129,9 @@ { if(ix) g_string_append_c(str,';'); - g_string_append_printf(str,"%s",gdk_rgba_to_string(v3270_get_color(GTK_WIDGET(object),ix))); + + g_autofree gchar * rgb = gdk_rgba_to_string(v3270_get_color(GTK_WIDGET(object),ix)); + g_string_append(str,rgb); } g_value_take_string(value,g_string_free(str,FALSE)); diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index 6206e10..f381225 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -159,7 +159,9 @@ #else debug("%s: Loading settings...",__FUNCTION__); GKeyFile * key_file = get_key_file(); - v3270_load_key_file(terminal,key_file,"terminal"); + v3270_load_key_file(terminal,key_file,NULL); + v3270_accelerator_map_load_key_file(terminal,key_file,NULL); + g_key_file_free(key_file); #endif // _WIN32 @@ -169,7 +171,8 @@ v3270_set_trace(terminal,TRUE); // Setup and show main window - gtk_window_set_title(GTK_WINDOW(window),v3270_get_session_title(terminal)); + g_autofree gchar * title = v3270_get_session_title(terminal); + gtk_window_set_title(GTK_WINDOW(window),title); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); gtk_window_set_default_size (GTK_WINDOW (window), 800, 500); gtk_container_add(GTK_CONTAINER(window),vBox); -- libgit2 0.21.2