Moving circle program ( redrawing problem )



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.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]