

Gtk-2 Binding for Lua 5.1
=========================

After finding the combination of Python and Gtk2 somewhat bloated, I looked for
another possibility.  gtk-server (at gtk-server.org) is already a step in the
right direction, but for big projects it looks rather limited.  As the previous
lua-gnome project apparently is defunct, I wrote a small library to interface
Lua with Gtk-2.0 (currently Lua 5.0 and Gtk 2.6.8).  It is supposed to work
under Linux and also Windows, but the latter hasn't been tested well and surely
needs some work.

Features:

 - all Gtk, Atk, Pango and GLib functions are available
 - connect() any signals to Lua functions (callbacks)
 - object-oriented calls are possible like win:show_all()
 - small footprint
 - probably efficient, too, but I'd have to do some tests

Memory management: gtk has reference counting, which is used, and of course Lua
has its garbage collection.  You don't have to worry about memory.  Gtk returns
pointers to widgets, these are stored in small user data objects (containing
only the pointer and a meta class pointer).


Callbacks: several parameters are passed:

 - first any additional parameters the user has specified for the gtk:connect
   call.  Tradionally (gtk, pygtk) these additional parameters are passed last
   to the signal handler, but I want to have "self" as the first parameter
 - next is the widget that originated the signal
 - finally all the parameters that gtk passes for this signal


Usage: after proper installation, this should work:

require "gtk2"
gtk.init(nil, nil)
win = gtk.window_new(gtk.GTK_WINDOW_TOPLEVEL)
win:connect('destroy', gtk.main_quit)
win:show()
gtk.main()

The list of Gtk functions, structures and enums is generated by a Perl script
(included) from the debugging information present in a minimal compiled C file
(requires binutils, only for Linux).  The resulting data is dumped into several
compileable .c files and are compiled into the library and is then applicable
to the Windows platform as well.



WARNING: this is BETA software, so expect some misbehavior.  Please send
feedback to wolfgang.oertl@gmx.at.


Data structures
===============

Callbacks: when you call connect a signal, a Lua function is provided by your
application.  A callback_info structure is allocated per signal connection. It
contains following information:

	ref		Reference to a Lua closure
	L		the Lua State this belongs to
	query		Information about the signal from g_type_query.

When Gtk calls such a callback, then the function do_callback builds a proper
Lua stack and invokes the user provided Lua function.



About GtkWindow refcounting
---------------------------

When you create a GtkWindow with gtk.window_new(), the returned window does not
have a floating reference as is usual with other widgets.  The reason is that
this widget is in the toplevel_list of Gtk; therefore it has two regular
references: one for the Lua proxy object, and one from Gtk.  If you just
"forget" about the GtkWindow, it will not be garbage collected.  Instead, you
have to call w:destroy() on it.


Performance
===========

Some tests with valgrind show that this binding, as well as Lua itself, account
for only a minimal part of the runtime.  Further optimization is therefore
currently not a goal.

# make sure that the script calls gtk.set_debug_flags("valgrind")
valgrind --tool=callgrind lua [script]
kcachegrind



Enum encoding
=============

  A list of nearly 5000 constants are currently defined; most of them are
ENUMs, but lots of integers (a few negative) and strings are also stored.  You
can access them directly with gtk.CONSTANT_NAME, like gtk.GTK_WINDOW_TOPLEVEL
or gtk.GTK_STOCK_OK.

  Bits of the first byte: TSNh hhhh

	T	if set, a type_idx is included
	S	if set, this is a string.
	N	if set, this is a negative number; unused for strings
	h	if T==1, high order bits of type_idx; else for a number,
		high order bits of the value.

  If T is set, another byte follows with the lower 8 bits of the type_idx.
  if S is set, the string follows (without terminating zero byte)

  Otherwise, an integer follows, with the higher order bytes first.

  Encoding happens in script/common.lua, decoding in src/data.c.


