From: Jürg Billeter Date: Wed, 16 Sep 2009 17:15:54 +0000 (+0200) Subject: Fix closures used as signal handlers X-Git-Tag: 0.7.6~29 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=40198156049e12d322298e8d630db81ef066d2fe;p=thirdparty%2Fvala.git Fix closures used as signal handlers --- diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala index 34d23eeda..eca199d76 100644 --- a/codegen/valagsignalmodule.vala +++ b/codegen/valagsignalmodule.vala @@ -672,7 +672,9 @@ internal class Vala.GSignalModule : GObjectModule { if (sig is DynamicSignal) { connect_func = head.get_dynamic_signal_connect_wrapper_name ((DynamicSignal) sig); } else { - if (in_gobject_instance (m)) { + if (m.closure) { + connect_func = "g_signal_connect_data"; + } else if (in_gobject_instance (m)) { connect_func = "g_signal_connect_object"; } else { connect_func = "g_signal_connect"; @@ -764,7 +766,26 @@ internal class Vala.GSignalModule : GObjectModule { // third resp. sixth argument: handler ccall.add_argument (new CCodeCastExpression ((CCodeExpression) handler.ccodenode, "GCallback")); - if (m.binding == MemberBinding.INSTANCE) { + if (m.closure) { + // g_signal_connect_data + + var closure_block = current_symbol as Block; + while (closure_block != null && !closure_block.captured) { + closure_block = closure_block.parent_symbol as Block; + } + int block_id = get_block_id (closure_block); + + // fourth argument: user_data + var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (block_id))); + ref_call.add_argument (get_delegate_target_cexpression (handler)); + ccall.add_argument (new CCodeCastExpression (ref_call, "GCallback")); + + // fifth argument: destroy_notify + ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("block%d_data_unref".printf (block_id)), "GClosureNotify")); + + // sixth argument: connect_flags + ccall.add_argument (new CCodeConstant ("0")); + } else if (m.binding == MemberBinding.INSTANCE) { // g_signal_connect_object or g_signal_handlers_disconnect_matched // or dynamic_signal_connect or dynamic_signal_disconnect