From: Corentin Noël Date: Tue, 7 Apr 2020 21:50:55 +0000 (+0200) Subject: gdbus: Bind properties with the GDBusProxy directly X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cab375a09a4fc6e973176c8957ccab5dbb66738;p=thirdparty%2Fvala.git gdbus: Bind properties with the GDBusProxy directly --- diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala index 697b08758..27a335d1a 100644 --- a/codegen/valagdbusclientmodule.vala +++ b/codegen/valagdbusclientmodule.vala @@ -210,17 +210,51 @@ public class Vala.GDBusClientModule : GDBusModule { cfile.add_type_member_definition (define_type); + generate_properties_enums (iface); + var proxy_class_init = new CCodeFunction (lower_cname + "_class_init", "void"); proxy_class_init.add_parameter (new CCodeParameter ("klass", cname + "Class*")); proxy_class_init.modifiers = CCodeModifiers.STATIC; push_function (proxy_class_init); var proxy_class = new CCodeFunctionCall (new CCodeIdentifier ("G_DBUS_PROXY_CLASS")); proxy_class.add_argument (new CCodeIdentifier ("klass")); - ccode.add_assignment (new CCodeMemberAccess.pointer (proxy_class, "g_signal"), new CCodeIdentifier (lower_cname + "_g_signal")); + ccode.add_declaration ("GDBusProxyClass *", new CCodeVariableDeclarator.zero ("proxy_class", proxy_class)); + var proxy_class_identifier = new CCodeIdentifier ("proxy_class"); + + var object_class = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS")); + object_class.add_argument (new CCodeIdentifier ("klass")); + ccode.add_declaration ("GObjectClass *", new CCodeVariableDeclarator.zero ("object_class", object_class)); + var object_class_identifier = new CCodeIdentifier ("object_class"); + + ccode.add_assignment (new CCodeMemberAccess.pointer (proxy_class_identifier, "g_signal"), new CCodeIdentifier (lower_cname + "_g_signal")); + ccode.add_assignment (new CCodeMemberAccess.pointer (proxy_class_identifier, "g_properties_changed"), new CCodeIdentifier (lower_cname + "_g_properties_changed")); + + ccode.add_assignment (new CCodeMemberAccess.pointer (object_class_identifier, "get_property"), new CCodeIdentifier (lower_cname + "_get_property")); + ccode.add_assignment (new CCodeMemberAccess.pointer (object_class_identifier, "set_property"), new CCodeIdentifier (lower_cname + "_set_property")); + + var sym_name = get_ccode_upper_case_name (iface) + "_PROXY"; + var pspecs = new CCodeIdentifier ("%s_proxy_properties".printf (get_ccode_lower_case_name (iface))); + foreach (Property prop in iface.get_properties ()) { + var upper_identifier = new CCodeIdentifier ("%s_%s_PROPERTY".printf (sym_name, Symbol.camel_case_to_lower_case (prop.name).ascii_up ())); + var override_func = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_override_property")); + override_func.add_argument (object_class_identifier); + override_func.add_argument (upper_identifier); + override_func.add_argument (get_property_canonical_cconstant (prop)); + ccode.add_expression (override_func); + var find_prop = new CCodeFunctionCall (new CCodeIdentifier ("g_object_class_find_property")); + find_prop.add_argument (object_class_identifier); + find_prop.add_argument (get_property_canonical_cconstant (prop)); + ccode.add_assignment (new CCodeElementAccess (pspecs, upper_identifier), find_prop); + } + pop_function (); cfile.add_function (proxy_class_init); + generate_pspec_from_dbus_property (iface); + generate_get_property_function (iface); + generate_set_property_function (iface); generate_signal_handler_function (iface); + generate_properties_changed_handler_function (iface); if (in_plugin) { var proxy_class_finalize = new CCodeFunction (lower_cname + "_class_finalize", "void"); @@ -506,6 +540,117 @@ public class Vala.GDBusClientModule : GDBusModule { return wrapper_name; } + void generate_properties_enums (ObjectTypeSymbol sym) { + var prop_enum = new CCodeEnum (); + var sym_name = get_ccode_upper_case_name (sym) + "_PROXY"; + prop_enum.add_value (new CCodeEnumValue ("%s_0_PROPERTY".printf (sym_name))); + var properties = sym.get_properties (); + foreach (Property prop in properties) { + prop_enum.add_value (new CCodeEnumValue ("%s_%s_PROPERTY".printf (sym_name, Symbol.camel_case_to_lower_case (prop.name).ascii_up ()))); + } + + var last_prop = "%s_NUM_PROPERTIES".printf (sym_name); + prop_enum.add_value (new CCodeEnumValue (last_prop)); + cfile.add_type_declaration (prop_enum); + + var prop_array_decl = new CCodeDeclaration ("GParamSpec*"); + prop_array_decl.modifiers |= CCodeModifiers.STATIC; + prop_array_decl.add_declarator (new CCodeVariableDeclarator ("%s_proxy_properties".printf (get_ccode_lower_case_name (sym)), null, new CCodeDeclaratorSuffix.with_array (new CCodeIdentifier (last_prop)))); + cfile.add_type_declaration (prop_array_decl); + } + + void generate_get_property_function (ObjectTypeSymbol sym) { + var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "proxy_get_property", "void"); + cfunc.add_parameter (new CCodeParameter ("object", "GObject*")); + cfunc.add_parameter (new CCodeParameter ("property_id", "guint")); + cfunc.add_parameter (new CCodeParameter ("value", "GValue*")); + cfunc.add_parameter (new CCodeParameter ("pspec", "GParamSpec*")); + + cfunc.modifiers |= CCodeModifiers.STATIC; + + cfile.add_function_declaration (cfunc); + + push_function (cfunc); + + ccode.add_declaration ("%s *".printf (get_ccode_name (sym)), new CCodeVariableDeclarator ("self")); + ccode.add_declaration ("GVariant *", new CCodeVariableDeclarator ("variant", null)); + ccode.add_declaration ("const gchar *", new CCodeVariableDeclarator.zero ("dbus_property_name", new CCodeConstant ("NULL"))); + + var cast_call = generate_instance_cast (new CCodeIdentifier ("object"), sym); + ccode.add_assignment (new CCodeIdentifier ("self"), cast_call); + + ccode.open_switch (new CCodeIdentifier ("property_id")); + + var sym_name = get_ccode_upper_case_name (sym) + "_PROXY"; + var dbus_proxy_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_DBUS_PROXY")); + dbus_proxy_cast.add_argument (new CCodeIdentifier ("object")); + foreach (Property prop in sym.get_properties ()) { + if (prop.access != SymbolAccessibility.PUBLIC) { + continue; + } + + var upper_identifier = new CCodeIdentifier ("%s_%s_PROPERTY".printf (sym_name, Symbol.camel_case_to_lower_case (prop.name).ascii_up ())); + ccode.add_case (upper_identifier); + + string proxy_name = "%sdbus_proxy_get_%s".printf (get_ccode_lower_case_prefix (sym), prop.name); + property_to_value (prop, new CCodeIdentifier (proxy_name), new CCodeIdentifier ("self"), null); + + ccode.add_break (); + } + + ccode.add_default (); + ccode.add_statement (new CCodeReturnStatement (null)); + ccode.close (); + + pop_function (); + + cfile.add_function (cfunc); + } + + void generate_set_property_function (ObjectTypeSymbol sym) { + // Create the function + var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "proxy_set_property", "void"); + cfunc.add_parameter (new CCodeParameter ("object", "GObject*")); + cfunc.add_parameter (new CCodeParameter ("property_id", "guint")); + cfunc.add_parameter (new CCodeParameter ("value", "const GValue*")); + cfunc.add_parameter (new CCodeParameter ("pspec", "GParamSpec*")); + + cfunc.modifiers |= CCodeModifiers.STATIC; + + cfile.add_function_declaration (cfunc); + + push_function (cfunc); + + var cast_call = generate_instance_cast (new CCodeIdentifier ("object"), sym); + ccode.add_declaration ("%s *".printf (get_ccode_name (sym)), new CCodeVariableDeclarator ("self")); + ccode.add_assignment (new CCodeIdentifier ("self"), cast_call); + + ccode.open_switch (new CCodeIdentifier ("property_id")); + + var sym_name = get_ccode_upper_case_name (sym) + "_PROXY"; + foreach (Property prop in sym.get_properties ()) { + if (prop.access != SymbolAccessibility.PUBLIC) { + continue; + } + + var upper_identifier = new CCodeIdentifier ("%s_%s_PROPERTY".printf (sym_name, Symbol.camel_case_to_lower_case (prop.name).ascii_up ())); + ccode.add_case (upper_identifier); + + string proxy_name = "%sdbus_proxy_set_%s".printf (get_ccode_lower_case_prefix (sym), prop.name); + property_from_value (prop, new CCodeIdentifier (proxy_name), new CCodeIdentifier ("self"), null); + + ccode.add_break (); + } + + ccode.add_default (); + ccode.add_statement (new CCodeReturnStatement (null)); + ccode.close (); + + pop_function (); + + cfile.add_function (cfunc); + } + void generate_signal_handler_function (ObjectTypeSymbol sym) { var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "proxy_g_signal", "void"); cfunc.add_parameter (new CCodeParameter ("proxy", "GDBusProxy*")); @@ -555,6 +700,118 @@ public class Vala.GDBusClientModule : GDBusModule { cfile.add_function (cfunc); } + void generate_pspec_from_dbus_property (ObjectTypeSymbol sym) { + var cfunc = new CCodeFunction ("_vala_%sfind_property_from_dbus_name".printf (get_ccode_lower_case_prefix (sym)), "GParamSpec *"); + cfunc.add_parameter (new CCodeParameter ("dbus_property_name", "const gchar *")); + cfunc.modifiers |= CCodeModifiers.STATIC; + + cfile.add_function_declaration (cfunc); + + push_function (cfunc); + + bool firstif = true; + + var pspecs = new CCodeIdentifier ("%s_proxy_properties".printf (get_ccode_lower_case_name (sym))); + var sym_name = get_ccode_upper_case_name (sym) + "_PROXY"; + foreach (Property prop in sym.get_properties ()) { + if (prop.access != SymbolAccessibility.PUBLIC) { + continue; + } + + var ccheck = new CCodeFunctionCall (new CCodeIdentifier ("g_strcmp0")); + ccheck.add_argument (new CCodeIdentifier ("dbus_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; + } else { + ccode.else_if (cond); + } + + var upper_identifier = new CCodeIdentifier ("%s_%s_PROPERTY".printf (sym_name, Symbol.camel_case_to_lower_case (prop.name).ascii_up ())); + ccode.add_statement (new CCodeReturnStatement (new CCodeElementAccess (pspecs, upper_identifier))); + } + + if (!firstif) { + ccode.close (); + } + + ccode.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL"))); + + pop_function (); + cfile.add_function (cfunc); + } + + void generate_properties_changed_handler_function (ObjectTypeSymbol sym) { + var cfunc = new CCodeFunction (get_ccode_lower_case_prefix (sym) + "proxy_g_properties_changed", "void"); + cfunc.add_parameter (new CCodeParameter ("proxy", "GDBusProxy*")); + cfunc.add_parameter (new CCodeParameter ("changed_properties", "GVariant*")); + cfunc.add_parameter (new CCodeParameter ("invalidated_properties", "const gchar* const*")); + + cfunc.modifiers |= CCodeModifiers.STATIC; + + cfile.add_function_declaration (cfunc); + + push_function (cfunc); + + ccode.add_declaration ("GVariantIter *", new CCodeVariableDeclarator ("iter", null)); + ccode.add_declaration ("const gchar *", new CCodeVariableDeclarator ("key", null)); + ccode.add_declaration ("GParamSpec *", new CCodeVariableDeclarator ("pspec", null)); + ccode.add_declaration ("guint", new CCodeVariableDeclarator ("n", null)); + var pspec_identifier = new CCodeIdentifier ("pspec"); + var n_identifier = new CCodeIdentifier ("n"); + var variant_get = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_get")); + variant_get.add_argument (new CCodeIdentifier ("changed_properties")); + variant_get.add_argument (new CCodeConstant.string ("\"a{sv}\"")); + variant_get.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("iter"))); + ccode.add_expression (variant_get); + + var variant_iter_next = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_next")); + variant_iter_next.add_argument (new CCodeIdentifier ("iter")); + variant_iter_next.add_argument (new CCodeConstant.string ("\"{&sv}\"")); + variant_iter_next.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("key"))); + variant_iter_next.add_argument (new CCodeConstant ("NULL")); + + ccode.open_while (variant_iter_next); + var find_property_from_dbus_name = new CCodeFunctionCall (new CCodeIdentifier ("_vala_%sfind_property_from_dbus_name".printf (get_ccode_lower_case_prefix (sym)))); + find_property_from_dbus_name.add_argument (new CCodeIdentifier ("key")); + ccode.add_assignment (pspec_identifier, find_property_from_dbus_name); + + ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, pspec_identifier, new CCodeConstant ("NULL"))); + + var notify_by_pspec = new CCodeFunctionCall (new CCodeIdentifier ("g_object_notify_by_pspec")); + notify_by_pspec.add_argument (new CCodeCastExpression (new CCodeIdentifier ("proxy"), "GObject *")); + notify_by_pspec.add_argument (pspec_identifier); + ccode.add_expression (notify_by_pspec); + + ccode.close (); + ccode.close (); + + var variant_iter_free = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_iter_free")); + variant_iter_free.add_argument (new CCodeIdentifier ("iter")); + ccode.add_expression (variant_iter_free); + + var for_init = new CCodeAssignment (n_identifier, new CCodeConstant ("0")); + var for_increment = new CCodeUnaryExpression (CCodeUnaryOperator.POSTFIX_INCREMENT, n_identifier); + var for_condition = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, new CCodeElementAccess (new CCodeIdentifier ("invalidated_properties"), n_identifier), new CCodeConstant ("NULL")); + ccode.open_for (for_init, for_condition, for_increment); + var find_invalidated_property_from_dbus_name = new CCodeFunctionCall (new CCodeIdentifier ("_vala_%sfind_property_from_dbus_name".printf (get_ccode_lower_case_prefix (sym)))); + find_invalidated_property_from_dbus_name.add_argument (new CCodeElementAccess (new CCodeIdentifier ("invalidated_properties"), n_identifier)); + ccode.add_assignment (pspec_identifier, find_invalidated_property_from_dbus_name); + + ccode.open_if (new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, pspec_identifier, new CCodeConstant ("NULL"))); + ccode.add_expression (notify_by_pspec); + ccode.close (); + ccode.close (); + + pop_function (); + + cfile.add_function (cfunc); + } + + void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name, int method_timeout) { var gdbusproxy = new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *"); diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala index 6e026b43b..4d9eddd78 100644 --- a/codegen/valagdbusservermodule.vala +++ b/codegen/valagdbusservermodule.vala @@ -704,6 +704,105 @@ public class Vala.GDBusServerModule : GDBusClientModule { } } + void generate_property_notify (ObjectTypeSymbol sym, Property prop) { + var cfunc = new CCodeFunction ("_%snotify_%s".printf (get_ccode_lower_case_prefix (sym), prop.name), "void"); + cfunc.add_parameter (new CCodeParameter ("gobject", "GObject *")); + cfunc.add_parameter (new CCodeParameter ("pspec", "GParamSpec *")); + cfunc.add_parameter (new CCodeParameter ("user_data", "gpointer")); + + cfunc.modifiers |= CCodeModifiers.STATIC; + + push_function (cfunc); + + ccode.add_declaration ("gpointer*", new CCodeVariableDeclarator.zero ("data", new CCodeIdentifier ("user_data"))); + ccode.add_declaration ("GError*", new CCodeVariableDeclarator.zero ("error", new CCodeConstant ("NULL"))); + ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator.zero ("parameters", new CCodeConstant ("NULL"))); + ccode.add_declaration ("GVariant*", new CCodeVariableDeclarator.zero ("variant", new CCodeConstant ("NULL"))); + ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("changed_builder", null)); + ccode.add_declaration ("GVariantBuilder", new CCodeVariableDeclarator ("invalidated_builder", null)); + + var variant_builder_init = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init")); + variant_builder_init.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("changed_builder"))); + variant_builder_init.add_argument (new CCodeConstant ("G_VARIANT_TYPE_VARDICT")); + ccode.add_expression (variant_builder_init); + + var variant_builder_init2 = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_init")); + variant_builder_init2.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("invalidated_builder"))); + variant_builder_init2.add_argument (new CCodeConstant ("G_VARIANT_TYPE_STRING_ARRAY")); + ccode.add_expression (variant_builder_init2); + + var cast_call = generate_instance_cast (new CCodeIdentifier ("gobject"), sym); + ccode.add_declaration ("%s *".printf (get_ccode_name (sym)), new CCodeVariableDeclarator ("self")); + ccode.add_assignment (new CCodeIdentifier ("self"), cast_call); + + var dbus_get_property = new CCodeFunctionCall (new CCodeIdentifier ("_dbus_%s".printf (get_ccode_name (prop.get_accessor)))); + dbus_get_property.add_argument (new CCodeIdentifier ("self")); + ccode.add_assignment (new CCodeIdentifier ("variant"), dbus_get_property); + + var variant_builder_add = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_builder_add")); + variant_builder_add.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("changed_builder"))); + variant_builder_add.add_argument (new CCodeConstant.string ("\"{sv}\"")); + variant_builder_add.add_argument (new CCodeConstant.string ("\"%s\"".printf (get_dbus_name_for_member (prop)))); + variant_builder_add.add_argument (new CCodeIdentifier ("variant")); + ccode.add_expression (variant_builder_add); + + var variant_new = new CCodeFunctionCall (new CCodeIdentifier ("g_variant_new")); + variant_new.add_argument (new CCodeConstant.string ("\"(sa{sv}as)\"")); + variant_new.add_argument (new CCodeConstant.string ("\"%s\"".printf (get_dbus_name (sym)))); + variant_new.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("changed_builder"))); + variant_new.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("invalidated_builder"))); + ccode.add_assignment (new CCodeIdentifier ("parameters"), variant_new); + + var disconnect_call = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_connection_emit_signal")); + disconnect_call.add_argument (new CCodeCastExpression (new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("1")), "GDBusConnection *")); + disconnect_call.add_argument (new CCodeConstant ("NULL")); + disconnect_call.add_argument (new CCodeCastExpression (new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("2")), "const gchar *")); + disconnect_call.add_argument (new CCodeConstant.string ("\"org.freedesktop.DBus.Properties\"")); + disconnect_call.add_argument (new CCodeConstant.string ("\"PropertiesChanged\"")); + disconnect_call.add_argument (new CCodeIdentifier ("parameters")); + disconnect_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error"))); + ccode.add_expression (disconnect_call); + + pop_function (); + + cfile.add_function_declaration (cfunc); + cfile.add_function (cfunc); + } + + void handle_properties (ObjectTypeSymbol sym, bool connect) { + string dbus_iface_name = get_dbus_name (sym); + if (dbus_iface_name == null) { + return; + } + + foreach (Property prop in sym.get_properties ()) { + if (prop.access != SymbolAccessibility.PUBLIC) { + continue; + } + if (!is_dbus_visible (prop)) { + continue; + } + + var notify_name = "_%snotify_%s".printf (get_ccode_lower_case_prefix (sym), prop.name); + if (connect) { + generate_property_notify (sym, prop); + var connect_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_connect")); + connect_call.add_argument (new CCodeIdentifier ("object")); + connect_call.add_argument (new CCodeConstant.string ("\"notify::%s\"".printf (get_ccode_name (prop)))); + connect_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (notify_name), "GCallback")); + connect_call.add_argument (new CCodeIdentifier ("data")); + ccode.add_expression (connect_call); + } else { + // disconnect the signals + var disconnect_call = new CCodeFunctionCall (new CCodeIdentifier ("g_signal_handlers_disconnect_by_func")); + disconnect_call.add_argument (new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("0"))); + disconnect_call.add_argument (new CCodeIdentifier (notify_name)); + disconnect_call.add_argument (new CCodeIdentifier ("data")); + ccode.add_expression (disconnect_call); + } + } + } + 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*")); @@ -1157,6 +1256,7 @@ public class Vala.GDBusServerModule : GDBusClientModule { ccode.close (); handle_signals (sym, true); + handle_properties (sym, true); ccode.add_return (new CCodeIdentifier ("result")); @@ -1173,6 +1273,7 @@ public class Vala.GDBusServerModule : GDBusClientModule { ccode.add_declaration ("gpointer*", new CCodeVariableDeclarator ("data", new CCodeIdentifier ("user_data"))); handle_signals (sym, false); + handle_properties (sym, false); var unref_object = new CCodeFunctionCall (new CCodeIdentifier (get_ccode_unref_function (sym))); unref_object.add_argument (new CCodeElementAccess (new CCodeIdentifier ("data"), new CCodeConstant ("0"))); diff --git a/tests/Makefile.am b/tests/Makefile.am index ce7f030f1..281b41b2f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -872,6 +872,7 @@ TESTS = \ dbus/enum-string-marshalling.vala \ dbus/generics.test \ dbus/no-reply.test \ + dbus/properties.test \ dbus/signals.test \ dbus/filedescriptor.test \ dbus/filedescriptor-async.test \ diff --git a/tests/dbus/properties.test b/tests/dbus/properties.test new file mode 100644 index 000000000..46358a34b --- /dev/null +++ b/tests/dbus/properties.test @@ -0,0 +1,110 @@ +Packages: gio-2.0 +D-Bus + +Program: client + +[DBus (name = "org.example.Test")] +interface Test : Object { + public abstract string test_property { owned get; set; } + public abstract int test_int_property { get; set; } + public abstract void change_everything () throws GLib.Error; + public abstract void check_everything () throws GLib.Error; +} + +class Test2 : Object { + public string test_property { get; set; } + public int test_int_property { get; set; } +} + +void main () { + // client + Test test = Bus.get_proxy_sync (BusType.SESSION, "org.example.Test", "/org/example/test", DBusProxyFlags.NONE); + assert (test.test_property == "foo"); + assert (test.test_int_property == 17); + + Test2 test2 = new Test2 (); + test.bind_property ("test-property", test2, "test-property", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); + test.bind_property ("test-int-property", test2, "test-int-property", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); + + { + MainLoop main_loop = new MainLoop (); + + assert (test2.test_property == "foo"); + assert (test2.test_int_property == 17); + + test2.notify["test-int-property"].connect ((p) => { + assert (((ParamSpecInt) p).name == "test-int-property"); + main_loop.quit (); + }); + + test.change_everything (); + main_loop.run (); + + assert (test.test_property == "bar"); + assert (test.test_int_property == 53); + } + { + MainLoop main_loop2 = new MainLoop (); + + assert (test2.test_property == "bar"); + assert (test2.test_int_property == 53); + + test.notify["test-property"].connect ((p) => { + assert (((ParamSpecString) p).name == "test-property"); + main_loop2.quit (); + }); + + test2.test_property = "baz"; + test2.test_int_property = 765; + main_loop2.run (); + + assert (test2.test_property == "baz"); + assert (test2.test_int_property == 765); + + test.check_everything (); + } +} + +Program: server + +[DBus (name = "org.example.Test")] +class Test : Object { + public string test_property { owned get; set; default = "foo";} + public int test_int_property { get; set; default = 17; } + + public void change_everything () throws GLib.Error { + test_property = "bar"; + test_int_property = 53; + } + + public void check_everything () throws GLib.Error { + assert (test_property == "baz"); + assert (test_int_property == 765); + } +} + +MainLoop main_loop; + +void client_exit (Pid pid, int status) { + // client finished, terminate server + assert (status == 0); + main_loop.quit (); +} + +void main () { + var conn = Bus.get_sync (BusType.SESSION); + conn.register_object ("/org/example/test", new Test ()); + + // try to register service in session bus + var request_result = conn.call_sync ("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "RequestName", + new Variant ("(su)", "org.example.Test", 0x4), null, 0, -1); + assert ((uint) request_result.get_child_value (0) == 1); + + // server ready, spawn client + Pid client_pid; + Process.spawn_async (null, { "dbus_properties_client" }, null, SpawnFlags.DO_NOT_REAP_CHILD, null, out client_pid); + ChildWatch.add (client_pid, client_exit); + + main_loop = new MainLoop (); + main_loop.run (); +} diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index b560f2a7a..cb8aa7ffa 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -473,11 +473,6 @@ public class Vala.SemanticAnalyzer : CodeVisitor { return false; } - if (type_sym is Interface && type_sym.has_attribute ("DBus")) { - // GObject properties not currently supported in D-Bus interfaces - return false; - } - return true; }