|
View:
New views
8 Messages
—
Rating Filter:
Alert me
|
|
|
Redirecting cout to a TextBufferHi all,
I'm using gtksourceviewmm as terminal-like widget, and I want to redirect std::cout to this widget. Currently I'm doing something like this in my constructor: std::ostringstream outs; std::cout.rdbuf (outs.rdbuf ()); and then I have a function 'update' that looks something like this bool update (int timer_number) { // Update text output buffer->insert (buffer->end(), outs.str ()); outs.str (""); // Empty stream return true; } this function is then called on a reglar basis using a 'Glib::signal_timeout'. This works, but the timer has to have a very high frequency if the output should appear smoothly. So, I'm not really a fan of this approach. Can I somehow redirect 'std::cout' directly to the TextBuffer? Thanks, Søren _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBufferI guess you should set up a watch on stdout using Glib::IOChannel. I'm not sure how to do this for C++ streams since the IOChannel API, while wrapped into C++, still operates on C FDs only, but this would solve the problem.
2008/5/10 Søren Hauberg <hauberg@...>: Hi all, _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBuffer2008/5/10 Milosz Derezynski <internalerror@...>:
> I guess you should set up a watch on stdout using Glib::IOChannel. I'm not > sure how to do this for C++ streams since the IOChannel API, while wrapped > into C++, still operates on C FDs only, but this would solve the problem. Thanks, I'll try that. Is such an approach portable? I mean, does it work on Windows? Søren _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBufferI don't really know anything about Windows programming but i'd imagine the Windows C runtime offers an stdout and stderr the same way as under *nix.
2008/5/11 Søren Hauberg <hauberg@...>: 2008/5/10 Milosz Derezynski <internalerror@...>: _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBufferOn Sat, 10 May 2008, Søren Hauberg wrote:
> Hi all, > I'm using gtksourceviewmm as terminal-like widget, and I want to > redirect std::cout to this widget. Currently I'm doing something like > this in my constructor: > > std::ostringstream outs; > std::cout.rdbuf (outs.rdbuf ()); Caveat: I don't know much about gtksourcemm but I do know something about STL streambufs. If the above code works (its an interesting idea that I have not seen before), then my advice would be subclass your own streambuf. You'll need to overload the the sync and overflow members. These have slightly weird actions and (on first viewing) appear non trivial. The advantage of this appreoach is that the source view will only be updated when 1) the buffer runs out, 2) the stream explicitly asks for it, usually via stream.sync() being called. This (correctly) puts the control of the updates in the hands of the user of the stream, rather than having to wait for timeouts. Here is an (untested) example based on a streambuf I wrote for encoding streams into base64, class ogsbuf : public std::streambuf { public: const static int kZBufferSize = 2048; typedef unsigned char char_type; typedef int int_type; typedef std::streampos pos_type; typedef std::streamoff off_type; private: gtksourceviewmm *destination; unsigned char buffer[kZBufferSize]; public: explicit ogsbuf(gtksourceviewmm *_destination) : destination(_destinination) { setp((char *)buffer, (char *)buffer + kZBufferSize); } ~ogsbuf() { sync(); } protected: inline int sync() { // pbase() is an unsigned char * pointing to the data to be written to the destination // pptr() is an end pointer for the data. // pptr() - pbase() is the length of the data in the buffer destination->append(pbase(), pbase() - pptr()); setp((char *)buffer, (char *)buffer + kZBufferSize); return 0; }; inline int overflow(int ch = traits_type::eof()) { int ret = sync(); *pptr() = ch; pbump(1); return ret; }; }; Then do ogsbuf gsb(ptrToSourceView); std::cout.rdbuf (gsb); Charlie - Metropolis Data Consultants - 07976 028167 - 01223 763758 _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBufferOn Sun, 11 May 2008, Milosz Derezynski wrote:
> I don't really know anything about Windows programming but i'd imagine the > Windows C runtime offers an stdout and stderr the same way as under *nix. Oh, if that were true everyone would be a lot happier. It depends on which flags you give the compiler. I use mingw32 to cross compile. If you give it -mwindows you don't get stdout/stderr/stdin and you also don't get a nasty empty console window when you invoke the program from Explorer. What actually happens when you try to use stderr/stdout from a -mwindows program also varies depending on version of mingw and version of windows. Sometimes your bytes just get ignored, sometimes an exception is raised, sometimes the program tight loops, sometimes it burns your toast and scares your cat. Charlie - Metropolis Data Consultants - 07976 028167 - 01223 763758 _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBuffer2008/5/12 Charles McLachlan <cim20@...>:
> If the above code works (its an interesting idea that I have not seen > before), then my advice would be subclass your own streambuf. You'll need to > overload the the sync and overflow members. These have slightly weird > actions and (on first viewing) appear non trivial. I haven't had the time to actually implement this, but it seems just like the approach I was looking for. Thanks, Søren _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
|
|
Re: Redirecting cout to a TextBuffer2008/5/12 Charles McLachlan <cim20@...>:
> On Sat, 10 May 2008, Søren Hauberg wrote: > >> Hi all, >> I'm using gtksourceviewmm as terminal-like widget, and I want to >> redirect std::cout to this widget. Currently I'm doing something like >> this in my constructor: >> >> std::ostringstream outs; >> std::cout.rdbuf (outs.rdbuf ()); > > Caveat: I don't know much about gtksourcemm but I do know something about > STL streambufs. > > If the above code works (its an interesting idea that I have not seen > before), then my advice would be subclass your own streambuf. You'll need to > overload the the sync and overflow members. These have slightly weird > actions and (on first viewing) appear non trivial. > > The advantage of this appreoach is that the source view will only be updated > when 1) the buffer runs out, 2) the stream explicitly asks for it, usually > via stream.sync() being called. This (correctly) puts the control of the > updates in the hands of the user of the stream, rather than having to wait > for timeouts. So, I finally got my act together and implemented your idea, so I thought I'd report back. Basically, your idea works great. Some modifications were necessary, so I thought I'd post the code in case anybody wanted something similar: class ogsbuf : public std::streambuf { private: const static int kZBufferSize = 2048; Glib::RefPtr<Gtk::TextBuffer> destination; char *buffer; public: explicit ogsbuf (Glib::RefPtr<Gtk::TextBuffer> &_destination) : destination (_destination) { buffer = (char*)malloc (sizeof (char) * kZBufferSize); setp (buffer, buffer + kZBufferSize); } ~ogsbuf () { sync (); clear (); } void clear () { free (buffer); } protected: inline int sync() { // pbase () is an unsigned char * pointing to the data to be written to the destination // pptr () is an end pointer for the data. destination->insert (destination->end (), pbase (), pptr ()); setp (buffer, buffer + kZBufferSize); return 0; } inline int overflow (int ch = traits_type::eof ()) { const int ret = sync (); *pptr () = ch; pbump (1); return ret; } }; Thanks, Søren _______________________________________________ gtkmm-list mailing list gtkmm-list@... http://mail.gnome.org/mailman/listinfo/gtkmm-list |
| Free Forum Powered by Nabble | Forum Help |