I am trying to write a program that shows a moving circle with pthread and a
custom libsigc++ signal to learn how to update a drawing. I use a similar
method of cairo clock in gtkmm example. If I compile and run the program the
terminal shows the following error message if I click on the window after
seeing a moving circle for a while (64 iterations of the loop in
thread_function).

    Fatal IO error 11 (Resource temporarily unavailable) on X server :0.0.

If I comment out win->process_updates( false ); in function
SpecArea::on_new_data, the circle doesn't move until the mouse cursor hovers
over the area.

I will greatly appreciate it if anybody points out the problem. And I also
wonder if this is the right way of updating drawing with pthread.

I am using ubuntu 9.04 64bit, kernel : 2.6.28-16-generic
Here is the code.

#include <unistd.h>
#include <cstdlib>
#include <pthread.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/drawingarea.h>
#include <cairomm/context.h>
#include <iostream>

void *thread_function( void *arg );

class SpecArea : public Gtk::DrawingArea
{
        double xc, yc;
public:
        SpecArea();
        virtual ~SpecArea();
protected:
        virtual bool on_expose_event( GdkEventExpose* event );
        void on_new_data( double x, double y );
};

sigc::signal<void, double, double> signal_new_data;

int main( int argc, char** argv )
{
        Gtk::Main kit( argc, argv );

        Gtk::Window win;
        win.set_title( "Spectrum analyzer" );

        SpecArea area;
        win.add( area );
        area.show();

        pthread_t thread;

        pthread_create( &thread, NULL, thread_function, NULL );

        Gtk::Main::run( win );

        pthread_join ( thread, NULL );

        return 0;
}

void *thread_function( void *arg )
{
        usleep(100000);
        for( int i=1; i<=100; ++i )
        {
                std::cout << i << '\n';
                usleep(10000);
                signal_new_data( i/100., i/100. );
        }
                
        return NULL;
}

SpecArea::SpecArea() : xc(0.), yc(0.)
{
        signal_new_data.connect( sigc::mem_fun( *this, &SpecArea::on_new_data ) 
);
        
        #ifndef GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
        //Connect the signal handler if it isn't already a virtual method 
override:
        signal_expose_event().connect( sigc::mem_fun( *this,
&SpecArea::on_expose_event ), false );
        #endif //GLIBMM_DEFAULT_SIGNAL_HANDLERS_ENABLED
}

SpecArea::~SpecArea() { }

bool SpecArea::on_expose_event( GdkEventExpose* event )
{
        Glib::RefPtr<Gdk::Window> window = get_window();
        if(window)
        {
                Gtk::Allocation allocation = get_allocation();
                const int width = allocation.get_width();
                const int height = allocation.get_height();
                int lesser = MIN(width, height);

                Cairo::RefPtr<Cairo::Context> cr = 
window->create_cairo_context();
                cr->set_line_width(lesser * 0.01);
        
                cr->rectangle( event->area.x, event->area.y, event->area.width,
event->area.height );
                cr->clip();

                cr->save();
                cr->arc( xc*width, yc*height, 0.1*lesser, 0.0, 2.0 * M_PI );
                cr->set_source_rgb( 0.9, 0.0, 0.0);
                cr->fill_preserve();
                cr->restore();
                cr->stroke();
        }
        
        return true;
}

void SpecArea::on_new_data( double x, double y )
{
        xc = x;
        yc = y;

        Glib::RefPtr<Gdk::Window> win = get_window();
        if( win )
        {
                Gdk::Rectangle rec( 0, 0, get_allocation().get_width(),
get_allocation().get_height() );
                win->invalidate_rect( rec, false );
                //win->process_updates( false );
        }
}
-- 
View this message in context: 
http://old.nabble.com/Moving-circle-program-%28-redrawing-problem-%29-tp26314511p26314511.html
Sent from the Gtkmm mailing list archive at Nabble.com.

_______________________________________________
gtkmm-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Reply via email to