Ok, so nickle isn't the worlds most popular
language. So why would I spend a couple of days building a binding to cairo
for it? Mostly because I like to code in nickle and I wanted some way to
get simple graphics up on the screen for plotting and the like. However,
it's also been a good way to get back into the heart of cairo and see how
things look.

Instead of a "direct" binding to cairo, I've created a slightly higher level
mechanism where nickle exposes none of the underlying window system details
and instead simply provides a 'window' upon which things can be drawn. This
means that the process of drawing is as simple as:

The back end code uses gtk+ instead of raw Xlib
because that way I get all of the ICCCM hints set and a whole lot of help
with threading. I run the gtk+ code in a separate thread from nickle and
have nickle just paint bits through cairo to a pixmap. Wake up the gtk+
thread and have it copy the pixmap to the window. Resize is handled by
creating a new pixmap of the new size, copying the old data (or as much as
will fit) to the new pixmap and repainting the screen.

The gtk+ thread also receives input, and writes simple string events to a
pipe which can be read by the nickle code without a lot of hassle.
Right now, it just does mouse input, keyboard input is a lot harder, so I'll
leave that until I really need it. Probably I'll send key up/down events
and also UTF-8 strings; that way apps can get what they need without a lot
of work.

The other piece of this work is in learning how to implement a usable
foreign function interface in nickle. I've put off this work in the hope
that I'd have a sudden flash of brilliance about how to make this all just
work without a lot of per-library stub writing. After doing all of that
stub generation by hand, I learned that there is a lot of repetitive stuff,
but also a huge amount of semantic knowledge about how both cairo and nickle
work needed to successfully glue things together.

The biggest problem (no surprise here) was the difference of memory
management methods. Nickle, like any sensible language, has automatic
storage allocation with a garbage collector. cairo, like any sane C libary
uses reference counts with no recursive data structures. It's not hard to
get a finalizer called from nickle to dereference the cairo object. The
trick is knowing what other places need references added or subtracted. And
that takes an intimate knowledge of the cairo internals, something which
can't be automatically abstracted from the headers. So, the goal of
automatically gaining access to cairo from nickle without writing any
cairo-specific code doesn't seem entirely possible.

Still, it seems like at least some of the work needed to generate a language
binding can be automated; the busy work of creating nickle datatypes
cooresponding to the exposed cairo structures and enums could surely be
streamlined somehow. And, the constant nickle↔C datatype conversions should
permit some automation. But, if that automated result needs to be
hand-edited to make it usable, the utility of automatic generation is
greatly reduced; it wouldn't aid maintenance of the resulting library at
all. Future experimentation is clearly needed here.

For those with an experiemental bent, the bits needed for all of this are
available from CVS on either nickle.org or
cairographics.org.