Commit 591864251d570d8d2583658977411de00487eb1f

Authored by Perry Werneck
Committed by GitHub
2 parents 51eeb99b 9c7305f5
Exists in master and in 1 other branch develop

Merge pull request #11 from PerryWerneck/develop

Fix exit segfault, auto-select sensitive page on settings dialog.
src/dialogs/settings/dialog.c
... ... @@ -284,10 +284,23 @@ GtkWidget * v3270_settings_dialog_new()
284 284  
285 285 }
286 286  
287   -static void set_terminal_widget(GtkWidget *settings, GtkWidget *terminal)
  287 +struct _set_terminal_info
  288 +{
  289 + GtkNotebook *notebook; ///< @brief The notebook.
  290 + GtkWidget *terminal; ///< @brief The V3270 terminal.
  291 + gint selected; ///< @brief First sensitive page (-1 = none)
  292 +};
  293 +
  294 +static void set_terminal_widget(GtkWidget *settings, struct _set_terminal_info *info)
288 295 {
289 296 if(GTK_IS_V3270_SETTINGS(settings))
290   - v3270_settings_set_terminal_widget(settings,terminal);
  297 + {
  298 + v3270_settings_set_terminal_widget(settings,info->terminal);
  299 + if(gtk_widget_get_sensitive(settings) && info->selected < 0)
  300 + info->selected = gtk_notebook_page_num(info->notebook,settings);
  301 + }
  302 +
  303 + gtk_widget_show(settings);
291 304 }
292 305  
293 306 void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal)
... ... @@ -298,11 +311,28 @@ void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *ter
298 311  
299 312 GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal;
300 313  
  314 + struct _set_terminal_info info = {
  315 + .notebook = GTK_V3270_SETTINGS_DIALOG(widget)->tabs,
  316 + .terminal = terminal,
  317 + .selected = -1
  318 + };
  319 +
301 320 gtk_container_foreach(
302   - GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(widget)->tabs),
  321 + GTK_CONTAINER(info.notebook),
303 322 (GtkCallback) set_terminal_widget,
304   - terminal
  323 + &info
305 324 );
  325 +
  326 + if(info.selected >= 0)
  327 + {
  328 + debug("Found active page on %d",info.selected);
  329 + gtk_notebook_set_current_page(info.notebook, info.selected);
  330 + }
  331 + else
  332 + {
  333 + g_message("No active page on settings dialog");
  334 + }
  335 +
306 336 }
307 337  
308 338 void v3270_settings_dialog_set_has_subtitle(GtkWidget *widget, gboolean has_subtitle)
... ...
src/terminal/callbacks.c
... ... @@ -426,6 +426,29 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
426 426 return response;
427 427 }
428 428  
  429 + struct _bg_reconnect
  430 + {
  431 + H3270 *hSession;
  432 + int seconds;
  433 + };
  434 +
  435 + static gboolean bg_reconnect(struct _bg_reconnect *cfg)
  436 + {
  437 + lib3270_reconnect(cfg->hSession,cfg->seconds);
  438 + return G_SOURCE_REMOVE;
  439 + }
  440 +
  441 + static int reconnect(H3270 *hSession,int seconds)
  442 + {
  443 + struct _bg_reconnect *cfg = g_new0(struct _bg_reconnect, 1);
  444 +
  445 + cfg->hSession = hSession;
  446 + cfg->seconds = seconds;
  447 +
  448 + g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,(GSourceFunc) bg_reconnect, cfg, g_free);
  449 +
  450 + return 0;
  451 + }
