Hello community, here is the log from the commit of package lua-lgi for openSUSE:Factory checked in at 2016-05-30 09:58:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lua-lgi (Old) and /work/SRC/openSUSE:Factory/.lua-lgi.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lua-lgi" Changes: -------- --- /work/SRC/openSUSE:Factory/lua-lgi/lua-lgi.changes 2015-09-03 18:09:57.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.lua-lgi.new/lua-lgi.changes 2016-05-30 09:58:17.000000000 +0200 @@ -1,0 +2,13 @@ +Sat May 28 15:43:12 UTC 2016 - [email protected] + +- Update to version 0.9.1: + * Marshal NULL strings as nil instead of empty strings. + This allows use of e.g. DataInputStream:read_line() APIs. + * Add support for arrays with lengths as struct fields. + * Allow GLib.Variant construction for lightuserdata. + * Fix gtop binding (certain structs could not be imported). + * Adapt to new set of annotations in newer GLib. + * Assorted Lua5.3 fixes, lgi is now fully Lua5.3 compatible. + * Fix binding of Gdk.Rectangle from newer Gdk. + +------------------------------------------------------------------- Old: ---- lgi-0.9.0.tar.gz New: ---- lgi-0.9.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lua-lgi.spec ++++++ --- /var/tmp/diff_new_pack.Ifv9lW/_old 2016-05-30 09:58:18.000000000 +0200 +++ /var/tmp/diff_new_pack.Ifv9lW/_new 2016-05-30 09:58:18.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package lua-lgi # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2012 Adam Mizerski <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -18,8 +18,8 @@ %define _name lgi -Name: lua-%{_name} -Version: 0.9.0 +Name: lua-lgi +Version: 0.9.1 Release: 0 Summary: Lua bindings to GObject libraries License: MIT @@ -32,8 +32,10 @@ BuildRequires: pkgconfig(libffi) BuildRequires: pkgconfig(lua) %if 0%{?suse_version} > 1320 -# LUA in openSUSE 13.2, Leap and SLE12 does not yet provide Lua(API), and as such we can only depend on it in TW -# we need the 'branch' of lua this package was built against (lua_version nicely provides this info) +# Lua in openSUSE 13.2, Leap 42.x and SLE 12 does not yet provide +# Lua(API), and as such we can only depend on it in Tumbleweed, +# we need the 'branch' of lua this package was built against +# (lua_version nicely provides this info). Requires: Lua(API) = %{lua_version} %endif ++++++ lgi-0.9.0.tar.gz -> lgi-0.9.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/Makefile new/lgi-0.9.1/Makefile --- old/lgi-0.9.0/Makefile 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/Makefile 2016-05-27 21:56:36.000000000 +0200 @@ -5,7 +5,7 @@ # License: MIT # -VERSION = 0.9.0 +VERSION = 0.9.1 MAKE ?= make ROCK = lgi-$(VERSION)-1.rockspec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/README.md new/lgi-0.9.1/README.md --- old/lgi-0.9.0/README.md 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/README.md 2016-05-27 21:56:36.000000000 +0200 @@ -58,6 +58,7 @@ - Jiří Klimeš - Garrett Regier - Kenneth Zhou +- Travis Hoppe Many other people contributed to what lgi is today, in many forms - writing patches, reporting bugs, packaging for distributions, @@ -65,6 +66,18 @@ ## History +### 0.9.1 (27-May-2016) + + - marshal NULL strings as nil instead of empty strings. This allows + use of e.g. DataInputStream:read_line() APIs. + - fix and improve build for OSX and Win-based configurations + - add support for arrays with lengths as struct fields + - allow GLib.Variant construction for lightuserdata + - fix gtop binding (certain structs could not be imported) + - adapt to new set of annotations in newer glib + - assorted Lua5.3 fixes, lgi is now fully Lua5.3 compatible + - fix binding of Gdk.Rectangle from newer GDK + ### 0.9.0 (23-Mar-2015) - new feature: allow defining new properties on custom GObject @@ -162,7 +175,7 @@ - Avoid unexpected dependency on cairo-devel, cairo-runtime is now enough - Make `set_resident()` more robust and fix stack leak for Lua 5.2 case, - avoid useless warning when `set_resident()` fails (to accomodate for + avoid useless warning when `set_resident()` fails (to accommodate for static linking case). - Fix small memory leak (mutex) which occured once per opened `lua_State` using lgi. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/Makefile new/lgi-0.9.1/lgi/Makefile --- old/lgi-0.9.0/lgi/Makefile 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/Makefile 2016-05-27 21:56:36.000000000 +0200 @@ -6,23 +6,26 @@ # PREFIX = /usr/local +HOST_OS = $(shell uname -s | tr A-Z a-z) LUA_VERSION=5.1 LUA_LIBDIR = $(PREFIX)/lib/lua/$(LUA_VERSION) LUA_SHAREDIR = $(PREFIX)/share/lua/$(LUA_VERSION) +PKG_CONFIG = pkg-config GINAME = gobject-introspection-1.0 PKGS = $(GINAME) gmodule-2.0 libffi VERSION_FILE = version.lua -ifneq ($(filter CYGWIN%, $(shell uname -s)),) +ifneq ($(filter cygwin% msys% mingw%, $(HOST_OS)),) CORE = corelgilua51.dll LIBFLAG = -shared LIBS += -llua else -ifeq ($(shell uname -s),Darwin) +ifeq ($(HOST_OS),darwin) CORE = corelgilua51.so LIBFLAG = -bundle -undefined dynamic_lookup CCSHARED = -fno-common +GOBJECT_INTROSPECTION_LIBDIR = $(shell pkg-config --variable=libdir $(GINAME)) else CORE = corelgilua51.so LIBFLAG = -shared @@ -37,14 +40,17 @@ CFLAGS = -Wall -Wextra -O2 -g endif endif -ALL_CFLAGS = $(CCSHARED) $(COPTFLAGS) $(LUA_CFLAGS) $(shell pkg-config --cflags $(PKGS)) $(CFLAGS) -LIBS += $(shell pkg-config --libs $(PKGS)) +ifeq ($(HOST_OS),darwin) +CFLAGS += -DGOBJECT_INTROSPECTION_LIBDIR=\"$(GOBJECT_INTROSPECTION_LIBDIR)\" +endif +ALL_CFLAGS = $(CCSHARED) $(COPTFLAGS) $(LUA_CFLAGS) $(shell $(PKG_CONFIG) --cflags $(PKGS)) $(CFLAGS) +LIBS += $(shell $(PKG_CONFIG) --libs $(PKGS)) ALL_LDFLAGS = $(LIBFLAG) $(LDFLAGS) DEPCHECK = .depcheck # Precondition check $(DEPCHECK) : Makefile - pkg-config --exists '$(GINAME) >= 0.10.8' --print-errors + $(PKG_CONFIG) --exists '$(GINAME) >= 0.10.8' --print-errors touch $@ .PHONY : all clean install @@ -79,6 +85,6 @@ mkdir -p $(DESTDIR)$(LUA_SHAREDIR) cp ../lgi.lua $(DESTDIR)$(LUA_SHAREDIR) mkdir -p $(DESTDIR)$(LUA_SHAREDIR)/lgi - cp $(CORESOURCES) $(VERSION_FILE) $(DESTDIR)$(LUA_SHAREDIR)/lgi + cp $(CORESOURCES) $(DESTDIR)$(LUA_SHAREDIR)/lgi mkdir -p $(DESTDIR)$(LUA_SHAREDIR)/lgi/override cp $(OVERRIDES) $(DESTDIR)$(LUA_SHAREDIR)/lgi/override diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/callable.c new/lgi-0.9.1/lgi/callable.c --- old/lgi-0.9.0/lgi/callable.c 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/callable.c 2016-05-27 21:56:36.000000000 +0200 @@ -539,7 +539,7 @@ /* Parses callable from given table. */ int -lgi_callable_parse (lua_State *L, int info) +lgi_callable_parse (lua_State *L, int info, gpointer addr) { Callable *callable; int nargs, i; @@ -558,9 +558,13 @@ lua_rawseti (L, -2, 0); /* Get address of the function. */ - lua_getfield (L, info, "addr"); - callable->address = lua_touserdata (L, -1); - lua_pop (L, 1); + if (addr == NULL) + { + lua_getfield (L, info, "addr"); + addr = lua_touserdata (L, -1); + lua_pop (L, 1); + } + callable->address = addr; /* Handle 'return' table. */ lua_getfield (L, info, "ret"); @@ -683,6 +687,7 @@ { lua_getfenv (L, 1); lua_rawgeti (L, -1, 0); + lua_replace (L, -2); lua_pushfstring (L, "lgi.efn (%s): %s", lua_tostring (L, -2), lua_tostring (L, -1)); lua_replace (L, -2); @@ -890,6 +895,10 @@ lua_insert (L, -nret - 1); caller_allocated++; } + else + /* Normal OUT parameters. Ideally we don't have to touch + them, but see https://github.com/pavouk/lgi/issues/118 */ + memset (&args[argi], 0, sizeof (args[argi])); } else if (param->internal_user_data) /* Provide userdata for the callback. */ @@ -1003,7 +1012,7 @@ Callable *callable = callable_get (L, 1); const gchar *verb = lua_tostring (L, 2); if (g_strcmp0 (verb, "info") == 0) - return lgi_gi_info_new (L, callable->info); + return lgi_gi_info_new (L, g_base_info_ref (callable->info)); else if (g_strcmp0 (verb, "params") == 0) { int index = 1, i; @@ -1464,17 +1473,18 @@ } /* Creates new Callable instance according to given gi.info. Lua prototype: - callable = callable.new(callable_info) or - callable = callable.new(description_table) */ + callable = callable.new(callable_info[, addr]) or + callable = callable.new(description_table[, addr]) */ static int callable_new (lua_State *L) { + gpointer addr = lua_touserdata (L, 2); if (lua_istable (L, 1)) - return lgi_callable_parse (L, 1); + return lgi_callable_parse (L, 1, addr); else return lgi_callable_create (L, *(GICallableInfo **) - luaL_checkudata (L, 1, LGI_GI_INFO), - NULL); + luaL_checkudata (L, 1, LGI_GI_INFO), + addr); } /* Callable module public API table. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/class.lua new/lgi-0.9.1/lgi/class.lua --- old/lgi-0.9.0/lgi/class.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/class.lua 2016-05-27 21:56:36.000000000 +0200 @@ -300,6 +300,7 @@ -- all known overriden virtual methods. local function class_init(class_addr) -- Create instance of real class. + local class_addr = core.record.query(class_addr, "addr") or class_addr local class_struct = core.record.new(new_class._class, class_addr) -- Iterate through all overrides and assign to the virtual callbacks. @@ -367,6 +368,7 @@ -- Prepare interface initialization closure. local function iface_init(iface_addr) + iface_addr = core.record.query(iface_addr, "addr") or iface_addr local iface_struct = core.record.new(iface._class, iface_addr) -- Iterate through all interface overrides and assign to the @@ -432,7 +434,7 @@ override = self._override end local guard, vfunc = core.marshal.callback( - class_struct[name].typeinfo.interface, target) + class_struct[name].callable, target) override[name] = vfunc self._guard[container.name .. ':' .. name] = guard else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/core.c new/lgi-0.9.1/lgi/core.c --- old/lgi-0.9.0/lgi/core.c 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/core.c 2016-05-27 21:56:36.000000000 +0200 @@ -536,6 +536,13 @@ name = g_strdup_printf (MODULE_NAME_FORMAT_PLAIN, luaL_checkstring (L, 1)); +#if defined(__APPLE__) + char *path = g_module_build_path (GOBJECT_INTROSPECTION_LIBDIR, + name); + g_free(name); + name = path; +#endif + /* Try to load the module. */ GModule *module = g_module_open (name, 0); if (module == NULL) @@ -621,6 +628,17 @@ } else { + if (lua_gettop(L) == 3) + { + /* Some Lua versions give us the path to the .so on the stack. + Just load & leak it. */ + GModule* module = g_module_open(lua_tostring(L, 2), + G_MODULE_BIND_LAZY | + G_MODULE_BIND_LOCAL); + if (module != NULL) + return; + } + /* This hack tries to enumerate the whole registry table and find 'LOADLIB: path' library. When it detects itself, it just removes pointer to the loaded library, disallowing Lua @@ -654,7 +672,7 @@ } } -int +G_MODULE_EXPORT int luaopen_lgi_corelgilua51 (lua_State* L) { LgiStateMutex *mutex; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/init.lua new/lgi-0.9.1/lgi/init.lua --- old/lgi-0.9.0/lgi/init.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/init.lua 2016-05-27 21:56:36.000000000 +0200 @@ -85,6 +85,8 @@ repo.GLib._precondition.Timer = 'GLib-Timer' repo.GLib._precondition.MarkupParser = 'GLib-Markup' repo.GLib._precondition.MarkupParseContext = 'GLib-Markup' +repo.GLib._precondition.Source = 'GLib-Source' +repo.GLib._precondition.SourceFuncs = 'GLib-Source' for _, name in pairs { 'Variant', 'VariantType', 'VariantBuilder' } do repo.GLib._precondition[name] = 'GLib-Variant' end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/lgi.h new/lgi-0.9.1/lgi/lgi.h --- old/lgi-0.9.0/lgi/lgi.h 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/lgi.h 2016-05-27 21:56:36.000000000 +0200 @@ -131,7 +131,7 @@ void lgi_marshal_2lua (lua_State *L, GITypeInfo *ti, GIArgInfo *ai, GIDirection dir, GITransfer xfer, gpointer source, int parent, - GICallableInfo *ci, void **args); + GICallableInfo *ci, void *args); /* Marshalls field to/from given memory (struct, union or object). Returns number of results pushed to the stack (0 or 1). */ @@ -147,7 +147,7 @@ int lgi_callable_create (lua_State *L, GICallableInfo *ci, gpointer addr); /* Parses callable from table-driven info description. */ -int lgi_callable_parse (lua_State *L, int info); +int lgi_callable_parse (lua_State *L, int info, gpointer addr); /* Creates container block for allocated closures. Returns address of the block, suitable as user_data parameter. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/marshal.c new/lgi-0.9.1/lgi/marshal.c --- old/lgi-0.9.0/lgi/marshal.c 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/marshal.c 2016-05-27 21:56:36.000000000 +0200 @@ -146,26 +146,47 @@ /* Gets or sets the length of the array. */ static void array_get_or_set_length (GITypeInfo *ti, gssize *get_length, gssize set_length, - GICallableInfo *ci, void **args) + GIBaseInfo *ci, void *args) { gint param = g_type_info_get_array_length (ti); - if (param >= 0 && ci != NULL && param < g_callable_info_get_n_args (ci)) + if (param >= 0 && ci != NULL) { - GIArgInfo ai; - GITypeInfo eti; GIArgument *val; - g_callable_info_load_arg (ci, param, &ai); - g_arg_info_load_type (&ai, &eti); - if (g_arg_info_get_direction (&ai) == GI_DIRECTION_IN) - /* For input parameters, value is directly pointed do by args - table element. */ - val = (GIArgument *) args[param]; + GITypeInfo *eti; + GIInfoType itype = g_base_info_get_type (ci); + + if (itype == GI_INFO_TYPE_FUNCTION || itype == GI_INFO_TYPE_CALLBACK) + { + GIArgInfo ai; + + if (param >= g_callable_info_get_n_args (ci)) + return; + g_callable_info_load_arg (ci, param, &ai); + eti = g_arg_info_get_type (&ai); + if (g_arg_info_get_direction (&ai) == GI_DIRECTION_IN) + /* For input parameters, value is directly pointed to by args + table element. */ + val = (GIArgument *) ((void **) args)[param]; + else + /* For output arguments, args table element points to pointer + to value. */ + val = *(GIArgument **) ((void **) args)[param]; + } + else if (itype == GI_INFO_TYPE_STRUCT || itype == GI_INFO_TYPE_UNION) + { + GIFieldInfo *fi; + + if (param >= g_struct_info_get_n_fields (ci)) + return; + fi = g_struct_info_get_field (ci, param); + eti = g_field_info_get_type (fi); + val = (GIArgument *) ((char *) args + g_field_info_get_offset (fi)); + g_base_info_unref (fi); + } else - /* For output arguments, args table element points to pointer - to value. */ - val = *(GIArgument **) args[param]; + return; - switch (g_type_info_get_tag (&eti)) + switch (g_type_info_get_tag (eti)) { #define HANDLE_ELT(tag, field) \ case GI_TYPE_TAG_ ## tag: \ @@ -188,6 +209,8 @@ default: g_assert_not_reached (); } + + g_base_info_unref (eti); } } @@ -478,7 +501,10 @@ /* UINT8 arrays are marshalled as Lua strings. */ if (len < 0) len = data ? strlen(data) : 0; - lua_pushlstring (L, data, len); + if (data != NULL || len != 0) + lua_pushlstring (L, data, len); + else + lua_pushnil (L); } else { @@ -1201,7 +1227,7 @@ void lgi_marshal_2lua (lua_State *L, GITypeInfo *ti, GIArgInfo *ai, GIDirection dir, GITransfer transfer, gpointer source, int parent, - GICallableInfo *ci, void **args) + GICallableInfo *ci, void *args) { gboolean own = (transfer != GI_TRANSFER_NOTHING); GITypeTag tag = g_type_info_get_tag (ti); @@ -1314,7 +1340,7 @@ { /* Store context associated with the callback to the callback object. */ - GIArgument *arg = args[closure]; + GIArgument *arg = ((void **) args)[closure]; lua_pushlightuserdata (L, arg->v_pointer); lua_setfield (L, -2, "user_data"); } @@ -1363,19 +1389,22 @@ { GITypeInfo *ti; int to_remove, nret; + GIBaseInfo *pi = NULL; + gpointer field_addr; /* Check the type of the field information. */ if (lgi_udata_test (L, field_arg, LGI_GI_INFO)) { - GIFieldInfo **fi = lua_touserdata (L, field_arg); GIFieldInfoFlags flags; + GIFieldInfo **fi = lua_touserdata (L, field_arg); + pi = g_base_info_get_container (*fi); /* Check, whether field is readable/writable. */ flags = g_field_info_get_flags (*fi); if ((flags & (getmode ? GI_FIELD_IS_READABLE - : GI_FIELD_IS_WRITABLE)) == 0) + : GI_FIELD_IS_WRITABLE)) == 0) { - /* Check, whether parent did not disable access checks + /* Check, whether parent did not disable access checks completely. */ lua_getfield (L, -1, "_allow"); if (!lua_toboolean (L, -1)) @@ -1394,7 +1423,7 @@ /* Map GIArgument to proper memory location, get typeinfo of the field and perform actual marshalling. */ - object = (char *) object + g_field_info_get_offset (*fi); + field_addr = (char *) object + g_field_info_get_offset (*fi); ti = g_field_info_get_type (*fi); lgi_gi_info_new (L, ti); to_remove = lua_gettop (L); @@ -1406,7 +1435,7 @@ lgi_makeabs (L, field_arg); luaL_checktype (L, field_arg, LUA_TTABLE); lua_rawgeti (L, field_arg, 1); - object = (char *) object + lua_tointeger (L, -1); + field_addr = (char *) object + lua_tointeger (L, -1); lua_rawgeti (L, field_arg, 2); kind = lua_tonumber (L, -1); lua_pop (L, 2); @@ -1425,15 +1454,15 @@ case 1: case 2: { - GIArgument *arg = (GIArgument *) object; + GIArgument *arg = (GIArgument *) field_addr; if (getmode) { if (kind == 1) { - object = arg->v_pointer; + field_addr = arg->v_pointer; parent_arg = 0; } - lgi_record_2lua (L, object, FALSE, parent_arg); + lgi_record_2lua (L, field_addr, FALSE, parent_arg); return 1; } else @@ -1455,7 +1484,7 @@ { /* Use typeinfo to unmarshal numeric value. */ lgi_marshal_2lua (L, ti, NULL, GI_DIRECTION_OUT, - GI_TRANSFER_NOTHING, object, 0, + GI_TRANSFER_NOTHING, field_addr, 0, NULL, NULL); /* Replace numeric field with symbolic value. */ @@ -1476,7 +1505,7 @@ } /* Use typeinfo to marshal the numeric value. */ - lgi_marshal_2c (L, ti, NULL, GI_TRANSFER_NOTHING, object, + lgi_marshal_2c (L, ti, NULL, GI_TRANSFER_NOTHING, field_addr, val_arg, 0, NULL, NULL); lua_pop (L, 2); return 0; @@ -1491,12 +1520,12 @@ if (getmode) { lgi_marshal_2lua (L, ti, NULL, GI_DIRECTION_OUT, GI_TRANSFER_NOTHING, - object, parent_arg, NULL, NULL); + field_addr, parent_arg, pi, object); nret = 1; } else { - lgi_marshal_2c (L, ti, NULL, GI_TRANSFER_EVERYTHING, object, val_arg, + lgi_marshal_2c (L, ti, NULL, GI_TRANSFER_EVERYTHING, field_addr, val_arg, 0, NULL, NULL); nret = 0; } @@ -1772,7 +1801,7 @@ user_data = lgi_closure_allocate (L, 1); *lgi_guard_create (L, lgi_closure_destroy) = user_data; if (lua_istable (L, 1)) - lgi_callable_parse (L, 1); + lgi_callable_parse (L, 1, NULL); else { ci = lgi_udata_test (L, 1, LGI_GI_INFO); @@ -1790,6 +1819,41 @@ lgi_closure_destroy (user_data); } +/* Workaround for incorrectly annotated g_closure_invoke. Since it is + pretty performance-sensitive, it is implemented here in native code + instead of creating overlay with custom ffi for it. */ +static int +marshal_closure_invoke (lua_State *L) +{ + GClosure *closure; + GValue *result, *params; + gint n_params, i; + + lgi_type_get_repotype (L, G_TYPE_CLOSURE, NULL); + lgi_record_2c (L, 1, &closure, FALSE, FALSE, FALSE, FALSE); + + lgi_type_get_repotype (L, G_TYPE_VALUE, NULL); + lua_pushvalue (L, -1); + lgi_record_2c (L, 2, &result, FALSE, FALSE, FALSE, FALSE); + + luaL_checktype (L, 3, LUA_TTABLE); + n_params = lua_objlen (L, 3); + + params = g_newa (GValue, n_params); + memset (params, 0, sizeof (GValue) * n_params); + for (i = 0; i < n_params; i++) + { + lua_pushnumber (L, i + 1); + lua_gettable (L, 3); + lua_pushvalue (L, -2); + lgi_record_2c (L, -2, ¶ms[i], TRUE, FALSE, FALSE, FALSE); + lua_pop (L, 1); + } + + g_closure_invoke (closure, result, n_params, params, lua_touserdata (L, 4)); + return 0; +} + /* This is workaround for missing glib function, which should look like this: @@ -1868,6 +1932,7 @@ { "argument", marshal_argument }, { "callback", marshal_callback }, { "closure_set_marshal", marshal_closure_set_marshal }, + { "closure_invoke", marshal_closure_invoke }, { "typeinfo", marshal_typeinfo }, { NULL, NULL } }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/GLib-Source.lua new/lgi-0.9.1/lgi/override/GLib-Source.lua --- old/lgi-0.9.0/lgi/override/GLib-Source.lua 1970-01-01 01:00:00.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/GLib-Source.lua 2016-05-27 21:56:36.000000000 +0200 @@ -0,0 +1,39 @@ +------------------------------------------------------------------------------ +-- +-- lgi GLib Source support +-- +-- Copyright (c) 2015 Pavel Holejsovsky +-- Licensed under the MIT license: +-- http://www.opensource.org/licenses/mit-license.php +-- +------------------------------------------------------------------------------ + +local type, setmetatable, pairs = type, setmetatable, pairs + +local lgi = require 'lgi' +local core = require 'lgi.core' +local gi = core.gi +local component = require 'lgi.component' +local record = require 'lgi.record' +local ffi = require 'lgi.ffi' +local ti = ffi.types + +local GLib = lgi.GLib +local Source = GLib.Source +local SourceFuncs = GLib.SourceFuncs + +SourceFuncs._field.prepare = { + name = 'prepare', + offset = SourceFuncs._field.prepare.offset, + ret = ti.boolean, Source, { ti.int, dir = 'out' } +} +local source_new = Source._new +function Source:_new(funcs) + if type(funcs) == 'table' then + funcs = SourceFuncs(funcs) + end + function funcs.finalize(source) + funcs = nil + end + return source_new(self, funcs, Source._size) +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/GLib-Variant.lua new/lgi-0.9.1/lgi/override/GLib-Variant.lua --- old/lgi-0.9.0/lgi/override/GLib-Variant.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/GLib-Variant.lua 2016-05-27 21:56:36.000000000 +0200 @@ -168,6 +168,10 @@ -- Variant.new() is just a facade over variant_new backend. function Variant.new(vt, val) + if type(vt) == 'userdata' then + -- Wrap existing pointer to variant. + return core.record.new(Variant, vt, val) + end if type(vt) ~= 'string' then vt = vt:dup_string() end local v, epos = variant_new(vt, 1, val) if not v or epos ~= #vt + 1 then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/GObject-Closure.lua new/lgi-0.9.1/lgi/override/GObject-Closure.lua --- old/lgi-0.9.0/lgi/override/GObject-Closure.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/GObject-Closure.lua 2016-05-27 21:56:36.000000000 +0200 @@ -294,5 +294,8 @@ return closure end +-- Use native marshalling for g_closure_invoke +Closure.invoke = core.marshal.closure_invoke + -- Export CallInfo as field of Closure. Closure.CallInfo = CallInfo diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/Gdk.lua new/lgi-0.9.1/lgi/override/Gdk.lua --- old/lgi-0.9.0/lgi/override/Gdk.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/Gdk.lua 2016-05-27 21:56:36.000000000 +0200 @@ -23,13 +23,15 @@ core.registerlock(core.gi.Gdk.resolve.gdk_threads_set_lock_functions) Gdk.threads_init() --- Gdk.Rectangle does not exist at all, because it is aliased to --- cairo.RectangleInt. Make sure that we have it exists, because it --- is very commonly used in API documentation. -Gdk.Rectangle = lgi.cairo.RectangleInt -Gdk.Rectangle._method = rawget(Gdk.Rectangle, '_method') or {} -Gdk.Rectangle._method.intersect = Gdk.rectangle_intersect -Gdk.Rectangle._method.union = Gdk.rectangle_union +-- Gdk.Rectangle does not exist at all in older GOI, because it is +-- aliased to cairo.RectangleInt. Make sure that we have it exists, +-- because it is very commonly used in API documentation. +if not Gdk.Rectangle then + Gdk.Rectangle = lgi.cairo.RectangleInt + Gdk.Rectangle._method = rawget(Gdk.Rectangle, '_method') or {} + Gdk.Rectangle._method.intersect = Gdk.rectangle_intersect + Gdk.Rectangle._method.union = Gdk.rectangle_union +end -- Declare GdkAtoms which are #define'd in Gdk sources and not -- introspected in gir. @@ -124,5 +126,8 @@ 'Any', 'Expose', 'Visibility', 'Motion', 'Button', 'Touch', 'Scroll', 'Key', 'Crossing', 'Focus', 'Configure', 'Property', 'Selection', 'OwnerChange', 'Proximity', 'DND', 'WindowState', 'Setting', 'GrabBroken' } do - Gdk['Event' .. event_type]._parent = Gdk.Event + local event = Gdk['Event' .. event_type] + if event then + event._parent = Gdk.Event + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/Gtk.lua new/lgi-0.9.1/lgi/override/Gtk.lua --- old/lgi-0.9.0/lgi/override/Gtk.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/Gtk.lua 2016-05-27 21:56:36.000000000 +0200 @@ -192,6 +192,7 @@ Gtk.Container._attribute.child = {} local container_child_mt = {} function container_child_mt:__index(id) + if type(id) ~= 'string' then return nil end local found = (core.object.env(self._container).id == id and self._container) if not found then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/override/Pango.lua new/lgi-0.9.1/lgi/override/Pango.lua --- old/lgi-0.9.0/lgi/override/Pango.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/override/Pango.lua 2016-05-27 21:56:36.000000000 +0200 @@ -166,14 +166,16 @@ } end --- Pango.GlyphString is struct with counted array inside. Very GI --- unfriendly, we have to handle it using lgi internal magic. -Pango.GlyphString._attribute = { glyphs = {} } -function Pango.GlyphString._attribute.glyphs:get() - local array = core.record.field(self, Pango.GlyphString._field.glyphs) - local glyphs = {} - for i = 0, self.num_glyphs - 1 do - glyphs[i + 1] = core.record.fromarray(array, i) +-- Pango.GlyphString is struct with counted array inside, until +-- Pango-1.38 which has fixed annotation. Fix for previous versions. +if gi.Pango.GlyphString.fields.glyphs.typeinfo.tag ~= 'array' then + Pango.GlyphString._attribute = { glyphs = {} } + function Pango.GlyphString._attribute.glyphs:get() + local array = core.record.field(self, Pango.GlyphString._field.glyphs) + local glyphs = {} + for i = 0, self.num_glyphs - 1 do + glyphs[i + 1] = core.record.fromarray(array, i) + end + return glyphs end - return glyphs end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/record.c new/lgi-0.9.1/lgi/record.c --- old/lgi-0.9.0/lgi/record.c 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/record.c 2016-05-27 21:56:36.000000000 +0200 @@ -588,7 +588,13 @@ else { if (lua_isnoneornil (L, 3)) - lua_pushlightuserdata (L, record_check (L, 1)->addr); + { + record = record_check (L, 1); + if (!record) + return 0; + + lua_pushlightuserdata (L, record->addr); + } else { gpointer addr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/lgi/record.lua new/lgi-0.9.1/lgi/record.lua --- old/lgi-0.9.0/lgi/record.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/lgi/record.lua 2016-05-27 21:56:36.000000000 +0200 @@ -49,7 +49,31 @@ function record.struct_mt:_element(instance, symbol) -- First of all, try normal inherited functionality. local element, category = component.mt._element(self, instance, symbol) - if element then return element, category end + if element then + if category == '_field' then + if type(element) == 'table' and element.ret then + category = '_cbkfield' + local ffi = require 'lgi.ffi' + element = { + name = element.name, + ptrfield = { element.offset, 0, ffi.types.ptr }, + callable = element + } + elseif gi.isinfo(element) and element.is_field then + local ii = element.typeinfo.interface + if ii and ii.type == 'callback' then + category = '_cbkfield' + local ffi = require 'lgi.ffi' + element = { + name = element.name, + ptrfield = { element.offset, 0, ffi.types.ptr }, + callable = ii + } + end + end + end + return element, category + end -- Special handling of '_native' attribute. if symbol == '_native' then return symbol, '_internal' @@ -95,6 +119,31 @@ end end +-- Add accessor for handling fields containing callbacks +local guards_station = setmetatable({}, { __mode = 'k' }) +function record.struct_mt:_access_cbkfield(instance, element, ...) + if select('#', ...) == 0 then + -- Reading callback field, get pointer and wrap it in proper + -- callable, so that caller can actually call it. + local addr = core.record.field(instance, element.ptrfield) + return core.callable.new(element.callable, addr) + else + local target = ... + if type(target) ~= 'userdata' then + -- Create closure over Lua target, keep guard stored. + local guard + guard, target = core.marshal.callback(element.callable, target) + local guards = guards_station[instance] + if not guards then + guards = {} + guards_station[instance] = guards + end + guards[element.name] = guard + end + core.record.field(instance, element.ptrfield, target) + end +end + -- Add accessor for 'internal' fields handling. function record.struct_mt:_access_internal(instance, element, ...) if select('#', ...) ~= 0 then return end @@ -150,7 +199,8 @@ -- Check, whether ctor is valid. In order to be valid, it must -- return instance of this record. - if (ctor and ctor.return_type.tag =='interface' + if (ctor and ctor.type == 'function' + and ctor.return_type.tag =='interface' and ctor.return_type.interface == info) then ctor = core.callable.new(ctor) record._new = function(typetable, ...) return ctor(...) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/Makefile new/lgi-0.9.1/tests/Makefile --- old/lgi-0.9.0/tests/Makefile 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/Makefile 2016-05-27 21:56:36.000000000 +0200 @@ -5,12 +5,14 @@ # License: MIT # -ifneq ($(filter CYGWIN%, $(shell uname -s)),) +HOST_OS = $(shell uname -s | tr A-Z a-z) + +ifneq ($(filter cygwin% msys% mingw%, $(HOST_OS)),) EXT = .dll PFX = cyg LIBFLAG = -shared else -ifeq ($(shell uname -s),Darwin) +ifeq ($(HOST_OS),darwin) EXT = .so PFX = lib LIBFLAG = -bundle -undefined dynamic_lookup @@ -25,20 +27,21 @@ PKGS = gio-2.0 cairo cairo-gobject gobject-introspection-1.0 gmodule-2.0 libffi LUA = lua +PKG_CONFIG = pkg-config ifndef CFLAGS ifndef COPTFLAGS CFLAGS = -Wall -g endif endif -ALL_CFLAGS = $(CCSHARED) $(COPTFLAGS) $(LUA_CFLAGS) $(shell pkg-config --cflags $(PKGS)) $(CFLAGS) -I . -LIBS += $(shell pkg-config --libs $(PKGS)) +ALL_CFLAGS = $(CCSHARED) $(COPTFLAGS) $(LUA_CFLAGS) $(shell $(PKG_CONFIG) --cflags $(PKGS)) $(CFLAGS) -I . +LIBS += $(shell $(PKG_CONFIG) --libs $(PKGS)) ALL_LDFLAGS = $(LIBFLAG) $(LDFLAGS) DEPCHECK = .depcheck # Precondition check $(DEPCHECK) : Makefile - pkg-config --exists '$(PKGS) >= 0.10.8' --print-errors + $(PKG_CONFIG) --exists '$(PKGS) >= 0.10.8' --print-errors touch $@ REGRESS = $(PFX)regress$(EXT) @@ -61,7 +64,7 @@ $(REGRESS) : regress.o $(CC) $(ALL_LDFLAGS) -o $@ regress.o $(LIBS) -GIDATADIR = $(shell pkg-config --variable=gidatadir gobject-introspection-1.0)/tests +GIDATADIR = $(shell $(PKG_CONFIG) --variable=gidatadir gobject-introspection-1.0)/tests regress.o : $(GIDATADIR)/regress.c $(GIDATADIR)/regress.h $(DEPCHECK) $(CC) $(ALL_CFLAGS) -c -o $@ $< diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/cairo.lua new/lgi-0.9.1/tests/cairo.lua --- old/lgi-0.9.0/tests/cairo.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/cairo.lua 2016-05-27 21:56:36.000000000 +0200 @@ -28,13 +28,24 @@ end end +-- Helper, checks that given value has number type and expected value, +-- with some tolerance. +local function checkvf(val, exp, tolerance) + check(type(val) == 'number', string.format( + "got type `%s', expected `number'", type(val)), 2) + check(math.abs(val - exp) <= tolerance, + string.format("got value `%s', expected `%s'", + tostring(val), tostring(exp)), 2) +end + local function check_matrix(matrix, xx, yx, xy, yy, x0, y0) - checkv(matrix.xx, xx, 'number') - checkv(matrix.yx, yx, 'number') - checkv(matrix.xy, xy, 'number') - checkv(matrix.yy, yy, 'number') - checkv(matrix.x0, x0, 'number') - checkv(matrix.y0, y0, 'number') + local t = 0.0000001 + checkvf(matrix.xx, xx, t) + checkvf(matrix.yx, yx, t) + checkvf(matrix.xy, xy, t) + checkvf(matrix.yy, yy, t) + checkvf(matrix.x0, x0, t) + checkvf(matrix.y0, y0, t) end function cairo.matrix() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/gio.lua new/lgi-0.9.1/tests/gio.lua --- old/lgi-0.9.0/tests/gio.lua 1970-01-01 01:00:00.000000000 +0100 +++ new/lgi-0.9.1/tests/gio.lua 2016-05-27 21:56:36.000000000 +0200 @@ -0,0 +1,39 @@ +--[[-------------------------------------------------------------------------- + + LGI testsuite, GIo test suite. + + Copyright (c) 2016 Uli Schlachter + Licensed under the MIT license: + http://www.opensource.org/licenses/mit-license.php + +--]]-------------------------------------------------------------------------- + +local lgi = require 'lgi' +local core = require 'lgi.core' + +local check = testsuite.check +local checkv = testsuite.checkv + +local gio = testsuite.group.new('gio') + +function gio.read() + local GLib, Gio = lgi.GLib, lgi.Gio + + -- Prepare the input to read + local input + input = "line" + input = Gio.MemoryInputStream.new_from_data(input) + input = Gio.DataInputStream.new(input) + + local line, length + + -- Read line + line, length = input:read_line() + checkv(line, "line", "string") + checkv(length, 4, "number") + + -- Read EOF + line, length = input:read_line() + checkv(line, nil, "nil") + checkv(length, 0, "number") +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/glib.lua new/lgi-0.9.1/tests/glib.lua --- old/lgi-0.9.0/tests/glib.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/glib.lua 2016-05-27 21:56:36.000000000 +0200 @@ -115,3 +115,21 @@ check(err.message == 'snafu 1') check(saved_err:matches(err)) end + +function glib.gsourcefuncs() + local GLib = lgi.GLib + + local called + local source_funcs = GLib.SourceFuncs { + prepare = function(source, timeout) + called = source + return true, 42 + end + } + + local source = GLib.Source(source_funcs) + local res, timeout = source_funcs.prepare(source) + check(res == true) + check(timeout == 42) + check(called == source) +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/gobject.lua new/lgi-0.9.1/tests/gobject.lua --- old/lgi-0.9.0/tests/gobject.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/gobject.lua 2016-05-27 21:56:36.000000000 +0200 @@ -282,6 +282,13 @@ 'LgiTestFakeMonitor1NetworkAvailable', 'Whether the network is available.', false, { GObject.ParamFlags.READABLE }) + FakeMonitor._property.connectivity = + GObject.ParamSpecEnum('connectivity', + 'LgiTestFakeMonitor1Connectivity', + 'Type of connectivity.', + Gio.NetworkConnectivity, + Gio.NetworkConnectivity.LOCAL, + { GObject.ParamFlags.READABLE }) function FakeMonitor:do_init(cancellable) self.priv.inited = true return true @@ -326,3 +333,15 @@ checkv(der.str, 'assign', 'string') checkv(propval, 'assign', 'string') end + +function gobject.signal_query() + local GObject = lgi.GObject + local id = GObject.signal_lookup('notify', GObject.Object) + check(id ~= 0) + local query = GObject.signal_query(id) + check(query.signal_id == id) + check(query.signal_name == 'notify') + check(query.n_params == 1) + check(#query.param_types == 1) + check(query.param_types[1] == GObject.Type.name(GObject.Type.PARAM)) +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/performance.lua new/lgi-0.9.1/tests/performance.lua --- old/lgi-0.9.0/tests/performance.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/performance.lua 2016-05-27 21:56:36.000000000 +0200 @@ -59,4 +59,7 @@ *** 0.9.0: (On Lua5.2) 0.65 0.09 0.09 0.96 0.63 1.76 0.02 2.94 + +*** 0.9.1: (On Lua5.3.2) +0.62 0.10 0.10 0.92 0.60 1.55 0.02 2.65 --]] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lgi-0.9.0/tests/test.lua new/lgi-0.9.1/tests/test.lua --- old/lgi-0.9.0/tests/test.lua 2015-03-23 23:48:44.000000000 +0100 +++ new/lgi-0.9.1/tests/test.lua 2016-05-27 21:56:36.000000000 +0200 @@ -117,6 +117,7 @@ 'gtk.lua', 'cairo.lua', 'pango.lua', + 'gio.lua', } do dofile(testpath .. '/' .. sourcefile) end
