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,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 if(GTK_IS_V3270_SETTINGS(settings)) 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 void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *terminal) 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,11 +311,28 @@ void v3270_settings_dialog_set_terminal_widget(GtkWidget *widget, GtkWidget *ter
298 311
299 GTK_V3270_SETTINGS_DIALOG(widget)->terminal = terminal; 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 gtk_container_foreach( 320 gtk_container_foreach(
302 - GTK_CONTAINER(GTK_V3270_SETTINGS_DIALOG(widget)->tabs), 321 + GTK_CONTAINER(info.notebook),
303 (GtkCallback) set_terminal_widget, 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 void v3270_settings_dialog_set_has_subtitle(GtkWidget *widget, gboolean has_subtitle) 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,6 +426,29 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
426 return response; 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 void v3270_install_callbacks(v3270 *widget) 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,6 +504,7 @@ static void popup_handler(H3270 *session, LIB3270_NOTIFY type, const char *title
481 cbk->load = load; 504 cbk->load = load;
482 cbk->popup = popup; 505 cbk->popup = popup;
483 cbk->action = action; 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,12 +146,8 @@ gpointer BgCall(struct bgParameter *p)
146 146
147 static int static_RunTask(H3270 *hSession, int(*callback)(H3270 *, void *), void *parm) 147 static int static_RunTask(H3270 *hSession, int(*callback)(H3270 *, void *), void *parm)
148 { 148 {
149 -// return callback(hSession,parm);  
150 -  
151 struct bgParameter p = { TRUE, hSession, -1, callback, parm }; 149 struct bgParameter p = { TRUE, hSession, -1, callback, parm };
152 150
153 -// trace("%s starts -------------------------------------", __FUNCTION__);  
154 -  
155 p.running = TRUE; 151 p.running = TRUE;
156 152
157 GThread *thread = g_thread_new(PACKAGE_NAME, (GThreadFunc) BgCall, &p); 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,21 +173,21 @@ static int static_RunTask(H3270 *hSession, int(*callback)(H3270 *, void *), void
177 173
178 void v3270_register_io_handlers(G_GNUC_UNUSED v3270Class *cls) 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,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 // Load V3270 properties 366 // Load V3270 properties
371 for(ix = 0; klass->properties.persistent[ix];ix++) 367 for(ix = 0; klass->properties.persistent[ix];ix++)
372 { 368 {
@@ -379,6 +375,10 @@ @@ -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 g_object_thaw_notify(G_OBJECT(widget)); 382 g_object_thaw_notify(G_OBJECT(widget));
383 terminal->freeze = 0; 383 terminal->freeze = 0;
384 384
src/terminal/widget.c
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
35 #include <lib3270/log.h> 35 #include <lib3270/log.h>
36 #include <lib3270/toggle.h> 36 #include <lib3270/toggle.h>
37 #include <lib3270/actions.h> 37 #include <lib3270/actions.h>
  38 + #include <lib3270/properties.h>
38 #include <lib3270/ssl.h> 39 #include <lib3270/ssl.h>
39 #include <internals.h> 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,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 static void finalize(GObject *object) { 199 static void finalize(GObject *object) {
187 200
188 debug("V3270::%s",__FUNCTION__); 201 debug("V3270::%s",__FUNCTION__);
189 202
190 v3270 * terminal = GTK_V3270(object); 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 if(terminal->host) { 205 if(terminal->host) {
198 // Release session 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 terminal->host = NULL; 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 if(terminal->accelerators) { 231 if(terminal->accelerators) {
204 g_slist_free_full(terminal->accelerators,g_free); 232 g_slist_free_full(terminal->accelerators,g_free);
205 terminal->accelerators = NULL; 233 terminal->accelerators = NULL;
@@ -597,6 +625,9 @@ static void v3270_destroy(GtkWidget *widget) @@ -597,6 +625,9 @@ static void v3270_destroy(GtkWidget *widget)
597 // Cleanup 625 // Cleanup
598 lib3270_reset_callbacks(terminal->host); 626 lib3270_reset_callbacks(terminal->host);
599 lib3270_set_user_data(terminal->host,NULL); 627 lib3270_set_user_data(terminal->host,NULL);
  628 +
  629 + debug("%s: disconnecting", __FUNCTION__);
  630 + lib3270_disconnect(terminal->host);
600 } 631 }
601 632
602 if(terminal->accessible) 633 if(terminal->accessible)