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,CCodeFormalParameter
> (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_type_member_declaration (func
.copy ());
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
CCodeFormalParameter ("proxy", "DBusGProxy*"));
154 cb_fun
.add_parameter (new
CCodeFormalParameter ("call", "DBusGProxyCall*"));
155 cb_fun
.add_parameter (new
CCodeFormalParameter ("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 ((CCodeExpression
) callback.ccodenode
);
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 (FormalParameter 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 (FormalParameter 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_array_length_cname (param
.name
, 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_array_length_cname (param
.name
, 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_array_length_cname (param
.name
, 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_array_length_cname (param
.name
, 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 (FormalParameter 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
CCodeFormalParameter ("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_type_member_declaration (func
.copy ());
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
CCodeFormalParameter ("obj", prop
.dynamic_type
.get_cname ()));
675 func
.add_parameter (new
CCodeFormalParameter ("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_type_member_declaration (func
.copy ());
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
CCodeFormalParameter ("obj", "gpointer"));
815 func
.add_parameter (new
CCodeFormalParameter ("signal_name", "const char *"));
816 func
.add_parameter (new
CCodeFormalParameter ("handler", "GCallback"));
817 func
.add_parameter (new
CCodeFormalParameter ("data", "gpointer"));
818 var block
= new
CCodeBlock ();
819 generate_dbus_connect_wrapper (sig
, block
);
821 // append to C source file
822 cfile
.add_type_member_declaration (func
.copy ());
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
CCodeFormalParameter ("obj", "gpointer"));
838 func
.add_parameter (new
CCodeFormalParameter ("signal_name", "const char *"));
839 func
.add_parameter (new
CCodeFormalParameter ("handler", "GCallback"));
840 func
.add_parameter (new
CCodeFormalParameter ("data", "gpointer"));
841 var block
= new
CCodeBlock ();
842 generate_dbus_disconnect_wrapper (sig
, block
);
844 // append to C source file
845 cfile
.add_type_member_declaration (func
.copy ());
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 (FormalParameter 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 ((CCodeExpression
) connection
.ccodenode
);
928 bus_name
.emit (this
);
929 ccall
.add_argument ((CCodeExpression
) bus_name
.ccodenode
);
930 object_path
.emit (this
);
931 ccall
.add_argument ((CCodeExpression
) object_path
.ccodenode
);
932 expr
.ccodenode
= 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
CCodeFormalParameter ("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_type_member_declaration (proxy_iface_init
.copy ());
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 // declare proxy_new function
1047 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1048 proxy_new
.add_parameter (new
CCodeFormalParameter ("connection", "DBusGConnection*"));
1049 proxy_new
.add_parameter (new
CCodeFormalParameter ("name", "const char*"));
1050 proxy_new
.add_parameter (new
CCodeFormalParameter ("path", "const char*"));
1052 decl_space
.add_type_member_declaration (proxy_new
);
1055 public override void visit_interface (Interface iface
) {
1056 base.visit_interface (iface
);
1058 string dbus_iface_name
= get_dbus_name (iface
);
1059 if (dbus_iface_name
== null) {
1064 cfile
.add_include ("string.h");
1066 // create proxy class
1067 string cname
= iface
.get_cname () + "DBusProxy";
1068 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1070 add_dbus_helpers ();
1072 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct _%s".printf (cname
), new
CCodeVariableDeclarator (cname
)));
1073 cfile
.add_type_declaration (new
CCodeTypeDefinition ("DBusGProxyClass", new
CCodeVariableDeclarator (cname
+ "Class")));
1075 var instance_struct
= new
CCodeStruct ("_%s".printf (cname
));
1076 instance_struct
.add_field ("DBusGProxy", "parent_instance");
1077 instance_struct
.add_field ("gboolean", "disposed");
1079 cfile
.add_type_definition (instance_struct
);
1081 var type_fun
= new
CCodeFunction(lower_cname
+ "_get_type", "GType");
1082 type_fun
.attributes
= "G_GNUC_CONST";
1083 cfile
.add_type_member_declaration (type_fun
);
1085 var define_type
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_DEFINE_TYPE_EXTENDED"));
1086 define_type
.add_argument (new
CCodeIdentifier (cname
));
1087 define_type
.add_argument (new
CCodeIdentifier (lower_cname
));
1088 define_type
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_G_PROXY"));
1089 define_type
.add_argument (new
CCodeConstant ("0"));
1090 define_type
.add_argument (new
CCodeIdentifier (implement_interface (define_type
, iface
, iface
)));
1092 cfile
.add_type_member_definition (new
CCodeExpressionStatement (define_type
));
1094 // generate proxy_new function
1095 var proxy_new
= new
CCodeFunction (lower_cname
+ "_new", iface
.get_cname () + "*");
1096 proxy_new
.add_parameter (new
CCodeFormalParameter ("connection", "DBusGConnection*"));
1097 proxy_new
.add_parameter (new
CCodeFormalParameter ("name", "const char*"));
1098 proxy_new
.add_parameter (new
CCodeFormalParameter ("path", "const char*"));
1100 var new_block
= new
CCodeBlock ();
1102 // create proxy object
1103 var new_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1104 new_call
.add_argument (new
CCodeFunctionCall (new
CCodeIdentifier (lower_cname
+ "_get_type")));
1105 new_call
.add_argument (new
CCodeConstant ("\"connection\""));
1106 new_call
.add_argument (new
CCodeIdentifier ("connection"));
1107 new_call
.add_argument (new
CCodeConstant ("\"name\""));
1108 new_call
.add_argument (new
CCodeIdentifier ("name"));
1109 new_call
.add_argument (new
CCodeConstant ("\"path\""));
1110 new_call
.add_argument (new
CCodeIdentifier ("path"));
1111 new_call
.add_argument (new
CCodeConstant ("\"interface\""));
1112 new_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1113 new_call
.add_argument (new
CCodeConstant ("NULL"));
1115 var cdecl
= new
CCodeDeclaration (iface
.get_cname () + "*");
1116 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", new_call
));
1117 new_block
.add_statement (cdecl
);
1118 new_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1120 proxy_new
.block
= new_block
;
1121 cfile
.add_function (proxy_new
);
1123 // dbus proxy construct
1124 var proxy_construct
= new
CCodeFunction (lower_cname
+ "_construct", "GObject*");
1125 proxy_construct
.add_parameter (new
CCodeFormalParameter ("gtype", "GType"));
1126 proxy_construct
.add_parameter (new
CCodeFormalParameter ("n_properties", "guint"));
1127 proxy_construct
.add_parameter (new
CCodeFormalParameter ("properties", "GObjectConstructParam*"));
1128 proxy_construct
.modifiers
= CCodeModifiers
.STATIC
;
1129 proxy_construct
.block
= new
CCodeBlock ();
1132 var parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1133 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1134 var chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "constructor"));
1135 chainup
.add_argument (new
CCodeIdentifier ("gtype"));
1136 chainup
.add_argument (new
CCodeIdentifier ("n_properties"));
1137 chainup
.add_argument (new
CCodeIdentifier ("properties"));
1139 cdecl
= new
CCodeDeclaration ("GObject*");
1140 cdecl
.add_declarator (new
CCodeVariableDeclarator ("self", chainup
));
1141 proxy_construct
.block
.add_statement (cdecl
);
1143 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1144 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1145 proxy_construct
.block
.add_statement (cdecl
);
1147 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1148 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1149 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1150 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1151 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1152 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1154 cdecl
= new
CCodeDeclaration ("char*");
1155 cdecl
.add_declarator (new
CCodeVariableDeclarator ("path"));
1156 proxy_construct
.block
.add_statement (cdecl
);
1158 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1159 path
.add_argument (new
CCodeIdentifier ("self"));
1160 path
.add_argument (new
CCodeConstant ("\"path\""));
1161 path
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("path")));
1162 path
.add_argument (new
CCodeConstant ("NULL"));
1163 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path
));
1165 var raw_connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1166 raw_connection
.add_argument (new
CCodeIdentifier ("connection"));
1168 // add filter to handle signals from the remote object
1169 var filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_add_filter"));
1170 filter_call
.add_argument (raw_connection
);
1171 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1172 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1173 filter_call
.add_argument (new
CCodeConstant ("NULL"));
1174 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1176 var filter_printf
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup_printf"));
1177 filter_printf
.add_argument (new
CCodeConstant ("\"type='signal',path='%s'\""));
1178 filter_printf
.add_argument (new
CCodeIdentifier ("path"));
1180 cdecl
= new
CCodeDeclaration ("char*");
1181 cdecl
.add_declarator (new
CCodeVariableDeclarator ("filter", filter_printf
));
1182 proxy_construct
.block
.add_statement (cdecl
);
1184 // ensure we receive signals from the remote object
1185 var match_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_bus_add_match"));
1186 match_call
.add_argument (raw_connection
);
1187 match_call
.add_argument (new
CCodeIdentifier ("filter"));
1188 match_call
.add_argument (new
CCodeConstant ("NULL"));
1189 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (match_call
));
1191 var connection_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1192 connection_free
.add_argument (new
CCodeIdentifier ("connection"));
1193 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (connection_free
));
1195 var path_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1196 path_free
.add_argument (new
CCodeIdentifier ("path"));
1197 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (path_free
));
1199 var filter_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1200 filter_free
.add_argument (new
CCodeIdentifier ("filter"));
1201 proxy_construct
.block
.add_statement (new
CCodeExpressionStatement (filter_free
));
1203 proxy_construct
.block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("self")));
1205 cfile
.add_function (proxy_construct
);
1207 // dbus proxy filter function
1208 generate_proxy_filter_function (iface
);
1210 // dbus proxy dispose
1211 var proxy_dispose
= new
CCodeFunction (lower_cname
+ "_dispose", "void");
1212 proxy_dispose
.add_parameter (new
CCodeFormalParameter ("self", "GObject*"));
1213 proxy_dispose
.modifiers
= CCodeModifiers
.STATIC
;
1214 proxy_dispose
.block
= new
CCodeBlock ();
1216 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1217 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*connection"));
1218 proxy_dispose
.block
.add_statement (cdecl
);
1220 // return if proxy is already disposed
1221 var dispose_return_block
= new
CCodeBlock ();
1222 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1223 proxy_dispose
.block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), dispose_return_block
));
1225 // mark proxy as disposed
1226 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), cname
+ "*"), "disposed"), new
CCodeConstant ("TRUE"))));
1228 gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1229 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1230 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1231 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("connection")));
1232 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1233 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1236 filter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_remove_filter"));
1237 filter_call
.add_argument (raw_connection
);
1238 filter_call
.add_argument (new
CCodeIdentifier (lower_cname
+ "_filter"));
1239 filter_call
.add_argument (new
CCodeIdentifier ("self"));
1240 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (filter_call
));
1243 parent_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1244 parent_class
.add_argument (new
CCodeIdentifier (lower_cname
+ "_parent_class"));
1245 chainup
= new
CCodeFunctionCall (new CCodeMemberAccess
.pointer (parent_class
, "dispose"));
1246 chainup
.add_argument (new
CCodeIdentifier ("self"));
1247 proxy_dispose
.block
.add_statement (new
CCodeExpressionStatement (chainup
));
1249 cfile
.add_function (proxy_dispose
);
1251 var proxy_class_init
= new
CCodeFunction (lower_cname
+ "_class_init", "void");
1252 proxy_class_init
.add_parameter (new
CCodeFormalParameter ("klass", cname
+ "Class*"));
1253 proxy_class_init
.modifiers
= CCodeModifiers
.STATIC
;
1254 proxy_class_init
.block
= new
CCodeBlock ();
1255 var gobject_class
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_OBJECT_CLASS"));
1256 gobject_class
.add_argument (new
CCodeIdentifier ("klass"));
1257 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "constructor"), new
CCodeIdentifier (lower_cname
+ "_construct"))));
1258 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "dispose"), new
CCodeIdentifier (lower_cname
+ "_dispose"))));
1259 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "get_property"), new
CCodeIdentifier (lower_cname
+ "_get_property"))));
1260 proxy_class_init
.block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (gobject_class
, "set_property"), new
CCodeIdentifier (lower_cname
+ "_set_property"))));
1261 cfile
.add_function (proxy_class_init
);
1263 prop_enum
= new
CCodeEnum ();
1264 prop_enum
.add_value (new
CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (lower_cname
.up ())));
1266 implement_property (proxy_class_init
.block
, iface
, iface
);
1268 cfile
.add_type_member_declaration (prop_enum
);
1270 var proxy_instance_init
= new
CCodeFunction (lower_cname
+ "_init", "void");
1271 proxy_instance_init
.add_parameter (new
CCodeFormalParameter ("self", cname
+ "*"));
1272 proxy_instance_init
.modifiers
= CCodeModifiers
.STATIC
;
1273 proxy_instance_init
.block
= new
CCodeBlock ();
1274 cfile
.add_function (proxy_instance_init
);
1276 generate_proxy_interface_init (iface
, iface
);
1278 // dbus proxy get/set_property stubs
1279 // TODO add actual implementation
1280 var get_prop
= new
CCodeFunction ("%s_get_property".printf (lower_cname
), "void");
1281 get_prop
.modifiers
= CCodeModifiers
.STATIC
;
1282 get_prop
.add_parameter (new
CCodeFormalParameter ("object", "GObject *"));
1283 get_prop
.add_parameter (new
CCodeFormalParameter ("property_id", "guint"));
1284 get_prop
.add_parameter (new
CCodeFormalParameter ("value", "GValue *"));
1285 get_prop
.add_parameter (new
CCodeFormalParameter ("pspec", "GParamSpec *"));
1286 cfile
.add_type_member_declaration (get_prop
.copy ());
1287 get_prop
.block
= new
CCodeBlock ();
1288 cfile
.add_function (get_prop
);
1290 var set_prop
= new
CCodeFunction ("%s_set_property".printf (lower_cname
), "void");
1291 set_prop
.modifiers
= CCodeModifiers
.STATIC
;
1292 set_prop
.add_parameter (new
CCodeFormalParameter ("object", "GObject *"));
1293 set_prop
.add_parameter (new
CCodeFormalParameter ("property_id", "guint"));
1294 set_prop
.add_parameter (new
CCodeFormalParameter ("value", "const GValue *"));
1295 set_prop
.add_parameter (new
CCodeFormalParameter ("pspec", "GParamSpec *"));
1296 cfile
.add_type_member_declaration (set_prop
.copy ());
1297 set_prop
.block
= new
CCodeBlock ();
1298 cfile
.add_function (set_prop
);
1301 public override TypeRegisterFunction
create_interface_register_function (Interface iface
) {
1302 string dbus_iface_name
= get_dbus_name (iface
);
1303 if (dbus_iface_name
== null) {
1304 return new
InterfaceRegisterFunction (iface
, context
);
1307 return new
DBusInterfaceRegisterFunction (iface
, context
);
1310 string generate_get_all_function (Method m
) {
1311 string get_all_func
= "_dbus_g_proxy_get_all";
1313 if (!add_wrapper (get_all_func
)) {
1314 // wrapper already defined
1315 return get_all_func
;
1318 var function
= new
CCodeFunction (get_all_func
, "GHashTable*");
1319 function
.modifiers
= CCodeModifiers
.STATIC
;
1321 function
.add_parameter (new
CCodeFormalParameter ("self", "DBusGProxy*"));
1322 function
.add_parameter (new
CCodeFormalParameter ("interface_name", "const gchar*"));
1323 function
.add_parameter (new
CCodeFormalParameter ("error", "GError**"));
1325 var block
= new
CCodeBlock ();
1326 var prefragment
= new
CCodeFragment ();
1327 var postfragment
= new
CCodeFragment ();
1329 var cdecl
= new
CCodeDeclaration ("DBusError");
1330 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1331 block
.add_statement (cdecl
);
1333 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1335 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1336 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1337 block
.add_statement (cdecl
);
1339 cdecl
= new
CCodeDeclaration ("DBusMessage");
1340 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1341 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1342 block
.add_statement (cdecl
);
1344 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1345 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1346 block
.add_statement (cdecl
);
1348 block
.add_statement (prefragment
);
1350 generate_marshalling (m
, "org.freedesktop.DBus.Properties", prefragment
, postfragment
);
1352 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1353 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1354 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1355 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1356 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1357 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1359 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1360 dbus_error_init
.add_argument (dbus_error
);
1361 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1363 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1364 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1366 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1367 ccall
.add_argument (connection
);
1368 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1369 ccall
.add_argument (get_dbus_timeout (m
));
1370 ccall
.add_argument (dbus_error
);
1371 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1373 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1374 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1375 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1377 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1378 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1379 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1381 check_error_reply (m
, block
);
1382 check_reply_signature (m
, block
);
1384 block
.add_statement (postfragment
);
1386 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1387 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1388 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1390 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1392 cfile
.add_type_member_declaration (function
.copy ());
1394 function
.block
= block
;
1395 cfile
.add_function (function
);
1397 return get_all_func
;
1400 public override void visit_method_call (MethodCall expr
) {
1401 var mtype
= expr
.call
.value_type as MethodType
;
1402 bool proxy_new_from_type
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_new_from_type");
1403 bool proxy_get_all
= (mtype
!= null && mtype
.method_symbol
.get_cname () == "dbus_g_proxy_get_all");
1404 if (!proxy_new_from_type
&& !proxy_get_all
) {
1405 base.visit_method_call (expr
);
1409 if (proxy_get_all
) {
1410 var ma
= expr
.call as MemberAccess
;
1411 var instance
= ma
.inner
;
1412 instance
.emit (this
);
1414 var args
= expr
.get_argument_list ();
1415 Expression interface_name
= args
.get (0);
1416 interface_name
.emit (this
);
1418 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_get_all_function (mtype
.method_symbol
)));
1419 ccall
.add_argument ((CCodeExpression
) instance
.ccodenode
);
1420 ccall
.add_argument ((CCodeExpression
) interface_name
.ccodenode
);
1422 current_method_inner_error
= true;
1423 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
1425 expr
.ccodenode
= ccall
;
1429 var args
= expr
.get_argument_list ();
1430 Expression connection
= ((MemberAccess
) expr
.call
).inner
;
1431 Expression bus_name
= args
.get (0);
1432 Expression object_path
= args
.get (1);
1433 Expression interface_name
= args
.get (2);
1434 Expression type
= args
.get (3);
1436 var quark_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_string"));
1437 quark_call
.add_argument (new
CCodeConstant ("\"ValaDBusInterfaceProxyType\""));
1439 var qdata_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
1441 qdata_call
.add_argument ((CCodeExpression
) type
.ccodenode
);
1442 qdata_call
.add_argument (quark_call
);
1444 var get_type_call
= new
CCodeFunctionCall (new
CCodeCastExpression (qdata_call
, "GType (*)(void)"));
1446 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_new"));
1447 ccall
.add_argument (get_type_call
);
1448 ccall
.add_argument (new
CCodeConstant ("\"connection\""));
1449 connection
.emit (this
);
1450 ccall
.add_argument ((CCodeExpression
) connection
.ccodenode
);
1451 ccall
.add_argument (new
CCodeConstant ("\"name\""));
1452 bus_name
.emit (this
);
1453 ccall
.add_argument ((CCodeExpression
) bus_name
.ccodenode
);
1454 ccall
.add_argument (new
CCodeConstant ("\"path\""));
1455 object_path
.emit (this
);
1456 ccall
.add_argument ((CCodeExpression
) object_path
.ccodenode
);
1457 ccall
.add_argument (new
CCodeConstant ("\"interface\""));
1458 interface_name
.emit (this
);
1459 ccall
.add_argument ((CCodeExpression
) interface_name
.ccodenode
);
1460 ccall
.add_argument (new
CCodeConstant ("NULL"));
1461 expr
.ccodenode
= ccall
;
1464 void generate_proxy_filter_function (Interface iface
) {
1465 string lower_cname
= iface
.get_lower_case_cprefix () + "dbus_proxy";
1467 var proxy_filter
= new
CCodeFunction (lower_cname
+ "_filter", "DBusHandlerResult");
1468 proxy_filter
.add_parameter (new
CCodeFormalParameter ("connection", "DBusConnection*"));
1469 proxy_filter
.add_parameter (new
CCodeFormalParameter ("message", "DBusMessage*"));
1470 proxy_filter
.add_parameter (new
CCodeFormalParameter ("user_data", "void*"));
1472 var filter_block
= new
CCodeBlock ();
1474 // only handle signals concering the object path
1475 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1476 path
.add_argument (new
CCodeIdentifier ("user_data"));
1478 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_has_path"));
1479 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1480 ccheck
.add_argument (path
);
1482 var object_filter_block
= new
CCodeBlock ();
1483 filter_block
.add_statement (new
CCodeIfStatement (ccheck
, object_filter_block
));
1485 handle_signals (iface
, object_filter_block
);
1487 filter_block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("DBUS_HANDLER_RESULT_NOT_YET_HANDLED")));
1489 cfile
.add_type_member_declaration (proxy_filter
.copy ());
1490 proxy_filter
.block
= filter_block
;
1491 cfile
.add_function (proxy_filter
);
1494 string generate_dbus_signal_handler (Signal sig
, ObjectTypeSymbol sym
) {
1495 string wrapper_name
= "_dbus_handle_%s_%s".printf (sym
.get_lower_case_cname (), sig
.get_cname ());
1499 CCodeDeclaration cdecl
;
1501 var function
= new
CCodeFunction (wrapper_name
, "void");
1502 function
.modifiers
= CCodeModifiers
.STATIC
;
1504 function
.add_parameter (new
CCodeFormalParameter ("self", sym
.get_cname () + "*"));
1505 function
.add_parameter (new
CCodeFormalParameter ("connection", "DBusConnection*"));
1506 function
.add_parameter (new
CCodeFormalParameter ("message", "DBusMessage*"));
1508 var block
= new
CCodeBlock ();
1509 var prefragment
= new
CCodeFragment ();
1510 var postfragment
= new
CCodeFragment ();
1512 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1513 cdecl
.add_declarator (new
CCodeVariableDeclarator ("iter"));
1514 block
.add_statement (cdecl
);
1516 block
.add_statement (prefragment
);
1518 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
1519 message_signature
.add_argument (new
CCodeIdentifier ("message"));
1520 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
1521 signature_check
.add_argument (message_signature
);
1522 var signature_error_block
= new
CCodeBlock ();
1523 signature_error_block
.add_statement (new
CCodeReturnStatement ());
1524 prefragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
1526 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1527 iter_call
.add_argument (new
CCodeIdentifier ("message"));
1528 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("iter")));
1529 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1531 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_emit_by_name"));
1532 ccall
.add_argument (new
CCodeIdentifier ("self"));
1533 ccall
.add_argument (sig
.get_canonical_cconstant ());
1535 // expected type signature for input parameters
1536 string type_signature
= "";
1538 foreach (FormalParameter param
in sig
.get_parameters ()) {
1539 var owned_type
= param
.variable_type
.copy ();
1540 owned_type
.value_owned
= true;
1542 cdecl
= new
CCodeDeclaration (owned_type
.get_cname ());
1543 cdecl
.add_declarator (new CCodeVariableDeclarator
.zero (param
.name
, default_value_for_type (param
.variable_type
, true)));
1544 prefragment
.append (cdecl
);
1546 if (get_type_signature (param
.variable_type
) == null) {
1547 Report
.error (param
.variable_type
.source_reference
, "D-Bus serialization of type `%s' is not supported".printf (param
.variable_type
.to_string ()));
1551 var st
= param
.variable_type
.data_type as Struct
;
1552 if (st
!= null && !st
.is_simple_type ()) {
1553 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param
.name
)));
1555 ccall
.add_argument (new
CCodeIdentifier (param
.name
));
1558 if (param
.variable_type is ArrayType
) {
1559 var array_type
= (ArrayType
) param
.variable_type
;
1561 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1562 string length_cname
= get_array_length_cname (param
.name
, dim
);
1564 cdecl
= new
CCodeDeclaration ("int");
1565 cdecl
.add_declarator (new
CCodeVariableDeclarator (length_cname
, new
CCodeConstant ("0")));
1566 prefragment
.append (cdecl
);
1567 ccall
.add_argument (new
CCodeIdentifier (length_cname
));
1571 type_signature
+= get_type_signature (param
.variable_type
);
1573 var target
= new
CCodeIdentifier (param
.name
);
1574 var expr
= read_expression (prefragment
, param
.variable_type
, new
CCodeIdentifier ("iter"), target
);
1575 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1577 if (requires_destroy (owned_type
)) {
1578 // keep local alive (symbol_reference is weak)
1579 var local
= new
LocalVariable (owned_type
, param
.name
);
1580 var ma
= new MemberAccess
.simple (param
.name
);
1581 ma
.symbol_reference
= local
;
1582 var stmt
= new
CCodeExpressionStatement (get_unref_expression (new
CCodeIdentifier (param
.name
), owned_type
, ma
));
1583 postfragment
.append (stmt
);
1587 signature_check
.add_argument (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
1589 block
.add_statement (new
CCodeExpressionStatement (ccall
));
1591 block
.add_statement (postfragment
);
1593 cdecl
= new
CCodeDeclaration ("DBusMessage*");
1594 cdecl
.add_declarator (new
CCodeVariableDeclarator ("reply"));
1595 block
.add_statement (cdecl
);
1597 cfile
.add_type_member_declaration (function
.copy ());
1599 function
.block
= block
;
1600 cfile
.add_function (function
);
1602 return wrapper_name
;
1605 void handle_signal (string dbus_iface_name
, string dbus_signal_name
, string handler_name
, CCodeBlock block
, ref CCodeIfStatement clastif
) {
1606 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_is_signal"));
1607 ccheck
.add_argument (new
CCodeIdentifier ("message"));
1608 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1609 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_signal_name
)));
1611 var callblock
= new
CCodeBlock ();
1613 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (handler_name
));
1614 ccall
.add_argument (new
CCodeIdentifier ("user_data"));
1615 ccall
.add_argument (new
CCodeIdentifier ("connection"));
1616 ccall
.add_argument (new
CCodeIdentifier ("message"));
1618 callblock
.add_statement (new
CCodeExpressionStatement (ccall
));
1620 var cif
= new
CCodeIfStatement (ccheck
, callblock
);
1621 if (clastif
== null) {
1622 block
.add_statement (cif
);
1624 clastif
.false_statement
= cif
;
1630 void handle_signals (Interface iface
, CCodeBlock block
) {
1631 string dbus_iface_name
= get_dbus_name (iface
);
1633 CCodeIfStatement clastif
= null;
1634 foreach (Signal sig
in iface
.get_signals ()) {
1635 if (sig
.access
!= SymbolAccessibility
.PUBLIC
) {
1639 handle_signal (dbus_iface_name
, get_dbus_name_for_member (sig
), generate_dbus_signal_handler (sig
, iface
), block
, ref clastif
);
1643 void generate_marshalling (Method m
, string dbus_iface_name
, CCodeFragment prefragment
, CCodeFragment postfragment
) {
1644 CCodeDeclaration cdecl
;
1646 var no_reply
= is_dbus_no_reply (m
);
1648 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
1649 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1650 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
1651 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
1653 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
1654 msgcall
.add_argument (destination
);
1655 msgcall
.add_argument (path
);
1656 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
1657 msgcall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m
))));
1658 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
1661 var noreplycall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_set_no_reply"));
1662 noreplycall
.add_argument (new
CCodeIdentifier ("_message"));
1663 noreplycall
.add_argument (new
CCodeConstant ("TRUE"));
1664 prefragment
.append (new
CCodeExpressionStatement (noreplycall
));
1667 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
1668 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
1669 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1670 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
1673 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
1674 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
1675 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
1676 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
1679 foreach (FormalParameter param
in m
.get_parameters ()) {
1680 if (param
.direction
== ParameterDirection
.IN
) {
1681 if (param
.variable_type
.data_type
!= null
1682 && param
.variable_type
.data_type
.get_full_name () == "DBus.BusName") {
1683 // ignore BusName sender parameters
1686 CCodeExpression expr
= new
CCodeIdentifier (param
.name
);
1687 if (param
.variable_type
.is_real_struct_type ()) {
1688 expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, expr
);
1690 write_expression (prefragment
, param
.variable_type
, new
CCodeIdentifier ("_iter"), expr
);
1693 Report
.error (param
.source_reference
, "No-reply DBus methods must not have out parameters");
1696 cdecl
= new
CCodeDeclaration (param
.variable_type
.get_cname ());
1697 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_" + param
.name
));
1698 postfragment
.append (cdecl
);
1700 var array_type
= param
.variable_type as ArrayType
;
1702 if (array_type
!= null) {
1703 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1704 cdecl
= new
CCodeDeclaration ("int");
1705 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_%s_length%d".printf (param
.name
, dim
), new
CCodeConstant ("0")));
1706 postfragment
.append (cdecl
);
1710 var target
= new
CCodeIdentifier ("_" + param
.name
);
1711 var expr
= read_expression (postfragment
, param
.variable_type
, new
CCodeIdentifier ("_iter"), target
);
1712 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1714 // TODO check that parameter is not NULL (out parameters are optional)
1715 // free value if parameter is NULL
1716 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier (param
.name
)), target
)));
1719 if (array_type
!= null) {
1720 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1721 // TODO check that parameter is not NULL (out parameters are optional)
1722 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
)))));
1728 if (!(m
.return_type is VoidType
)) {
1730 Report
.error (m
.return_type
.source_reference
, "No-reply DBus methods must return void");
1732 if (m
.return_type
.is_real_non_null_struct_type ()) {
1733 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
1734 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1735 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1737 cdecl
= new
CCodeDeclaration (m
.return_type
.get_cname ());
1738 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
1739 postfragment
.append (cdecl
);
1741 var array_type
= m
.return_type as ArrayType
;
1743 if (array_type
!= null) {
1744 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1745 cdecl
= new
CCodeDeclaration ("int");
1746 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
1747 postfragment
.append (cdecl
);
1751 var target
= new
CCodeIdentifier ("_result");
1752 var expr
= read_expression (postfragment
, m
.return_type
, new
CCodeIdentifier ("_iter"), target
);
1753 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
1755 if (array_type
!= null) {
1756 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
1757 // TODO check that parameter is not NULL (out parameters are optional)
1758 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
)))));
1765 void check_error_reply (Method m
, CCodeBlock block
) {
1766 var error_types
= m
.get_error_types ();
1767 if (!has_dbus_error (error_types
)) {
1768 Report
.error (m
.source_reference
, "D-Bus methods must throw DBus.Error");
1771 if (is_dbus_no_reply (m
)) {
1772 // no-reply messages throw no error
1776 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1778 var error_block
= new
CCodeBlock ();
1780 var cdecl
= new
CCodeDeclaration ("GQuark");
1781 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_edomain"));
1782 error_block
.add_statement (cdecl
);
1784 cdecl
= new
CCodeDeclaration ("gint");
1785 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_ecode"));
1786 error_block
.add_statement (cdecl
);
1788 generate_client_error_cases (error_block
, error_types
, new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "name"), new
CCodeIdentifier ("_edomain"), new
CCodeIdentifier ("_ecode"));
1790 var g_set_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1791 g_set_error
.add_argument (new
CCodeIdentifier ("error"));
1792 g_set_error
.add_argument (new
CCodeIdentifier ("_edomain"));
1793 g_set_error
.add_argument (new
CCodeIdentifier ("_ecode"));
1794 g_set_error
.add_argument (new
CCodeConstant ("\"%s\""));
1795 g_set_error
.add_argument (new
CCodeMemberAccess (new
CCodeIdentifier ("_dbus_error"), "message"));
1796 error_block
.add_statement (new
CCodeExpressionStatement (g_set_error
));
1798 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
1799 dbus_error_free
.add_argument (dbus_error
);
1800 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
1802 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1803 error_block
.add_statement (new
CCodeReturnStatement ());
1805 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1808 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
1809 dbus_error_is_set
.add_argument (dbus_error
);
1810 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
1813 string generate_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1814 string proxy_name
= "%sdbus_proxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1816 string dbus_iface_name
= get_dbus_name (iface
);
1818 CCodeDeclaration cdecl
;
1820 var function
= new
CCodeFunction (proxy_name
);
1821 function
.modifiers
= CCodeModifiers
.STATIC
;
1823 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1825 generate_cparameters (m
, cfile
, cparam_map
, function
);
1827 var block
= new
CCodeBlock ();
1828 var prefragment
= new
CCodeFragment ();
1829 var postfragment
= new
CCodeFragment ();
1831 // throw error and return if proxy is disposed
1832 var dispose_return_block
= new
CCodeBlock ();
1833 if (m
.get_error_types ().size
> 0) {
1834 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1835 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1836 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1837 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
1838 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1839 set_error_call
.add_argument (new
CCodeConstant ("\"Connection is closed\""));
1840 dispose_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1842 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
1843 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1845 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
1847 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
1849 cdecl
= new
CCodeDeclaration ("DBusError");
1850 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
1851 block
.add_statement (cdecl
);
1853 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
1855 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1856 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1857 block
.add_statement (cdecl
);
1859 cdecl
= new
CCodeDeclaration ("DBusMessage");
1860 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1861 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
1862 block
.add_statement (cdecl
);
1864 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1865 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1866 block
.add_statement (cdecl
);
1868 block
.add_statement (prefragment
);
1870 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
1872 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1873 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1874 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1875 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1876 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1877 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1879 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
1880 dbus_error_init
.add_argument (dbus_error
);
1881 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
1883 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1884 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1886 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
1887 ccall
.add_argument (connection
);
1888 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1889 ccall
.add_argument (get_dbus_timeout (m
));
1890 ccall
.add_argument (dbus_error
);
1891 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
1893 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1894 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1895 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
1897 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1898 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
1899 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
1901 check_error_reply (m
, block
);
1902 check_reply_signature (m
, block
);
1904 block
.add_statement (postfragment
);
1906 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
1907 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
1908 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
1910 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
1911 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
1914 cfile
.add_type_member_declaration (function
.copy ());
1915 function
.block
= block
;
1916 cfile
.add_function (function
);
1921 string generate_noreply_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
1922 string proxy_name
= "%sdbus_proxy_%s".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
1924 string dbus_iface_name
= get_dbus_name (iface
);
1926 CCodeDeclaration cdecl
;
1928 var function
= new
CCodeFunction (proxy_name
);
1929 function
.modifiers
= CCodeModifiers
.STATIC
;
1931 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
1933 generate_cparameters (m
, cfile
, cparam_map
, function
);
1935 var block
= new
CCodeBlock ();
1936 var prefragment
= new
CCodeFragment ();
1937 var postfragment
= new
CCodeFragment ();
1939 // throw error and return if proxy is disposed
1940 var dispose_return_block
= new
CCodeBlock ();
1941 if (m
.get_error_types ().size
> 0) {
1942 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1943 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1944 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1945 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_DISCONNECTED"));
1946 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1947 set_error_call
.add_argument (new
CCodeConstant ("\"Connection is closed\""));
1948 dispose_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1949 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
1951 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
1953 cdecl
= new
CCodeDeclaration ("DBusGConnection");
1954 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
1955 block
.add_statement (cdecl
);
1957 cdecl
= new
CCodeDeclaration ("DBusMessage");
1958 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
1959 block
.add_statement (cdecl
);
1961 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
1962 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
1963 block
.add_statement (cdecl
);
1965 block
.add_statement (prefragment
);
1967 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
1969 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
1970 gconnection
.add_argument (new
CCodeIdentifier ("self"));
1971 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
1972 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
1973 gconnection
.add_argument (new
CCodeConstant ("NULL"));
1974 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
1976 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
1977 connection
.add_argument (new
CCodeIdentifier ("_connection"));
1979 var oom_return_block
= new
CCodeBlock ();
1980 if (m
.get_error_types ().size
> 0) {
1981 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
1982 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
1983 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
1984 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_NO_MEMORY"));
1985 set_error_call
.add_argument (new
CCodeConstant ("\"%s\""));
1986 set_error_call
.add_argument (new
CCodeConstant ("\"Out of memory\""));
1987 oom_return_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
1988 oom_return_block
.add_statement (new
CCodeReturnStatement ());
1991 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send"));
1992 ccall
.add_argument (connection
);
1993 ccall
.add_argument (new
CCodeIdentifier ("_message"));
1994 ccall
.add_argument (new
CCodeConstant ("NULL"));
1995 block
.add_statement (new
CCodeIfStatement (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, ccall
), oom_return_block
));
1997 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
1998 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
1999 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2001 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2002 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2003 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2005 check_error_reply (m
, block
);
2007 block
.add_statement (postfragment
);
2009 cfile
.add_type_member_declaration (function
.copy ());
2010 function
.block
= block
;
2011 cfile
.add_function (function
);
2016 void generate_client_error_cases (CCodeBlock error_block
, List
<DataType
> error_types
, CCodeExpression dbus_error_name
, CCodeExpression result_edomain
, CCodeExpression result_ecode
) {
2017 CCodeStatement if_else_if
= null;
2018 CCodeIfStatement last_statement
= null;
2020 foreach (DataType error_type
in error_types
) {
2021 var edomain
= ((ErrorType
) error_type
).error_domain
;
2023 if (edomain
== null) {
2024 Report
.error (error_type
.source_reference
, "Generic errors cannot be serialized over DBus");
2028 var edomain_dbus_name
= get_dbus_name (edomain
);
2029 if (edomain_dbus_name
== null) {
2030 Report
.error (edomain
.source_reference
, "Errordomain must have a DBus.name annotation to be serialized over DBus");
2033 var true_block
= new
CCodeBlock ();
2034 true_block
.suppress_newline
= true;
2036 string temp_name
= "_tmp%d_".printf (next_temp_var_id
++);
2038 var cdecl
= new
CCodeDeclaration ("const char*");
2039 cdecl
.add_declarator (new
CCodeVariableDeclarator (temp_name
));
2040 true_block
.add_statement (cdecl
);
2042 true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_edomain
, new
CCodeIdentifier (edomain
.get_upper_case_cname ()))));
2044 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))))));
2046 CCodeStatement inner_if_else_if
= null;
2047 CCodeIfStatement inner_last_statement
= null;
2048 foreach (ErrorCode ecode
in edomain
.get_codes ()) {
2049 var inner_true_block
= new
CCodeBlock ();
2050 inner_true_block
.suppress_newline
= true;
2051 inner_true_block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (result_ecode
, new
CCodeIdentifier (ecode
.get_cname ()))));
2053 var ecode_dbus_name
= get_dbus_name (ecode
);
2054 if (ecode_dbus_name
== null) {
2055 ecode_dbus_name
= Symbol
.lower_case_to_camel_case (ecode
.name
.down ());
2058 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2059 string_comparison
.add_argument (new
CCodeIdentifier (temp_name
));
2060 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (ecode_dbus_name
)));
2061 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, new
CCodeConstant ("0")), inner_true_block
);
2063 if (inner_last_statement
!= null) {
2064 inner_last_statement
.false_statement
= stmt
;
2066 inner_if_else_if
= stmt
;
2068 inner_last_statement
= stmt
;
2070 true_block
.add_statement (inner_if_else_if
);
2072 var string_comparison
= new
CCodeFunctionCall (new
CCodeIdentifier ("strstr"));
2073 string_comparison
.add_argument (dbus_error_name
);
2074 string_comparison
.add_argument (new
CCodeConstant ("\"%s\"".printf (edomain_dbus_name
)));
2075 var stmt
= new
CCodeIfStatement (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, string_comparison
, dbus_error_name
), true_block
);
2077 if (last_statement
!= null) {
2078 last_statement
.false_statement
= stmt
;
2082 last_statement
= stmt
;
2084 error_block
.add_statement (if_else_if
);
2087 string generate_async_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
2088 string proxy_name
= "%sdbus_proxy_%s_async".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
2090 string dbus_iface_name
= get_dbus_name (iface
);
2092 CCodeDeclaration cdecl
;
2095 // generate data struct
2097 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
2098 var datastruct
= new
CCodeStruct ("_" + dataname
);
2100 datastruct
.add_field ("GAsyncReadyCallback", "_callback_");
2101 datastruct
.add_field ("gpointer", "_user_data_");
2102 datastruct
.add_field ("DBusPendingCall*", "pending");
2104 cfile
.add_type_definition (datastruct
);
2105 cfile
.add_type_declaration (new
CCodeTypeDefinition ("struct _" + dataname
, new
CCodeVariableDeclarator (dataname
)));
2108 // generate async function
2110 var function
= new
CCodeFunction (proxy_name
, "void");
2111 function
.modifiers
= CCodeModifiers
.STATIC
;
2113 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
2115 cparam_map
.set (get_param_pos (-1), new
CCodeFormalParameter ("_callback_", "GAsyncReadyCallback"));
2116 cparam_map
.set (get_param_pos (-0.9), new
CCodeFormalParameter ("_user_data_", "gpointer"));
2118 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 1);
2120 var block
= new
CCodeBlock ();
2121 var prefragment
= new
CCodeFragment ();
2122 var postfragment
= new
CCodeFragment ();
2124 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2125 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2126 block
.add_statement (cdecl
);
2128 cdecl
= new
CCodeDeclaration ("DBusMessage");
2129 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2130 block
.add_statement (cdecl
);
2132 cdecl
= new
CCodeDeclaration ("DBusPendingCall");
2133 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_pending"));
2134 block
.add_statement (cdecl
);
2136 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2137 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2138 block
.add_statement (cdecl
);
2140 block
.add_statement (prefragment
);
2142 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2144 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2145 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2146 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2147 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2148 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2149 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2151 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2152 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2154 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply"));
2155 ccall
.add_argument (connection
);
2156 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2157 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_pending")));
2158 ccall
.add_argument (get_dbus_timeout (m
));
2159 block
.add_statement (new
CCodeExpressionStatement (ccall
));
2161 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2162 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2163 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2165 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2166 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2167 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2169 var dataalloc
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_new0"));
2170 dataalloc
.add_argument (new
CCodeIdentifier (dataname
));
2172 var datadecl
= new
CCodeDeclaration (dataname
+ "*");
2173 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2174 block
.add_statement (datadecl
);
2175 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), dataalloc
)));
2177 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"), new
CCodeIdentifier ("_callback_"))));
2178 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"), new
CCodeIdentifier ("_user_data_"))));
2179 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"), new
CCodeIdentifier ("_pending"))));
2181 var pending
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_set_notify"));
2182 pending
.add_argument (new
CCodeIdentifier ("_pending"));
2183 pending
.add_argument (new
CCodeIdentifier ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
)));
2184 pending
.add_argument (new
CCodeIdentifier ("_data_"));
2185 pending
.add_argument (new
CCodeConstant ("NULL"));
2186 block
.add_statement (new
CCodeExpressionStatement (pending
));
2188 cfile
.add_type_member_declaration (function
.copy ());
2189 function
.block
= block
;
2190 cfile
.add_function (function
);
2193 // generate ready function
2195 function
= new
CCodeFunction ("%sdbus_proxy_%s_ready".printf (iface
.get_lower_case_cprefix (), m
.name
), "void");
2196 function
.modifiers
= CCodeModifiers
.STATIC
;
2198 function
.add_parameter (new
CCodeFormalParameter ("pending", "DBusPendingCall*"));
2199 function
.add_parameter (new
CCodeFormalParameter ("user_data", "void*"));
2201 block
= new
CCodeBlock ();
2203 datadecl
= new
CCodeDeclaration (dataname
+ "*");
2204 datadecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2205 block
.add_statement (datadecl
);
2206 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), new
CCodeIdentifier ("user_data"))));
2208 // complete async call by invoking callback
2209 var obj_decl
= new
CCodeDeclaration ("GObject *");
2210 obj_decl
.add_declarator (new
CCodeVariableDeclarator ("_obj_"));
2211 block
.add_statement (obj_decl
);
2213 var object_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_newv"));
2214 object_creation
.add_argument (new
CCodeConstant ("G_TYPE_OBJECT"));
2215 object_creation
.add_argument (new
CCodeConstant ("0"));
2216 object_creation
.add_argument (new
CCodeConstant ("NULL"));
2217 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_obj_"), object_creation
)));
2219 var async_result_decl
= new
CCodeDeclaration ("GSimpleAsyncResult *");
2220 async_result_decl
.add_declarator (new
CCodeVariableDeclarator ("_res_"));
2221 block
.add_statement (async_result_decl
);
2223 var async_result_creation
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_new"));
2224 async_result_creation
.add_argument (new
CCodeIdentifier ("_obj_"));
2225 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_callback_"));
2226 async_result_creation
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "_user_data_"));
2227 async_result_creation
.add_argument (new
CCodeIdentifier ("_data_"));
2228 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_res_"), async_result_creation
)));
2230 var completecall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_complete"));
2231 completecall
.add_argument (new
CCodeIdentifier ("_res_"));
2232 block
.add_statement (new
CCodeExpressionStatement (completecall
));
2234 var obj_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2235 obj_free
.add_argument (new
CCodeIdentifier ("_obj_"));
2236 block
.add_statement (new
CCodeExpressionStatement (obj_free
));
2238 var async_result_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
2239 async_result_free
.add_argument (new
CCodeIdentifier ("_res_"));
2240 block
.add_statement (new
CCodeExpressionStatement (async_result_free
));
2242 var datafree
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_slice_free"));
2243 datafree
.add_argument (new
CCodeIdentifier (dataname
));
2244 datafree
.add_argument (new
CCodeIdentifier ("_data_"));
2245 block
.add_statement (new
CCodeExpressionStatement (datafree
));
2247 var pendingfree
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_unref"));
2248 pendingfree
.add_argument (new
CCodeIdentifier ("pending"));
2249 block
.add_statement (new
CCodeExpressionStatement (pendingfree
));
2251 cfile
.add_type_member_declaration (function
.copy ());
2252 function
.block
= block
;
2253 cfile
.add_function (function
);
2259 CCodeConstant
get_reply_signature (Method m
) {
2260 // expected type signature for output parameters
2261 string type_signature
= "";
2263 foreach (FormalParameter param
in m
.get_parameters ()) {
2264 if (param
.direction
== ParameterDirection
.OUT
) {
2265 type_signature
+= get_type_signature (param
.variable_type
);
2269 if (!(m
.return_type is VoidType
)) {
2270 type_signature
+= get_type_signature (m
.return_type
);
2273 return (new
CCodeConstant ("\"%s\"".printf (type_signature
)));
2276 void check_reply_signature (Method m
, CCodeBlock block
) {
2277 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2278 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2280 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2281 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2283 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2284 signature_check
.add_argument (message_signature
);
2285 signature_check
.add_argument (get_reply_signature (m
));
2287 var signature_error_block
= new
CCodeBlock ();
2288 var set_error_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error"));
2289 set_error_call
.add_argument (new
CCodeIdentifier ("error"));
2290 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR"));
2291 set_error_call
.add_argument (new
CCodeIdentifier ("DBUS_GERROR_INVALID_SIGNATURE"));
2292 set_error_call
.add_argument (new
CCodeConstant ("\"Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2293 set_error_call
.add_argument (get_reply_signature (m
));
2294 set_error_call
.add_argument (message_signature
);
2295 signature_error_block
.add_statement (new
CCodeExpressionStatement (set_error_call
));
2296 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2297 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (m
.return_type
, false)));
2299 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2302 string generate_finish_dbus_proxy_method (Interface main_iface
, Interface iface
, Method m
) {
2303 string proxy_name
= "%sdbus_proxy_%s_finish".printf (main_iface
.get_lower_case_cprefix (), m
.name
);
2305 string dbus_iface_name
= get_dbus_name (iface
);
2307 CCodeDeclaration cdecl
;
2309 var function
= new
CCodeFunction (proxy_name
);
2310 function
.modifiers
= CCodeModifiers
.STATIC
;
2312 var cparam_map
= new HashMap
<int,CCodeFormalParameter
> (direct_hash
, direct_equal
);
2314 cparam_map
.set (get_param_pos (0.1), new
CCodeFormalParameter ("_res_", "GAsyncResult*"));
2316 generate_cparameters (m
, cfile
, cparam_map
, function
, null, null, null, 2);
2318 var block
= new
CCodeBlock ();
2319 var prefragment
= new
CCodeFragment ();
2320 var postfragment
= new
CCodeFragment ();
2322 string dataname
= "%sDBusProxy%sData".printf (iface
.get_cname (), Symbol
.lower_case_to_camel_case (m
.name
));
2323 cdecl
= new
CCodeDeclaration (dataname
+ "*");
2324 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_data_"));
2325 block
.add_statement (cdecl
);
2327 cdecl
= new
CCodeDeclaration ("DBusError");
2328 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2329 block
.add_statement (cdecl
);
2331 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2333 cdecl
= new
CCodeDeclaration ("DBusMessage");
2334 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2335 block
.add_statement (cdecl
);
2337 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2338 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2339 block
.add_statement (cdecl
);
2341 var get_source_tag
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_simple_async_result_get_source_tag"));
2342 get_source_tag
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("_res_"), "GSimpleAsyncResult *"));
2343 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_data_"), get_source_tag
)));
2345 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2346 dbus_error_init
.add_argument (dbus_error
);
2347 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2349 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_pending_call_steal_reply"));
2350 ccall
.add_argument (new CCodeMemberAccess
.pointer (new
CCodeIdentifier ("_data_"), "pending"));
2351 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2353 var set_error_from_message
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_set_error_from_message"));
2354 set_error_from_message
.add_argument (dbus_error
);
2355 set_error_from_message
.add_argument (new
CCodeIdentifier ("_reply"));
2356 block
.add_statement (new
CCodeExpressionStatement (set_error_from_message
));
2358 check_error_reply (m
, block
);
2359 check_reply_signature (m
, block
);
2361 generate_marshalling (m
, dbus_iface_name
, prefragment
, postfragment
);
2363 block
.add_statement (postfragment
);
2365 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2366 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2367 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2369 if (!(m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ())) {
2370 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2373 cfile
.add_type_member_declaration (function
.copy ());
2374 function
.block
= block
;
2375 cfile
.add_function (function
);
2380 void check_property_error_reply (PropertyAccessor acc
, CCodeBlock block
) {
2381 var dbus_error
= new
CCodeIdentifier ("_dbus_error");
2382 var dbus_error_ptr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, dbus_error
);
2384 var error_block
= new
CCodeBlock ();
2386 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2387 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: uncaught error: %s (%s)\""));
2388 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2389 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2390 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "message"));
2391 ccritical
.add_argument (new
CCodeMemberAccess (dbus_error
, "name"));
2393 error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2395 var dbus_error_free
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_free"));
2396 dbus_error_free
.add_argument (dbus_error_ptr
);
2397 error_block
.add_statement (new
CCodeExpressionStatement (dbus_error_free
));
2399 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2400 error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2402 error_block
.add_statement (new
CCodeReturnStatement ());
2405 var dbus_error_is_set
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_is_set"));
2406 dbus_error_is_set
.add_argument (dbus_error_ptr
);
2407 block
.add_statement (new
CCodeIfStatement (dbus_error_is_set
, error_block
));
2410 CCodeConstant
get_property_reply_signature (PropertyAccessor acc
) {
2412 return new
CCodeConstant ("\"v\"");
2414 return new
CCodeConstant ("\"\"");
2418 CCodeConstant
get_property_inner_signature (PropertyAccessor acc
) {
2419 return new
CCodeConstant ("\"%s\"".printf (get_type_signature (acc
.value_type
)));
2422 void check_property_reply_signature (PropertyAccessor acc
, CCodeBlock block
) {
2423 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2424 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2426 var message_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_get_signature"));
2427 message_signature
.add_argument (new
CCodeIdentifier ("_reply"));
2429 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2430 signature_check
.add_argument (message_signature
);
2431 signature_check
.add_argument (get_property_reply_signature (acc
));
2433 var signature_error_block
= new
CCodeBlock ();
2435 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2436 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2437 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2438 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2439 ccritical
.add_argument (get_property_reply_signature (acc
));
2440 ccritical
.add_argument (message_signature
);
2442 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2443 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2445 if (acc
.readable
&& !acc
.value_type
.is_real_non_null_struct_type ()) {
2446 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2448 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2451 block
.add_statement (new
CCodeIfStatement (signature_check
, signature_error_block
));
2454 void check_property_inner_signature (PropertyAccessor acc
, CCodeFragment fragment
) {
2455 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2456 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2458 var iter_signature
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_get_signature"));
2459 iter_signature
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2461 var signature_check
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
2462 signature_check
.add_argument (iter_signature
);
2463 signature_check
.add_argument (get_property_inner_signature (acc
));
2465 var signature_error_block
= new
CCodeBlock ();
2467 var ccritical
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_critical"));
2468 ccritical
.add_argument (new
CCodeConstant ("\"file %s: line %d: Invalid signature, expected \\\"%s\\\", got \\\"%s\\\"\""));
2469 ccritical
.add_argument (new
CCodeConstant ("__FILE__"));
2470 ccritical
.add_argument (new
CCodeConstant ("__LINE__"));
2471 ccritical
.add_argument (get_property_inner_signature (acc
));
2472 ccritical
.add_argument (iter_signature
);
2474 signature_error_block
.add_statement (new
CCodeExpressionStatement (ccritical
));
2475 signature_error_block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2477 if (!acc
.value_type
.is_real_non_null_struct_type ()) {
2478 signature_error_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (acc
.value_type
, false)));
2480 signature_error_block
.add_statement (new
CCodeReturnStatement ());
2483 fragment
.append (new
CCodeIfStatement (signature_check
, signature_error_block
));
2486 string generate_dbus_proxy_property_get (Interface main_iface
, Interface iface
, Property prop
) {
2487 string proxy_name
= "%sdbus_proxy_get_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2489 string dbus_iface_name
= get_dbus_name (iface
);
2491 var owned_type
= prop
.get_accessor
.value_type
.copy ();
2492 owned_type
.value_owned
= true;
2493 if (owned_type
.is_disposable () && !prop
.get_accessor
.value_type
.value_owned
) {
2494 Report
.error (prop
.get_accessor
.value_type
.source_reference
, "Properties used in D-Bus clients require owned get accessor");
2497 var array_type
= prop
.get_accessor
.value_type as ArrayType
;
2499 CCodeDeclaration cdecl
;
2501 var function
= new
CCodeFunction (proxy_name
);
2502 function
.modifiers
= CCodeModifiers
.STATIC
;
2504 function
.add_parameter (new
CCodeFormalParameter ("self", "%s*".printf (iface
.get_cname ())));
2506 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2507 function
.add_parameter (new
CCodeFormalParameter ("result", "%s*".printf (prop
.get_accessor
.value_type
.get_cname ())));
2509 if (array_type
!= null) {
2510 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2511 function
.add_parameter (new
CCodeFormalParameter ("result_length%d".printf (dim
), "int*"));
2515 function
.return_type
= prop
.get_accessor
.value_type
.get_cname ();
2518 var block
= new
CCodeBlock ();
2519 var prefragment
= new
CCodeFragment ();
2520 var postfragment
= new
CCodeFragment ();
2522 var dispose_return_block
= new
CCodeBlock ();
2523 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2524 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2526 dispose_return_block
.add_statement (new
CCodeReturnStatement (default_value_for_type (prop
.property_type
, false)));
2528 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2530 cdecl
= new
CCodeDeclaration ("DBusError");
2531 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2532 block
.add_statement (cdecl
);
2534 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2536 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2537 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2538 block
.add_statement (cdecl
);
2540 cdecl
= new
CCodeDeclaration ("DBusMessage");
2541 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2542 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2543 block
.add_statement (cdecl
);
2545 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2546 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2547 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2548 block
.add_statement (cdecl
);
2550 block
.add_statement (prefragment
);
2552 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2553 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2554 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2555 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2557 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2558 msgcall
.add_argument (destination
);
2559 msgcall
.add_argument (path
);
2560 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2561 msgcall
.add_argument (new
CCodeConstant ("\"Get\""));
2562 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2564 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2565 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2566 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2567 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2569 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2570 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2571 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2572 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2575 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2577 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2579 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_recurse"));
2580 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2581 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2582 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2584 check_property_inner_signature (prop
.get_accessor
, postfragment
);
2586 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2587 var target
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("result"));
2588 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2589 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2591 cdecl
= new
CCodeDeclaration (prop
.get_accessor
.value_type
.get_cname ());
2592 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result"));
2593 postfragment
.append (cdecl
);
2595 if (array_type
!= null) {
2596 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2597 cdecl
= new
CCodeDeclaration ("int");
2598 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_result_length%d".printf (dim
), new
CCodeConstant ("0")));
2599 postfragment
.append (cdecl
);
2603 var target
= new
CCodeIdentifier ("_result");
2604 var expr
= read_expression (postfragment
, prop
.get_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), target
);
2605 postfragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (target
, expr
)));
2607 if (array_type
!= null) {
2608 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2609 // TODO check that parameter is not NULL (out parameters are optional)
2610 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
)))));
2615 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2616 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2617 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2618 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2619 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2620 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2622 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2623 dbus_error_init
.add_argument (dbus_error
);
2624 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2626 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2627 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2629 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2630 ccall
.add_argument (connection
);
2631 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2632 ccall
.add_argument (get_dbus_timeout (prop
));
2633 ccall
.add_argument (dbus_error
);
2634 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2636 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2637 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2638 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2640 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2641 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2642 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2644 check_property_error_reply (prop
.get_accessor
, block
);
2645 check_property_reply_signature (prop
.get_accessor
, block
);
2647 block
.add_statement (postfragment
);
2649 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2650 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2651 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2653 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2654 block
.add_statement (new
CCodeReturnStatement ());
2656 block
.add_statement (new
CCodeReturnStatement (new
CCodeIdentifier ("_result")));
2659 cfile
.add_type_member_declaration (function
.copy ());
2660 function
.block
= block
;
2661 cfile
.add_function (function
);
2666 string generate_dbus_proxy_property_set (Interface main_iface
, Interface iface
, Property prop
) {
2667 string proxy_name
= "%sdbus_proxy_set_%s".printf (main_iface
.get_lower_case_cprefix (), prop
.name
);
2669 string dbus_iface_name
= get_dbus_name (iface
);
2671 var array_type
= prop
.set_accessor
.value_type as ArrayType
;
2673 CCodeDeclaration cdecl
;
2675 var function
= new
CCodeFunction (proxy_name
);
2676 function
.modifiers
= CCodeModifiers
.STATIC
;
2678 function
.add_parameter (new
CCodeFormalParameter ("self", "%s*".printf (iface
.get_cname ())));
2680 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2681 function
.add_parameter (new
CCodeFormalParameter ("value", "%s*".printf (prop
.set_accessor
.value_type
.get_cname ())));
2683 function
.add_parameter (new
CCodeFormalParameter ("value", prop
.set_accessor
.value_type
.get_cname ()));
2685 if (array_type
!= null) {
2686 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
2687 function
.add_parameter (new
CCodeFormalParameter ("value_length%d".printf (dim
), "int"));
2692 var block
= new
CCodeBlock ();
2693 var prefragment
= new
CCodeFragment ();
2694 var postfragment
= new
CCodeFragment ();
2696 var dispose_return_block
= new
CCodeBlock ();
2697 dispose_return_block
.add_statement (new
CCodeReturnStatement ());
2698 block
.add_statement (new
CCodeIfStatement (new CCodeMemberAccess
.pointer (new
CCodeCastExpression (new
CCodeIdentifier ("self"), iface
.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block
));
2700 cdecl
= new
CCodeDeclaration ("DBusError");
2701 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_dbus_error"));
2702 block
.add_statement (cdecl
);
2704 var dbus_error
= new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_dbus_error"));
2706 cdecl
= new
CCodeDeclaration ("DBusGConnection");
2707 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_connection"));
2708 block
.add_statement (cdecl
);
2710 cdecl
= new
CCodeDeclaration ("DBusMessage");
2711 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_message"));
2712 cdecl
.add_declarator (new
CCodeVariableDeclarator ("*_reply"));
2713 block
.add_statement (cdecl
);
2715 cdecl
= new
CCodeDeclaration ("DBusMessageIter");
2716 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_iter"));
2717 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_subiter"));
2718 block
.add_statement (cdecl
);
2720 block
.add_statement (prefragment
);
2722 var destination
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
2723 destination
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2724 var path
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_proxy_get_path"));
2725 path
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("self"), "DBusGProxy*"));
2727 var msgcall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_new_method_call"));
2728 msgcall
.add_argument (destination
);
2729 msgcall
.add_argument (path
);
2730 msgcall
.add_argument (new
CCodeConstant ("\"org.freedesktop.DBus.Properties\""));
2731 msgcall
.add_argument (new
CCodeConstant ("\"Set\""));
2732 prefragment
.append (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_message"), msgcall
)));
2734 var iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init_append"));
2735 iter_call
.add_argument (new
CCodeIdentifier ("_message"));
2736 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2737 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2739 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_init"));
2740 iter_call
.add_argument (new
CCodeIdentifier ("_reply"));
2741 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2742 postfragment
.append (new
CCodeExpressionStatement (iter_call
));
2745 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
2747 write_expression (prefragment
, string_type
, new
CCodeIdentifier ("_iter"), new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
2749 // property value (as variant)
2750 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_open_container"));
2751 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2752 iter_call
.add_argument (new
CCodeIdentifier ("DBUS_TYPE_VARIANT"));
2753 iter_call
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_type_signature (prop
.property_type
))));
2754 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2755 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2757 if (prop
.property_type
.is_real_non_null_struct_type ()) {
2758 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, new
CCodeIdentifier ("value")));
2760 write_expression (prefragment
, prop
.set_accessor
.value_type
, new
CCodeIdentifier ("_subiter"), new
CCodeIdentifier ("value"));
2763 iter_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_iter_close_container"));
2764 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_iter")));
2765 iter_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_subiter")));
2766 prefragment
.append (new
CCodeExpressionStatement (iter_call
));
2768 var gconnection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_get"));
2769 gconnection
.add_argument (new
CCodeIdentifier ("self"));
2770 gconnection
.add_argument (new
CCodeConstant ("\"connection\""));
2771 gconnection
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_connection")));
2772 gconnection
.add_argument (new
CCodeConstant ("NULL"));
2773 block
.add_statement (new
CCodeExpressionStatement (gconnection
));
2775 var dbus_error_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_error_init"));
2776 dbus_error_init
.add_argument (dbus_error
);
2777 block
.add_statement (new
CCodeExpressionStatement (dbus_error_init
));
2779 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_get_connection"));
2780 connection
.add_argument (new
CCodeIdentifier ("_connection"));
2782 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_connection_send_with_reply_and_block"));
2783 ccall
.add_argument (connection
);
2784 ccall
.add_argument (new
CCodeIdentifier ("_message"));
2785 ccall
.add_argument (get_dbus_timeout (prop
));
2786 ccall
.add_argument (dbus_error
);
2787 block
.add_statement (new
CCodeExpressionStatement (new
CCodeAssignment (new
CCodeIdentifier ("_reply"), ccall
)));
2789 var conn_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_g_connection_unref"));
2790 conn_unref
.add_argument (new
CCodeIdentifier ("_connection"));
2791 block
.add_statement (new
CCodeExpressionStatement (conn_unref
));
2793 var message_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2794 message_unref
.add_argument (new
CCodeIdentifier ("_message"));
2795 block
.add_statement (new
CCodeExpressionStatement (message_unref
));
2797 check_property_error_reply (prop
.set_accessor
, block
);
2798 check_property_reply_signature (prop
.set_accessor
, block
);
2800 block
.add_statement (postfragment
);
2802 var reply_unref
= new
CCodeFunctionCall (new
CCodeIdentifier ("dbus_message_unref"));
2803 reply_unref
.add_argument (new
CCodeIdentifier ("_reply"));
2804 block
.add_statement (new
CCodeExpressionStatement (reply_unref
));
2806 cfile
.add_type_member_declaration (function
.copy ());
2807 function
.block
= block
;
2808 cfile
.add_function (function
);