views:

202

answers:

0

Hi, I'm looking for a way to redirect stdout to a Gtk::TextView widget in gtkmm. Ideally, I want it to work both on Windows and UNIX-like OSes.

So far, I've tried to redirect stdout to a file, then monitor changes to this file using Glib, like so (highly inspired from the gtkmm examples on gnome.org) :

#include <stdio.h>
#include <fcntl.h>
#include <gtkmm-2.4/gtkmm.h>

// In main  
freopen("stdout.log", "w", stdout);  
MyClass mc;  
Gtk::Main::run(mc);  
fclose(stdout);  

// Global variables :  
int fd;
Gtk::TextView tv;  
Glib::RefPtr<Gtk::TextBuffer> txtBuffer;  
Glib::RefPtr<Glib::IOChannel> iochannel;

// In constructor of MyClass :  
fd = open("stdout.log", O_RDONLY);  
Glib::signal_io().connect(sigc::mem_fun(*this,&MyClass::on_stdout_change), fd, Glib::IO_IN);  
iochannel = Glib::IOChannel::create_from_fd(fd);  
txtBuffer = tv.get_buffer();  

// Callback method on_stdout_change :  
bool MyClass::on_stdout_change(Glib::IOCondition io_condition) {  
    if ((io_condition & Glib::IO_IN) == 0) {   
        std::cerr << "Invalid file response" << std::endl;
    }  
    else {  
        Glib::ustring buf;  
        #ifdef GLIBMM_EXCEPTIONS_ENABLED  
        iochannel->read_line(buf);  
        #else  
        std::auto_ptr<Glib::Error> ex;  
        iochannel->read_line(buf, ex);  
        if(ex.get())  
            std::cerr << "Error: " << ex->what() << std::endl;  
        #endif //GLIBMM_EXCEPTIONS_ENABLED  

        Gtk::TextIter iter = txtBuffer->end();  
        txtBuffer->insert(iter, buf);  
    }
   return true;
}

Now, this compiles and runs, but it hangs right after the application window appears. The window remains gray and empty. If I try to send buf to std::cerr, I can see in the terminal window that many blank lines are being written. If that is so, it must mean there is constant calling of the callback function, as if data was ready to be read from stdout.log constantly. I would expect there would only be something to be read when I actually send stuff to stdout.

Any suggestions on how to do this or explanations about what is happening are greatly appreciated.