429 452  
430 453 void v3270_install_callbacks(v3270 *widget)
431 454 {
... ... @@ -481,6 +504,7 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
481 504 cbk->load = load;
482 505 cbk->popup = popup;
483 506 cbk->action = action;
  507 + cbk->reconnect = reconnect;
484 508  
485 509 }
486 510  
... ...
src/terminal/iocallback.c
... ... @@ -146,12 +146,8 @@ gpointer BgCall(struct bgParameter *p)
146 146  
147 147 static int static_RunTask(H3270 *hSession, int(*callback)(H3270 *, void *), void *parm)
148 148 {
149   -// return callback(hSession,parm);
150   -
151 149 struct bgParameter p = { TRUE, hSession, -1, callback, parm };
152 150  
153   -// trace("%s starts -------------------------------------", __FUNCTION__);
154   -
155 151 p.running = TRUE;
156 152  
157 153 GThread *thread = g_thread_new(PACKAGE_NAME, (GThreadFunc) BgCall, &p);
... ... @@ -177,21 +173,21 @@ static int static_RunTask(H3270 *hSession, int(*callback)(H3270 *, void *), void
177 173  
178 174 void v3270_register_io_handlers(G_GNUC_UNUSED v3270Class *cls)
179 175 {
180   - static LIB3270_IO_CONTROLLER hdl =
  176 + static const LIB3270_IO_CONTROLLER hdl =
181 177 {
182   - sizeof(LIB3270_IO_CONTROLLER),
  178 + .sz = sizeof(LIB3270_IO_CONTROLLER),
183 179  
184   - static_AddTimer,
185   - static_RemoveTimer,
  180 + .AddTimer = static_AddTimer,
  181 + .RemoveTimer = static_RemoveTimer,
186 182  
187   - static_AddSource,
188   - static_RemoveSource,
189   - static_SetSourceState,
  183 + .add_poll = static_AddSource,
  184 + .remove_poll = static_RemoveSource,
  185 + .set_poll_state = static_SetSourceState,
190 186  
191   - static_Sleep,
192   - static_RunPendingEvents,
193   - beep,
194   - static_RunTask
  187 + .Wait = static_Sleep,
  188 + .event_dispatcher = static_RunPendingEvents,
  189 + .ring_bell = beep,
  190 + .run_task = static_RunTask
195 191  
196 192 };
197 193  
... ...
src/terminal/keyfile.c
... ... @@ -363,10 +363,6 @@
363 363  
364 364 }
365 365  
366   - // Load Toggles
367   - for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
368   - load_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name);
369   -
370 366 // Load V3270 properties
371 367 for(ix = 0; klass->properties.persistent[ix];ix++)
372 368 {
... ... @@ -379,6 +375,10 @@
379 375  
380 376 }
381 377  
  378 + // Load Toggles
  379 + for(ix = 0; ix < G_N_ELEMENTS(klass->properties.toggle); ix++)
  380 + load_by_pspec(widget,klass->properties.toggle[ix],key_file,group_name);
  381 +
382 382 g_object_thaw_notify(G_OBJECT(widget));
383 383 terminal->freeze = 0;
384 384  
... ...
src/terminal/widget.c
... ... @@ -35,6 +35,7 @@
35 35 #include <lib3270/log.h>
36 36 #include <lib3270/toggle.h>
37 37 #include <lib3270/actions.h>
  38 + #include <lib3270/properties.h>
38 39 #include <lib3270/ssl.h>
39 40 #include <internals.h>
40 41  
... ... @@ -183,23 +184,50 @@ static void v3270_toggle_changed(G_GNUC_UNUSED v3270 *widget, G_GNUC_UNUSED LIB3
183 184 {
184 185 }
185 186  
  187 +static gboolean delayed_cleanup(H3270 *hSession) {
  188 +
  189 + if(lib3270_get_task_count(hSession))
  190 + return G_SOURCE_CONTINUE;
  191 +
  192 + g_message("Delayed cleanup complete");
  193 + lib3270_free(hSession);
  194 +
  195 + return G_SOURCE_REMOVE;
  196 +
  197 +}
  198 +
186 199 static void finalize(GObject *object) {
187 200  
188 201 debug("V3270::%s",__FUNCTION__);
189 202  
190 203 v3270 * terminal = GTK_V3270(object);
191 204  
192   - if(terminal->remap_filename) {
193   - g_free(terminal->remap_filename);
194   - terminal->remap_filename = NULL;
195   - }
196   -
197 205 if(terminal->host) {
198 206 // Release session
199   - lib3270_session_free(terminal->host);
  207 + debug("%s: Cleaning 3270 session",__FUNCTION__);
  208 + lib3270_disconnect(terminal->host);
  209 +
  210 + debug("Task count: %u",lib3270_get_task_count(terminal->host));
  211 + if(lib3270_get_task_count(terminal->host))
  212 + {
  213 + // Should wait.
  214 + g_message("TN3270 session is busy, delaying cleanup");
  215 + lib3270_set_user_data(terminal->host,NULL);
  216 + g_idle_add((GSourceFunc) delayed_cleanup,terminal->host);
  217 + }
  218 + else
  219 + {
  220 + lib3270_session_free(terminal->host);
  221 + }
  222 +
200 223 terminal->host = NULL;
201 224 }
202 225  
  226 + if(terminal->remap_filename) {
  227 + g_free(terminal->remap_filename);
  228 + terminal->remap_filename = NULL;
  229 + }
  230 +
203 231 if(terminal->accelerators) {
204 232 g_slist_free_full(terminal->accelerators,g_free);
205 233 terminal->accelerators = NULL;
... ... @@ -597,6 +625,9 @@ static void v3270_destroy(GtkWidget *widget)
597 625 // Cleanup
598 626 lib3270_reset_callbacks(terminal->host);
599 627 lib3270_set_user_data(terminal->host,NULL);
  628 +
  629 + debug("%s: disconnecting", __FUNCTION__);
  630 + lib3270_disconnect(terminal->host);
600 631 }
601 632  
602 633 if(terminal->accessible)
... ...