LCOV - code coverage report
Current view: top level - codegen - valagdbusclientmodule.vala (source / functions) Coverage Total Hit
Test: vala 0.57.0.298-a8cae1 Lines: 95.8 % 753 721
Test Date: 2024-04-25 11:34:36 Functions: - 0 0

            Line data    Source code
       1              : /* valagdbusclientmodule.vala
       2              :  *
       3              :  * Copyright (C) 2010-2011  Jürg Billeter
       4              :  *
       5              :  * This library is free software; you can redistribute it and/or
       6              :  * modify it under the terms of the GNU Lesser General Public
       7              :  * License as published by the Free Software Foundation; either
       8              :  * version 2.1 of the License, or (at your option) any later version.
       9              : 
      10              :  * This library is distributed in the hope that it will be useful,
      11              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13              :  * Lesser General Public License for more details.
      14              : 
      15              :  * You should have received a copy of the GNU Lesser General Public
      16              :  * License along with this library; if not, write to the Free Software
      17              :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
      18              :  *
      19              :  * Author:
      20              :  *      Jürg Billeter <j@bitron.ch>
      21              :  *      Philip Van Hoof <pvanhoof@gnome.org>
      22              :  */
      23              : 
      24         2914 : public class Vala.GDBusClientModule : GDBusModule {
      25              :         enum CallType {
      26              :                 SYNC,
      27              :                 ASYNC,
      28              :                 FINISH,
      29              :                 NO_REPLY
      30              :         }
      31              : 
      32           36 :         public CCodeConstant get_dbus_timeout (Symbol symbol) {
      33           36 :                 int timeout = -1;
      34              : 
      35        16990 :                 var dbus = symbol.get_attribute ("DBus");
      36           36 :                 if (dbus != null && dbus.has_argument ("timeout")) {
      37            0 :                         timeout = dbus.get_integer ("timeout");
      38           36 :                 } else if (symbol.parent_symbol != null) {
      39           24 :                         return get_dbus_timeout (symbol.parent_symbol);
      40              :                 }
      41              : 
      42           12 :                 return new CCodeConstant (timeout.to_string ());
      43              :         }
      44              : 
      45            2 :         public override void generate_dynamic_method_wrapper (DynamicMethod method) {
      46            1 :                 var func = new CCodeFunction (get_ccode_name (method));
      47            1 :                 func.modifiers = CCodeModifiers.STATIC;
      48              : 
      49            1 :                 var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
      50              : 
      51            1 :                 generate_cparameters (method, cfile, cparam_map, func);
      52              : 
      53            1 :                 push_function (func);
      54              : 
      55            1 :                 if (method.dynamic_type.type_symbol == dbus_proxy_type) {
      56            1 :                         generate_marshalling (method, CallType.SYNC, null, method.name, -1);
      57              :                 } else {
      58            0 :                         Report.error (method.source_reference, "dynamic methods are not supported for `%s'", method.dynamic_type.to_string ());
      59              :                 }
      60              : 
      61            1 :                 pop_function ();
      62              : 
      63            1 :                 cfile.add_function_declaration (func);
      64            1 :                 cfile.add_function (func);
      65              :         }
      66              : 
      67           54 :         void generate_proxy_interface_init (Interface main_iface, Interface iface) {
      68              :                 // also generate proxy for prerequisites
      69           81 :                 foreach (var prereq in iface.get_prerequisites ()) {
      70           27 :                         if (prereq.type_symbol is Interface) {
      71            0 :                                 generate_proxy_interface_init (main_iface, (Interface) prereq.type_symbol);
      72              :                         }
      73              :                 }
      74              : 
      75           27 :                 string lower_cname = get_ccode_lower_case_prefix (main_iface) + "proxy";
      76              : 
      77           27 :                 var proxy_iface_init = new CCodeFunction (lower_cname + "_" + get_ccode_lower_case_prefix (iface) + "interface_init", "void");
      78           27 :                 proxy_iface_init.add_parameter (new CCodeParameter ("iface", get_ccode_name (iface) + "Iface*"));
      79              : 
      80           27 :                 push_function (proxy_iface_init);
      81              : 
      82          127 :                 foreach (Method m in iface.get_methods ()) {
      83           50 :                         if (!m.is_abstract) {
      84            0 :                                 continue;
      85              :                         }
      86              : 
      87           50 :                         var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), get_ccode_vfunc_name (m));
      88           50 :                         if (!m.coroutine) {
      89           37 :                                 ccode.add_assignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_method (main_iface, iface, m)));
      90              :                         } else {
      91           13 :                                 ccode.add_assignment (vfunc_entry, new CCodeIdentifier (generate_async_dbus_proxy_method (main_iface, iface, m)));
      92           13 :                                 vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), get_ccode_finish_vfunc_name (m));
      93           13 :                                 ccode.add_assignment (vfunc_entry, new CCodeIdentifier (generate_finish_dbus_proxy_method (main_iface, iface, m)));
      94              :                         }
      95              :                 }
      96              : 
      97           39 :                 foreach (Property prop in iface.get_properties ()) {
      98            6 :                         if (!prop.is_abstract) {
      99            0 :                                 continue;
     100              :                         }
     101              : 
     102           12 :                         if (prop.get_accessor != null) {
     103            6 :                                 var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), "get_" + prop.name);
     104            6 :                                 ccode.add_assignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_property_get (main_iface, iface, prop)));
     105              :                         }
     106           12 :                         if (prop.set_accessor != null) {
     107            6 :                                 var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), "set_" + prop.name);
     108            6 :                                 ccode.add_assignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_property_set (main_iface, iface, prop)));
     109              :                         }
     110              :                 }
     111              : 
     112           27 :                 proxy_iface_init.modifiers = CCodeModifiers.STATIC;
     113           27 :                 pop_function ();
     114           27 :                 cfile.add_function_declaration (proxy_iface_init);
     115           27 :                 cfile.add_function (proxy_iface_init);
     116              :         }
     117              : 
     118           27 :         string implement_interface (CCodeFunctionCall define_type, Interface main_iface, Interface iface) {
     119           27 :                 string result = "";
     120              : 
     121              :                 // also implement prerequisites
     122           81 :                 foreach (var prereq in iface.get_prerequisites ()) {
     123           27 :                         if (prereq.type_symbol is Interface) {
     124            0 :                                 result += implement_interface (define_type, main_iface, (Interface) prereq.type_symbol);
     125              :                         }
     126              :                 }
     127              : 
     128              :                 string interface_macro;
     129              : 
     130           27 :                 if (in_plugin) {
     131            0 :                         interface_macro = "G_IMPLEMENT_INTERFACE_DYNAMIC";
     132              :                 } else {
     133           27 :                         interface_macro = "G_IMPLEMENT_INTERFACE";
     134              :                 }
     135              : 
     136           27 :                 result += "%s (%s, %sproxy_%sinterface_init) ".printf (
     137              :                         interface_macro,
     138              :                         get_ccode_upper_case_name (iface, "TYPE_"),
     139              :                         get_ccode_lower_case_prefix (main_iface),
     140              :                         get_ccode_lower_case_prefix (iface));
     141           27 :                 return result;
     142              :         }
     143              : 
     144         4533 :         public override void generate_interface_declaration (Interface iface, CCodeFile decl_space) {
     145         4474 :                 base.generate_interface_declaration (iface, decl_space);
     146              : 
     147         4474 :                 string dbus_iface_name = get_dbus_name (iface);
     148         4474 :                 if (dbus_iface_name == null) {
     149         3803 :                         return;
     150              :                 }
     151              : 
     152          671 :                 string get_type_name = "%sproxy_get_type".printf (get_ccode_lower_case_prefix (iface));
     153              : 
     154          671 :                 if (add_symbol_declaration (decl_space, iface, get_type_name)) {
     155          612 :                         return;
     156              :                 }
     157              : 
     158           59 :                 decl_space.add_type_declaration (new CCodeNewline ());
     159           59 :                 var macro = "(%s ())".printf (get_type_name);
     160           59 :                 decl_space.add_type_declaration (new CCodeMacroReplacement ("%s_PROXY".printf (get_ccode_type_id (iface)), macro));
     161              : 
     162              :                 // declare proxy_get_type function
     163           59 :                 var proxy_get_type = new CCodeFunction (get_type_name, "GType");
     164           59 :                 proxy_get_type.modifiers = CCodeModifiers.CONST | CCodeModifiers.EXTERN;
     165           59 :                 requires_vala_extern = true;
     166              : 
     167           59 :                 decl_space.add_function_declaration (proxy_get_type);
     168              : 
     169           59 :                 if (in_plugin) {
     170            0 :                         var proxy_register_type = new CCodeFunction ("%sproxy_register_dynamic_type".printf (get_ccode_lower_case_prefix (iface)));
     171            0 :                         proxy_register_type.add_parameter (new CCodeParameter ("module", "GTypeModule*"));
     172            0 :                         proxy_register_type.modifiers |= CCodeModifiers.EXTERN;
     173            0 :                         requires_vala_extern = true;
     174              : 
     175            0 :                         decl_space.add_function_declaration (proxy_register_type);
     176              :                 }
     177              :         }
     178              : 
     179          145 :         public override void visit_interface (Interface iface) {
     180          118 :                 base.visit_interface (iface);
     181              : 
     182          118 :                 string dbus_iface_name = get_dbus_name (iface);
     183          118 :                 if (dbus_iface_name == null) {
     184           91 :                         return;
     185              :                 }
     186              : 
     187           27 :                 cfile.add_include ("gio/gio.h");
     188              : 
     189              :                 // create proxy class
     190           27 :                 string cname = get_ccode_name (iface) + "Proxy";
     191           27 :                 string lower_cname = get_ccode_lower_case_prefix (iface) + "proxy";
     192              : 
     193           27 :                 cfile.add_type_declaration (new CCodeTypeDefinition ("GDBusProxy", new CCodeVariableDeclarator (cname)));
     194           27 :                 cfile.add_type_declaration (new CCodeTypeDefinition ("GDBusProxyClass", new CCodeVariableDeclarator (cname + "Class")));
     195              : 
     196              :                 string type_macro;
     197              : 
     198           27 :                 if (in_plugin) {
     199            0 :                         type_macro = "G_DEFINE_DYNAMIC_TYPE_EXTENDED";
     200              :                 } else {
     201           27 :                         type_macro = "G_DEFINE_TYPE_EXTENDED";
     202              :                 }
     203              : 
     204           27 :                 var define_type = new CCodeFunctionCall (new CCodeIdentifier (type_macro));
     205           27 :                 define_type.add_argument (new CCodeIdentifier (cname));
     206           27 :                 define_type.add_argument (new CCodeIdentifier (lower_cname));
     207           27 :                 define_type.add_argument (new CCodeIdentifier ("G_TYPE_DBUS_PROXY"));
     208           27 :                 define_type.add_argument (new CCodeConstant ("0"));
     209           27 :                 define_type.add_argument (new CCodeIdentifier (implement_interface (define_type, iface, iface)));
     210              : 
     211           27 :                 cfile.add_type_member_definition (define_type);
     212              : 
     213           27 :                 var proxy_class_init = new CCodeFunction (lower_cname + "_class_init", "void");
     214           27 :                 proxy_class_init.add_parameter (new CCodeParameter ("klass", cname + "Class*"));
     215           27 :                 proxy_class_init.modifiers = CCodeModifiers.STATIC;
     216           27 :                 push_function (proxy_class_init);
     217           27 :                 var proxy_class = new CCodeFunctionCall (new CCodeIdentifier ("G_DBUS_PROXY_CLASS"));
     218           27 :                 proxy_class.add_argument (new CCodeIdentifier ("klass"));
     219           27 :                 ccode.add_assignment (new CCodeMemberAccess.pointer (proxy_class, "g_signal"), new CCodeIdentifier (lower_cname + "_g_signal"));
     220           27 :                 pop_function ();
     221           27 :                 cfile.add_function (proxy_class_init);
     222              : 
     223           27 :                 generate_signal_handler_function (iface);
     224              : 
     225           27 :                 if (in_plugin) {
     226            0 :                         var proxy_class_finalize = new CCodeFunction (lower_cname + "_class_finalize", "void");
     227            0 :                         proxy_class_finalize.add_parameter (new CCodeParameter ("klass", cname + "Class*"));
     228            0 :                         proxy_class_finalize.modifiers = CCodeModifiers.STATIC;
     229            0 :                         cfile.add_function (proxy_class_finalize);
     230              : 
     231            0 :                         var proxy_type_init = new CCodeFunction (lower_cname + "_register_dynamic_type", "void");
     232            0 :                         proxy_type_init.add_parameter (new CCodeParameter ("module", "GTypeModule*"));
     233            0 :                         push_function (proxy_type_init);
     234            0 :                         var call_register_type = new CCodeFunctionCall (new CCodeIdentifier (lower_cname + "_register_type"));
     235            0 :                         call_register_type.add_argument (new CCodeIdentifier ("module"));
     236            0 :                         ccode.add_expression (call_register_type);
     237            0 :                         pop_function ();
     238            0 :                         cfile.add_function(proxy_type_init);
     239              :                 }
     240              : 
     241           27 :                 var proxy_instance_init = new CCodeFunction (lower_cname + "_init", "void");
     242           27 :                 proxy_instance_init.add_parameter (new CCodeParameter ("self", cname + "*"));
     243           27 :                 proxy_instance_init.modifiers = CCodeModifiers.STATIC;
     244           27 :                 push_function (proxy_instance_init);
     245              : 
     246              :                 // TODO Replaces setting of "vala-dbus-interface-info"
     247           27 :                 var dbus_proxy_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_DBUS_PROXY"));
     248           27 :                 dbus_proxy_cast.add_argument (new CCodeIdentifier ("self"));
     249           27 :                 var set_interface_info = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_set_interface_info"));
     250           27 :                 set_interface_info.add_argument (dbus_proxy_cast);
     251           27 :                 set_interface_info.add_argument (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_interface_info (iface)), "GDBusInterfaceInfo *"));
     252           27 :                 ccode.add_expression (set_interface_info);
     253              : 
     254           27 :                 pop_function ();
     255           27 :                 cfile.add_function (proxy_instance_init);
     256              : 
     257           27 :                 generate_proxy_interface_init (iface, iface);
     258              :         }
     259              : 
     260        17596 :         public override void visit_method_call (MethodCall expr) {
     261        17573 :                 var mtype = expr.call.value_type as MethodType;
     262        16800 :                 bool bus_get_proxy_async = (mtype != null && get_ccode_name (mtype.method_symbol) == "g_bus_get_proxy");
     263        16800 :                 bool bus_get_proxy_sync = (mtype != null && get_ccode_name (mtype.method_symbol) == "g_bus_get_proxy_sync");
     264        16800 :                 bool conn_get_proxy_async = (mtype != null && get_ccode_name (mtype.method_symbol) == "g_dbus_connection_get_proxy");
     265        16800 :                 bool conn_get_proxy_sync = (mtype != null && get_ccode_name (mtype.method_symbol) == "g_dbus_connection_get_proxy_sync");
     266        17573 :                 if (!bus_get_proxy_async && !bus_get_proxy_sync && !conn_get_proxy_async && !conn_get_proxy_sync) {
     267        17546 :                         base.visit_method_call (expr);
     268        17546 :                         return;
     269              :                 }
     270              : 
     271           27 :                 var ma = (MemberAccess) expr.call;
     272           27 :                 var type_arg = ma.get_type_arguments ().get (0);
     273              : 
     274              :                 CCodeExpression proxy_type;
     275              :                 CCodeExpression dbus_iface_name;
     276              : 
     277           27 :                 var object_type = type_arg as ObjectType;
     278           54 :                 if (object_type != null) {
     279           26 :                         var iface = (Interface) object_type.type_symbol;
     280              : 
     281           26 :                         if (get_dbus_name (iface) == null) {
     282            0 :                                 Report.error (expr.source_reference, "`%s' is not a D-Bus interface", iface.get_full_name ());
     283            0 :                                 return;
     284              :                         }
     285              : 
     286           26 :                         proxy_type = new CCodeIdentifier ("%s_PROXY".printf (get_ccode_type_id (iface)));
     287           26 :                         dbus_iface_name = new CCodeConstant ("\"%s\"".printf (get_dbus_name (iface)));
     288              :                 } else {
     289              :                         // use runtime type information for generic methods
     290              : 
     291            1 :                         var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
     292            1 :                         quark.add_argument (new CCodeConstant ("\"vala-dbus-proxy-type\""));
     293              : 
     294            1 :                         var get_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_get_qdata"));
     295            1 :                         get_qdata.add_argument (get_type_id_expression (type_arg));
     296            1 :                         get_qdata.add_argument (quark);
     297              : 
     298            1 :                         proxy_type = new CCodeFunctionCall (new CCodeCastExpression (get_qdata, "GType (*) (void)"));
     299              : 
     300            1 :                         quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
     301            1 :                         quark.add_argument (new CCodeConstant ("\"vala-dbus-interface-name\""));
     302              : 
     303            1 :                         get_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_get_qdata"));
     304            1 :                         get_qdata.add_argument (get_type_id_expression (type_arg));
     305            1 :                         get_qdata.add_argument (quark);
     306              : 
     307            3 :                         dbus_iface_name = get_qdata;
     308              :                 }
     309              : 
     310           27 :                 if (bus_get_proxy_async || conn_get_proxy_async) {
     311           10 :                         if (ma.member_name == "end" && ma.inner.symbol_reference == ma.symbol_reference) {
     312              :                                 // method can fail
     313            2 :                                 current_method_inner_error = true;
     314              : 
     315           27 :                                 var args = expr.get_argument_list ();
     316            2 :                                 Expression res = args.get (0);
     317              : 
     318            2 :                                 var source_var = get_temp_variable (expr.value_type, expr.value_type.value_owned);
     319            2 :                                 var source_ref = get_variable_cexpression (source_var.name);
     320            2 :                                 emit_temp_var (source_var);
     321            2 :                                 var source = new CCodeFunctionCall (new CCodeIdentifier ("g_async_result_get_source_object"));
     322            2 :                                 source.add_argument (get_cvalue (res));
     323            2 :                                 ccode.add_assignment (source_ref, source);
     324              : 
     325            2 :                                 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_async_initable_new_finish"));
     326            2 :                                 ccall.add_argument (new CCodeCastExpression (source_ref, "GAsyncInitable *"));
     327            2 :                                 ccall.add_argument (get_cvalue (res));
     328            2 :                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_inner_error_cexpression ()));
     329              : 
     330            2 :                                 var temp_var = get_temp_variable (expr.value_type, expr.value_type.value_owned);
     331            2 :                                 var temp_ref = get_variable_cexpression (temp_var.name);
     332            2 :                                 emit_temp_var (temp_var);
     333            2 :                                 ccode.add_assignment (temp_ref, new CCodeCastExpression (ccall, get_ccode_name (expr.value_type)));
     334              : 
     335              :                                 // g_async_result_get_source_object transfers ownership, unref after use
     336            2 :                                 var unref_proxy = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
     337            2 :                                 unref_proxy.add_argument (source_ref);
     338            2 :                                 ccode.add_expression (unref_proxy);
     339              : 
     340            2 :                                 set_cvalue (expr, temp_ref);
     341              : 
     342            2 :                                 return;
     343              :                         }
     344              :                 }
     345              : 
     346           25 :                 var base_arg_index = 0;
     347           25 :                 if (bus_get_proxy_async || bus_get_proxy_sync)
     348           22 :                         base_arg_index = 1;
     349              : 
     350           25 :                 var args = expr.get_argument_list ();
     351           25 :                 Expression name = args.get (base_arg_index + 0);
     352           25 :                 Expression object_path = args.get (base_arg_index + 1);
     353           25 :                 Expression flags = args.get (base_arg_index + 2);
     354           25 :                 Expression cancellable = args.get (base_arg_index + 3);
     355              : 
     356              :                 // method can fail
     357           25 :                 current_method_inner_error = true;
     358              : 
     359              :                 CCodeFunctionCall ccall;
     360           25 :                 if (bus_get_proxy_async || conn_get_proxy_async) {
     361            8 :                         ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_async_initable_new_async"));
     362              :                 } else {
     363           17 :                         ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_initable_new"));
     364              :                 }
     365           25 :                 ccall.add_argument (proxy_type);
     366           25 :                 if (bus_get_proxy_async || conn_get_proxy_async) {
     367              :                         // I/O priority
     368            8 :                         ccall.add_argument (new CCodeConstant ("0"));
     369              :                 }
     370           25 :                 ccall.add_argument (get_cvalue (cancellable));
     371           25 :                 if (bus_get_proxy_async || conn_get_proxy_async) {
     372           10 :                         if (expr.is_yield_expression) {
     373              :                                 // asynchronous call
     374            6 :                                 ccall.add_argument (new CCodeIdentifier (generate_ready_function (current_method)));
     375            6 :                                 ccall.add_argument (new CCodeIdentifier ("_data_"));
     376              :                         } else {
     377              :                                 // begin
     378            2 :                                 Expression callback = args.get (base_arg_index + 4);
     379            2 :                                 ccall.add_argument (get_cvalue (callback));
     380            2 :                                 ccall.add_argument (get_delegate_target (callback));
     381              :                         }
     382              :                 } else {
     383           17 :                         ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_inner_error_cexpression ()));
     384              :                 }
     385           25 :                 ccall.add_argument (new CCodeConstant ("\"g-flags\""));
     386           25 :                 ccall.add_argument (get_cvalue (flags));
     387           25 :                 ccall.add_argument (new CCodeConstant ("\"g-name\""));
     388           25 :                 ccall.add_argument (get_cvalue (name));
     389           50 :                 if (bus_get_proxy_async || bus_get_proxy_sync) {
     390           22 :                         Expression bus_type = args.get (0);
     391           22 :                         ccall.add_argument (new CCodeConstant ("\"g-bus-type\""));
     392           22 :                         ccall.add_argument (get_cvalue (bus_type));
     393              :                 } else {
     394            3 :                         Expression connection = ma.inner;
     395            4 :                         if (ma.member_name == "begin" && ma.inner.symbol_reference == ma.symbol_reference) {
     396            1 :                                 var inner_ma = (MemberAccess) ma.inner;
     397            2 :                                 connection = inner_ma.inner;
     398              :                         }
     399            3 :                         ccall.add_argument (new CCodeConstant ("\"g-connection\""));
     400            3 :                         ccall.add_argument (get_cvalue (connection));
     401              :                 }
     402           25 :                 ccall.add_argument (new CCodeConstant ("\"g-object-path\""));
     403           25 :                 ccall.add_argument (get_cvalue (object_path));
     404           25 :                 ccall.add_argument (new CCodeConstant ("\"g-interface-name\""));
     405           25 :                 ccall.add_argument (dbus_iface_name);
     406           25 :                 ccall.add_argument (new CCodeConstant ("NULL"));
     407              : 
     408           25 :                 if (bus_get_proxy_async || conn_get_proxy_async) {
     409            8 :                         if (expr.is_yield_expression) {
     410            6 :                                 int state = emit_context.next_coroutine_state++;
     411              : 
     412            6 :                                 ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_"), new CCodeConstant (state.to_string ()));
     413            6 :                                 ccode.add_expression (ccall);
     414            6 :                                 ccode.add_return (new CCodeConstant ("FALSE"));
     415            6 :                                 ccode.add_label ("_state_%d".printf (state));
     416              : 
     417            6 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_async_initable_new_finish"));
     418            6 :                                 ccall.add_argument (new CCodeCastExpression (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_source_object_"), "GAsyncInitable *"));
     419              :                                 // pass GAsyncResult stored in closure to finish function
     420            6 :                                 ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_res_"));
     421            6 :                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_inner_error_cexpression ()));
     422              :                         } else {
     423              :                                 // begin
     424            2 :                                 ccode.add_expression (ccall);
     425            2 :                                 return;
     426              :                         }
     427              :                 }
     428              : 
     429           23 :                 var temp_var = get_temp_variable (expr.value_type, expr.value_type.value_owned);
     430           23 :                 var temp_ref = get_variable_cexpression (temp_var.name);
     431              : 
     432           23 :                 emit_temp_var (temp_var);
     433              : 
     434           23 :                 ccode.add_assignment (temp_ref, new CCodeCastExpression (ccall, get_ccode_name (expr.value_type)));
     435           23 :                 set_cvalue (expr, temp_ref);
     436              :         }
     437              : 
     438            5 :         string generate_dbus_signal_handler (Signal sig, ObjectTypeSymbol sym) {
     439            5 :                 string wrapper_name = "_dbus_handle_%s_%s".printf (get_ccode_lower_case_name (sym), get_ccode_lower_case_name (sig));
     440              : 
     441            5 :                 var function = new CCodeFunction (wrapper_name);
     442            5 :                 function.modifiers = CCodeModifiers.STATIC;
     443            5 :                 function.add_parameter (new CCodeParameter ("self", get_ccode_name (sym) + "*"));
     444            5 :                 function.add_parameter (new CCodeParameter ("parameters", "GVariant*"));
     445              : 
     446            5 :                 push_function (function);
     447              : 
     448            5 :                 ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_arguments_iter"));
     449              : 
     450            5 :                 var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
     451            5 :                 iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_iter")));
     452            5 :                 iter_init.add_argument (new CCodeIdentifier ("parameters"));
     453            5 :                 ccode.add_expression (iter_init);
     454              : 
     455            5 :                 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_emit_by_name"));
     456            5 :                 ccall.add_argument (new CCodeIdentifier ("self"));
     457            5 :                 ccall.add_argument (get_signal_canonical_constant (sig));
     458              : 
     459           15 :                 foreach (Parameter param in sig.get_parameters ()) {
     460            5 :                         var param_name = get_variable_cname (param.name);
     461            5 :                         var owned_type = param.variable_type.copy ();
     462            5 :                         owned_type.value_owned = true;
     463              : 
     464            5 :                         ccode.add_declaration (get_ccode_name (owned_type), new CCodeVariableDeclarator.zero (param_name, default_value_for_type (param.variable_type, true)));
     465              : 
     466            5 :                         unowned Struct? st = param.variable_type.type_symbol as Struct;
     467            5 :                         if (st != null && !st.is_simple_type ()) {
     468            0 :                                 ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param_name)));
     469              :                         } else {
     470            5 :                                 ccall.add_argument (new CCodeIdentifier (param_name));
     471              :                         }
     472              : 
     473            6 :                         if (param.variable_type is ArrayType) {
     474            1 :                                 var array_type = (ArrayType) param.variable_type;
     475            1 :                                 var length_ctype = get_ccode_array_length_type (array_type);
     476              : 
     477            2 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     478            1 :                                         string length_cname = get_variable_array_length_cname (param, dim);
     479              : 
     480            1 :                                         ccode.add_declaration (length_ctype, new CCodeVariableDeclarator (length_cname, new CCodeConstant ("0")));
     481            1 :                                         ccall.add_argument (new CCodeIdentifier (length_cname));
     482              :                                 }
     483              :                         }
     484              : 
     485            5 :                         read_expression (param.variable_type, new CCodeIdentifier ("_arguments_iter"), new CCodeIdentifier (param_name), param);
     486              :                 }
     487              : 
     488            5 :                 ccode.add_expression (ccall);
     489              : 
     490           15 :                 foreach (Parameter param in sig.get_parameters ()) {
     491            5 :                         var owned_type = param.variable_type.copy ();
     492            5 :                         owned_type.value_owned = true;
     493              : 
     494            8 :                         if (requires_destroy (owned_type)) {
     495              :                                 // keep local alive (symbol_reference is weak)
     496            3 :                                 var local = new LocalVariable (owned_type, param.name);
     497            3 :                                 ccode.add_expression (destroy_local (local));
     498              :                         }
     499              :                 }
     500              : 
     501            5 :                 pop_function ();
     502              : 
     503            5 :                 cfile.add_function_declaration (function);
     504            5 :                 cfile.add_function (function);
     505              : 
     506            5 :                 return wrapper_name;
     507              :         }
     508              : 
     509           54 :         void generate_signal_handler_function (ObjectTypeSymbol sym) {
     510           27 :                 var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "proxy_g_signal", "void");
     511           27 :                 cfunc.add_parameter (new CCodeParameter ("proxy", "GDBusProxy*"));
     512           27 :                 cfunc.add_parameter (new CCodeParameter ("sender_name", "const gchar*"));
     513           27 :                 cfunc.add_parameter (new CCodeParameter ("signal_name", "const gchar*"));
     514           27 :                 cfunc.add_parameter (new CCodeParameter ("parameters", "GVariant*"));
     515              : 
     516           27 :                 cfunc.modifiers |= CCodeModifiers.STATIC;
     517              : 
     518           27 :                 cfile.add_function_declaration (cfunc);
     519              : 
     520           27 :                 push_function (cfunc);
     521              : 
     522           27 :                 bool firstif = true;
     523              : 
     524           38 :                 foreach (Signal sig in sym.get_signals ()) {
     525            6 :                         if (sig.access != SymbolAccessibility.PUBLIC) {
     526            1 :                                 continue;
     527              :                         }
     528              : 
     529            5 :                         cfile.add_include ("string.h");
     530              : 
     531            5 :                         var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
     532            5 :                         ccheck.add_argument (new CCodeIdentifier ("signal_name"));
     533            5 :                         ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig))));
     534              : 
     535            5 :                         var cond = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccheck, new CCodeConstant ("0"));
     536            5 :                         if (firstif) {
     537            4 :                                 ccode.open_if (cond);
     538            4 :                                 firstif = false;
     539              :                         } else {
     540            1 :                                 ccode.else_if (cond);
     541              :                         }
     542              : 
     543            5 :                         var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_dbus_signal_handler (sig, sym)));
     544            5 :                         ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("proxy"), get_ccode_name (sym) + "*"));
     545            5 :                         ccall.add_argument (new CCodeIdentifier ("parameters"));
     546              : 
     547            5 :                         ccode.add_expression (ccall);
     548              :                 }
     549           27 :                 if (!firstif) {
     550            4 :                         ccode.close ();
     551              :                 }
     552              : 
     553           27 :                 pop_function ();
     554              : 
     555           27 :                 cfile.add_function (cfunc);
     556              :         }
     557              : 
     558          128 :         void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name, int method_timeout) {
     559           64 :                 var gdbusproxy = new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *");
     560              : 
     561           64 :                 var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_connection"));
     562           64 :                 connection.add_argument (gdbusproxy);
     563              : 
     564           64 :                 bool uses_fd = dbus_method_uses_file_descriptor (m);
     565           64 :                 if (uses_fd) {
     566            4 :                         cfile.add_include ("gio/gunixfdlist.h");
     567            4 :                         ccode.add_declaration ("GUnixFDList*", new CCodeVariableDeclarator ("_fd_list"));
     568              :                 }
     569              : 
     570           64 :                 bool has_error_argument = m.tree_can_fail;
     571              :                 CCodeExpression error_argument;
     572           64 :                 if (has_error_argument) {
     573           60 :                         error_argument = new CCodeIdentifier ("error");
     574              :                 } else {
     575            4 :                         error_argument = new CCodeConstant ("NULL");
     576              :                 }
     577              : 
     578          128 :                 if (call_type != CallType.FINISH) {
     579           51 :                         var destination = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_name"));
     580           51 :                         destination.add_argument (gdbusproxy);
     581              : 
     582           51 :                         var interface_name = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_interface_name"));
     583           51 :                         interface_name.add_argument (gdbusproxy);
     584              : 
     585           51 :                         var object_path = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_object_path"));
     586           51 :                         object_path.add_argument (gdbusproxy);
     587              : 
     588              :                         CCodeExpression timeout;
     589           51 :                         if (method_timeout <= 0) {
     590           51 :                                 timeout = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_default_timeout"));
     591           51 :                                 ((CCodeFunctionCall) timeout).add_argument (gdbusproxy);
     592              :                         } else {
     593            0 :                                 timeout = new CCodeConstant ("%d".printf (method_timeout));
     594              :                         }
     595              : 
     596              :                         // register errors
     597           51 :                         var error_types = new ArrayList<DataType> ();
     598           51 :                         m.get_error_types (error_types);
     599          167 :                         foreach (var error_type in error_types) {
     600           58 :                                 var errtype = (ErrorType) error_type;
     601           58 :                                 if (errtype.error_domain != null) {
     602           48 :                                         ccode.add_expression (new CCodeIdentifier (get_ccode_upper_case_name (errtype.error_domain)));
     603              :                                 }
     604              :                         }
     605              : 
     606              :                         // build D-Bus message
     607              : 
     608           51 :                         ccode.add_declaration ("GDBusMessage", new CCodeVariableDeclarator ("*_message"));
     609              : 
     610           51 :                         var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_new_method_call"));
     611           51 :                         ccall.add_argument (destination);
     612           51 :                         ccall.add_argument (object_path);
     613           51 :                         if (iface_name != null) {
     614           50 :                                 ccall.add_argument (new CCodeConstant ("\"%s\"".printf (iface_name)));
     615              :                         } else {
     616            1 :                                 ccall.add_argument (interface_name);
     617              :                         }
     618           51 :                         ccall.add_argument (new CCodeConstant ("\"%s\"".printf (method_name)));
     619           51 :                         ccode.add_assignment (new CCodeIdentifier ("_message"), ccall);
     620              : 
     621           51 :                         ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
     622           51 :                         ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
     623              : 
     624           51 :                         var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
     625           51 :                         builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
     626           51 :                         builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
     627           51 :                         ccode.add_expression (builder_init);
     628              : 
     629           51 :                         if (uses_fd) {
     630            3 :                                 ccode.add_assignment (new CCodeIdentifier ("_fd_list"), new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_new")));
     631              :                         }
     632              : 
     633           51 :                         CCodeExpression cancellable = new CCodeConstant ("NULL");
     634              : 
     635          145 :                         foreach (Parameter param in m.get_parameters ()) {
     636           80 :                                 if (param.direction == ParameterDirection.IN) {
     637           34 :                                         CCodeExpression expr = new CCodeIdentifier (get_variable_cname (param.name));
     638           34 :                                         if (param.variable_type.is_real_struct_type ()) {
     639            1 :                                                 expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr);
     640              :                                         }
     641              : 
     642           34 :                                         if (param.variable_type is ObjectType && param.variable_type.type_symbol.get_full_name () == "GLib.Cancellable") {
     643            4 :                                                 cancellable = expr;
     644            2 :                                                 continue;
     645              :                                         }
     646              : 
     647           32 :                                         if (param.variable_type is ObjectType && param.variable_type.type_symbol.get_full_name () == "GLib.BusName") {
     648              :                                                 // ignore BusName sender parameters
     649            0 :                                                 continue;
     650              :                                         }
     651              : 
     652           32 :                                         send_dbus_value (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
     653              :                                 }
     654              :                         }
     655              : 
     656           51 :                         var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
     657           51 :                         builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
     658           51 :                         ccode.add_assignment (new CCodeIdentifier ("_arguments"), builder_end);
     659              : 
     660           51 :                         var set_body = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_body"));
     661           51 :                         set_body.add_argument (new CCodeIdentifier ("_message"));
     662           51 :                         set_body.add_argument (new CCodeIdentifier ("_arguments"));
     663           51 :                         ccode.add_expression (set_body);
     664              : 
     665           51 :                         if (uses_fd) {
     666            3 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
     667            3 :                                 ccall.add_argument (new CCodeIdentifier ("_message"));
     668            3 :                                 ccall.add_argument (new CCodeIdentifier ("_fd_list"));
     669            3 :                                 ccode.add_expression (ccall);
     670              : 
     671            3 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
     672            3 :                                 ccall.add_argument (new CCodeIdentifier ("_fd_list"));
     673            3 :                                 ccode.add_expression (ccall);
     674              :                         }
     675              : 
     676              :                         // send D-Bus message
     677              : 
     678           51 :                         if (call_type == CallType.SYNC) {
     679           37 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message_with_reply_sync"));
     680           37 :                                 ccall.add_argument (connection);
     681           37 :                                 ccall.add_argument (new CCodeIdentifier ("_message"));
     682           37 :                                 ccall.add_argument (new CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
     683           37 :                                 ccall.add_argument (timeout);
     684           37 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     685           37 :                                 ccall.add_argument (cancellable);
     686           37 :                                 ccall.add_argument (error_argument);
     687           37 :                                 ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
     688           15 :                         } else if (call_type == CallType.NO_REPLY) {
     689            1 :                                 var set_flags = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_flags"));
     690            1 :                                 set_flags.add_argument (new CCodeIdentifier ("_message"));
     691            1 :                                 set_flags.add_argument (new CCodeConstant ("G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED"));
     692            1 :                                 ccode.add_expression (set_flags);
     693              : 
     694            1 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message"));
     695            1 :                                 ccall.add_argument (connection);
     696            1 :                                 ccall.add_argument (new CCodeIdentifier ("_message"));
     697            1 :                                 ccall.add_argument (new CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
     698            1 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     699            1 :                                 ccall.add_argument (error_argument);
     700            1 :                                 ccode.add_expression (ccall);
     701           26 :                         } else if (call_type == CallType.ASYNC) {
     702           13 :                                 var callback_specified = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier ("_callback_"), new CCodeConstant ("NULL"));
     703           13 :                                 ccode.open_if (callback_specified);
     704              : 
     705           13 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message_with_reply"));
     706           13 :                                 ccall.add_argument (connection);
     707           13 :                                 ccall.add_argument (new CCodeIdentifier ("_message"));
     708           13 :                                 ccall.add_argument (new CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
     709           13 :                                 ccall.add_argument (timeout);
     710           13 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     711           13 :                                 ccall.add_argument (cancellable);
     712              : 
     713           13 :                                 CCodeFunctionCall res_wrapper = null;
     714              : 
     715              :                                 // use wrapper as source_object wouldn't be correct otherwise
     716           13 :                                 ccall.add_argument (new CCodeIdentifier (generate_async_callback_wrapper ()));
     717           13 :                                 res_wrapper = new CCodeFunctionCall (new CCodeIdentifier ("g_task_new"));
     718           13 :                                 res_wrapper.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GObject *"));
     719           13 :                                 res_wrapper.add_argument (new CCodeConstant ("NULL"));
     720           13 :                                 res_wrapper.add_argument (new CCodeIdentifier ("_callback_"));
     721           13 :                                 res_wrapper.add_argument (new CCodeIdentifier ("_user_data_"));
     722           13 :                                 ccall.add_argument (res_wrapper);
     723              : 
     724           13 :                                 ccode.add_expression (ccall);
     725              : 
     726           13 :                                 ccode.add_else ();
     727              : 
     728           13 :                                 var set_flags = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_flags"));
     729           13 :                                 set_flags.add_argument (new CCodeIdentifier ("_message"));
     730           13 :                                 set_flags.add_argument (new CCodeConstant ("G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED"));
     731           13 :                                 ccode.add_expression (set_flags);
     732              : 
     733           13 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message"));
     734           13 :                                 ccall.add_argument (connection);
     735           13 :                                 ccall.add_argument (new CCodeIdentifier ("_message"));
     736           13 :                                 ccall.add_argument (new CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
     737           13 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     738           13 :                                 ccall.add_argument (new CCodeConstant ("NULL"));
     739           13 :                                 ccode.add_expression (ccall);
     740              : 
     741           13 :                                 ccode.close ();
     742              :                         }
     743              : 
     744              :                         // free D-Bus message
     745              : 
     746           51 :                         ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
     747           51 :                         ccall.add_argument (new CCodeIdentifier ("_message"));
     748           51 :                         ccode.add_expression (ccall);
     749              :                 } else {
     750           13 :                         var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message_with_reply_finish"));
     751           13 :                         ccall.add_argument (connection);
     752              : 
     753              :                         // unwrap async result
     754           13 :                         ccode.add_declaration ("GAsyncResult", new CCodeVariableDeclarator ("*_inner_res"));
     755              : 
     756           13 :                         var inner_res = new CCodeFunctionCall (new CCodeIdentifier ("g_task_propagate_pointer"));
     757           13 :                         inner_res.add_argument (new CCodeCastExpression (new CCodeIdentifier ("_res_"), "GTask *"));
     758           13 :                         inner_res.add_argument (new CCodeConstant ("NULL"));
     759           13 :                         ccode.add_assignment (new CCodeIdentifier ("_inner_res"), inner_res);
     760              : 
     761           13 :                         ccall.add_argument (new CCodeIdentifier ("_inner_res"));
     762           13 :                         ccall.add_argument (error_argument);
     763           13 :                         ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
     764              : 
     765              :                         // _inner_res is guaranteed to be non-NULL, so just unref it
     766           13 :                         var unref_inner_res = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
     767           13 :                         unref_inner_res.add_argument (new CCodeIdentifier ("_inner_res"));
     768           13 :                         ccode.add_expression (unref_inner_res);
     769              :                 }
     770              : 
     771          114 :                 if (call_type == CallType.SYNC || call_type == CallType.FINISH) {
     772           50 :                         ccode.add_declaration ("GDBusMessage", new CCodeVariableDeclarator ("*_reply_message"));
     773              : 
     774           50 :                         var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
     775           50 :                         unref_reply.add_argument (new CCodeIdentifier ("_reply_message"));
     776              : 
     777              :                         // return on io error
     778           50 :                         var reply_is_null = new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply_message"));
     779           50 :                         ccode.open_if (reply_is_null);
     780           50 :                         return_default_value (m.return_type);
     781           50 :                         ccode.close ();
     782              : 
     783              :                         // return on remote error
     784           50 :                         var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_to_gerror"));
     785           50 :                         ccall.add_argument (new CCodeIdentifier ("_reply_message"));
     786           50 :                         ccall.add_argument (error_argument);
     787           50 :                         ccode.open_if (ccall);
     788           50 :                         ccode.add_expression (unref_reply);
     789           50 :                         return_default_value (m.return_type);
     790           50 :                         ccode.close ();
     791              : 
     792           50 :                         bool has_result = !(m.return_type is VoidType);
     793              : 
     794           50 :                         if (uses_fd) {
     795            3 :                                 ccode.add_declaration ("gint", new CCodeVariableDeclarator.zero ("_fd_index", new CCodeConstant ("0")));
     796            3 :                                 ccode.add_declaration ("gint", new CCodeVariableDeclarator ("_fd"));
     797              :                         }
     798              : 
     799          144 :                         foreach (Parameter param in m.get_parameters ()) {
     800           47 :                                 if (param.direction == ParameterDirection.OUT) {
     801           14 :                                         has_result = true;
     802              :                                 }
     803              :                         }
     804              : 
     805           81 :                         if (has_result) {
     806           31 :                                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
     807           31 :                                 ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_reply_iter"));
     808              : 
     809           31 :                                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_get_body"));
     810           31 :                                 ccall.add_argument (new CCodeIdentifier ("_reply_message"));
     811           31 :                                 ccode.add_assignment (new CCodeIdentifier ("_reply"), ccall);
     812              : 
     813           31 :                                 var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
     814           31 :                                 iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_iter")));
     815           31 :                                 iter_init.add_argument (new CCodeIdentifier ("_reply"));
     816           31 :                                 ccode.add_expression (iter_init);
     817              : 
     818           99 :                                 foreach (Parameter param in m.get_parameters ()) {
     819           48 :                                         if (param.direction == ParameterDirection.OUT) {
     820           14 :                                                 ccode.add_declaration (get_ccode_name (param.variable_type), new CCodeVariableDeclarator.zero ("_vala_%s".printf (param.name), default_value_for_type (param.variable_type, true)));
     821              : 
     822           14 :                                                 var array_type = param.variable_type as ArrayType;
     823            4 :                                                 if (array_type != null) {
     824            2 :                                                         var length_ctype = get_ccode_array_length_type (array_type);
     825            4 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     826            2 :                                                                 ccode.add_declaration (length_ctype, new CCodeVariableDeclarator ("_vala_%s_length%d".printf (param.name, dim), new CCodeConstant ("0")));
     827              :                                                         }
     828              :                                                 }
     829              : 
     830           14 :                                                 var target = new CCodeIdentifier ("_vala_%s".printf (param.name));
     831              :                                                 bool may_fail;
     832              : 
     833           14 :                                                 receive_dbus_value (param.variable_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), target, param, error_argument, out may_fail);
     834              : 
     835              :                                                 // TODO check that parameter is not NULL (out parameters are optional)
     836              :                                                 // free value if parameter is NULL
     837           14 :                                                 ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (get_variable_cname (param.name))), target);
     838              : 
     839           14 :                                                 if (array_type != null) {
     840            4 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     841              :                                                                 // TODO check that parameter is not NULL (out parameters are optional)
     842            2 :                                                                 ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("%s_length%d".printf (param.name, dim))), new CCodeIdentifier ("_vala_%s_length%d".printf (param.name, dim)));
     843              :                                                         }
     844              :                                                 }
     845              : 
     846           14 :                                                 if (may_fail && has_error_argument) {
     847            2 :                                                         ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("error"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error"))));
     848            2 :                                                         ccode.add_expression (unref_reply);
     849            2 :                                                         return_default_value (m.return_type);
     850            2 :                                                         ccode.close ();
     851              :                                                 }
     852              :                                         }
     853              :                                 }
     854              : 
     855           31 :                                 if (!(m.return_type is VoidType)) {
     856           62 :                                         if (m.return_type.is_real_non_null_struct_type ()) {
     857            1 :                                                 var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
     858            1 :                                                 receive_dbus_value (m.return_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), target, m);
     859              :                                         } else {
     860           30 :                                                 ccode.add_declaration (get_ccode_name (m.return_type), new CCodeVariableDeclarator.zero ("_result", default_value_for_type (m.return_type, true)));
     861              : 
     862           30 :                                                 var array_type = m.return_type as ArrayType;
     863           14 :                                                 if (array_type != null) {
     864            7 :                                                         var length_ctype = get_ccode_array_length_type (array_type);
     865           17 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     866           10 :                                                                 ccode.add_declaration (length_ctype, new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
     867              :                                                         }
     868              :                                                 }
     869              : 
     870              :                                                 bool may_fail;
     871           30 :                                                 receive_dbus_value (m.return_type, new CCodeIdentifier ("_reply_message"), new CCodeIdentifier ("_reply_iter"), new CCodeIdentifier ("_result"), m, new CCodeIdentifier ("error"), out may_fail);
     872              : 
     873           30 :                                                 if (array_type != null) {
     874           17 :                                                         for (int dim = 1; dim <= array_type.rank; dim++) {
     875              :                                                                 // TODO check that parameter is not NULL (out parameters are optional)
     876           10 :                                                                 ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)));
     877              :                                                         }
     878              :                                                 }
     879              : 
     880           30 :                                                 if (may_fail) {
     881            2 :                                                         ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.AND, new CCodeIdentifier ("error"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("error"))));
     882            2 :                                                         ccode.add_expression (unref_reply);
     883            2 :                                                         return_default_value (m.return_type);
     884            2 :                                                         ccode.close ();
     885              :                                                 }
     886              :                                         }
     887              :                                 }
     888              :                         }
     889              : 
     890           50 :                         ccode.add_expression (unref_reply);
     891              : 
     892           50 :                         if (!(m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ())) {
     893           30 :                                 ccode.add_return (new CCodeIdentifier ("_result"));
     894              :                         }
     895              :                 }
     896              :         }
     897              : 
     898           37 :         string generate_dbus_proxy_method (Interface main_iface, Interface iface, Method m) {
     899           37 :                 string proxy_name = "%sproxy_%s".printf (get_ccode_lower_case_prefix (main_iface), m.name);
     900              : 
     901           37 :                 string dbus_iface_name = get_dbus_name (iface);
     902              : 
     903           37 :                 bool no_reply = is_dbus_no_reply (m);
     904              : 
     905           37 :                 var function = new CCodeFunction (proxy_name);
     906           37 :                 function.modifiers = CCodeModifiers.STATIC;
     907              : 
     908           37 :                 var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
     909              : 
     910           37 :                 generate_cparameters (m, cfile, cparam_map, function);
     911              : 
     912           37 :                 push_function (function);
     913              : 
     914           37 :                 generate_marshalling (m, no_reply ? CallType.NO_REPLY : CallType.SYNC, dbus_iface_name, get_dbus_name_for_member (m), get_dbus_timeout_for_member (m));
     915              : 
     916           37 :                 pop_function ();
     917              : 
     918           37 :                 cfile.add_function_declaration (function);
     919           37 :                 cfile.add_function (function);
     920              : 
     921           37 :                 return proxy_name;
     922              :         }
     923              : 
     924           13 :         string generate_async_dbus_proxy_method (Interface main_iface, Interface iface, Method m) {
     925           13 :                 string proxy_name = "%sproxy_%s_async".printf (get_ccode_lower_case_prefix (main_iface), m.name);
     926              : 
     927           13 :                 string dbus_iface_name = get_dbus_name (iface);
     928              : 
     929           13 :                 var function = new CCodeFunction (proxy_name, "void");
     930           13 :                 function.modifiers = CCodeModifiers.STATIC;
     931              : 
     932           13 :                 var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
     933              : 
     934           13 :                 cparam_map.set (get_param_pos (-1), new CCodeParameter ("_callback_", "GAsyncReadyCallback"));
     935           13 :                 cparam_map.set (get_param_pos (-0.9), new CCodeParameter ("_user_data_", "gpointer"));
     936              : 
     937           13 :                 generate_cparameters (m, cfile, cparam_map, function, null, null, null, 1);
     938              : 
     939           13 :                 push_function (function);
     940              : 
     941           13 :                 generate_marshalling (m, CallType.ASYNC, dbus_iface_name, get_dbus_name_for_member (m), get_dbus_timeout_for_member (m));
     942              : 
     943           13 :                 pop_function ();
     944              : 
     945           13 :                 cfile.add_function_declaration (function);
     946           13 :                 cfile.add_function (function);
     947              : 
     948           13 :                 return proxy_name;
     949              :         }
     950              : 
     951           13 :         string generate_finish_dbus_proxy_method (Interface main_iface, Interface iface, Method m) {
     952           13 :                 string proxy_name = "%sproxy_%s_finish".printf (get_ccode_lower_case_prefix (main_iface), m.name);
     953              : 
     954           13 :                 var function = new CCodeFunction (proxy_name);
     955           13 :                 function.modifiers = CCodeModifiers.STATIC;
     956              : 
     957           13 :                 var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
     958              : 
     959           13 :                 cparam_map.set (get_param_pos (get_ccode_async_result_pos (m)), new CCodeParameter ("_res_", "GAsyncResult*"));
     960              : 
     961           13 :                 generate_cparameters (m, cfile, cparam_map, function, null, null, null, 2);
     962              : 
     963           13 :                 push_function (function);
     964              : 
     965           13 :                 generate_marshalling (m, CallType.FINISH, null, null, -1);
     966              : 
     967           13 :                 pop_function ();
     968              : 
     969           13 :                 cfile.add_function_declaration (function);
     970           13 :                 cfile.add_function (function);
     971              : 
     972           13 :                 return proxy_name;
     973              :         }
     974              : 
     975            6 :         string generate_dbus_proxy_property_get (Interface main_iface, Interface iface, Property prop) {
     976            6 :                 string proxy_name = "%sdbus_proxy_get_%s".printf (get_ccode_lower_case_prefix (main_iface), prop.name);
     977              : 
     978            6 :                 string dbus_iface_name = get_dbus_name (iface);
     979              : 
     980            6 :                 var owned_type = prop.get_accessor.value_type.copy ();
     981            6 :                 owned_type.value_owned = true;
     982            6 :                 if (owned_type.is_disposable () && !prop.get_accessor.value_type.value_owned) {
     983            0 :                         Report.error (prop.get_accessor.value_type.source_reference, "Properties used in D-Bus clients require owned get accessor");
     984              :                 }
     985              : 
     986            6 :                 var array_type = prop.get_accessor.value_type as ArrayType;
     987              : 
     988            6 :                 var function = new CCodeFunction (proxy_name);
     989            6 :                 function.modifiers = CCodeModifiers.STATIC;
     990              : 
     991            6 :                 function.add_parameter (new CCodeParameter ("self", "%s*".printf (get_ccode_name (iface))));
     992              : 
     993            6 :                 if (prop.property_type.is_real_non_null_struct_type ()) {
     994            1 :                         function.add_parameter (new CCodeParameter ("result", "%s*".printf (get_ccode_name (prop.get_accessor.value_type))));
     995              :                 } else {
     996            6 :                         if (array_type != null) {
     997            1 :                                 var length_ctype = get_ccode_array_length_type (array_type) + "*";
     998            2 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
     999            1 :                                         function.add_parameter (new CCodeParameter ("result_length%d".printf (dim), length_ctype));
    1000              :                                 }
    1001              :                         }
    1002              : 
    1003            5 :                         function.return_type = get_ccode_name (prop.get_accessor.value_type);
    1004              :                 }
    1005              : 
    1006            6 :                 push_function (function);
    1007              : 
    1008            6 :                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_inner_reply"));
    1009              : 
    1010              :                 // first try cached value
    1011            6 :                 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_cached_property"));
    1012            6 :                 ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
    1013            6 :                 ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))));
    1014            6 :                 ccode.add_assignment (new CCodeIdentifier ("_inner_reply"), ccall);
    1015              : 
    1016              :                 // if not successful, retrieve value via D-Bus
    1017            6 :                 ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_inner_reply")));
    1018              : 
    1019            6 :                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
    1020            6 :                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
    1021            6 :                 ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
    1022              : 
    1023            6 :                 var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
    1024            6 :                 builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1025            6 :                 builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
    1026            6 :                 ccode.add_expression (builder_init);
    1027              : 
    1028              :                 // interface name
    1029            6 :                 write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
    1030              :                 // property name
    1031            6 :                 write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
    1032              : 
    1033            6 :                 var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
    1034            6 :                 builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1035            6 :                 ccode.add_assignment (new CCodeIdentifier ("_arguments"), builder_end);
    1036              : 
    1037            6 :                 ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
    1038            6 :                 ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
    1039            6 :                 ccall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties.Get\""));
    1040            6 :                 ccall.add_argument (new CCodeIdentifier ("_arguments"));
    1041            6 :                 ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
    1042            6 :                 ccall.add_argument (get_dbus_timeout (prop));
    1043            6 :                 ccall.add_argument (new CCodeConstant ("NULL"));
    1044            6 :                 ccall.add_argument (new CCodeConstant ("NULL"));
    1045              : 
    1046            6 :                 ccode.add_assignment (new CCodeIdentifier ("_reply"), ccall);
    1047              : 
    1048              :                 // return on error
    1049            6 :                 ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")));
    1050            6 :                 return_default_value (prop.property_type);
    1051            6 :                 ccode.close ();
    1052              : 
    1053            6 :                 var get_variant = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_get"));
    1054            6 :                 get_variant.add_argument (new CCodeIdentifier ("_reply"));
    1055            6 :                 get_variant.add_argument (new CCodeConstant ("\"(v)\""));
    1056            6 :                 get_variant.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_inner_reply")));
    1057            6 :                 ccode.add_expression (get_variant);
    1058              : 
    1059            6 :                 var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
    1060            6 :                 unref_reply.add_argument (new CCodeIdentifier ("_reply"));
    1061            6 :                 ccode.add_expression (unref_reply);
    1062              : 
    1063            6 :                 ccode.close ();
    1064              : 
    1065            7 :                 if (prop.property_type.is_real_non_null_struct_type ()) {
    1066            1 :                         var target = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result"));
    1067            1 :                         var result = deserialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_inner_reply"), target);
    1068            1 :                         ccode.add_assignment (target, result);
    1069              :                 } else {
    1070            5 :                         ccode.add_declaration (get_ccode_name (prop.get_accessor.value_type), new CCodeVariableDeclarator ("_result"));
    1071              : 
    1072            9 :                         if (get_dbus_signature (prop) != null) {
    1073              :                                 // raw GVariant
    1074            1 :                                 ccode.add_assignment (new CCodeIdentifier ("_result"), new CCodeIdentifier("_inner_reply"));
    1075              :                         } else {
    1076            5 :                                 if (array_type != null) {
    1077            1 :                                         var length_ctype = get_ccode_array_length_type (array_type);
    1078            2 :                                         for (int dim = 1; dim <= array_type.rank; dim++) {
    1079            1 :                                                 ccode.add_declaration (length_ctype, new CCodeVariableDeclarator ("_result_length%d".printf (dim), new CCodeConstant ("0")));
    1080              :                                         }
    1081              :                                 }
    1082              : 
    1083            4 :                                 var result = deserialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("_inner_reply"), new CCodeIdentifier ("_result"));
    1084            4 :                                 ccode.add_assignment (new CCodeIdentifier ("_result"), result);
    1085              : 
    1086            4 :                                 if (array_type != null) {
    1087            2 :                                         for (int dim = 1; dim <= array_type.rank; dim++) {
    1088              :                                                 // TODO check that parameter is not NULL (out parameters are optional)
    1089            1 :                                                 ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length%d".printf (dim))), new CCodeIdentifier ("_result_length%d".printf (dim)));
    1090              :                                         }
    1091              :                                 }
    1092              :                         }
    1093              :                 }
    1094              : 
    1095            6 :                 if (prop.property_type.is_real_non_null_struct_type () || get_dbus_signature (prop) == null) {
    1096            5 :                         unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
    1097            5 :                         unref_reply.add_argument (new CCodeIdentifier ("_inner_reply"));
    1098            5 :                         ccode.add_expression (unref_reply);
    1099              :                 }
    1100              : 
    1101            6 :                 if (prop.property_type.is_real_non_null_struct_type ()) {
    1102            1 :                         ccode.add_return ();
    1103              :                 } else {
    1104            5 :                         ccode.add_return (new CCodeIdentifier ("_result"));
    1105              :                 }
    1106              : 
    1107            6 :                 pop_function ();
    1108              : 
    1109            6 :                 cfile.add_function_declaration (function);
    1110            6 :                 cfile.add_function (function);
    1111              : 
    1112            6 :                 return proxy_name;
    1113              :         }
    1114              : 
    1115            6 :         string generate_dbus_proxy_property_set (Interface main_iface, Interface iface, Property prop) {
    1116            6 :                 string proxy_name = "%sdbus_proxy_set_%s".printf (get_ccode_lower_case_prefix (main_iface), prop.name);
    1117              : 
    1118            6 :                 string dbus_iface_name = get_dbus_name (iface);
    1119              : 
    1120            6 :                 var array_type = prop.set_accessor.value_type as ArrayType;
    1121              : 
    1122            6 :                 var function = new CCodeFunction (proxy_name);
    1123            6 :                 function.modifiers = CCodeModifiers.STATIC;
    1124              : 
    1125            6 :                 function.add_parameter (new CCodeParameter ("self", "%s*".printf (get_ccode_name (iface))));
    1126              : 
    1127            6 :                 if (prop.property_type.is_real_non_null_struct_type ()) {
    1128            1 :                         function.add_parameter (new CCodeParameter ("value", "%s*".printf (get_ccode_name (prop.set_accessor.value_type))));
    1129              :                 } else {
    1130            5 :                         function.add_parameter (new CCodeParameter ("value", get_ccode_name (prop.set_accessor.value_type)));
    1131              : 
    1132            6 :                         if (array_type != null) {
    1133            1 :                                 var length_ctype = get_ccode_array_length_type (array_type);
    1134            2 :                                 for (int dim = 1; dim <= array_type.rank; dim++) {
    1135            1 :                                         function.add_parameter (new CCodeParameter ("value_length%d".printf (dim), length_ctype));
    1136              :                                 }
    1137              :                         }
    1138              :                 }
    1139              : 
    1140            6 :                 push_function (function);
    1141              : 
    1142            6 :                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
    1143            6 :                 ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_reply"));
    1144              : 
    1145            6 :                 ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
    1146              : 
    1147            6 :                 var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
    1148            6 :                 builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1149            6 :                 builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
    1150            6 :                 ccode.add_expression (builder_init);
    1151              : 
    1152              :                 // interface name
    1153            6 :                 write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (dbus_iface_name)), null);
    1154              :                 // property name
    1155            6 :                 write_expression (string_type, new CCodeIdentifier ("_arguments_builder"), new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))), null);
    1156              : 
    1157              :                 // property value (as variant)
    1158            6 :                 var builder_open = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_open"));
    1159            6 :                 builder_open.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1160            6 :                 builder_open.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_VARIANT"));
    1161            6 :                 ccode.add_expression (builder_open);
    1162              : 
    1163            6 :                 if (prop.property_type.is_real_non_null_struct_type ()) {
    1164            1 :                         write_expression (prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("value")), prop);
    1165              :                 } else {
    1166            5 :                         write_expression (prop.set_accessor.value_type, new CCodeIdentifier ("_arguments_builder"), new CCodeIdentifier ("value"), prop);
    1167              :                 }
    1168              : 
    1169            6 :                 var builder_close = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_close"));
    1170            6 :                 builder_close.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1171            6 :                 ccode.add_expression (builder_close);
    1172              : 
    1173            6 :                 var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
    1174            6 :                 builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
    1175            6 :                 ccode.add_assignment (new CCodeIdentifier ("_arguments"), builder_end);
    1176              : 
    1177            6 :                 var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_call_sync"));
    1178            6 :                 ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"));
    1179            6 :                 ccall.add_argument (new CCodeConstant ("\"org.freedesktop.DBus.Properties.Set\""));
    1180            6 :                 ccall.add_argument (new CCodeIdentifier ("_arguments"));
    1181            6 :                 ccall.add_argument (new CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
    1182            6 :                 ccall.add_argument (get_dbus_timeout (prop));
    1183            6 :                 ccall.add_argument (new CCodeConstant ("NULL"));
    1184            6 :                 ccall.add_argument (new CCodeConstant ("NULL"));
    1185              : 
    1186            6 :                 ccode.add_assignment (new CCodeIdentifier ("_reply"), ccall);
    1187              : 
    1188              :                 // return on error
    1189            6 :                 ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("_reply")));
    1190            6 :                 ccode.add_return ();
    1191            6 :                 ccode.close ();
    1192              : 
    1193            6 :                 var unref_reply = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_unref"));
    1194            6 :                 unref_reply.add_argument (new CCodeIdentifier ("_reply"));
    1195            6 :                 ccode.add_expression (unref_reply);
    1196              : 
    1197            6 :                 pop_function ();
    1198              : 
    1199            6 :                 cfile.add_function_declaration (function);
    1200            6 :                 cfile.add_function (function);
    1201              : 
    1202            6 :                 return proxy_name;
    1203              :         }
    1204              : 
    1205           81 :         public override void register_dbus_info (CCodeBlock block, ObjectTypeSymbol sym) {
    1206           54 :                 if (!(sym is Interface)) {
    1207              :                         return;
    1208              :                 }
    1209              : 
    1210           27 :                 string dbus_iface_name = get_dbus_name (sym);
    1211           27 :                 if (dbus_iface_name == null) {
    1212            0 :                         return;
    1213              :                 }
    1214              : 
    1215           27 :                 var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
    1216           27 :                 quark.add_argument (new CCodeConstant ("\"vala-dbus-proxy-type\""));
    1217              : 
    1218           27 :                 var proxy_type = new CCodeIdentifier (get_ccode_lower_case_prefix (sym) + "proxy_get_type");
    1219              : 
    1220           27 :                 var set_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
    1221           27 :                 set_qdata.add_argument (new CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (sym, null))));
    1222           27 :                 set_qdata.add_argument (quark);
    1223           27 :                 set_qdata.add_argument (new CCodeCastExpression (proxy_type, "void*"));
    1224              : 
    1225           27 :                 block.add_statement (new CCodeExpressionStatement (set_qdata));
    1226              : 
    1227           27 :                 quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
    1228           27 :                 quark.add_argument (new CCodeConstant ("\"vala-dbus-interface-name\""));
    1229              : 
    1230           27 :                 set_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
    1231           27 :                 set_qdata.add_argument (new CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (sym, null))));
    1232           27 :                 set_qdata.add_argument (quark);
    1233           27 :                 set_qdata.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name)));
    1234              : 
    1235           27 :                 block.add_statement (new CCodeExpressionStatement (set_qdata));
    1236              : 
    1237              :                 // TODO Replaced by g_dbus_proxy_set_interface_info() call in *_init
    1238           27 :                 quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
    1239           27 :                 quark.add_argument (new CCodeConstant ("\"vala-dbus-interface-info\""));
    1240              : 
    1241           27 :                 set_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
    1242           27 :                 set_qdata.add_argument (new CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (sym, null))));
    1243           27 :                 set_qdata.add_argument (quark);
    1244           27 :                 set_qdata.add_argument (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_interface_info (sym)), "void*"));
    1245              : 
    1246           27 :                 block.add_statement (new CCodeExpressionStatement (set_qdata));
    1247              :         }
    1248              : }
        

Generated by: LCOV version 2.0-1