[gtk] Fortschrittbalken für cdrecord -v
-
Hallo
Ich will mit gtk+ eine Fortschrittbalken erzeugen. Mein programm ruft irgendwann cdrecord auf die Fortschrittbalken sollte den Fortschritt von cdrecord anzeigen.
Ich hab folgende Funktion geschrieben:
int gtk_exec(const gchar* file, GList* argv) { gint len, i, status; gchar **ar, **tmp, *string; len = g_list_length(argv); ar = g_malloc(sizeof(gchar*)); if(!ar) return -1; ar[0] = file; for(i = 0; i < len; ++i) { tmp = g_realloc(ar, sizeof(gchar*) * ( i + 2)); if(!tmp) { g_free(ar); return -1; } if(tmp != ar) ar = tmp; string = g_list_nth_data(argv, i); ar[i + 1] = string; } tmp = g_realloc(ar, sizeof(gchar*) * ( i + 2)); if(!tmp) { g_free(ar); return -1; } if(tmp != ar) ar = tmp; ar[i + 1] = NULL; switch(fork()) { case -1: perror("vfork"); g_free(ar); return -1; break; case 0: execvp(file, ar); _exit(EXIT_SUCCESS); break; } wait(&status); g_free(ar); return 0; }
Nun, ich kann mit dieser Funktion cdrecord aufrufen. Aber das GTK Programm bleibt sozusagen intaktiv, d.h. der Knopf bleibt gedrückt und das GTK Programm ist wie eingefroren. Wenn aber das Programm beendet, kehrt das GTK Programm zum Leben. D.h. eine Fortschrittbalken wäre da nicht möglich.
Außerdem wird die Ausgabe vom aufgerufenen Programm auf stdin geschrieben, so dass ich im meinem GTK Programm die Ausgabe nicht parsen kann, so dass ich die Fortschrittbalken irgendwie steuere. Ich hab eigentlich keine Ahnung, wie ich das machen sollte.
Danke
Gruss
Pablo
-
*bump*
Kann mir wirklich keiner helfen?
-
Ich hab mal ein Programm geschrieben, dass mir wwDial startet und seine Ausgabe in ein Textfeld einträgt. Das müsstest du modifizieren können.
Ich hab noch ein paar Kommentare hinzugefügt...
/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <gtk/gtk.h> /* Glade Includes */ #include "support.h" #include "main_window.h" pid_t child_pid = 0; gint WriteOutputHandler = 0; /* Startet den Kindprozess */ int ExecuteCapture( int *out_pipe, const char *pszCommand ) { if(pipe(out_pipe) != 0 ) { perror( "pipe FIALED" ); return 1; } int child_pid; if( ( child_pid = fork() ) == 0 ) { /* child */ close( out_pipe[0] ); /* map all outputs to our pipe */ if (out_pipe[1] != STDERR_FILENO) { if (dup2( out_pipe[1], STDERR_FILENO ) != STDERR_FILENO) { perror("dup2 error on stdout"); } close(out_pipe[1]); } /* execute the process */ if (execl("/bin/sh", "sh", "-c", pszCommand,(void *)NULL) < 0) { perror("execl error"); } write( out_pipe[1], "ERROR", 6 ); return 0; } /* this isn't used for the parent */ close( out_pipe[1] ); return child_pid; } /* Fügt Text, dem Textfeld an */ void GtkTextBufferInsertText (GtkTextBuffer *buffer, char *pszText ) { GtkTextIter iter; /* move the cursor to the end of text */ gtk_text_buffer_get_iter_at_offset (buffer, &iter, -1); /* insert the text */ gtk_text_buffer_insert (buffer, &iter, pszText, -1); } /* Wird bei Daten auf stdin aufgerufen */ void CaptureOutput(GtkTextBuffer *pTextBuffer, gint source, GdkInputCondition cond) { char pBuffer[64]; int l; if( (l = read( source, pBuffer, 63 ) ) > 0 ) { pBuffer[l] = 0; GtkTextBufferInsertText( pTextBuffer, pBuffer ); } else { if( WriteOutputHandler != 0 ) { gdk_input_remove ( WriteOutputHandler ); WriteOutputHandler = 0; } } } /* Diese Funktion startet einen Befehl und ruft bei Daten über stdin die Funktion CaptureOutput auf */ int ExecuteCaptureGTK( const char *pszCommand, GtkTextBuffer *pTextBuffer ) { int out_pipe[2]; int bRunning = 0; if( child_pid != 0 ) { bRunning = (waitpid( child_pid, 0, WNOHANG ) == 0); } if( !bRunning ) { /* new child process */ child_pid = ExecuteCapture( out_pipe, pszCommand ); if( child_pid == 0 ) return 0; /* catch output of child */ WriteOutputHandler = gdk_input_add( out_pipe[0], GDK_INPUT_READ, (GdkInputFunction) CaptureOutput, pTextBuffer); } else { GtkWidget *dialog; dialog = gtk_message_dialog_new (0, (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "wvDial already running.\n" "Please disconnect first."); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } } int DialConnect( GtkWidget* pWidget ) { set_status_text( "Connecting..." ); GtkWidget *pMainLog; /* Das Widget, dem der Text angefügt wird */ pMainLog = lookup_widget( pWidget, "main_log" ); ExecuteCaptureGTK( "wvdial", gtk_text_view_get_buffer (GTK_TEXT_VIEW (pMainLog)) ); return 0; } /* Diese Funktion beendet wvDial */ int DialDisconnect() { if( child_pid != 0 ) { /* send wvdial the 'CTRL-C' signal */ kill( child_pid, SIGINT ); waitpid( child_pid, 0, 0 ); child_pid = 0; } return 0; }
-
danke schön, ich werde mir den Code anschauen.