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); | ... | ... |