From 2b9417707a6cac377e2caca047fde8169236d93e Mon Sep 17 00:00:00 2001 From: "John (J5) Palmieri" Date: Tue, 18 Oct 2005 04:38:05 +0000 Subject: * glib/dbus-gvalue-utils.c (hash_free_from_gtype): handle gdouble and G_TYPE_VALUE_ARRAY (DBUS_TYPE_STRUCT) (gvalue_from_hash_value, hash_value_from_gvalue): handle gdouble * glib/dbus-gvalue.c (dbus_gvalue_to_signature): add missing DBUS_STRUCT_BEGIN_CHAR and DBUS_STRUCT_END_CHAR charaters when constructing struct signatures * python/_dbus.py (Bus): handle private connections using the private keyword in the constructor. defaults to private=False (Bus::close): new method to close a connection to the bus * python/dbus_bindings.pyx (Connection::close): renamed method was previously called disconnect (bus_get): now supports getting a private connection * python/proxies.py (ProxyMethod::__call__): check if ignore_reply keyword is set to True. if it is, execute the method without waiting for a reply (ProxyObject::_introspect_execute_queue): new method for executing all the pending methods that were waiting for the introspect to finish. this is called when introspect either succeeds or fails (ProxyObject::_introspect_error_handler): call queued methods --- ChangeLog | 26 +++++++++++++++++++++++++ glib/dbus-gvalue-utils.c | 17 +++++++++++++++++ glib/dbus-gvalue.c | 4 +++- python/_dbus.py | 31 ++++++++++++++++-------------- python/dbus_bindings.pyx | 16 ++++++++++------ python/proxies.py | 44 ++++++++++++++++++++++++------------------- test/glib/test-service-glib.c | 4 +++- test/python/run-test.sh | 4 ++++ test/python/test-client.py | 11 +++-------- 9 files changed, 108 insertions(+), 49 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3d6cce4c..9edf717c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2005-10-17 John (J5) Palmieri + + * glib/dbus-gvalue-utils.c (hash_free_from_gtype): handle gdouble + and G_TYPE_VALUE_ARRAY (DBUS_TYPE_STRUCT) + (gvalue_from_hash_value, hash_value_from_gvalue): handle gdouble + + * glib/dbus-gvalue.c (dbus_gvalue_to_signature): add missing + DBUS_STRUCT_BEGIN_CHAR and DBUS_STRUCT_END_CHAR charaters + when constructing struct signatures + + * python/_dbus.py (Bus): handle private connections using the + private keyword in the constructor. defaults to private=False + (Bus::close): new method to close a connection to the bus + + * python/dbus_bindings.pyx (Connection::close): renamed method + was previously called disconnect + (bus_get): now supports getting a private connection + + * python/proxies.py (ProxyMethod::__call__): check if ignore_reply + keyword is set to True. if it is, execute the method without waiting + for a reply + (ProxyObject::_introspect_execute_queue): new method for executing + all the pending methods that were waiting for the introspect to + finish. this is called when introspect either succeeds or fails + (ProxyObject::_introspect_error_handler): call queued methods + 2005-10-14 John (J5) Palmieri * python/dbus_bindings.pyx (MessageIter::append_strict): check for diff --git a/glib/dbus-gvalue-utils.c b/glib/dbus-gvalue-utils.c index c7b0d580..4956f222 100644 --- a/glib/dbus-gvalue-utils.c +++ b/glib/dbus-gvalue-utils.c @@ -299,6 +299,7 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func) case G_TYPE_UINT: *func = NULL; return TRUE; + case G_TYPE_DOUBLE: case G_TYPE_STRING: *func = g_free; return TRUE; @@ -308,6 +309,12 @@ hash_free_from_gtype (GType gtype, GDestroyNotify *func) *func = unset_and_free_g_value; return TRUE; } + else if (gtype == G_TYPE_VALUE_ARRAY) + { + *func = g_value_array_free; + return TRUE; + } + return FALSE; } } @@ -387,6 +394,9 @@ gvalue_from_hash_value (GValue *value, gpointer instance) case G_TYPE_UINT: g_value_set_uint (value, GPOINTER_TO_UINT (instance)); break; + case G_TYPE_DOUBLE: + g_value_set_double (value, *(gdouble *) instance); + break; case G_TYPE_STRING: g_value_set_static_string (value, instance); break; @@ -426,6 +436,13 @@ hash_value_from_gvalue (GValue *value) case G_TYPE_UINT: return GUINT_TO_POINTER (g_value_get_uint (value)); break; + case G_TYPE_DOUBLE: + { + gdouble *p = (gdouble *) g_malloc0 (sizeof (gdouble)); + *p = g_value_get_double (value); + return (gpointer) p; + } + break; case G_TYPE_STRING: return (gpointer) g_value_get_string (value); break; diff --git a/glib/dbus-gvalue.c b/glib/dbus-gvalue.c index 528f5033..2f6371e3 100644 --- a/glib/dbus-gvalue.c +++ b/glib/dbus-gvalue.c @@ -402,7 +402,7 @@ dbus_gvalue_to_signature (const GValue *val) array = g_value_get_boxed (val); - str = g_string_new (""); + str = g_string_new (DBUS_STRUCT_BEGIN_CHAR_AS_STRING); for (i = 0; i < array->n_values; i++) { char *sig; @@ -410,6 +410,8 @@ dbus_gvalue_to_signature (const GValue *val) g_string_append (str, sig); g_free (sig); } + g_string_append (str, DBUS_STRUCT_END_CHAR_AS_STRING); + return g_string_free (str, FALSE); } else diff --git a/python/_dbus.py b/python/_dbus.py index 890cdda8..2e7e671b 100644 --- a/python/_dbus.py +++ b/python/_dbus.py @@ -67,8 +67,8 @@ class Bus: START_REPLY_SUCCESS = dbus_bindings.DBUS_START_REPLY_SUCCESS START_REPLY_ALREADY_RUNNING = dbus_bindings.DBUS_START_REPLY_ALREADY_RUNNING - def __init__(self, bus_type=TYPE_SESSION, use_default_mainloop=True): - self._connection = dbus_bindings.bus_get(bus_type) + def __init__(self, bus_type=TYPE_SESSION, use_default_mainloop=True, private=False): + self._connection = dbus_bindings.bus_get(bus_type, private) self._connection.add_filter(self._signal_func) self._match_rule_tree = SignalMatchTree() @@ -78,25 +78,28 @@ class Bus: if func != None: func(self) + def close(self): + self._connection.close() + def get_connection(self): return self._connection - def get_session(): + def get_session(private=False): """Static method that returns the session bus""" - return SessionBus() + return SessionBus(private) get_session = staticmethod(get_session) - def get_system(): + def get_system(private=False): """Static method that returns the system bus""" - return SystemBus() + return SystemBus(private) get_system = staticmethod(get_system) - def get_starter(): + def get_starter(private=False): """Static method that returns the starter bus""" - return StarterBus() + return StarterBus(private) get_starter = staticmethod(get_starter) @@ -196,21 +199,21 @@ class Bus: class SystemBus(Bus): """The system-wide message bus """ - def __init__(self): - Bus.__init__(self, Bus.TYPE_SYSTEM) + def __init__(self, use_default_mainloop=True, private=False): + Bus.__init__(self, Bus.TYPE_SYSTEM, use_default_mainloop, private) class SessionBus(Bus): """The session (current login) message bus """ - def __init__(self): - Bus.__init__(self, Bus.TYPE_SESSION) + def __init__(self, use_default_mainloop=True, private=False): + Bus.__init__(self, Bus.TYPE_SESSION, use_default_mainloop, private) class StarterBus(Bus): """The bus that activated this process (if this process was launched by DBus activation) """ - def __init__(self): - Bus.__init__(self, Bus.TYPE_STARTER) + def __init__(self, use_default_mainloop=True, private=False): + Bus.__init__(self, Bus.TYPE_STARTER, use_default_mainloop, private) class Interface: """An inteface into a remote object diff --git a/python/dbus_bindings.pyx b/python/dbus_bindings.pyx index 35ad492b..f7c88006 100644 --- a/python/dbus_bindings.pyx +++ b/python/dbus_bindings.pyx @@ -278,8 +278,8 @@ cdef class Connection: def get_unique_name(self): return bus_get_unique_name(self) - def disconnect(self): - dbus_connection_disconnect(self.conn) + def close(self): + dbus_connection_close(self.conn) def get_is_connected(self): return dbus_connection_get_is_connected(self.conn) @@ -1638,14 +1638,18 @@ BUS_SESSION = DBUS_BUS_SESSION BUS_SYSTEM = DBUS_BUS_SYSTEM BUS_STARTER = DBUS_BUS_STARTER -def bus_get (bus_type): +def bus_get (bus_type, private=False): cdef DBusError error cdef Connection conn - dbus_error_init(&error) cdef DBusConnection *connection - connection = dbus_bus_get(bus_type, - &error) + dbus_error_init(&error) + if private: + connection = dbus_bus_get_private(bus_type, + &error) + else: + connection = dbus_bus_get(bus_type, + &error) if dbus_error_is_set(&error): errormsg = error.message diff --git a/python/proxies.py b/python/proxies.py index ee2a3f7e..efa2b501 100644 --- a/python/proxies.py +++ b/python/proxies.py @@ -46,6 +46,10 @@ class ProxyMethod: if keywords.has_key('error_handler'): error_handler = keywords['error_handler'] + ignore_reply = False + if keywords.has_key('ignore_reply'): + ignore_reply = keywords['ignore_reply'] + if not(reply_handler and error_handler): if reply_handler: raise MissingErrorHandlerException() @@ -65,8 +69,11 @@ class ProxyMethod: iter.append_strict(arg, sig) else: iter.append(arg) - - if reply_handler: + + if ignore_reply: + result = self._connection.send(message) + args_tuple = (result,) + elif reply_handler: result = self._connection.send_with_reply_handlers(message, timeout, reply_handler, error_handler) args_tuple = result else: @@ -94,8 +101,6 @@ class ProxyObject: INTROSPECT_STATE_INTROSPECT_IN_PROGRESS = 1 INTROSPECT_STATE_INTROSPECT_DONE = 2 - #TODO: default introspect to False right now because it is not done yet - # make sure to default to True later def __init__(self, bus, named_service, object_path, introspect=True): self._bus = bus self._named_service = named_service @@ -132,20 +137,8 @@ class ProxyObject: self._introspect_reply_handler, self._introspect_error_handler) return result - - - - def _introspect_reply_handler(self, data): - try: - self._introspect_method_map = introspect_parser.process_introspection_data(data) - except IntrospectionParserException, e: - self._introspect_error_handler(e) - return - - self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE - - #TODO: we should actually call these even if introspection fails + def _introspect_execute_queue(self): for call in self._pending_introspect_queue: (member, iface, args, keywords) = call @@ -162,14 +155,27 @@ class ProxyObject: call_object = self.ProxyMethodClass(self._bus.get_connection(), self._named_service, - self._object_path, iface, member, + self._object_path, + iface, + member, introspect_sig) call_object(args, keywords) + def _introspect_reply_handler(self, data): + try: + self._introspect_method_map = introspect_parser.process_introspection_data(data) + except IntrospectionParserException, e: + self._introspect_error_handler(e) + return + + self._introspect_state = self.INTROSPECT_STATE_INTROSPECT_DONE + #self._introspect_execute_queue() + def _introspect_error_handler(self, error): self._introspect_state = self.INTROSPECT_STATE_DONT_INTROSPECT - sys.stderr.write(str(error)) + self._introspect_execute_queue() + sys.stderr.write("Introspect error: " + str(error) + "\n") def __getattr__(self, member, **keywords): if member == '__call__': diff --git a/test/glib/test-service-glib.c b/test/glib/test-service-glib.c index 06cc5957..6d10b937 100644 --- a/test/glib/test-service-glib.c +++ b/test/glib/test-service-glib.c @@ -670,7 +670,9 @@ my_object_get_value (MyObject *obj, guint *ret, GError **error) gboolean my_object_echo_variant (MyObject *obj, GValue *variant, GValue *ret, GError **error) { - g_value_init (ret, G_VALUE_TYPE(variant)); + GType t; + t = G_VALUE_TYPE(variant); + g_value_init (ret, t); g_value_copy (variant, ret); return TRUE; diff --git a/test/python/run-test.sh b/test/python/run-test.sh index aa6bd366..a50a5f48 100755 --- a/test/python/run-test.sh +++ b/test/python/run-test.sh @@ -32,6 +32,10 @@ echo "running test-client.py" #uncomment this if you need to see the output from the service for debugging #otherwise keep it commented so we can test activation #libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/python/test-service.py & +#libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/glib/test-service-glib & +#sleep 1 +#ps +#sleep 9 libtool --mode=execute $DEBUG $DBUS_TOP_BUILDDIR/test/python/test-client.py || die "test-client.py failed" rm $DBUS_TOP_BUILDDIR/python/dbus diff --git a/test/python/test-client.py b/test/python/test-client.py index f90ce13c..57965cc7 100755 --- a/test/python/test-client.py +++ b/test/python/test-client.py @@ -25,9 +25,9 @@ test_types_vals = [1, 12323231, 3.14159265, 99999999.99, "dude", "123", "What is all the fuss about?", "gob@gob.com", [1,2,3], ["how", "are", "you"], [1.23,2.3], [1], ["Hello"], (1,2,3), (1,), (1,"2",3), ("2", "what"), ("you", 1.2), - {1:"a", 2:"b"}, {"a":1, "b":2}, {1:1.1, 2:2.2}, {1.1:"a", 1.2:"b"}, - [[1,2,3],[2,3,4]], [["a","b"],["c","d"]], - ([1,2,3],"c", 1.2, ["a","b","c"], {"a": (1,"v"), "b": (2,"d")}) + {1:"a", 2:"b"}, {"a":1, "b":2}, #{"a":(1,"B")}, + {1:1.1, 2:2.2}, [[1,2,3],[2,3,4]], [["a","b"],["c","d"]], + #([1,2,3],"c", 1.2, ["a","b","c"], {"a": (1,"v"), "b": (2,"d")}) ] class TestDBusBindings(unittest.TestCase): @@ -129,9 +129,6 @@ class TestDBusPythonToGLibBindings(unittest.TestCase): print "Call test passed" self.assert_(True) - #this crashes glib so disable it for now - #until glib is fixed - """ def testPythonTypes(self): print "\n********* Testing Python Types ***********" @@ -139,11 +136,9 @@ class TestDBusPythonToGLibBindings(unittest.TestCase): print "Testing %s"% str(send_val) recv_val = self.iface.EchoVariant(send_val) self.assertEquals(send_val, recv_val) - """ if __name__ == '__main__': gobject.threads_init() dbus.glib.init_threads() unittest.main() - -- cgit