Re: Re: Re: Getting a Cairo context



Hi;

On 25 March 2015 at 13:45, Sergei Naumov <vomus rambler ru> wrote:

    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?

Not off hand, no.

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.

More or less, yes, that's how you could structure your code.

Another option is to subclass the GtkDrawingArea widget and add
members to the instance structures.

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

Why are you using a timeout to fire of a thread? Timeouts do not use a
separate thread: they are part of the main loop. Are you calling
g_thread_new() from a timeout callback?

I sense some underlying confusion, here.

Ciao,
 Emmanuele.

-- 
https://www.bassi.io
[ ] ebassi [ gmail com]


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