Thanks everyone, I have this working now :-) Special thanks to Tomas! The program still freezes for a very brief moment, but then it comes quickly back to life with wonderful data spilling onto the notebook pages.
Here's the target function: void on_confirm_okbutton_clicked (GtkWidget *widget, gpointer data) { gchar *tmp_ssh_command; gchar **ssh_command; gint i = 0; gint count = g_strv_length(serverlist); /* remove any existing notebook pages */ remove_notebook_pages(GTK_NOTEBOOK(notebook1)); /* start a process for each server */ for (i=0; i<count; i++ ) { tmp_ssh_command=g_strjoin(" ", SSH_PROGRAM, serverlist[i], MAINSCRIPT_PROGRAM, command, serverlist[i], NULL); ssh_command = g_strsplit(tmp_ssh_command, " ", -1); /* create notebook page with textview for this process */ GtkWidget *textview; GtkWidget *scroller; GtkTextBuffer *buffer = gtk_text_buffer_new(NULL); GtkWidget *label = gtk_label_new(serverlist[i]); textview = gtk_text_view_new_with_buffer(buffer); scroller = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(scroller), textview); gtk_notebook_insert_page(GTK_NOTEBOOK(notebook1), scroller, label, i); gtk_widget_show_all(notebook1); /* spawn off the process */ GPid pid; gint stdout; GIOChannel *gioout; g_spawn_async_with_pipes( NULL, ssh_command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &pid, NULL, &stdout, NULL, NULL ); gioout = g_io_channel_unix_new(stdout); g_io_add_watch_full(gioout, G_PRIORITY_DEFAULT, (GIOCondition)(G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL), (GIOFunc)watch_out_callback, textview, NULL); g_io_channel_unref(gioout); g_free(tmp_ssh_command); } gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook1), 0); gtk_widget_show(progressdialog); gtk_widget_hide(confirmdialog); } And here is the callback function. The new item I added that I think helped stop the program from freezing is the addtion of an iter and a call to 'gtk_text_buffer_get_end_iter'. gboolean watch_out_callback (GIOChannel *channel, GIOCondition condition, gpointer data) { GIOStatus status = G_IO_STATUS_NORMAL; GtkTextView *textview; GtkTextBuffer *buffer; GtkTextIter iter; GtkTextMark *mark; gchar buf[512]; gsize bytes_read; /* set up pointers to our textbuffer */ textview = GTK_TEXT_VIEW((GtkWidget *)data); buffer = gtk_text_view_get_buffer(textview); gtk_text_buffer_get_end_iter(buffer, &iter); /* send ssh output to our gui */ status = g_io_channel_read_chars(channel, buf, sizeof(buf), &bytes_read, NULL); if (bytes_read) { gtk_text_buffer_insert(buffer, &iter, buf, bytes_read); } /* decide if we should close the channel */ switch (status) { case G_IO_STATUS_NORMAL: return TRUE; default: return FALSE; } } Thanks for helping me get through this. It sure was the most difficult part of this program. I still have a lot to do, but mainly cosmetic compared to this. Thanks! -- Tony _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list