Commit 591864251d570d8d2583658977411de00487eb1f
Committed by
GitHub
Exists in
master
and in
1 other branch
Merge pull request #11 from PerryWerneck/develop
Fix exit segfault, auto-select sensitive page on settings dialog.
Showing
5 changed files
with
110 additions
and
29 deletions
Show diff stats
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) |