Commit e8267e3592222ad66fd88b2ae3fd8e51d5318281
1 parent
0af119d4
Exists in
master
and in
1 other branch
Adding support for customized accelerators.
Showing
5 changed files
with
101 additions
and
21 deletions
Show diff stats
src/include/internals.h
| ... | ... | @@ -148,7 +148,7 @@ |
| 148 | 148 | { |
| 149 | 149 | V3270_ACCELERATOR_TYPE_INTERNAL, ///< @brief Accelerator is internal. |
| 150 | 150 | V3270_ACCELERATOR_TYPE_LIB3270_ACTION, ///< @brief Accelerator is a lib3270 action. |
| 151 | - V3270_ACCELERATOR_TYPE_GTK_ACTION, ///< @brief Accelerator is a GTK Action (Deprececated). | |
| 151 | + V3270_ACCELERATOR_TYPE_CUSTOM, ///< @brief Custom (application based) accelerator. | |
| 152 | 152 | }; |
| 153 | 153 | |
| 154 | 154 | struct _V3270Accelerator |
| ... | ... | @@ -160,6 +160,12 @@ |
| 160 | 160 | GCallback activate; |
| 161 | 161 | }; |
| 162 | 162 | |
| 163 | + typedef struct _V3270CustomAccelerator | |
| 164 | + { | |
| 165 | + struct _V3270Accelerator parent; | |
| 166 | + const gchar *name; | |
| 167 | + } V3270CustomAccelerator; | |
| 168 | + | |
| 163 | 169 | typedef enum v3270_toggleable_dialog |
| 164 | 170 | { |
| 165 | 171 | V3270_TOGGLEABLE_DIALOG_PASTE_FAILED, | ... | ... |
src/include/v3270/actions.h
| ... | ... | @@ -56,10 +56,9 @@ |
| 56 | 56 | |
| 57 | 57 | /// @brief Reset accelerator map to defaults. |
| 58 | 58 | LIB3270_EXPORT void v3270_accelerator_map_reset(GtkWidget *widget); |
| 59 | - | |
| 60 | 59 | LIB3270_EXPORT void v3270_accelerator_map_foreach(GtkWidget *widget,void (*call)(const V3270Accelerator * accel, const char *keys, gpointer ptr), gpointer ptr); |
| 61 | - | |
| 62 | 60 | LIB3270_EXPORT void v3270_accelerator_map_to_key_file(GtkWidget *widget, GKeyFile *key_file, const gchar *group_name); |
| 61 | + LIB3270_EXPORT V3270Accelerator * v3270_accelerator_map_add_entry(GtkWidget *widget, const gchar *name, guint accel_key, GdkModifierType accel_mods, GCallback callback, gpointer data); | |
| 63 | 62 | |
| 64 | 63 | LIB3270_EXPORT const V3270Accelerator * v3270_get_accelerator(GtkWidget *widget, guint keyval, GdkModifierType state); |
| 65 | 64 | LIB3270_EXPORT void v3270_accelerator_activate(const V3270Accelerator * accel, GtkWidget *terminal); | ... | ... |
src/terminal/keyboard/accelerator.c
| ... | ... | @@ -79,11 +79,20 @@ |
| 79 | 79 | |
| 80 | 80 | const V3270Accelerator * v3270_get_accelerator(GtkWidget *widget, guint keyval, GdkModifierType state) |
| 81 | 81 | { |
| 82 | - GSList * acccelerator; | |
| 83 | - for(acccelerator = GTK_V3270(widget)->accelerators; acccelerator; acccelerator = g_slist_next(acccelerator)) | |
| 82 | + GSList * ix; | |
| 83 | + | |
| 84 | + debug("%s: %u %u",__FUNCTION__,(unsigned int) keyval, (unsigned int) state); | |
| 85 | + | |
| 86 | + for(ix = GTK_V3270(widget)->accelerators; ix; ix = g_slist_next(ix)) | |
| 84 | 87 | { |
| 85 | - if(v3270_accelerator_compare((V3270Accelerator *) acccelerator->data, keyval, state)) | |
| 86 | - return (V3270Accelerator *) acccelerator->data; | |
| 88 | + debug( | |
| 89 | + "%s: %u %u", | |
| 90 | + v3270_accelerator_get_name((V3270Accelerator *) ix->data), | |
| 91 | + (unsigned int) ((V3270Accelerator *) ix->data)->key, | |
| 92 | + (unsigned int) ((V3270Accelerator *) ix->data)->mods | |
| 93 | + ); | |
| 94 | + if(v3270_accelerator_compare((V3270Accelerator *) ix->data, keyval, state)) | |
| 95 | + return (V3270Accelerator *) ix->data; | |
| 87 | 96 | } |
| 88 | 97 | |
| 89 | 98 | return NULL; |
| ... | ... | @@ -112,8 +121,8 @@ |
| 112 | 121 | case V3270_ACCELERATOR_TYPE_LIB3270_ACTION: |
| 113 | 122 | return gettext(((LIB3270_ACTION *) accel->arg)->name); |
| 114 | 123 | |
| 115 | - // case V3270_ACCELERATOR_TYPE_INTERNAL: | |
| 116 | - // case V3270_ACCELERATOR_TYPE_GTK_ACTION: | |
| 124 | + case V3270_ACCELERATOR_TYPE_CUSTOM: | |
| 125 | + return ((V3270CustomAccelerator *) accel)->name; | |
| 117 | 126 | |
| 118 | 127 | } |
| 119 | 128 | |
| ... | ... | @@ -140,9 +149,11 @@ |
| 140 | 149 | if(str->str[0]) |
| 141 | 150 | g_string_append(str," "); |
| 142 | 151 | |
| 143 | - g_autofree gchar * keyname = gtk_accelerator_name(accel->key,accel->mods); | |
| 144 | - g_string_append(str,keyname); | |
| 145 | - | |
| 152 | + if(accel->key) | |
| 153 | + { | |
| 154 | + g_autofree gchar * keyname = gtk_accelerator_name(accel->key,accel->mods); | |
| 155 | + g_string_append(str,keyname); | |
| 156 | + } | |
| 146 | 157 | |
| 147 | 158 | } |
| 148 | 159 | |
| ... | ... | @@ -157,7 +168,65 @@ |
| 157 | 168 | |
| 158 | 169 | } |
| 159 | 170 | |
| 160 | - LIB3270_EXPORT gchar * v3270_accelerator_get_label(const V3270Accelerator * accel) | |
| 171 | + gchar * v3270_accelerator_get_label(const V3270Accelerator * accel) | |
| 161 | 172 | { |
| 162 | 173 | return gtk_accelerator_get_label(accel->key,accel->mods); |
| 163 | 174 | } |
| 175 | + | |
| 176 | + V3270Accelerator * v3270_accelerator_map_add_entry(GtkWidget *widget, const gchar *name, guint accel_key, GdkModifierType accel_mods, GCallback callback, gpointer data) | |
| 177 | + { | |
| 178 | + GSList * ix; | |
| 179 | + v3270 * terminal = GTK_V3270(widget); | |
| 180 | + V3270Accelerator * accel = NULL; | |
| 181 | + | |
| 182 | + // Find accel by name | |
| 183 | + for(ix = terminal->accelerators; ix; ix = g_slist_next(ix)) | |
| 184 | + { | |
| 185 | + const gchar * nm = v3270_accelerator_get_name((V3270Accelerator *) ix->data); | |
| 186 | + if(nm && !g_ascii_strcasecmp(name,nm)) | |
| 187 | + { | |
| 188 | + accel = (V3270Accelerator *) ix->data; | |
| 189 | + break; | |
| 190 | + } | |
| 191 | + } | |
| 192 | + | |
| 193 | + if(!accel) | |
| 194 | + { | |
| 195 | + // Not found, create a custom accelerator. | |
| 196 | + debug("%s: Adding accelerator %s",__FUNCTION__,name); | |
| 197 | + | |
| 198 | + V3270CustomAccelerator *customAccel = g_new0(V3270CustomAccelerator,1); | |
| 199 | + | |
| 200 | + customAccel->parent.type = V3270_ACCELERATOR_TYPE_CUSTOM; | |
| 201 | + customAccel->name = name; | |
| 202 | + | |
| 203 | + terminal->accelerators = g_slist_prepend(terminal->accelerators,customAccel); | |
| 204 | + | |
| 205 | + accel = (V3270Accelerator *) customAccel; | |
| 206 | + } | |
| 207 | + | |
| 208 | + accel->arg = data; | |
| 209 | + accel->activate = callback; | |
| 210 | + accel->key = accel_key; | |
| 211 | + accel->mods = accel_mods; | |
| 212 | + | |
| 213 | + // Any other accell in the same key? If yes, clear it. | |
| 214 | + for(ix = terminal->accelerators; ix; ix = g_slist_next(ix)) | |
| 215 | + { | |
| 216 | + V3270Accelerator * acc = (V3270Accelerator *) ix->data; | |
| 217 | + if((acc == accel) || !(acc->key == accel->key && acc->mods == accel->mods)) | |
| 218 | + continue; | |
| 219 | + | |
| 220 | + debug("Resetting accelerator \"%s\"",v3270_accelerator_get_name(acc)); | |
| 221 | + | |
| 222 | + acc->key = 0; | |
| 223 | + acc->mods = 0; | |
| 224 | + | |
| 225 | + } | |
| 226 | + | |
| 227 | + // Sort! | |
| 228 | + v3270_accelerator_map_sort(terminal); | |
| 229 | + | |
| 230 | + return accel; | |
| 231 | + | |
| 232 | + } | ... | ... |
src/terminal/keyboard/keyfile.c
src/testprogram/testprogram.c
| ... | ... | @@ -40,7 +40,9 @@ |
| 40 | 40 | #include <v3270/settings.h> |
| 41 | 41 | #include <v3270/trace.h> |
| 42 | 42 | #include <lib3270/log.h> |
| 43 | + #include <v3270/actions.h> | |
| 43 | 44 | #include <stdlib.h> |
| 45 | + #include <gdk/gdkkeysyms-compat.h> | |
| 44 | 46 | |
| 45 | 47 | /*---[ Implement ]----------------------------------------------------------------------------------*/ |
| 46 | 48 | |
| ... | ... | @@ -118,6 +120,13 @@ |
| 118 | 120 | |
| 119 | 121 | #endif // _WIN32 |
| 120 | 122 | |
| 123 | + static void accel_copy(GtkWidget *widget, GtkWidget *window) { | |
| 124 | + debug("%s",__FUNCTION__); | |
| 125 | + } | |
| 126 | + | |
| 127 | + static void accel_paste(GtkWidget *widget, GtkWidget *window) { | |
| 128 | + debug("%s",__FUNCTION__); | |
| 129 | + } | |
| 121 | 130 | |
| 122 | 131 | static void activate(GtkApplication* app, G_GNUC_UNUSED gpointer user_data) { |
| 123 | 132 | |
| ... | ... | @@ -164,16 +173,13 @@ |
| 164 | 173 | |
| 165 | 174 | } |
| 166 | 175 | |
| 176 | + // Set accelerators | |
| 177 | + v3270_accelerator_map_add_entry(terminal, "copy", 'c', GDK_CONTROL_MASK, G_CALLBACK(accel_copy), window); | |
| 178 | + v3270_accelerator_map_add_entry(terminal, "paste", 'v', GDK_CONTROL_MASK, G_CALLBACK(accel_paste), window); | |
| 179 | + | |
| 167 | 180 | // Create trace window |
| 168 | 181 | v3270_set_trace(terminal,TRUE); |
| 169 | 182 | |
| 170 | - /* | |
| 171 | - GtkWidget *trace = v3270_trace_new(terminal); | |
| 172 | - debug("Trace=%p",trace); | |
| 173 | - gtk_notebook_append_page(GTK_NOTEBOOK(notebook),trace,gtk_label_new("Trace")); | |
| 174 | - // v3270_trace_window_new(terminal,NULL); | |
| 175 | - */ | |
| 176 | - | |
| 177 | 183 | // Setup and show main window |
| 178 | 184 | gtk_window_set_title(GTK_WINDOW(window),v3270_get_session_title(terminal)); |
| 179 | 185 | gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER); | ... | ... |