*/
public class Vala.GDBusServerModule : GDBusClientModule {
- string generate_dbus_wrapper (Method m, ObjectTypeSymbol sym, bool ready = false) {
- string wrapper_name = "_dbus_%s".printf (get_ccode_name (m));
- bool need_goto_label = ready;
-
- if (m.base_method != null) {
- m = m.base_method;
- } else if (m.base_interface_method != null) {
- m = m.base_interface_method;
+ public static bool is_dbus_visible (CodeNode node) {
+ var dbus_attribute = node.get_attribute ("DBus");
+ if (dbus_attribute != null
+ && dbus_attribute.has_argument ("visible")
+ && !dbus_attribute.get_bool ("visible")) {
+ return false;
}
- if (ready) {
- // async ready function
- wrapper_name += "_ready";
- }
-
- var function = new CCodeFunction (wrapper_name);
- function.modifiers = CCodeModifiers.STATIC;
-
- if (!ready) {
- function.add_parameter (new CCodeParameter ("self", get_ccode_name (sym) + "*"));
- function.add_parameter (new CCodeParameter ("_parameters_", "GVariant*"));
- function.add_parameter (new CCodeParameter ("invocation", "GDBusMethodInvocation*"));
- } else {
- function.add_parameter (new CCodeParameter ("source_object", "GObject *"));
- function.add_parameter (new CCodeParameter ("_res_", "GAsyncResult *"));
- function.add_parameter (new CCodeParameter ("_user_data_", "gpointer"));
- }
-
- push_function (function);
-
- CCodeIdentifier ready_data_expr = m.coroutine ? new CCodeIdentifier ("_ready_data") : null;
- string ready_data_struct_name = Symbol.lower_case_to_camel_case (get_ccode_name (m)) + "ReadyData";
-
- if (ready) {
- ccode.add_declaration (ready_data_struct_name + "*", new CCodeVariableDeclarator ("_ready_data", new CCodeIdentifier ("_user_data_")));
- ccode.add_declaration ("GDBusMethodInvocation*", new CCodeVariableDeclarator ("invocation", new CCodeMemberAccess.pointer (ready_data_expr, "_invocation_")));
- }
-
- var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_get_connection"));
- connection.add_argument (new CCodeIdentifier ("invocation"));
-
- bool no_reply = is_dbus_no_reply (m);
- bool uses_fd = dbus_method_uses_file_descriptor (m);
- if (uses_fd) {
- cfile.add_include ("gio/gunixfdlist.h");
- ccode.add_declaration ("GUnixFDList*", new CCodeVariableDeclarator ("_fd_list"));
- }
-
- bool uses_error = false;
-
- if (!m.coroutine || ready) {
- ccode.add_declaration ("GError*", new CCodeVariableDeclarator.zero ("error", new CCodeConstant ("NULL")));
- uses_error = true;
- }
-
- if (!ready) {
- ccode.add_declaration ("GVariantIter", new CCodeVariableDeclarator ("_arguments_iter"));
-
- var iter_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_init"));
- iter_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_iter")));
- iter_init.add_argument (new CCodeIdentifier ("_parameters_"));
- ccode.add_expression (iter_init);
- }
-
- CCodeFunctionCall ccall;
- if (!ready) {
- ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (m)));
- ccall.add_argument (new CCodeIdentifier ("self"));
- } else {
- ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_finish_name (m)));
- ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("source_object"), get_ccode_name (sym) + "*"));
- ccall.add_argument (new CCodeIdentifier ("_res_"));
- }
-
- if (!ready) {
- if (uses_fd) {
- ccode.add_declaration ("gint", new CCodeVariableDeclarator.zero ("_fd_index", new CCodeConstant ("0")));
- ccode.add_declaration ("gint", new CCodeVariableDeclarator ("_fd"));
- }
-
- CCodeStruct? ready_data_struct = null;
-
- if (m.coroutine) {
- ready_data_struct = new CCodeStruct ("_" + ready_data_struct_name);
- ready_data_struct.add_field ("GDBusMethodInvocation*", "_invocation_");
- append_struct (ready_data_struct);
-
- var ready_data_alloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
- ready_data_alloc.add_argument (new CCodeIdentifier (ready_data_struct_name));
-
- ccode.add_declaration (ready_data_struct_name + "*", new CCodeVariableDeclarator ("_ready_data"));
- ccode.add_assignment (ready_data_expr, ready_data_alloc);
-
- ccode.add_assignment (new CCodeMemberAccess.pointer (ready_data_expr, "_invocation_"), new CCodeIdentifier ("invocation"));
- }
-
- foreach (Parameter param in m.get_parameters ()) {
- string param_name = get_variable_cname (param.name);
- if (param.direction != ParameterDirection.IN) {
- continue;
- }
-
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.Cancellable") {
- continue;
- }
-
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.BusName") {
- // ignore BusName sender parameters
- continue;
- }
-
- CCodeExpression param_expr;
- if (ready_data_expr != null) {
- param_expr = new CCodeMemberAccess.pointer (ready_data_expr, param_name);
- } else {
- param_expr = new CCodeIdentifier (param_name);
- }
-
- var owned_type = param.variable_type.copy ();
- owned_type.value_owned = true;
-
- if (ready_data_struct != null) {
- ready_data_struct.add_field (get_ccode_name (owned_type), param_name);
- } else {
- ccode.add_declaration (get_ccode_name (owned_type), new CCodeVariableDeclarator.zero (param_name, default_value_for_type (param.variable_type, true)));
- }
-
- var array_type = param.variable_type as ArrayType;
- if (array_type != null) {
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_variable_array_length_cname (param, dim);
-
- if (ready_data_struct != null) {
- ready_data_struct.add_field (length_ctype, length_cname);
- } else {
- ccode.add_declaration (length_ctype, new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
- }
- }
- }
-
- var message_expr = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_get_message"));
- message_expr.add_argument (new CCodeIdentifier ("invocation"));
-
- bool may_fail;
- receive_dbus_value (param.variable_type, message_expr, new CCodeIdentifier ("_arguments_iter"), param_expr, param, new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")), out may_fail);
-
- if (may_fail) {
- if (!uses_error) {
- ccode.add_declaration ("GError*", new CCodeVariableDeclarator.zero ("error", new CCodeConstant ("NULL")));
- uses_error = true;
- }
-
- ccode.open_if (new CCodeIdentifier ("error"));
-
- var return_error = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
- return_error.add_argument (new CCodeIdentifier ("invocation"));
- return_error.add_argument (new CCodeIdentifier ("error"));
- ccode.add_expression (return_error);
-
- var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
- free_error.add_argument (new CCodeIdentifier ("error"));
- ccode.add_expression (free_error);
-
- if (need_goto_label || requires_destroy (owned_type)) {
- ccode.add_goto ("_error");
- need_goto_label = true;
- } else {
- ccode.add_return ();
- }
-
- ccode.close ();
- }
- }
- }
-
- foreach (Parameter param in m.get_parameters ()) {
- string param_name = get_variable_cname (param.name);
-
- CCodeExpression param_expr;
- if (ready_data_expr != null && param.direction == ParameterDirection.IN) {
- param_expr = new CCodeMemberAccess.pointer (ready_data_expr, param_name);
- } else {
- param_expr = new CCodeIdentifier (param_name);
- }
-
- if (param.direction == ParameterDirection.IN && !ready) {
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.Cancellable") {
- ccall.add_argument (new CCodeConstant ("NULL"));
- continue;
- }
-
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.BusName") {
- // ignore BusName sender parameters
- var sender = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_get_sender"));
- sender.add_argument (new CCodeIdentifier ("invocation"));
- ccall.add_argument (sender);
- continue;
- }
-
- var st = param.variable_type.data_type as Struct;
- if (st != null && !st.is_simple_type ()) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, param_expr));
- } else {
- ccall.add_argument (param_expr);
- }
- } else if (param.direction == ParameterDirection.OUT && (!m.coroutine || ready)) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, param_expr));
- }
-
- var array_type = param.variable_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_variable_array_length_cname (param, dim);
-
- CCodeExpression length_expr;
- if (ready_data_expr != null && param.direction == ParameterDirection.IN)
- length_expr = new CCodeMemberAccess.pointer (ready_data_expr, length_cname);
- else
- length_expr = new CCodeIdentifier (length_cname);
-
- if (param.direction == ParameterDirection.IN && !ready) {
- ccall.add_argument (length_expr);
- } else if (param.direction == ParameterDirection.OUT && !no_reply && (!m.coroutine || ready)) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, length_expr));
- }
- }
- }
- }
-
- if (!m.coroutine || ready) {
- if (!(m.return_type is VoidType)) {
- if (m.return_type.is_real_non_null_struct_type ()) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
- } else {
- var array_type = m.return_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_array_length_cname ("result", dim);
-
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
- }
- }
- }
- }
- }
-
- if (m.coroutine && !ready) {
- ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier (wrapper_name + "_ready"), "GAsyncReadyCallback"));
- ccall.add_argument (ready_data_expr);
- }
-
- if (!m.coroutine || ready) {
- if (m.tree_can_fail) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
- }
- }
-
- if (!no_reply && (!m.coroutine || ready)) {
- if (m.return_type is VoidType || m.return_type.is_real_non_null_struct_type ()) {
- ccode.add_expression (ccall);
- } else {
- ccode.add_assignment (new CCodeIdentifier ("result"), ccall);
- }
-
- if (m.tree_can_fail) {
- ccode.open_if (new CCodeIdentifier ("error"));
-
- var return_error = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_return_gerror"));
- return_error.add_argument (new CCodeIdentifier ("invocation"));
- return_error.add_argument (new CCodeIdentifier ("error"));
- ccode.add_expression (return_error);
-
- var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
- free_error.add_argument (new CCodeIdentifier ("error"));
- ccode.add_expression (free_error);
-
- if (need_goto_label) {
- ccode.add_goto ("_error");
- } else {
- ccode.add_return ();
- }
-
- ccode.close ();
- }
-
- ccode.add_declaration ("GDBusMessage*", new CCodeVariableDeclarator.zero ("_reply_message", new CCodeConstant ("NULL")));
-
- var message_expr = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_method_invocation_get_message"));
- message_expr.add_argument (new CCodeIdentifier ("invocation"));
-
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_new_method_reply"));
- ccall.add_argument (message_expr);
- ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
-
- ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator ("_reply"));
- ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_reply_builder"));
-
- var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
- builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
- builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
- ccode.add_expression (builder_init);
-
- if (uses_fd) {
- ccode.add_assignment (new CCodeIdentifier ("_fd_list"), new CCodeFunctionCall (new CCodeIdentifier ("g_unix_fd_list_new")));
- }
-
- foreach (Parameter param in m.get_parameters ()) {
- if (param.direction != ParameterDirection.OUT) {
- continue;
- }
-
- string param_name = get_variable_cname (param.name);
- var owned_type = param.variable_type.copy ();
- owned_type.value_owned = true;
-
- ccode.add_declaration (get_ccode_name (owned_type), new CCodeVariableDeclarator.zero (param_name, default_value_for_type (param.variable_type, true)));
-
- var array_type = param.variable_type as ArrayType;
- if (array_type != null) {
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_variable_array_length_cname (param, dim);
-
- ccode.add_declaration (length_ctype, new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
- }
- }
-
- send_dbus_value (param.variable_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier (param_name), param);
- }
-
- if (!(m.return_type is VoidType)) {
- if (m.return_type.is_real_non_null_struct_type ()) {
- ccode.add_declaration (get_ccode_name (m.return_type), new CCodeVariableDeclarator.zero ("result", default_value_for_type (m.return_type, true)));
-
- send_dbus_value (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
-
- if (requires_destroy (m.return_type)) {
- // keep local alive (symbol_reference is weak)
- var local = new LocalVariable (m.return_type, ".result");
- ccode.add_expression (destroy_local (local));
- }
- } else {
- ccode.add_declaration (get_ccode_name (m.return_type), new CCodeVariableDeclarator ("result"));
-
- var array_type = m.return_type as ArrayType;
- if (array_type != null) {
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_array_length_cname ("result", dim);
-
- ccode.add_declaration (length_ctype, new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
- }
- }
-
- send_dbus_value (m.return_type, new CCodeIdentifier ("_reply_builder"), new CCodeIdentifier ("result"), m);
-
- if (requires_destroy (m.return_type)) {
- // keep local alive (symbol_reference is weak)
- var local = new LocalVariable (m.return_type, ".result");
- ccode.add_expression (destroy_local (local));
- }
- }
- }
-
- var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
- builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_reply_builder")));
- ccode.add_assignment (new CCodeIdentifier ("_reply"), builder_end);
-
- var set_body = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_body"));
- set_body.add_argument (new CCodeIdentifier ("_reply_message"));
- set_body.add_argument (new CCodeIdentifier ("_reply"));
- ccode.add_expression (set_body);
-
- if (uses_fd) {
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_message_set_unix_fd_list"));
- ccall.add_argument (new CCodeIdentifier ("_reply_message"));
- ccall.add_argument (new CCodeIdentifier ("_fd_list"));
- ccode.add_expression (ccall);
-
- ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
- ccall.add_argument (new CCodeIdentifier ("_fd_list"));
- ccode.add_expression (ccall);
- }
- } else {
- ccode.add_expression (ccall);
- }
-
- if (!no_reply && (!m.coroutine || ready)) {
- var return_value = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_send_message"));
- return_value.add_argument (connection);
- return_value.add_argument (new CCodeIdentifier ("_reply_message"));
- return_value.add_argument (new CCodeConstant ("G_DBUS_SEND_MESSAGE_FLAGS_NONE"));
- return_value.add_argument (new CCodeConstant ("NULL"));
- return_value.add_argument (new CCodeConstant ("NULL"));
- ccode.add_expression (return_value);
-
- // free invocation like g_dbus_method_invocation_return_*
- var unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
- unref_call.add_argument (new CCodeIdentifier ("invocation"));
- ccode.add_expression (unref_call);
-
- unref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
- unref_call.add_argument (new CCodeIdentifier ("_reply_message"));
- ccode.add_expression (unref_call);
- }
-
- if (need_goto_label) {
- ccode.add_label ("_error");
- }
-
- foreach (Parameter param in m.get_parameters ()) {
- if ((param.direction == ParameterDirection.IN && (ready_data_expr == null || ready)) ||
- (param.direction == ParameterDirection.OUT && !no_reply && (!m.coroutine || ready))) {
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.Cancellable") {
- continue;
- }
-
- if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.BusName") {
- // ignore BusName sender parameters
- continue;
- }
-
- var owned_type = param.variable_type.copy ();
- owned_type.value_owned = true;
-
- if (requires_destroy (owned_type)) {
- if (ready_data_expr != null && param.direction == ParameterDirection.IN) {
- var target = new GLibValue (owned_type, new CCodeMemberAccess.pointer (ready_data_expr, param.name), true);
-
- var array_type = owned_type as ArrayType;
- if (array_type != null) {
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_variable_array_length_cname (param, dim);
-
- target.append_array_length_cvalue (new CCodeMemberAccess.pointer (ready_data_expr, length_cname));
- }
- }
-
- ccode.add_expression (destroy_value (target));
- } else {
- // keep local alive (symbol_reference is weak)
- var local = new LocalVariable (owned_type, get_variable_cname (param.name));
- ccode.add_expression (destroy_local (local));
- }
- }
- }
- }
-
- if (ready) {
- var freecall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
- freecall.add_argument (new CCodeIdentifier (ready_data_struct_name));
- freecall.add_argument (ready_data_expr);
- ccode.add_expression (freecall);
- } else if (need_goto_label) {
- ccode.add_statement (new CCodeEmptyStatement ());
- }
-
- pop_function ();
-
- cfile.add_function_declaration (function);
- cfile.add_function (function);
-
- if (m.coroutine && !ready) {
- // generate ready function
- generate_dbus_wrapper (m, sym, true);
- }
-
- return wrapper_name;
+ return true;
}
- string generate_dbus_signal_wrapper (Signal sig, ObjectTypeSymbol sym, string dbus_iface_name) {
- string wrapper_name = "_dbus_%s_%s".printf (get_ccode_lower_case_name (sym), get_ccode_lower_case_name (sig));
-
- var function = new CCodeFunction (wrapper_name, "void");
- function.modifiers = CCodeModifiers.STATIC;
-
- function.add_parameter (new CCodeParameter ("_sender", "GObject*"));
-
- foreach (var param in sig.get_parameters ()) {
- // ensure ccodenode of parameter is set
- var cparam = generate_parameter (param, cfile, new HashMap<int,CCodeParameter> (), null);
-
- function.add_parameter (cparam);
- if (param.variable_type is ArrayType) {
- var array_type = (ArrayType) param.variable_type;
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- function.add_parameter (new CCodeParameter (get_variable_array_length_cname (param, dim), length_ctype));
- }
- }
- }
-
- function.add_parameter (new CCodeParameter ("_data", "gpointer*"));
-
- push_function (function);
-
- ccode.add_declaration ("GDBusConnection *", new CCodeVariableDeclarator ("_connection", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("1"))));
- ccode.add_declaration ("const gchar *", new CCodeVariableDeclarator ("_path", new CCodeElementAccess (new CCodeIdentifier ("_data"), new CCodeConstant ("2"))));
- ccode.add_declaration ("GVariant", new CCodeVariableDeclarator ("*_arguments"));
- ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("_arguments_builder"));
-
- var builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init"));
- builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
- builder_init.add_argument (new CCodeIdentifier ("G_VARIANT_TYPE_TUPLE"));
- ccode.add_expression (builder_init);
-
- foreach (Parameter param in sig.get_parameters ()) {
- string param_name = get_variable_cname (param.name);
- CCodeExpression expr = new CCodeIdentifier (param_name);
- if (param.variable_type.is_real_struct_type ()) {
- expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, expr);
- }
- write_expression (param.variable_type, new CCodeIdentifier ("_arguments_builder"), expr, param);
+ public static string dbus_result_name (Method m) {
+ var dbus_name = m.get_attribute_string ("DBus", "result");
+ if (dbus_name != null && dbus_name != "") {
+ return dbus_name;
}
- var builder_end = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_end"));
- builder_end.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_arguments_builder")));
- ccode.add_assignment (new CCodeIdentifier ("_arguments"), builder_end);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_emit_signal"));
- ccall.add_argument (new CCodeIdentifier ("_connection"));
- ccall.add_argument (new CCodeConstant ("NULL"));
- ccall.add_argument (new CCodeIdentifier ("_path"));
- ccall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_iface_name)));
- ccall.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig))));
- ccall.add_argument (new CCodeIdentifier ("_arguments"));
- ccall.add_argument (new CCodeConstant ("NULL"));
- ccode.add_expression (ccall);
-
- pop_function ();
-
- cfile.add_function_declaration (function);
- cfile.add_function (function);
-
- return wrapper_name;
+ return "result";
}
- string generate_dbus_property_get_wrapper (Property prop, ObjectTypeSymbol sym) {
- string wrapper_name = "_dbus_%s".printf (get_ccode_name (prop.get_accessor));
-
- var function = new CCodeFunction (wrapper_name, "GVariant*");
- function.modifiers = CCodeModifiers.STATIC;
- function.add_parameter (new CCodeParameter ("self", get_ccode_name (sym) + "*"));
-
- push_function (function);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (prop.get_accessor)));
- ccall.add_argument (new CCodeIdentifier ("self"));
-
- if (prop.get_accessor.value_type.is_real_non_null_struct_type ()) {
- 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)));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("result")));
-
- ccode.add_expression (ccall);
- } else {
- ccode.add_declaration (get_ccode_name (prop.get_accessor.value_type), new CCodeVariableDeclarator ("result"));
- ccode.add_assignment (new CCodeIdentifier ("result"), ccall);
-
- var array_type = prop.get_accessor.value_type as ArrayType;
- if (array_type != null) {
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- string length_cname = get_array_length_cname ("result", dim);
-
- ccode.add_declaration (length_ctype, new CCodeVariableDeclarator.zero (length_cname, new CCodeConstant ("0")));
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (length_cname)));
- }
- }
- }
-
- ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator ("_reply"));
-
- if (get_dbus_signature (prop) != null) {
- // raw GVariant
- ccode.add_assignment (new CCodeIdentifier ("_reply"), new CCodeIdentifier("result"));
- } else {
- var reply_expr = serialize_expression (prop.get_accessor.value_type, new CCodeIdentifier ("result"));
-
- ccode.add_assignment (new CCodeIdentifier ("_reply"), reply_expr);
-
- if (requires_destroy (prop.get_accessor.value_type)) {
- // keep local alive (symbol_reference is weak)
- var local = new LocalVariable (prop.get_accessor.value_type, ".result");
- ccode.add_expression (destroy_local (local));
- }
- }
-
- ccode.add_return (new CCodeIdentifier ("_reply"));
-
- pop_function ();
-
- cfile.add_function_declaration (function);
- cfile.add_function (function);
-
- return wrapper_name;
- }
-
- string generate_dbus_property_set_wrapper (Property prop, ObjectTypeSymbol sym) {
- string wrapper_name = "_dbus_%s".printf (get_ccode_name (prop.set_accessor));
-
- var function = new CCodeFunction (wrapper_name);
- function.modifiers = CCodeModifiers.STATIC;
- function.add_parameter (new CCodeParameter ("self", get_ccode_name (sym) + "*"));
- function.add_parameter (new CCodeParameter ("_value", "GVariant*"));
-
- push_function (function);
-
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_name (prop.set_accessor)));
- ccall.add_argument (new CCodeIdentifier ("self"));
-
- var owned_type = prop.property_type.copy ();
- owned_type.value_owned = true;
-
- ccode.add_declaration (get_ccode_name (owned_type), new CCodeVariableDeclarator.zero ("value", default_value_for_type (prop.property_type, true)));
-
- var st = prop.property_type.data_type as Struct;
- if (st != null && !st.is_simple_type ()) {
- ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("value")));
- } else {
- ccall.add_argument (new CCodeIdentifier ("value"));
-
- var array_type = prop.property_type as ArrayType;
- if (array_type != null) {
- var length_ctype = get_ccode_array_length_type (array_type);
- for (int dim = 1; dim <= array_type.rank; dim++) {
- ccode.add_declaration (length_ctype, new CCodeVariableDeclarator (get_array_length_cname ("value", dim)));
- ccall.add_argument (new CCodeIdentifier (get_array_length_cname ("value", dim)));
- }
- }
- }
-
- var target = new CCodeIdentifier ("value");
-
- if (get_dbus_signature (prop) != null) {
- ccode.add_assignment (target, new CCodeIdentifier("_value"));
- ccode.add_expression (ccall);
- } else {
- var expr = deserialize_expression (prop.property_type, new CCodeIdentifier ("_value"), target);
- ccode.add_assignment (target, expr);
- ccode.add_expression (ccall);
-
- if (requires_destroy (owned_type)) {
- // keep local alive (symbol_reference is weak)
- var local = new LocalVariable (owned_type, "value");
- ccode.add_expression (destroy_local (local));
- }
- }
-
- pop_function ();
-
- cfile.add_function_declaration (function);
- cfile.add_function (function);
-
- return wrapper_name;
+ string generate_dbus_signal_wrapper (Signal sig, ObjectTypeSymbol sym, string dbus_iface_name) {
+ return "_dbus_%s_%s".printf (get_ccode_lower_case_name (sym), get_ccode_lower_case_name (sig));
}
void handle_signals (ObjectTypeSymbol sym, bool connect) {
}
}
- void generate_interface_method_call_function (ObjectTypeSymbol sym) {
- var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "dbus_interface_method_call", "void");
- cfunc.add_parameter (new CCodeParameter ("connection", "GDBusConnection*"));
- cfunc.add_parameter (new CCodeParameter ("sender", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("object_path", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("interface_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("method_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("parameters", "GVariant*"));
- cfunc.add_parameter (new CCodeParameter ("invocation", "GDBusMethodInvocation*"));
- cfunc.add_parameter (new CCodeParameter ("user_data", "gpointer"));
-
- cfunc.modifiers |= CCodeModifiers.STATIC;
-
- push_function (cfunc);
-
- ccode.add_declaration ("gpointer*", new CCodeVariableDeclarator ("data", new CCodeIdentifier ("user_data")));
- ccode.add_declaration ("gpointer", new CCodeVariableDeclarator ("object", new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("0"))));
-
- bool first = true;
+ CCodeExpression get_method_info (ObjectTypeSymbol sym) {
+ var infos = new CCodeInitializerList ();
foreach (Method m in sym.get_methods ()) {
if (m is CreationMethod || m.binding != MemberBinding.INSTANCE
continue;
}
- cfile.add_include ("string.h");
+ var in_args_info = new CCodeInitializerList ();
+ var out_args_info = new CCodeInitializerList ();
- var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
- ccheck.add_argument (new CCodeIdentifier ("method_name"));
- ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m))));
+ foreach (Parameter param in m.get_parameters ()) {
+ if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.Cancellable") {
+ continue;
+ }
+ if (param.variable_type is ObjectType && param.variable_type.data_type.get_full_name () == "GLib.BusName") {
+ continue;
+ }
- if (first) {
- ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccheck, new CCodeConstant ("0")));
- first = false;
- } else {
- ccode.else_if (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccheck, new CCodeConstant ("0")));
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (param.name)));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_type_signature (param.variable_type, param))));
+ info.append (new CCodeConstant ("NULL"));
+
+ var cdecl = new CCodeDeclaration ("const GDBusArgInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_" + param.name, info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
+
+ if (param.direction == ParameterDirection.IN) {
+ in_args_info.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_" + param.name)));
+ } else {
+ out_args_info.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_" + param.name)));
+ }
}
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_dbus_wrapper (m, sym)));
- ccall.add_argument (new CCodeIdentifier ("object"));
- ccall.add_argument (new CCodeIdentifier ("parameters"));
- ccall.add_argument (new CCodeIdentifier ("invocation"));
- ccode.add_expression (ccall);
- }
+ if (!(m.return_type is VoidType)) {
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (dbus_result_name (m))));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_type_signature (m.return_type, m))));
+ info.append (new CCodeConstant ("NULL"));
- if (!first) {
- ccode.add_else ();
- }
+ var cdecl = new CCodeDeclaration ("const GDBusArgInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_result", info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
- ccall.add_argument (new CCodeIdentifier ("invocation"));
- ccode.add_expression (ccall);
+ out_args_info.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_result")));
+ }
- if (!first) {
- ccode.close ();
- }
+ in_args_info.append (new CCodeConstant ("NULL"));
+ out_args_info.append (new CCodeConstant ("NULL"));
- pop_function ();
+ var cdecl = new CCodeDeclaration ("const GDBusArgInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_in[]", in_args_info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- cfile.add_function_declaration (cfunc);
- cfile.add_function (cfunc);
- }
+ cdecl = new CCodeDeclaration ("const GDBusArgInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_out[]", out_args_info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- void generate_interface_get_property_function (ObjectTypeSymbol sym) {
- var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "dbus_interface_get_property", "GVariant*");
- cfunc.add_parameter (new CCodeParameter ("connection", "GDBusConnection*"));
- cfunc.add_parameter (new CCodeParameter ("sender", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("object_path", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("interface_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("property_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("error", "GError**"));
- cfunc.add_parameter (new CCodeParameter ("user_data", "gpointer"));
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (m))));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_in")), "GDBusArgInfo **"));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + m.name + "_out")), "GDBusArgInfo **"));
+ info.append (new CCodeConstant ("NULL"));
- cfunc.modifiers |= CCodeModifiers.STATIC;
+ cdecl = new CCodeDeclaration ("const GDBusMethodInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_method_info_" + m.name, info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- cfile.add_function_declaration (cfunc);
+ infos.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_method_info_" + m.name)));
+ }
- push_function (cfunc);
+ infos.append (new CCodeConstant ("NULL"));
- ccode.add_declaration ("gpointer*", new CCodeVariableDeclarator ("data", new CCodeIdentifier ("user_data")));
+ var cdecl = new CCodeDeclaration ("const GDBusMethodInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_method_info[]", infos));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- ccode.add_declaration ("gpointer", new CCodeVariableDeclarator ("object", new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("0"))));
+ return new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_method_info");
+ }
- bool firstif = true;
+ CCodeExpression get_signal_info (ObjectTypeSymbol sym) {
+ var infos = new CCodeInitializerList ();
- foreach (Property prop in sym.get_properties ()) {
- if (prop.binding != MemberBinding.INSTANCE
- || prop.overrides || prop.access != SymbolAccessibility.PUBLIC) {
- continue;
- }
- if (!is_dbus_visible (prop)) {
+ foreach (Signal sig in sym.get_signals ()) {
+ if (sig.access != SymbolAccessibility.PUBLIC) {
continue;
}
- if (prop.get_accessor == null) {
+ if (!is_dbus_visible (sig)) {
continue;
}
- cfile.add_include ("string.h");
+ var args_info = new CCodeInitializerList ();
- var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
- ccheck.add_argument (new CCodeIdentifier ("property_name"));
- ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))));
+ foreach (Parameter param in sig.get_parameters ()) {
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (param.name)));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_type_signature (param.variable_type, param))));
+ info.append (new CCodeConstant ("NULL"));
- var cond = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccheck, new CCodeConstant ("0"));
- if (firstif) {
- ccode.open_if (cond);
- firstif = false;
- } else {
- ccode.else_if (cond);
+ var cdecl = new CCodeDeclaration ("const GDBusArgInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + get_ccode_lower_case_name (sig) + "_" + param.name, info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
+
+ args_info.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + get_ccode_lower_case_name (sig) + "_" + param.name)));
}
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_dbus_property_get_wrapper (prop, sym)));
- ccall.add_argument (new CCodeIdentifier ("object"));
+ args_info.append (new CCodeConstant ("NULL"));
- ccode.add_return (ccall);
- }
- if (!firstif) {
- ccode.close ();
- }
+ var cdecl = new CCodeDeclaration ("const GDBusArgInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + get_ccode_lower_case_name (sig) + "[]", args_info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- ccode.add_return (new CCodeConstant ("NULL"));
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (sig))));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_arg_info_" + get_ccode_lower_case_name (sig))), "GDBusArgInfo **"));
+ info.append (new CCodeConstant ("NULL"));
- pop_function ();
- cfile.add_function (cfunc);
- }
+ cdecl = new CCodeDeclaration ("const GDBusSignalInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_signal_info_" + get_ccode_lower_case_name (sig), info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- void generate_interface_set_property_function (ObjectTypeSymbol sym) {
- var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "dbus_interface_set_property", "gboolean");
- cfunc.add_parameter (new CCodeParameter ("connection", "GDBusConnection*"));
- cfunc.add_parameter (new CCodeParameter ("sender", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("object_path", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("interface_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("property_name", "const gchar*"));
- cfunc.add_parameter (new CCodeParameter ("value", "GVariant*"));
- cfunc.add_parameter (new CCodeParameter ("error", "GError**"));
- cfunc.add_parameter (new CCodeParameter ("user_data", "gpointer"));
-
- cfunc.modifiers |= CCodeModifiers.STATIC;
+ infos.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_signal_info_" + get_ccode_lower_case_name (sig))));
+ }
- cfile.add_function_declaration (cfunc);
+ infos.append (new CCodeConstant ("NULL"));
- push_function (cfunc);
-
- ccode.add_declaration ("gpointer*", new CCodeVariableDeclarator ("data", new CCodeIdentifier ("user_data")));
+ var cdecl = new CCodeDeclaration ("const GDBusSignalInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_signal_info[]", infos));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- ccode.add_declaration ("gpointer", new CCodeVariableDeclarator ("object", new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("0"))));
+ return new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_signal_info");
+ }
- bool firstif = true;
+ CCodeExpression get_property_info (ObjectTypeSymbol sym) {
+ var infos = new CCodeInitializerList ();
foreach (Property prop in sym.get_properties ()) {
if (prop.binding != MemberBinding.INSTANCE
if (!is_dbus_visible (prop)) {
continue;
}
- if (prop.set_accessor == null) {
- continue;
- }
- cfile.add_include ("string.h");
-
- var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
- ccheck.add_argument (new CCodeIdentifier ("property_name"));
- ccheck.add_argument (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))));
-
- var cond = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, ccheck, new CCodeConstant ("0"));
- if (firstif) {
- ccode.open_if (cond);
- firstif = false;
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_dbus_name_for_member (prop))));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_type_signature (prop.property_type, prop))));
+ if (prop.get_accessor != null && prop.set_accessor != null) {
+ info.append (new CCodeConstant ("G_DBUS_PROPERTY_INFO_FLAGS_READABLE | G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"));
+ } else if (prop.get_accessor != null) {
+ info.append (new CCodeConstant ("G_DBUS_PROPERTY_INFO_FLAGS_READABLE"));
+ } else if (prop.set_accessor != null) {
+ info.append (new CCodeConstant ("G_DBUS_PROPERTY_INFO_FLAGS_WRITABLE"));
} else {
- ccode.else_if (cond);
+ info.append (new CCodeConstant ("G_DBUS_PROPERTY_INFO_FLAGS_NONE"));
}
+ info.append (new CCodeConstant ("NULL"));
- var ccall = new CCodeFunctionCall (new CCodeIdentifier (generate_dbus_property_set_wrapper (prop, sym)));
- ccall.add_argument (new CCodeIdentifier ("object"));
- ccall.add_argument (new CCodeIdentifier ("value"));
+ var cdecl = new CCodeDeclaration ("const GDBusPropertyInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_property_info_" + prop.name, info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
- ccode.add_expression (ccall);
- ccode.add_return (new CCodeConstant ("TRUE"));
- }
- if (!firstif) {
- ccode.close ();
+ infos.append (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_property_info_" + prop.name)));
}
- ccode.add_return (new CCodeConstant ("FALSE"));
- pop_function ();
- cfile.add_function (cfunc);
+ infos.append (new CCodeConstant ("NULL"));
+
+ var cdecl = new CCodeDeclaration ("const GDBusPropertyInfo * const");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_property_info[]", infos));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
+
+ return new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_property_info");
+ }
+
+ CCodeExpression get_interface_info (ObjectTypeSymbol sym) {
+ var info = new CCodeInitializerList ();
+ info.append (new CCodeConstant ("-1"));
+ info.append (new CCodeConstant ("\"%s\"".printf (get_dbus_name (sym))));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_method_info (sym)), "GDBusMethodInfo **"));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_signal_info (sym)), "GDBusSignalInfo **"));
+ info.append (new CCodeCastExpression (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_property_info (sym)), "GDBusPropertyInfo **"));
+ info.append (new CCodeConstant ("NULL"));
+
+ var cdecl = new CCodeDeclaration ("const GDBusInterfaceInfo");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_interface_info", info));
+ cdecl.modifiers = CCodeModifiers.STATIC;
+ cfile.add_constant_declaration (cdecl);
+
+ return new CCodeIdentifier ("_" + get_ccode_lower_case_prefix (sym) + "dbus_interface_info");
}
CCodeExpression get_interface_vtable (ObjectTypeSymbol sym) {
vtable.append (new CCodeIdentifier (get_ccode_lower_case_prefix (sym) + "dbus_interface_get_property"));
vtable.append (new CCodeIdentifier (get_ccode_lower_case_prefix (sym) + "dbus_interface_set_property"));
- generate_interface_method_call_function (sym);
- generate_interface_get_property_function (sym);
- generate_interface_set_property_function (sym);
-
var cdecl = new CCodeDeclaration ("const GDBusInterfaceVTable");
cdecl.add_declarator (new CCodeVariableDeclarator ("_" + get_ccode_lower_case_prefix (sym) + "dbus_interface_vtable", vtable));
cdecl.modifiers = CCodeModifiers.STATIC;
--- /dev/null
+/* valagdbusservertransformer.vala
+ *
+ * Copyright (C) 2011 Luca Bruno
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Luca Bruno <lucabru@src.gnome.org>
+ */
+
+/**
+ * Code visitor for transforming the code tree related to DBus server.
+ */
+public class Vala.GDBusServerTransformer : GDBusClientTransformer {
+ public override void visit_class (Class cl) {
+ visit_object_type_symbol (cl);
+
+ base.visit_class (cl);
+ }
+
+ public override void visit_interface (Interface iface) {
+ visit_object_type_symbol (iface);
+
+ base.visit_interface (iface);
+ }
+
+ string generate_dbus_method_wrapper (Method m, ObjectTypeSymbol sym) {
+ Method wrapper;
+ wrapper_method (new VoidType (), "gdbus_server "+m.get_full_name (), out wrapper);
+ var object_type = context.analyzer.get_data_type_for_symbol (sym);
+ wrapper.add_parameter (new Parameter ("object", object_type));
+ wrapper.add_parameter (new Parameter ("arguments", data_type ("GLib.Variant", false)));
+ wrapper.add_parameter (new Parameter ("invocation", data_type ("GLib.DBusMethodInvocation", false)));
+ b.push_method (wrapper);
+
+ var iter = b.add_temp_declaration (null, expression ("arguments.iterator ()"));
+
+ var call = (MethodCall) expression (@"object.$(m.name) ()");
+ var finish_call = call;
+ Method ready = null;
+ CodeBuilder ready_builder = null;
+ if (m.coroutine) {
+ wrapper_method (new VoidType (), "gdbus_server_async_ready "+m.get_full_name (), out ready);
+ ready.add_parameter (new Parameter ("source_object", data_type ("GLib.Object", false)));
+ ready.add_parameter (new Parameter ("res", data_type ("GLib.AsyncResult", false)));
+ ready.add_parameter (new Parameter ("invocation", data_type ("GLib.DBusMethodInvocation", false)));
+ ready_builder = new CodeBuilder.for_subroutine (ready);
+
+ finish_call = (MethodCall) expression (@"(($object_type)(source_object)).$(m.name).end (res)");
+ }
+
+ var out_args = new string[0];
+ var out_types = new DataType[0];
+ string fd_list = null;
+ string fd_index = null;
+ foreach (var param in m.get_parameters ()) {
+ string? type_name = null;
+ if (param.variable_type is ObjectType) {
+ type_name = param.variable_type.data_type.get_full_name ();
+ }
+ if (type_name == "GLib.Cancellable") {
+ call.add_argument (expression ("null"));
+ continue;
+ }
+ if (type_name == "GLib.BusName") {
+ continue;
+ }
+
+ if (param.direction == ParameterDirection.IN) {
+ var arg = b.add_temp_declaration (copy_type (param.variable_type, true));
+ b.add_assignment (expression (arg), read_dbus_value (param.variable_type, iter, "invocation.get_message ()", ref fd_list, ref fd_index));
+ call.add_argument (expression (arg));
+ } else if (param.direction == ParameterDirection.OUT) {
+ if (m.coroutine) {
+ // declare the out argument in the ready callback
+ push_builder (ready_builder);
+ }
+ var arg = b.add_temp_declaration (copy_type (param.variable_type, true));
+ out_args += arg;
+ out_types += param.variable_type;
+ finish_call.add_argument (new UnaryExpression (UnaryOperator.OUT, expression (arg), m.source_reference));
+ if (m.coroutine) {
+ pop_builder ();
+ }
+ }
+ }
+
+ if (m.coroutine) {
+ call.add_argument (expression (@"(s,r) => $(ready.name) (s, r, invocation)"));
+ b.add_expression (call);
+ push_builder (ready_builder);
+ }
+
+ b.open_try ();
+ string result = null;
+ if (m.has_result) {
+ result = b.add_temp_declaration (m.return_type);
+ b.add_assignment (expression (result), finish_call);
+ } else {
+ b.add_expression (finish_call);
+ }
+ b.add_catch (data_type ("GLib.Error"), "e");
+ b.add_expression (expression ("invocation.return_gerror (e)"));
+ b.add_return ();
+ b.close ();
+
+ fd_list = null;
+ var reply = b.add_temp_declaration (null, expression ("new GLib.DBusMessage.method_reply (invocation.get_message ())"));
+ var builder = b.add_temp_declaration (null, expression ("new GLib.VariantBuilder (GLib.VariantType.TUPLE)"));
+ for (int i=0; i < out_args.length; i++) {
+ write_dbus_value (out_types[i], builder, out_args[i], ref fd_list);
+ }
+ if (result != null) {
+ write_dbus_value (m.return_type, builder, result, ref fd_list);
+ }
+ b.add_expression (expression (@"$reply.set_body ($builder.end ())"));
+ if (fd_list != null) {
+ b.add_expression (expression (@"$reply.set_unix_fd_list ($fd_list)"));
+ }
+ b.add_expression (expression (@"invocation.get_connection().send_message ($reply, GLib.DBusSendMessageFlags.NONE, null)"));
+
+ if (m.coroutine) {
+ pop_builder ();
+ check (ready);
+ }
+
+ b.pop_method ();
+ check (wrapper);
+ return wrapper.name;
+ }
+
+ public static bool is_dbus_visible (CodeNode node) {
+ var dbus_attribute = node.get_attribute ("DBus");
+ if (dbus_attribute != null
+ && dbus_attribute.has_argument ("visible")
+ && !dbus_attribute.get_bool ("visible")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ void generate_interface_method_call (ObjectTypeSymbol sym) {
+ if (sym.scope.lookup ("dbus_interface_method_call") != null) {
+ return;
+ }
+
+ var im = new Method ("dbus_interface_method_call", new VoidType (), sym.source_reference);
+ im.access = SymbolAccessibility.PRIVATE;
+ im.binding = MemberBinding.STATIC;
+ im.add_parameter (new Parameter ("connection", data_type ("GLib.DBusConnection", false)));
+ im.add_parameter (new Parameter ("sender", data_type ("string", false)));
+ im.add_parameter (new Parameter ("object_path", data_type ("string", false)));
+ im.add_parameter (new Parameter ("interface_name", data_type ("string", false)));
+ im.add_parameter (new Parameter ("method_name", data_type ("string", false)));
+ im.add_parameter (new Parameter ("_parameters_", data_type ("GLib.Variant", false)));
+ im.add_parameter (new Parameter ("invocation", data_type ("GLib.DBusMethodInvocation", false)));
+ im.add_parameter (new Parameter ("user_data", new PointerType (new VoidType ())));
+ sym.add_method (im);
+
+ push_builder (new CodeBuilder.for_subroutine (im));
+ var object_type = context.analyzer.get_data_type_for_symbol (sym);
+ var object = b.add_temp_declaration (null, expression (@"($object_type) (((Object[])user_data)[0])"));
+ b.open_switch (expression ("method_name"), null);
+ b.add_return ();
+ foreach (var m in sym.get_methods ()) {
+ if (m is CreationMethod || m.binding != MemberBinding.INSTANCE
+ || m.overrides || m.access != SymbolAccessibility.PUBLIC
+ || !is_dbus_visible (m)) {
+ continue;
+ }
+ b.add_section (expression (@"\"$(get_dbus_name_for_member (m))\""));
+ var wrapper = generate_dbus_method_wrapper (m, sym);
+ b.add_expression (expression (@"$wrapper ($object, _parameters_, invocation)"));
+ b.add_break ();
+ }
+ b.close ();
+ pop_builder ();
+ check (im);
+ }
+
+ void generate_interface_get_property (ObjectTypeSymbol sym) {
+ if (sym.scope.lookup ("dbus_interface_get_property") != null) {
+ return;
+ }
+
+ var m = new Method ("dbus_interface_get_property", data_type ("GLib.Variant", true, true), sym.source_reference);
+ m.access = SymbolAccessibility.PRIVATE;
+ m.binding = MemberBinding.STATIC;
+ m.add_parameter (new Parameter ("connection", data_type ("GLib.DBusConnection", false)));
+ m.add_parameter (new Parameter ("sender", data_type ("string", false)));
+ m.add_parameter (new Parameter ("object_path", data_type ("string", false)));
+ m.add_parameter (new Parameter ("interface_name", data_type ("string", false)));
+ m.add_parameter (new Parameter ("property_name", data_type ("string", false)));
+ m.add_parameter (new Parameter ("error", new PointerType (new PointerType (new VoidType ()))));
+ m.add_parameter (new Parameter ("user_data", new PointerType (new VoidType ())));
+ sym.add_method (m);
+
+ push_builder (new CodeBuilder.for_subroutine (m));
+ var object_type = context.analyzer.get_data_type_for_symbol (sym);
+ var object = b.add_temp_declaration (null, expression (@"($object_type) (((Object[])user_data)[0])"));
+ b.open_switch (expression ("property_name"), null);
+ b.add_return (expression ("null"));
+ foreach (var prop in sym.get_properties ()) {
+ if (prop.binding != MemberBinding.INSTANCE
+ || prop.overrides || prop.access != SymbolAccessibility.PUBLIC
+ || !is_dbus_visible (prop)
+ || prop.get_accessor == null) {
+ continue;
+ }
+ b.add_section (expression (@"\"$(get_dbus_name_for_member (prop))\""));
+ b.add_return (expression (@"$object.$(prop.name)"));
+ }
+ pop_builder ();
+ check (m);
+ }
+
+ void generate_interface_set_property (ObjectTypeSymbol sym) {
+ if (sym.scope.lookup ("dbus_interface_set_property") != null) {
+ return;
+ }
+
+ var m = new Method ("dbus_interface_set_property", data_type ("bool"), sym.source_reference);
+ m.access = SymbolAccessibility.PRIVATE;
+ m.binding = MemberBinding.STATIC;
+ m.add_parameter (new Parameter ("connection", data_type ("GLib.DBusConnection", false)));
+ m.add_parameter (new Parameter ("sender", data_type ("string", false)));
+ m.add_parameter (new Parameter ("object_path", data_type ("string", false)));
+ m.add_parameter (new Parameter ("interface_name", data_type ("string", false)));
+ m.add_parameter (new Parameter ("property_name", data_type ("string", false)));
+ m.add_parameter (new Parameter ("value", data_type ("GLib.Variant", false)));
+ m.add_parameter (new Parameter ("error", new PointerType (new PointerType (new VoidType ()))));
+ m.add_parameter (new Parameter ("user_data", new PointerType (new VoidType ())));
+ sym.add_method (m);
+
+ push_builder (new CodeBuilder.for_subroutine (m));
+ var object_type = context.analyzer.get_data_type_for_symbol (sym);
+ var object = b.add_temp_declaration (null, expression (@"($object_type) (((Object[])user_data)[0])"));
+ b.open_switch (expression ("property_name"), null);
+ b.add_return (expression ("false"));
+ foreach (var prop in sym.get_properties ()) {
+ if (prop.binding != MemberBinding.INSTANCE
+ || prop.overrides || prop.access != SymbolAccessibility.PUBLIC
+ || !is_dbus_visible (prop)
+ || prop.set_accessor == null) {
+ continue;
+ }
+ b.add_section (expression (@"\"$(get_dbus_name_for_member (prop))\""));
+ b.add_expression (expression (@"$object.$(prop.name) = ($(prop.property_type)) value"));
+ b.add_return (expression ("true"));
+ }
+ pop_builder ();
+ check (m);
+ }
+
+ void generate_interface_signal_emitter (Signal sig, ObjectTypeSymbol sym, string dbus_iface_name) {
+ var wrapper_name = "_dbus_%s_%s".printf (get_ccode_lower_case_name (sym), get_ccode_lower_case_name (sig));
+ if (context.root.scope.lookup (wrapper_name) != null) {
+ return;
+ }
+
+ var m = new Method (wrapper_name, new VoidType (), sym.source_reference);
+ context.root.add_method (m);
+ m.access = SymbolAccessibility.PRIVATE;
+ m.binding = MemberBinding.STATIC;
+ m.add_parameter (new Parameter ("_sender", data_type ("GLib.Object", false)));
+ foreach (var param in sig.get_parameters ()) {
+ m.add_parameter (param.copy ());
+ }
+ m.add_parameter (new Parameter ("_data", new PointerType (new PointerType (new VoidType ()))));
+ push_builder (new CodeBuilder.for_subroutine (m));
+
+ var builder = b.add_temp_declaration (null, expression ("new GLib.VariantBuilder (GLib.VariantType.TUPLE)"));
+ foreach (var param in sig.get_parameters ()) {
+ if (param.variable_type.data_type == context.analyzer.gvariant_type.data_type) {
+ b.add_expression (expression (@"$builder.add (\"v\", $(param.name))"));
+ } else {
+ b.add_expression (expression (@"$builder.add_value ($(param.name))"));
+ }
+ }
+ b.add_expression (expression (@"((GLib.DBusConnection) _data[1]).emit_signal (null, (string) _data[2], \"$dbus_iface_name\", \"$(get_dbus_name_for_member (sig))\", $builder.end ())"));
+ pop_builder ();
+ check (m);
+ }
+
+ void visit_object_type_symbol (ObjectTypeSymbol sym) {
+ string dbus_iface_name = get_dbus_name (sym);
+ if (dbus_iface_name == null) {
+ return;
+ }
+
+ generate_interface_method_call (sym);
+ generate_interface_get_property (sym);
+ generate_interface_set_property (sym);
+
+ foreach (var sig in sym.get_signals ()) {
+ if (sig.access != SymbolAccessibility.PUBLIC || !is_dbus_visible (sig)) {
+ continue;
+ }
+ generate_interface_signal_emitter (sig, sym, dbus_iface_name);
+ }
+ }
+}