Installation and requirements
*Introduction
Goals
Development History
Features
*Examples
*GObject binding: using objects, handling memory
*Using Gtk+ in Lisp: Gtk+, Widgets, main loop, threading
*Advanced GObject: defining objects, creating custom gobject classes, overriding and implementing methods and properties
*Internals: how gobject binding is implemented
CL-GTK2 package is a Common Lisp binding for Gtk+ and related libraries. This package enables Lisp developers to develop Gtk+-based GUI applications.
The goal of CL-GTK2 is to provide portable (modulo threading, metaobject protocol, FFI), extensible and feature-complete binding for Gtk+ and set of related libraries (GLib, GObject, Gdk, Pango, Cairo, GdkPixbuf, GtkSourceView, etc.)
Gtk+ is writtent in C and uses object-oriented style of programming with support of GObject library. GObject provides classes, objects, memory management via reference counters, classes introspection, signals, properties. Goal includes "lispy" interface to GObject-based libraries. This means that GObject classes should map into CLOS classes, GObject instance into CLOS instances, properties should match to slots, it should be possible to attach closures as signal handlers. It should be possible to define GObject classes, implement properties, methods, signals, interfaces from lisp.
All memory management (object instances, closures, signal handlers, etc.) should be automatic. When applicable, optional support for manual management (using refcounts) should be provided for perfomance reasons.
All Gtk+ classes should be mapped, and the rest of the API should be mapped in lispy way. Support for NIH features should not be provided (e.g., do not expose GSList, GList, GHashtable, GUri but rather transparently convert to/from them).
Error handling should be provided; GObject/Gtk warnings and errors should be exposed as conditions. It should not be possible to bring Gtk+ into incostistent state when error in lisp code called from Gtk occurs (e.g., error in signal handler should not cause fatal errors but rather should be handleable).
CL-GTK2 should be threadsafe: it should be possible to make actions under the Gdk lock, and make actions from withing the GUI thread.
Ease of extending and updating to reflect progress of Gtk+ is also important.
CL-GTK2 should run main-loop threadedly; it should be possible to interactively modify the code while the GUI program is running.
This project was started by Kalyanov Dmitry in 2008. It was a hobby project to address the (perceived or real) lack of good portable GUI libraries for Common Lisp and to be able to use it for writing diploma (or is it called "graduate"?) project during final course of the university.
Initial intent was to use SWIG[1] in order to be able to generate all of the code. After some experimenting, it was found out that use of SWIG would not help to achieve the goals. First of all, in order to create "lispy" bindings, a lot of integration should be done: object systems, memory management, passing closure and values, type mapping (G(S)List to list, GCallback/GCLosure to functions, etc.). SWIG is not of much help here.
So, it was decided to use CFFI and manually map all of the API. First, base infrastructure was created (definition of basic types, maps for basic types, integration with GObject object system and memory management, introspection of GObject types). Then large chunks of API were mapped with automatic generation of classes definitions. Then missing properties were added and functions were mapped.
In order to map GtkTreeModel, preliminary support for subclassing and implementing GObjects was introduced. With its help, lispy ArrayListStore (analog for GtkListStore) was implemented.
At the moment, next version of GObject binding using the CLOS MOP is being developed. It pretty much obsoletes class generation macroses and is neede in order to be able to make lispy maps of GObject methods into CLOS generic functions and to subclass GObject classes.
For future development, using GObjectIntrospection seems the definite way.
[1] Simplified Wrapper and Interface Generator; a program that automatically parses C and C++ header files and generates the binding code for many languages, including Common Lisp (targetting CFFI).
Short summary of features provided by CL-GTK2:
Mapping from GObject to CLOS with (partial) support for creating subclasses, overriding methods
Automatic memory management (with optional support for manual reference counting)
Lispy interface to related libraries (currently only to GLib, GObject, Gdk, Gtk)
Lispy mapping of Gtk+ API
Custom ListStore (TreeStore to be done) for GtkTreeModel
Partial error management (closures are invoked with restarts making it possible to cancel signal handling without crashing Gtk+)
Some high-level features based on Gtk+ API: with-progress-bar, with-message-error-handler