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 string get_dynamic_dbus_name (string vala_name
) {
34 // TODO switch default to no transformation as soon as we have static D-Bus client support
35 // keep transformation by default for static D-Bus client and server support
36 if (context
.dbus_transformation
) {
37 return Symbol
.lower_case_to_camel_case (vala_name
);
43 public CCodeConstant
get_dbus_timeout (Symbol symbol
) {
46 var dbus
= symbol
.get_attribute ("DBus");
47 if (dbus
!= null && dbus
.has_argument ("timeout")) {
48 timeout
= dbus
.get_integer ("timeout");
49 } else if (symbol
.parent_symbol
!= null) {
50 return get_dbus_timeout (symbol
.parent_symbol
);
53 return new
CCodeConstant (timeout
.to_string ());
56 public static bool is_dbus_no_reply (CodeNode node
) {
57 var dbus_attribute
= node
.get_attribute ("DBus");
58 if (dbus_attribute
!= null
59 && dbus_attribute
.has_argument ("no_reply")
60 && dbus_attribute
.get_bool ("no_reply")) {
67 bool has_dbus_error (List
<DataType
> error_types
) {
68 foreach (DataType error_type
in error_types
) {
69 if (((ErrorType
) error_type
).error_domain
.get_full_name () == "DBus.Error") {
76 public override void generate_dynamic_method_wrapper (DynamicMethod method
) {
77 var dynamic_method
= (DynamicMethod
) method
;
79 var func
= new
CCodeFunction (method
.get_cname ());
80 func
.modifiers
= CCodeModifiers
.STATIC
;
82 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
84 generate_cparameters (method
, cfile
, cparam_map
, func
);
86 var block
= new
CCodeBlock ();
87 if (dynamic_method
.dynamic_type
.data_type
== dbus_object_type
) {
88 generate_dbus_method_wrapper (method
, block
);
90 Report
.error (method
.source_reference
, "dynamic methods are not supported for `%s'".printf (dynamic_method
.dynamic_type
.to_string ()));
93 // append to C source file
94 cfile
.add_function_declaration (func
);
97 cfile
.add_function (func
);
100 void generate_dbus_method_wrapper (Method method
, CCodeBlock block
) {
101 var dynamic_method
= (DynamicMethod
) method
;
103 var expr
= dynamic_method
.invocation
;
105 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_begin_call"));
107 ccall
.add_argument (new
CCodeIdentifier ("self"));
109 bool found_out
= false;
110 Expression
callback = null;
111 int callback_index
= -1;
113 foreach (Expression arg
in expr
.get_argument_list ()) {
114 if (arg
.symbol_reference is Method
) {
116 if (callback != null) {
117 Report
.error (expr
.source_reference
, "only one reply callback may be specified in invocation of DBus method");
120 } else if (found_out
) {
121 Report
.error (expr
.source_reference
, "out argument and reply callback conflict in invocation of DBus method");
126 callback_index
= arg_index
;
127 } else if (arg is UnaryExpression
&& ((UnaryExpression
) arg
).operator
== UnaryOperator
.OUT
) {
129 if (callback != null) {
130 Report
.error (expr
.source_reference
, "out argument and reply callback conflict in invocation of DBus method");
137 if (callback != null || found_out
) {
138 Report
.error (expr
.source_reference
, "in argument must not follow out argument or reply callback in invocation of DBus method");
146 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (method
.name
))));
148 if (callback != null) {
149 var reply_method
= (Method
) callback.symbol_reference
;
151 var cb_fun
= new
CCodeFunction ("_%s_cb".printf (reply_method
.get_cname ()), "void");
152 cb_fun
.modifiers
= CCodeModifiers
.STATIC
;
153 cb_fun
.add_parameter (new
CCodeParameter ("proxy", "DBusGProxy*"));
154 cb_fun
.add_parameter (new
CCodeParameter ("call", "DBusGProxyCall*"));
155 cb_fun
.add_parameter (new
CCodeParameter ("user_data", "void*"));
156 cb_fun
.block
= new
CCodeBlock ();
157 var cerrdecl
= new
CCodeDeclaration ("GError*");
158 cerrdecl
.add_declarator (new
CCodeVariableDeclarator ("error", new
CCodeConstant ("NULL")));
159 cb_fun
.block
.add_statement (cerrdecl
);
160 var cend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_end_call"));
161 cend_call
.add_argument (new
CCodeIdentifier ("proxy"));
162 cend_call
.add_argument (new
CCodeIdentifier ("call"));
163 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("error")));
164 var creply_call
= new
CCodeFunctionCall (get_cvalue (callback));
165 if (reply_method
.binding
!= MemberBinding
.STATIC
) {
166 creply_call
.add_argument (new
CCodeIdentifier ("user_data"));
168 int param_count
= reply_method
.get_parameters ().size
;
170 foreach (Parameter param
in reply_method
.get_parameters ()) {
171 if ((++i
) == param_count
) {
172 if (!(param
.variable_type is ErrorType
)) {
173 Report
.error (null, "DBus reply callbacks must end with GLib.Error argument");
179 if (param
.variable_type is ArrayType
&& ((ArrayType
) param
.variable_type
).element_type
.data_type
!= string_type
.data_type
) {
180 var array_type
= (ArrayType
) param
.variable_type
;
181 CCodeDeclaration cdecl
;
182 if (dbus_use_ptr_array (array_type
)) {
183 cdecl
= new
CCodeDeclaration ("GPtrArray*");
185 cdecl
= new
CCodeDeclaration ("GArray*");
187 cdecl
.add_declarator (new
CCodeVariableDeclarator (param
.name
));
188 cb_fun
.block
.add_statement (cdecl
);
189 cend_call
.add_argument (get_dbus_g_type (array_type
));
190 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
191 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 ()));
192 creply_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), "len"));
194 var cdecl
= new
CCodeDeclaration (param
.variable_type
.get_cname ());
195 cdecl
.add_declarator (new
CCodeVariableDeclarator (param
.name
));
196 cb_fun
.block
.add_statement (cdecl
);
197 cend_call
.add_argument (get_dbus_g_type (param
.variable_type
));
198 cend_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
199 creply_call
.add_argument (new
CCodeIdentifier (param
.name
));
201 if (param
.variable_type is ArrayType
&& ((ArrayType
) param
.variable_type
).element_type
.data_type
== string_type
.data_type
) {
202 var cstrvlen
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strv_length"));
203 cstrvlen
.add_argument (new
CCodeIdentifier (param
.name
));
204 creply_call
.add_argument (cstrvlen
);
209 cend_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
210 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (cend_call
));
211 creply_call
.add_argument (new
CCodeIdentifier ("error"));
212 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (creply_call
));
214 CCodeExpression target
= new
CCodeConstant ("param%d_target".printf (callback_index
));
215 var ma
= (MemberAccess
) callback;
216 if (reply_method
.binding
!= MemberBinding
.STATIC
&& ma
.inner
.value_type
.data_type
!= null && ma
.inner
.value_type
.data_type
.is_reference_counting ()) {
217 // unref user_data after creply_call
218 var unref_call
= new
CCodeFunctionCall (get_destroy_func_expression (ma
.inner
.value_type
));
219 unref_call
.add_argument (new
CCodeIdentifier ("user_data"));
220 cb_fun
.block
.add_statement (new
CCodeExpressionStatement (unref_call
));
222 // ref target for ccall
223 var ref_call
= new
CCodeFunctionCall (get_dup_func_expression (ma
.inner
.value_type
, callback.source_reference
));
224 ref_call
.add_argument (target
);
228 if (!cfile
.add_declaration (cb_fun
.name
)) {
229 // avoid duplicate function definition
230 cfile
.add_function (cb_fun
);
233 ccall
.add_argument (new
CCodeIdentifier (cb_fun
.name
));
234 ccall
.add_argument (target
);
235 ccall
.add_argument (new
CCodeConstant ("NULL"));
237 ccall
.call
= new
CCodeIdentifier ("dbus_g_proxy_call");
239 ccall
.add_argument (new
CCodeIdentifier ("error"));
242 foreach (Parameter param
in method
.get_parameters ()) {
243 if (param
.variable_type is MethodType
244 || param
.variable_type is DelegateType
) {
245 // callback parameter
249 if (param
.direction
!= ParameterDirection
.IN
) {
253 var array_type
= param
.variable_type as ArrayType
;
254 if (array_type
!= null) {
256 if (array_type
.element_type
.data_type
!= string_type
.data_type
) {
257 // non-string arrays (use GArray)
258 ccall
.add_argument (get_dbus_g_type (array_type
));
260 var sizeof_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("sizeof"));
261 sizeof_call
.add_argument (new
CCodeIdentifier (array_type
.element_type
.get_cname ()));
263 CCodeDeclaration cdecl
;
264 CCodeFunctionCall array_construct
;
265 if (dbus_use_ptr_array (array_type
)) {
266 cdecl
= new
CCodeDeclaration ("GPtrArray*");
268 array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_ptr_array_sized_new"));
269 array_construct
.add_argument (new
CCodeIdentifier (get_parameter_array_length_cname (param
, 1)));
271 cdecl
= new
CCodeDeclaration ("GArray*");
273 array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_array_new"));
274 array_construct
.add_argument (new
CCodeConstant ("TRUE"));
275 array_construct
.add_argument (new
CCodeConstant ("TRUE"));
276 array_construct
.add_argument (sizeof_call
);
279 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
), array_construct
));
280 block
.add_statement (cdecl
);
282 if (dbus_use_ptr_array (array_type
)) {
283 cfile
.add_include ("string.h");
285 var memcpy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("memcpy"));
286 memcpy_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)), "pdata"));
287 memcpy_call
.add_argument (new
CCodeIdentifier (param
.name
));
288 memcpy_call
.add_argument (new
CCodeBinaryExpression (CCodeBinaryOperator
.MUL
, new
CCodeIdentifier (get_parameter_array_length_cname (param
, 1)), sizeof_call
));
289 block
.add_statement (new
CCodeExpressionStatement (memcpy_call
));
291 var len_assignment
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)), "len"), new
CCodeIdentifier (get_parameter_array_length_cname (param
, 1)));
292 block
.add_statement (new
CCodeExpressionStatement (len_assignment
));
294 var cappend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_array_append_vals"));
295 cappend_call
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
296 cappend_call
.add_argument (new
CCodeIdentifier (param
.name
));
297 cappend_call
.add_argument (new
CCodeIdentifier (get_parameter_array_length_cname (param
, 1)));
298 block
.add_statement (new
CCodeExpressionStatement (cappend_call
));
301 ccall
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
304 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRV"));
305 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
307 } else if (get_type_signature (param
.variable_type
).has_prefix ("(")) {
309 var st
= (Struct
) param
.variable_type
.data_type
;
311 var array_construct
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_array_new"));
312 array_construct
.add_argument (new
CCodeConstant ("0"));
314 var cdecl
= new
CCodeDeclaration ("GValueArray*");
315 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
), array_construct
));
316 block
.add_statement (cdecl
);
318 foreach (Field f
in st
.get_fields ()) {
319 if (f
.binding
!= MemberBinding
.INSTANCE
) {
323 string val_name
= "val_%s_%s".printf (param
.name
, f
.name
);
325 // 0-initialize struct with struct initializer { 0 }
326 var cvalinit
= new
CCodeInitializerList ();
327 cvalinit
.append (new
CCodeConstant ("0"));
329 var cval_decl
= new
CCodeDeclaration ("GValue");
330 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero (val_name
, cvalinit
));
331 block
.add_statement (cval_decl
);
333 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (val_name
));
335 var cinit_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_init"));
336 cinit_call
.add_argument (val_ptr
);
337 cinit_call
.add_argument (new
CCodeIdentifier (f
.variable_type
.data_type
.get_type_id ()));
338 block
.add_statement (new
CCodeExpressionStatement (cinit_call
));
340 var cset_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.variable_type
.data_type
.get_set_value_function ()));
341 cset_call
.add_argument (val_ptr
);
342 cset_call
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), f
.name
));
343 block
.add_statement (new
CCodeExpressionStatement (cset_call
));
345 var cappend_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_array_append"));
346 cappend_call
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
347 cappend_call
.add_argument (val_ptr
);
348 block
.add_statement (new
CCodeExpressionStatement (cappend_call
));
351 ccall
.add_argument (get_dbus_g_type (param
.variable_type
));
352 ccall
.add_argument (new
CCodeIdentifier ("dbus_%s".printf (param
.name
)));
354 ccall
.add_argument (get_dbus_g_type (param
.variable_type
));
355 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
359 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
361 var out_marshalling_fragment
= new
CCodeFragment ();
363 foreach (Parameter param
in method
.get_parameters ()) {
364 if (param
.variable_type is MethodType
) {
365 // callback parameter
369 if (param
.direction
!= ParameterDirection
.OUT
) {
373 if (get_type_signature (param
.variable_type
).has_prefix ("(")) {
374 // struct output parameter
375 var st
= (Struct
) param
.variable_type
.data_type
;
377 var cdecl
= new
CCodeDeclaration ("GValueArray*");
378 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_%s".printf (param
.name
)));
379 block
.add_statement (cdecl
);
382 foreach (Field f
in st
.get_fields ()) {
383 if (f
.binding
!= MemberBinding
.INSTANCE
) {
387 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.variable_type
.data_type
.get_get_value_function ()));
388 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 ()))));
390 var converted_value
= cget_call
;
392 if (requires_copy (f
.variable_type
)) {
393 var dupexpr
= get_dup_func_expression (f
.variable_type
, expr
.source_reference
);
394 converted_value
= new
CCodeFunctionCall (dupexpr
);
395 converted_value
.add_argument (cget_call
);
398 var assign
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier (param
.name
), f
.name
), converted_value
);
399 out_marshalling_fragment
.append (new
CCodeExpressionStatement (assign
));
404 ccall
.add_argument (get_dbus_g_type (param
.variable_type
));
405 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("dbus_%s".printf (param
.name
))));
407 ccall
.add_argument (get_dbus_g_type (param
.variable_type
));
408 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
412 if (!(method
.return_type is VoidType
)) {
413 // synchronous D-Bus method call with reply
414 ccall
.add_argument (get_dbus_g_type (method
.return_type
));
416 var array_type
= method
.return_type as ArrayType
;
417 if (array_type
!= null && array_type
.element_type
.data_type
!= string_type
.data_type
) {
418 // non-string arrays (use GArray)
419 CCodeDeclaration cdecl
;
420 if (dbus_use_ptr_array (array_type
)) {
421 cdecl
= new
CCodeDeclaration ("GPtrArray*");
423 cdecl
= new
CCodeDeclaration ("GArray*");
425 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
426 block
.add_statement (cdecl
);
428 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
429 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
431 block
.add_statement (new
CCodeExpressionStatement (ccall
));
433 // don't access result when error occured
434 var creturnblock
= new
CCodeBlock ();
435 creturnblock
.add_statement (new
CCodeReturnStatement (default_value_for_type (method
.return_type
, false)));
436 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
437 block
.add_statement (cerrorif
);
439 block
.add_statement (out_marshalling_fragment
);
441 // *result_length1 = result->len;
442 var garray_length
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("result"), "len");
443 var result_length
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length1"));
444 var assign
= new
CCodeAssignment (result_length
, garray_length
);
445 block
.add_statement (new
CCodeExpressionStatement (assign
));
447 // return result->data;
448 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 ())));
449 } else if (method
.return_type
.is_real_non_null_struct_type ()) {
450 // structs are returned via out parameter
451 var st
= (Struct
) method
.return_type
.data_type
;
453 if (st
.get_full_name () == "GLib.Value") {
454 ccall
.add_argument (new
CCodeIdentifier ("result"));
455 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
457 block
.add_statement (new
CCodeExpressionStatement (ccall
));
459 var cdecl
= new
CCodeDeclaration ("GValueArray*");
460 cdecl
.add_declarator (new
CCodeVariableDeclarator ("dbus_result"));
461 block
.add_statement (cdecl
);
464 foreach (Field f
in st
.get_fields ()) {
465 if (f
.binding
!= MemberBinding
.INSTANCE
) {
469 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (f
.variable_type
.data_type
.get_get_value_function ()));
470 cget_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeElementAccess (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("dbus_result"), "values"), new
CCodeConstant (i
.to_string ()))));
472 var converted_value
= cget_call
;
474 if (requires_copy (f
.variable_type
)) {
475 var dupexpr
= get_dup_func_expression (f
.variable_type
, expr
.source_reference
);
476 converted_value
= new
CCodeFunctionCall (dupexpr
);
477 converted_value
.add_argument (cget_call
);
480 var assign
= new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("result"), f
.name
), converted_value
);
481 out_marshalling_fragment
.append (new
CCodeExpressionStatement (assign
));
486 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("dbus_result")));
487 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
489 block
.add_statement (new
CCodeExpressionStatement (ccall
));
492 // don't access result when error occured
493 var creturnblock
= new
CCodeBlock ();
494 creturnblock
.add_statement (new
CCodeReturnStatement ());
495 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
496 block
.add_statement (cerrorif
);
498 block
.add_statement (out_marshalling_fragment
);
500 // string arrays or other datatypes
501 var cdecl
= new
CCodeDeclaration (method
.return_type
.get_cname ());
502 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
503 block
.add_statement (cdecl
);
505 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
506 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
508 block
.add_statement (new
CCodeExpressionStatement (ccall
));
510 // don't access result when error occured
511 var creturnblock
= new
CCodeBlock ();
512 creturnblock
.add_statement (new
CCodeReturnStatement (default_value_for_type (method
.return_type
, false)));
513 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
514 block
.add_statement (cerrorif
);
516 block
.add_statement (out_marshalling_fragment
);
518 if (array_type
!= null) {
519 // special case string array
521 // *result_length1 = g_strv_length (result);
522 var cstrvlen
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strv_length"));
523 cstrvlen
.add_argument (new
CCodeIdentifier ("result"));
524 var result_length
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result_length1"));
525 var assign
= new
CCodeAssignment (result_length
, cstrvlen
);
526 block
.add_statement (new
CCodeExpressionStatement (assign
));
529 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
532 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
534 block
.add_statement (new
CCodeExpressionStatement (ccall
));
536 // don't access result when error occured
537 var creturnblock
= new
CCodeBlock ();
538 creturnblock
.add_statement (new
CCodeReturnStatement ());
539 var cerrorif
= new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("error")), creturnblock
);
540 block
.add_statement (cerrorif
);
542 block
.add_statement (out_marshalling_fragment
);
546 public override CCodeExpression
get_dbus_g_type (DataType data_type
) {
547 if (data_type is ArrayType
) {
548 var array_type
= data_type as ArrayType
;
549 if (array_type
.element_type
.data_type
== string_type
.data_type
) {
550 return new
CCodeIdentifier ("G_TYPE_STRV");
553 var carray_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_collection"));
554 if (dbus_use_ptr_array (array_type
)) {
555 carray_type
.add_argument (new
CCodeConstant ("\"GPtrArray\""));
557 carray_type
.add_argument (new
CCodeConstant ("\"GArray\""));
559 carray_type
.add_argument (get_dbus_g_type (array_type
.element_type
));
561 } else if (data_type
.data_type is Enum
) {
562 var en
= (Enum
) data_type
.data_type
;
564 return new
CCodeIdentifier ("G_TYPE_UINT");
566 return new
CCodeIdentifier ("G_TYPE_INT");
568 } else if (data_type
.data_type
== null) {
569 critical ("Internal error during DBus type generation with: %s", data_type
.to_string ());
570 return new
CCodeIdentifier ("G_TYPE_NONE");
571 } else if (data_type
.data_type
.get_full_name () == "GLib.HashTable") {
572 var cmap_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_map"));
573 var type_args
= data_type
.get_type_arguments ();
575 cmap_type
.add_argument (new
CCodeConstant ("\"GHashTable\""));
576 foreach (DataType type_arg
in type_args
) {
577 cmap_type
.add_argument (get_dbus_g_type (type_arg
));
581 } else if (get_type_signature (data_type
).has_prefix ("(")) {
583 var st
= (Struct
) data_type
.data_type
;
585 var type_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_type_get_struct"));
586 type_call
.add_argument (new
CCodeConstant ("\"GValueArray\""));
588 foreach (Field f
in st
.get_fields ()) {
589 if (f
.binding
!= MemberBinding
.INSTANCE
) {
593 type_call
.add_argument (get_dbus_g_type (f
.variable_type
));
596 type_call
.add_argument (new
CCodeConstant ("G_TYPE_INVALID"));
600 return new
CCodeIdentifier (data_type
.data_type
.get_type_id ());
604 public bool dbus_use_ptr_array (ArrayType array_type
) {
605 if (array_type
.element_type
.data_type
== string_type
.data_type
) {
608 } else if (array_type
.element_type
.data_type
== bool_type
.data_type
609 || array_type
.element_type
.data_type
== char_type
.data_type
610 || array_type
.element_type
.data_type
== uchar_type
.data_type
611 || array_type
.element_type
.data_type
== int_type
.data_type
612 || array_type
.element_type
.data_type
== uint_type
.data_type
613 || array_type
.element_type
.data_type
== long_type
.data_type
614 || array_type
.element_type
.data_type
== ulong_type
.data_type
615 || array_type
.element_type
.data_type
== int8_type
.data_type
616 || array_type
.element_type
.data_type
== uint8_type
.data_type
617 || array_type
.element_type
.data_type
== int32_type
.data_type
618 || array_type
.element_type
.data_type
== uint32_type
.data_type
619 || array_type
.element_type
.data_type
== int64_type
.data_type
620 || array_type
.element_type
.data_type
== uint64_type
.data_type
621 || array_type
.element_type
.data_type
== double_type
.data_type
) {
630 public override string get_dynamic_property_getter_cname (DynamicProperty prop
) {
631 if (prop
.dynamic_type
.data_type
!= dbus_object_type
) {
632 return base.get_dynamic_property_getter_cname (prop
);
635 string getter_cname
= "_dynamic_get_%s%d".printf (prop
.name
, dynamic_property_id
++);
637 if (get_type_signature (prop
.property_type
) == null) {
638 Report
.error (prop
.property_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (prop
.property_type
.to_string ()));
642 var func
= new
CCodeFunction (getter_cname
, prop
.property_type
.get_cname ());
643 func
.modifiers
|= CCodeModifiers
.STATIC
| CCodeModifiers
.INLINE
;
645 func
.add_parameter (new
CCodeParameter ("obj", prop
.dynamic_type
.get_cname ()));
647 var block
= new
CCodeBlock ();
648 generate_dbus_property_getter_wrapper (prop
, block
);
650 // append to C source file
651 cfile
.add_function_declaration (func
);
654 cfile
.add_function (func
);
659 public override string get_dynamic_property_setter_cname (DynamicProperty prop
) {
660 if (prop
.dynamic_type
.data_type
!= dbus_object_type
) {
661 return base.get_dynamic_property_setter_cname (prop
);
664 string setter_cname
= "_dynamic_set_%s%d".printf (prop
.name
, dynamic_property_id
++);
666 if (get_type_signature (prop
.property_type
) == null) {
667 Report
.error (prop
.property_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (prop
.property_type
.to_string ()));
671 var func
= new
CCodeFunction (setter_cname
, "void");
672 func
.modifiers
|= CCodeModifiers
.STATIC
| CCodeModifiers
.INLINE
;
674 func
.add_parameter (new
CCodeParameter ("obj", prop
.dynamic_type
.get_cname ()));
675 func
.add_parameter (new
CCodeParameter ("value", prop
.property_type
.get_cname ()));
677 var block
= new
CCodeBlock ();
678 generate_dbus_property_setter_wrapper (prop
, block
);
680 // append to C source file
681 cfile
.add_function_declaration (func
);
684 cfile
.add_function (func
);
689 void create_dbus_property_proxy (DynamicProperty node
, CCodeBlock block
) {
690 var prop_proxy_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_new_from_proxy"));
691 prop_proxy_call
.add_argument (new
CCodeIdentifier ("obj"));
692 prop_proxy_call
.add_argument (new
CCodeConstant ("DBUS_INTERFACE_PROPERTIES"));
693 prop_proxy_call
.add_argument (new
CCodeConstant ("NULL"));
695 var prop_proxy_decl
= new
CCodeDeclaration ("DBusGProxy*");
696 prop_proxy_decl
.add_declarator (new
CCodeVariableDeclarator ("property_proxy", prop_proxy_call
));
697 block
.add_statement (prop_proxy_decl
);
700 void generate_dbus_property_getter_wrapper (DynamicProperty node
, CCodeBlock block
) {
701 create_dbus_property_proxy (node
, block
);
704 var cvalinit
= new
CCodeInitializerList ();
705 cvalinit
.append (new
CCodeConstant ("0"));
707 var cval_decl
= new
CCodeDeclaration ("GValue");
708 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero ("gvalue", cvalinit
));
709 block
.add_statement (cval_decl
);
711 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("gvalue"));
713 // call Get method on property proxy
714 var cdecl
= new
CCodeDeclaration (node
.property_type
.get_cname ());
715 cdecl
.add_declarator (new
CCodeVariableDeclarator ("result"));
716 block
.add_statement (cdecl
);
718 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_call"));
719 ccall
.add_argument (new
CCodeIdentifier ("property_proxy"));
720 ccall
.add_argument (new
CCodeConstant ("\"Get\""));
721 ccall
.add_argument (new
CCodeConstant ("NULL"));
723 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
724 var get_iface
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_interface"));
725 get_iface
.add_argument (new
CCodeIdentifier ("obj"));
726 ccall
.add_argument (get_iface
);
728 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
729 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node
.name
))));
731 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
733 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_VALUE"));
734 ccall
.add_argument (val_ptr
);
736 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
738 block
.add_statement (new
CCodeExpressionStatement (ccall
));
740 // unref property proxy
741 var prop_proxy_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
742 prop_proxy_unref
.add_argument (new
CCodeIdentifier ("property_proxy"));
743 block
.add_statement (new
CCodeExpressionStatement (prop_proxy_unref
));
745 // assign value to result variable
746 var cget_call
= new
CCodeFunctionCall (new
CCodeIdentifier (node
.property_type
.data_type
.get_get_value_function ()));
747 cget_call
.add_argument (val_ptr
);
748 var assign
= new
CCodeAssignment (new
CCodeIdentifier ("result"), cget_call
);
749 block
.add_statement (new
CCodeExpressionStatement (assign
));
752 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("result")));
755 void generate_dbus_property_setter_wrapper (DynamicProperty node
, CCodeBlock block
) {
756 create_dbus_property_proxy (node
, block
);
759 var cvalinit
= new
CCodeInitializerList ();
760 cvalinit
.append (new
CCodeConstant ("0"));
762 var cval_decl
= new
CCodeDeclaration ("GValue");
763 cval_decl
.add_declarator (new CCodeVariableDeclarator
.zero ("gvalue", cvalinit
));
764 block
.add_statement (cval_decl
);
766 var val_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("gvalue"));
768 var cinit_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_value_init"));
769 cinit_call
.add_argument (val_ptr
);
770 cinit_call
.add_argument (new
CCodeIdentifier (node
.property_type
.data_type
.get_type_id ()));
771 block
.add_statement (new
CCodeExpressionStatement (cinit_call
));
773 var cset_call
= new
CCodeFunctionCall (new
CCodeIdentifier (node
.property_type
.data_type
.get_set_value_function ()));
774 cset_call
.add_argument (val_ptr
);
775 cset_call
.add_argument (new
CCodeIdentifier ("value"));
776 block
.add_statement (new
CCodeExpressionStatement (cset_call
));
778 // call Set method on property proxy
779 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_call"));
780 ccall
.add_argument (new
CCodeIdentifier ("property_proxy"));
781 ccall
.add_argument (new
CCodeConstant ("\"Set\""));
782 ccall
.add_argument (new
CCodeConstant ("NULL"));
784 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
785 var get_iface
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_interface"));
786 get_iface
.add_argument (new
CCodeIdentifier ("obj"));
787 ccall
.add_argument (get_iface
);
789 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_STRING"));
790 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (node
.name
))));
792 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_VALUE"));
793 ccall
.add_argument (val_ptr
);
795 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
797 ccall
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
799 block
.add_statement (new
CCodeExpressionStatement (ccall
));
801 // unref property proxy
802 var prop_proxy_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
803 prop_proxy_unref
.add_argument (new
CCodeIdentifier ("property_proxy"));
804 block
.add_statement (new
CCodeExpressionStatement (prop_proxy_unref
));
807 public override string get_dynamic_signal_connect_wrapper_name (DynamicSignal sig
) {
808 if (sig
.dynamic_type
.data_type
!= dbus_object_type
) {
809 return base.get_dynamic_signal_connect_wrapper_name (sig
);
812 string connect_wrapper_name
= "_%sconnect".printf (get_dynamic_signal_cname (sig
));
813 var func
= new
CCodeFunction (connect_wrapper_name
, "void");
814 func
.add_parameter (new
CCodeParameter ("obj", "gpointer"));
815 func
.add_parameter (new
CCodeParameter ("signal_name", "const char *"));
816 func
.add_parameter (new
CCodeParameter ("handler", "GCallback"));
817 func
.add_parameter (new
CCodeParameter ("data", "gpointer"));
818 var block
= new
CCodeBlock ();
819 generate_dbus_connect_wrapper (sig
, block
);
821 // append to C source file
822 cfile
.add_function_declaration (func
);
825 cfile
.add_function (func
);
827 return connect_wrapper_name
;
830 public override string get_dynamic_signal_disconnect_wrapper_name (DynamicSignal sig
) {
831 if (sig
.dynamic_type
.data_type
!= dbus_object_type
) {
832 return base.get_dynamic_signal_disconnect_wrapper_name (sig
);
835 string disconnect_wrapper_name
= "_%sdisconnect".printf (get_dynamic_signal_cname (sig
));
836 var func
= new
CCodeFunction (disconnect_wrapper_name
, "void");
837 func
.add_parameter (new
CCodeParameter ("obj", "gpointer"));
838 func
.add_parameter (new
CCodeParameter ("signal_name", "const char *"));
839 func
.add_parameter (new
CCodeParameter ("handler", "GCallback"));
840 func
.add_parameter (new
CCodeParameter ("data", "gpointer"));
841 var block
= new
CCodeBlock ();
842 generate_dbus_disconnect_wrapper (sig
, block
);
844 // append to C source file
845 cfile
.add_function_declaration (func
);
848 cfile
.add_function (func
);
850 return disconnect_wrapper_name
;
853 void generate_dbus_connect_wrapper (DynamicSignal sig
, CCodeBlock block
) {
854 var m
= (Method
) sig
.handler
.symbol_reference
;
858 // FIXME should only be done once per marshaller
859 var register_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_object_register_marshaller"));
860 generate_marshaller (sig
.get_parameters (), sig
.return_type
, true);
861 register_call
.add_argument (new
CCodeIdentifier (get_marshaller_function (sig
.get_parameters (), sig
.return_type
, null, true)));
862 register_call
.add_argument (new
CCodeIdentifier ("G_TYPE_NONE"));
864 var add_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_add_signal"));
865 add_call
.add_argument (new
CCodeIdentifier ("obj"));
866 add_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
869 foreach (Parameter param
in m
.get_parameters ()) {
871 // skip sender parameter
876 register_call
.add_argument (get_dbus_g_type (param
.variable_type
));
877 add_call
.add_argument (get_dbus_g_type (param
.variable_type
));
879 register_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
880 add_call
.add_argument (new
CCodeIdentifier ("G_TYPE_INVALID"));
882 block
.add_statement (new
CCodeExpressionStatement (register_call
));
883 block
.add_statement (new
CCodeExpressionStatement (add_call
));
885 var call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_connect_signal"));
886 call
.add_argument (new
CCodeIdentifier ("obj"));
887 call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
888 call
.add_argument (new
CCodeIdentifier ("handler"));
889 call
.add_argument (new
CCodeIdentifier ("data"));
890 call
.add_argument (new
CCodeConstant ("NULL"));
891 block
.add_statement (new
CCodeExpressionStatement (call
));
894 void generate_dbus_disconnect_wrapper (DynamicSignal sig
, CCodeBlock block
) {
895 var call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_disconnect_signal"));
896 call
.add_argument (new
CCodeIdentifier ("obj"));
897 call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dynamic_dbus_name (sig
.name
))));
898 call
.add_argument (new
CCodeIdentifier ("handler"));
899 call
.add_argument (new
CCodeIdentifier ("data"));
900 block
.add_statement (new
CCodeExpressionStatement (call
));
903 public override void visit_cast_expression (CastExpression expr
) {
904 // handles casting DBus.Object instances to DBus interfaces
906 var type
= expr
.type_reference as ObjectType
;
907 var call
= expr
.inner as MethodCall
;
908 if (type
== null || !(type
.type_symbol is Interface
)
909 || type
.type_symbol
.get_attribute ("DBus") == null || call
== null) {
910 base.visit_cast_expression (expr
);
914 var mtype
= call
.call
.value_type as MethodType
;
915 if (mtype
== null || mtype
.method_symbol
.get_cname () != "dbus_g_proxy_new_for_name") {
916 base.visit_cast_expression (expr
);
920 var args
= call
.get_argument_list ();
921 Expression connection
= ((MemberAccess
) call
.call
).inner
;
922 Expression bus_name
= args
.get (0);
923 Expression object_path
= args
.get (1);
925 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (type
.type_symbol
.get_lower_case_cprefix () + "dbus_proxy_new"));
926 connection
.emit (this
);
927 ccall
.add_argument (get_cvalue (connection
));
928 bus_name
.emit (this
);
929 ccall
.add_argument (get_cvalue (bus_name
));
930 object_path
.emit (this
);
931 ccall
.add_argument (get_cvalue (object_path
));
932 set_cvalue (expr
, ccall
);
935 void generate_proxy_interface_init (Interface main_iface
, Interface iface
) {
936 // also generate proxy for prerequisites
937 foreach (var prereq
in iface
.get_prerequisites ()) {
938 if (prereq
.data_type is Interface
) {
939 generate_proxy_interface_init (main_iface
, (Interface
) prereq
.data_type
);
943 string lower_cname
= main_iface
.get_lower_case_cprefix () + "dbus_proxy";
945 var proxy_iface_init
= new
CCodeFunction (lower_cname
+ "_" + iface
.get_lower_case_cprefix () + "_interface_init", "void");
946 proxy_iface_init
.add_parameter (new
CCodeParameter ("iface", iface
.get_cname () + "Iface*"));
948 var iface_block
= new
CCodeBlock ();
950 foreach (Method m
in iface
.get_methods ()) {
951 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.vfunc_name
);
952 if (is_dbus_no_reply (m
)) {
954 Report
.error (m
.source_reference
, "No-reply DBus methods must not be async");
956 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_noreply_dbus_proxy_method (main_iface
, iface
, m
)))));
957 } else if (!m
.coroutine
) {
958 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_method (main_iface
, iface
, m
)))));
960 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_async_dbus_proxy_method (main_iface
, iface
, m
)))));
961 vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), m
.get_finish_vfunc_name ());
962 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_finish_dbus_proxy_method (main_iface
, iface
, m
)))));
966 foreach (Property prop
in iface
.get_properties ()) {
967 if (prop
.get_accessor
!= null) {
968 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "get_" + prop
.name
);
969 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_get (main_iface
, iface
, prop
)))));
971 if (prop
.set_accessor
!= null) {
972 var vfunc_entry
= new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("iface"), "set_" + prop
.name
);
973 iface_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (vfunc_entry
, new
CCodeIdentifier (generate_dbus_proxy_property_set (main_iface
, iface
, prop
)))));
977 proxy_iface_init
.modifiers
= CCodeModifiers
.STATIC
;
978 cfile
.add_function_declaration (proxy_iface_init
);
979 proxy_iface_init
.block
= iface_block
;
980 cfile
.add_function (proxy_iface_init
);
983 string implement_interface (CCodeFunctionCall define_type
, Interface main_iface
, Interface iface
) {
986 // also implement prerequisites
987 foreach (var prereq
in iface
.get_prerequisites ()) {
988 if (prereq
.data_type is Interface
) {
989 result
+= implement_interface (define_type
, main_iface
, (Interface
) prereq
.data_type
);
993 result
+= "G_IMPLEMENT_INTERFACE (%s, %sdbus_proxy_%s_interface_init) ".printf (
994 iface
.get_upper_case_cname ("TYPE_"),
995 main_iface
.get_lower_case_cprefix (),
996 iface
.get_lower_case_cprefix ());
1000 void implement_property (CCodeBlock block
, Interface main_iface
, Interface iface
) {
1001 // also implement prerequisites
1002 foreach (var prereq
in iface
.get_prerequisites ()) {
1003 if (prereq
.data_type is Interface
) {
1004 implement_property (block
, main_iface
, (Interface
) prereq
.data_type
);
1008 var gobject_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1009 gobject_class
.add_argument (new
CCodeIdentifier ("klass"));
1011 foreach (Property prop
in iface
.get_properties ()) {
1012 if (!prop
.is_abstract
) {
1016 if (!is_gobject_property (prop
)) {
1020 string prop_ev
= "%s_dbus_proxy_%s".printf (main_iface
.get_lower_case_cname (null), Symbol
.camel_case_to_lower_case (prop
.name
)).up ();
1022 var cinst
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_class_override_property"));
1023 cinst
.add_argument (gobject_class
);
1024 cinst
.add_argument (new
CCodeConstant (prop_ev
));
1025 cinst
.add_argument (prop
.get_canonical_cconstant ());
1026 block
.add_statement (new
CCodeExpressionStatement (cinst
));
1028 prop_enum
.add_value (new
CCodeEnumValue (prop_ev
));
1032 public override void generate_interface_declaration (Interface iface
, CCodeFile decl_space
) {
1033 base.generate_interface_declaration (iface
, decl_space
);
1035 string dbus_iface_name
= get_dbus_name (iface
);
1036 if (dbus_iface_name
== null) {
1040 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1042 if (add_symbol_declaration (decl_space
, iface
, lower_cname
+ "_new")) {
1046 decl_space
.add_include ("dbus/dbus-glib.h");
1048 // declare proxy_new function
1049 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1050 proxy_new
.add_parameter (new
CCodeParameter ("connection", "DBusGConnection*"));
1051 proxy_new
.add_parameter (new
CCodeParameter ("name", "const char*"));
1052 proxy_new
.add_parameter (new
CCodeParameter ("path", "const char*"));
1054 decl_space
.add_function_declaration (proxy_new
);
1057 public override void visit_interface (Interface iface
) {
1058 base.visit_interface (iface
);
1060 string dbus_iface_name
= get_dbus_name (iface
);
1061 if (dbus_iface_name
== null) {
1066 cfile
.add_include ("string.h");
1068 // create proxy class
1069 string cname
= iface
.get_cname () + "DBusProxy";
1070 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1072 add_dbus_helpers ();
1074 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cname
), new
CCodeVariableDeclarator (cname
)));
1075 cfile
.add_type_declaration (new
CCodeTypeDefinition ("DBusGProxyClass", new
CCodeVariableDeclarator (cname
+ "Class")));
1077 var instance_struct
= new
CCodeStruct ("_%s".printf (cname
));
1078 instance_struct
.add_field ("DBusGProxy", "parent_instance");
1079 instance_struct
.add_field ("gboolean", "disposed");
1081 cfile
.add_type_definition (instance_struct
);
1083 var type_fun
= new
CCodeFunction(lower_cname
+ "_get_type", "GType");
1084 type_fun
.attributes
= "G_GNUC_CONST";
1085 cfile
.add_function_declaration (type_fun
);
1087 var define_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_DEFINE_TYPE_EXTENDED"));
1088 define_type
.add_argument (new
CCodeIdentifier (cname
));
1089 define_type
.add_argument (new
CCodeIdentifier (lower_cname
));
1090 define_type
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_G_PROXY"));
1091 define_type
.add_argument (new
CCodeConstant ("0"));
1092 define_type
.add_argument (new
CCodeIdentifier (implement_interface (define_type
, iface
, iface
)));
1094 cfile
.add_type_member_definition (new
CCodeExpressionStatement (define_type
));
1096 // generate proxy_new function
1097 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1098 proxy_new
.add_parameter (new
CCodeParameter ("connection", "DBusGConnection*"));
1099 proxy_new
.add_parameter (new
CCodeParameter ("name", "const char*"));
1100 proxy_new
.add_parameter (new
CCodeParameter ("path", "const char*"));
1102 var new_block
= new
CCodeBlock ();
1104 // create proxy object
1105 var new_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1106 new_call
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier (lower_cname
+ "_get_type")));
1107 new_call
.add_argument (new
CCodeConstant ("\"connection\""));
1108 new_call
.add_argument (new
CCodeIdentifier ("connection"));
1109 new_call
.add_argument (new
CCodeConstant ("\"name\""));
1110 new_call
.add_argument (new
CCodeIdentifier ("name"));
1111 new_call
.add_argument (new
CCodeConstant ("\"path\""));
1112 new_call
.add_argument (new
CCodeIdentifier ("path"));
1113 new_call
.add_argument (new
CCodeConstant ("\"interface\""));
1114 new_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1115 new_call
.add_argument (new
CCodeConstant ("NULL"));
1117 var cdecl
= new
CCodeDeclaration (iface
.get_cname () + "*");
1118 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", new_call
));
1119 new_block
.add_statement (cdecl
);
1120 new_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1122 proxy_new
.block
= new_block
;
1123 cfile
.add_function (proxy_new
);
1125 // dbus proxy construct
1126 var proxy_construct
= new
CCodeFunction (lower_cname
+ "_construct", "GObject*");
1127 proxy_construct
.add_parameter (new
CCodeParameter ("gtype", "GType"));
1128 proxy_construct
.add_parameter (new
CCodeParameter ("n_properties", "guint"));
1129 proxy_construct
.add_parameter (new
CCodeParameter ("properties", "GObjectConstructParam*"));
1130 proxy_construct
.modifiers
= CCodeModifiers
.STATIC
;
1131 proxy_construct
.block
= new
CCodeBlock ();
1134 var parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1135 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1136 var chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "constructor"));
1137 chainup
.add_argument (new
CCodeIdentifier ("gtype"));
1138 chainup
.add_argument (new
CCodeIdentifier ("n_properties"));
1139 chainup
.add_argument (new
CCodeIdentifier ("properties"));
1141 cdecl
= new
CCodeDeclaration ("GObject*");
1142 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", chainup
));
1143 proxy_construct
.block
.add_statement (cdecl
);
1145 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1146 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1147 proxy_construct
.block
.add_statement (cdecl
);
1149 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1150 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1151 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1152 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1153 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1154 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1156 cdecl
= new
CCodeDeclaration ("char*");
1157 cdecl
.add_declarator (new
CCodeVariableDeclarator ("path"));
1158 proxy_construct
.block
.add_statement (cdecl
);
1160 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1161 path
.add_argument (new
CCodeIdentifier ("self"));
1162 path
.add_argument (new
CCodeConstant ("\"path\""));
1163 path
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("path")));
1164 path
.add_argument (new
CCodeConstant ("NULL"));
1165 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path
));
1167 var raw_connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1168 raw_connection
.add_argument (new
CCodeIdentifier ("connection"));
1170 // add filter to handle signals from the remote object
1171 var filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_add_filter"));
1172 filter_call
.add_argument (raw_connection
);
1173 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1174 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1175 filter_call
.add_argument (new
CCodeConstant ("NULL"));
1176 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1178 var filter_printf
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup_printf"));
1179 filter_printf
.add_argument (new
CCodeConstant ("\"type='signal',path='%s'\""));
1180 filter_printf
.add_argument (new
CCodeIdentifier ("path"));
1182 cdecl
= new
CCodeDeclaration ("char*");
1183 cdecl
.add_declarator (new
CCodeVariableDeclarator ("filter", filter_printf
));
1184 proxy_construct
.block
.add_statement (cdecl
);
1186 // ensure we receive signals from the remote object
1187 var match_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_bus_add_match"));
1188 match_call
.add_argument (raw_connection
);
1189 match_call
.add_argument (new
CCodeIdentifier ("filter"));
1190 match_call
.add_argument (new
CCodeConstant ("NULL"));
1191 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (match_call
));
1193 var connection_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1194 connection_free
.add_argument (new
CCodeIdentifier ("connection"));
1195 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (connection_free
));
1197 var path_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1198 path_free
.add_argument (new
CCodeIdentifier ("path"));
1199 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path_free
));
1201 var filter_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1202 filter_free
.add_argument (new
CCodeIdentifier ("filter"));
1203 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_free
));
1205 proxy_construct
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1207 cfile
.add_function (proxy_construct
);
1209 // dbus proxy filter function
1210 generate_proxy_filter_function (iface
);
1212 // dbus proxy dispose
1213 var proxy_dispose
= new
CCodeFunction (lower_cname
+ "_dispose", "void");
1214 proxy_dispose
.add_parameter (new
CCodeParameter ("self", "GObject*"));
1215 proxy_dispose
.modifiers
= CCodeModifiers
.STATIC
;
1216 proxy_dispose
.block
= new
CCodeBlock ();
1218 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1219 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1220 proxy_dispose
.block
.add_statement (cdecl
);
1222 // return if proxy is already disposed
1223 var dispose_return_block
= new
CCodeBlock ();
1224 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1225 proxy_dispose
.block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), dispose_return_block
));
1227 // mark proxy as disposed
1228 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), new
CCodeConstant ("TRUE"))));
1230 gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1231 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1232 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1233 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1234 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1235 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1238 filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_remove_filter"));
1239 filter_call
.add_argument (raw_connection
);
1240 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1241 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1242 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1245 parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1246 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1247 chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "dispose"));
1248 chainup
.add_argument (new
CCodeIdentifier ("self"));
1249 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (chainup
));
1251 cfile
.add_function (proxy_dispose
);
1253 var proxy_class_init
= new
CCodeFunction (lower_cname
+ "_class_init", "void");
1254 proxy_class_init
.add_parameter (new
CCodeParameter ("klass", cname
+ "Class*"));
1255 proxy_class_init
.modifiers
= CCodeModifiers
.STATIC
;
1256 proxy_class_init
.block
= new
CCodeBlock ();
1257 var gobject_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1258 gobject_class
.add_argument (new
CCodeIdentifier ("klass"));
1259 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "constructor"), new
CCodeIdentifier (lower_cname
+ "_construct"))));
1260 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "dispose"), new
CCodeIdentifier (lower_cname
+ "_dispose"))));
1261 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "get_property"), new
CCodeIdentifier ("_vala_%s_get_property".printf (lower_cname
)))));
1262 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "set_property"), new
CCodeIdentifier ("_vala_%s_set_property".printf (lower_cname
)))));
1263 cfile
.add_function (proxy_class_init
);
1265 prop_enum
= new
CCodeEnum ();
1266 prop_enum
.add_value (new
CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (lower_cname
.up ())));
1268 implement_property (proxy_class_init
.block
, iface
, iface
);
1270 cfile
.add_type_member_declaration (prop_enum
);
1272 var proxy_instance_init
= new
CCodeFunction (lower_cname
+ "_init", "void");
1273 proxy_instance_init
.add_parameter (new
CCodeParameter ("self", cname
+ "*"));
1274 proxy_instance_init
.modifiers
= CCodeModifiers
.STATIC
;
1275 proxy_instance_init
.block
= new
CCodeBlock ();
1276 cfile
.add_function (proxy_instance_init
);
1278 generate_proxy_interface_init (iface
, iface
);
1280 // dbus proxy get/set_property stubs
1281 // TODO add actual implementation
1282 var get_prop
= new
CCodeFunction ("_vala_%s_get_property".printf (lower_cname
), "void");
1283 get_prop
.modifiers
= CCodeModifiers
.STATIC
;
1284 get_prop
.add_parameter (new
CCodeParameter ("object", "GObject *"));
1285 get_prop
.add_parameter (new
CCodeParameter ("property_id", "guint"));
1286 get_prop
.add_parameter (new
CCodeParameter ("value", "GValue *"));
1287 get_prop
.add_parameter (new
CCodeParameter ("pspec", "GParamSpec *"));
1288 cfile
.add_function_declaration (get_prop
);
1289 get_prop
.block
= new
CCodeBlock ();
1290 cfile
.add_function (get_prop
);
1292 var set_prop
= new
CCodeFunction ("_vala_%s_set_property".printf (lower_cname
), "void");
1293 set_prop
.modifiers
= CCodeModifiers
.STATIC
;
1294 set_prop
.add_parameter (new
CCodeParameter ("object", "GObject *"));
1295 set_prop
.add_parameter (new
CCodeParameter ("property_id", "guint"));
1296 set_prop
.add_parameter (new
CCodeParameter ("value", "const GValue *"));
1297 set_prop
.add_parameter (new
CCodeParameter ("pspec", "GParamSpec *"));
1298 cfile
.add_function_declaration (set_prop
);
1299 set_prop
.block
= new
CCodeBlock ();
1300 cfile
.add_function (set_prop
);
1303 public override TypeRegisterFunction
create_interface_register_function (Interface iface
) {
1304 string dbus_iface_name
= get_dbus_name (iface
);
1305 if (dbus_iface_name
== null) {
1306 return new
InterfaceRegisterFunction (iface
, context
);
1309 return new
DBusInterfaceRegisterFunction (iface
, context
);
1312 string generate_get_all_function (Method m
) {
1313 string get_all_func
= "_dbus_g_proxy_get_all";
1315 if (!add_wrapper (get_all_func
)) {
1316 // wrapper already defined
1317 return get_all_func
;
1320 var function
= new
CCodeFunction (get_all_func
, "GHashTable*");
1321 function
.modifiers
= CCodeModifiers
.STATIC
;
1323 function
.add_parameter (new
CCodeParameter ("self", "DBusGProxy*"));
1324 function
.add_parameter (new
CCodeParameter ("interface_name", "const gchar*"));
1325 function
.add_parameter (new
CCodeParameter ("error", "GError**"));
1327 var block
= new
CCodeBlock ();
1328 var prefragment
= new
CCodeFragment ();
1329 var postfragment
= new
CCodeFragment ();
1331 var cdecl
= new
CCodeDeclaration ("DBusError");
1332 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1333 block
.add_statement (cdecl
);
1335 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1337 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1338 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1339 block
.add_statement (cdecl
);
1341 cdecl
= new
CCodeDeclaration ("DBusMessage");
1342 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1343 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1344 block
.add_statement (cdecl
);
1346 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1347 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1348 block
.add_statement (cdecl
);
1350 block
.add_statement (prefragment
);
1352 generate_marshalling (m
, "org.freedesktop.DBus.Properties", prefragment
, postfragment
);
1354 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1355 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1356 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1357 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1358 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1359 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1361 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1362 dbus_error_init
.add_argument (dbus_error
);
1363 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1365 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1366 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1368 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1369 ccall
.add_argument (connection
);
1370 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1371 ccall
.add_argument (get_dbus_timeout (m
));
1372 ccall
.add_argument (dbus_error
);
1373 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1375 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1376 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1377 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1379 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1380 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1381 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1383 check_error_reply (m
, block
);
1384 check_reply_signature (m
, block
);
1386 block
.add_statement (postfragment
);
1388 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1389 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1390 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1392 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1394 cfile
.add_function_declaration (function
);
1396 function
.block
= block
;
1397 cfile
.add_function (function
);
1399 return get_all_func
;
1402 public override void visit_method_call (MethodCall expr
) {
1403 var mtype
= expr
.call
.value_type as MethodType
;
1404 bool proxy_new_from_type
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_new_from_type");
1405 bool proxy_get_all
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_get_all");
1406 if (!proxy_new_from_type
&& !proxy_get_all
) {
1407 base.visit_method_call (expr
);
1411 if (proxy_get_all
) {
1412 var ma
= expr
.call as MemberAccess
;
1413 var instance
= ma
.inner
;
1414 instance
.emit (this
);
1416 var args
= expr
.get_argument_list ();
1417 Expression interface_name
= args
.get (0);
1418 interface_name
.emit (this
);
1420 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_get_all_function (mtype
.method_symbol
)));
1421 ccall
.add_argument (get_cvalue (instance
));
1422 ccall
.add_argument (get_cvalue (interface_name
));
1424 current_method_inner_error
= true;
1425 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
1427 set_cvalue (expr
, ccall
);
1431 var args
= expr
.get_argument_list ();
1432 Expression connection
= ((MemberAccess
) expr
.call
).inner
;
1433 Expression bus_name
= args
.get (0);
1434 Expression object_path
= args
.get (1);
1435 Expression interface_name
= args
.get (2);
1436 Expression type
= args
.get (3);
1438 var quark_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_string"));
1439 quark_call
.add_argument (new
CCodeConstant ("\"ValaDBusInterfaceProxyType\""));
1441 var qdata_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
1443 qdata_call
.add_argument (get_cvalue (type
));
1444 qdata_call
.add_argument (quark_call
);
1446 var get_type_call
= new
CCodeFunctionCall (new
CCodeCastExpression (qdata_call
, "GType (*)(void)"));
1448 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1449 ccall
.add_argument (get_type_call
);
1450 ccall
.add_argument (new
CCodeConstant ("\"connection\""));
1451 connection
.emit (this
);
1452 ccall
.add_argument (get_cvalue (connection
));
1453 ccall
.add_argument (new
CCodeConstant ("\"name\""));
1454 bus_name
.emit (this
);
1455 ccall
.add_argument (get_cvalue (bus_name
));
1456 ccall
.add_argument (new
CCodeConstant ("\"path\""));
1457 object_path
.emit (this
);
1458 ccall
.add_argument (get_cvalue (object_path
));
1459 ccall
.add_argument (new
CCodeConstant ("\"interface\""));
1460 interface_name
.emit (this
);
1461 ccall
.add_argument (get_cvalue (interface_name
));
1462 ccall
.add_argument (new
CCodeConstant ("NULL"));
1463 set_cvalue (expr
, ccall
);
1466 void generate_proxy_filter_function (Interface iface
) {
1467 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1469 var proxy_filter
= new
CCodeFunction (lower_cname
+ "_filter", "DBusHandlerResult");
1470 proxy_filter
.add_parameter (new
CCodeParameter ("connection", "DBusConnection*"));
1471 proxy_filter
.add_parameter (new
CCodeParameter ("message", "DBusMessage*"));
1472 proxy_filter
.add_parameter (new
CCodeParameter ("user_data", "void*"));
1474 var filter_block
= new
CCodeBlock ();
1476 // only handle signals concering the object path
1477 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1478 path
.add_argument (new
CCodeIdentifier ("user_data"));
1480 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_has_path"));
1481 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1482 ccheck
.add_argument (path
);
1484 var object_filter_block
= new
CCodeBlock ();
1485 filter_block
.add_statement (new
CCodeIfStatement (ccheck
, object_filter_block
));
1487 handle_signals (iface
, object_filter_block
);
1489 filter_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED")));
1491 cfile
.add_function_declaration (proxy_filter
);
1492 proxy_filter
.block
= filter_block
;
1493 cfile
.add_function (proxy_filter
);
1496 string generate_dbus_signal_handler (Signal sig
, ObjectTypeSymbol sym
) {
1497 string wrapper_name
= "_dbus_handle_%s_%s".printf (sym
.get_lower_case_cname (), sig
.get_cname ());
1501 CCodeDeclaration cdecl
;
1503 var function
= new
CCodeFunction (wrapper_name
, "void");
1504 function
.modifiers
= CCodeModifiers
.STATIC
;
1506 function
.add_parameter (new
CCodeParameter ("self", sym
.get_cname () + "*"));
1507 function
.add_parameter (new
CCodeParameter ("connection", "DBusConnection*"));
1508 function
.add_parameter (new
CCodeParameter ("message", "DBusMessage*"));
1510 var block
= new
CCodeBlock ();
1511 var prefragment
= new
CCodeFragment ();
1512 var postfragment
= new
CCodeFragment ();
1514 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1515 cdecl
.add_declarator (new
CCodeVariableDeclarator ("iter"));
1516 block
.add_statement (cdecl
);
1518 block
.add_statement (prefragment
);
1520 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
1521 message_signature
.add_argument (new
CCodeIdentifier ("message"));
1522 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
1523 signature_check
.add_argument (message_signature
);
1524 var signature_error_block
= new
CCodeBlock ();
1525 signature_error_block
.add_statement (new
CCodeReturnStatement ());
1526 prefragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
1528 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1529 iter_call
.add_argument (new
CCodeIdentifier ("message"));
1530 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("iter")));
1531 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1533 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_emit_by_name"));
1534 ccall
.add_argument (new
CCodeIdentifier ("self"));
1535 ccall
.add_argument (sig
.get_canonical_cconstant ());
1537 // expected type signature for input parameters
1538 string type_signature
= "";
1540 foreach (Parameter param
in sig
.get_parameters ()) {
1541 var owned_type
= param
.variable_type
.copy ();
1542 owned_type
.value_owned
= true;
1544 cdecl
= new
CCodeDeclaration (owned_type
.get_cname ());
1545 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero (param
.name
, default_value_for_type (param
.variable_type
, true)));
1546 prefragment
.append (cdecl
);
1548 if (get_type_signature (param
.variable_type
) == null) {
1549 Report
.error (param
.variable_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (param
.variable_type
.to_string ()));
1553 var st
= param
.variable_type
.data_type as Struct
;
1554 if (st
!= null && !st
.is_simple_type ()) {
1555 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
1557 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
1560 if (param
.variable_type is ArrayType
) {
1561 var array_type
= (ArrayType
) param
.variable_type
;
1563 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1564 string length_cname
= get_parameter_array_length_cname (param
, dim
);
1566 cdecl
= new
CCodeDeclaration ("int");
1567 cdecl
.add_declarator (new
CCodeVariableDeclarator (length_cname
, new
CCodeConstant ("0")));
1568 prefragment
.append (cdecl
);
1569 ccall
.add_argument (new
CCodeIdentifier (length_cname
));
1573 type_signature
+= get_type_signature (param
.variable_type
);
1575 var target
= new
CCodeIdentifier (param
.name
);
1576 var expr
= read_expression (prefragment
, param
.variable_type
, new
CCodeIdentifier ("iter"), target
);
1577 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1579 if (requires_destroy (owned_type
)) {
1580 // keep local alive (symbol_reference is weak)
1581 var local
= new
LocalVariable (owned_type
, param
.name
);
1582 var ma
= new MemberAccess
.simple (param
.name
);
1583 ma
.symbol_reference
= local
;
1584 ma
.value_type
= owned_type
.copy ();
1585 visit_member_access (ma
);
1586 var stmt
= new
CCodeExpressionStatement (get_unref_expression (new
CCodeIdentifier (param
.name
), owned_type
, ma
));
1587 postfragment
.append (stmt
);
1591 signature_check
.add_argument (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
1593 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1595 block
.add_statement (postfragment
);
1597 cdecl
= new
CCodeDeclaration ("DBusMessage*");
1598 cdecl
.add_declarator (new
CCodeVariableDeclarator ("reply"));
1599 block
.add_statement (cdecl
);
1601 cfile
.add_function_declaration (function
);
1603 function
.block
= block
;
1604 cfile
.add_function (function
);
1606 return wrapper_name
;
1609 void handle_signal (string dbus_iface_name
, string dbus_signal_name
, string handler_name
, CCodeBlock block
, ref CCodeIfStatement clastif
) {
1610 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_is_signal"));
1611 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1612 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1613 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_signal_name
)));
1615 var callblock
= new
CCodeBlock ();
1617 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (handler_name
));
1618 ccall
.add_argument (new
CCodeIdentifier ("user_data"));
1619 ccall
.add_argument (new
CCodeIdentifier ("connection"));
1620 ccall
.add_argument (new
CCodeIdentifier ("message"));
1622 callblock
.add_statement (new
CCodeExpressionStatement (ccall
));
1624 var cif
= new
CCodeIfStatement (ccheck
, callblock
);
1625 if (clastif
== null) {
1626 block
.add_statement (cif
);
1628 clastif
.false_statement
= cif
;
1634 void handle_signals (Interface iface
, CCodeBlock block
) {
1635 string dbus_iface_name
= get_dbus_name (iface
);
1637 CCodeIfStatement clastif
= null;
1638 foreach (Signal sig
in iface
.get_signals ()) {
1639 if (sig
.access
!= SymbolAccessibility
.PUBLIC
) {
1643 handle_signal (dbus_iface_name
, get_dbus_name_for_member (sig
), generate_dbus_signal_handler (sig
, iface
), block
, ref clastif
);
1647 void generate_marshalling (Method m
, string dbus_iface_name
, CCodeFragment prefragment
, CCodeFragment postfragment
) {
1648 CCodeDeclaration cdecl
;
1650 var no_reply
= is_dbus_no_reply (m
);
1652 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
1653 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1654 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1655 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1657 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
1658 msgcall
.add_argument (destination
);
1659 msgcall
.add_argument (path
);
1660 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1661 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m
))));
1662 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
1665 var noreplycall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_set_no_reply"));
1666 noreplycall
.add_argument (new
CCodeIdentifier ("_message"));
1667 noreplycall
.add_argument (new
CCodeConstant ("TRUE"));
1668 prefragment
.append (new
CCodeExpressionStatement (noreplycall
));
1671 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
1672 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
1673 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1674 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1677 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1678 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
1679 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1680 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
1683 foreach (Parameter param
in m
.get_parameters ()) {
1684 if (param
.direction
== ParameterDirection
.IN
) {
1685 if (param
.variable_type
.data_type
!= null
1686 && param
.variable_type
.data_type
.get_full_name () == "DBus.BusName") {
1687 // ignore BusName sender parameters
1690 CCodeExpression expr
= new
CCodeIdentifier (param
.name
);
1691 if (param
.variable_type
.is_real_struct_type ()) {
1692 expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, expr
);
1694 write_expression (prefragment
, param
.variable_type
, new
CCodeIdentifier ("_iter"), expr
);
1697 Report
.error (param
.source_reference
, "No-reply DBus methods must not have out parameters");
1700 cdecl
= new
CCodeDeclaration (param
.variable_type
.get_cname ());
1701 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_" + param
.name
));
1702 postfragment
.append (cdecl
);
1704 var array_type
= param
.variable_type as ArrayType
;
1706 if (array_type
!= null) {
1707 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1708 cdecl
= new
CCodeDeclaration ("int");
1709 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_length%d".printf (param
.name
, dim
), new
CCodeConstant ("0")));
1710 postfragment
.append (cdecl
);
1714 var target
= new
CCodeIdentifier ("_" + param
.name
);
1715 var expr
= read_expression (postfragment
, param
.variable_type
, new
CCodeIdentifier ("_iter"), target
);
1716 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1718 // TODO check that parameter is not NULL (out parameters are optional)
1719 // free value if parameter is NULL
1720 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier (param
.name
)), target
)));
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 ("%s_length%d".printf (param
.name
, dim
))), new
CCodeIdentifier ("_%s_length%d".printf (param
.name
, dim
)))));
1732 if (!(m
.return_type is VoidType
)) {
1734 Report
.error (m
.return_type
.source_reference
, "No-reply DBus methods must return void");
1736 if (m
.return_type
.is_real_non_null_struct_type ()) {
1737 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
1738 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1739 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1741 cdecl
= new
CCodeDeclaration (m
.return_type
.get_cname ());
1742 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
1743 postfragment
.append (cdecl
);
1745 var array_type
= m
.return_type as ArrayType
;
1747 if (array_type
!= null) {
1748 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1749 cdecl
= new
CCodeDeclaration ("int");
1750 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
1751 postfragment
.append (cdecl
);
1755 var target
= new
CCodeIdentifier ("_result");
1756 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1757 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1759 if (array_type
!= null) {
1760 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1761 // TODO check that parameter is not NULL (out parameters are optional)
1762 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
)))));
1769 void check_error_reply (Method m
, CCodeBlock block
) {
1770 var error_types
= m
.get_error_types ();
1771 if (!has_dbus_error (error_types
)) {
1772 Report
.error (m
.source_reference
, "D-Bus methods must throw DBus.Error");
1775 if (is_dbus_no_reply (m
)) {
1776 // no-reply messages throw no error
1780 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1782 var error_block
= new
CCodeBlock ();
1784 var cdecl
= new
CCodeDeclaration ("GQuark");
1785 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero ("_edomain", new
CCodeConstant ("0")));
1786 error_block
.add_statement (cdecl
);
1788 cdecl
= new
CCodeDeclaration ("gint");
1789 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero ("_ecode", new
CCodeConstant ("0")));
1790 error_block
.add_statement (cdecl
);
1792 generate_client_error_cases (error_block
, error_types
, new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "name"), new
CCodeIdentifier ("_edomain"), new
CCodeIdentifier ("_ecode"));
1794 var g_set_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1795 g_set_error
.add_argument (new
CCodeIdentifier ("error"));
1796 g_set_error
.add_argument (new
CCodeIdentifier ("_edomain"));
1797 g_set_error
.add_argument (new
CCodeIdentifier ("_ecode"));
1798 g_set_error
.add_argument (new
CCodeConstant ("\"%s\""));
1799 g_set_error
.add_argument (new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "message"));
1800 error_block
.add_statement (new
CCodeExpressionStatement (g_set_error
));
1802 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
1803 dbus_error_free
.add_argument (dbus_error
);
1804 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
1806 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1807 error_block
.add_statement (new
CCodeReturnStatement ());
1809 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1812 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
1813 dbus_error_is_set
.add_argument (dbus_error
);
1814 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
1817 string generate_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1818 string proxy_name
= "%sdbus_proxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1820 string dbus_iface_name
= get_dbus_name (iface
);
1822 CCodeDeclaration cdecl
;
1824 var function
= new
CCodeFunction (proxy_name
);
1825 function
.modifiers
= CCodeModifiers
.STATIC
;
1827 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
1829 generate_cparameters (m
, cfile
, cparam_map
, function
);
1831 var block
= new
CCodeBlock ();
1832 var prefragment
= new
CCodeFragment ();
1833 var postfragment
= new
CCodeFragment ();
1835 // throw error and return if proxy is disposed
1836 var dispose_return_block
= new
CCodeBlock ();
1837 if (m
.get_error_types ().size
> 0) {
1838 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1839 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1840 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1841 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
1842 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1843 set_error_call
.add_argument (new
CCodeConstant ("\"Connection is closed\""));
1844 dispose_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1846 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1847 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1849 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1851 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
1853 cdecl
= new
CCodeDeclaration ("DBusError");
1854 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1855 block
.add_statement (cdecl
);
1857 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1859 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1860 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1861 block
.add_statement (cdecl
);
1863 cdecl
= new
CCodeDeclaration ("DBusMessage");
1864 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1865 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1866 block
.add_statement (cdecl
);
1868 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1869 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1870 block
.add_statement (cdecl
);
1872 block
.add_statement (prefragment
);
1874 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
1876 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1877 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1878 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1879 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1880 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1881 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1883 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1884 dbus_error_init
.add_argument (dbus_error
);
1885 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1887 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1888 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1890 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1891 ccall
.add_argument (connection
);
1892 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1893 ccall
.add_argument (get_dbus_timeout (m
));
1894 ccall
.add_argument (dbus_error
);
1895 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1897 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1898 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1899 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1901 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1902 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1903 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1905 check_error_reply (m
, block
);
1906 check_reply_signature (m
, block
);
1908 block
.add_statement (postfragment
);
1910 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1911 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1912 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1914 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
1915 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1918 cfile
.add_function_declaration (function
);
1919 function
.block
= block
;
1920 cfile
.add_function (function
);
1925 string generate_noreply_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1926 string proxy_name
= "%sdbus_proxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1928 string dbus_iface_name
= get_dbus_name (iface
);
1930 CCodeDeclaration cdecl
;
1932 var function
= new
CCodeFunction (proxy_name
);
1933 function
.modifiers
= CCodeModifiers
.STATIC
;
1935 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
1937 generate_cparameters (m
, cfile
, cparam_map
, function
);
1939 var block
= new
CCodeBlock ();
1940 var prefragment
= new
CCodeFragment ();
1941 var postfragment
= new
CCodeFragment ();
1943 // throw error and return if proxy is disposed
1944 var dispose_return_block
= new
CCodeBlock ();
1945 if (m
.get_error_types ().size
> 0) {
1946 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1947 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1948 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1949 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
1950 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1951 set_error_call
.add_argument (new
CCodeConstant ("\"Connection is closed\""));
1952 dispose_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1953 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1955 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
1957 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1958 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1959 block
.add_statement (cdecl
);
1961 cdecl
= new
CCodeDeclaration ("DBusMessage");
1962 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1963 block
.add_statement (cdecl
);
1965 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1966 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1967 block
.add_statement (cdecl
);
1969 block
.add_statement (prefragment
);
1971 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
1973 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1974 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1975 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1976 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1977 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1978 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1980 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1981 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1983 var oom_return_block
= new
CCodeBlock ();
1984 if (m
.get_error_types ().size
> 0) {
1985 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1986 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1987 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1988 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_NO_MEMORY"));
1989 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1990 set_error_call
.add_argument (new
CCodeConstant ("\"Out of memory\""));
1991 oom_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1992 oom_return_block
.add_statement (new
CCodeReturnStatement ());
1995 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send"));
1996 ccall
.add_argument (connection
);
1997 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1998 ccall
.add_argument (new
CCodeConstant ("NULL"));
1999 block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, ccall
), oom_return_block
));
2001 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2002 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2003 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2005 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2006 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2007 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2009 check_error_reply (m
, block
);
2011 block
.add_statement (postfragment
);
2013 cfile
.add_function_declaration (function
);
2014 function
.block
= block
;
2015 cfile
.add_function (function
);
2020 void generate_client_error_cases (CCodeBlock error_block
, List
<DataType
> error_types
, CCodeExpression dbus_error_name
, CCodeExpression result_edomain
, CCodeExpression result_ecode
) {
2021 CCodeStatement if_else_if
= null;
2022 CCodeIfStatement last_statement
= null;
2024 foreach (DataType error_type
in error_types
) {
2025 var edomain
= ((ErrorType
) error_type
).error_domain
;
2027 if (edomain
== null) {
2028 Report
.error (error_type
.source_reference
, "Generic errors cannot be serialized over DBus");
2032 var edomain_dbus_name
= get_dbus_name (edomain
);
2033 if (edomain_dbus_name
== null) {
2034 Report
.error (edomain
.source_reference
, "Errordomain must have a DBus.name annotation to be serialized over DBus");
2037 var true_block
= new
CCodeBlock ();
2038 true_block
.suppress_newline
= true;
2040 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
2042 var cdecl
= new
CCodeDeclaration ("const char*");
2043 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
2044 true_block
.add_statement (cdecl
);
2046 true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_edomain
, new
CCodeIdentifier (edomain
.get_upper_case_cname ()))));
2048 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))))));
2050 CCodeStatement inner_if_else_if
= null;
2051 CCodeIfStatement inner_last_statement
= null;
2052 foreach (ErrorCode ecode
in edomain
.get_codes ()) {
2053 var inner_true_block
= new
CCodeBlock ();
2054 inner_true_block
.suppress_newline
= true;
2055 inner_true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_ecode
, new
CCodeIdentifier (ecode
.get_cname ()))));
2057 var ecode_dbus_name
= get_dbus_name (ecode
);
2058 if (ecode_dbus_name
== null) {
2059 ecode_dbus_name
= Symbol
.lower_case_to_camel_case (ecode
.name
.down ());
2062 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2063 string_comparison
.add_argument (new
CCodeIdentifier (temp_name
));
2064 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (ecode_dbus_name
)));
2065 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, new
CCodeConstant ("0")), inner_true_block
);
2067 if (inner_last_statement
!= null) {
2068 inner_last_statement
.false_statement
= stmt
;
2070 inner_if_else_if
= stmt
;
2072 inner_last_statement
= stmt
;
2074 true_block
.add_statement (inner_if_else_if
);
2076 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strstr"));
2077 string_comparison
.add_argument (dbus_error_name
);
2078 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (edomain_dbus_name
)));
2079 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, dbus_error_name
), true_block
);
2081 if (last_statement
!= null) {
2082 last_statement
.false_statement
= stmt
;
2086 last_statement
= stmt
;
2088 error_block
.add_statement (if_else_if
);
2091 string generate_async_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
2092 string proxy_name
= "%sdbus_proxy_%s_async".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
2094 string dbus_iface_name
= get_dbus_name (iface
);
2096 CCodeDeclaration cdecl
;
2099 // generate data struct
2101 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
2102 var datastruct
= new
CCodeStruct ("_" + dataname
);
2104 datastruct
.add_field ("GAsyncReadyCallback", "_callback_");
2105 datastruct
.add_field ("gpointer", "_user_data_");
2106 datastruct
.add_field ("DBusPendingCall*", "pending");
2108 cfile
.add_type_definition (datastruct
);
2109 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct _" + dataname
, new
CCodeVariableDeclarator (dataname
)));
2112 // generate async function
2114 var function
= new
CCodeFunction (proxy_name
, "void");
2115 function
.modifiers
= CCodeModifiers
.STATIC
;
2117 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
2119 cparam_map
.set (get_param_pos (-1), new
CCodeParameter ("_callback_", "GAsyncReadyCallback"));
2120 cparam_map
.set (get_param_pos (-0.9), new
CCodeParameter ("_user_data_", "gpointer"));
2122 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 1);
2124 var block
= new
CCodeBlock ();
2125 var prefragment
= new
CCodeFragment ();
2126 var postfragment
= new
CCodeFragment ();
2128 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2129 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2130 block
.add_statement (cdecl
);
2132 cdecl
= new
CCodeDeclaration ("DBusMessage");
2133 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2134 block
.add_statement (cdecl
);
2136 cdecl
= new
CCodeDeclaration ("DBusPendingCall");
2137 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_pending"));
2138 block
.add_statement (cdecl
);
2140 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2141 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2142 block
.add_statement (cdecl
);
2144 block
.add_statement (prefragment
);
2146 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2148 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2149 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2150 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2151 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2152 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2153 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2155 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2156 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2158 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply"));
2159 ccall
.add_argument (connection
);
2160 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2161 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_pending")));
2162 ccall
.add_argument (get_dbus_timeout (m
));
2163 block
.add_statement (new
CCodeExpressionStatement (ccall
));
2165 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2166 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2167 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2169 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2170 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2171 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2173 var dataalloc
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_new0"));
2174 dataalloc
.add_argument (new
CCodeIdentifier (dataname
));
2176 var datadecl
= new
CCodeDeclaration (dataname
+ "*");
2177 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2178 block
.add_statement (datadecl
);
2179 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), dataalloc
)));
2181 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"), new
CCodeIdentifier ("_callback_"))));
2182 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"), new
CCodeIdentifier ("_user_data_"))));
2183 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"), new
CCodeIdentifier ("_pending"))));
2185 var pending
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_set_notify"));
2186 pending
.add_argument (new
CCodeIdentifier ("_pending"));
2187 pending
.add_argument (new
CCodeIdentifier ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
)));
2188 pending
.add_argument (new
CCodeIdentifier ("_data_"));
2189 pending
.add_argument (new
CCodeConstant ("NULL"));
2190 block
.add_statement (new
CCodeExpressionStatement (pending
));
2192 cfile
.add_function_declaration (function
);
2193 function
.block
= block
;
2194 cfile
.add_function (function
);
2197 // generate ready function
2199 function
= new
CCodeFunction ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
), "void");
2200 function
.modifiers
= CCodeModifiers
.STATIC
;
2202 function
.add_parameter (new
CCodeParameter ("pending", "DBusPendingCall*"));
2203 function
.add_parameter (new
CCodeParameter ("user_data", "void*"));
2205 block
= new
CCodeBlock ();
2207 datadecl
= new
CCodeDeclaration (dataname
+ "*");
2208 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2209 block
.add_statement (datadecl
);
2210 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), new
CCodeIdentifier ("user_data"))));
2212 // complete async call by invoking callback
2213 var obj_decl
= new
CCodeDeclaration ("GObject *");
2214 obj_decl
.add_declarator (new
CCodeVariableDeclarator ("_obj_"));
2215 block
.add_statement (obj_decl
);
2217 var object_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_newv"));
2218 object_creation
.add_argument (new
CCodeConstant ("G_TYPE_OBJECT"));
2219 object_creation
.add_argument (new
CCodeConstant ("0"));
2220 object_creation
.add_argument (new
CCodeConstant ("NULL"));
2221 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_obj_"), object_creation
)));
2223 var async_result_decl
= new
CCodeDeclaration ("GSimpleAsyncResult *");
2224 async_result_decl
.add_declarator (new
CCodeVariableDeclarator ("_res_"));
2225 block
.add_statement (async_result_decl
);
2227 var async_result_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_new"));
2228 async_result_creation
.add_argument (new
CCodeIdentifier ("_obj_"));
2229 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"));
2230 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"));
2231 async_result_creation
.add_argument (new
CCodeIdentifier ("_data_"));
2232 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_res_"), async_result_creation
)));
2234 var completecall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_complete"));
2235 completecall
.add_argument (new
CCodeIdentifier ("_res_"));
2236 block
.add_statement (new
CCodeExpressionStatement (completecall
));
2238 var obj_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2239 obj_free
.add_argument (new
CCodeIdentifier ("_obj_"));
2240 block
.add_statement (new
CCodeExpressionStatement (obj_free
));
2242 var async_result_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2243 async_result_free
.add_argument (new
CCodeIdentifier ("_res_"));
2244 block
.add_statement (new
CCodeExpressionStatement (async_result_free
));
2246 var datafree
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
2247 datafree
.add_argument (new
CCodeIdentifier (dataname
));
2248 datafree
.add_argument (new
CCodeIdentifier ("_data_"));
2249 block
.add_statement (new
CCodeExpressionStatement (datafree
));
2251 var pendingfree
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_unref"));
2252 pendingfree
.add_argument (new
CCodeIdentifier ("pending"));
2253 block
.add_statement (new
CCodeExpressionStatement (pendingfree
));
2255 cfile
.add_function_declaration (function
);
2256 function
.block
= block
;
2257 cfile
.add_function (function
);
2263 CCodeConstant
get_reply_signature (Method m
) {
2264 // expected type signature for output parameters
2265 string type_signature
= "";
2267 foreach (Parameter param
in m
.get_parameters ()) {
2268 if (param
.direction
== ParameterDirection
.OUT
) {
2269 type_signature
+= get_type_signature (param
.variable_type
);
2273 if (!(m
.return_type is VoidType
)) {
2274 type_signature
+= get_type_signature (m
.return_type
);
2277 return (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
2280 void check_reply_signature (Method m
, CCodeBlock block
) {
2281 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2282 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2284 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2285 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2287 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2288 signature_check
.add_argument (message_signature
);
2289 signature_check
.add_argument (get_reply_signature (m
));
2291 var signature_error_block
= new
CCodeBlock ();
2292 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
2293 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
2294 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
2295 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_INVALID_SIGNATURE"));
2296 set_error_call
.add_argument (new
CCodeConstant ("\"Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2297 set_error_call
.add_argument (get_reply_signature (m
));
2298 set_error_call
.add_argument (message_signature
);
2299 signature_error_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
2300 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2301 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
2303 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2306 string generate_finish_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
2307 string proxy_name
= "%sdbus_proxy_%s_finish".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
2309 string dbus_iface_name
= get_dbus_name (iface
);
2311 CCodeDeclaration cdecl
;
2313 var function
= new
CCodeFunction (proxy_name
);
2314 function
.modifiers
= CCodeModifiers
.STATIC
;
2316 var cparam_map
= new HashMap
<int,CCodeParameter
> (direct_hash
, direct_equal
);
2318 cparam_map
.set (get_param_pos (0.1), new
CCodeParameter ("_res_", "GAsyncResult*"));
2320 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 2);
2322 var block
= new
CCodeBlock ();
2323 var prefragment
= new
CCodeFragment ();
2324 var postfragment
= new
CCodeFragment ();
2326 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
2327 cdecl
= new
CCodeDeclaration (dataname
+ "*");
2328 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2329 block
.add_statement (cdecl
);
2331 cdecl
= new
CCodeDeclaration ("DBusError");
2332 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2333 block
.add_statement (cdecl
);
2335 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2337 cdecl
= new
CCodeDeclaration ("DBusMessage");
2338 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2339 block
.add_statement (cdecl
);
2341 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2342 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2343 block
.add_statement (cdecl
);
2345 var get_source_tag
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_get_source_tag"));
2346 get_source_tag
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("_res_"), "GSimpleAsyncResult *"));
2347 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), get_source_tag
)));
2349 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2350 dbus_error_init
.add_argument (dbus_error
);
2351 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2353 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_steal_reply"));
2354 ccall
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"));
2355 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2357 var set_error_from_message
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_set_error_from_message"));
2358 set_error_from_message
.add_argument (dbus_error
);
2359 set_error_from_message
.add_argument (new
CCodeIdentifier ("_reply"));
2360 block
.add_statement (new
CCodeExpressionStatement (set_error_from_message
));
2362 check_error_reply (m
, block
);
2363 check_reply_signature (m
, block
);
2365 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2367 block
.add_statement (postfragment
);
2369 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2370 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2371 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2373 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
2374 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2377 cfile
.add_function_declaration (function
);
2378 function
.block
= block
;
2379 cfile
.add_function (function
);
2384 void check_property_error_reply (PropertyAccessor acc
, CCodeBlock block
) {
2385 var dbus_error
= new
CCodeIdentifier ("_dbus_error");
2386 var dbus_error_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, dbus_error
);
2388 var error_block
= new
CCodeBlock ();
2390 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2391 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: uncaught error: %s (%s)\""));
2392 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2393 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2394 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "message"));
2395 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "name"));
2397 error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2399 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
2400 dbus_error_free
.add_argument (dbus_error_ptr
);
2401 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
2403 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2404 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2406 error_block
.add_statement (new
CCodeReturnStatement ());
2409 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
2410 dbus_error_is_set
.add_argument (dbus_error_ptr
);
2411 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
2414 CCodeConstant
get_property_reply_signature (PropertyAccessor acc
) {
2416 return new
CCodeConstant ("\"v\"");
2418 return new
CCodeConstant ("\"\"");
2422 CCodeConstant
get_property_inner_signature (PropertyAccessor acc
) {
2423 return new
CCodeConstant ("\"%s\"".printf (get_type_signature (acc
.value_type
)));
2426 void check_property_reply_signature (PropertyAccessor acc
, CCodeBlock block
) {
2427 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2428 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2430 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2431 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2433 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2434 signature_check
.add_argument (message_signature
);
2435 signature_check
.add_argument (get_property_reply_signature (acc
));
2437 var signature_error_block
= new
CCodeBlock ();
2439 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2440 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2441 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2442 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2443 ccritical
.add_argument (get_property_reply_signature (acc
));
2444 ccritical
.add_argument (message_signature
);
2446 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2447 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2449 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2450 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2452 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2455 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2458 void check_property_inner_signature (PropertyAccessor acc
, CCodeFragment fragment
) {
2459 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2460 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2462 var iter_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_signature"));
2463 iter_signature
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2465 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2466 signature_check
.add_argument (iter_signature
);
2467 signature_check
.add_argument (get_property_inner_signature (acc
));
2469 var signature_error_block
= new
CCodeBlock ();
2471 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2472 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2473 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2474 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2475 ccritical
.add_argument (get_property_inner_signature (acc
));
2476 ccritical
.add_argument (iter_signature
);
2478 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2479 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2481 if (!acc
.value_type
.is_real_non_null_struct_type ()) {
2482 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2484 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2487 fragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
2490 string generate_dbus_proxy_property_get (Interface main_iface
, Interface iface
, Property prop
) {
2491 string proxy_name
= "%sdbus_proxy_get_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2493 string dbus_iface_name
= get_dbus_name (iface
);
2495 var owned_type
= prop
.get_accessor
.value_type
.copy ();
2496 owned_type
.value_owned
= true;
2497 if (owned_type
.is_disposable () && !prop
.get_accessor
.value_type
.value_owned
) {
2498 Report
.error (prop
.get_accessor
.value_type
.source_reference
, "Properties used in D-Bus clients require owned get accessor");
2501 var array_type
= prop
.get_accessor
.value_type as ArrayType
;
2503 CCodeDeclaration cdecl
;
2505 var function
= new
CCodeFunction (proxy_name
);
2506 function
.modifiers
= CCodeModifiers
.STATIC
;
2508 function
.add_parameter (new
CCodeParameter ("self", "%s*".printf (iface
.get_cname ())));
2510 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2511 function
.add_parameter (new
CCodeParameter ("result", "%s*".printf (prop
.get_accessor
.value_type
.get_cname ())));
2513 if (array_type
!= null) {
2514 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2515 function
.add_parameter (new
CCodeParameter ("result_length%d".printf (dim
), "int*"));
2519 function
.return_type
= prop
.get_accessor
.value_type
.get_cname ();
2522 var block
= new
CCodeBlock ();
2523 var prefragment
= new
CCodeFragment ();
2524 var postfragment
= new
CCodeFragment ();
2526 var dispose_return_block
= new
CCodeBlock ();
2527 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2528 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2530 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (prop
.property_type
, false)));
2532 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2534 cdecl
= new
CCodeDeclaration ("DBusError");
2535 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2536 block
.add_statement (cdecl
);
2538 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2540 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2541 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2542 block
.add_statement (cdecl
);
2544 cdecl
= new
CCodeDeclaration ("DBusMessage");
2545 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2546 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2547 block
.add_statement (cdecl
);
2549 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2550 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2551 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2552 block
.add_statement (cdecl
);
2554 block
.add_statement (prefragment
);
2556 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2557 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2558 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2559 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2561 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2562 msgcall
.add_argument (destination
);
2563 msgcall
.add_argument (path
);
2564 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2565 msgcall
.add_argument (new
CCodeConstant ("\"Get\""));
2566 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2568 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2569 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2570 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2571 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2573 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2574 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2575 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2576 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2579 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2581 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2583 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
2584 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2585 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2586 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2588 check_property_inner_signature (prop
.get_accessor
, postfragment
);
2590 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2591 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
2592 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2593 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2595 cdecl
= new
CCodeDeclaration (prop
.get_accessor
.value_type
.get_cname ());
2596 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
2597 postfragment
.append (cdecl
);
2599 if (array_type
!= null) {
2600 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2601 cdecl
= new
CCodeDeclaration ("int");
2602 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
2603 postfragment
.append (cdecl
);
2607 var target
= new
CCodeIdentifier ("_result");
2608 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2609 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2611 if (array_type
!= null) {
2612 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2613 // TODO check that parameter is not NULL (out parameters are optional)
2614 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
)))));
2619 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2620 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2621 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2622 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2623 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2624 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2626 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2627 dbus_error_init
.add_argument (dbus_error
);
2628 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2630 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2631 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2633 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2634 ccall
.add_argument (connection
);
2635 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2636 ccall
.add_argument (get_dbus_timeout (prop
));
2637 ccall
.add_argument (dbus_error
);
2638 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2640 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2641 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2642 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2644 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2645 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2646 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2648 check_property_error_reply (prop
.get_accessor
, block
);
2649 check_property_reply_signature (prop
.get_accessor
, block
);
2651 block
.add_statement (postfragment
);
2653 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2654 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2655 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2657 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2658 block
.add_statement (new
CCodeReturnStatement ());
2660 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2663 cfile
.add_function_declaration (function
);
2664 function
.block
= block
;
2665 cfile
.add_function (function
);
2670 string generate_dbus_proxy_property_set (Interface main_iface
, Interface iface
, Property prop
) {
2671 string proxy_name
= "%sdbus_proxy_set_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2673 string dbus_iface_name
= get_dbus_name (iface
);
2675 var array_type
= prop
.set_accessor
.value_type as ArrayType
;
2677 CCodeDeclaration cdecl
;
2679 var function
= new
CCodeFunction (proxy_name
);
2680 function
.modifiers
= CCodeModifiers
.STATIC
;
2682 function
.add_parameter (new
CCodeParameter ("self", "%s*".printf (iface
.get_cname ())));
2684 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2685 function
.add_parameter (new
CCodeParameter ("value", "%s*".printf (prop
.set_accessor
.value_type
.get_cname ())));
2687 function
.add_parameter (new
CCodeParameter ("value", prop
.set_accessor
.value_type
.get_cname ()));
2689 if (array_type
!= null) {
2690 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2691 function
.add_parameter (new
CCodeParameter ("value_length%d".printf (dim
), "int"));
2696 var block
= new
CCodeBlock ();
2697 var prefragment
= new
CCodeFragment ();
2698 var postfragment
= new
CCodeFragment ();
2700 var dispose_return_block
= new
CCodeBlock ();
2701 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2702 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2704 cdecl
= new
CCodeDeclaration ("DBusError");
2705 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2706 block
.add_statement (cdecl
);
2708 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2710 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2711 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2712 block
.add_statement (cdecl
);
2714 cdecl
= new
CCodeDeclaration ("DBusMessage");
2715 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2716 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2717 block
.add_statement (cdecl
);
2719 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2720 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2721 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2722 block
.add_statement (cdecl
);
2724 block
.add_statement (prefragment
);
2726 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2727 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2728 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2729 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2731 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2732 msgcall
.add_argument (destination
);
2733 msgcall
.add_argument (path
);
2734 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2735 msgcall
.add_argument (new
CCodeConstant ("\"Set\""));
2736 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2738 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2739 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2740 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2741 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2743 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2744 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2745 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2746 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2749 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2751 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2753 // property value (as variant)
2754 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
2755 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2756 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_VARIANT"));
2757 iter_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_type_signature (prop
.property_type
))));
2758 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2759 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2761 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2762 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("value")));
2764 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeIdentifier ("value"));
2767 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
2768 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2769 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2770 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2772 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2773 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2774 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2775 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2776 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2777 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2779 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2780 dbus_error_init
.add_argument (dbus_error
);
2781 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2783 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2784 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2786 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2787 ccall
.add_argument (connection
);
2788 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2789 ccall
.add_argument (get_dbus_timeout (prop
));
2790 ccall
.add_argument (dbus_error
);
2791 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2793 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2794 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2795 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2797 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2798 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2799 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2801 check_property_error_reply (prop
.set_accessor
, block
);
2802 check_property_reply_signature (prop
.set_accessor
, block
);
2804 block
.add_statement (postfragment
);
2806 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2807 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2808 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2810 cfile
.add_function_declaration (function
);
2811 function
.block
= block
;
2812 cfile
.add_function (function
);