RE: Re: Re: Getting a Cairo context
- From: "Sergei Naumov" <vomus rambler ru>
- To: "Gtk App Devel List" <gtk-app-devel-list gnome org>
- Subject: RE: Re: Re: Getting a Cairo context
- Date: Wed, 25 Mar 2015 16:45:59 +0300
24.03.2015, 18:59:07 пользователь Emmanuele Bassi (ebassi gmail com) написал:
1. create the widget instance
2. realize it
3. create a similar Cairo surface from the GdkWindow of the widget
4. store Cairo surface on the widget instance; you can use a
subclass or g_object_set_data(), with a preference for the former
5. connect a callback to/override the class closure of the ::draw signal
a. in the draw signal handler, you take the surface and use it a
source to draw on the cairo_t given to you; you can use a boolean flag
to know whether or not the contents of the surface are okay to use
6. fire off a thread, and pass the pointer to widget to the thread function
7. inside the thread function, draw on the surface
8. at the end of the thread, schedule a redraw in the main thread
a. use gdk_threads_add_idle() with a callback and pass the widget
pointer as the data
b. from within the callback, set the boolean flag that tells the
::draw callback to use the surface as a source, and call
gtk_widget_queue_draw()
It's safe to draw on Cairo surfaces from different threads, assuming
only a thread at a time does it; it's not safe to use GTK API from
different threads, though. That's why you can create a surface from
the main thread, and draw on it in a separate thread — as long as you
ensure that all the operations involving GTK happen on the main
thread.
Ok. I am going to try it all out but I have a few questions:
1) do you know any example code that does what you are describing?
2) there is something I do not understand in (5). Do you mean something like this:
plotwindow_surface = gdk_window_create_similar_surface(gtk_widget_get_window(gcu.plotwindow),
CAIRO_CONTENT_COLOR,_DISPLAY_X,_DISPLAY_Y/2);
g_object_set_data(G_OBJECT(gcu.plotwindow),"plotwindow",(gpointer)plotwindow_surface);
g_signal_connect( G_OBJECT( gcu.plotwindow ), "draw", G_CALLBACK( ev_plotwindow_draw ), NULL );
in the ev_plotwindow_draw() I extract data (i.e. the surface) from gcu.plotwindow and use cairo drawing
functions to draw in it. This is going to be my setup draw (axes, tickmarks, etc). Then because I use
g_timeout_add_seconds() to fire up the thread, I'd have to change it to something like that
g_timeout_add_seconds(MODBUS_WAKEUP_SECS,update_from_modbus,gcu.plotwindow)
But the call g_signal_connect to a "draw" will create another surface. Will it not? And would need to pass a widget in
g_timeout_seconds() if gcu.plotwindow is global in my code? I could get rid of this "gobality" though.
-- Sergei
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]