1 /* valagdbusmodule.vala
3 * Copyright (C) 2010 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
.GDBusModule
: GVariantModule
{
24 public static string?
get_dbus_name (TypeSymbol symbol
) {
25 var dbus
= symbol
.get_attribute ("DBus");
30 return dbus
.get_string ("name");
33 public static string get_dbus_name_for_member (Symbol symbol
) {
34 var dbus
= symbol
.get_attribute ("DBus");
35 if (dbus
!= null && dbus
.has_argument ("name")) {
36 return dbus
.get_string ("name");
39 return Symbol
.lower_case_to_camel_case (symbol
.name
);
42 public static bool is_dbus_no_reply (Method m
) {
43 var dbus_attribute
= m
.get_attribute ("DBus");
44 if (dbus_attribute
!= null
45 && dbus_attribute
.has_argument ("no_reply")
46 && dbus_attribute
.get_bool ("no_reply")) {
53 public override void visit_error_domain (ErrorDomain edomain
) {
54 var edomain_dbus_name
= get_dbus_name (edomain
);
55 if (edomain_dbus_name
== null) {
56 base.visit_error_domain (edomain
);
60 generate_error_domain_declaration (edomain
, cfile
);
62 if (!edomain
.is_internal_symbol ()) {
63 generate_error_domain_declaration (edomain
, header_file
);
65 if (!edomain
.is_private_symbol ()) {
66 generate_error_domain_declaration (edomain
, internal_header_file
);
69 var error_entries
= new
CCodeInitializerList ();
70 foreach (ErrorCode ecode
in edomain
.get_codes ()) {
71 var ecode_dbus_name
= get_dbus_name (ecode
);
72 if (ecode_dbus_name
== null) {
73 ecode_dbus_name
= Symbol
.lower_case_to_camel_case (ecode
.name
.down ());
76 var error_entry
= new
CCodeInitializerList ();
77 error_entry
.append (new
CCodeIdentifier (ecode
.get_cname ()));
78 error_entry
.append (new
CCodeConstant ("\"%s.%s\"".printf (edomain_dbus_name
, ecode_dbus_name
)));
79 error_entries
.append (error_entry
);
82 var cdecl
= new
CCodeDeclaration ("const GDBusErrorEntry");
83 cdecl
.add_declarator (new
CCodeVariableDeclarator (edomain
.get_lower_case_cname () + "_entries[]", error_entries
));
84 cdecl
.modifiers
= CCodeModifiers
.STATIC
;
85 cfile
.add_constant_declaration (cdecl
);
87 string quark_fun_name
= edomain
.get_lower_case_cprefix () + "quark";
89 var cquark_fun
= new
CCodeFunction (quark_fun_name
, gquark_type
.data_type
.get_cname ());
90 var cquark_block
= new
CCodeBlock ();
92 string quark_name
= "%squark_volatile".printf (edomain
.get_lower_case_cprefix ());
94 cdecl
= new
CCodeDeclaration ("gsize");
95 cdecl
.add_declarator (new
CCodeVariableDeclarator (quark_name
, new
CCodeConstant ("0")));
96 cdecl
.modifiers
= CCodeModifiers
.STATIC
| CCodeModifiers
.VOLATILE
;
97 cquark_block
.add_statement (cdecl
);
99 var register_call
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_error_register_error_domain"));
100 register_call
.add_argument (new
CCodeConstant ("\"" + edomain
.get_lower_case_cname () + "-quark\""));
101 register_call
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier (quark_name
)));
102 register_call
.add_argument (new
CCodeIdentifier (edomain
.get_lower_case_cname () + "_entries"));
103 var nentries
= new
CCodeFunctionCall (new
CCodeIdentifier ("G_N_ELEMENTS"));
104 nentries
.add_argument (new
CCodeIdentifier (edomain
.get_lower_case_cname () + "_entries"));
105 register_call
.add_argument (nentries
);
106 cquark_block
.add_statement (new
CCodeExpressionStatement (register_call
));
108 cquark_block
.add_statement (new
CCodeReturnStatement (new
CCodeCastExpression (new
CCodeIdentifier (quark_name
), "GQuark")));
110 cquark_fun
.block
= cquark_block
;
111 cfile
.add_function (cquark_fun
);
114 bool is_file_descriptor (DataType type
) {
115 if (type is ObjectType
) {
116 if (type
.data_type
.get_full_name () == "GLib.UnixInputStream" ||
117 type
.data_type
.get_full_name () == "GLib.UnixOutputStream" ||
118 type
.data_type
.get_full_name () == "GLib.Socket") {
126 public bool dbus_method_uses_file_descriptor (Method method
) {
127 foreach (Parameter param
in method
.get_parameters ()) {
128 if (is_file_descriptor (param
.variable_type
)) {
133 if (is_file_descriptor (method
.return_type
)) {
140 CCodeExpression?
get_file_descriptor (DataType type
, CCodeExpression expr
) {
141 if (type is ObjectType
) {
142 if (type
.data_type
.get_full_name () == "GLib.UnixInputStream") {
143 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_input_stream_get_fd"));
144 result
.add_argument (expr
);
146 } else if (type
.data_type
.get_full_name () == "GLib.UnixOutputStream") {
147 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_output_stream_get_fd"));
148 result
.add_argument (expr
);
150 } else if (type
.data_type
.get_full_name () == "GLib.Socket") {
151 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_socket_get_fd"));
152 result
.add_argument (expr
);
160 public void send_dbus_value (DataType type
, CCodeExpression builder_expr
, CCodeExpression expr
, Symbol? sym
) {
161 var fd
= get_file_descriptor (type
, expr
);
163 // add file descriptor to the file descriptor list
164 var fd_append
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_fd_list_append"));
165 fd_append
.add_argument (new
CCodeIdentifier ("_fd_list"));
166 fd_append
.add_argument (fd
);
167 fd_append
.add_argument (new
CCodeConstant ("NULL"));
169 // add index to file descriptor to gvariant
170 var builder_add
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_builder_add"));
171 builder_add
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, builder_expr
));
172 builder_add
.add_argument (new
CCodeConstant ("\"h\""));
173 builder_add
.add_argument (fd_append
);
174 ccode
.add_expression (builder_add
);
176 write_expression (type
, builder_expr
, expr
, sym
);
180 CCodeExpression?
create_from_file_descriptor (DataType type
, CCodeExpression expr
) {
181 if (type is ObjectType
) {
182 if (type
.data_type
.get_full_name () == "GLib.UnixInputStream") {
183 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_input_stream_new"));
184 result
.add_argument (expr
);
185 result
.add_argument (new
CCodeConstant ("TRUE"));
186 return new
CCodeCastExpression (result
, "GUnixInputStream *");
187 } else if (type
.data_type
.get_full_name () == "GLib.UnixOutputStream") {
188 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_output_stream_new"));
189 result
.add_argument (expr
);
190 result
.add_argument (new
CCodeConstant ("TRUE"));
191 return new
CCodeCastExpression (result
, "GUnixOutputStream *");
192 } else if (type
.data_type
.get_full_name () == "GLib.Socket") {
193 var result
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_socket_new_from_fd"));
194 result
.add_argument (expr
);
195 result
.add_argument (new
CCodeConstant ("NULL"));
203 public void receive_dbus_value (DataType type
, CCodeExpression message_expr
, CCodeExpression iter_expr
, CCodeExpression target_expr
, Symbol? sym
, CCodeExpression? error_expr
= null, out bool may_fail
= null) {
204 var fd_list
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_dbus_message_get_unix_fd_list"));
205 fd_list
.add_argument (message_expr
);
207 var fd
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_unix_fd_list_get"));
208 fd
.add_argument (fd_list
);
209 fd
.add_argument (new
CCodeIdentifier ("_fd_index"));
210 fd
.add_argument (new
CCodeConstant ("NULL"));
212 var stream
= create_from_file_descriptor (type
, fd
);
213 if (stream
!= null) {
214 var get_fd
= new
CCodeFunctionCall (new
CCodeIdentifier ("g_variant_iter_next"));
215 get_fd
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, iter_expr
));
216 get_fd
.add_argument (new
CCodeConstant ("\"h\""));
217 get_fd
.add_argument (new
CCodeUnaryExpression (CCodeUnaryOperator
.ADDRESS_OF
, new
CCodeIdentifier ("_fd_index")));
218 ccode
.add_expression (get_fd
);
220 ccode
.add_assignment (target_expr
, stream
);
222 read_expression (type
, iter_expr
, target_expr
, sym
, error_expr
, out may_fail
);