X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/0c92ab0b40d0c819fe88edd88db5dbf4f609d6da..43115cbfefb29535b3e9da83ab247a7f24c6994b:/src/main.c diff --git a/src/main.c b/src/main.c index 424f12c..6a0c791 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ * Copyright (C) 1999,2000 the Free Software Foundation. * Copyright (C) 2000 Eazel, Inc. * Copyright (C) 2001-2011 George (Jiri) Lebl + * Copyright © 2019-2020 Nick Bowler * * Author: George (Jiri) Lebl * @@ -1129,20 +1130,46 @@ add_interfaces (void) static void add_dynamic_interfaces(void) { - GList *li; - for (li = ((Class *)class)->interfaces; - li != NULL; - li = li ->next) { - char *name = replace_sep (li->data, '_'); - char *type = make_pre_macro (li->data, "TYPE"); + GList *li = ((Class *)class)->interfaces; - out_printf(out, - "\t\tg_type_module_add_interface(\n" - "\t\t\ttype_module,\n" - "\t\t\t%s_type_id,\n" - "\t\t\t%s,\n" - "\t\t\t&%s_info);\n", - funcbase, type, name); + if (li) { + /* + * Hack to work around bug in g_type_module_add_interface, + * which will fail to add an interface to types that derive + * from something that also implements the same interface. + * + * The actual GType system does not have any such problem, + * and the GTypeModule implementation details relied upon + * here have not changed once since the feature was first + * implemented almost 20 years ago. + */ + out_printf(out, "\t\tstruct _ModuleInterfaceInfo {\n" + "\t\t\tgboolean loaded;\n" + "\t\t\tGType instance_type;\n" + "\t\t\tGType interface_type;\n" + "\t\t\tGInterfaceInfo info;\n" + "\t\t} *modinfo;\n"); + } + + for (; li; li = li->next) { + char *name = replace_sep(li->data, '_'); + char *type = make_pre_macro(li->data, "TYPE"); + + out_printf(out, "\n" + "\t\tmodinfo = g_malloc(sizeof *modinfo);\n" + "\t\tmodinfo->loaded = TRUE;\n" + "\t\tmodinfo->instance_type = %s_type_id;\n" + "\t\tmodinfo->interface_type = %s;\n" + "\t\tmodinfo->info = %s_info;\n" + "\t\tg_type_add_interface_dynamic\n" + "\t\t\t( modinfo->instance_type\n" + "\t\t\t, modinfo->interface_type\n" + "\t\t\t, G_TYPE_PLUGIN(type_module)\n" + "\t\t\t);\n" + "\t\ttype_module->interface_infos = g_slist_prepend\n" + "\t\t\t( type_module->interface_infos\n" + "\t\t\t, modinfo\n" + "\t\t\t);\n", funcbase, type, name); g_free(type); g_free(name);