From 62e67d83660fa6d4281db743004811353982f7ed Mon Sep 17 00:00:00 2001 From: Perry Werneck Date: Wed, 13 Feb 2019 13:43:08 -0200 Subject: [PATCH] Working on FT worker widget. --- src/dialogs/tools.c | 11 +++++++++++ src/filetransfer/activity.c | 19 +++++++++++++++++++ src/filetransfer/marshal | 1 + src/filetransfer/set.c | 2 +- src/filetransfer/v3270ftprogress.c | 18 +++++++++--------- src/filetransfer/worker.c | 417 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------ src/include/internals.h | 2 ++ src/include/v3270/filetransfer.h | 3 +++ src/testprogram/testprogram.c | 9 +++++++-- 9 files changed, 446 insertions(+), 36 deletions(-) diff --git a/src/dialogs/tools.c b/src/dialogs/tools.c index 15df15d..a0db079 100644 --- a/src/dialogs/tools.c +++ b/src/dialogs/tools.c @@ -82,5 +82,16 @@ return child; } + void gtk_entry_set_text_printf(GtkEntry *entry, const gchar *fmt, ...) + { + va_list arg_ptr; + va_start(arg_ptr, fmt); + gchar *text = g_strdup_vprintf(fmt,arg_ptr); + va_end(arg_ptr); + + gtk_entry_set_text(entry,text); + g_free(text); + + } diff --git a/src/filetransfer/activity.c b/src/filetransfer/activity.c index a20ef7f..bde2f57 100644 --- a/src/filetransfer/activity.c +++ b/src/filetransfer/activity.c @@ -298,3 +298,22 @@ g_markup_parse_context_push(context,&parser,activity); } + + LIB3270_EXPORT H3270FT * v3270_ft_activity_begin_transfer(GObject * object, H3270 *hSession, const char **message) + { + V3270FTActivity * activity = G_V3270_FT_ACTIVITY(object); + + return lib3270_ft_new( + hSession, + activity->options, + activity->file.local, + activity->file.remote, + activity->values[LIB3270_FT_VALUE_LRECL], + activity->values[LIB3270_FT_VALUE_BLKSIZE], + activity->values[LIB3270_FT_VALUE_PRIMSPACE], + activity->values[LIB3270_FT_VALUE_SECSPACE], + activity->values[LIB3270_FT_VALUE_DFT], + message + ); + + } diff --git a/src/filetransfer/marshal b/src/filetransfer/marshal index 6dd82d3..1547529 100644 --- a/src/filetransfer/marshal +++ b/src/filetransfer/marshal @@ -1,4 +1,5 @@ VOID:POINTER,POINTER VOID:VOID,BOOLEAN VOID:VOID,OBJECT +VOID:UINT,POINTER diff --git a/src/filetransfer/set.c b/src/filetransfer/set.c index b9d57d9..7f7c1f5 100644 --- a/src/filetransfer/set.c +++ b/src/filetransfer/set.c @@ -182,7 +182,7 @@ void v3270ftprogress_set_session(GtkWidget *widget, H3270 *session) { v3270ftprogress * dialog = GTK_V3270FTPROGRESS(widget); if(dialog->session) { - lib3270_ft_destroy(dialog->session); + lib3270_ft_destroy(dialog->session,NULL); } dialog->session = session; diff --git a/src/filetransfer/v3270ftprogress.c b/src/filetransfer/v3270ftprogress.c index f507b8e..aac5397 100644 --- a/src/filetransfer/v3270ftprogress.c +++ b/src/filetransfer/v3270ftprogress.c @@ -247,7 +247,7 @@ gboolean v3270ftprogress_cleanup(v3270ftprogress * dialog) { if(dialog->session) { debug("%s: FT session was destroyed",__FUNCTION__); lib3270_ft_set_user_data(dialog->session,NULL); - lib3270_ft_destroy(dialog->session); + lib3270_ft_destroy(dialog->session,NULL); } return FALSE; @@ -282,7 +282,7 @@ static void dialog_response(GtkDialog *widget, gint response_id) { // Removo do objeto para evitar a geração de sinais e destruo. lib3270_ft_set_user_data(dialog->session,NULL); - lib3270_ft_destroy(dialog->session); + lib3270_ft_destroy(dialog->session,NULL); } @@ -298,7 +298,7 @@ static void dialog_close(GtkDialog *object) { debug("%s",__FUNCTION__); // Se tem sessão e conseguiu cancelar. - if(dialog->session && lib3270_ft_cancel(dialog->session,0) == 0) + if(dialog->session && lib3270_ft_cancel(dialog->session,0,NULL) == 0) return; GTK_DIALOG_CLASS(v3270ftprogress_parent_class)->close(object); @@ -367,7 +367,7 @@ static void cancel_clicked(G_GNUC_UNUSED GtkButton *button,v3270ftprogress *dial debug("%s",__FUNCTION__); if(dialog->session) { - lib3270_ft_cancel(dialog->session,1); + lib3270_ft_cancel(dialog->session,1,NULL); } } @@ -540,7 +540,7 @@ gboolean send_delayed_signal(struct delayed_signal *sig) { void * userdata = lib3270_ft_get_user_data(sig->hSession); lib3270_ft_set_user_data(sig->hSession,NULL); - lib3270_ft_destroy(sig->hSession); + lib3270_ft_destroy(sig->hSession,NULL); if(userdata) { g_signal_emit(GTK_WIDGET(userdata),v3270ftprogress_signal[sig->signal], 0, sig->msg, sig->text); @@ -679,10 +679,10 @@ static void ft_running(G_GNUC_UNUSED H3270 *hSession, G_GNUC_UNUSED int is_cut, GTK_V3270FTPROGRESS(widget)->timeout = time(NULL)+10; } -static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, void *widget) { +static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, const char *reason, void *widget) { if(widget) { - v3270ftprogress_set_header(GTK_WIDGET(widget),_("Aborting transfer")); + v3270ftprogress_set_header(GTK_WIDGET(widget),reason); } } @@ -714,7 +714,7 @@ static gboolean do_timer(v3270ftprogress *dialog) { if(dialog->session) { lib3270_ft_set_user_data(dialog->session,NULL); - lib3270_ft_destroy(dialog->session); + lib3270_ft_destroy(dialog->session,NULL); } g_signal_emit(GTK_WIDGET(dialog),v3270ftprogress_signal[V3270FTPROGRESS_SIGNAL_FAILED], 0, _( "Transfer failed" ), strerror(ETIMEDOUT)); @@ -768,7 +768,7 @@ void v3270ftprogress_start_transfer(GtkWidget *widget) { if(!cbk) { - lib3270_ft_destroy(dialog->session); + lib3270_ft_destroy(dialog->session,NULL); g_signal_emit(GTK_WIDGET(widget),v3270ftprogress_signal[V3270FTPROGRESS_SIGNAL_FAILED], 0, _( "Can't set callback table" ), NULL); return; diff --git a/src/filetransfer/worker.c b/src/filetransfer/worker.c index a748c8c..c448737 100644 --- a/src/filetransfer/worker.c +++ b/src/filetransfer/worker.c @@ -35,21 +35,20 @@ /*--[ Widget definition ]----------------------------------------------------------------------------*/ - enum _SIGNALS + typedef enum _V3270_WORKER_SIGNAL { - V3270_WORKER_ACTIVITY_SIGNAL, ///< @brief Indicates if the list has an activity set. + V3270_WORKER_ACTIVITY_SIGNAL, ///< @brief Indicates if the list has an activity set. + V3270_WORKER_TRANSFER_FAILED_SIGNAL, ///< @brief Transfer has failed. + V3270_WORKER_TRANSFER_SUCCESS_SIGNAL, ///< @brief Transfer complete. + V3270_WORKER_TRANSFER_STATE_SIGNAL, ///< @brief Transfer state has changed. V3270_WORKER_LAST_SIGNAL - }; + } V3270_WORKER_SIGNAL; struct _V3270FTWorkerClass { GtkGridClass parent_class; - struct - { - void (*activity)(GtkWidget *, GObject *); - } signal; }; @@ -57,10 +56,20 @@ { GtkGrid parent; + H3270 * hSession; + GtkProgressBar * pbar; ///< @brief Progress bar. GObject * activity; ///< @brief File transfer activity. GSource * pulse; ///< @brief Process pulse. + struct + { + GSource * timer; ///< @brief Timeout timer. + time_t limit; ///< @brief Timestamp for timeout transfer. + time_t value; ///< @brief Timeout value. + + } timeout; + GtkEntry * field[PROGRESS_FIELD_COUNT]; ///< @brief Transfer information widgets. }; @@ -96,13 +105,30 @@ } } + static void timer_stop(V3270FTWorker *worker) + { + if(worker->timeout.timer) + { + g_source_destroy(worker->timeout.timer); + worker->timeout.timer = NULL; + } + } + static void finalize(GObject *object) { debug("%s",__FUNCTION__); V3270FTWorker * worker = GTK_V3270_FT_WORKER(object); + if(worker->hSession) + { + lib3270_ft_set_user_data(worker->hSession,NULL); + lib3270_ft_destroy(worker->hSession,NULL); + worker->hSession = NULL; + } + pulse_stop(worker); + timer_stop(worker); if(worker->activity) { @@ -114,27 +140,45 @@ } - static void V3270FTWorker_activity(GtkWidget G_GNUC_UNUSED(*widget), GObject G_GNUC_UNUSED(*activity)) - { - debug("%s",__FUNCTION__); - } - static void V3270FTWorker_class_init(G_GNUC_UNUSED V3270FTWorkerClass *klass) { GObjectClass * gobject_class = G_OBJECT_CLASS(klass); gobject_class->finalize = finalize; - klass->signal.activity = V3270FTWorker_activity; - v3270_worker_signals[V3270_WORKER_ACTIVITY_SIGNAL] = - g_signal_new( "activity", - G_OBJECT_CLASS_TYPE (gobject_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (V3270FTWorkerClass, signal.activity), - NULL, NULL, - v3270ft_VOID__VOID_OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); + g_signal_new( + "activity", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, NULL, + v3270ft_VOID__VOID_OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT + ); + + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL] = + g_signal_new( + "failed", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + 0, + NULL, NULL, + v3270ft_VOID__POINTER_POINTER, + G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER + ); + + v3270_worker_signals[V3270_WORKER_TRANSFER_STATE_SIGNAL] = + g_signal_new( + "ft-state-changed", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + 0, + NULL, NULL, + v3270ft_VOID__UINT_POINTER, + G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER + ); + } @@ -162,6 +206,7 @@ gtk_grid_attach(GTK_GRID(grid),label,0,top,1,1); widget->field[id] = GTK_ENTRY(gtk_entry_new()); + gtk_entry_set_alignment(widget->field[id],1); gtk_grid_attach(GTK_GRID(grid),GTK_WIDGET(widget->field[id]),1,top,1,1); @@ -169,6 +214,9 @@ static void V3270FTWorker_init(V3270FTWorker *widget) { + // Set defaults. + widget->timeout.value = 10; + // https://developer.gnome.org/hig/stable/visual-layout.html.en gtk_grid_set_row_spacing(GTK_GRID(widget),6); gtk_grid_set_column_spacing(GTK_GRID(widget),12); @@ -240,6 +288,11 @@ V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + if(worker->hSession) + { + lib3270_ft_destroy(worker->hSession,NULL); + } + if(worker->activity) { g_object_unref(worker->activity); @@ -254,11 +307,16 @@ gtk_entry_set_text(worker->field[PROGRESS_FIELD_LOCAL],v3270_ft_activity_get_local_filename(activity)); gtk_entry_set_text(worker->field[PROGRESS_FIELD_REMOTE],v3270_ft_activity_get_remote_filename(activity)); + gtk_progress_bar_set_text(worker->pbar,_("Starting transfer")); + pulse_start(worker); + } else { gtk_entry_set_text(worker->field[PROGRESS_FIELD_LOCAL],""); gtk_entry_set_text(worker->field[PROGRESS_FIELD_REMOTE],""); + pulse_stop(worker); + } for(ix = PROGRESS_FIELD_TOTAL; ix < PROGRESS_FIELD_COUNT; ix++) @@ -266,10 +324,321 @@ gtk_entry_set_text(worker->field[ix],""); } - gtk_progress_bar_set_text(worker->pbar,_("Starting transfer")); - pulse_start(worker); - g_signal_emit(widget, v3270_worker_signals[V3270_WORKER_ACTIVITY_SIGNAL], 0, worker->activity); } + LIB3270_EXPORT void v3270_ft_worker_set_session(GtkWidget *widget, H3270 *hSession) + { + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + worker->hSession = hSession; + + } + + struct bg_complete + { + V3270FTWorker * worker; + V3270_WORKER_SIGNAL signal; + unsigned long length; + double kbytes_sec; + char msg[1]; + }; + + static gboolean bg_emit_complete(struct bg_complete * cfg) + { + // Try to get more detailed info. + const gchar * description = NULL; + + if(cfg->length) + { + gtk_entry_set_text_printf(cfg->worker->field[PROGRESS_FIELD_TOTAL],"%lu",cfg->length); + } + else + { + gtk_entry_set_text(cfg->worker->field[PROGRESS_FIELD_TOTAL],""); + } + + gtk_entry_set_text(cfg->worker->field[PROGRESS_FIELD_ETA],""); + + + const LIB3270_FT_MESSAGE * ftMessage = lib3270_translate_ft_message(cfg->msg); + + if(ftMessage) + { + description = ftMessage->description; + if(ftMessage->failed) + cfg->signal = V3270_WORKER_TRANSFER_FAILED_SIGNAL; + + } + + gtk_progress_bar_set_text(cfg->worker->pbar,cfg->msg); + + g_signal_emit( + GTK_WIDGET(cfg->worker), + v3270_worker_signals[cfg->signal], + 0, + cfg->msg, + description + ); + + return FALSE; + + } + + static void ft_complete(H3270 G_GNUC_UNUSED(*hSession), unsigned long length, double kbytes_sec, const char *msg, void *widget) + { + struct bg_complete * state = g_malloc0(sizeof(struct bg_complete)+strlen(msg)+1); + + state->worker = GTK_V3270_FT_WORKER(widget); + state->signal = V3270_WORKER_TRANSFER_SUCCESS_SIGNAL; + state->length = length; + state->kbytes_sec = kbytes_sec; + + strcpy(state->msg,msg); + + pulse_stop(state->worker); + timer_stop(state->worker); + + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_complete, state, g_free); + + } + + static void ft_failed(H3270 G_GNUC_UNUSED(*hSession), unsigned long length, double kbytes_sec, const char *msg, void *widget) + { + debug("%s(%p,%s)",__FUNCTION__,widget,msg); + + struct bg_complete * state = g_malloc0(sizeof(struct bg_complete)+strlen(msg)); + strcpy(state->msg,msg); + + state->worker = GTK_V3270_FT_WORKER(widget); + state->signal = V3270_WORKER_TRANSFER_FAILED_SIGNAL; + state->length = length; + state->kbytes_sec = kbytes_sec; + + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_complete, state, g_free); + + } + + static void ft_message(G_GNUC_UNUSED H3270 *hSession, const char *msg, void *widget) + { + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + debug("%s(%p,%s)",__FUNCTION__,worker,msg); + + gtk_progress_bar_set_text(worker->pbar,msg); + + } + + struct bg_update + { + V3270FTWorker * worker; + unsigned long current; + unsigned long total; + double kbytes_sec; + }; + + static gboolean bg_emit_update(struct bg_update * update) + { + // Update values + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_CURRENT],"%lu",update->current); + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_TOTAL],"%lu",update->total); + + if(update->total) + { + // Calculate ETA + double remaining = ((double) (update->total - update->current))/1024.0; + + if(remaining > 0 && update->kbytes_sec > 0) { + + char buffer[40]; + double seconds = ((double) remaining) / update->kbytes_sec; + time_t eta = time(NULL) + ((time_t) seconds); + strftime(buffer, 39, "%H:%M:%S", localtime(&eta)); + + gtk_entry_set_text(update->worker->field[PROGRESS_FIELD_ETA],buffer); + + } else { + + gtk_entry_set_text(update->worker->field[PROGRESS_FIELD_ETA],""); + + } + + if(update->current) + { + // Update progress bar + pulse_stop(update->worker); + gtk_progress_bar_set_fraction(update->worker->pbar, ((gdouble) update->current) / ((gdouble) update->total)); + } + + gtk_entry_set_text_printf(update->worker->field[PROGRESS_FIELD_ETA],"%lu",update->total); + + } + + return FALSE; + } + + static void ft_update(G_GNUC_UNUSED H3270 *hSession, unsigned long current, unsigned long total, double kbytes_sec, void *widget) + { + debug("%s(%p,%p)",__FUNCTION__,widget,widget); + + struct bg_update * update = g_new0(struct bg_update,1); + + update->worker = GTK_V3270_FT_WORKER(widget); + update->current = current; + update->total = total; + update->kbytes_sec = kbytes_sec; + + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_update, update, g_free); + + } + + static void ft_running(G_GNUC_UNUSED H3270 *hSession, G_GNUC_UNUSED int is_cut, void *widget) + { + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + debug("%s(%p,%p)",__FUNCTION__,worker,widget); + + // Reset timeout. + worker->timeout.limit = time(NULL) + worker->timeout.value; + + } + + static void ft_aborting(G_GNUC_UNUSED H3270 *hSession, const char *reason, void *widget) + { + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + debug("%s(%p,%p)",__FUNCTION__,worker,widget); + + gtk_progress_bar_set_text(worker->pbar,reason); + + } + + struct bg_state_changed + { + V3270FTWorker * worker; + LIB3270_FT_STATE st; + char msg[1]; + }; + + static gboolean bg_emit_state_changed(struct bg_state_changed * cfg) + { + g_signal_emit(cfg->worker, v3270_worker_signals[V3270_WORKER_TRANSFER_STATE_SIGNAL], 0, (guint) cfg->st, cfg->msg); + return FALSE; + } + + static void ft_state_changed(G_GNUC_UNUSED H3270 *hSession, LIB3270_FT_STATE st, const char *msg, void *widget) + { + debug("%s(%p,%s)",__FUNCTION__,widget,msg); + + struct bg_state_changed * state = g_malloc0(sizeof(struct bg_state_changed)+strlen(msg)+1); + state->worker = GTK_V3270_FT_WORKER(widget); + state->st = st; + strcpy(state->msg,msg); + + gdk_threads_add_idle_full(G_PRIORITY_LOW,(GSourceFunc) bg_emit_state_changed, state, g_free); + + } + +static gboolean do_timer(V3270FTWorker *worker) { + + debug("%d",(int) worker->timeout.limit - time(NULL)); + + if(time(NULL) > worker->timeout.limit) { + + // Timeout. + debug("%s: Transfer timeout",__FUNCTION__); + + pulse_stop(worker); + timer_stop(worker); + + const gchar * message = _("Transfer operation has timed out"); + + if(worker->hSession) + { + lib3270_ft_destroy(worker->hSession, message); + } + else + { + gtk_progress_bar_set_text(worker->pbar,message); + + g_signal_emit( + GTK_WIDGET(worker), + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL], + 0, + _( "Transfer failed" ), + message + ); + + } + } + + return TRUE; + } + + LIB3270_EXPORT int v3270_ft_worker_start(GtkWidget *widget) + { + V3270FTWorker * worker = GTK_V3270_FT_WORKER(widget); + + if(!(worker->hSession && worker->activity)) + return errno = EINVAL; + + const char *message = NULL; + H3270FT * ft = v3270_ft_activity_begin_transfer(worker->activity, worker->hSession, &message); + + if(!ft) + { + if(!message) + message = N_("Can't start file transfer session"); + + gtk_progress_bar_set_text(worker->pbar,gettext(message)); + + pulse_stop(worker); + g_signal_emit(GTK_WIDGET(widget),v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL], 0, gettext(message), NULL); + + return -1; + } + + struct lib3270_ft_callbacks * cbk = lib3270_get_ft_callbacks(worker->hSession, sizeof(struct lib3270_ft_callbacks)); + + if(!cbk) { + + gchar *message = _( "Can't set callback table" ); + + lib3270_ft_destroy(worker->hSession,message); + + gtk_progress_bar_set_text(worker->pbar,message); + pulse_stop(worker); + + g_signal_emit( + GTK_WIDGET(widget), + v3270_worker_signals[V3270_WORKER_TRANSFER_FAILED_SIGNAL], + 0, + message, + _("The callback table for file transfer was rejected, possible version mismatch on lib3270") + ); + + return -1; + } + + debug("*************************************worker=%p",widget); + lib3270_ft_set_user_data(worker->hSession,widget); + + cbk->complete = ft_complete; + cbk->failed = ft_failed; + cbk->update = ft_update; + cbk->running = ft_running; + cbk->aborting = ft_aborting; + cbk->state_changed = ft_state_changed; + cbk->message = ft_message; + + worker->timeout.limit = time(NULL) + worker->timeout.value; + + if(!worker->timeout.timer) + { + worker->timeout.timer = g_timeout_source_new_seconds(1); + g_source_set_callback(worker->timeout.timer,(GSourceFunc) do_timer,worker,NULL); + g_source_attach(worker->timeout.timer,NULL); + } + + lib3270_ft_start(worker->hSession); + + return 0; + } + diff --git a/src/include/internals.h b/src/include/internals.h index 1e14114..f6fb949 100644 --- a/src/include/internals.h +++ b/src/include/internals.h @@ -78,6 +78,8 @@ G_GNUC_INTERNAL void v3270_activity_list_save(GtkWidget *widget); G_GNUC_INTERNAL void v3270_activity_list_save_as(GtkWidget *widget); + G_GNUC_INTERNAL void gtk_entry_set_text_printf(GtkEntry *entry, const gchar *fmt, ...); + G_END_DECLS #endif // V3270_INTERNALS_H_INCLUDED diff --git a/src/include/v3270/filetransfer.h b/src/include/v3270/filetransfer.h index 741cf2d..3d23568 100644 --- a/src/include/v3270/filetransfer.h +++ b/src/include/v3270/filetransfer.h @@ -129,6 +129,7 @@ LIB3270_EXPORT void v3270_ft_activity_set_remote_filename(GObject *object, const gchar *filename); LIB3270_EXPORT void v3270_ft_activity_set_options(GObject * object, LIB3270_FT_OPTION options); LIB3270_EXPORT void v3270_ft_activity_set_value(GObject * object, LIB3270_FT_VALUE id, guint value); + LIB3270_EXPORT H3270FT * v3270_ft_activity_begin_transfer(GObject * object, H3270 *hSession, const char **message); // FT Dialog widget #define GTK_TYPE_V3270_FT_DIALOG (V3270FTDialog_get_type ()) @@ -159,5 +160,7 @@ LIB3270_EXPORT GtkWidget * v3270_ft_worker_new(); LIB3270_EXPORT void v3270_ft_worker_set_activity(GtkWidget *widget, GObject *activity); + LIB3270_EXPORT void v3270_ft_worker_set_session(GtkWidget *widget, H3270 *hSession); + LIB3270_EXPORT int v3270_ft_worker_start(GtkWidget *widget); #endif // V3270FT_H_INCLUDED diff --git a/src/testprogram/testprogram.c b/src/testprogram/testprogram.c index 5fc3d23..fe89cab 100644 --- a/src/testprogram/testprogram.c +++ b/src/testprogram/testprogram.c @@ -153,12 +153,17 @@ static void ft_clicked(GtkButton G_GNUC_UNUSED(*button), GtkWidget *terminal) GtkWidget * worker = v3270_ft_worker_new(); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),worker,TRUE,TRUE,2); + v3270_ft_worker_set_session(worker,v3270_get_session(terminal)); + GObject * activity = v3270_ft_activity_new(); - v3270_ft_activity_set_local_filename(activity,"local_file"); - v3270_ft_activity_set_remote_filename(activity,"remove_file"); + v3270_ft_activity_set_local_filename(activity,"/tmp/test.txt"); + v3270_ft_activity_set_remote_filename(activity,"remote_file"); + v3270_ft_activity_set_options(activity,LIB3270_FT_OPTION_RECEIVE|LIB3270_FT_OPTION_ASCII|LIB3270_FT_OPTION_REMAP); v3270_ft_worker_set_activity(worker,activity); g_object_unref(activity); + v3270_ft_worker_start(worker); + // GtkWidget * dialog = v3270ftprogress_new(); // GtkWidget * dialog = v3270_ft_dialog_new(terminal); -- libgit2 0.21.2