From 246ad358ba84cf2799fa040f26f5417a6576f954 Mon Sep 17 00:00:00 2001 From: Angelo Verlain Date: Tue, 26 Dec 2023 21:19:51 +0200 Subject: [PATCH] correctly set interface vfuncs --- src/bindings/girepository.js | 1 + src/bindings/gobject.js | 11 +++++++++++ src/types/callable.js | 34 +++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/bindings/girepository.js b/src/bindings/girepository.js index ebaccd6..f705ac8 100644 --- a/src/bindings/girepository.js +++ b/src/bindings/girepository.js @@ -100,6 +100,7 @@ const { g } = openLib(libName("girepository-1.0", 1), { get_vfunc: $pointer($pointer, $i32), get_n_properties: $i32($pointer), get_property: $pointer($pointer, $i32), + get_iface_struct: $pointer($pointer), }, property_info: { get_flags: $i32($pointer), diff --git a/src/bindings/gobject.js b/src/bindings/gobject.js index 2f37f38..e84cbca 100644 --- a/src/bindings/gobject.js +++ b/src/bindings/gobject.js @@ -86,6 +86,17 @@ const { g } = openLib(libName("gobject-2.0", 0), { get_object: $pointer($buffer), get_boxed: $pointer($buffer), }, + closure: { + new_simple: $pointer($u32, $pointer), + set_marshal: $void($pointer, $pointer), + ref: $void($pointer), + sink: $void($pointer), + add_finalize_notifier: $void($pointer, $pointer, $pointer), + invoke: $void($pointer, $pointer, $u32, $pointer, $pointer), + }, + cclosure: { + new: $pointer($pointer, $pointer, $pointer), + }, }, }); diff --git a/src/types/callable.js b/src/types/callable.js index d1bb5d7..ca1e887 100644 --- a/src/types/callable.js +++ b/src/types/callable.js @@ -137,24 +137,40 @@ export function handleCallable(target, info) { set(value) { const baseName = g.base_info.get_name(info); - const objectInfo = g.base_info.get_container(info); - const classStruct = g.object_info.get_class_struct(objectInfo); - const fieldInfo = g.struct_info.find_field(classStruct, baseName); + const containerInfo = g.base_info.get_container(info); + const containerType = g.base_info.get_type(containerInfo); + + let containerStruct, pointer; + + if (containerType === GIInfoType.INTERFACE) { + containerStruct = g.interface_info.get_iface_struct(containerInfo); + const klass = g.type_class.ref( + Reflect.getOwnMetadata("gi:gtype", this.constructor), + ); + pointer = g.type_interface.peek( + klass, + g.registered_type_info.get_g_type(containerInfo), + ); + } else { + // it's a class + containerStruct = g.object_info.get_class_struct(containerInfo); + pointer = g.type_class.ref( + Reflect.getOwnMetadata("gi:gtype", this.constructor), + ); + } + + const fieldInfo = g.struct_info.find_field(containerStruct, baseName); if (!fieldInfo) { // This vfunc doesn't have a corresponding field in the class struct return; } - const klass = g.type_class.ref( - Reflect.getOwnMetadata("gi:gtype", this.constructor), - ); - - const cb = createCallback(info, value); + const cb = createCallback(info, value, this); const offset = g.field_info.get_offset(fieldInfo); const dataView = new ExtendedDataView( deref_buf( - klass, + pointer, offset + 8, offset, ),