[cairo] cairo_set_user_data () and other "set_user_data" functions
Daniel Goldman
dagoldman at yahoo.com
Fri Aug 20 16:26:29 PDT 2010
> > I already understood what the function does. What I'm looking for asking is
>a
>
> > specific example. What kind of resource might typically get attached in a
> > real-world case? Yes, the search results show real world use on the API, but
>
> > they shed little or no light on my general question.
>
> Did you actually read any of the functions
>
> > > http://www.koders.com/default.aspx?s="cairo_surface_set_user_data"
>
> pointed you at? Let's take the results and apply some mindful code
> reading skills. Skipping the first few results from the cairo library
> source itself, the first search result is
>
>http://www.koders.com/c/fid8F95E6BFAA83A308AD102E365AAE13ADC9FA682A.aspx?s="cairo_surface_set_user_data"#L34
>4
>
> In the function f_image_surface_create(), you see that it is
> allocating a pixel buffer, creating an image surface for it, and then
> attaching both the pixel format and pixel buffers to the image
> surface. Clearly the purpose of this is to use glib's g_malloc() to
> allocate the large pixel buffer so that the caller doesn't have to
> check for allocation errors (however, it's not careful about
> arithmetic overflow when computing the size, so don't do this.)
>
> The second search result is
>
>http://www.koders.com/cpp/fid5BDE65224ED2830DCED6AFFD8956B029C2396699.aspx?s="cairo_surface_set_user_data"#L48
>8
>
> In the function TestNewSurface(), it is creating an image surface and
> attaching an integer counter value (&destroyed) to it using a dummy
> key (&destruction_key), for the sole purpose of getting a callback to
> SurfaceDestroyNotifier when the surface is destroyed. The
> SurfaceDestroyNotifier sets the value of the destroyed variable to 1
> when it is called. The purpose of the user data in this case is to
> unit test the reference counting mechanism to make sure that indeed,
> the SurfaceDestroyNotifier is called when the last reference to the
> surface has been destroyed.
>
> Skipping past duplicates again, the third result is
>
>http://www.koders.com/csharp/fidEF55CE573B71D4AE98D1F20975C069E72045C435.aspx?s="cairo_surface_set_user_data"#L178
>8
>
> This case is similar to the first case in usage, except the code is a
> C# class, and the pixel buffer allocation mechanism is different
> (Marshal.AllocHGlobal / FreeHGlobal instead of g_malloc/g_free.)
>
> The next result is merely an Ada language binding to the
> cairo_surface_set_user_data() function, so that's not helpful wrt.
> usae. The next result is again managing the lifetime of a pixel
> buffer, as is the next one, and the next one. Skipping ahead to some
> interesting use cases, we find
>
>http://www.koders.com/c/fid69CD1B67619C208294D43A44FEFCBB3109B59FF9.aspx?s="cairo_surface_set_user_data"#L1498
>8
>
> This is gdk_x11_ref_cairo_surface() inside GDK, and what it's doing is
> attaching a cairo surface to a GDK X11 Drawable, so you can draw onto
> the Drawable using cairo. Nifty, no? The purpose of the
> set_user_data call is to set a notifier on surface destruction to
> detach the surface from the drawable.
>
> Skipping ahead over some more duplicates, we see another similar case
> inside GDK
>
>http://www.koders.com/c/fidADDA5A368114609CF9092A6336B27CE9909930AD.aspx?s="cairo_surface_set_user_data"#L70
>0
>
> This is gdk_quartz_ref_cairo_surface(), where the basic usage is
> similar to the x11 case, only it's adding a slightly more complex
> structure (a SurfaceInfo object) to the surface, to track both the
> Drawable and the Quartz context object CGContextRef.
>
> Moving along, we see create_preview_surface_platform() in moo (which
> seems to be some sort of UI framework using cairo)
>
>http://www.koders.com/c/fid7494FC2222E3A5A2770B0103D3354E9763BB497C.aspx?s="cairo_surface_set_user_data"#L228
>8
>
> This function is attaching a windows metafile to a win32 printing
> surface so that the metafile is closed and its handled deleted when
> the last surface reference causes the surface to be destroyed.
>
> The next one is a java binding, so let's skip that. The next one is a
> pixel destructor again, and we've had a lot of those already, so let's
> skip that. More auxiliary resource destruction in GDK, we've had
> those, so skip. Another language binding, skip. Closing a file at
> surface destruction, skip. Killing a pixel buffer, skip. There are
> seven pages of results here which continue in essentially the same
> vein.
>
> Hope that helps,
>
> Joonas
>
Yes, that helps more than I could have expected. I really appreciate your
detailed response.
I did look at the code some, but not nearly in the depth or detail you did. It's
not an efficient way to learn an API, especially a rich and complex API like
cairo. The problem is the cairo API reference docs are somewhat lacking in
providing insight and any kind of big picture. The API reference tells me the
name of the function is "set_user_data" for some object. OK. Then, the parameter
is called "user_data". All right. Finally, the documentation for the parameter
is "user data to attach". Wow! I hope you get the point. A fair amount of the
cairo API reference docs similarly kind of misses the boat. Even if the missing
content were found in tutorials (it's mostly not), it should not be left out of
the API docs. Good, useful API docs explain more about the intention and
usefulness of functions, like the great examples you've provided. Good docs
don't just tersely repeat the names of self-explanatory function and parameter
names.
Thanks,
Daniel
More information about the cairo
mailing list