3
* Library to use the Gnome family of libraries from Lua 5.1
4
* Copyright (C) 2005, 2008 Wolfgang Oertl
5
* Use this software under the terms of the GPLv2 (the license of Gnome).
7
* Library initialization, and a few basic routines which could as well
11
* 2005-07-24 first public release
12
* 2005-08-18 update for Lua 5.1-work6
13
* 2007-02-02 (almost) no global Lua state; use luaL_ref
14
* 2007-10-12 improved modularization of the code; ENUM typechecking
24
#include <string.h> // strcpy
26
#include <stdlib.h> // abort
28
const char msgprefix[] = "[LuaGnome]";
29
const char *thismodulename = "gnome";
33
* Main module for the Lua-Gnome binding.
39
* A method has been found and should now be called.
40
* input stack: parameters to the function
41
* upvalues: the func_info structure
43
static int lg_call_wrapper(lua_State *L)
45
struct func_info *fi = (struct func_info*) lua_touserdata(L,
47
return lg_call(L, fi, 1);
52
* Create a closure for a C (library) function. The function info may be
53
* static, which is for elements of structures, or dynamically created, as
54
* is the case for regular library functions.
56
* XXX when alloc_fi is not 0, when will this memory be freed again?
59
* @param fi Function Info with name, address and signature
60
* @param alloc_fi 0=use fi as-is; 1=duplicate the structure; 2=also duplicate
63
int lg_push_closure(lua_State *L, const struct func_info *fi, int alloc_fi)
66
struct func_info *fi2;
70
lua_pushlightuserdata(L, (void*) fi);
74
fi2 = (struct func_info*) lua_newuserdata(L, sizeof(*fi2));
75
memcpy(fi2, fi, sizeof(*fi2));
79
name_len = strlen(fi->name) + 1;
80
fi2 = (struct func_info*) lua_newuserdata(L, sizeof(*fi2) + name_len);
81
memcpy(fi2, fi, sizeof(*fi2));
82
memcpy(fi2+1, fi->name, name_len);
83
fi2->name = (char*) (fi2+1);
87
return luaL_error(L, "%s invalid call to lg_push_closure", msgprefix);
90
lua_pushcclosure(L, lg_call_wrapper, 1);
96
* A function should be used as a function pointer. If this is a C closure
97
* to a library function, we can use that library function's address directly.
98
* This avoids a C closure for a Lua closure, the invocation of which would
99
* look like this: FFI closure -> closure_handler -> lg_call_wrapper -> library
102
* @return 1 on success, i.e. ar->arg->p has been set to the C function, or 0
105
int lg_use_c_closure(struct argconv_t *ar)
107
lua_State *L = ar->L;
109
lua_CFunction func = lua_tocfunction(L, ar->index);
110
if (!func || func != &lg_call_wrapper)
113
// the first upvalue of this closure is a struct fi
114
if (lua_getupvalue(L, ar->index, 1)) {
115
struct func_info *fi = (struct func_info*) lua_touserdata(L, -1);
116
ar->arg->p = fi->func;
128
* The specified Lua value might contain a closure created with the function
129
* above, or contain a . If so, return the func_info embedded in it, otherwise raise an
132
struct func_info *lg_get_closure(lua_State *L, int index)
135
struct func_info *fi;
137
// verify that this is actually a closure with the correct C function.
138
f = lua_tocfunction(L, index);
140
LG_ERROR(2, "Not a C function, but a %s.",
141
lua_typename(L, lua_type(L, index)));
142
if (f != &lg_call_wrapper)
143
LG_ERROR(3, "Invalid closure.");
145
// the first upvalue is the func_info structure.
146
lua_getupvalue(L, index, 1);
147
fi = (struct func_info*) lua_touserdata(L, -1);
149
LG_ERROR(4, "Invalid closure (upvalue 1 not a userdata)");
156
* Look up a name in the given module. This works for functions, like
157
* gtk.window_new(), and constants, like gtk.WINDOW_TOPLEVEL.
158
* Lua Stack: [1]=gnome [2]=name
161
* @luaparam table The table to look in
162
* @luaparam key The name of the item to look up
163
* @luareturn Either a userdata (for ENUMs) or a closure (for
166
static int lg_generic_index(lua_State *L)
168
size_t name_len, prefix_len = 0;
169
const char *name = luaL_checklstring(L, 2, &name_len);
170
struct func_info fi = { 0 };
174
// Get the module. No checks here because this function is called
175
// by Lua and should always have the correct arguments.
176
lua_getfield(L, 1, "_modinfo");
177
mi = lua_touserdata(L, -1);
182
return luaL_error(L, "%s attempt to look up a NULL or empty string",
184
prefix_len = strlen(mi->prefix_func);
185
prefix_len = MAX(prefix_len, strlen(mi->prefix_constant));
186
if (name_len + prefix_len > sizeof(symname) - 10)
187
return luaL_error(L, "%s key is too long, max is %d", msgprefix,
188
sizeof(symname) - 10);
190
/* if it starts with an uppercase letter, it's probably an ENUM. */
191
if (name[0] >= 'A' && name[0] <= 'Z') {
193
const char *prefix = mi->prefix_constant;
195
typespec_t ts = { 0 };
196
ts.module_idx = mi->module_idx;
198
sprintf(symname, "%s%s", prefix ? prefix : "", name);
199
// strcpy(symname, prefix);
200
// strcat(symname, name);
201
switch (lg_find_constant(L, &ts, symname, -1, &val)) {
202
case 1: // ENUM/FLAG found
203
return lg_push_constant(L, ts, val);
205
case 2: // integer found
206
lua_pushinteger(L, val);
209
case 3: // string found - is on Lua stack
218
// If it starts with "__", then remove that and don't look for
219
// overrides. This is something that overrides written in Lua can use,
220
// to avoid recursively calling itself instead of the Gtk function.
221
if (name[0] == '_' && name[1] == '_') {
222
strcpy(symname, name + 2);
223
if (!lg_find_func(L, mi, symname, &fi))
224
return luaL_error(L, "%s not found: %s.%s", msgprefix, mi->name,
229
// Check for an override (with the function prefix).
230
strcpy(symname, mi->prefix_func);
231
strcat(symname, name);
232
lua_pushstring(L, symname);
234
if (!lua_isnil(L, -1)) {
235
lua_pushstring(L, name);
236
lua_pushvalue(L, -2);
242
// Otherwise, simply look it up
243
if (lg_find_func(L, mi, symname, &fi))
246
// maybe it's a function but with the prefix already added.
247
if (*mi->prefix_func && lg_find_func(L, mi, name, &fi))
250
// Might be a global variable. This is not so common, therefore
251
// it is not checked for earlier.
252
if (lg_find_global(L, mi, symname))
255
// "name" might not need the prefix.
256
if (lg_find_global(L, mi, name))
259
// Maybe it's Windows and a function with _utf8 suffix? While there
260
// are a few with the gtk_ prefix and _utf8 suffix, most have the
261
// g_ or gdk_ prefix, so don't automatically add this prefix.
263
strcat(symname, "_utf8");
264
// sprintf(symname, "%s%s_utf8", prefix_func, name);
265
if (lg_find_func(L, mi, symname, &fi))
270
return luaL_error(L, "%s not found: %s.%s", msgprefix, mi->name, name);
273
lg_push_closure(L, &fi, 2);
275
// cache the result of this lookup, using the key given by the user,
276
// and not necessarily the name of the function that was found.
277
lua_pushvalue(L, 2); // key
278
lua_pushvalue(L, -2); // the new closure
279
lua_rawset(L, 1); // [1]=table
286
* If a module doesn't provide a handler to allocate objects, use this
289
static void *default_allocate_object(cmi mi, lua_State *L, typespec_t ts,
290
int count, int *flags)
292
type_info_t ti = mi->type_list + ts.type_idx;
296
*flags = FLAG_ARRAY | FLAG_NEW_OBJECT;
297
p = g_malloc(ti->st.struct_size * count);
299
*flags = FLAG_ALLOCATED | FLAG_NEW_OBJECT;
300
p = g_slice_alloc0(ti->st.struct_size);
308
* Allocate a structure, initialize with zero and return it.
310
* This is NOT intended for objects or structures that have specialized
311
* creator functions, like gtk_window_new and such. Use it for simple
312
* structures like GtkTreeIter.
314
* The object is, as usual, a Lua wrapper in the form of a userdata,
315
* containing a pointer to the actual object.
318
* @param mi Module that handles the type
319
* @param is_array If true, Stack[2] is the count, else allocate a single
322
* @luaparam typename Type of the structure to allocate
323
* @luaparam ... array size, or optional additional arguments to the allocator
325
* @luareturn The new structure
327
static int lg_generic_new_array(lua_State *L, cmi mi, int is_array)
332
const char *type_name;
334
const char *name_in = luaL_checkstring(L, 1);
338
count = luaL_checknumber(L, 2);
340
return luaL_error(L, "%s Invalid array size %d", msgprefix, count);
343
// add the prefix if available.
344
if (mi->prefix_type) {
345
strcpy(tmp_name, mi->prefix_type);
346
strcat(tmp_name, name_in);
347
type_name = tmp_name;
351
// look for the type; if not found, try again without the prefix.
353
ts = lg_find_struct(L, type_name, 1);
356
ts = lg_find_struct(L, type_name, 0);
359
if (type_name == name_in)
360
return luaL_error(L, "%s type %s* not found\n", msgprefix,
365
/* There may be an allocator function; if so, use it (but only for single
366
* objects, not for arrays); use the optional additional arguments */
371
lg_make_func_name(func_name, sizeof(func_name), type_name, "new");
372
if (lg_find_func(L, mi, func_name, &fi))
373
return lg_call(L, &fi, 2);
376
/* no additional arguments must be given - they won't be used. */
377
luaL_checktype(L, 3, LUA_TNONE);
379
if (mi->allocate_object)
380
p = mi->allocate_object(mi, L, ts, count, &flags);
382
p = default_allocate_object(mi, L, ts, count, &flags);
384
/* Allocate and initialize the object. I used to allocate just one
385
* userdata big enough for both the wrapper and the object, but many free
386
* functions exist, like gtk_tree_iter_free, and they expect a memory block
387
* allocated by g_slice_alloc0. Therefore this optimization is not
390
/* Make a Lua wrapper for it, push it on the stack. FLAG_ALLOCATED causes
391
* the _malloc_handler be used, and FLAG_NEW_OBJECT makes it not complain
392
* about increasing the (non existant) refcounter. */
393
lg_get_object(L, p, ts, flags);
396
struct object *w = (struct object*) lua_touserdata(L, -1);
397
w->array_size = count;
405
* Give the application an idea of the platform. Could be used to select
406
* path separators and more. I have not found a way to determine this
407
* in any other way, so far.
410
* @luareturn The the operating system, e.g. "win32" or "linux".
411
* @luareturn The CPU, e.g. "i386", "amd64"
413
static int l_get_osname(lua_State *L)
415
luaL_checktype(L, 1, LUA_TNONE);
416
lua_pushliteral(L, LUAGTK_ARCH_OS);
417
lua_pushliteral(L, LUAGTK_ARCH_CPU);
421
static int l_void_ptr(lua_State *L)
424
luaL_checktype(L, 2, LUA_TNONE);
425
struct value_wrapper *p = lg_make_value_wrapper(L, 1);
426
return lg_push_vwrapper_wrapper(L, p);
429
static const char _module_info[] =
433
"LuaGnome is a binding to the Gnome family of librarlies, like GLib, GDK,\n"
434
"Gtk and others for easy development of GUI applications.\0"
436
"Copyright (C) 2006, 2008 Wolfgang Oertl\0"
440
* Add some meta information to the new module.
442
static void _init_module_info(lua_State *L)
444
const char *s = _module_info;
447
lua_pushstring(L, s); /* name */
449
lua_pushstring(L, s); /* value */
457
* When a proxy object should be destroyed right away, without waiting for
458
* the garbage collection, this can be used.
460
static int l_destroy(lua_State *L)
462
struct object *o = (struct object*) lua_touserdata(L, 1);
464
// dec_refcount sets the pointer to NULL, which disturbs
465
// lg_invalidate_object (which sets it to NULL itself).
467
lg_dec_refcount(L, o);
470
lg_invalidate_object(L, o);
474
static int l_cast(lua_State *L)
476
luaL_checktype(L, 1, LUA_TUSERDATA);
477
struct object *o = (struct object*) lua_topointer(L, 1);
479
return luaL_error(L, "%s cast with NULL object", msgprefix);
480
const char *type_name = luaL_checkstring(L, 2);
481
typespec_t ts = lg_find_struct(L, type_name, 1);
483
return luaL_error(L, "%s cast to unknown type %s", msgprefix,
485
lg_get_object(L, o->p, ts, FLAG_NOT_NEW_OBJECT);
489
int l_dump_vwrappers(lua_State *L);
490
int l_get_vwrapper_count(lua_State *L);
492
/* methods directly callable from Lua; most go through __index of
493
* the individual modules, which call api->generic_index. */
494
static const luaL_reg gnome_methods[] = {
495
{"get_osname", l_get_osname },
496
{"void_ptr", l_void_ptr },
497
{"dump_vwrappers", l_dump_vwrappers },
498
{"get_vwrapper_count", l_get_vwrapper_count },
499
{"destroy", l_destroy },
508
* This is the structure accessible from library modules and the only way
509
* how library modules can call into the base library.
511
static struct lg_module_api module_api = {
512
LUAGNOME_MODULE_MAJOR,
513
LUAGNOME_MODULE_MINOR,
514
LUAGNOME_HASH_METHOD,
517
lg_register_object_type,
521
lg_generic_new_array,
527
lg_lua_to_gvalue_cast,
532
lg_invalidate_object,
540
#ifdef RUNTIME_LINKING
541
extern const char gnome_dynlink_names[];
544
static struct dynlink gnome_dynlink = {
545
#ifdef LUAGTK_LIBRARIES
546
dll_list: LUAGTK_LIBRARIES,
548
#ifdef RUNTIME_LINKING
549
dynlink_names: gnome_dynlink_names,
550
dynlink_table: gnome_dynlink_table,
555
extern struct call_info *ci_current;
556
static void lg_log_func(const gchar *domain, GLogLevelFlags log_level,
557
const gchar *message, gpointer user_data)
560
call_info_warn(ci_current);
561
fprintf(stderr, "%s\n", message);
562
if (log_level & G_LOG_FLAG_FATAL)
567
* Initialize the library, returns a table. This function is called by Lua
568
* when this library is dynamically loaded. Note that the table is also stored
569
* as the global "gnome" (by the "require" command), and that is accessed
570
* from this library sometimes.
572
* @luaparam name This library's name, i.e. "gnome".
574
int luaopen_gnome(lua_State *L)
576
// get this module's name, then discard the argument.
577
lib_name = strdup(lua_tostring(L, 1));
578
lg_dl_init(L, &gnome_dynlink);
580
lg_debug_flags_global(L);
584
/* make the table to return, and make it global as "gnome" */
585
luaL_register(L, lib_name, gnome_methods);
586
_init_module_info(L);
592
// an object that can be used as NIL
593
lua_pushliteral(L, "NIL");
594
lua_pushlightuserdata(L, NULL);
597
// a metatable to make another table have weak values
598
lua_newtable(L); // gnome mt
599
lua_pushliteral(L, "v"); // gnome mt "v"
600
lua_setfield(L, -2, "__mode"); // gnome mt
602
// Table with all object metatables; [name] = table. When no objects
603
// of the given type exist anymore, they may be removed if weak values
604
// are used; this doesn't make much sense, as a program will most likely
605
// use a certain object type again if it is used once.
606
lua_newtable(L); // gnome mt t
607
lua_setfield(L, 1, LUAGTK_METATABLES); // gnome mt
609
// objects: not a weak table. It only contains references to entries
610
// in the aliases table; they are removed manually when the last alias
611
// is garbage collected.
612
lua_newtable(L); // gnome mt t
613
lua_setfield(L, 1, LUAGTK_WIDGETS); // gnome mt
615
// gnome.objects_aliases. It has automatic garbage collection (weak
618
lua_pushvalue(L, -2);
619
lua_setmetatable(L, -2);
620
lua_setfield(L, 1, LUAGTK_ALIASES); // gnome mt
622
// gnome.typemap is a table that maps hash values of native types to
623
// their typespec_t. It is required in lg_type_normalize.
625
lua_setfield(L, 1, "typemap");
627
// gnome.fundamental_map is a table that maps hash values of fundamental
628
// types to their index in ffi_type_map.
629
lg_create_fundamental_map(L);
631
lua_pop(L, 1); // gnome
634
/* default attribute table of an object */
635
lua_newtable(L); // gnome t
636
lua_setfield(L, 1, LUAGTK_EMPTYATTR);
638
/* execute the glue library (compiled in) */
639
// XXX this should be moved to the modules
640
// luaL_loadbuffer(L, override_data, override_size, "override.lua");
641
// lua_pcall(L, 0, 0, 0);
643
// make gnome its own metatable - it contains __index and maybe other
645
lua_pushvalue(L, -1);
646
lua_setmetatable(L, -2);
649
lua_pushlightuserdata(L, &module_api);
650
lua_setfield(L, 1, "api");
652
// Can't initialize Gtk right away: if memory tracing is used, it must
653
// be activated first; otherwise, initial allocations are not noted and
654
// lead to errors later on, e.g. when a block is reallocated.
655
// gtk_init(NULL, NULL);
657
// set up error logging to be more useful: display which function is
658
// currently running before showing the error message.
659
g_log_set_default_handler(lg_log_func, NULL);
661
/* one retval on the stack: gnome. This is usually not used anywhere,
662
* but you have to use the global variable "gnome". */