From e8267e3592222ad66fd88b2ae3fd8e51d5318281 Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Thu, 28 Nov 2019 08:27:47 -0300 Subject: [PATCH] Adding support for customized accelerators. --- src/include/internals.h | 8 +++++++- src/include/v3270/actions.h | 3 +-- src/terminal/keyboard/accelerator.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- src/terminal/keyboard/keyfile.c | 2 +- src/testprogram/testprogram.c | 20 +++++++++++++------- 5 files changed, 101 insertions(+), 21 deletions(-) diff --git a/src/include/internals.h b/src/include/internals.h index 5e92019..5c4d2b7 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -148,7 +148,7 @@ { V3270_ACCELERATOR_TYPE_INTERNAL, ///< @brief Accelerator is internal. V3270_ACCELERATOR_TYPE_LIB3270_ACTION, ///< @brief Accelerator is a lib3270 action. - V3270_ACCELERATOR_TYPE_GTK_ACTION, ///< @brief Accelerator is a GTK Action (Deprececated). + V3270_ACCELERATOR_TYPE_CUSTOM, ///< @brief Custom (application based) accelerator. }; struct _V3270Accelerator @@ -160,6 +160,12 @@ GCallback activate; }; + typedef struct _V3270CustomAccelerator + { + struct _V3270Accelerator parent; + const gchar *name; + } V3270CustomAccelerator; + typedef enum v3270_toggleable_dialog { V3270_TOGGLEABLE_DIALOG_PASTE_FAILED, diff --git a/src/include/v3270/actions.h b/src/include/v3270/actions.h index 4dd9583..e7bbf12 100644 --- a/src/include/v3270/actions.h +++ b/src/include/v3270/actions.h @@ -56,10 +56,9 @@ /// @brief Reset accelerator map to defaults. 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 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); LIB3270_EXPORT void v3270_accelerator_activate(const V3270Accelerator * accel, GtkWidget *terminal); diff --git a/src/terminal/keyboard/accelerator.c b/src/terminal/keyboard/accelerator.c index 34fc87e..ea274da 100644 --- a/src/terminal/keyboard/accelerator.c +++ b/src/terminal/keyboard/accelerator.c @@ -79,11 +79,20 @@ const V3270Accelerator * v3270_get_accelerator(GtkWidget *widget, guint keyval, GdkModifierType state) { - GSList * acccelerator; - for(acccelerator = GTK_V3270(widget)->accelerators; acccelerator; acccelerator = g_slist_next(acccelerator)) + GSList * ix; + + debug("%s: %u %u",__FUNCTION__,(unsigned int) keyval, (unsigned int) state); + + for(ix = GTK_V3270(widget)->accelerators; ix; ix = g_slist_next(ix)) { - if(v3270_accelerator_compare((V3270Accelerator *) acccelerator->data, keyval, state)) - return (V3270Accelerator *) acccelerator->data; + debug( + "%s: %u %u", + v3270_accelerator_get_name((V3270Accelerator *) ix->data), + (unsigned int) ((V3270Accelerator *) ix->data)->key, + (unsigned int) ((V3270Accelerator *) ix->data)->mods + ); + if(v3270_accelerator_compare((V3270Accelerator *) ix->data, keyval, state)) + return (V3270Accelerator *) ix->data; } return NULL; @@ -112,8 +121,8 @@ case V3270_ACCELERATOR_TYPE_LIB3270_ACTION: return gettext(((LIB3270_ACTION *) accel->arg)->name); - // case V3270_ACCELERATOR_TYPE_INTERNAL: - // case V3270_ACCELERATOR_TYPE_GTK_ACTION: + case V3270_ACCELERATOR_TYPE_CUSTOM: + return ((V3270CustomAccelerator *) accel)->name; } @@ -140,9 +149,11 @@ if(str->str[0]) g_string_append(str," "); - g_autofree gchar * keyname = gtk_accelerator_name(accel->key,accel->mods); - g_string_append(str,keyname); - + if(accel->key) + { + g_autofree gchar * keyname = gtk_accelerator_name(accel->key,accel->mods); + g_string_append(str,keyname); + } } @@ -157,7 +168,65 @@ } - LIB3270_EXPORT gchar * v3270_accelerator_get_label(const V3270Accelerator * accel) + gchar * v3270_accelerator_get_label(const V3270Accelerator * accel) { return gtk_accelerator_get_label(accel->key,accel->mods); } + + V3270Accelerator * v3270_accelerator_map_add_entry(GtkWidget *widget, const gchar *name, guint accel_key, GdkModifierType accel_mods, GCallback callback, gpointer data) + { + GSList * ix; + v3270 * terminal = GTK_V3270(widget); + V3270Accelerator * accel = NULL; + + // Find accel by name + for(ix = terminal->accelerators; ix; ix = g_slist_next(ix)) + { + const gchar * nm = v3270_accelerator_get_name((V3270Accelerator *) ix->data); + if(nm && !g_ascii_strcasecmp(name,nm)) + { + accel = (V3270Accelerator *) ix->data; + break; + } + } + + if(!accel) + { + // Not found, create a custom accelerator. + debug("%s: Adding accelerator %s",__FUNCTION__,name); + + V3270CustomAccelerator *customAccel = g_new0(V3270CustomAccelerator,1); + + customAccel->parent.type = V3270_ACCELERATOR_TYPE_CUSTOM; + customAccel->name = name; + + terminal->accelerators = g_slist_prepend(terminal->accelerators,customAccel); + + accel = (V3270Accelerator *) customAccel; + } + + accel->arg = data; + accel->activate = callback; + accel->key = accel_key; + accel->mods = accel_mods; + + // Any other accell in the same key? If yes, clear it. + for(ix = terminal->accelerators; ix; ix = g_slist_next(ix)) + { + V3270Accelerator * acc = (V3270Accelerator *) ix->data; + if((acc == accel) || !(acc->key == accel->key && acc->mods == accel->mods)) + continue; + + debug("Resetting accelerator \"%s\"",v3270_accelerator_get_name(acc)); + + acc->key = 0; + acc->mods = 0; + + } + + // Sort! + v3270_accelerator_map_sort(terminal); + + return accel; + + } diff --git a/src/terminal/keyboard/keyfile.c b/src/terminal/keyboard/keyfile.c index 71b36f8..3be1c59 100644 --- a/src/terminal/keyboard/keyfile.c +++ b/src/terminal/keyboard/keyfile.c @@ -53,7 +53,7 @@ ((struct Args *) ptr)->key_file, ((struct Args *) ptr)->group_name, key, - keys + (keys ? keys : "") ); } diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index 39eebf4..f13791f 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -40,7 +40,9 @@ #include #include #include + #include #include + #include /*---[ Implement ]----------------------------------------------------------------------------------*/ @@ -118,6 +120,13 @@ #endif // _WIN32 + static void accel_copy(GtkWidget *widget, GtkWidget *window) { + debug("%s",__FUNCTION__); + } + + static void accel_paste(GtkWidget *widget, GtkWidget *window) { + debug("%s",__FUNCTION__); + } static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) { @@ -164,16 +173,13 @@ } + // Set accelerators + v3270_accelerator_map_add_entry(terminal, "copy", 'c', GDK_CONTROL_MASK, G_CALLBACK(accel_copy), window); + v3270_accelerator_map_add_entry(terminal, "paste", 'v', GDK_CONTROL_MASK, G_CALLBACK(accel_paste), window); + // Create trace window v3270_set_trace(terminal,TRUE); - /* - GtkWidget *trace = v3270_trace_new(terminal); - debug("Trace=%p",trace); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook),trace,gtk_label_new("Trace")); - // v3270_trace_window_new(terminal,NULL); - */ - // Setup and show main window gtk_window_set_title(GTK_WINDOW(window),v3270_get_session_title(terminal)); gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); -- libgit2 0.21.2