1 /* valagdbusclientmodule.vala
3 * Copyright (C) 2010-2011 Jürg Billeter
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.
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.
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
20 * Jürg Billeter <j@bitron.ch>
21 * Philip Van Hoof <pvanhoof@gnome.org>
24 public class Vala
.GDBusClientModule
: GDBusModule
{
32 public CCodeConstant
get_dbus_timeout (Symbol symbol
) {
35 var dbus
= symbol
.get_attribute ("DBus");
36 if (dbus
!= null && dbus
.has_argument ("timeout")) {
37 timeout
= dbus
.get_integer ("timeout");
38 } else if (symbol
.parent_symbol
!= null) {
39 return get_dbus_timeout (symbol
.parent_symbol
);
42 return new
CCodeConstant (timeout
.to_string ());
45 public override void generate_dynamic_method_wrapper (DynamicMethod method
) {
46 var dynamic_method
= (DynamicMethod
) method
;
48 var func
= new
CCodeFunction (method
.get_cname ());
49 func
.modifiers
= CCodeModifiers
.STATIC
;
51 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
53 generate_cparameters (method
, cfile
, cparam_map
, func
);
57 if (dynamic_method
.dynamic_type
.data_type
== dbus_proxy_type
) {
58 generate_marshalling (method
, CallType
.SYNC
, null, method
.name
);
60 Report
.error (method
.source_reference
, "dynamic methods are not supported for `%s'".printf (dynamic_method
.dynamic_type
.to_string ()));
65 cfile
.add_function_declaration (func
);
66 cfile
.add_function (func
);
69 void generate_proxy_interface_init (Interface main_iface
, Interface iface
) {
70 // also generate proxy for prerequisites
71 foreach (var prereq
in iface
.get_prerequisites ()) {
72 if (prereq
.data_type is Interface
) {
73 generate_proxy_interface_init (main_iface
, (Interface
) prereq
.data_type
);
77 string lower_cname
= main_iface
.get_lower_case_cprefix () + "proxy";
79 var proxy_iface_init
= new
CCodeFunction (lower_cname
+ "_" + iface
.get_lower_case_cprefix () + "interface_init", "void");
80 proxy_iface_init
.add_parameter (new
CCodeParameter ("iface", iface
.get_cname () + "Iface*"));
82 var iface_block
= new
CCodeBlock ();
84 foreach (Method m
in iface
.get_methods ()) {
89 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.vfunc_name
);
91 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_method (main_iface
, iface
, m
)))));
93 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_async_dbus_proxy_method (main_iface
, iface
, m
)))));
94 vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.get_finish_vfunc_name ());
95 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_finish_dbus_proxy_method (main_iface
, iface
, m
)))));
99 foreach (Property prop
in iface
.get_properties ()) {
100 if (!prop
.is_abstract
) {
104 if (prop
.get_accessor
!= null) {
105 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "get_" + prop
.name
);
106 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_get (main_iface
, iface
, prop
)))));
108 if (prop
.set_accessor
!= null) {
109 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "set_" + prop
.name
);
110 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_set (main_iface
, iface
, prop
)))));
114 proxy_iface_init
.modifiers
= CCodeModifiers
.STATIC
;
115 cfile
.add_function_declaration (proxy_iface_init
);
116 proxy_iface_init
.block
= iface_block
;
117 cfile
.add_function (proxy_iface_init
);
120 string implement_interface (CCodeFunctionCall define_type
, Interface main_iface
, Interface iface
) {
123 // also implement prerequisites
124 foreach (var prereq
in iface
.get_prerequisites ()) {
125 if (prereq
.data_type is Interface
) {
126 result
+= implement_interface (define_type
, main_iface
, (Interface
) prereq
.data_type
);
130 result
+= "G_IMPLEMENT_INTERFACE (%s, %sproxy_%sinterface_init) ".printf (
131 iface
.get_upper_case_cname ("TYPE_"),
132 main_iface
.get_lower_case_cprefix (),
133 iface
.get_lower_case_cprefix ());
137 public override void generate_interface_declaration (Interface iface
, CCodeFile decl_space
) {
138 base.generate_interface_declaration (iface
, decl_space
);
140 string dbus_iface_name
= get_dbus_name (iface
);
141 if (dbus_iface_name
== null) {
145 string get_type_name
= "%sproxy_get_type".printf (iface
.get_lower_case_cprefix ());
147 if (add_symbol_declaration (decl_space
, iface
, get_type_name
)) {
151 decl_space
.add_type_declaration (new
CCodeNewline ());
152 var macro
= "(%s ())".printf (get_type_name
);
153 decl_space
.add_type_declaration (new
CCodeMacroReplacement ("%s_PROXY".printf (iface
.get_type_id ()), macro
));
155 // declare proxy_get_type function
156 var proxy_get_type
= new
CCodeFunction (get_type_name
, "GType");
157 proxy_get_type
.attributes
= "G_GNUC_CONST";
158 decl_space
.add_function_declaration (proxy_get_type
);
161 public override void visit_interface (Interface iface
) {
162 base.visit_interface (iface
);
164 string dbus_iface_name
= get_dbus_name (iface
);
165 if (dbus_iface_name
== null) {
169 cfile
.add_include ("gio/gio.h");
171 // create proxy class
172 string cname
= iface
.get_cname () + "Proxy";
173 string lower_cname
= iface
.get_lower_case_cprefix () + "proxy";
175 cfile
.add_type_declaration (new
CCodeTypeDefinition ("GDBusProxy", new
CCodeVariableDeclarator (cname
)));
176 cfile
.add_type_declaration (new
CCodeTypeDefinition ("GDBusProxyClass", new
CCodeVariableDeclarator (cname
+ "Class")));
178 var define_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_DEFINE_TYPE_EXTENDED"));
179 define_type
.add_argument (new
CCodeIdentifier (cname
));
180 define_type
.add_argument (new
CCodeIdentifier (lower_cname
));
181 define_type
.add_argument (new
CCodeIdentifier ("G_TYPE_DBUS_PROXY"));
182 define_type
.add_argument (new
CCodeConstant ("0"));
183 define_type
.add_argument (new
CCodeIdentifier (implement_interface (define_type
, iface
, iface
)));
185 cfile
.add_type_member_definition (new
CCodeExpressionStatement (define_type
));
187 var proxy_class_init
= new
CCodeFunction (lower_cname
+ "_class_init", "void");
188 proxy_class_init
.add_parameter (new
CCodeParameter ("klass", cname
+ "Class*"));
189 proxy_class_init
.modifiers
= CCodeModifiers
.STATIC
;
190 proxy_class_init
.block
= new
CCodeBlock ();
191 var proxy_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_DBUS_PROXY_CLASS"));
192 proxy_class
.add_argument (new
CCodeIdentifier ("klass"));
193 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (proxy_class
, "g_signal"), new
CCodeIdentifier (lower_cname
+ "_g_signal"))));
194 cfile
.add_function (proxy_class_init
);
196 generate_signal_handler_function (iface
);
198 var proxy_instance_init
= new
CCodeFunction (lower_cname
+ "_init", "void");
199 proxy_instance_init
.add_parameter (new
CCodeParameter ("self", cname
+ "*"));
200 proxy_instance_init
.modifiers
= CCodeModifiers
.STATIC
;
201 proxy_instance_init
.block
= new
CCodeBlock ();
202 cfile
.add_function (proxy_instance_init
);
204 generate_proxy_interface_init (iface
, iface
);
207 public override void visit_method_call (MethodCall expr
) {
208 var mtype
= expr
.call
.value_type as MethodType
;
209 bool bus_get_proxy_async
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "g_bus_get_proxy");
210 bool bus_get_proxy_sync
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "g_bus_get_proxy_sync");
211 bool conn_get_proxy_async
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "g_dbus_connection_get_proxy");
212 bool conn_get_proxy_sync
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "g_dbus_connection_get_proxy_sync");
213 if (!bus_get_proxy_async
&& !bus_get_proxy_sync
&& !conn_get_proxy_async
&& !conn_get_proxy_sync
) {
214 base.visit_method_call (expr
);
218 var ma
= (MemberAccess
) expr
.call
;
219 var type_arg
= ma
.get_type_arguments ().get (0);
221 CCodeExpression proxy_type
;
222 CCodeExpression dbus_iface_name
;
224 var object_type
= type_arg as ObjectType
;
225 if (object_type
!= null) {
226 var iface
= (Interface
) object_type
.type_symbol
;
228 if (get_dbus_name (iface
) == null) {
229 Report
.error (expr
.source_reference
, "`%s' is not a D-Bus interface".printf (iface
.get_full_name ()));
233 proxy_type
= new
CCodeIdentifier ("%s_PROXY".printf (iface
.get_type_id ()));
234 dbus_iface_name
= new
CCodeConstant ("\"%s\"".printf (get_dbus_name (iface
)));
236 // use runtime type information for generic methods
238 var quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
239 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-proxy-type\""));
241 var get_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
242 get_qdata
.add_argument (get_type_id_expression (type_arg
));
243 get_qdata
.add_argument (quark
);
245 proxy_type
= new
CCodeFunctionCall (new
CCodeCastExpression (get_qdata
, "GType (*) (void)"));
247 quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
248 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-interface-name\""));
250 get_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
251 get_qdata
.add_argument (get_type_id_expression (type_arg
));
252 get_qdata
.add_argument (quark
);
254 dbus_iface_name
= get_qdata
;
257 var base_arg_index
= 0;
258 if (bus_get_proxy_async
|| bus_get_proxy_sync
)
261 var args
= expr
.get_argument_list ();
262 Expression name
= args
.get (base_arg_index
+ 0);
263 Expression object_path
= args
.get (base_arg_index
+ 1);
264 Expression flags
= args
.get (base_arg_index
+ 2);
265 Expression cancellable
= args
.get (base_arg_index
+ 3);
268 current_method_inner_error
= true;
270 CCodeFunctionCall ccall
;
271 if (bus_get_proxy_async
|| conn_get_proxy_async
) {
272 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_async_initable_new_async"));
274 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_initable_new"));
276 ccall
.add_argument (proxy_type
);
277 if (bus_get_proxy_async
|| conn_get_proxy_async
) {
279 ccall
.add_argument (new
CCodeConstant ("0"));
281 cancellable
.emit (this
);
282 ccall
.add_argument (get_cvalue (cancellable
));
283 if (bus_get_proxy_async
|| conn_get_proxy_async
) {
284 if (expr
.is_yield_expression
) {
286 ccall
.add_argument (new
CCodeIdentifier (generate_ready_function (current_method
)));
287 ccall
.add_argument (new
CCodeIdentifier ("data"));
290 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
292 ccall
.add_argument (new
CCodeConstant ("\"g-flags\""));
293 ccall
.add_argument (get_cvalue (flags
));
294 ccall
.add_argument (new
CCodeConstant ("\"g-name\""));
296 ccall
.add_argument (get_cvalue (name
));
297 if (bus_get_proxy_async
|| bus_get_proxy_sync
) {
298 Expression bus_type
= args
.get (0);
299 ccall
.add_argument (new
CCodeConstant ("\"g-bus-type\""));
300 bus_type
.emit (this
);
301 ccall
.add_argument (get_cvalue (bus_type
));
303 Expression connection
= ((MemberAccess
) expr
.call
).inner
;
304 ccall
.add_argument (new
CCodeConstant ("\"g-connection\""));
305 connection
.emit (this
);
306 ccall
.add_argument (get_cvalue (connection
));
308 ccall
.add_argument (new
CCodeConstant ("\"g-object-path\""));
309 object_path
.emit (this
);
310 ccall
.add_argument (get_cvalue (object_path
));
311 ccall
.add_argument (new
CCodeConstant ("\"g-interface-name\""));
312 ccall
.add_argument (dbus_iface_name
);
313 ccall
.add_argument (new
CCodeConstant ("NULL"));
315 if (bus_get_proxy_async
|| conn_get_proxy_async
) {
316 if (expr
.is_yield_expression
) {
317 int state
= next_coroutine_state
++;
319 ccode
.add_assignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("data"), "_state_"), new
CCodeConstant (state
.to_string ()));
320 ccode
.add_expression (ccall
);
321 ccode
.add_return (new
CCodeConstant ("FALSE"));
322 ccode
.add_label ("_state_%d".printf (state
));
324 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_async_initable_new_finish"));
325 ccall
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("data"), "_source_object_"));
326 // pass GAsyncResult stored in closure to finish function
327 ccall
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("data"), "_res_"));
328 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
332 var temp_var
= get_temp_variable (expr
.value_type
, expr
.value_type
.value_owned
);
333 var temp_ref
= get_variable_cexpression (temp_var
.name
);
335 emit_temp_var (temp_var
);
337 ccode
.add_assignment (temp_ref
, ccall
);
338 set_cvalue (expr
, temp_ref
);
341 string generate_dbus_signal_handler (Signal sig
, ObjectTypeSymbol sym
) {
342 string wrapper_name
= "_dbus_handle_%s_%s".printf (sym
.get_lower_case_cname (), sig
.get_cname ());
344 var function
= new
CCodeFunction (wrapper_name
);
345 function
.modifiers
= CCodeModifiers
.STATIC
;
346 function
.add_parameter (new
CCodeParameter ("self", sym
.get_cname () + "*"));
347 function
.add_parameter (new
CCodeParameter ("parameters", "GVariant*"));
349 push_function (function
);
351 ccode
.add_declaration ("GVariantIter", new
CCodeVariableDeclarator ("_arguments_iter"));
353 var iter_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_iter_init"));
354 iter_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_iter")));
355 iter_init
.add_argument (new
CCodeIdentifier ("parameters"));
356 ccode
.add_expression (iter_init
);
358 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_emit_by_name"));
359 ccall
.add_argument (new
CCodeIdentifier ("self"));
360 ccall
.add_argument (sig
.get_canonical_cconstant ());
362 foreach (Parameter param
in sig
.get_parameters ()) {
363 var owned_type
= param
.variable_type
.copy ();
364 owned_type
.value_owned
= true;
366 ccode
.add_declaration (owned_type
.get_cname (), new CCodeVariableDeclarator
.zero (param
.name
, default_value_for_type (param
.variable_type
, true)));
368 var st
= param
.variable_type
.data_type as Struct
;
369 if (st
!= null && !st
.is_simple_type ()) {
370 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
372 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
375 if (param
.variable_type is ArrayType
) {
376 var array_type
= (ArrayType
) param
.variable_type
;
378 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
379 string length_cname
= get_parameter_array_length_cname (param
, dim
);
381 ccode
.add_declaration ("int", new
CCodeVariableDeclarator (length_cname
, new
CCodeConstant ("0")));
382 ccall
.add_argument (new
CCodeIdentifier (length_cname
));
386 read_expression (param
.variable_type
, new
CCodeIdentifier ("_arguments_iter"), new
CCodeIdentifier (param
.name
), param
);
389 ccode
.add_expression (ccall
);
391 foreach (Parameter param
in sig
.get_parameters ()) {
392 var owned_type
= param
.variable_type
.copy ();
393 owned_type
.value_owned
= true;
395 if (requires_destroy (owned_type
)) {
396 // keep local alive (symbol_reference is weak)
397 var local
= new
LocalVariable (owned_type
, param
.name
);
398 ccode
.add_expression (destroy_variable (local
));
404 cfile
.add_function_declaration (function
);
405 cfile
.add_function (function
);
410 void generate_signal_handler_function (ObjectTypeSymbol sym
) {
411 var cfunc
= new
CCodeFunction (sym
.get_lower_case_cprefix () + "proxy_g_signal", "void");
412 cfunc
.add_parameter (new
CCodeParameter ("proxy", "GDBusProxy*"));
413 cfunc
.add_parameter (new
CCodeParameter ("sender_name", "const gchar*"));
414 cfunc
.add_parameter (new
CCodeParameter ("signal_name", "const gchar*"));
415 cfunc
.add_parameter (new
CCodeParameter ("parameters", "GVariant*"));
417 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
419 cfile
.add_function_declaration (cfunc
);
421 var block
= new
CCodeBlock ();
424 CCodeIfStatement clastif
= null;
426 foreach (Signal sig
in sym
.get_signals ()) {
427 if (sig
.access
!= SymbolAccessibility
.PUBLIC
) {
431 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
432 ccheck
.add_argument (new
CCodeIdentifier ("signal_name"));
433 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig
))));
435 var callblock
= new
CCodeBlock ();
437 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_dbus_signal_handler (sig
, sym
)));
438 ccall
.add_argument (new
CCodeIdentifier ("proxy"));
439 ccall
.add_argument (new
CCodeIdentifier ("parameters"));
441 callblock
.add_statement (new
CCodeExpressionStatement (ccall
));
443 var cif
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, ccheck
, new
CCodeConstant ("0")), callblock
);
444 if (clastif
== null) {
445 block
.add_statement (cif
);
447 clastif
.false_statement
= cif
;
453 cfile
.add_function (cfunc
);
456 void generate_marshalling (Method m
, CallType call_type
, string? iface_name
, string? method_name
) {
457 var gdbusproxy
= new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GDBusProxy *");
459 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_connection"));
460 connection
.add_argument (gdbusproxy
);
462 bool uses_fd
= dbus_method_uses_file_descriptor (m
);
464 cfile
.add_include ("gio/gunixfdlist.h");
467 if (call_type
!= CallType
.FINISH
) {
468 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_name"));
469 destination
.add_argument (gdbusproxy
);
471 var interface_name
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_interface_name"));
472 interface_name
.add_argument (gdbusproxy
);
474 var object_path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_object_path"));
475 object_path
.add_argument (gdbusproxy
);
477 var timeout
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_default_timeout"));
478 timeout
.add_argument (gdbusproxy
);
481 foreach (var error_type
in m
.get_error_types ()) {
482 var errtype
= (ErrorType
) error_type
;
483 if (errtype
.error_domain
!= null) {
484 ccode
.add_expression (new
CCodeIdentifier (errtype
.error_domain
.get_upper_case_cname ()));
488 // build D-Bus message
490 ccode
.add_declaration ("GDBusMessage", new
CCodeVariableDeclarator ("*_message"));
492 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_new_method_call"));
493 ccall
.add_argument (destination
);
494 ccall
.add_argument (object_path
);
495 if (iface_name
!= null) {
496 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (iface_name
)));
498 ccall
.add_argument (interface_name
);
500 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (method_name
)));
501 ccode
.add_assignment (new
CCodeIdentifier ("_message"), ccall
);
503 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_arguments"));
504 ccode
.add_declaration ("GVariantBuilder", new
CCodeVariableDeclarator ("_arguments_builder"));
506 var builder_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_init"));
507 builder_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
508 builder_init
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
509 ccode
.add_expression (builder_init
);
512 ccode
.add_declaration ("GUnixFDList", new
CCodeVariableDeclarator ("*_fd_list"));
513 ccode
.add_assignment (new
CCodeIdentifier ("_fd_list"), new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_fd_list_new")));
516 CCodeExpression cancellable
= new
CCodeConstant ("NULL");
518 foreach (Parameter param
in m
.get_parameters ()) {
519 if (param
.direction
== ParameterDirection
.IN
) {
520 CCodeExpression expr
= new
CCodeIdentifier (param
.name
);
521 if (param
.variable_type
.is_real_struct_type ()) {
522 expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, expr
);
525 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.Cancellable") {
530 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.BusName") {
531 // ignore BusName sender parameters
535 send_dbus_value (param
.variable_type
, new
CCodeIdentifier ("_arguments_builder"), expr
, param
);
539 var builder_end
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_end"));
540 builder_end
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
541 ccode
.add_assignment (new
CCodeIdentifier ("_arguments"), builder_end
);
543 var set_body
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_set_body"));
544 set_body
.add_argument (new
CCodeIdentifier ("_message"));
545 set_body
.add_argument (new
CCodeIdentifier ("_arguments"));
546 ccode
.add_expression (set_body
);
549 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
550 ccall
.add_argument (new
CCodeIdentifier ("_message"));
551 ccall
.add_argument (new
CCodeIdentifier ("_fd_list"));
552 ccode
.add_expression (ccall
);
554 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
555 ccall
.add_argument (new
CCodeIdentifier ("_fd_list"));
556 ccode
.add_expression (ccall
);
559 // send D-Bus message
561 if (call_type
== CallType
.SYNC
) {
562 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_send_message_with_reply_sync"));
563 ccall
.add_argument (connection
);
564 ccall
.add_argument (new
CCodeIdentifier ("_message"));
565 ccall
.add_argument (new
CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
566 ccall
.add_argument (timeout
);
567 ccall
.add_argument (new
CCodeConstant ("NULL"));
568 ccall
.add_argument (cancellable
);
569 ccall
.add_argument (new
CCodeIdentifier ("error"));
570 ccode
.add_assignment (new
CCodeIdentifier ("_reply_message"), ccall
);
571 } else if (call_type
== CallType
.NO_REPLY
) {
572 var set_flags
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_set_flags"));
573 set_flags
.add_argument (new
CCodeIdentifier ("_message"));
574 set_flags
.add_argument (new
CCodeConstant ("G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED"));
575 ccode
.add_expression (set_flags
);
577 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_send_message"));
578 ccall
.add_argument (connection
);
579 ccall
.add_argument (new
CCodeIdentifier ("_message"));
580 ccall
.add_argument (new
CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
581 ccall
.add_argument (new
CCodeConstant ("NULL"));
582 ccall
.add_argument (new
CCodeIdentifier ("error"));
583 ccode
.add_expression (ccall
);
584 } else if (call_type
== CallType
.ASYNC
) {
585 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_send_message_with_reply"));
586 ccall
.add_argument (connection
);
587 ccall
.add_argument (new
CCodeIdentifier ("_message"));
588 ccall
.add_argument (new
CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
589 ccall
.add_argument (timeout
);
590 ccall
.add_argument (new
CCodeConstant ("NULL"));
591 ccall
.add_argument (cancellable
);
593 // use wrapper as source_object wouldn't be correct otherwise
594 ccall
.add_argument (new
CCodeIdentifier (generate_async_callback_wrapper ()));
595 var res_wrapper
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_new"));
596 res_wrapper
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GObject *"));
597 res_wrapper
.add_argument (new
CCodeIdentifier ("_callback_"));
598 res_wrapper
.add_argument (new
CCodeIdentifier ("_user_data_"));
599 res_wrapper
.add_argument (new
CCodeConstant ("NULL"));
600 ccall
.add_argument (res_wrapper
);
602 ccode
.add_expression (ccall
);
605 // free D-Bus message
607 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
608 ccall
.add_argument (new
CCodeIdentifier ("_message"));
609 ccode
.add_expression (ccall
);
611 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_send_message_with_reply_finish"));
612 ccall
.add_argument (connection
);
614 // unwrap async result
615 var inner_res
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_get_op_res_gpointer"));
616 inner_res
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("_res_"), "GSimpleAsyncResult *"));
617 ccall
.add_argument (inner_res
);
619 ccall
.add_argument (new
CCodeConstant ("error"));
620 ccode
.add_assignment (new
CCodeIdentifier ("_reply_message"), ccall
);
623 if (call_type
== CallType
.SYNC
|| call_type
== CallType
.FINISH
) {
624 ccode
.add_declaration ("GDBusMessage", new
CCodeVariableDeclarator ("*_reply_message"));
626 var unref_reply
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
627 unref_reply
.add_argument (new
CCodeIdentifier ("_reply_message"));
629 // return on io error
630 var reply_is_null
= new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("_reply_message"));
631 ccode
.open_if (reply_is_null
);
632 return_default_value (m
.return_type
);
635 // return on remote error
636 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_to_gerror"));
637 ccall
.add_argument (new
CCodeIdentifier ("_reply_message"));
638 ccall
.add_argument (new
CCodeIdentifier ("error"));
639 ccode
.open_if (ccall
);
640 ccode
.add_expression (unref_reply
);
641 return_default_value (m
.return_type
);
644 bool has_result
= !(m
.return_type is VoidType
);
647 ccode
.add_declaration ("gint", new CCodeVariableDeclarator
.zero ("_fd_index", new
CCodeConstant ("0")));
650 foreach (Parameter param
in m
.get_parameters ()) {
651 if (param
.direction
== ParameterDirection
.OUT
) {
657 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_reply"));
658 ccode
.add_declaration ("GVariantIter", new
CCodeVariableDeclarator ("_reply_iter"));
660 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_get_body"));
661 ccall
.add_argument (new
CCodeIdentifier ("_reply_message"));
662 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), ccall
);
664 var iter_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_iter_init"));
665 iter_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_reply_iter")));
666 iter_init
.add_argument (new
CCodeIdentifier ("_reply"));
667 ccode
.add_expression (iter_init
);
669 foreach (Parameter param
in m
.get_parameters ()) {
670 if (param
.direction
== ParameterDirection
.OUT
) {
671 ccode
.add_declaration (param
.variable_type
.get_cname (), new
CCodeVariableDeclarator ("_" + param
.name
));
673 var array_type
= param
.variable_type as ArrayType
;
675 if (array_type
!= null) {
676 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
677 ccode
.add_declaration ("int", new
CCodeVariableDeclarator ("_%s_length%d".printf (param
.name
, dim
), new
CCodeConstant ("0")));
681 var target
= new
CCodeIdentifier ("_" + param
.name
);
683 receive_dbus_value (param
.variable_type
, new
CCodeIdentifier ("_reply_message"), new
CCodeIdentifier ("_reply_iter"), target
, param
, new
CCodeIdentifier ("error"), out may_fail
);
685 // TODO check that parameter is not NULL (out parameters are optional)
686 // free value if parameter is NULL
687 ccode
.add_assignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier (param
.name
)), target
);
689 if (array_type
!= null) {
690 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
691 // TODO check that parameter is not NULL (out parameters are optional)
692 ccode
.add_assignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("%s_length%d".printf (param
.name
, dim
))), new
CCodeIdentifier ("_%s_length%d".printf (param
.name
, dim
)));
697 ccode
.open_if (new
CCodeBinaryExpression (CCodeBinaryOperator
.AND
, new
CCodeIdentifier ("error"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error"))));
698 ccode
.add_expression (unref_reply
);
699 return_default_value (m
.return_type
);
705 if (!(m
.return_type is VoidType
)) {
706 if (m
.return_type
.is_real_non_null_struct_type ()) {
707 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
708 receive_dbus_value (m
.return_type
, new
CCodeIdentifier ("_reply_message"), new
CCodeIdentifier ("_reply_iter"), target
, m
);
710 ccode
.add_declaration (m
.return_type
.get_cname (), new
CCodeVariableDeclarator ("_result"));
712 var array_type
= m
.return_type as ArrayType
;
714 if (array_type
!= null) {
715 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
716 ccode
.add_declaration ("int", new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
721 receive_dbus_value (m
.return_type
, new
CCodeIdentifier ("_reply_message"), new
CCodeIdentifier ("_reply_iter"), new
CCodeIdentifier ("_result"), m
, new
CCodeIdentifier ("error"), out may_fail
);
723 if (array_type
!= null) {
724 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
725 // TODO check that parameter is not NULL (out parameters are optional)
726 ccode
.add_assignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length%d".printf (dim
))), new
CCodeIdentifier ("_result_length%d".printf (dim
)));
731 ccode
.open_if (new
CCodeBinaryExpression (CCodeBinaryOperator
.AND
, new
CCodeIdentifier ("error"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error"))));
732 ccode
.add_expression (unref_reply
);
733 return_default_value (m
.return_type
);
740 ccode
.add_expression (unref_reply
);
742 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
743 ccode
.add_return (new
CCodeIdentifier ("_result"));
748 string generate_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
749 string proxy_name
= "%sproxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
751 string dbus_iface_name
= get_dbus_name (iface
);
753 bool no_reply
= is_dbus_no_reply (m
);
755 var function
= new
CCodeFunction (proxy_name
);
756 function
.modifiers
= CCodeModifiers
.STATIC
;
758 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
760 generate_cparameters (m
, cfile
, cparam_map
, function
);
762 push_function (function
);
764 generate_marshalling (m
, no_reply ? CallType
.NO_REPLY
: CallType
.SYNC
, dbus_iface_name
, get_dbus_name_for_member (m
));
768 cfile
.add_function_declaration (function
);
769 cfile
.add_function (function
);
774 string generate_async_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
775 string proxy_name
= "%sproxy_%s_async".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
777 string dbus_iface_name
= get_dbus_name (iface
);
779 var function
= new
CCodeFunction (proxy_name
, "void");
780 function
.modifiers
= CCodeModifiers
.STATIC
;
782 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
784 cparam_map
.set (get_param_pos (-1), new
CCodeParameter ("_callback_", "GAsyncReadyCallback"));
785 cparam_map
.set (get_param_pos (-0.9), new
CCodeParameter ("_user_data_", "gpointer"));
787 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 1);
789 push_function (function
);
791 generate_marshalling (m
, CallType
.ASYNC
, dbus_iface_name
, get_dbus_name_for_member (m
));
795 cfile
.add_function_declaration (function
);
796 cfile
.add_function (function
);
801 string generate_finish_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
802 string proxy_name
= "%sproxy_%s_finish".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
804 var function
= new
CCodeFunction (proxy_name
);
805 function
.modifiers
= CCodeModifiers
.STATIC
;
807 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
809 cparam_map
.set (get_param_pos (0.1), new
CCodeParameter ("_res_", "GAsyncResult*"));
811 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 2);
813 push_function (function
);
815 generate_marshalling (m
, CallType
.FINISH
, null, null);
819 cfile
.add_function_declaration (function
);
820 cfile
.add_function (function
);
825 string generate_dbus_proxy_property_get (Interface main_iface
, Interface iface
, Property prop
) {
826 string proxy_name
= "%sdbus_proxy_get_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
828 string dbus_iface_name
= get_dbus_name (iface
);
830 var owned_type
= prop
.get_accessor
.value_type
.copy ();
831 owned_type
.value_owned
= true;
832 if (owned_type
.is_disposable () && !prop
.get_accessor
.value_type
.value_owned
) {
833 Report
.error (prop
.get_accessor
.value_type
.source_reference
, "Properties used in D-Bus clients require owned get accessor");
836 var array_type
= prop
.get_accessor
.value_type as ArrayType
;
838 var function
= new
CCodeFunction (proxy_name
);
839 function
.modifiers
= CCodeModifiers
.STATIC
;
841 function
.add_parameter (new
CCodeParameter ("self", "%s*".printf (iface
.get_cname ())));
843 if (prop
.property_type
.is_real_non_null_struct_type ()) {
844 function
.add_parameter (new
CCodeParameter ("result", "%s*".printf (prop
.get_accessor
.value_type
.get_cname ())));
846 if (array_type
!= null) {
847 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
848 function
.add_parameter (new
CCodeParameter ("result_length%d".printf (dim
), "int*"));
852 function
.return_type
= prop
.get_accessor
.value_type
.get_cname ();
855 push_function (function
);
857 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_inner_reply"));
859 // first try cached value
860 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_get_cached_property"));
861 ccall
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GDBusProxy *"));
862 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
863 ccode
.add_assignment (new
CCodeIdentifier ("_inner_reply"), ccall
);
865 // if not successful, retrieve value via D-Bus
866 ccode
.open_if (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("_inner_reply")));
868 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_arguments"));
869 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_reply"));
870 ccode
.add_declaration ("GVariantBuilder", new
CCodeVariableDeclarator ("_arguments_builder"));
872 var builder_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_init"));
873 builder_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
874 builder_init
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
875 ccode
.add_expression (builder_init
);
878 write_expression (string_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)), null);
880 write_expression (string_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))), null);
882 var builder_end
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_end"));
883 builder_end
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
884 ccode
.add_assignment (new
CCodeIdentifier ("_arguments"), builder_end
);
886 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_call_sync"));
887 ccall
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GDBusProxy *"));
888 ccall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties.Get\""));
889 ccall
.add_argument (new
CCodeIdentifier ("_arguments"));
890 ccall
.add_argument (new
CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
891 ccall
.add_argument (get_dbus_timeout (prop
));
892 ccall
.add_argument (new
CCodeConstant ("NULL"));
893 ccall
.add_argument (new
CCodeConstant ("NULL"));
895 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), ccall
);
898 ccode
.open_if (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("_reply")));
899 return_default_value (prop
.property_type
);
902 var get_variant
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_get"));
903 get_variant
.add_argument (new
CCodeIdentifier ("_reply"));
904 get_variant
.add_argument (new
CCodeConstant ("\"(v)\""));
905 get_variant
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_inner_reply")));
906 ccode
.add_expression (get_variant
);
908 var unref_reply
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_unref"));
909 unref_reply
.add_argument (new
CCodeIdentifier ("_reply"));
910 ccode
.add_expression (unref_reply
);
914 if (prop
.property_type
.is_real_non_null_struct_type ()) {
915 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
916 var result
= deserialize_expression (prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_inner_reply"), target
);
917 ccode
.add_assignment (target
, result
);
919 ccode
.add_declaration (prop
.get_accessor
.value_type
.get_cname (), new
CCodeVariableDeclarator ("_result"));
921 if (array_type
!= null) {
922 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
923 ccode
.add_declaration ("int", new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
927 var result
= deserialize_expression (prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_inner_reply"), new
CCodeIdentifier ("_result"));
928 ccode
.add_assignment (new
CCodeIdentifier ("_result"), result
);
930 if (array_type
!= null) {
931 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
932 // TODO check that parameter is not NULL (out parameters are optional)
933 ccode
.add_assignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length%d".printf (dim
))), new
CCodeIdentifier ("_result_length%d".printf (dim
)));
938 unref_reply
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_unref"));
939 unref_reply
.add_argument (new
CCodeIdentifier ("_inner_reply"));
940 ccode
.add_expression (unref_reply
);
942 if (prop
.property_type
.is_real_non_null_struct_type ()) {
945 ccode
.add_return (new
CCodeIdentifier ("_result"));
950 cfile
.add_function_declaration (function
);
951 cfile
.add_function (function
);
956 string generate_dbus_proxy_property_set (Interface main_iface
, Interface iface
, Property prop
) {
957 string proxy_name
= "%sdbus_proxy_set_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
959 string dbus_iface_name
= get_dbus_name (iface
);
961 var array_type
= prop
.set_accessor
.value_type as ArrayType
;
963 var function
= new
CCodeFunction (proxy_name
);
964 function
.modifiers
= CCodeModifiers
.STATIC
;
966 function
.add_parameter (new
CCodeParameter ("self", "%s*".printf (iface
.get_cname ())));
968 if (prop
.property_type
.is_real_non_null_struct_type ()) {
969 function
.add_parameter (new
CCodeParameter ("value", "%s*".printf (prop
.set_accessor
.value_type
.get_cname ())));
971 function
.add_parameter (new
CCodeParameter ("value", prop
.set_accessor
.value_type
.get_cname ()));
973 if (array_type
!= null) {
974 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
975 function
.add_parameter (new
CCodeParameter ("value_length%d".printf (dim
), "int"));
980 push_function (function
);
982 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_arguments"));
983 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_reply"));
985 ccode
.add_declaration ("GVariantBuilder", new
CCodeVariableDeclarator ("_arguments_builder"));
987 var builder_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_init"));
988 builder_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
989 builder_init
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
990 ccode
.add_expression (builder_init
);
993 write_expression (string_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)), null);
995 write_expression (string_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))), null);
997 // property value (as variant)
998 var builder_open
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_open"));
999 builder_open
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
1000 builder_open
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_VARIANT"));
1001 ccode
.add_expression (builder_open
);
1003 if (prop
.property_type
.is_real_non_null_struct_type ()) {
1004 write_expression (prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("value")), prop
);
1006 write_expression (prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_arguments_builder"), new
CCodeIdentifier ("value"), prop
);
1009 var builder_close
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_close"));
1010 builder_close
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
1011 ccode
.add_expression (builder_close
);
1013 var builder_end
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_end"));
1014 builder_end
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
1015 ccode
.add_assignment (new
CCodeIdentifier ("_arguments"), builder_end
);
1017 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_proxy_call_sync"));
1018 ccall
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "GDBusProxy *"));
1019 ccall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties.Set\""));
1020 ccall
.add_argument (new
CCodeIdentifier ("_arguments"));
1021 ccall
.add_argument (new
CCodeConstant ("G_DBUS_CALL_FLAGS_NONE"));
1022 ccall
.add_argument (get_dbus_timeout (prop
));
1023 ccall
.add_argument (new
CCodeConstant ("NULL"));
1024 ccall
.add_argument (new
CCodeConstant ("NULL"));
1026 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), ccall
);
1029 ccode
.open_if (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("_reply")));
1030 ccode
.add_return ();
1033 var unref_reply
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_unref"));
1034 unref_reply
.add_argument (new
CCodeIdentifier ("_reply"));
1035 ccode
.add_expression (unref_reply
);
1039 cfile
.add_function_declaration (function
);
1040 cfile
.add_function (function
);
1045 public override void register_dbus_info (CCodeBlock block
, ObjectTypeSymbol sym
) {
1046 if (!(sym is Interface
)) {
1050 string dbus_iface_name
= get_dbus_name (sym
);
1051 if (dbus_iface_name
== null) {
1055 var quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
1056 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-proxy-type\""));
1058 var proxy_type
= new
CCodeIdentifier (sym
.get_lower_case_cprefix () + "proxy_get_type");
1060 var set_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_set_qdata"));
1061 set_qdata
.add_argument (new
CCodeIdentifier ("%s_type_id".printf (sym
.get_lower_case_cname (null))));
1062 set_qdata
.add_argument (quark
);
1063 set_qdata
.add_argument (new
CCodeCastExpression (proxy_type
, "void*"));
1065 block
.add_statement (new
CCodeExpressionStatement (set_qdata
));
1067 quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
1068 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-interface-name\""));
1070 set_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_set_qdata"));
1071 set_qdata
.add_argument (new
CCodeIdentifier ("%s_type_id".printf (sym
.get_lower_case_cname (null))));
1072 set_qdata
.add_argument (quark
);
1073 set_qdata
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1075 block
.add_statement (new
CCodeExpressionStatement (set_qdata
));