1 /* valadbusclientmodule.vala
3 * Copyright (C) 2007-2010 Jürg Billeter
4 * Copyright (C) 2008 Philip Van Hoof
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * Jürg Billeter <j@bitron.ch>
22 * Philip Van Hoof <pvanhoof@gnome.org>
28 * The link between a dynamic method and generated code.
30 public class Vala
.DBusClientModule
: DBusModule
{
31 int dynamic_property_id
;
33 public DBusClientModule (CCodeGenerator codegen
, CCodeModule? next
) {
37 string get_dynamic_dbus_name (string vala_name
) {
38 // TODO switch default to no transformation as soon as we have static D-Bus client support
39 // keep transformation by default for static D-Bus client and server support
40 if (context
.dbus_transformation
) {
41 return Symbol
.lower_case_to_camel_case (vala_name
);
47 public CCodeConstant
get_dbus_timeout (Symbol symbol
) {
50 var dbus
= symbol
.get_attribute ("DBus");
51 if (dbus
!= null && dbus
.has_argument ("timeout")) {
52 timeout
= dbus
.get_integer ("timeout");
53 } else if (symbol
.parent_symbol
!= null) {
54 return get_dbus_timeout (symbol
.parent_symbol
);
57 return new
CCodeConstant (timeout
.to_string ());
60 bool has_dbus_error (List
<DataType
> error_types
) {
61 foreach (DataType error_type
in error_types
) {
62 if (((ErrorType
) error_type
).error_domain
.get_full_name () == "DBus.Error") {
69 public override void generate_dynamic_method_wrapper (DynamicMethod method
) {
70 var dynamic_method
= (DynamicMethod
) method
;
72 var func
= new
CCodeFunction (method
.get_cname ());
73 func
.modifiers
= CCodeModifiers
.STATIC
;
75 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
77 generate_cparameters (method
, source_declarations
, cparam_map
, func
);
79 var block
= new
CCodeBlock ();
80 if (dynamic_method
.dynamic_type
.data_type
== dbus_object_type
) {
81 generate_dbus_method_wrapper (method
, block
);
83 Report
.error (method
.source_reference
, "dynamic methods are not supported for `%s'".printf (dynamic_method
.dynamic_type
.to_string ()));
86 // append to C source file
87 source_declarations
.add_type_member_declaration (func
.copy ());
90 source_type_member_definition
.append (func
);
93 void generate_dbus_method_wrapper (Method method
, CCodeBlock block
) {
94 var dynamic_method
= (DynamicMethod
) method
;
96 var expr
= dynamic_method
.invocation
;
98 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_begin_call"));
100 ccall
.add_argument (new
CCodeIdentifier ("self"));
102 bool found_out
= false;
103 Expression
callback = null;
104 int callback_index
= -1;
106 foreach (Expression arg
in expr
.get_argument_list ()) {
107 if (arg
.symbol_reference is Method
) {
109 if (callback != null) {
110 Report
.error (expr
.source_reference
, "only one reply callback may be specified in invocation of DBus method");
113 } else if (found_out
) {
114 Report
.error (expr
.source_reference
, "out argument and reply callback conflict in invocation of DBus method");
119 callback_index
= arg_index
;
120 } else if (arg is UnaryExpression
&& ((UnaryExpression
) arg
).operator
== UnaryOperator
.OUT
) {
122 if (callback != null) {
123 Report
.error (expr
.source_reference
, "out argument and reply callback conflict in invocation of DBus method");
130 if (callback != null || found_out
) {
131 Report
.error (expr
.source_reference
, "in argument must not follow out argument or reply callback in invocation of DBus method");
139 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (method
.name
))));
141 if (callback != null) {
142 var reply_method
= (Method
) callback.symbol_reference
;
144 var cb_fun
= new
CCodeFunction ("_%s_cb".printf (reply_method
.get_cname ()), "void");
145 cb_fun
.modifiers
= CCodeModifiers
.STATIC
;
146 cb_fun
.add_parameter (new
CCodeFormalParameter ("proxy", "DBusGProxy*"));
147 cb_fun
.add_parameter (new
CCodeFormalParameter ("call", "DBusGProxyCall*"));
148 cb_fun
.add_parameter (new
CCodeFormalParameter ("user_data", "void*"));
149 cb_fun
.block
= new
CCodeBlock ();
150 var cerrdecl
= new
CCodeDeclaration ("GError*");
151 cerrdecl
.add_declarator (new
CCodeVariableDeclarator ("error", new
CCodeConstant ("NULL")));
152 cb_fun
.block
.add_statement (cerrdecl
);
153 var cend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_end_call"));
154 cend_call
.add_argument (new
CCodeIdentifier ("proxy"));
155 cend_call
.add_argument (new
CCodeIdentifier ("call"));
156 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("error")));
157 var creply_call
= new
CCodeFunctionCall ((CCodeExpression
) callback.ccodenode
);
158 if (reply_method
.binding
!= MemberBinding
.STATIC
) {
159 creply_call
.add_argument (new
CCodeIdentifier ("user_data"));
161 int param_count
= reply_method
.get_parameters ().size
;
163 foreach (FormalParameter param
in reply_method
.get_parameters ()) {
164 if ((++i
) == param_count
) {
165 if (!(param
.parameter_type is ErrorType
)) {
166 Report
.error (null, "DBus reply callbacks must end with GLib.Error argument");
172 if (param
.parameter_type is ArrayType
&& ((ArrayType
) param
.parameter_type
).element_type
.data_type
!= string_type
.data_type
) {
173 var array_type
= (ArrayType
) param
.parameter_type
;
174 CCodeDeclaration cdecl
;
175 if (dbus_use_ptr_array (array_type
)) {
176 cdecl
= new
CCodeDeclaration ("GPtrArray*");
178 cdecl
= new
CCodeDeclaration ("GArray*");
180 cdecl
.add_declarator (new
CCodeVariableDeclarator (param
.name
));
181 cb_fun
.block
.add_statement (cdecl
);
182 cend_call
.add_argument (get_dbus_g_type (array_type
));
183 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
184 creply_call
.add_argument (new
CCodeCastExpression (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), dbus_use_ptr_array (array_type
) ?
"pdata" : "data"), array_type
.get_cname ()));
185 creply_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), "len"));
187 var cdecl
= new
CCodeDeclaration (param
.parameter_type
.get_cname ());
188 cdecl
.add_declarator (new
CCodeVariableDeclarator (param
.name
));
189 cb_fun
.block
.add_statement (cdecl
);
190 cend_call
.add_argument (get_dbus_g_type (param
.parameter_type
));
191 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
192 creply_call
.add_argument (new
CCodeIdentifier (param
.name
));
194 if (param
.parameter_type is ArrayType
&& ((ArrayType
) param
.parameter_type
).element_type
.data_type
== string_type
.data_type
) {
195 var cstrvlen
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strv_length"));
196 cstrvlen
.add_argument (new
CCodeIdentifier (param
.name
));
197 creply_call
.add_argument (cstrvlen
);
202 cend_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
203 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (cend_call
));
204 creply_call
.add_argument (new
CCodeIdentifier ("error"));
205 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (creply_call
));
207 CCodeExpression target
= new
CCodeConstant ("param%d_target".printf (callback_index
));
208 var ma
= (MemberAccess
) callback;
209 if (reply_method
.binding
!= MemberBinding
.STATIC
&& ma
.inner
.value_type
.data_type
!= null && ma
.inner
.value_type
.data_type
.is_reference_counting ()) {
210 // unref user_data after creply_call
211 var unref_call
= new
CCodeFunctionCall (get_destroy_func_expression (ma
.inner
.value_type
));
212 unref_call
.add_argument (new
CCodeIdentifier ("user_data"));
213 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (unref_call
));
215 // ref target for ccall
216 var ref_call
= new
CCodeFunctionCall (get_dup_func_expression (ma
.inner
.value_type
, callback.source_reference
));
217 ref_call
.add_argument (target
);
221 if (!source_declarations
.add_declaration (cb_fun
.name
)) {
222 // avoid duplicate function definition
223 source_type_member_definition
.append (cb_fun
);
226 ccall
.add_argument (new
CCodeIdentifier (cb_fun
.name
));
227 ccall
.add_argument (target
);
228 ccall
.add_argument (new
CCodeConstant ("NULL"));
230 ccall
.call
= new
CCodeIdentifier ("dbus_g_proxy_call");
232 ccall
.add_argument (new
CCodeIdentifier ("error"));
235 foreach (FormalParameter param
in method
.get_parameters ()) {
236 if (param
.parameter_type is MethodType
237 || param
.parameter_type is DelegateType
) {
238 // callback parameter
242 if (param
.direction
!= ParameterDirection
.IN
) {
246 var array_type
= param
.parameter_type as ArrayType
;
247 if (array_type
!= null) {
249 if (array_type
.element_type
.data_type
!= string_type
.data_type
) {
250 // non-string arrays (use GArray)
251 ccall
.add_argument (get_dbus_g_type (array_type
));
253 var sizeof_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
254 sizeof_call
.add_argument (new
CCodeIdentifier (array_type
.element_type
.get_cname ()));
256 CCodeDeclaration cdecl
;
257 CCodeFunctionCall array_construct
;
258 if (dbus_use_ptr_array (array_type
)) {
259 cdecl
= new
CCodeDeclaration ("GPtrArray*");
261 array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_ptr_array_sized_new"));
262 array_construct
.add_argument (new
CCodeIdentifier (head
.get_array_length_cname (param
.name
, 1)));
264 cdecl
= new
CCodeDeclaration ("GArray*");
266 array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_array_new"));
267 array_construct
.add_argument (new
CCodeConstant ("TRUE"));
268 array_construct
.add_argument (new
CCodeConstant ("TRUE"));
269 array_construct
.add_argument (sizeof_call
);
272 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
), array_construct
));
273 block
.add_statement (cdecl
);
275 if (dbus_use_ptr_array (array_type
)) {
276 source_declarations
.add_include ("string.h");
278 var memcpy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("memcpy"));
279 memcpy_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)), "pdata"));
280 memcpy_call
.add_argument (new
CCodeIdentifier (param
.name
));
281 memcpy_call
.add_argument (new
CCodeBinaryExpression (CCodeBinaryOperator
.MUL
, new
CCodeIdentifier (head
.get_array_length_cname (param
.name
, 1)), sizeof_call
));
282 block
.add_statement (new
CCodeExpressionStatement (memcpy_call
));
284 var len_assignment
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)), "len"), new
CCodeIdentifier (head
.get_array_length_cname (param
.name
, 1)));
285 block
.add_statement (new
CCodeExpressionStatement (len_assignment
));
287 var cappend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_array_append_vals"));
288 cappend_call
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
289 cappend_call
.add_argument (new
CCodeIdentifier (param
.name
));
290 cappend_call
.add_argument (new
CCodeIdentifier (head
.get_array_length_cname (param
.name
, 1)));
291 block
.add_statement (new
CCodeExpressionStatement (cappend_call
));
294 ccall
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
297 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRV"));
298 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
300 } else if (get_type_signature (param
.parameter_type
).has_prefix ("(")) {
302 var st
= (Struct
) param
.parameter_type
.data_type
;
304 var array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_array_new"));
305 array_construct
.add_argument (new
CCodeConstant ("0"));
307 var cdecl
= new
CCodeDeclaration ("GValueArray*");
308 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
), array_construct
));
309 block
.add_statement (cdecl
);
311 foreach (Field f
in st
.get_fields ()) {
312 if (f
.binding
!= MemberBinding
.INSTANCE
) {
316 string val_name
= "val_%s_%s".printf (param
.name
, f
.name
);
318 // 0-initialize struct with struct initializer { 0 }
319 var cvalinit
= new
CCodeInitializerList ();
320 cvalinit
.append (new
CCodeConstant ("0"));
322 var cval_decl
= new
CCodeDeclaration ("GValue");
323 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero (val_name
, cvalinit
));
324 block
.add_statement (cval_decl
);
326 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (val_name
));
328 var cinit_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_init"));
329 cinit_call
.add_argument (val_ptr
);
330 cinit_call
.add_argument (new
CCodeIdentifier (f
.field_type
.data_type
.get_type_id ()));
331 block
.add_statement (new
CCodeExpressionStatement (cinit_call
));
333 var cset_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.field_type
.data_type
.get_set_value_function ()));
334 cset_call
.add_argument (val_ptr
);
335 cset_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), f
.name
));
336 block
.add_statement (new
CCodeExpressionStatement (cset_call
));
338 var cappend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_array_append"));
339 cappend_call
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
340 cappend_call
.add_argument (val_ptr
);
341 block
.add_statement (new
CCodeExpressionStatement (cappend_call
));
344 ccall
.add_argument (get_dbus_g_type (param
.parameter_type
));
345 ccall
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
347 ccall
.add_argument (get_dbus_g_type (param
.parameter_type
));
348 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
352 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
354 var out_marshalling_fragment
= new
CCodeFragment ();
356 foreach (FormalParameter param
in method
.get_parameters ()) {
357 if (param
.parameter_type is MethodType
) {
358 // callback parameter
362 if (param
.direction
!= ParameterDirection
.OUT
) {
366 if (get_type_signature (param
.parameter_type
).has_prefix ("(")) {
367 // struct output parameter
368 var st
= (Struct
) param
.parameter_type
.data_type
;
370 var cdecl
= new
CCodeDeclaration ("GValueArray*");
371 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
)));
372 block
.add_statement (cdecl
);
375 foreach (Field f
in st
.get_fields ()) {
376 if (f
.binding
!= MemberBinding
.INSTANCE
) {
380 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.field_type
.data_type
.get_get_value_function ()));
381 cget_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeElementAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)), "values"), new
CCodeConstant (i
.to_string ()))));
383 var converted_value
= cget_call
;
385 if (requires_copy (f
.field_type
)) {
386 var dupexpr
= get_dup_func_expression (f
.field_type
, expr
.source_reference
);
387 converted_value
= new
CCodeFunctionCall (dupexpr
);
388 converted_value
.add_argument (cget_call
);
391 var assign
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), f
.name
), converted_value
);
392 out_marshalling_fragment
.append (new
CCodeExpressionStatement (assign
));
397 ccall
.add_argument (get_dbus_g_type (param
.parameter_type
));
398 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("dbus_%s".printf (param
.name
))));
400 ccall
.add_argument (get_dbus_g_type (param
.parameter_type
));
401 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
405 if (!(method
.return_type is VoidType
)) {
406 // synchronous D-Bus method call with reply
407 ccall
.add_argument (get_dbus_g_type (method
.return_type
));
409 var array_type
= method
.return_type as ArrayType
;
410 if (array_type
!= null && array_type
.element_type
.data_type
!= string_type
.data_type
) {
411 // non-string arrays (use GArray)
412 CCodeDeclaration cdecl
;
413 if (dbus_use_ptr_array (array_type
)) {
414 cdecl
= new
CCodeDeclaration ("GPtrArray*");
416 cdecl
= new
CCodeDeclaration ("GArray*");
418 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
419 block
.add_statement (cdecl
);
421 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
422 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
424 block
.add_statement (new
CCodeExpressionStatement (ccall
));
426 // don't access result when error occured
427 var creturnblock
= new
CCodeBlock ();
428 creturnblock
.add_statement (new
CCodeReturnStatement (default_value_for_type (method
.return_type
, false)));
429 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
430 block
.add_statement (cerrorif
);
432 block
.add_statement (out_marshalling_fragment
);
434 // *result_length1 = result->len;
435 var garray_length
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("result"), "len");
436 var result_length
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length1"));
437 var assign
= new
CCodeAssignment (result_length
, garray_length
);
438 block
.add_statement (new
CCodeExpressionStatement (assign
));
440 // return result->data;
441 block
.add_statement (new
CCodeReturnStatement (new
CCodeCastExpression (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("result"), dbus_use_ptr_array (array_type
) ?
"pdata" : "data"), method
.return_type
.get_cname ())));
442 } else if (method
.return_type
.is_real_non_null_struct_type ()) {
443 // structs are returned via out parameter
444 var st
= (Struct
) method
.return_type
.data_type
;
446 if (st
.get_full_name () == "GLib.Value") {
447 ccall
.add_argument (new
CCodeIdentifier ("result"));
448 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
450 block
.add_statement (new
CCodeExpressionStatement (ccall
));
452 var cdecl
= new
CCodeDeclaration ("GValueArray*");
453 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_result"));
454 block
.add_statement (cdecl
);
457 foreach (Field f
in st
.get_fields ()) {
458 if (f
.binding
!= MemberBinding
.INSTANCE
) {
462 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.field_type
.data_type
.get_get_value_function ()));
463 cget_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeElementAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_result"), "values"), new
CCodeConstant (i
.to_string ()))));
465 var converted_value
= cget_call
;
467 if (requires_copy (f
.field_type
)) {
468 var dupexpr
= get_dup_func_expression (f
.field_type
, expr
.source_reference
);
469 converted_value
= new
CCodeFunctionCall (dupexpr
);
470 converted_value
.add_argument (cget_call
);
473 var assign
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("result"), f
.name
), converted_value
);
474 out_marshalling_fragment
.append (new
CCodeExpressionStatement (assign
));
479 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("dbus_result")));
480 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
482 block
.add_statement (new
CCodeExpressionStatement (ccall
));
485 // don't access result when error occured
486 var creturnblock
= new
CCodeBlock ();
487 creturnblock
.add_statement (new
CCodeReturnStatement ());
488 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
489 block
.add_statement (cerrorif
);
491 block
.add_statement (out_marshalling_fragment
);
493 // string arrays or other datatypes
494 var cdecl
= new
CCodeDeclaration (method
.return_type
.get_cname ());
495 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
496 block
.add_statement (cdecl
);
498 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
499 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
501 block
.add_statement (new
CCodeExpressionStatement (ccall
));
503 // don't access result when error occured
504 var creturnblock
= new
CCodeBlock ();
505 creturnblock
.add_statement (new
CCodeReturnStatement (default_value_for_type (method
.return_type
, false)));
506 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
507 block
.add_statement (cerrorif
);
509 block
.add_statement (out_marshalling_fragment
);
511 if (array_type
!= null) {
512 // special case string array
514 // *result_length1 = g_strv_length (result);
515 var cstrvlen
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strv_length"));
516 cstrvlen
.add_argument (new
CCodeIdentifier ("result"));
517 var result_length
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length1"));
518 var assign
= new
CCodeAssignment (result_length
, cstrvlen
);
519 block
.add_statement (new
CCodeExpressionStatement (assign
));
522 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
525 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
527 block
.add_statement (new
CCodeExpressionStatement (ccall
));
529 // don't access result when error occured
530 var creturnblock
= new
CCodeBlock ();
531 creturnblock
.add_statement (new
CCodeReturnStatement ());
532 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
533 block
.add_statement (cerrorif
);
535 block
.add_statement (out_marshalling_fragment
);
539 public override CCodeExpression
get_dbus_g_type (DataType data_type
) {
540 if (data_type is ArrayType
) {
541 var array_type
= data_type as ArrayType
;
542 if (array_type
.element_type
.data_type
== string_type
.data_type
) {
543 return new
CCodeIdentifier ("G_TYPE_STRV");
546 var carray_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_collection"));
547 if (dbus_use_ptr_array (array_type
)) {
548 carray_type
.add_argument (new
CCodeConstant ("\"GPtrArray\""));
550 carray_type
.add_argument (new
CCodeConstant ("\"GArray\""));
552 carray_type
.add_argument (get_dbus_g_type (array_type
.element_type
));
554 } else if (data_type
.data_type is Enum
) {
555 var en
= (Enum
) data_type
.data_type
;
557 return new
CCodeIdentifier ("G_TYPE_UINT");
559 return new
CCodeIdentifier ("G_TYPE_INT");
561 } else if (data_type
.data_type
== null) {
562 critical ("Internal error during DBus type generation with: %s", data_type
.to_string ());
563 return new
CCodeIdentifier ("G_TYPE_NONE");
564 } else if (data_type
.data_type
.get_full_name () == "GLib.HashTable") {
565 var cmap_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_map"));
566 var type_args
= data_type
.get_type_arguments ();
568 cmap_type
.add_argument (new
CCodeConstant ("\"GHashTable\""));
569 foreach (DataType type_arg
in type_args
) {
570 cmap_type
.add_argument (get_dbus_g_type (type_arg
));
574 } else if (get_type_signature (data_type
).has_prefix ("(")) {
576 var st
= (Struct
) data_type
.data_type
;
578 var type_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_struct"));
579 type_call
.add_argument (new
CCodeConstant ("\"GValueArray\""));
581 foreach (Field f
in st
.get_fields ()) {
582 if (f
.binding
!= MemberBinding
.INSTANCE
) {
586 type_call
.add_argument (get_dbus_g_type (f
.field_type
));
589 type_call
.add_argument (new
CCodeConstant ("G_TYPE_INVALID"));
593 return new
CCodeIdentifier (data_type
.data_type
.get_type_id ());
597 public bool dbus_use_ptr_array (ArrayType array_type
) {
598 if (array_type
.element_type
.data_type
== string_type
.data_type
) {
601 } else if (array_type
.element_type
.data_type
== bool_type
.data_type
602 || array_type
.element_type
.data_type
== char_type
.data_type
603 || array_type
.element_type
.data_type
== uchar_type
.data_type
604 || array_type
.element_type
.data_type
== int_type
.data_type
605 || array_type
.element_type
.data_type
== uint_type
.data_type
606 || array_type
.element_type
.data_type
== long_type
.data_type
607 || array_type
.element_type
.data_type
== ulong_type
.data_type
608 || array_type
.element_type
.data_type
== int8_type
.data_type
609 || array_type
.element_type
.data_type
== uint8_type
.data_type
610 || array_type
.element_type
.data_type
== int32_type
.data_type
611 || array_type
.element_type
.data_type
== uint32_type
.data_type
612 || array_type
.element_type
.data_type
== int64_type
.data_type
613 || array_type
.element_type
.data_type
== uint64_type
.data_type
614 || array_type
.element_type
.data_type
== double_type
.data_type
) {
623 public override string get_dynamic_property_getter_cname (DynamicProperty prop
) {
624 if (prop
.dynamic_type
.data_type
!= dbus_object_type
) {
625 return base.get_dynamic_property_getter_cname (prop
);
628 string getter_cname
= "_dynamic_get_%s%d".printf (prop
.name
, dynamic_property_id
++);
630 if (get_type_signature (prop
.property_type
) == null) {
631 Report
.error (prop
.property_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (prop
.property_type
.to_string ()));
635 var func
= new
CCodeFunction (getter_cname
, prop
.property_type
.get_cname ());
636 func
.modifiers
|= CCodeModifiers
.STATIC
| CCodeModifiers
.INLINE
;
638 func
.add_parameter (new
CCodeFormalParameter ("obj", prop
.dynamic_type
.get_cname ()));
640 var block
= new
CCodeBlock ();
641 generate_dbus_property_getter_wrapper (prop
, block
);
643 // append to C source file
644 source_declarations
.add_type_member_declaration (func
.copy ());
647 source_type_member_definition
.append (func
);
652 public override string get_dynamic_property_setter_cname (DynamicProperty prop
) {
653 if (prop
.dynamic_type
.data_type
!= dbus_object_type
) {
654 return base.get_dynamic_property_setter_cname (prop
);
657 string setter_cname
= "_dynamic_set_%s%d".printf (prop
.name
, dynamic_property_id
++);
659 if (get_type_signature (prop
.property_type
) == null) {
660 Report
.error (prop
.property_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (prop
.property_type
.to_string ()));
664 var func
= new
CCodeFunction (setter_cname
, "void");
665 func
.modifiers
|= CCodeModifiers
.STATIC
| CCodeModifiers
.INLINE
;
667 func
.add_parameter (new
CCodeFormalParameter ("obj", prop
.dynamic_type
.get_cname ()));
668 func
.add_parameter (new
CCodeFormalParameter ("value", prop
.property_type
.get_cname ()));
670 var block
= new
CCodeBlock ();
671 generate_dbus_property_setter_wrapper (prop
, block
);
673 // append to C source file
674 source_declarations
.add_type_member_declaration (func
.copy ());
677 source_type_member_definition
.append (func
);
682 void create_dbus_property_proxy (DynamicProperty node
, CCodeBlock block
) {
683 var prop_proxy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
684 prop_proxy_call
.add_argument (new
CCodeIdentifier ("obj"));
685 prop_proxy_call
.add_argument (new
CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
686 prop_proxy_call
.add_argument (new
CCodeConstant ("NULL"));
688 var prop_proxy_decl
= new
CCodeDeclaration ("DBusGProxy*");
689 prop_proxy_decl
.add_declarator (new
CCodeVariableDeclarator ("property_proxy", prop_proxy_call
));
690 block
.add_statement (prop_proxy_decl
);
693 void generate_dbus_property_getter_wrapper (DynamicProperty node
, CCodeBlock block
) {
694 create_dbus_property_proxy (node
, block
);
697 var cvalinit
= new
CCodeInitializerList ();
698 cvalinit
.append (new
CCodeConstant ("0"));
700 var cval_decl
= new
CCodeDeclaration ("GValue");
701 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero ("gvalue", cvalinit
));
702 block
.add_statement (cval_decl
);
704 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("gvalue"));
706 // call Get method on property proxy
707 var cdecl
= new
CCodeDeclaration (node
.property_type
.get_cname ());
708 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
709 block
.add_statement (cdecl
);
711 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_call"));
712 ccall
.add_argument (new
CCodeIdentifier ("property_proxy"));
713 ccall
.add_argument (new
CCodeConstant ("\"Get\""));
714 ccall
.add_argument (new
CCodeConstant ("NULL"));
716 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
717 var get_iface
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_interface"));
718 get_iface
.add_argument (new
CCodeIdentifier ("obj"));
719 ccall
.add_argument (get_iface
);
721 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
722 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node
.name
))));
724 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
726 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_VALUE"));
727 ccall
.add_argument (val_ptr
);
729 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
731 block
.add_statement (new
CCodeExpressionStatement (ccall
));
733 // unref property proxy
734 var prop_proxy_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
735 prop_proxy_unref
.add_argument (new
CCodeIdentifier ("property_proxy"));
736 block
.add_statement (new
CCodeExpressionStatement (prop_proxy_unref
));
738 // assign value to result variable
739 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (node
.property_type
.data_type
.get_get_value_function ()));
740 cget_call
.add_argument (val_ptr
);
741 var assign
= new
CCodeAssignment (new
CCodeIdentifier ("result"), cget_call
);
742 block
.add_statement (new
CCodeExpressionStatement (assign
));
745 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
748 void generate_dbus_property_setter_wrapper (DynamicProperty node
, CCodeBlock block
) {
749 create_dbus_property_proxy (node
, block
);
752 var cvalinit
= new
CCodeInitializerList ();
753 cvalinit
.append (new
CCodeConstant ("0"));
755 var cval_decl
= new
CCodeDeclaration ("GValue");
756 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero ("gvalue", cvalinit
));
757 block
.add_statement (cval_decl
);
759 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("gvalue"));
761 var cinit_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_init"));
762 cinit_call
.add_argument (val_ptr
);
763 cinit_call
.add_argument (new
CCodeIdentifier (node
.property_type
.data_type
.get_type_id ()));
764 block
.add_statement (new
CCodeExpressionStatement (cinit_call
));
766 var cset_call
= new
CCodeFunctionCall (new
CCodeIdentifier (node
.property_type
.data_type
.get_set_value_function ()));
767 cset_call
.add_argument (val_ptr
);
768 cset_call
.add_argument (new
CCodeIdentifier ("value"));
769 block
.add_statement (new
CCodeExpressionStatement (cset_call
));
771 // call Set method on property proxy
772 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_call"));
773 ccall
.add_argument (new
CCodeIdentifier ("property_proxy"));
774 ccall
.add_argument (new
CCodeConstant ("\"Set\""));
775 ccall
.add_argument (new
CCodeConstant ("NULL"));
777 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
778 var get_iface
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_interface"));
779 get_iface
.add_argument (new
CCodeIdentifier ("obj"));
780 ccall
.add_argument (get_iface
);
782 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
783 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node
.name
))));
785 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_VALUE"));
786 ccall
.add_argument (val_ptr
);
788 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
790 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
792 block
.add_statement (new
CCodeExpressionStatement (ccall
));
794 // unref property proxy
795 var prop_proxy_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
796 prop_proxy_unref
.add_argument (new
CCodeIdentifier ("property_proxy"));
797 block
.add_statement (new
CCodeExpressionStatement (prop_proxy_unref
));
800 public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig
) {
801 if (sig
.dynamic_type
.data_type
!= dbus_object_type
) {
802 return base.get_dynamic_signal_connect_wrapper_name (sig
);
805 string connect_wrapper_name
= "_%sconnect".printf (get_dynamic_signal_cname (sig
));
806 var func
= new
CCodeFunction (connect_wrapper_name
, "void");
807 func
.add_parameter (new
CCodeFormalParameter ("obj", "gpointer"));
808 func
.add_parameter (new
CCodeFormalParameter ("signal_name", "const char *"));
809 func
.add_parameter (new
CCodeFormalParameter ("handler", "GCallback"));
810 func
.add_parameter (new
CCodeFormalParameter ("data", "gpointer"));
811 var block
= new
CCodeBlock ();
812 generate_dbus_connect_wrapper (sig
, block
);
814 // append to C source file
815 source_declarations
.add_type_member_declaration (func
.copy ());
818 source_type_member_definition
.append (func
);
820 return connect_wrapper_name
;
823 public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal sig
) {
824 if (sig
.dynamic_type
.data_type
!= dbus_object_type
) {
825 return base.get_dynamic_signal_disconnect_wrapper_name (sig
);
828 string disconnect_wrapper_name
= "_%sdisconnect".printf (get_dynamic_signal_cname (sig
));
829 var func
= new
CCodeFunction (disconnect_wrapper_name
, "void");
830 func
.add_parameter (new
CCodeFormalParameter ("obj", "gpointer"));
831 func
.add_parameter (new
CCodeFormalParameter ("signal_name", "const char *"));
832 func
.add_parameter (new
CCodeFormalParameter ("handler", "GCallback"));
833 func
.add_parameter (new
CCodeFormalParameter ("data", "gpointer"));
834 var block
= new
CCodeBlock ();
835 generate_dbus_disconnect_wrapper (sig
, block
);
837 // append to C source file
838 source_declarations
.add_type_member_declaration (func
.copy ());
841 source_type_member_definition
.append (func
);
843 return disconnect_wrapper_name
;
846 void generate_dbus_connect_wrapper (DynamicSignal sig
, CCodeBlock block
) {
847 var m
= (Method
) sig
.handler
.symbol_reference
;
849 sig
.accept (codegen
);
851 // FIXME should only be done once per marshaller
852 var register_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_object_register_marshaller"));
853 head
.generate_marshaller (sig
.get_parameters (), sig
.return_type
, true);
854 register_call
.add_argument (new
CCodeIdentifier (head
.get_marshaller_function (sig
.get_parameters (), sig
.return_type
, null, true)));
855 register_call
.add_argument (new
CCodeIdentifier ("G_TYPE_NONE"));
857 var add_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_add_signal"));
858 add_call
.add_argument (new
CCodeIdentifier ("obj"));
859 add_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
862 foreach (FormalParameter param
in m
.get_parameters ()) {
864 // skip sender parameter
869 register_call
.add_argument (get_dbus_g_type (param
.parameter_type
));
870 add_call
.add_argument (get_dbus_g_type (param
.parameter_type
));
872 register_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
873 add_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
875 block
.add_statement (new
CCodeExpressionStatement (register_call
));
876 block
.add_statement (new
CCodeExpressionStatement (add_call
));
878 var call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_connect_signal"));
879 call
.add_argument (new
CCodeIdentifier ("obj"));
880 call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
881 call
.add_argument (new
CCodeIdentifier ("handler"));
882 call
.add_argument (new
CCodeIdentifier ("data"));
883 call
.add_argument (new
CCodeConstant ("NULL"));
884 block
.add_statement (new
CCodeExpressionStatement (call
));
887 void generate_dbus_disconnect_wrapper (DynamicSignal sig
, CCodeBlock block
) {
888 var call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
889 call
.add_argument (new
CCodeIdentifier ("obj"));
890 call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
891 call
.add_argument (new
CCodeIdentifier ("handler"));
892 call
.add_argument (new
CCodeIdentifier ("data"));
893 block
.add_statement (new
CCodeExpressionStatement (call
));
896 public override void visit_cast_expression (CastExpression expr
) {
897 // handles casting DBus.Object instances to DBus interfaces
899 var type
= expr
.type_reference as ObjectType
;
900 var call
= expr
.inner as MethodCall
;
901 if (type
== null || !(type
.type_symbol is Interface
)
902 || type
.type_symbol
.get_attribute ("DBus") == null || call
== null) {
903 base.visit_cast_expression (expr
);
907 var mtype
= call
.call
.value_type as MethodType
;
908 if (mtype
== null || mtype
.method_symbol
.get_cname () != "dbus_g_proxy_new_for_name") {
909 base.visit_cast_expression (expr
);
913 var args
= call
.get_argument_list ();
914 Expression connection
= ((MemberAccess
) call
.call
).inner
;
915 Expression bus_name
= args
.get (0);
916 Expression object_path
= args
.get (1);
918 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (type
.type_symbol
.get_lower_case_cprefix () + "dbus_proxy_new"));
919 connection
.accept (codegen
);
920 ccall
.add_argument ((CCodeExpression
) connection
.ccodenode
);
921 bus_name
.accept (codegen
);
922 ccall
.add_argument ((CCodeExpression
) bus_name
.ccodenode
);
923 object_path
.accept (codegen
);
924 ccall
.add_argument ((CCodeExpression
) object_path
.ccodenode
);
925 expr
.ccodenode
= ccall
;
928 void generate_proxy_interface_init (Interface main_iface
, Interface iface
) {
929 // also generate proxy for prerequisites
930 foreach (var prereq
in iface
.get_prerequisites ()) {
931 if (prereq
.data_type is Interface
) {
932 generate_proxy_interface_init (main_iface
, (Interface
) prereq
.data_type
);
936 string lower_cname
= main_iface
.get_lower_case_cprefix () + "dbus_proxy";
938 var proxy_iface_init
= new
CCodeFunction (lower_cname
+ "_" + iface
.get_lower_case_cprefix () + "_interface_init", "void");
939 proxy_iface_init
.add_parameter (new
CCodeFormalParameter ("iface", iface
.get_cname () + "Iface*"));
941 var iface_block
= new
CCodeBlock ();
943 foreach (Method m
in iface
.get_methods ()) {
944 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.vfunc_name
);
946 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_method (main_iface
, iface
, m
)))));
948 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_async_dbus_proxy_method (main_iface
, iface
, m
)))));
949 vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.get_finish_vfunc_name ());
950 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_finish_dbus_proxy_method (main_iface
, iface
, m
)))));
954 foreach (Property prop
in iface
.get_properties ()) {
955 if (prop
.get_accessor
!= null) {
956 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "get_" + prop
.name
);
957 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_get (main_iface
, iface
, prop
)))));
959 if (prop
.set_accessor
!= null) {
960 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "set_" + prop
.name
);
961 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_set (main_iface
, iface
, prop
)))));
965 proxy_iface_init
.modifiers
= CCodeModifiers
.STATIC
;
966 source_declarations
.add_type_member_declaration (proxy_iface_init
.copy ());
967 proxy_iface_init
.block
= iface_block
;
968 source_type_member_definition
.append (proxy_iface_init
);
971 string implement_interface (CCodeFunctionCall define_type
, Interface main_iface
, Interface iface
) {
974 // also implement prerequisites
975 foreach (var prereq
in iface
.get_prerequisites ()) {
976 if (prereq
.data_type is Interface
) {
977 result
+= implement_interface (define_type
, main_iface
, (Interface
) prereq
.data_type
);
981 result
+= "G_IMPLEMENT_INTERFACE (%s, %sdbus_proxy_%s_interface_init) ".printf (
982 iface
.get_upper_case_cname ("TYPE_"),
983 main_iface
.get_lower_case_cprefix (),
984 iface
.get_lower_case_cprefix ());
988 void implement_property (CCodeBlock block
, Interface main_iface
, Interface iface
) {
989 // also implement prerequisites
990 foreach (var prereq
in iface
.get_prerequisites ()) {
991 if (prereq
.data_type is Interface
) {
992 implement_property (block
, main_iface
, (Interface
) prereq
.data_type
);
996 var gobject_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
997 gobject_class
.add_argument (new
CCodeIdentifier ("klass"));
999 foreach (Property prop
in iface
.get_properties ()) {
1000 if (!prop
.is_abstract
) {
1004 if (!is_gobject_property (prop
)) {
1008 string prop_ev
= "%s_dbus_proxy_%s".printf (main_iface
.get_lower_case_cname (null), Symbol
.camel_case_to_lower_case (prop
.name
)).up ();
1010 var cinst
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_class_override_property"));
1011 cinst
.add_argument (gobject_class
);
1012 cinst
.add_argument (new
CCodeConstant (prop_ev
));
1013 cinst
.add_argument (prop
.get_canonical_cconstant ());
1014 block
.add_statement (new
CCodeExpressionStatement (cinst
));
1016 prop_enum
.add_value (new
CCodeEnumValue (prop_ev
));
1020 public override void generate_interface_declaration (Interface iface
, CCodeDeclarationSpace decl_space
) {
1021 base.generate_interface_declaration (iface
, decl_space
);
1023 string dbus_iface_name
= get_dbus_name (iface
);
1024 if (dbus_iface_name
== null) {
1028 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1030 if (decl_space
.add_symbol_declaration (iface
, lower_cname
+ "_new")) {
1034 // declare proxy_new function
1035 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1036 proxy_new
.add_parameter (new
CCodeFormalParameter ("connection", "DBusGConnection*"));
1037 proxy_new
.add_parameter (new
CCodeFormalParameter ("name", "const char*"));
1038 proxy_new
.add_parameter (new
CCodeFormalParameter ("path", "const char*"));
1040 decl_space
.add_type_member_declaration (proxy_new
);
1043 public override void visit_interface (Interface iface
) {
1044 base.visit_interface (iface
);
1046 string dbus_iface_name
= get_dbus_name (iface
);
1047 if (dbus_iface_name
== null) {
1052 source_declarations
.add_include ("string.h");
1054 // create proxy class
1055 string cname
= iface
.get_cname () + "DBusProxy";
1056 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1058 add_dbus_helpers ();
1060 source_declarations
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cname
), new
CCodeVariableDeclarator (cname
)));
1061 source_declarations
.add_type_declaration (new
CCodeTypeDefinition ("DBusGProxyClass", new
CCodeVariableDeclarator (cname
+ "Class")));
1063 var instance_struct
= new
CCodeStruct ("_%s".printf (cname
));
1064 instance_struct
.add_field ("DBusGProxy", "parent_instance");
1065 instance_struct
.add_field ("gboolean", "disposed");
1067 source_declarations
.add_type_definition (instance_struct
);
1069 source_declarations
.add_type_member_declaration (new
CCodeFunction(lower_cname
+ "_get_type", "GType"));
1071 var define_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_DEFINE_TYPE_EXTENDED"));
1072 define_type
.add_argument (new
CCodeIdentifier (cname
));
1073 define_type
.add_argument (new
CCodeIdentifier (lower_cname
));
1074 define_type
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_G_PROXY"));
1075 define_type
.add_argument (new
CCodeConstant ("0"));
1076 define_type
.add_argument (new
CCodeIdentifier (implement_interface (define_type
, iface
, iface
)));
1078 source_type_member_definition
.append (new
CCodeExpressionStatement (define_type
));
1080 // generate proxy_new function
1081 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1082 proxy_new
.add_parameter (new
CCodeFormalParameter ("connection", "DBusGConnection*"));
1083 proxy_new
.add_parameter (new
CCodeFormalParameter ("name", "const char*"));
1084 proxy_new
.add_parameter (new
CCodeFormalParameter ("path", "const char*"));
1086 var new_block
= new
CCodeBlock ();
1088 // create proxy object
1089 var new_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1090 new_call
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier (lower_cname
+ "_get_type")));
1091 new_call
.add_argument (new
CCodeConstant ("\"connection\""));
1092 new_call
.add_argument (new
CCodeIdentifier ("connection"));
1093 new_call
.add_argument (new
CCodeConstant ("\"name\""));
1094 new_call
.add_argument (new
CCodeIdentifier ("name"));
1095 new_call
.add_argument (new
CCodeConstant ("\"path\""));
1096 new_call
.add_argument (new
CCodeIdentifier ("path"));
1097 new_call
.add_argument (new
CCodeConstant ("\"interface\""));
1098 new_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1099 new_call
.add_argument (new
CCodeConstant ("NULL"));
1101 var cdecl
= new
CCodeDeclaration (iface
.get_cname () + "*");
1102 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", new_call
));
1103 new_block
.add_statement (cdecl
);
1104 new_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1106 proxy_new
.block
= new_block
;
1107 source_type_member_definition
.append (proxy_new
);
1109 // dbus proxy construct
1110 var proxy_construct
= new
CCodeFunction (lower_cname
+ "_construct", "GObject*");
1111 proxy_construct
.add_parameter (new
CCodeFormalParameter ("gtype", "GType"));
1112 proxy_construct
.add_parameter (new
CCodeFormalParameter ("n_properties", "guint"));
1113 proxy_construct
.add_parameter (new
CCodeFormalParameter ("properties", "GObjectConstructParam*"));
1114 proxy_construct
.modifiers
= CCodeModifiers
.STATIC
;
1115 proxy_construct
.block
= new
CCodeBlock ();
1118 var parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1119 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1120 var chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "constructor"));
1121 chainup
.add_argument (new
CCodeIdentifier ("gtype"));
1122 chainup
.add_argument (new
CCodeIdentifier ("n_properties"));
1123 chainup
.add_argument (new
CCodeIdentifier ("properties"));
1125 cdecl
= new
CCodeDeclaration ("GObject*");
1126 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", chainup
));
1127 proxy_construct
.block
.add_statement (cdecl
);
1129 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1130 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1131 proxy_construct
.block
.add_statement (cdecl
);
1133 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1134 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1135 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1136 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1137 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1138 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1140 cdecl
= new
CCodeDeclaration ("char*");
1141 cdecl
.add_declarator (new
CCodeVariableDeclarator ("path"));
1142 proxy_construct
.block
.add_statement (cdecl
);
1144 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1145 path
.add_argument (new
CCodeIdentifier ("self"));
1146 path
.add_argument (new
CCodeConstant ("\"path\""));
1147 path
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("path")));
1148 path
.add_argument (new
CCodeConstant ("NULL"));
1149 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path
));
1151 var raw_connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1152 raw_connection
.add_argument (new
CCodeIdentifier ("connection"));
1154 // add filter to handle signals from the remote object
1155 var filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_add_filter"));
1156 filter_call
.add_argument (raw_connection
);
1157 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1158 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1159 filter_call
.add_argument (new
CCodeConstant ("NULL"));
1160 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1162 var filter_printf
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup_printf"));
1163 filter_printf
.add_argument (new
CCodeConstant ("\"type='signal',path='%s'\""));
1164 filter_printf
.add_argument (new
CCodeIdentifier ("path"));
1166 cdecl
= new
CCodeDeclaration ("char*");
1167 cdecl
.add_declarator (new
CCodeVariableDeclarator ("filter", filter_printf
));
1168 proxy_construct
.block
.add_statement (cdecl
);
1170 // ensure we receive signals from the remote object
1171 var match_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_bus_add_match"));
1172 match_call
.add_argument (raw_connection
);
1173 match_call
.add_argument (new
CCodeIdentifier ("filter"));
1174 match_call
.add_argument (new
CCodeConstant ("NULL"));
1175 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (match_call
));
1177 var connection_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1178 connection_free
.add_argument (new
CCodeIdentifier ("connection"));
1179 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (connection_free
));
1181 var path_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1182 path_free
.add_argument (new
CCodeIdentifier ("path"));
1183 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path_free
));
1185 var filter_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1186 filter_free
.add_argument (new
CCodeIdentifier ("filter"));
1187 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_free
));
1189 proxy_construct
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1191 source_type_member_definition
.append (proxy_construct
);
1193 // dbus proxy filter function
1194 generate_proxy_filter_function (iface
);
1196 // dbus proxy dispose
1197 var proxy_dispose
= new
CCodeFunction (lower_cname
+ "_dispose", "void");
1198 proxy_dispose
.add_parameter (new
CCodeFormalParameter ("self", "GObject*"));
1199 proxy_dispose
.modifiers
= CCodeModifiers
.STATIC
;
1200 proxy_dispose
.block
= new
CCodeBlock ();
1202 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1203 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1204 proxy_dispose
.block
.add_statement (cdecl
);
1206 // return if proxy is already disposed
1207 var dispose_return_block
= new
CCodeBlock ();
1208 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1209 proxy_dispose
.block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), dispose_return_block
));
1211 // mark proxy as disposed
1212 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), new
CCodeConstant ("TRUE"))));
1214 gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1215 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1216 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1217 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1218 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1219 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1222 filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_remove_filter"));
1223 filter_call
.add_argument (raw_connection
);
1224 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1225 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1226 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1229 parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1230 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1231 chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "dispose"));
1232 chainup
.add_argument (new
CCodeIdentifier ("self"));
1233 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (chainup
));
1235 source_type_member_definition
.append (proxy_dispose
);
1237 var proxy_class_init
= new
CCodeFunction (lower_cname
+ "_class_init", "void");
1238 proxy_class_init
.add_parameter (new
CCodeFormalParameter ("klass", cname
+ "Class*"));
1239 proxy_class_init
.modifiers
= CCodeModifiers
.STATIC
;
1240 proxy_class_init
.block
= new
CCodeBlock ();
1241 var gobject_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1242 gobject_class
.add_argument (new
CCodeIdentifier ("klass"));
1243 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "constructor"), new
CCodeIdentifier (lower_cname
+ "_construct"))));
1244 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "dispose"), new
CCodeIdentifier (lower_cname
+ "_dispose"))));
1245 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "get_property"), new
CCodeIdentifier (lower_cname
+ "_get_property"))));
1246 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "set_property"), new
CCodeIdentifier (lower_cname
+ "_set_property"))));
1247 source_type_member_definition
.append (proxy_class_init
);
1249 prop_enum
= new
CCodeEnum ();
1250 prop_enum
.add_value (new
CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (lower_cname
.up ())));
1252 implement_property (proxy_class_init
.block
, iface
, iface
);
1254 source_declarations
.add_type_member_declaration (prop_enum
);
1256 var proxy_instance_init
= new
CCodeFunction (lower_cname
+ "_init", "void");
1257 proxy_instance_init
.add_parameter (new
CCodeFormalParameter ("self", cname
+ "*"));
1258 proxy_instance_init
.modifiers
= CCodeModifiers
.STATIC
;
1259 proxy_instance_init
.block
= new
CCodeBlock ();
1260 source_type_member_definition
.append (proxy_instance_init
);
1262 generate_proxy_interface_init (iface
, iface
);
1264 // dbus proxy get/set_property stubs
1265 // TODO add actual implementation
1266 var get_prop
= new
CCodeFunction ("%s_get_property".printf (lower_cname
), "void");
1267 get_prop
.modifiers
= CCodeModifiers
.STATIC
;
1268 get_prop
.add_parameter (new
CCodeFormalParameter ("object", "GObject *"));
1269 get_prop
.add_parameter (new
CCodeFormalParameter ("property_id", "guint"));
1270 get_prop
.add_parameter (new
CCodeFormalParameter ("value", "GValue *"));
1271 get_prop
.add_parameter (new
CCodeFormalParameter ("pspec", "GParamSpec *"));
1272 source_declarations
.add_type_member_declaration (get_prop
.copy ());
1273 get_prop
.block
= new
CCodeBlock ();
1274 source_type_member_definition
.append (get_prop
);
1276 var set_prop
= new
CCodeFunction ("%s_set_property".printf (lower_cname
), "void");
1277 set_prop
.modifiers
= CCodeModifiers
.STATIC
;
1278 set_prop
.add_parameter (new
CCodeFormalParameter ("object", "GObject *"));
1279 set_prop
.add_parameter (new
CCodeFormalParameter ("property_id", "guint"));
1280 set_prop
.add_parameter (new
CCodeFormalParameter ("value", "const GValue *"));
1281 set_prop
.add_parameter (new
CCodeFormalParameter ("pspec", "GParamSpec *"));
1282 source_declarations
.add_type_member_declaration (set_prop
.copy ());
1283 set_prop
.block
= new
CCodeBlock ();
1284 source_type_member_definition
.append (set_prop
);
1287 public override TypeRegisterFunction
create_interface_register_function (Interface iface
) {
1288 string dbus_iface_name
= get_dbus_name (iface
);
1289 if (dbus_iface_name
== null) {
1290 return new
InterfaceRegisterFunction (iface
, context
);
1293 return new
DBusInterfaceRegisterFunction (iface
, context
);
1296 string generate_get_all_function (Method m
) {
1297 string get_all_func
= "_dbus_g_proxy_get_all";
1299 if (!add_wrapper (get_all_func
)) {
1300 // wrapper already defined
1301 return get_all_func
;
1304 var function
= new
CCodeFunction (get_all_func
, "GHashTable*");
1305 function
.modifiers
= CCodeModifiers
.STATIC
;
1307 function
.add_parameter (new
CCodeFormalParameter ("self", "DBusGProxy*"));
1308 function
.add_parameter (new
CCodeFormalParameter ("interface_name", "const gchar*"));
1309 function
.add_parameter (new
CCodeFormalParameter ("error", "GError**"));
1311 var block
= new
CCodeBlock ();
1312 var prefragment
= new
CCodeFragment ();
1313 var postfragment
= new
CCodeFragment ();
1315 var cdecl
= new
CCodeDeclaration ("DBusError");
1316 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1317 block
.add_statement (cdecl
);
1319 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1321 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1322 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1323 block
.add_statement (cdecl
);
1325 cdecl
= new
CCodeDeclaration ("DBusMessage");
1326 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1327 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1328 block
.add_statement (cdecl
);
1330 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1331 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1332 block
.add_statement (cdecl
);
1334 block
.add_statement (prefragment
);
1336 generate_marshalling (m
, "org.freedesktop.DBus.Properties", prefragment
, postfragment
);
1338 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1339 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1340 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1341 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1342 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1343 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1345 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1346 dbus_error_init
.add_argument (dbus_error
);
1347 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1349 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1350 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1352 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1353 ccall
.add_argument (connection
);
1354 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1355 ccall
.add_argument (get_dbus_timeout (m
));
1356 ccall
.add_argument (dbus_error
);
1357 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1359 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1360 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1361 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1363 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1364 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1365 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1367 check_error_reply (m
, block
);
1368 check_reply_signature (m
, block
);
1370 block
.add_statement (postfragment
);
1372 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1373 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1374 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1376 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1378 source_declarations
.add_type_member_declaration (function
.copy ());
1380 function
.block
= block
;
1381 source_type_member_definition
.append (function
);
1383 return get_all_func
;
1386 public override void visit_method_call (MethodCall expr
) {
1387 var mtype
= expr
.call
.value_type as MethodType
;
1388 bool proxy_new_from_type
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_new_from_type");
1389 bool proxy_get_all
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_get_all");
1390 if (!proxy_new_from_type
&& !proxy_get_all
) {
1391 base.visit_method_call (expr
);
1395 if (proxy_get_all
) {
1396 var ma
= expr
.call as MemberAccess
;
1397 var instance
= ma
.inner
;
1398 instance
.accept (codegen
);
1400 var args
= expr
.get_argument_list ();
1401 Expression interface_name
= args
.get (0);
1402 interface_name
.accept (codegen
);
1404 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_get_all_function (mtype
.method_symbol
)));
1405 ccall
.add_argument ((CCodeExpression
) instance
.ccodenode
);
1406 ccall
.add_argument ((CCodeExpression
) interface_name
.ccodenode
);
1408 current_method_inner_error
= true;
1409 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
1411 expr
.ccodenode
= ccall
;
1415 var args
= expr
.get_argument_list ();
1416 Expression connection
= ((MemberAccess
) expr
.call
).inner
;
1417 Expression bus_name
= args
.get (0);
1418 Expression object_path
= args
.get (1);
1419 Expression interface_name
= args
.get (2);
1420 Expression type
= args
.get (3);
1422 var quark_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_string"));
1423 quark_call
.add_argument (new
CCodeConstant ("\"ValaDBusInterfaceProxyType\""));
1425 var qdata_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
1426 type
.accept (codegen
);
1427 qdata_call
.add_argument ((CCodeExpression
) type
.ccodenode
);
1428 qdata_call
.add_argument (quark_call
);
1430 var get_type_call
= new
CCodeFunctionCall (new
CCodeCastExpression (qdata_call
, "GType (*)(void)"));
1432 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1433 ccall
.add_argument (get_type_call
);
1434 ccall
.add_argument (new
CCodeConstant ("\"connection\""));
1435 connection
.accept (codegen
);
1436 ccall
.add_argument ((CCodeExpression
) connection
.ccodenode
);
1437 ccall
.add_argument (new
CCodeConstant ("\"name\""));
1438 bus_name
.accept (codegen
);
1439 ccall
.add_argument ((CCodeExpression
) bus_name
.ccodenode
);
1440 ccall
.add_argument (new
CCodeConstant ("\"path\""));
1441 object_path
.accept (codegen
);
1442 ccall
.add_argument ((CCodeExpression
) object_path
.ccodenode
);
1443 ccall
.add_argument (new
CCodeConstant ("\"interface\""));
1444 interface_name
.accept (codegen
);
1445 ccall
.add_argument ((CCodeExpression
) interface_name
.ccodenode
);
1446 ccall
.add_argument (new
CCodeConstant ("NULL"));
1447 expr
.ccodenode
= ccall
;
1450 void generate_proxy_filter_function (Interface iface
) {
1451 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1453 var proxy_filter
= new
CCodeFunction (lower_cname
+ "_filter", "DBusHandlerResult");
1454 proxy_filter
.add_parameter (new
CCodeFormalParameter ("connection", "DBusConnection*"));
1455 proxy_filter
.add_parameter (new
CCodeFormalParameter ("message", "DBusMessage*"));
1456 proxy_filter
.add_parameter (new
CCodeFormalParameter ("user_data", "void*"));
1458 var filter_block
= new
CCodeBlock ();
1460 // only handle signals concering the object path
1461 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1462 path
.add_argument (new
CCodeIdentifier ("user_data"));
1464 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_has_path"));
1465 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1466 ccheck
.add_argument (path
);
1468 var object_filter_block
= new
CCodeBlock ();
1469 filter_block
.add_statement (new
CCodeIfStatement (ccheck
, object_filter_block
));
1471 handle_signals (iface
, object_filter_block
);
1473 filter_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED")));
1475 source_declarations
.add_type_member_declaration (proxy_filter
.copy ());
1476 proxy_filter
.block
= filter_block
;
1477 source_type_member_definition
.append (proxy_filter
);
1480 string generate_dbus_signal_handler (Signal sig
, ObjectTypeSymbol sym
) {
1481 string wrapper_name
= "_dbus_handle_%s_%s".printf (sym
.get_lower_case_cname (), sig
.get_cname ());
1485 CCodeDeclaration cdecl
;
1487 var function
= new
CCodeFunction (wrapper_name
, "void");
1488 function
.modifiers
= CCodeModifiers
.STATIC
;
1490 function
.add_parameter (new
CCodeFormalParameter ("self", sym
.get_cname () + "*"));
1491 function
.add_parameter (new
CCodeFormalParameter ("connection", "DBusConnection*"));
1492 function
.add_parameter (new
CCodeFormalParameter ("message", "DBusMessage*"));
1494 var block
= new
CCodeBlock ();
1495 var prefragment
= new
CCodeFragment ();
1496 var postfragment
= new
CCodeFragment ();
1498 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1499 cdecl
.add_declarator (new
CCodeVariableDeclarator ("iter"));
1500 block
.add_statement (cdecl
);
1502 block
.add_statement (prefragment
);
1504 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
1505 message_signature
.add_argument (new
CCodeIdentifier ("message"));
1506 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
1507 signature_check
.add_argument (message_signature
);
1508 var signature_error_block
= new
CCodeBlock ();
1509 signature_error_block
.add_statement (new
CCodeReturnStatement ());
1510 prefragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
1512 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1513 iter_call
.add_argument (new
CCodeIdentifier ("message"));
1514 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("iter")));
1515 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1517 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_emit_by_name"));
1518 ccall
.add_argument (new
CCodeIdentifier ("self"));
1519 ccall
.add_argument (sig
.get_canonical_cconstant ());
1521 // expected type signature for input parameters
1522 string type_signature
= "";
1524 foreach (FormalParameter param
in sig
.get_parameters ()) {
1525 var owned_type
= param
.parameter_type
.copy ();
1526 owned_type
.value_owned
= true;
1528 cdecl
= new
CCodeDeclaration (owned_type
.get_cname ());
1529 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero (param
.name
, default_value_for_type (param
.parameter_type
, true)));
1530 prefragment
.append (cdecl
);
1532 if (get_type_signature (param
.parameter_type
) == null) {
1533 Report
.error (param
.parameter_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (param
.parameter_type
.to_string ()));
1537 var st
= param
.parameter_type
.data_type as Struct
;
1538 if (st
!= null && !st
.is_simple_type ()) {
1539 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
1541 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
1544 if (param
.parameter_type is ArrayType
) {
1545 var array_type
= (ArrayType
) param
.parameter_type
;
1547 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1548 string length_cname
= get_array_length_cname (param
.name
, dim
);
1550 cdecl
= new
CCodeDeclaration ("int");
1551 cdecl
.add_declarator (new
CCodeVariableDeclarator (length_cname
, new
CCodeConstant ("0")));
1552 prefragment
.append (cdecl
);
1553 ccall
.add_argument (new
CCodeIdentifier (length_cname
));
1557 type_signature
+= get_type_signature (param
.parameter_type
);
1559 var target
= new
CCodeIdentifier (param
.name
);
1560 var expr
= read_expression (prefragment
, param
.parameter_type
, new
CCodeIdentifier ("iter"), target
);
1561 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1563 if (requires_destroy (owned_type
)) {
1564 // keep local alive (symbol_reference is weak)
1565 var local
= new
LocalVariable (owned_type
, param
.name
);
1566 var ma
= new MemberAccess
.simple (param
.name
);
1567 ma
.symbol_reference
= local
;
1568 var stmt
= new
CCodeExpressionStatement (get_unref_expression (new
CCodeIdentifier (param
.name
), owned_type
, ma
));
1569 postfragment
.append (stmt
);
1573 signature_check
.add_argument (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
1575 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1577 block
.add_statement (postfragment
);
1579 cdecl
= new
CCodeDeclaration ("DBusMessage*");
1580 cdecl
.add_declarator (new
CCodeVariableDeclarator ("reply"));
1581 block
.add_statement (cdecl
);
1583 source_declarations
.add_type_member_declaration (function
.copy ());
1585 function
.block
= block
;
1586 source_type_member_definition
.append (function
);
1588 return wrapper_name
;
1591 void handle_signal (string dbus_iface_name
, string dbus_signal_name
, string handler_name
, CCodeBlock block
, ref CCodeIfStatement clastif
) {
1592 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_is_signal"));
1593 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1594 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1595 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_signal_name
)));
1597 var callblock
= new
CCodeBlock ();
1599 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (handler_name
));
1600 ccall
.add_argument (new
CCodeIdentifier ("user_data"));
1601 ccall
.add_argument (new
CCodeIdentifier ("connection"));
1602 ccall
.add_argument (new
CCodeIdentifier ("message"));
1604 callblock
.add_statement (new
CCodeExpressionStatement (ccall
));
1606 var cif
= new
CCodeIfStatement (ccheck
, callblock
);
1607 if (clastif
== null) {
1608 block
.add_statement (cif
);
1610 clastif
.false_statement
= cif
;
1616 void handle_signals (Interface iface
, CCodeBlock block
) {
1617 string dbus_iface_name
= get_dbus_name (iface
);
1619 CCodeIfStatement clastif
= null;
1620 foreach (Signal sig
in iface
.get_signals ()) {
1621 if (sig
.access
!= SymbolAccessibility
.PUBLIC
) {
1625 handle_signal (dbus_iface_name
, get_dbus_name_for_member (sig
), generate_dbus_signal_handler (sig
, iface
), block
, ref clastif
);
1629 void generate_marshalling (Method m
, string dbus_iface_name
, CCodeFragment prefragment
, CCodeFragment postfragment
) {
1630 CCodeDeclaration cdecl
;
1632 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
1633 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1634 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1635 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1637 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
1638 msgcall
.add_argument (destination
);
1639 msgcall
.add_argument (path
);
1640 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1641 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m
))));
1642 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
1644 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
1645 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
1646 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1647 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1649 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1650 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
1651 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1652 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
1654 foreach (FormalParameter param
in m
.get_parameters ()) {
1655 if (param
.direction
== ParameterDirection
.IN
) {
1656 if (param
.parameter_type
.data_type
!= null
1657 && param
.parameter_type
.data_type
.get_full_name () == "DBus.BusName") {
1658 // ignore BusName sender parameters
1661 CCodeExpression expr
= new
CCodeIdentifier (param
.name
);
1662 if (param
.parameter_type
.is_real_struct_type ()) {
1663 expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, expr
);
1665 write_expression (prefragment
, param
.parameter_type
, new
CCodeIdentifier ("_iter"), expr
);
1667 cdecl
= new
CCodeDeclaration (param
.parameter_type
.get_cname ());
1668 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_" + param
.name
));
1669 postfragment
.append (cdecl
);
1671 var array_type
= param
.parameter_type as ArrayType
;
1673 if (array_type
!= null) {
1674 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1675 cdecl
= new
CCodeDeclaration ("int");
1676 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_length%d".printf (param
.name
, dim
), new
CCodeConstant ("0")));
1677 postfragment
.append (cdecl
);
1681 var target
= new
CCodeIdentifier ("_" + param
.name
);
1682 var expr
= read_expression (postfragment
, param
.parameter_type
, new
CCodeIdentifier ("_iter"), target
);
1683 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1685 // TODO check that parameter is not NULL (out parameters are optional)
1686 // free value if parameter is NULL
1687 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier (param
.name
)), target
)));
1690 if (array_type
!= null) {
1691 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1692 // TODO check that parameter is not NULL (out parameters are optional)
1693 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("%s_length%d".printf (param
.name
, dim
))), new
CCodeIdentifier ("_%s_length%d".printf (param
.name
, dim
)))));
1699 if (!(m
.return_type is VoidType
)) {
1700 if (m
.return_type
.is_real_non_null_struct_type ()) {
1701 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
1702 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1703 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1705 cdecl
= new
CCodeDeclaration (m
.return_type
.get_cname ());
1706 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
1707 postfragment
.append (cdecl
);
1709 var array_type
= m
.return_type as ArrayType
;
1711 if (array_type
!= null) {
1712 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1713 cdecl
= new
CCodeDeclaration ("int");
1714 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
1715 postfragment
.append (cdecl
);
1719 var target
= new
CCodeIdentifier ("_result");
1720 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1721 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1723 if (array_type
!= null) {
1724 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1725 // TODO check that parameter is not NULL (out parameters are optional)
1726 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length%d".printf (dim
))), new
CCodeIdentifier ("_result_length%d".printf (dim
)))));
1733 void check_error_reply (Method m
, CCodeBlock block
) {
1734 var error_types
= m
.get_error_types ();
1735 if (!has_dbus_error (error_types
)) {
1736 Report
.error (m
.source_reference
, "D-Bus methods must throw DBus.Error");
1740 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1742 var error_block
= new
CCodeBlock ();
1744 var cdecl
= new
CCodeDeclaration ("GQuark");
1745 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_edomain"));
1746 error_block
.add_statement (cdecl
);
1748 cdecl
= new
CCodeDeclaration ("gint");
1749 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_ecode"));
1750 error_block
.add_statement (cdecl
);
1752 generate_client_error_cases (error_block
, error_types
, new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "name"), new
CCodeIdentifier ("_edomain"), new
CCodeIdentifier ("_ecode"));
1754 var g_set_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1755 g_set_error
.add_argument (new
CCodeIdentifier ("error"));
1756 g_set_error
.add_argument (new
CCodeIdentifier ("_edomain"));
1757 g_set_error
.add_argument (new
CCodeIdentifier ("_ecode"));
1758 g_set_error
.add_argument (new
CCodeConstant ("\"%s\""));
1759 g_set_error
.add_argument (new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "message"));
1760 error_block
.add_statement (new
CCodeExpressionStatement (g_set_error
));
1762 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
1763 dbus_error_free
.add_argument (dbus_error
);
1764 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
1766 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1767 error_block
.add_statement (new
CCodeReturnStatement ());
1769 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1772 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
1773 dbus_error_is_set
.add_argument (dbus_error
);
1774 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
1777 string generate_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1778 string proxy_name
= "%sdbus_proxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1780 string dbus_iface_name
= get_dbus_name (iface
);
1782 CCodeDeclaration cdecl
;
1784 var function
= new
CCodeFunction (proxy_name
);
1785 function
.modifiers
= CCodeModifiers
.STATIC
;
1787 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1789 generate_cparameters (m
, source_declarations
, cparam_map
, function
);
1791 var block
= new
CCodeBlock ();
1792 var prefragment
= new
CCodeFragment ();
1793 var postfragment
= new
CCodeFragment ();
1795 // throw error and return if proxy is disposed
1796 var dispose_return_block
= new
CCodeBlock ();
1797 if (m
.get_error_types ().size
> 0) {
1798 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1799 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1800 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1801 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
1802 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1803 set_error_call
.add_argument (new
CCodeConstant ("\"Connection is closed\""));
1804 dispose_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1806 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1807 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1809 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1811 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
1813 cdecl
= new
CCodeDeclaration ("DBusError");
1814 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1815 block
.add_statement (cdecl
);
1817 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1819 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1820 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1821 block
.add_statement (cdecl
);
1823 cdecl
= new
CCodeDeclaration ("DBusMessage");
1824 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1825 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1826 block
.add_statement (cdecl
);
1828 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1829 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1830 block
.add_statement (cdecl
);
1832 block
.add_statement (prefragment
);
1834 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
1836 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1837 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1838 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1839 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1840 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1841 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1843 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1844 dbus_error_init
.add_argument (dbus_error
);
1845 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1847 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1848 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1850 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1851 ccall
.add_argument (connection
);
1852 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1853 ccall
.add_argument (get_dbus_timeout (m
));
1854 ccall
.add_argument (dbus_error
);
1855 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1857 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1858 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1859 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1861 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1862 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1863 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1865 check_error_reply (m
, block
);
1866 check_reply_signature (m
, block
);
1868 block
.add_statement (postfragment
);
1870 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1871 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1872 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1874 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
1875 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1878 source_declarations
.add_type_member_declaration (function
.copy ());
1879 function
.block
= block
;
1880 source_type_member_definition
.append (function
);
1885 void generate_client_error_cases (CCodeBlock error_block
, List
<DataType
> error_types
, CCodeExpression dbus_error_name
, CCodeExpression result_edomain
, CCodeExpression result_ecode
) {
1886 CCodeStatement if_else_if
= null;
1887 CCodeIfStatement last_statement
= null;
1889 foreach (DataType error_type
in error_types
) {
1890 var edomain
= ((ErrorType
) error_type
).error_domain
;
1892 if (edomain
== null) {
1893 Report
.error (error_type
.source_reference
, "Generic errors cannot be serialized over DBus");
1897 var edomain_dbus_name
= get_dbus_name (edomain
);
1898 if (edomain_dbus_name
== null) {
1899 Report
.error (edomain
.source_reference
, "Errordomain must have a DBus.name annotation to be serialized over DBus");
1902 var true_block
= new
CCodeBlock ();
1903 true_block
.suppress_newline
= true;
1905 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
1907 var cdecl
= new
CCodeDeclaration ("const char*");
1908 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
1909 true_block
.add_statement (cdecl
);
1911 true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_edomain
, new
CCodeIdentifier (edomain
.get_upper_case_cname ()))));
1913 true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier (temp_name
), new
CCodeBinaryExpression (CCodeBinaryOperator
.PLUS
, dbus_error_name
, new
CCodeConstant ("%ld".printf (edomain_dbus_name
.length
+ 1))))));
1915 CCodeStatement inner_if_else_if
= null;
1916 CCodeIfStatement inner_last_statement
= null;
1917 foreach (ErrorCode ecode
in edomain
.get_codes ()) {
1918 var inner_true_block
= new
CCodeBlock ();
1919 inner_true_block
.suppress_newline
= true;
1920 inner_true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_ecode
, new
CCodeIdentifier (ecode
.get_cname ()))));
1922 var ecode_dbus_name
= get_dbus_name (ecode
);
1923 if (ecode_dbus_name
== null) {
1924 ecode_dbus_name
= Symbol
.lower_case_to_camel_case (ecode
.name
.down ());
1927 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
1928 string_comparison
.add_argument (new
CCodeIdentifier (temp_name
));
1929 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (ecode_dbus_name
)));
1930 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, new
CCodeConstant ("0")), inner_true_block
);
1932 if (inner_last_statement
!= null) {
1933 inner_last_statement
.false_statement
= stmt
;
1935 inner_if_else_if
= stmt
;
1937 inner_last_statement
= stmt
;
1939 true_block
.add_statement (inner_if_else_if
);
1941 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strstr"));
1942 string_comparison
.add_argument (dbus_error_name
);
1943 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (edomain_dbus_name
)));
1944 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, dbus_error_name
), true_block
);
1946 if (last_statement
!= null) {
1947 last_statement
.false_statement
= stmt
;
1951 last_statement
= stmt
;
1953 error_block
.add_statement (if_else_if
);
1956 string generate_async_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1957 string proxy_name
= "%sdbus_proxy_%s_async".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1959 string dbus_iface_name
= get_dbus_name (iface
);
1961 CCodeDeclaration cdecl
;
1964 // generate data struct
1966 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
1967 var datastruct
= new
CCodeStruct ("_" + dataname
);
1969 datastruct
.add_field ("GAsyncReadyCallback", "_callback_");
1970 datastruct
.add_field ("gpointer", "_user_data_");
1971 datastruct
.add_field ("DBusPendingCall*", "pending");
1973 source_declarations
.add_type_definition (datastruct
);
1974 source_declarations
.add_type_declaration (new
CCodeTypeDefinition ("struct _" + dataname
, new
CCodeVariableDeclarator (dataname
)));
1977 // generate async function
1979 var function
= new
CCodeFunction (proxy_name
, "void");
1980 function
.modifiers
= CCodeModifiers
.STATIC
;
1982 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1984 cparam_map
.set (get_param_pos (-1), new
CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
1985 cparam_map
.set (get_param_pos (-0.9), new
CCodeFormalParameter ("_user_data_", "gpointer"));
1987 generate_cparameters (m
, source_declarations
, cparam_map
, function
, null, null, null, 1);
1989 var block
= new
CCodeBlock ();
1990 var prefragment
= new
CCodeFragment ();
1991 var postfragment
= new
CCodeFragment ();
1993 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1994 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1995 block
.add_statement (cdecl
);
1997 cdecl
= new
CCodeDeclaration ("DBusMessage");
1998 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1999 block
.add_statement (cdecl
);
2001 cdecl
= new
CCodeDeclaration ("DBusPendingCall");
2002 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_pending"));
2003 block
.add_statement (cdecl
);
2005 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2006 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2007 block
.add_statement (cdecl
);
2009 block
.add_statement (prefragment
);
2011 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2013 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2014 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2015 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2016 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2017 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2018 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2020 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2021 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2023 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply"));
2024 ccall
.add_argument (connection
);
2025 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2026 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_pending")));
2027 ccall
.add_argument (get_dbus_timeout (m
));
2028 block
.add_statement (new
CCodeExpressionStatement (ccall
));
2030 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2031 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2032 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2034 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2035 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2036 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2038 var dataalloc
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_new0"));
2039 dataalloc
.add_argument (new
CCodeIdentifier (dataname
));
2041 var datadecl
= new
CCodeDeclaration (dataname
+ "*");
2042 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2043 block
.add_statement (datadecl
);
2044 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), dataalloc
)));
2046 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"), new
CCodeIdentifier ("_callback_"))));
2047 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"), new
CCodeIdentifier ("_user_data_"))));
2048 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"), new
CCodeIdentifier ("_pending"))));
2050 var pending
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_set_notify"));
2051 pending
.add_argument (new
CCodeIdentifier ("_pending"));
2052 pending
.add_argument (new
CCodeIdentifier ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
)));
2053 pending
.add_argument (new
CCodeIdentifier ("_data_"));
2054 pending
.add_argument (new
CCodeConstant ("NULL"));
2055 block
.add_statement (new
CCodeExpressionStatement (pending
));
2057 source_declarations
.add_type_member_declaration (function
.copy ());
2058 function
.block
= block
;
2059 source_type_member_definition
.append (function
);
2062 // generate ready function
2064 function
= new
CCodeFunction ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
), "void");
2065 function
.modifiers
= CCodeModifiers
.STATIC
;
2067 function
.add_parameter (new
CCodeFormalParameter ("pending", "DBusPendingCall*"));
2068 function
.add_parameter (new
CCodeFormalParameter ("user_data", "void*"));
2070 block
= new
CCodeBlock ();
2072 datadecl
= new
CCodeDeclaration (dataname
+ "*");
2073 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2074 block
.add_statement (datadecl
);
2075 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), new
CCodeIdentifier ("user_data"))));
2077 // complete async call by invoking callback
2078 var obj_decl
= new
CCodeDeclaration ("GObject *");
2079 obj_decl
.add_declarator (new
CCodeVariableDeclarator ("_obj_"));
2080 block
.add_statement (obj_decl
);
2082 var object_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_newv"));
2083 object_creation
.add_argument (new
CCodeConstant ("G_TYPE_OBJECT"));
2084 object_creation
.add_argument (new
CCodeConstant ("0"));
2085 object_creation
.add_argument (new
CCodeConstant ("NULL"));
2086 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_obj_"), object_creation
)));
2088 var async_result_decl
= new
CCodeDeclaration ("GSimpleAsyncResult *");
2089 async_result_decl
.add_declarator (new
CCodeVariableDeclarator ("_res_"));
2090 block
.add_statement (async_result_decl
);
2092 var async_result_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_new"));
2093 async_result_creation
.add_argument (new
CCodeIdentifier ("_obj_"));
2094 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"));
2095 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"));
2096 async_result_creation
.add_argument (new
CCodeIdentifier ("_data_"));
2097 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_res_"), async_result_creation
)));
2099 var completecall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_complete"));
2100 completecall
.add_argument (new
CCodeIdentifier ("_res_"));
2101 block
.add_statement (new
CCodeExpressionStatement (completecall
));
2103 var obj_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2104 obj_free
.add_argument (new
CCodeIdentifier ("_obj_"));
2105 block
.add_statement (new
CCodeExpressionStatement (obj_free
));
2107 var async_result_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2108 async_result_free
.add_argument (new
CCodeIdentifier ("_res_"));
2109 block
.add_statement (new
CCodeExpressionStatement (async_result_free
));
2111 var datafree
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
2112 datafree
.add_argument (new
CCodeIdentifier (dataname
));
2113 datafree
.add_argument (new
CCodeIdentifier ("_data_"));
2114 block
.add_statement (new
CCodeExpressionStatement (datafree
));
2116 var pendingfree
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_unref"));
2117 pendingfree
.add_argument (new
CCodeIdentifier ("pending"));
2118 block
.add_statement (new
CCodeExpressionStatement (pendingfree
));
2120 source_declarations
.add_type_member_declaration (function
.copy ());
2121 function
.block
= block
;
2122 source_type_member_definition
.append (function
);
2128 CCodeConstant
get_reply_signature (Method m
) {
2129 // expected type signature for output parameters
2130 string type_signature
= "";
2132 foreach (FormalParameter param
in m
.get_parameters ()) {
2133 if (param
.direction
== ParameterDirection
.OUT
) {
2134 type_signature
+= get_type_signature (param
.parameter_type
);
2138 if (!(m
.return_type is VoidType
)) {
2139 type_signature
+= get_type_signature (m
.return_type
);
2142 return (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
2145 void check_reply_signature (Method m
, CCodeBlock block
) {
2146 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2147 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2149 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2150 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2152 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2153 signature_check
.add_argument (message_signature
);
2154 signature_check
.add_argument (get_reply_signature (m
));
2156 var signature_error_block
= new
CCodeBlock ();
2157 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
2158 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
2159 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
2160 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_INVALID_SIGNATURE"));
2161 set_error_call
.add_argument (new
CCodeConstant ("\"Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2162 set_error_call
.add_argument (get_reply_signature (m
));
2163 set_error_call
.add_argument (message_signature
);
2164 signature_error_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
2165 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2166 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
2168 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2171 string generate_finish_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
2172 string proxy_name
= "%sdbus_proxy_%s_finish".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
2174 string dbus_iface_name
= get_dbus_name (iface
);
2176 CCodeDeclaration cdecl
;
2178 var function
= new
CCodeFunction (proxy_name
);
2179 function
.modifiers
= CCodeModifiers
.STATIC
;
2181 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
2183 cparam_map
.set (get_param_pos (0.1), new
CCodeFormalParameter ("_res_", "GAsyncResult*"));
2185 generate_cparameters (m
, source_declarations
, cparam_map
, function
, null, null, null, 2);
2187 var block
= new
CCodeBlock ();
2188 var prefragment
= new
CCodeFragment ();
2189 var postfragment
= new
CCodeFragment ();
2191 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
2192 cdecl
= new
CCodeDeclaration (dataname
+ "*");
2193 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2194 block
.add_statement (cdecl
);
2196 cdecl
= new
CCodeDeclaration ("DBusError");
2197 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2198 block
.add_statement (cdecl
);
2200 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2202 cdecl
= new
CCodeDeclaration ("DBusMessage");
2203 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2204 block
.add_statement (cdecl
);
2206 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2207 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2208 block
.add_statement (cdecl
);
2210 var get_source_tag
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_get_source_tag"));
2211 get_source_tag
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("_res_"), "GSimpleAsyncResult *"));
2212 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), get_source_tag
)));
2214 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2215 dbus_error_init
.add_argument (dbus_error
);
2216 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2218 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_steal_reply"));
2219 ccall
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"));
2220 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2222 var set_error_from_message
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_set_error_from_message"));
2223 set_error_from_message
.add_argument (dbus_error
);
2224 set_error_from_message
.add_argument (new
CCodeIdentifier ("_reply"));
2225 block
.add_statement (new
CCodeExpressionStatement (set_error_from_message
));
2227 check_error_reply (m
, block
);
2228 check_reply_signature (m
, block
);
2230 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2232 block
.add_statement (postfragment
);
2234 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2235 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2236 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2238 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
2239 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2242 source_declarations
.add_type_member_declaration (function
.copy ());
2243 function
.block
= block
;
2244 source_type_member_definition
.append (function
);
2249 void check_property_error_reply (PropertyAccessor acc
, CCodeBlock block
) {
2250 var dbus_error
= new
CCodeIdentifier ("_dbus_error");
2251 var dbus_error_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, dbus_error
);
2253 var error_block
= new
CCodeBlock ();
2255 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2256 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: uncaught error: %s (%s)\""));
2257 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2258 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2259 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "message"));
2260 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "name"));
2262 error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2264 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
2265 dbus_error_free
.add_argument (dbus_error_ptr
);
2266 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
2268 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2269 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2271 error_block
.add_statement (new
CCodeReturnStatement ());
2274 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
2275 dbus_error_is_set
.add_argument (dbus_error_ptr
);
2276 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
2279 CCodeConstant
get_property_reply_signature (PropertyAccessor acc
) {
2281 return new
CCodeConstant ("\"v\"");
2283 return new
CCodeConstant ("\"\"");
2287 CCodeConstant
get_property_inner_signature (PropertyAccessor acc
) {
2288 return new
CCodeConstant ("\"%s\"".printf (get_type_signature (acc
.value_type
)));
2291 void check_property_reply_signature (PropertyAccessor acc
, CCodeBlock block
) {
2292 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2293 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2295 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2296 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2298 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2299 signature_check
.add_argument (message_signature
);
2300 signature_check
.add_argument (get_property_reply_signature (acc
));
2302 var signature_error_block
= new
CCodeBlock ();
2304 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2305 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2306 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2307 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2308 ccritical
.add_argument (get_property_reply_signature (acc
));
2309 ccritical
.add_argument (message_signature
);
2311 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2312 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2314 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2315 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2317 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2320 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2323 void check_property_inner_signature (PropertyAccessor acc
, CCodeFragment fragment
) {
2324 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2325 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2327 var iter_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_signature"));
2328 iter_signature
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2330 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2331 signature_check
.add_argument (iter_signature
);
2332 signature_check
.add_argument (get_property_inner_signature (acc
));
2334 var signature_error_block
= new
CCodeBlock ();
2336 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2337 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2338 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2339 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2340 ccritical
.add_argument (get_property_inner_signature (acc
));
2341 ccritical
.add_argument (iter_signature
);
2343 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2344 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2346 if (!acc
.value_type
.is_real_non_null_struct_type ()) {
2347 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2349 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2352 fragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
2355 string generate_dbus_proxy_property_get (Interface main_iface
, Interface iface
, Property prop
) {
2356 string proxy_name
= "%sdbus_proxy_get_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2358 string dbus_iface_name
= get_dbus_name (iface
);
2360 var owned_type
= prop
.get_accessor
.value_type
.copy ();
2361 owned_type
.value_owned
= true;
2362 if (owned_type
.is_disposable () && !prop
.get_accessor
.value_type
.value_owned
) {
2363 Report
.error (prop
.get_accessor
.value_type
.source_reference
, "Properties used in D-Bus clients require owned get accessor");
2366 var array_type
= prop
.get_accessor
.value_type as ArrayType
;
2368 CCodeDeclaration cdecl
;
2370 var function
= new
CCodeFunction (proxy_name
);
2371 function
.modifiers
= CCodeModifiers
.STATIC
;
2373 function
.add_parameter (new
CCodeFormalParameter ("self", "%s*".printf (iface
.get_cname ())));
2375 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2376 function
.add_parameter (new
CCodeFormalParameter ("result", "%s*".printf (prop
.get_accessor
.value_type
.get_cname ())));
2378 if (array_type
!= null) {
2379 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2380 function
.add_parameter (new
CCodeFormalParameter ("result_length%d".printf (dim
), "int*"));
2384 function
.return_type
= prop
.get_accessor
.value_type
.get_cname ();
2387 var block
= new
CCodeBlock ();
2388 var prefragment
= new
CCodeFragment ();
2389 var postfragment
= new
CCodeFragment ();
2391 var dispose_return_block
= new
CCodeBlock ();
2392 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2393 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2395 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (prop
.property_type
, false)));
2397 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2399 cdecl
= new
CCodeDeclaration ("DBusError");
2400 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2401 block
.add_statement (cdecl
);
2403 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2405 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2406 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2407 block
.add_statement (cdecl
);
2409 cdecl
= new
CCodeDeclaration ("DBusMessage");
2410 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2411 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2412 block
.add_statement (cdecl
);
2414 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2415 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2416 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2417 block
.add_statement (cdecl
);
2419 block
.add_statement (prefragment
);
2421 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2422 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2423 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2424 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2426 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2427 msgcall
.add_argument (destination
);
2428 msgcall
.add_argument (path
);
2429 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2430 msgcall
.add_argument (new
CCodeConstant ("\"Get\""));
2431 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2433 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2434 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2435 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2436 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2438 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2439 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2440 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2441 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2444 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2446 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2448 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
2449 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2450 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2451 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2453 check_property_inner_signature (prop
.get_accessor
, postfragment
);
2455 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2456 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
2457 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2458 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2460 cdecl
= new
CCodeDeclaration (prop
.get_accessor
.value_type
.get_cname ());
2461 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
2462 postfragment
.append (cdecl
);
2464 if (array_type
!= null) {
2465 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2466 cdecl
= new
CCodeDeclaration ("int");
2467 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
2468 postfragment
.append (cdecl
);
2472 var target
= new
CCodeIdentifier ("_result");
2473 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2474 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2476 if (array_type
!= null) {
2477 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2478 // TODO check that parameter is not NULL (out parameters are optional)
2479 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length%d".printf (dim
))), new
CCodeIdentifier ("_result_length%d".printf (dim
)))));
2484 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2485 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2486 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2487 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2488 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2489 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2491 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2492 dbus_error_init
.add_argument (dbus_error
);
2493 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2495 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2496 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2498 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2499 ccall
.add_argument (connection
);
2500 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2501 ccall
.add_argument (get_dbus_timeout (prop
));
2502 ccall
.add_argument (dbus_error
);
2503 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2505 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2506 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2507 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2509 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2510 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2511 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2513 check_property_error_reply (prop
.get_accessor
, block
);
2514 check_property_reply_signature (prop
.get_accessor
, block
);
2516 block
.add_statement (postfragment
);
2518 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2519 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2520 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2522 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2523 block
.add_statement (new
CCodeReturnStatement ());
2525 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2528 source_declarations
.add_type_member_declaration (function
.copy ());
2529 function
.block
= block
;
2530 source_type_member_definition
.append (function
);
2535 string generate_dbus_proxy_property_set (Interface main_iface
, Interface iface
, Property prop
) {
2536 string proxy_name
= "%sdbus_proxy_set_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2538 string dbus_iface_name
= get_dbus_name (iface
);
2540 var array_type
= prop
.set_accessor
.value_type as ArrayType
;
2542 CCodeDeclaration cdecl
;
2544 var function
= new
CCodeFunction (proxy_name
);
2545 function
.modifiers
= CCodeModifiers
.STATIC
;
2547 function
.add_parameter (new
CCodeFormalParameter ("self", "%s*".printf (iface
.get_cname ())));
2549 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2550 function
.add_parameter (new
CCodeFormalParameter ("value", "%s*".printf (prop
.set_accessor
.value_type
.get_cname ())));
2552 function
.add_parameter (new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname ()));
2554 if (array_type
!= null) {
2555 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2556 function
.add_parameter (new
CCodeFormalParameter ("value_length%d".printf (dim
), "int"));
2561 var block
= new
CCodeBlock ();
2562 var prefragment
= new
CCodeFragment ();
2563 var postfragment
= new
CCodeFragment ();
2565 var dispose_return_block
= new
CCodeBlock ();
2566 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2567 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2569 cdecl
= new
CCodeDeclaration ("DBusError");
2570 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2571 block
.add_statement (cdecl
);
2573 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2575 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2576 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2577 block
.add_statement (cdecl
);
2579 cdecl
= new
CCodeDeclaration ("DBusMessage");
2580 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2581 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2582 block
.add_statement (cdecl
);
2584 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2585 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2586 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2587 block
.add_statement (cdecl
);
2589 block
.add_statement (prefragment
);
2591 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2592 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2593 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2594 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2596 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2597 msgcall
.add_argument (destination
);
2598 msgcall
.add_argument (path
);
2599 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2600 msgcall
.add_argument (new
CCodeConstant ("\"Set\""));
2601 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2603 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2604 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2605 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2606 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2608 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2609 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2610 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2611 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2614 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2616 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2618 // property value (as variant)
2619 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
2620 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2621 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_VARIANT"));
2622 iter_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_type_signature (prop
.property_type
))));
2623 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2624 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2626 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2627 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("value")));
2629 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeIdentifier ("value"));
2632 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
2633 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2634 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2635 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2637 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2638 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2639 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2640 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2641 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2642 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2644 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2645 dbus_error_init
.add_argument (dbus_error
);
2646 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2648 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2649 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2651 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2652 ccall
.add_argument (connection
);
2653 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2654 ccall
.add_argument (get_dbus_timeout (prop
));
2655 ccall
.add_argument (dbus_error
);
2656 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2658 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2659 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2660 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2662 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2663 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2664 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2666 check_property_error_reply (prop
.set_accessor
, block
);
2667 check_property_reply_signature (prop
.set_accessor
, block
);
2669 block
.add_statement (postfragment
);
2671 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2672 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2673 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2675 source_declarations
.add_type_member_declaration (function
.copy ());
2676 function
.block
= block
;
2677 source_type_member_definition
.append (function
);