add experimental D-Bus client support
authorJuerg Billeter <j@bitron.ch>
Mon, 6 Aug 2007 14:43:16 +0000 (14:43 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Mon, 6 Aug 2007 14:43:16 +0000 (14:43 +0000)
2007-08-06  Juerg Billeter  <j@bitron.ch>

* vala/Makefile.am, vala/parser.y, vala/valaarray.vala,
  vala/valabindingprovider.vala, vala/valaclass.vala,
  vala/valaenum.vala, vala/valainterface.vala,
  vala/valamemorymanager.vala, vala/valamethod.vala,
  vala/valasemanticanalyzer.vala, vala/valasymbol.vala,
  vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
  gobject/Makefile.am, gobject/valacodegenerator.vala,
  gobject/valacodegeneratorassignment.vala,
  gobject/valacodegeneratorclass.vala,
  gobject/valacodegeneratorinterface.vala,
  gobject/valacodegeneratorinvocationexpression.vala,
  gobject/valacodegeneratormethod.vala,
  gobject/valadbusbindingprovider.vala, gobject/valadbusmethod.vala,
  gobject/valadbussignal.vala, compiler/valacompiler.vala,
  vapi/dbus-glib-1.vala, vapi/hal.vala: add experimental D-Bus client
  support

svn path=/trunk/; revision=419

27 files changed:
ChangeLog
compiler/valacompiler.vala
gobject/Makefile.am
gobject/valacodegenerator.vala
gobject/valacodegeneratorassignment.vala
gobject/valacodegeneratorclass.vala
gobject/valacodegeneratorinterface.vala
gobject/valacodegeneratorinvocationexpression.vala
gobject/valacodegeneratormethod.vala
gobject/valadbusbindingprovider.vala [new file with mode: 0644]
gobject/valadbusmethod.vala [new file with mode: 0644]
gobject/valadbussignal.vala [new file with mode: 0644]
vala/Makefile.am
vala/parser.y
vala/valaarray.vala
vala/valabindingprovider.vala [new file with mode: 0644]
vala/valaclass.vala
vala/valaenum.vala
vala/valainterface.vala
vala/valamemorymanager.vala
vala/valamethod.vala
vala/valasemanticanalyzer.vala
vala/valasymbol.vala
vala/valasymbolresolver.vala
vala/valavariabledeclarator.vala
vapi/dbus-glib-1.vala
vapi/hal.vala

index 80e3d41..391191d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2007-08-06  Jürg Billeter  <j@bitron.ch>
 
+       * vala/Makefile.am, vala/parser.y, vala/valaarray.vala,
+         vala/valabindingprovider.vala, vala/valaclass.vala,
+         vala/valaenum.vala, vala/valainterface.vala,
+         vala/valamemorymanager.vala, vala/valamethod.vala,
+         vala/valasemanticanalyzer.vala, vala/valasymbol.vala,
+         vala/valasymbolresolver.vala, vala/valavariabledeclarator.vala,
+         gobject/Makefile.am, gobject/valacodegenerator.vala,
+         gobject/valacodegeneratorassignment.vala,
+         gobject/valacodegeneratorclass.vala,
+         gobject/valacodegeneratorinterface.vala,
+         gobject/valacodegeneratorinvocationexpression.vala,
+         gobject/valacodegeneratormethod.vala,
+         gobject/valadbusbindingprovider.vala, gobject/valadbusmethod.vala,
+         gobject/valadbussignal.vala, compiler/valacompiler.vala,
+         vapi/dbus-glib-1.vala, vapi/hal.vala: add experimental D-Bus client
+         support
+
+2007-08-06  Jürg Billeter  <j@bitron.ch>
+
        * gobject/valacodegenerator.vala,
          gobject/valacodegeneratorassignment.vala: fixes for multi-dimension
          arrays
index d7be88c..1ad4f5a 100644 (file)
@@ -217,8 +217,12 @@ class Vala.Compiler {
                if (Report.get_errors () > 0) {
                        return quit ();
                }
-               
+
+               var dbus_binding_provider = new DBusBindingProvider ();
+               dbus_binding_provider.context = context;
+
                var analyzer = new SemanticAnalyzer (!disable_memory_management);
+               analyzer.add_binding_provider (dbus_binding_provider);
                analyzer.analyze (context);
                
                if (Report.get_errors () > 0) {
index 08758d4..02b6c8f 100644 (file)
@@ -48,6 +48,15 @@ libvala_la_SOURCES = \
        valacodegeneratorstruct.c \
        valacodegeneratorstruct.h \
        valacodegeneratorstruct.vala \
+       valadbusbindingprovider.c \
+       valadbusbindingprovider.h \
+       valadbusbindingprovider.vala \
+       valadbusmethod.c \
+       valadbusmethod.h \
+       valadbusmethod.vala \
+       valadbussignal.c \
+       valadbussignal.h \
+       valadbussignal.vala \
        valainterfaceregisterfunction.c \
        valainterfaceregisterfunction.h \
        valainterfaceregisterfunction.vala \
@@ -71,6 +80,9 @@ gobjectinclude_HEADERS = \
        valacodegeneratorsignal.h \
        valacodegeneratorsourcefile.h \
        valacodegeneratorstruct.h \
+       valadbusbindingprovider.h \
+       valadbusmethod.h \
+       valadbussignal.h \
        valainterfaceregisterfunction.h \
        valatyperegisterfunction.h \
        $(NULL)
index edf9b7d..7ba7b2e 100644 (file)
@@ -99,12 +99,14 @@ public class Vala.CodeGenerator : CodeVisitor {
        DataType glist_type;
        DataType gslist_type;
        DataType gstring_type;
+       DataType garray_type;
        TypeReference mutex_type;
        DataType type_module_type;
        DataType iterable_type;
        DataType iterator_type;
        DataType list_type;
        DataType map_type;
+       DataType connection_type;
 
        Method substring_method;
 
@@ -246,6 +248,7 @@ public class Vala.CodeGenerator : CodeVisitor {
                glist_type = (DataType) glib_ns.scope.lookup ("List");
                gslist_type = (DataType) glib_ns.scope.lookup ("SList");
                gstring_type = (DataType) glib_ns.scope.lookup ("String");
+               garray_type = (DataType) glib_ns.scope.lookup ("Array");
                
                mutex_type = new TypeReference ();
                mutex_type.data_type = (DataType) glib_ns.scope.lookup ("Mutex");
@@ -270,6 +273,11 @@ public class Vala.CodeGenerator : CodeVisitor {
                        list_type = (DataType) gee_ns.scope.lookup ("List");
                        map_type = (DataType) gee_ns.scope.lookup ("Map");
                }
+
+               var dbus_ns = root_symbol.scope.lookup ("DBus");
+               if (dbus_ns != null) {
+                       connection_type = (DataType) dbus_ns.scope.lookup ("Connection");
+               }
        
                /* we're only interested in non-pkg source files */
                var source_files = context.get_source_files ();
@@ -807,6 +815,8 @@ public class Vala.CodeGenerator : CodeVisitor {
        }
 
        public override void visit_variable_declarator (VariableDeclarator! decl) {
+               decl.accept_children (this);
+
                if (decl.type_reference.data_type is Array) {
                        // create variables to store array dimensions
                        var arr = (Array) decl.type_reference.data_type;
index c334f96..e7cbb7e 100644 (file)
@@ -125,12 +125,20 @@ public class Vala.CodeGenerator {
                        bool disconnect = false;
 
                        if (a.operator == AssignmentOperator.ADD) {
-                               connect_func = "g_signal_connect_object";
-                               if (!m.instance) {
-                                       connect_func = "g_signal_connect";
+                               if (sig is DBusSignal) {
+                                       connect_func = "dbus_g_proxy_connect_signal";
+                               } else {
+                                       connect_func = "g_signal_connect_object";
+                                       if (!m.instance) {
+                                               connect_func = "g_signal_connect";
+                                       }
                                }
                        } else if (a.operator == AssignmentOperator.SUB) {
-                               connect_func = "g_signal_handlers_disconnect_matched";
+                               if (sig is DBusSignal) {
+                                       connect_func = "dbus_g_proxy_disconnect_signal";
+                               } else {
+                                       connect_func = "g_signal_handlers_disconnect_matched";
+                               }
                                disconnect = true;
                        } else {
                                a.error = true;
@@ -146,7 +154,7 @@ public class Vala.CodeGenerator {
                                ccall.add_argument (new CCodeIdentifier ("self"));
                        }
 
-                       if (!disconnect) {
+                       if (!disconnect || sig is DBusSignal) {
                                ccall.add_argument (sig.get_canonical_cconstant ());
                        } else {
                                ccall.add_argument (new CCodeConstant ("G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA"));
@@ -185,13 +193,74 @@ public class Vala.CodeGenerator {
                                        ccall.add_argument (new CCodeIdentifier ("self"));
                                }
                                if (!disconnect) {
-                                       ccall.add_argument (new CCodeConstant ("0"));
+                                       if (sig is DBusSignal) {
+                                               // free_data_func
+                                               ccall.add_argument (new CCodeConstant ("NULL"));
+                                       } else {
+                                               // connect_flags
+                                               ccall.add_argument (new CCodeConstant ("0"));
+                                       }
                                }
                        } else {
                                ccall.add_argument (new CCodeConstant ("NULL"));
                        }
                        
                        a.ccodenode = ccall;
+                       
+                       if (sig is DBusSignal && !disconnect) {
+                               bool first = true;
+                               foreach (FormalParameter param in m.get_parameters ()) {
+                                       if (first) {
+                                               // skip sender parameter
+                                               first = false;
+                                               continue;
+                                       }
+                                       sig.add_parameter (param);
+                               }
+
+                               sig.accept (this);
+
+                               // FIXME should only be done once per marshaller
+                               var register_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_object_register_marshaller"));
+                               register_call.add_argument (new CCodeIdentifier (get_signal_marshaller_function (sig)));
+                               register_call.add_argument (new CCodeIdentifier ("G_TYPE_NONE"));
+
+                               var add_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_add_signal"));
+                               if (ma.inner != null) {
+                                       add_call.add_argument ((CCodeExpression) ma.inner.ccodenode);
+                               } else {
+                                       add_call.add_argument (new CCodeIdentifier ("self"));
+                               }
+                               add_call.add_argument (sig.get_canonical_cconstant ());
+
+                               first = true;
+                               foreach (FormalParameter param in m.get_parameters ()) {
+                                       if (first) {
+                                               // skip sender parameter
+                                               first = false;
+                                               continue;
+                                       }
+                                       if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != string_type.data_type) {
+                                               var array = (Array) param.type_reference.data_type;
+                                               var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
+                                               carray_type.add_argument (new CCodeConstant ("\"GArray\""));
+                                               carray_type.add_argument (new CCodeIdentifier (array.element_type.get_type_id ()));
+                                               register_call.add_argument (carray_type);
+                                               add_call.add_argument (carray_type);
+                                       } else {
+                                               register_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
+                                               add_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
+                                       }
+                               }
+                               register_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+                               add_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (register_call);
+                               ccomma.append_expression (add_call);
+                               ccomma.append_expression (ccall);
+                               a.ccodenode = ccomma;
+                       }
                } else if (a.left is ElementAccess && !(((ElementAccess) a.left).container.static_type.data_type is Array)) {
                        // custom element access
                        CCodeExpression rhs = (CCodeExpression) a.right.ccodenode;
index f38322e..6cf5553 100644 (file)
@@ -97,7 +97,7 @@ public class Vala.CodeGenerator {
                def_frag.append (instance_struct);
                def_frag.append (type_struct);
                /* only add the *Private struct if it is not empty, i.e. we actually have private data */
-               if (cl.has_private_fields) {
+               if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
                        source_type_member_declaration.append (instance_priv_struct);
                        macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_upper_case_cname ("TYPE_"), cl.get_cname ());
                        source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
@@ -107,10 +107,10 @@ public class Vala.CodeGenerator {
                cl.accept_children (this);
 
                if (!cl.is_static) {
-                       if (class_has_readable_properties (cl)) {
+                       if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
                                add_get_property_function (cl);
                        }
-                       if (class_has_writable_properties (cl)) {
+                       if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
                                add_set_property_function (cl);
                        }
                        add_class_init_function (cl);
@@ -176,7 +176,7 @@ public class Vala.CodeGenerator {
                init_block.add_statement (new CCodeExpressionStatement (parent_assignment));
                
                /* add struct for private fields */
-               if (cl.has_private_fields) {
+               if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
                        ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_type_class_add_private"));
                        ccall.add_argument (new CCodeIdentifier ("klass"));
                        ccall.add_argument (new CCodeConstant ("sizeof (%sPrivate)".printf (cl.get_cname ())));
@@ -186,10 +186,10 @@ public class Vala.CodeGenerator {
                /* set property handlers */
                ccall = new CCodeFunctionCall (new CCodeIdentifier ("G_OBJECT_CLASS"));
                ccall.add_argument (new CCodeIdentifier ("klass"));
-               if (class_has_readable_properties (cl)) {
+               if (class_has_readable_properties (cl) || cl.get_type_parameters ().size > 0) {
                        init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "get_property"), new CCodeIdentifier ("%s_get_property".printf (cl.get_lower_case_cname (null))))));
                }
-               if (class_has_writable_properties (cl)) {
+               if (class_has_writable_properties (cl) || cl.get_type_parameters ().size > 0) {
                        init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (ccall, "set_property"), new CCodeIdentifier ("%s_set_property".printf (cl.get_lower_case_cname (null))))));
                }
                
@@ -337,7 +337,7 @@ public class Vala.CodeGenerator {
                var init_block = new CCodeBlock ();
                instance_init.block = init_block;
                
-               if (cl.has_private_fields) {
+               if (cl.has_private_fields || cl.get_type_parameters ().size > 0) {
                        var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_PRIVATE".printf (cl.get_upper_case_cname (null))));
                        ccall.add_argument (new CCodeIdentifier ("self"));
                        init_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), ccall)));
index 1669ed8..58516ee 100644 (file)
@@ -28,7 +28,7 @@ public class Vala.CodeGenerator {
                current_symbol = iface;
                current_type_symbol = iface;
 
-               if (!iface.is_static) {
+               if (!iface.is_static && !iface.declaration_only) {
                        type_struct = new CCodeStruct ("_%s".printf (iface.get_type_cname ()));
                        
                        header_type_declaration.append (new CCodeNewline ());
@@ -61,7 +61,7 @@ public class Vala.CodeGenerator {
 
                iface.accept_children (this);
 
-               if (!iface.is_static) {
+               if (!iface.is_static && !iface.declaration_only) {
                        add_interface_base_init_function (iface);
 
                        var type_fun = new InterfaceRegisterFunction (iface);
index 306fece..7a43287 100644 (file)
@@ -73,12 +73,12 @@ public class Vala.CodeGenerator {
                        if (ma.inner == null) {
                                instance = new CCodeIdentifier ("self");
                                /* require casts for overriden and inherited methods */
-                               req_cast = m.overrides || m.base_interface_method != null || (m.parent_symbol != current_type_symbol);
+                               req_cast = m.overrides || m.base_interface_method != null || (m.parent_symbol != null && m.parent_symbol != current_type_symbol);
                        } else {
                                instance = (CCodeExpression) ma.inner.ccodenode;
                                /* reqiure casts if the type of the used instance is
                                 * different than the type which declared the method */
-                               req_cast = base_method.parent_symbol != ma.inner.static_type.data_type;
+                               req_cast = base_method.parent_symbol != null && base_method.parent_symbol != ma.inner.static_type.data_type;
                        }
                        
                        if (m.instance_by_reference && (ma.inner != null || m.parent_symbol != current_type_symbol)) {
@@ -102,6 +102,103 @@ public class Vala.CodeGenerator {
                        var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
                        csizeof.add_argument (new CCodeIdentifier (array.get_cname ()));
                        ccall.add_argument (csizeof);
+               } else if (m is DBusMethod) {
+                       bool found_out = false;
+                       Expression callback = null;
+                       foreach (Expression arg in expr.get_argument_list ()) {
+                               if (arg.symbol_reference is Method) {
+                                       // callback
+                                       if (callback != null) {
+                                               Report.error (expr.source_reference, "only one reply callback may be specified in invocation of DBus method");
+                                               expr.error = true;
+                                               return;
+                                       } else if (found_out) {
+                                               Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method");
+                                               expr.error = true;
+                                               return;
+                                       }
+                                       callback = arg;
+                               } else if (arg is UnaryExpression && ((UnaryExpression) arg).operator == UnaryOperator.OUT) {
+                                       // out arg
+                                       if (callback != null) {
+                                               Report.error (expr.source_reference, "out argument and reply callback conflict in invocation of DBus method");
+                                               expr.error = true;
+                                               return;
+                                       }
+                                       found_out = true;
+                               } else {
+                                       // in arg
+                                       if (callback != null || found_out) {
+                                               Report.error (expr.source_reference, "in argument must not follow out argument or reply callback in invocation of DBus method");
+                                               expr.error = true;
+                                               return;
+                                       }
+                               }
+                       }
+
+                       ccall.add_argument (new CCodeConstant ("\"%s\"".printf (m.name)));
+
+                       if (callback != null) {
+                               var reply_method = (Method) callback.symbol_reference;
+
+                               var cb_fun = new CCodeFunction ("_%s_cb".printf (reply_method.get_cname ()), "void");
+                               cb_fun.modifiers = CCodeModifiers.STATIC;
+                               cb_fun.add_parameter (new CCodeFormalParameter ("proxy", "DBusGProxy*"));
+                               cb_fun.add_parameter (new CCodeFormalParameter ("call", "DBusGProxyCall*"));
+                               cb_fun.add_parameter (new CCodeFormalParameter ("user_data", "void*"));
+                               cb_fun.block = new CCodeBlock ();
+                               var cerrdecl = new CCodeDeclaration ("GError*");
+                               cerrdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("error", new CCodeConstant ("NULL")));
+                               cb_fun.block.add_statement (cerrdecl);
+                               var cend_call = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_end_call"));
+                               cend_call.add_argument (new CCodeIdentifier ("proxy"));
+                               cend_call.add_argument (new CCodeIdentifier ("call"));
+                               cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("error")));
+                               var creply_call = new CCodeFunctionCall ((CCodeExpression) callback.ccodenode);
+                               creply_call.add_argument (new CCodeIdentifier ("user_data"));
+                               int param_count = reply_method.get_parameters ().size;
+                               int i = 0;
+                               foreach (FormalParameter param in reply_method.get_parameters ()) {
+                                       if ((++i) == param_count) {
+                                               // error parameter
+                                               break;
+                                       }
+                                       if (param.type_reference.data_type is Array && ((Array) param.type_reference.data_type).element_type != string_type.data_type) {
+                                               var array = (Array) param.type_reference.data_type;
+                                               var cdecl = new CCodeDeclaration ("GArray*");
+                                               cdecl.add_declarator (new CCodeVariableDeclarator (param.name));
+                                               cb_fun.block.add_statement (cdecl);
+                                               cend_call.add_argument (get_dbus_array_type (array));
+                                               cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+                                               creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "len"));
+                                               creply_call.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier (param.name), "data"));
+                                       } else {
+                                               var cdecl = new CCodeDeclaration (param.type_reference.get_cname ());
+                                               cdecl.add_declarator (new CCodeVariableDeclarator (param.name));
+                                               cb_fun.block.add_statement (cdecl);
+                                               cend_call.add_argument (new CCodeIdentifier (param.type_reference.data_type.get_type_id ()));
+                                               cend_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+                                               creply_call.add_argument (new CCodeIdentifier (param.name));
+                                       }
+                               }
+                               cend_call.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+                               cb_fun.block.add_statement (new CCodeExpressionStatement (cend_call));
+                               creply_call.add_argument (new CCodeIdentifier ("error"));
+                               cb_fun.block.add_statement (new CCodeExpressionStatement (creply_call));
+                               source_type_member_definition.append (cb_fun);
+
+                               ccall.add_argument (new CCodeIdentifier (cb_fun.name));
+                               ccall.add_argument (new CCodeConstant ("self"));
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       } else if (found_out || m.return_type.data_type != null) {
+                               ccall.call = new CCodeIdentifier ("dbus_g_proxy_call");
+
+                               // method can fail
+                               current_method_inner_error = true;
+                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
+                       } else {
+                               ccall.call = new CCodeIdentifier ("dbus_g_proxy_call_no_reply");
+                       }
                }
 
                bool ellipsis = false;
@@ -109,9 +206,15 @@ public class Vala.CodeGenerator {
                var i = 1;
                Iterator<FormalParameter> params_it = params.iterator ();
                foreach (Expression arg in expr.get_argument_list ()) {
-                       /* explicitly use strong reference as ccall gets
-                        * unrefed at end of inner block
-                        */
+                       if (m is DBusMethod) {
+                               if (arg.symbol_reference is Method) {
+                                       // callback parameter
+                                       break;
+                               }
+                               
+                               ccall.add_argument (new CCodeIdentifier (arg.static_type.data_type.get_type_id ()));
+                       }
+
                        CCodeExpression cexpr = (CCodeExpression) arg.ccodenode;
                        if (params_it.next ()) {
                                var param = params_it.get ();
@@ -175,7 +278,7 @@ public class Vala.CodeGenerator {
                }
 
                /* add length argument for methods returning arrays */
-               if (m != null && m.return_type.data_type is Array) {
+               if (m != null && m.return_type.data_type is Array && !(m is DBusMethod)) {
                        var arr = (Array) m.return_type.data_type;
                        for (int dim = 1; dim <= arr.rank; dim++) {
                                if (!m.no_array_length) {
@@ -193,7 +296,15 @@ public class Vala.CodeGenerator {
                        }
                }
 
-               if (expr.can_fail) {
+               if (connection_type != null && ma.inner != null && ma.inner.static_type != null && ma.inner.static_type.data_type == connection_type && m.name == "get_object") {
+                       var dbus_iface = (Interface) m.return_type.data_type;
+                       var dbus_attr = dbus_iface.get_attribute ("DBusInterface");
+                       ccall.add_argument (new CCodeConstant ("\"%s\"".printf (dbus_attr.get_string ("name"))));
+               } else if (m is DBusMethod) {
+                       ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+               }
+
+               if (expr.can_fail && !(m is DBusMethod)) {
                        // method can fail
                        current_method_inner_error = true;
                        ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("inner_error")));
@@ -204,7 +315,7 @@ public class Vala.CodeGenerator {
                } else if (ellipsis) {
                        /* ensure variable argument list ends with NULL
                         * except when using printf-style arguments */
-                       if (m == null || !m.printf_format) {
+                       if ((m == null || !m.printf_format) && !(m is DBusMethod)) {
                                ccall.add_argument (new CCodeConstant ("NULL"));
                        }
                }
@@ -282,7 +393,52 @@ public class Vala.CodeGenerator {
                        ccomma.append_expression (cndupcall);
 
                        expr.ccodenode = ccomma;
+               } else if (m is DBusMethod && m.return_type.data_type != null) {
+                       if (m.return_type.data_type is Array && ((Array) m.return_type.data_type).element_type != string_type.data_type) {
+                               var array = (Array) m.return_type.data_type;
+
+                               ccall.add_argument (get_dbus_array_type (array));
+
+                               var garray_type_reference = new TypeReference ();
+                               garray_type_reference.data_type = garray_type;
+                               var temp_decl = get_temp_variable_declarator (garray_type_reference);
+                               temp_vars.insert (0, temp_decl);
+                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
+
+                               ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (ccall);
+                               ccomma.append_expression (new CCodeMemberAccess.pointer (new CCodeIdentifier (temp_decl.name), "data"));
+                               expr.ccodenode = ccomma;
+
+                               if (!m.no_array_length) {
+                                       expr.append_array_size (new CCodeMemberAccess.pointer (new CCodeIdentifier (temp_decl.name), "len"));
+                               } else {
+                                       expr.append_array_size (new CCodeConstant ("-1"));
+                               }
+                       } else {
+                               ccall.add_argument (new CCodeIdentifier (m.return_type.data_type.get_type_id ()));
+
+                               var temp_decl = get_temp_variable_declarator (m.return_type);
+                               temp_vars.insert (0, temp_decl);
+                               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (temp_decl.name)));
+
+                               ccall.add_argument (new CCodeIdentifier ("G_TYPE_INVALID"));
+
+                               var ccomma = new CCodeCommaExpression ();
+                               ccomma.append_expression (ccall);
+                               ccomma.append_expression (new CCodeIdentifier (temp_decl.name));
+                               expr.ccodenode = ccomma;
+                       }
                }
        }
+
+       private CCodeExpression! get_dbus_array_type (Array! array) {
+               var carray_type = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_type_get_collection"));
+               carray_type.add_argument (new CCodeConstant ("\"GArray\""));
+               carray_type.add_argument (new CCodeIdentifier (array.element_type.get_type_id ()));
+               return carray_type;
+       }
 }
 
index 6c28945..55e1db3 100644 (file)
@@ -454,7 +454,7 @@ public class Vala.CodeGenerator {
        private CCodeStatement create_type_check_statement (CodeNode! method_node, DataType ret_type, DataType! t, bool non_null, string! var_name) {
                var ccheck = new CCodeFunctionCall ();
                
-               if (t is Class || t is Interface) {
+               if (t is Class || (t is Interface && !((Interface) t).declaration_only)) {
                        var ctype_check = new CCodeFunctionCall (new CCodeIdentifier (t.get_upper_case_cname ("IS_")));
                        ctype_check.add_argument (new CCodeIdentifier (var_name));
                        
diff --git a/gobject/valadbusbindingprovider.vala b/gobject/valadbusbindingprovider.vala
new file mode 100644 (file)
index 0000000..c307af3
--- /dev/null
@@ -0,0 +1,116 @@
+/* valadbusbindingprovider.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * 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 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:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * Dynamic binding provider for DBus objects.
+ */
+public class Vala.DBusBindingProvider : BindingProvider {
+       public CodeContext context {
+               set {
+                       _context = value;
+
+                       string_type = (DataType) _context.root.scope.lookup ("string");
+
+                       var dbus_ns = _context.root.scope.lookup ("DBus");
+                       if (dbus_ns != null) {
+                               connection_type = (DataType) dbus_ns.scope.lookup ("Connection");
+                               dbus_error_type = (DataType) dbus_ns.scope.lookup ("Error");
+                       }
+               }
+       }
+
+       private CodeContext _context;
+       private DataType string_type;
+       private DataType connection_type;
+       private DataType dbus_error_type;
+
+       private Collection<Symbol> symbols = new ArrayList<Symbol> ();
+
+       public DBusBindingProvider () {
+       }
+
+       public Symbol get_binding (MemberAccess! ma) {
+               if (connection_type != null && ma.inner != null && ma.inner.static_type.data_type == connection_type) {
+                       var type_args = ma.get_type_arguments ();
+                       if (type_args.size != 1) {
+                               return null;
+                       }
+                       Iterator<TypeReference> type_args_it = type_args.iterator ();
+                       type_args_it.next ();
+                       var ret_type = new TypeReference ();
+                       ret_type.data_type = type_args_it.get ().data_type;
+                       if (!is_dbus_interface (ret_type.data_type)) {
+                               return null;
+                       }
+                       var m = new Method ("get_object", ret_type, ma.source_reference);
+                       m.set_cname ("dbus_g_proxy_new_for_name");
+                       m.add_cheader_filename ("dbus/dbus-glib.h");
+                       m.access = MemberAccessibility.PUBLIC;
+                       var string_type_ref = new TypeReference ();
+                       string_type_ref.data_type = string_type;
+                       m.add_parameter (new FormalParameter ("name", string_type_ref));
+                       m.add_parameter (new FormalParameter ("path", string_type_ref));
+                       symbols.add (m);
+                       return m;
+               } else if (ma.inner != null && is_dbus_interface (ma.inner.static_type.data_type)) {
+                       if (ma.parent_node is InvocationExpression) {
+                               var expr = (InvocationExpression) ma.parent_node;
+                               var ret_type = new TypeReference ();
+                               if (expr.expected_type != null) {
+                                       ret_type.data_type = expr.expected_type.data_type;
+                                       ret_type.transfers_ownership = ret_type.data_type.is_reference_type ();
+                               }
+                               var m = new DBusMethod (ma.member_name, ret_type, ma.source_reference);
+                               if (expr.expected_type != null) {
+                                       var error_type = new TypeReference ();
+                                       error_type.data_type = dbus_error_type;
+                                       m.add_error_domain (error_type);
+                               }
+                               m.access = MemberAccessibility.PUBLIC;
+                               m.add_parameter (new FormalParameter.with_ellipsis ());
+                               symbols.add (m);
+                               return m;
+                       } else if (ma.parent_node is Assignment) {
+                               var a = (Assignment) ma.parent_node;
+                               if (a.left != ma) {
+                                       return null;
+                               }
+                               var s = new DBusSignal (ma.member_name, new TypeReference (), ma.source_reference);
+                               s.access = MemberAccessibility.PUBLIC;
+                               symbols.add (s);
+                               return s;
+                       }
+               }
+               return null;
+       }
+
+       private bool is_dbus_interface (DataType! t) {
+               if (!(t is Interface)) {
+                       return false;
+               }
+               return (t.get_attribute ("DBusInterface") != null);
+       }
+}
+
diff --git a/gobject/valadbusmethod.vala b/gobject/valadbusmethod.vala
new file mode 100644 (file)
index 0000000..702f65a
--- /dev/null
@@ -0,0 +1,40 @@
+/* valadbusmethod.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * 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 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:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+using Gee;
+
+/**
+ * Represents a dynamic bound DBus method.
+ */
+public class Vala.DBusMethod : Method {
+       public DBusMethod (construct string name, construct TypeReference return_type, construct SourceReference source_reference = null) {
+       }
+
+       public override Collection<string> get_cheader_filenames () {
+               return new ReadOnlyCollection<string> ();
+       }
+
+       public override string! get_default_cname () {
+               return "dbus_g_proxy_begin_call";
+       }
+}
diff --git a/gobject/valadbussignal.vala b/gobject/valadbussignal.vala
new file mode 100644 (file)
index 0000000..9ed10da
--- /dev/null
@@ -0,0 +1,31 @@
+/* valadbussignal.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * 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 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:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents a dynamic bound DBus signal.
+ */
+public class Vala.DBusSignal : Signal {
+       public DBusSignal (construct string name, construct TypeReference return_type, construct SourceReference source_reference = null) {
+       }
+}
index efa4784..211acec 100644 (file)
@@ -49,6 +49,9 @@ libvalacore_la_SOURCES = \
        valabinaryexpression.c \
        valabinaryexpression.h \
        valabinaryexpression.vala \
+       valabindingprovider.c \
+       valabindingprovider.h \
+       valabindingprovider.vala \
        valablock.c \
        valablock.h \
        valablock.vala \
@@ -333,6 +336,7 @@ valainclude_HEADERS = \
        valaattributeprocessor.h \
        valabaseaccess.h \
        valabinaryexpression.h \
+       valabindingprovider.h \
        valablock.h \
        valabooleanliteral.h \
        valabreakstatement.h \
index 362fb43..9160815 100644 (file)
@@ -3074,6 +3074,11 @@ interface_declaration
 
 interface_body
        : OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE
+       | SEMICOLON
+         {
+               vala_symbol_set_is_imported (symbol_stack->data, TRUE);
+               vala_interface_set_declaration_only (VALA_INTERFACE (symbol_stack->data), TRUE);
+         }
        ;
 
 opt_interface_member_declarations
index d72ce9c..5ef035c 100644 (file)
@@ -143,6 +143,14 @@ public class Vala.Array : DataType {
                return "g_value_set_pointer";
        }
 
+       public override string get_type_id () {
+               if (element_type == source_reference.file.context.root.scope.lookup ("string")) {
+                       return "G_TYPE_STRV";
+               } else {
+                       return null;
+               }
+       }
+
        public ArrayLengthField get_length_field () {
                if (length_field == null) {
                        length_field = new ArrayLengthField (source_reference);
diff --git a/vala/valabindingprovider.vala b/vala/valabindingprovider.vala
new file mode 100644 (file)
index 0000000..ec1a802
--- /dev/null
@@ -0,0 +1,37 @@
+/* valabindingprovider.vala
+ *
+ * Copyright (C) 2007  Jürg Billeter
+ *
+ * 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 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:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Interface for dynamic binding providers.
+ */
+public interface Vala.BindingProvider {
+       /**
+        * Return custom binding for the specified member access expression.
+        *
+        * @param ma member access expression
+        * @return   resolved symbol or null if no binding can be provided
+        */
+       public abstract Symbol get_binding (MemberAccess! ma);
+}
+
index 17f3c29..5c5baef 100644 (file)
@@ -372,6 +372,9 @@ public class Vala.Class : DataType {
                if (a.has_argument ("cname")) {
                        set_cname (a.get_string ("cname"));
                }
+               if (a.has_argument ("lower_case_csuffix")) {
+                       lower_case_csuffix = a.get_string ("lower_case_csuffix");
+               }
                if (a.has_argument ("cheader_filename")) {
                        var val = a.get_string ("cheader_filename");
                        foreach (string filename in val.split (",")) {
index 684855f..0e54a31 100644 (file)
@@ -133,7 +133,7 @@ public class Vala.Enum : DataType {
        }
 
        public override string get_upper_case_cname (string infix) {
-               return "%s%s".printf (parent_symbol.get_lower_case_cprefix (), camel_case_to_lower_case (name)).up ();
+               return get_lower_case_cname (null).up ();
        }
 
        public override bool is_reference_type () {
@@ -174,6 +174,9 @@ public class Vala.Enum : DataType {
                if (a.has_argument ("cprefix")) {
                        set_cprefix (a.get_string ("cprefix"));
                }
+               if (a.has_argument ("lower_case_csuffix")) {
+                       lower_case_csuffix = a.get_string ("lower_case_csuffix");
+               }
                if (a.has_argument ("cheader_filename")) {
                        var val = a.get_string ("cheader_filename");
                        foreach (string filename in val.split (",")) {
index 1fa120d..ce2b8d5 100644 (file)
@@ -33,6 +33,8 @@ public class Vala.Interface : DataType {
         */
        public bool is_static { get; set; }
 
+       public bool declaration_only { get; set; }
+
        private Gee.List<TypeParameter> type_parameters = new ArrayList<TypeParameter> ();
        
        private Gee.List<TypeReference> prerequisites = new ArrayList<TypeReference> ();
@@ -310,7 +312,13 @@ public class Vala.Interface : DataType {
                        }
                }
        }
-       
+
+       private void process_dbus_interface_attribute (Attribute! a) {
+               if (declaration_only) {
+                       cname = "DBusGProxy";
+               }
+       }
+
        /**
         * Process all associated attributes.
         */
@@ -318,6 +326,8 @@ public class Vala.Interface : DataType {
                foreach (Attribute a in attributes) {
                        if (a.name == "CCode") {
                                process_ccode_attribute (a);
+                       } else if (a.name == "DBusInterface") {
+                               process_dbus_interface_attribute (a);
                        }
                }
        }
index f62244e..7cf7e9f 100644 (file)
@@ -123,6 +123,8 @@ public class Vala.MemoryManager : CodeVisitor {
        }
 
        public override void visit_variable_declarator (VariableDeclarator! decl) {
+               decl.accept_children (this);
+
                if (decl.initializer != null) {
                        if (decl.type_reference.takes_ownership) {
                                visit_possibly_missing_copy_expression (decl.initializer);
index 72bc1e7..8cde40d 100644 (file)
@@ -126,13 +126,7 @@ public class Vala.Method : Member, Invokable {
                        }
                }
        }
-       
-       /**
-        * Specifies whether this is an imported method i.e. the Import
-        * attribute ist set for this method.
-        */
-       public bool is_imported { get; set; }
-       
+
        /**
         * Specifies whether this method expects printf-style format arguments.
         */
index 93f2cfd..4fabb1b 100644 (file)
@@ -62,10 +62,16 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
        private int next_lambda_id = 0;
 
+       private Collection<BindingProvider> binding_providers = new ArrayList<BindingProvider> ();
+
        public SemanticAnalyzer (bool manage_memory = true) {
                memory_management = manage_memory;
        }
 
+       public void add_binding_provider (BindingProvider! binding_provider) {
+               binding_providers.add (binding_provider);
+       }
+
        /**
         * Analyze and check code in the specified context.
         *
@@ -661,6 +667,12 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        }
 
        public override void visit_variable_declarator (VariableDeclarator! decl) {
+               if (decl.initializer != null) {
+                       decl.initializer.expected_type = decl.type_reference;
+               }
+
+               decl.accept_children (this);
+
                if (decl.type_reference == null) {
                        /* var type */
 
@@ -1185,9 +1197,19 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                }
 
                if (expr.symbol_reference == null) {
-                       expr.error = true;
-                       Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_symbol.get_full_name ()));
-                       return;
+                       /* allow plug-ins to provide custom member bindings */
+                       foreach (BindingProvider binding_provider in binding_providers) {
+                               expr.symbol_reference = binding_provider.get_binding (expr);
+                               if (expr.symbol_reference != null) {
+                                       break;
+                               }
+                       }
+
+                       if (expr.symbol_reference == null) {
+                               expr.error = true;
+                               Report.error (expr.source_reference, "The name `%s' does not exist in the context of `%s'".printf (expr.member_name, base_symbol.get_full_name ()));
+                               return;
+                       }
                }
 
                var member = expr.symbol_reference;
@@ -2350,6 +2372,8 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
 
                                a.right.expected_type = new TypeReference ();
                                a.right.expected_type.data_type = sig.get_callback ();
+                       } else {
+                               a.right.expected_type = ma.static_type;
                        }
                } else if (a.left is ElementAccess) {
                        // do nothing
index 83d76e6..1127a6a 100644 (file)
@@ -71,6 +71,12 @@ public abstract class Vala.Symbol : CodeNode {
        public Scope scope {
                get { return _scope; }
        }
+       
+       /**
+        * Specifies whether this is an imported symbol e.g. the Import
+        * attribute has been set.
+        */
+       public bool is_imported { get; set; }
 
        private weak Scope _owner;
        private Scope _scope;
index e5921de..e16c2d4 100644 (file)
@@ -286,6 +286,10 @@ public class Vala.SymbolResolver : CodeVisitor {
                }
        }
 
+       public override void visit_variable_declarator (VariableDeclarator! decl) {
+               decl.accept_children (this);
+       }
+
        public override void visit_throw_statement (ThrowStatement! stmt) {
                stmt.accept_children (this);
        }
index 1e28e22..c32f3b5 100644 (file)
@@ -61,6 +61,10 @@ public class Vala.VariableDeclarator : Symbol, Invokable {
        }
        
        public override void accept (CodeVisitor! visitor) {
+               visitor.visit_variable_declarator (this);
+       }
+
+       public override void accept_children (CodeVisitor! visitor) {
                if (initializer != null) {
                        initializer.accept (visitor);
                
@@ -70,8 +74,6 @@ public class Vala.VariableDeclarator : Symbol, Invokable {
                if (type_reference != null) {
                        type_reference.accept (visitor);
                }
-       
-               visitor.visit_variable_declarator (this);
        }
 
        public Collection<FormalParameter> get_parameters () {
index 8aa3a03..364882b 100644 (file)
@@ -20,7 +20,7 @@
  *     Jürg Billeter <j@bitron.ch>
  */
 
-[CCode (cheader_filename = "dbus/dbus-glib-lowlevel.h")]
+[CCode (cheader_filename = "dbus/dbus-glib-lowlevel.h,dbus/dbus-glib.h")]
 namespace DBus {
        [CCode (cprefix = "DBUS_BUS_")]
        public enum BusType {
@@ -29,17 +29,20 @@ namespace DBus {
                STARTER
        }
 
-       public struct Bus {
-               public static Connection get (BusType type, ref Error error);
+       public struct RawBus {
+               [CCode (cname = "dbus_bus_get")]
+               public static RawConnection get (BusType type, ref Error error);
        }
 
        [ReferenceType (dup_function = "dbus_connection_ref", free_function = "dbus_connection_unref")]
-       public struct Connection {
+       [CCode (cname = "DBusConnection")]
+       public struct RawConnection {
                [CCode (cname = "dbus_connection_setup_with_g_main")]
-               public void setup_with_main (GLib.MainContext context);
+               public void setup_with_main (GLib.MainContext context = null);
        }
 
-       public struct Error {
+       [CCode (cname = "DBusError")]
+       public struct RawError {
                public string name;
                public string message;
 
@@ -50,4 +53,69 @@ namespace DBus {
                [InstanceByReference]
                public bool is_set ();
        }
+
+       [ErrorDomain]
+       [CCode (cname = "DBusGError", lower_case_csuffix = "gerror", cprefix = "DBUS_GERROR_")]
+       public enum Error {
+               FAILED,
+               NO_MEMORY,
+               SERVICE_UNKNOWN,
+               NAME_HAS_NO_OWNER,
+               NO_REPLY,
+               IO_ERROR,
+               BAD_ADDRESS,
+               NOT_SUPPORTED,
+               LIMITS_EXCEEDED,
+               ACCESS_DENIED,
+               AUTH_FAILED,
+               NO_SERVER,
+               TIMEOUT,
+               NO_NETWORK,
+               ADDRESS_IN_USE,
+               DISCONNECTED,
+               INVALID_ARGS,
+               FILE_NOT_FOUND,
+               FILE_EXISTS,
+               UNKNOWN_METHOD,
+               TIMED_OUT,
+               MATCH_RULE_NOT_FOUND,
+               MATCH_RULE_INVALID,
+               SPAWN_EXEC_FAILED,
+               SPAWN_FORK_FAILED,
+               SPAWN_CHILD_EXITED,
+               SPAWN_CHILD_SIGNALED,
+               SPAWN_FAILED,
+               UNIX_PROCESS_ID_UNKNOWN,
+               INVALID_SIGNATURE,
+               INVALID_FILE_CONTENT,
+               SELINUX_SECURITY_CONTEXT_UNKNOWN,
+               REMOTE_EXCEPTION
+       }
+
+       public struct Bus {
+               [CCode (cname = "dbus_g_bus_get")]
+               public static Connection get (BusType type) throws Error;
+               
+       }
+
+       [ReferenceType (dup_function = "dbus_g_connection_ref", free_function = "dbus_g_connection_unref")]
+       [CCode (cname = "DBusGConnection")]
+       public struct Connection {
+       }
+
+       [CCode (cname = "DBusGProxy", lower_case_csuffix = "g_proxy")]
+       public class Proxy {
+               public Proxy.for_name (Connection! connection, string! name, string! path, string! interface_);
+               public bool call (string! method, out GLib.Error error, GLib.Type first_arg_type, ...);
+               public weak ProxyCall begin_call (string! method, ProxyCallNotify notify, pointer data, GLib.DestroyNotify destroy, GLib.Type first_arg_type, ...);
+               public bool end_call (ProxyCall call, out GLib.Error error, GLib.Type first_arg_type, ...);
+               public void cancel_call (ProxyCall call);
+       }
+
+       [CCode (cname = "DBusGProxyCallNotify")]
+       public static delegate void ProxyCallNotify (Proxy proxy, ProxyCall call_id, pointer user_data);
+
+       [ReferenceType]
+       public struct ProxyCall {
+       }
 }
index fc40782..593636a 100644 (file)
@@ -29,23 +29,23 @@ namespace Hal {
        [CCode (cprefix = "libhal_ctx_")]
        public struct Context {
                public Context ();
-               public bool init (ref DBus.Error error);
-               public bool set_dbus_connection (DBus.Connection conn);
+               public bool init (ref DBus.RawError error);
+               public bool set_dbus_connection (DBus.RawConnection conn);
                public bool set_user_data (pointer user_data);
                public pointer get_user_data ();
                public bool set_device_added (DeviceAdded _callback);
                public bool set_device_removed (DeviceRemoved _callback);
                [NoArrayLength]
                [CCode (cname = "libhal_find_device_by_capability")]
-               public string[] find_device_by_capability (string capability, ref int num_devices, ref DBus.Error error);
+               public string[] find_device_by_capability (string capability, ref int num_devices, ref DBus.RawError error);
 
                [CCode (cname = "libhal_device_get_property_string")]
-               public string device_get_property_string (string udi, string key, ref DBus.Error error);
+               public string device_get_property_string (string udi, string key, ref DBus.RawError error);
                [CCode (cname = "libhal_device_get_property_int")]
-               public int device_get_property_int (string udi, string key, ref DBus.Error error);
+               public int device_get_property_int (string udi, string key, ref DBus.RawError error);
                [CCode (cname = "libhal_device_get_property_uint64")]
-               public uint64 device_get_property_uint64 (string udi, string key, ref DBus.Error error);
+               public uint64 device_get_property_uint64 (string udi, string key, ref DBus.RawError error);
                [CCode (cname = "libhal_device_query_capability")]
-               public bool device_query_capability (string udi, string capability, ref DBus.Error error);
+               public bool device_query_capability (string udi, string capability, ref DBus.RawError error);
        }
 }