1 /* valagdbusservermodule.vala
3 * Copyright (C) 2010-2011 Jürg Billeter
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * Jürg Billeter <j@bitron.ch>
23 public class Vala
.GDBusServerModule
: GDBusClientModule
{
24 string generate_dbus_wrapper (Method m
, ObjectTypeSymbol sym
, bool ready
= false) {
25 string wrapper_name
= "_dbus_%s".printf (get_ccode_name (m
));
26 bool need_goto_label
= false;
28 if (m
.base_method
!= null) {
30 } else if (m
.base_interface_method
!= null) {
31 m
= m
.base_interface_method
;
35 // async ready function
36 wrapper_name
+= "_ready";
39 var function
= new
CCodeFunction (wrapper_name
);
40 function
.modifiers
= CCodeModifiers
.STATIC
;
43 function
.add_parameter (new
CCodeParameter ("self", get_ccode_name (sym
) + "*"));
44 function
.add_parameter (new
CCodeParameter ("_parameters_", "GVariant*"));
45 function
.add_parameter (new
CCodeParameter ("invocation", "GDBusMethodInvocation*"));
47 function
.add_parameter (new
CCodeParameter ("source_object", "GObject *"));
48 function
.add_parameter (new
CCodeParameter ("_res_", "GAsyncResult *"));
49 function
.add_parameter (new
CCodeParameter ("_user_data_", "gpointer"));
52 push_function (function
);
55 ccode
.add_declaration ("GDBusMethodInvocation *", new
CCodeVariableDeclarator ("invocation", new
CCodeIdentifier ("_user_data_")));
58 var connection
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_get_connection"));
59 connection
.add_argument (new
CCodeIdentifier ("invocation"));
61 bool no_reply
= is_dbus_no_reply (m
);
62 bool uses_fd
= dbus_method_uses_file_descriptor (m
);
64 cfile
.add_include ("gio/gunixfdlist.h");
65 ccode
.add_declaration ("GUnixFDList*", new
CCodeVariableDeclarator ("_fd_list"));
68 bool uses_error
= false;
70 if (!m
.coroutine
|| ready
) {
71 ccode
.add_declaration ("GError*", new CCodeVariableDeclarator
.zero ("error", new
CCodeConstant ("NULL")));
76 ccode
.add_declaration ("GVariantIter", new
CCodeVariableDeclarator ("_arguments_iter"));
78 var iter_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_iter_init"));
79 iter_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_iter")));
80 iter_init
.add_argument (new
CCodeIdentifier ("_parameters_"));
81 ccode
.add_expression (iter_init
);
84 CCodeFunctionCall ccall
;
86 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (get_ccode_name (m
)));
87 ccall
.add_argument (new
CCodeIdentifier ("self"));
89 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (get_ccode_finish_name (m
)));
90 ccall
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier ("source_object"), get_ccode_name (sym
) + "*"));
91 ccall
.add_argument (new
CCodeIdentifier ("_res_"));
96 ccode
.add_declaration ("gint", new CCodeVariableDeclarator
.zero ("_fd_index", new
CCodeConstant ("0")));
97 ccode
.add_declaration ("gint", new
CCodeVariableDeclarator ("_fd"));
100 foreach (Parameter param
in m
.get_parameters ()) {
101 string param_name
= get_variable_cname (param
.name
);
102 if (param
.direction
!= ParameterDirection
.IN
) {
106 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.Cancellable") {
110 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.BusName") {
111 // ignore BusName sender parameters
115 var owned_type
= param
.variable_type
.copy ();
116 owned_type
.value_owned
= true;
118 ccode
.add_declaration (get_ccode_name (owned_type
), new CCodeVariableDeclarator
.zero (param_name
, default_value_for_type (param
.variable_type
, true)));
120 var array_type
= param
.variable_type as ArrayType
;
121 if (array_type
!= null) {
122 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
123 string length_cname
= get_parameter_array_length_cname (param
, dim
);
125 ccode
.add_declaration ("int", new CCodeVariableDeclarator
.zero (length_cname
, new
CCodeConstant ("0")));
129 var message_expr
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_get_message"));
130 message_expr
.add_argument (new
CCodeIdentifier ("invocation"));
133 receive_dbus_value (param
.variable_type
, message_expr
, new
CCodeIdentifier ("_arguments_iter"), new
CCodeIdentifier (param_name
), param
, new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("error")), out may_fail
);
137 ccode
.add_declaration ("GError*", new CCodeVariableDeclarator
.zero ("error", new
CCodeConstant ("NULL")));
141 ccode
.open_if (new
CCodeIdentifier ("error"));
143 var return_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
144 return_error
.add_argument (new
CCodeIdentifier ("invocation"));
145 return_error
.add_argument (new
CCodeIdentifier ("error"));
146 ccode
.add_expression (return_error
);
148 if (need_goto_label
|| requires_destroy (owned_type
)) {
149 ccode
.add_goto ("_error");
150 need_goto_label
= true;
160 foreach (Parameter param
in m
.get_parameters ()) {
161 string param_name
= get_variable_cname (param
.name
);
162 if (param
.direction
== ParameterDirection
.IN
&& !ready
) {
163 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.Cancellable") {
164 ccall
.add_argument (new
CCodeConstant ("NULL"));
168 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.BusName") {
169 // ignore BusName sender parameters
170 var sender
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_get_sender"));
171 sender
.add_argument (new
CCodeIdentifier ("invocation"));
172 ccall
.add_argument (sender
);
176 var st
= param
.variable_type
.data_type as Struct
;
177 if (st
!= null && !st
.is_simple_type ()) {
178 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param_name
)));
180 ccall
.add_argument (new
CCodeIdentifier (param_name
));
182 } else if (param
.direction
== ParameterDirection
.OUT
&& (!m
.coroutine
|| ready
)) {
183 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (param_name
)));
186 var array_type
= param
.variable_type as ArrayType
;
187 if (array_type
!= null) {
188 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
189 string length_cname
= get_parameter_array_length_cname (param
, dim
);
191 if (param
.direction
== ParameterDirection
.IN
&& !ready
) {
192 ccall
.add_argument (new
CCodeIdentifier (length_cname
));
193 } else if (param
.direction
== ParameterDirection
.OUT
&& !no_reply
&& (!m
.coroutine
|| ready
)) {
194 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (length_cname
)));
200 if (!m
.coroutine
|| ready
) {
201 if (!(m
.return_type is VoidType
)) {
202 if (m
.return_type
.is_real_non_null_struct_type ()) {
203 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
205 var array_type
= m
.return_type as ArrayType
;
206 if (array_type
!= null) {
207 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
208 string length_cname
= get_array_length_cname ("result", dim
);
210 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (length_cname
)));
217 if (m
.coroutine
&& !ready
) {
218 ccall
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier (wrapper_name
+ "_ready"), "GAsyncReadyCallback"));
219 ccall
.add_argument (new
CCodeIdentifier ("invocation"));
222 if (!m
.coroutine
|| ready
) {
223 if (m
.get_error_types ().size
> 0) {
224 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("error")));
228 if (!no_reply
&& (!m
.coroutine
|| ready
)) {
229 if (m
.return_type is VoidType
|| m
.return_type
.is_real_non_null_struct_type ()) {
230 ccode
.add_expression (ccall
);
232 ccode
.add_assignment (new
CCodeIdentifier ("result"), ccall
);
235 if (m
.get_error_types ().size
> 0) {
236 ccode
.open_if (new
CCodeIdentifier ("error"));
238 var return_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
239 return_error
.add_argument (new
CCodeIdentifier ("invocation"));
240 return_error
.add_argument (new
CCodeIdentifier ("error"));
241 ccode
.add_expression (return_error
);
243 if (need_goto_label
) {
244 ccode
.add_goto ("_error");
252 ccode
.add_declaration ("GDBusMessage*", new CCodeVariableDeclarator
.zero ("_reply_message", new
CCodeConstant ("NULL")));
254 var message_expr
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_method_invocation_get_message"));
255 message_expr
.add_argument (new
CCodeIdentifier ("invocation"));
257 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_new_method_reply"));
258 ccall
.add_argument (message_expr
);
259 ccode
.add_assignment (new
CCodeIdentifier ("_reply_message"), ccall
);
261 ccode
.add_declaration ("GVariant*", new
CCodeVariableDeclarator ("_reply"));
262 ccode
.add_declaration ("GVariantBuilder", new
CCodeVariableDeclarator ("_reply_builder"));
264 var builder_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_init"));
265 builder_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_reply_builder")));
266 builder_init
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
267 ccode
.add_expression (builder_init
);
270 ccode
.add_assignment (new
CCodeIdentifier ("_fd_list"), new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_fd_list_new")));
273 foreach (Parameter param
in m
.get_parameters ()) {
274 if (param
.direction
!= ParameterDirection
.OUT
) {
278 string param_name
= get_variable_cname (param
.name
);
279 var owned_type
= param
.variable_type
.copy ();
280 owned_type
.value_owned
= true;
282 ccode
.add_declaration (get_ccode_name (owned_type
), new CCodeVariableDeclarator
.zero (param_name
, default_value_for_type (param
.variable_type
, true)));
284 var array_type
= param
.variable_type as ArrayType
;
285 if (array_type
!= null) {
286 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
287 string length_cname
= get_parameter_array_length_cname (param
, dim
);
289 ccode
.add_declaration ("int", new CCodeVariableDeclarator
.zero (length_cname
, new
CCodeConstant ("0")));
293 send_dbus_value (param
.variable_type
, new
CCodeIdentifier ("_reply_builder"), new
CCodeIdentifier (param_name
), param
);
296 if (!(m
.return_type is VoidType
)) {
297 if (m
.return_type
.is_real_non_null_struct_type ()) {
298 ccode
.add_declaration (get_ccode_name (m
.return_type
), new CCodeVariableDeclarator
.zero ("result", default_value_for_type (m
.return_type
, true)));
300 send_dbus_value (m
.return_type
, new
CCodeIdentifier ("_reply_builder"), new
CCodeIdentifier ("result"), m
);
302 if (requires_destroy (m
.return_type
)) {
303 // keep local alive (symbol_reference is weak)
304 var local
= new
LocalVariable (m
.return_type
, ".result");
305 ccode
.add_expression (destroy_local (local
));
308 ccode
.add_declaration (get_ccode_name (m
.return_type
), new
CCodeVariableDeclarator ("result"));
310 var array_type
= m
.return_type as ArrayType
;
311 if (array_type
!= null) {
312 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
313 string length_cname
= get_array_length_cname ("result", dim
);
315 ccode
.add_declaration ("int", new CCodeVariableDeclarator
.zero (length_cname
, new
CCodeConstant ("0")));
319 send_dbus_value (m
.return_type
, new
CCodeIdentifier ("_reply_builder"), new
CCodeIdentifier ("result"), m
);
321 if (requires_destroy (m
.return_type
)) {
322 // keep local alive (symbol_reference is weak)
323 var local
= new
LocalVariable (m
.return_type
, ".result");
324 ccode
.add_expression (destroy_local (local
));
329 var builder_end
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_end"));
330 builder_end
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_reply_builder")));
331 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), builder_end
);
333 var set_body
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_set_body"));
334 set_body
.add_argument (new
CCodeIdentifier ("_reply_message"));
335 set_body
.add_argument (new
CCodeIdentifier ("_reply"));
336 ccode
.add_expression (set_body
);
339 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
340 ccall
.add_argument (new
CCodeIdentifier ("_reply_message"));
341 ccall
.add_argument (new
CCodeIdentifier ("_fd_list"));
342 ccode
.add_expression (ccall
);
344 ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
345 ccall
.add_argument (new
CCodeIdentifier ("_fd_list"));
346 ccode
.add_expression (ccall
);
349 ccode
.add_expression (ccall
);
352 if (!no_reply
&& (!m
.coroutine
|| ready
)) {
353 var return_value
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_send_message"));
354 return_value
.add_argument (connection
);
355 return_value
.add_argument (new
CCodeIdentifier ("_reply_message"));
356 return_value
.add_argument (new
CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
357 return_value
.add_argument (new
CCodeConstant ("NULL"));
358 return_value
.add_argument (new
CCodeConstant ("NULL"));
359 ccode
.add_expression (return_value
);
361 // free invocation like g_dbus_method_invocation_return_*
362 var unref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
363 unref_call
.add_argument (new
CCodeIdentifier ("invocation"));
364 ccode
.add_expression (unref_call
);
366 unref_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
367 unref_call
.add_argument (new
CCodeIdentifier ("_reply_message"));
368 ccode
.add_expression (unref_call
);
371 if (need_goto_label
) {
372 ccode
.add_label ("_error");
375 foreach (Parameter param
in m
.get_parameters ()) {
376 if ((param
.direction
== ParameterDirection
.IN
&& !ready
) ||
377 (param
.direction
== ParameterDirection
.OUT
&& !no_reply
&& (!m
.coroutine
|| ready
))) {
378 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.Cancellable") {
382 if (param
.variable_type is ObjectType
&& param
.variable_type
.data_type
.get_full_name () == "GLib.BusName") {
383 // ignore BusName sender parameters
387 var owned_type
= param
.variable_type
.copy ();
388 owned_type
.value_owned
= true;
390 if (requires_destroy (owned_type
)) {
391 // keep local alive (symbol_reference is weak)
392 var local
= new
LocalVariable (owned_type
, get_variable_cname (param
.name
));
393 ccode
.add_expression (destroy_local (local
));
400 cfile
.add_function_declaration (function
);
401 cfile
.add_function (function
);
403 if (m
.coroutine
&& !ready
) {
404 // generate ready function
405 generate_dbus_wrapper (m
, sym
, true);
411 string generate_dbus_signal_wrapper (Signal sig
, ObjectTypeSymbol sym
, string dbus_iface_name
) {
412 string wrapper_name
= "_dbus_%s_%s".printf (get_ccode_lower_case_name (sym
), get_ccode_lower_case_name (sig
));
414 var function
= new
CCodeFunction (wrapper_name
, "void");
415 function
.modifiers
= CCodeModifiers
.STATIC
;
417 function
.add_parameter (new
CCodeParameter ("_sender", "GObject*"));
419 foreach (var param
in sig
.get_parameters ()) {
420 // ensure ccodenode of parameter is set
421 var cparam
= generate_parameter (param
, cfile
, new HashMap
<int,CCodeParameter
> (), null);
423 function
.add_parameter (cparam
);
424 if (param
.variable_type is ArrayType
) {
425 var array_type
= (ArrayType
) param
.variable_type
;
426 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
427 function
.add_parameter (new
CCodeParameter (get_parameter_array_length_cname (param
, dim
), "int"));
432 function
.add_parameter (new
CCodeParameter ("_data", "gpointer*"));
434 push_function (function
);
436 ccode
.add_declaration ("GDBusConnection *", new
CCodeVariableDeclarator ("_connection", new
CCodeElementAccess (new
CCodeIdentifier ("_data"), new
CCodeConstant ("1"))));
437 ccode
.add_declaration ("const gchar *", new
CCodeVariableDeclarator ("_path", new
CCodeElementAccess (new
CCodeIdentifier ("_data"), new
CCodeConstant ("2"))));
438 ccode
.add_declaration ("GVariant", new
CCodeVariableDeclarator ("*_arguments"));
439 ccode
.add_declaration ("GVariantBuilder", new
CCodeVariableDeclarator ("_arguments_builder"));
441 var builder_init
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_init"));
442 builder_init
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
443 builder_init
.add_argument (new
CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
444 ccode
.add_expression (builder_init
);
446 foreach (Parameter param
in sig
.get_parameters ()) {
447 string param_name
= get_variable_cname (param
.name
);
448 CCodeExpression expr
= new
CCodeIdentifier (param_name
);
449 if (param
.variable_type
.is_real_struct_type ()) {
450 expr
= new
CCodeUnaryExpression (CCodeUnaryOperator
.POINTER_INDIRECTION
, expr
);
452 write_expression (param
.variable_type
, new
CCodeIdentifier ("_arguments_builder"), expr
, param
);
455 var builder_end
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_end"));
456 builder_end
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_arguments_builder")));
457 ccode
.add_assignment (new
CCodeIdentifier ("_arguments"), builder_end
);
459 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_emit_signal"));
460 ccall
.add_argument (new
CCodeIdentifier ("_connection"));
461 ccall
.add_argument (new
CCodeConstant ("NULL"));
462 ccall
.add_argument (new
CCodeIdentifier ("_path"));
463 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (dbus_iface_name
)));
464 ccall
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig
))));
465 ccall
.add_argument (new
CCodeIdentifier ("_arguments"));
466 ccall
.add_argument (new
CCodeConstant ("NULL"));
467 ccode
.add_expression (ccall
);
471 cfile
.add_function_declaration (function
);
472 cfile
.add_function (function
);
477 string generate_dbus_property_get_wrapper (Property prop
, ObjectTypeSymbol sym
) {
478 string wrapper_name
= "_dbus_%s".printf (get_ccode_name (prop
.get_accessor
));
480 var function
= new
CCodeFunction (wrapper_name
, "GVariant*");
481 function
.modifiers
= CCodeModifiers
.STATIC
;
482 function
.add_parameter (new
CCodeParameter ("self", get_ccode_name (sym
) + "*"));
484 push_function (function
);
486 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (get_ccode_name (prop
.get_accessor
)));
487 ccall
.add_argument (new
CCodeIdentifier ("self"));
489 if (prop
.get_accessor
.value_type
.is_real_non_null_struct_type ()) {
490 ccode
.add_declaration (get_ccode_name (prop
.get_accessor
.value_type
), new CCodeVariableDeclarator
.zero ("result", default_value_for_type (prop
.get_accessor
.value_type
, true)));
491 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("result")));
493 ccode
.add_expression (ccall
);
495 ccode
.add_declaration (get_ccode_name (prop
.get_accessor
.value_type
), new
CCodeVariableDeclarator ("result"));
496 ccode
.add_assignment (new
CCodeIdentifier ("result"), ccall
);
498 var array_type
= prop
.get_accessor
.value_type as ArrayType
;
499 if (array_type
!= null) {
500 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
501 string length_cname
= get_array_length_cname ("result", dim
);
503 ccode
.add_declaration ("int", new CCodeVariableDeclarator
.zero (length_cname
, new
CCodeConstant ("0")));
504 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (length_cname
)));
509 ccode
.add_declaration ("GVariant*", new
CCodeVariableDeclarator ("_reply"));
511 if (get_dbus_signature (prop
) != null) {
513 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), new
CCodeIdentifier("result"));
515 var reply_expr
= serialize_expression (prop
.get_accessor
.value_type
, new
CCodeIdentifier ("result"));
517 ccode
.add_assignment (new
CCodeIdentifier ("_reply"), reply_expr
);
519 if (requires_destroy (prop
.get_accessor
.value_type
)) {
520 // keep local alive (symbol_reference is weak)
521 var local
= new
LocalVariable (prop
.get_accessor
.value_type
, ".result");
522 ccode
.add_expression (destroy_local (local
));
526 ccode
.add_return (new
CCodeIdentifier ("_reply"));
530 cfile
.add_function_declaration (function
);
531 cfile
.add_function (function
);
536 string generate_dbus_property_set_wrapper (Property prop
, ObjectTypeSymbol sym
) {
537 string wrapper_name
= "_dbus_%s".printf (get_ccode_name (prop
.set_accessor
));
539 var function
= new
CCodeFunction (wrapper_name
);
540 function
.modifiers
= CCodeModifiers
.STATIC
;
541 function
.add_parameter (new
CCodeParameter ("self", get_ccode_name (sym
) + "*"));
542 function
.add_parameter (new
CCodeParameter ("_value", "GVariant*"));
544 push_function (function
);
546 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (get_ccode_name (prop
.set_accessor
)));
547 ccall
.add_argument (new
CCodeIdentifier ("self"));
549 var owned_type
= prop
.property_type
.copy ();
550 owned_type
.value_owned
= true;
552 ccode
.add_declaration (get_ccode_name (owned_type
), new CCodeVariableDeclarator
.zero ("value", default_value_for_type (prop
.property_type
, true)));
554 var st
= prop
.property_type
.data_type as Struct
;
555 if (st
!= null && !st
.is_simple_type ()) {
556 ccall
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("value")));
558 ccall
.add_argument (new
CCodeIdentifier ("value"));
560 var array_type
= prop
.property_type as ArrayType
;
561 if (array_type
!= null) {
562 for (int dim
= 1; dim
<= array_type
.rank
; dim
++) {
563 ccode
.add_declaration ("int", new
CCodeVariableDeclarator (get_array_length_cname ("value", dim
)));
564 ccall
.add_argument (new
CCodeIdentifier (get_array_length_cname ("value", dim
)));
569 var target
= new
CCodeIdentifier ("value");
571 if (get_dbus_signature (prop
) != null) {
572 ccode
.add_assignment (target
, new
CCodeIdentifier("_value"));
573 ccode
.add_expression (ccall
);
575 var expr
= deserialize_expression (prop
.property_type
, new
CCodeIdentifier ("_value"), target
);
576 ccode
.add_assignment (target
, expr
);
577 ccode
.add_expression (ccall
);
579 if (requires_destroy (owned_type
)) {
580 // keep local alive (symbol_reference is weak)
581 var local
= new
LocalVariable (owned_type
, "value");
582 ccode
.add_expression (destroy_local (local
));
588 cfile
.add_function_declaration (function
);
589 cfile
.add_function (function
);
594 void handle_signals (ObjectTypeSymbol sym
, bool connect
) {
595 string dbus_iface_name
= get_dbus_name (sym
);
596 if (dbus_iface_name
== null) {
600 foreach (Signal sig
in sym
.get_signals ()) {
601 if (sig
.access
!= SymbolAccessibility
.PUBLIC
) {
604 if (!is_dbus_visible (sig
)) {
609 var connect_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_connect"));
610 connect_call
.add_argument (new
CCodeIdentifier ("object"));
611 connect_call
.add_argument (get_signal_canonical_constant (sig
));
612 connect_call
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier (generate_dbus_signal_wrapper (sig
, sym
, dbus_iface_name
)), "GCallback"));
613 connect_call
.add_argument (new
CCodeIdentifier ("data"));
614 ccode
.add_expression (connect_call
);
616 // disconnect the signals
617 var disconnect_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_signal_handlers_disconnect_by_func"));
618 disconnect_call
.add_argument (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0")));
619 disconnect_call
.add_argument (new
CCodeIdentifier ("_dbus_%s_%s".printf (get_ccode_lower_case_name (sym
), get_ccode_lower_case_name (sig
))));
620 disconnect_call
.add_argument (new
CCodeIdentifier ("data"));
621 ccode
.add_expression (disconnect_call
);
626 void generate_interface_method_call_function (ObjectTypeSymbol sym
) {
627 var cfunc
= new
CCodeFunction (get_ccode_lower_case_prefix (sym
) + "dbus_interface_method_call", "void");
628 cfunc
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
629 cfunc
.add_parameter (new
CCodeParameter ("sender", "const gchar*"));
630 cfunc
.add_parameter (new
CCodeParameter ("object_path", "const gchar*"));
631 cfunc
.add_parameter (new
CCodeParameter ("interface_name", "const gchar*"));
632 cfunc
.add_parameter (new
CCodeParameter ("method_name", "const gchar*"));
633 cfunc
.add_parameter (new
CCodeParameter ("parameters", "GVariant*"));
634 cfunc
.add_parameter (new
CCodeParameter ("invocation", "GDBusMethodInvocation*"));
635 cfunc
.add_parameter (new
CCodeParameter ("user_data", "gpointer"));
637 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
639 push_function (cfunc
);
641 ccode
.add_declaration ("gpointer*", new
CCodeVariableDeclarator ("data", new
CCodeIdentifier ("user_data")));
642 ccode
.add_declaration ("gpointer", new
CCodeVariableDeclarator ("object", new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0"))));
646 foreach (Method m
in sym
.get_methods ()) {
647 if (m is CreationMethod
|| m
.binding
!= MemberBinding
.INSTANCE
648 || m
.overrides
|| m
.access
!= SymbolAccessibility
.PUBLIC
) {
651 if (!is_dbus_visible (m
)) {
655 cfile
.add_include ("string.h");
657 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
658 ccheck
.add_argument (new
CCodeIdentifier ("method_name"));
659 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m
))));
662 ccode
.open_if (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, ccheck
, new
CCodeConstant ("0")));
665 ccode
.else_if (new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, ccheck
, new
CCodeConstant ("0")));
668 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_dbus_wrapper (m
, sym
)));
669 ccall
.add_argument (new
CCodeIdentifier ("object"));
670 ccall
.add_argument (new
CCodeIdentifier ("parameters"));
671 ccall
.add_argument (new
CCodeIdentifier ("invocation"));
672 ccode
.add_expression (ccall
);
679 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
680 ccall
.add_argument (new
CCodeIdentifier ("invocation"));
681 ccode
.add_expression (ccall
);
689 cfile
.add_function_declaration (cfunc
);
690 cfile
.add_function (cfunc
);
693 void generate_interface_get_property_function (ObjectTypeSymbol sym
) {
694 var cfunc
= new
CCodeFunction (get_ccode_lower_case_prefix (sym
) + "dbus_interface_get_property", "GVariant*");
695 cfunc
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
696 cfunc
.add_parameter (new
CCodeParameter ("sender", "const gchar*"));
697 cfunc
.add_parameter (new
CCodeParameter ("object_path", "const gchar*"));
698 cfunc
.add_parameter (new
CCodeParameter ("interface_name", "const gchar*"));
699 cfunc
.add_parameter (new
CCodeParameter ("property_name", "const gchar*"));
700 cfunc
.add_parameter (new
CCodeParameter ("error", "GError**"));
701 cfunc
.add_parameter (new
CCodeParameter ("user_data", "gpointer"));
703 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
705 cfile
.add_function_declaration (cfunc
);
707 push_function (cfunc
);
709 ccode
.add_declaration ("gpointer*", new
CCodeVariableDeclarator ("data", new
CCodeIdentifier ("user_data")));
711 ccode
.add_declaration ("gpointer", new
CCodeVariableDeclarator ("object", new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0"))));
715 foreach (Property prop
in sym
.get_properties ()) {
716 if (prop
.binding
!= MemberBinding
.INSTANCE
717 || prop
.overrides
|| prop
.access
!= SymbolAccessibility
.PUBLIC
) {
720 if (!is_dbus_visible (prop
)) {
723 if (prop
.get_accessor
== null) {
727 cfile
.add_include ("string.h");
729 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
730 ccheck
.add_argument (new
CCodeIdentifier ("property_name"));
731 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
733 var cond
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, ccheck
, new
CCodeConstant ("0"));
735 ccode
.open_if (cond
);
738 ccode
.else_if (cond
);
741 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_dbus_property_get_wrapper (prop
, sym
)));
742 ccall
.add_argument (new
CCodeIdentifier ("object"));
744 ccode
.add_return (ccall
);
750 ccode
.add_return (new
CCodeConstant ("NULL"));
753 cfile
.add_function (cfunc
);
756 void generate_interface_set_property_function (ObjectTypeSymbol sym
) {
757 var cfunc
= new
CCodeFunction (get_ccode_lower_case_prefix (sym
) + "dbus_interface_set_property", "gboolean");
758 cfunc
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
759 cfunc
.add_parameter (new
CCodeParameter ("sender", "const gchar*"));
760 cfunc
.add_parameter (new
CCodeParameter ("object_path", "const gchar*"));
761 cfunc
.add_parameter (new
CCodeParameter ("interface_name", "const gchar*"));
762 cfunc
.add_parameter (new
CCodeParameter ("property_name", "const gchar*"));
763 cfunc
.add_parameter (new
CCodeParameter ("value", "GVariant*"));
764 cfunc
.add_parameter (new
CCodeParameter ("error", "GError**"));
765 cfunc
.add_parameter (new
CCodeParameter ("user_data", "gpointer"));
767 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
769 cfile
.add_function_declaration (cfunc
);
771 push_function (cfunc
);
773 ccode
.add_declaration ("gpointer*", new
CCodeVariableDeclarator ("data", new
CCodeIdentifier ("user_data")));
775 ccode
.add_declaration ("gpointer", new
CCodeVariableDeclarator ("object", new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0"))));
779 foreach (Property prop
in sym
.get_properties ()) {
780 if (prop
.binding
!= MemberBinding
.INSTANCE
781 || prop
.overrides
|| prop
.access
!= SymbolAccessibility
.PUBLIC
) {
784 if (!is_dbus_visible (prop
)) {
787 if (prop
.set_accessor
== null) {
791 cfile
.add_include ("string.h");
793 var ccheck
= new
CCodeFunctionCall (new
CCodeIdentifier ("strcmp"));
794 ccheck
.add_argument (new
CCodeIdentifier ("property_name"));
795 ccheck
.add_argument (new
CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop
))));
797 var cond
= new
CCodeBinaryExpression (CCodeBinaryOperator
.EQUALITY
, ccheck
, new
CCodeConstant ("0"));
799 ccode
.open_if (cond
);
802 ccode
.else_if (cond
);
805 var ccall
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_dbus_property_set_wrapper (prop
, sym
)));
806 ccall
.add_argument (new
CCodeIdentifier ("object"));
807 ccall
.add_argument (new
CCodeIdentifier ("value"));
809 ccode
.add_expression (ccall
);
810 ccode
.add_return (new
CCodeConstant ("TRUE"));
815 ccode
.add_return (new
CCodeConstant ("FALSE"));
818 cfile
.add_function (cfunc
);
821 CCodeExpression
get_interface_vtable (ObjectTypeSymbol sym
) {
822 var vtable
= new
CCodeInitializerList ();
823 vtable
.append (new
CCodeIdentifier (get_ccode_lower_case_prefix (sym
) + "dbus_interface_method_call"));
824 vtable
.append (new
CCodeIdentifier (get_ccode_lower_case_prefix (sym
) + "dbus_interface_get_property"));
825 vtable
.append (new
CCodeIdentifier (get_ccode_lower_case_prefix (sym
) + "dbus_interface_set_property"));
827 generate_interface_method_call_function (sym
);
828 generate_interface_get_property_function (sym
);
829 generate_interface_set_property_function (sym
);
831 var cdecl
= new
CCodeDeclaration ("const GDBusInterfaceVTable");
832 cdecl
.add_declarator (new
CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym
) + "dbus_interface_vtable", vtable
));
833 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
834 cfile
.add_constant_declaration (cdecl
);
836 return new
CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym
) + "dbus_interface_vtable");
839 string generate_register_object_function () {
840 string register_object_func
= "_vala_g_dbus_connection_register_object";
842 if (!add_wrapper (register_object_func
)) {
843 return register_object_func
;
846 cfile
.add_include ("gio/gio.h");
848 var function
= new
CCodeFunction (register_object_func
, "guint");
849 function
.modifiers
= CCodeModifiers
.STATIC
;
851 function
.add_parameter (new
CCodeParameter ("type", "GType"));
852 function
.add_parameter (new
CCodeParameter ("object", "void*"));
853 function
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
854 function
.add_parameter (new
CCodeParameter ("path", "const gchar*"));
855 function
.add_parameter (new
CCodeParameter ("error", "GError**"));
857 push_function (function
);
859 var quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
860 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-register-object\""));
862 var get_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_get_qdata"));
863 get_qdata
.add_argument (new
CCodeIdentifier ("type"));
864 get_qdata
.add_argument (quark
);
866 ccode
.add_declaration ("void", new
CCodeVariableDeclarator ("*func"));
867 ccode
.add_assignment (new
CCodeIdentifier ("func"), get_qdata
);
869 ccode
.open_if (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("func")));
870 // no D-Bus interface
873 var set_error
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_set_error_literal"));
874 set_error
.add_argument (new
CCodeIdentifier ("error"));
875 set_error
.add_argument (new
CCodeIdentifier ("G_IO_ERROR"));
876 set_error
.add_argument (new
CCodeIdentifier ("G_IO_ERROR_FAILED"));
877 set_error
.add_argument (new
CCodeConstant ("\"The specified type does not support D-Bus registration\""));
878 ccode
.add_expression (set_error
);
880 ccode
.add_return (new
CCodeConstant ("0"));
884 var register_object
= new
CCodeCastExpression (new
CCodeIdentifier ("func"), "guint (*) (void *, GDBusConnection *, const gchar *, GError **)");
886 var ccall
= new
CCodeFunctionCall (register_object
);
887 ccall
.add_argument (new
CCodeIdentifier ("object"));
888 ccall
.add_argument (new
CCodeIdentifier ("connection"));
889 ccall
.add_argument (new
CCodeIdentifier ("path"));
890 ccall
.add_argument (new
CCodeIdentifier ("error"));
892 ccode
.add_return (ccall
);
896 cfile
.add_function_declaration (function
);
897 cfile
.add_function (function
);
899 return register_object_func
;
902 public override void visit_method_call (MethodCall expr
) {
903 var mtype
= expr
.call
.value_type as MethodType
;
904 if (mtype
== null || get_ccode_name (mtype
.method_symbol
) != "g_dbus_connection_register_object") {
905 base.visit_method_call (expr
);
909 var ma
= (MemberAccess
) expr
.call
;
910 var type_arg
= ma
.get_type_arguments ().get (0);
912 CCodeFunctionCall cregister
;
914 var object_type
= type_arg as ObjectType
;
915 if (object_type
!= null) {
916 if (get_dbus_name (object_type
.type_symbol
) == null) {
917 Report
.error (expr
.source_reference
, "DBusConnection.register_object requires type argument with [DBus (name = ...)] attribute");
921 cregister
= new
CCodeFunctionCall (new
CCodeIdentifier ("%sregister_object".printf (get_ccode_lower_case_prefix (object_type
.type_symbol
))));
923 // use runtime type information for generic methods
924 cregister
= new
CCodeFunctionCall (new
CCodeIdentifier (generate_register_object_function ()));
925 cregister
.add_argument (get_type_id_expression (type_arg
));
928 var args
= expr
.get_argument_list ();
929 var path_arg
= args
[0];
930 var obj_arg
= args
[1];
933 current_method_inner_error
= true;
935 cregister
.add_argument (get_cvalue (obj_arg
));
936 cregister
.add_argument (get_cvalue (ma
.inner
));
937 cregister
.add_argument (get_cvalue (path_arg
));
938 cregister
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_variable_cexpression ("_inner_error_")));
940 if (expr
.parent_node is ExpressionStatement
) {
941 ccode
.add_expression (cregister
);
943 var temp_var
= get_temp_variable (expr
.value_type
, expr
.value_type
.value_owned
);
944 var temp_ref
= get_variable_cexpression (temp_var
.name
);
946 emit_temp_var (temp_var
);
948 ccode
.add_assignment (temp_ref
, cregister
);
949 set_cvalue (expr
, temp_ref
);
953 public override void generate_class_declaration (Class cl
, CCodeFile decl_space
) {
954 base.generate_class_declaration (cl
, decl_space
);
956 generate_object_type_symbol_declaration (cl
, decl_space
);
959 public override void generate_interface_declaration (Interface iface
, CCodeFile decl_space
) {
960 base.generate_interface_declaration (iface
, decl_space
);
962 generate_object_type_symbol_declaration (iface
, decl_space
);
965 public override void visit_class (Class cl
) {
966 base.visit_class (cl
);
968 visit_object_type_symbol (cl
);
971 public override void visit_interface (Interface iface
) {
972 base.visit_interface (iface
);
974 visit_object_type_symbol (iface
);
977 void generate_object_type_symbol_declaration (ObjectTypeSymbol sym
, CCodeFile decl_space
) {
978 string dbus_iface_name
= get_dbus_name (sym
);
979 if (dbus_iface_name
== null) {
983 string register_object_name
= "%sregister_object".printf (get_ccode_lower_case_prefix (sym
));
985 if (add_symbol_declaration (decl_space
, sym
, register_object_name
)) {
989 decl_space
.add_include ("gio/gio.h");
991 // declare register_object function
992 var cfunc
= new
CCodeFunction (register_object_name
, "guint");
993 cfunc
.add_parameter (new
CCodeParameter ("object", "void*"));
994 cfunc
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
995 cfunc
.add_parameter (new
CCodeParameter ("path", "const gchar*"));
996 cfunc
.add_parameter (new
CCodeParameter ("error", "GError**"));
997 if (sym
.is_private_symbol ()) {
998 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
999 } else if (context
.hide_internal
&& sym
.is_internal_symbol ()) {
1000 cfunc
.modifiers
|= CCodeModifiers
.INTERNAL
;
1002 decl_space
.add_function_declaration (cfunc
);
1005 void visit_object_type_symbol (ObjectTypeSymbol sym
) {
1006 // only support registering a single D-Bus interface at a time (unlike old D-Bus support)
1007 // however, register_object can be invoked multiple times for the same object path with different interfaces
1008 string dbus_iface_name
= get_dbus_name (sym
);
1009 if (dbus_iface_name
== null) {
1013 cfile
.add_include ("gio/gio.h");
1015 var cfunc
= new
CCodeFunction (get_ccode_lower_case_prefix (sym
) + "register_object", "guint");
1016 cfunc
.add_parameter (new
CCodeParameter ("object", "gpointer"));
1017 cfunc
.add_parameter (new
CCodeParameter ("connection", "GDBusConnection*"));
1018 cfunc
.add_parameter (new
CCodeParameter ("path", "const gchar*"));
1019 cfunc
.add_parameter (new
CCodeParameter ("error", "GError**"));
1020 if (sym
.is_private_symbol ()) {
1021 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
1022 } else if (context
.hide_internal
&& sym
.is_internal_symbol ()) {
1023 cfunc
.modifiers
|= CCodeModifiers
.INTERNAL
;
1026 push_function (cfunc
);
1028 ccode
.add_declaration ("guint", new
CCodeVariableDeclarator ("result"));
1031 // data consists of 3 pointers: object, connection, path
1032 ccode
.add_declaration ("gpointer", new
CCodeVariableDeclarator ("*data"));
1034 var alloc_data
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_new"));
1035 alloc_data
.add_argument (new
CCodeIdentifier ("gpointer"));
1036 alloc_data
.add_argument (new
CCodeConstant ("3"));
1037 ccode
.add_assignment (new
CCodeIdentifier ("data"), alloc_data
);
1039 var ref_function
= get_ccode_ref_function (sym
);
1040 if (sym is Interface
&& ref_function
== null) {
1041 Report
.error (sym
.source_reference
, "missing class prerequisite for interface `%s', add GLib.Object to interface declaration if unsure".printf (sym
.get_full_name ()));
1045 var ref_object
= new
CCodeFunctionCall (new
CCodeIdentifier (ref_function
));
1046 ref_object
.add_argument (new
CCodeIdentifier ("object"));
1047 ccode
.add_assignment (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0")), ref_object
);
1049 ref_object
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_ref"));
1050 ref_object
.add_argument (new
CCodeIdentifier ("connection"));
1051 ccode
.add_assignment (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("1")), ref_object
);
1053 var dup_path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_strdup"));
1054 dup_path
.add_argument (new
CCodeIdentifier ("path"));
1055 ccode
.add_assignment (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("2")), dup_path
);
1058 var cregister
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_connection_register_object"));
1059 cregister
.add_argument (new
CCodeIdentifier ("connection"));
1060 cregister
.add_argument (new
CCodeIdentifier ("path"));
1062 cregister
.add_argument (new
CCodeCastExpression (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_interface_info (sym
)), "GDBusInterfaceInfo *"));
1063 cregister
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, get_interface_vtable (sym
)));
1065 cregister
.add_argument (new
CCodeIdentifier ("data"));
1066 cregister
.add_argument (new
CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym
) + "unregister_object"));
1067 cregister
.add_argument (new
CCodeIdentifier ("error"));
1069 ccode
.add_assignment (new
CCodeIdentifier ("result"), cregister
);
1071 ccode
.open_if (new
CCodeUnaryExpression (CCodeUnaryOperator
.LOGICAL_NEGATION
, new
CCodeIdentifier ("result")));
1072 ccode
.add_return (new
CCodeConstant ("0"));
1075 handle_signals (sym
, true);
1077 ccode
.add_return (new
CCodeIdentifier ("result"));
1080 cfile
.add_function (cfunc
);
1083 cfunc
= new
CCodeFunction ("_" + get_ccode_lower_case_prefix (sym
) + "unregister_object");
1084 cfunc
.add_parameter (new
CCodeParameter ("user_data", "gpointer"));
1085 cfunc
.modifiers
|= CCodeModifiers
.STATIC
;
1087 push_function (cfunc
);
1089 ccode
.add_declaration ("gpointer*", new
CCodeVariableDeclarator ("data", new
CCodeIdentifier ("user_data")));
1091 handle_signals (sym
, false);
1093 var unref_object
= new
CCodeFunctionCall (new
CCodeIdentifier (get_ccode_unref_function (sym
)));
1094 unref_object
.add_argument (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("0")));
1095 ccode
.add_expression (unref_object
);
1097 unref_object
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_object_unref"));
1098 unref_object
.add_argument (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("1")));
1099 ccode
.add_expression (unref_object
);
1101 var free_path
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1102 free_path
.add_argument (new
CCodeElementAccess (new
CCodeIdentifier ("data"), new
CCodeConstant ("2")));
1103 ccode
.add_expression (free_path
);
1105 var free_data
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_free"));
1106 free_data
.add_argument (new
CCodeIdentifier ("data"));
1107 ccode
.add_expression (free_data
);
1110 cfile
.add_function_declaration (cfunc
);
1111 cfile
.add_function (cfunc
);
1114 public override void register_dbus_info (CCodeBlock block
, ObjectTypeSymbol sym
) {
1115 string dbus_iface_name
= get_dbus_name (sym
);
1116 if (dbus_iface_name
== null) {
1120 base.register_dbus_info (block
, sym
);
1122 var quark
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_quark_from_static_string"));
1123 quark
.add_argument (new
CCodeConstant ("\"vala-dbus-register-object\""));
1125 var set_qdata
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_type_set_qdata"));
1126 set_qdata
.add_argument (new
CCodeIdentifier ("%s_type_id".printf (get_ccode_lower_case_name (sym
, null))));
1127 set_qdata
.add_argument (quark
);
1128 set_qdata
.add_argument (new
CCodeCastExpression (new
CCodeIdentifier (get_ccode_lower_case_prefix (sym
) + "register_object"), "void*"));
1130 block
.add_statement (new
CCodeExpressionStatement (set_qdata
));