diff options
author | Seth Nickell <seth@gnome.org> | 2003-09-25 06:57:01 +0000 |
---|---|---|
committer | Seth Nickell <seth@gnome.org> | 2003-09-25 06:57:01 +0000 |
commit | 6f5fc71b10ab910612b7af767308f52bb8266b1e (patch) | |
tree | f43de9016ccfb2b69a021797260a8bc807d96eec | |
parent | 31881de7dafad50446d2b0c8c0c96aa87a70ba61 (diff) |
2003-09-24 Seth Nickell <seth@gnome.org>
* python/dbus.py:
Connect Object methods (when you are sharing an object) up... pass
in a list of methods to be shared. Sharing all the methods just
worked out too weird. You can now create nice Services over the
DBus in Python. :-)
* python/dbus_bindings.pyx.in:
Keep references to user_data tuples passed into C functions so
Python doesn't garbage collect on us.
Implement MethodReturn and Error subclasses of Message for creating
DBusMessage's of those types.
* python/examples/example-client.py:
* python/examples/example-service.py:
Simple example code showing both how create DBus services and objects,
and how to use them.
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | python/dbus.py | 25 | ||||
-rw-r--r-- | python/dbus_bindings.pyx.in | 40 | ||||
-rw-r--r-- | python/examples/example-client.py | 9 | ||||
-rw-r--r-- | python/examples/example-service.py | 16 |
5 files changed, 97 insertions, 16 deletions
@@ -1,3 +1,26 @@ +2003-09-24 Seth Nickell <seth@gnome.org> + + * python/dbus.py: + + Connect Object methods (when you are sharing an object) up... pass + in a list of methods to be shared. Sharing all the methods just + worked out too weird. You can now create nice Services over the + DBus in Python. :-) + + * python/dbus_bindings.pyx.in: + + Keep references to user_data tuples passed into C functions so + Python doesn't garbage collect on us. + + Implement MethodReturn and Error subclasses of Message for creating + DBusMessage's of those types. + + * python/examples/example-client.py: + * python/examples/example-service.py: + + Simple example code showing both how create DBus services and objects, + and how to use them. + 2003-09-23 Havoc Pennington <hp@pobox.com> * glib/dbus-gproxy.c (dbus_gproxy_manager_filter): implement diff --git a/python/dbus.py b/python/dbus.py index a7cca56a..55e5944a 100644 --- a/python/dbus.py +++ b/python/dbus.py @@ -159,18 +159,35 @@ class Object: def __init__(self, object_path, methods_to_share, service): self._object_path = object_path self._service = service - self._object_methods = methods_to_share self._bus = service.get_bus() self._connection = self._bus.get_connection() + + self._method_name_to_method = self._build_method_dictionary(methods_to_share) self._connection.register_object_path(object_path, self._unregister_cb, self._message_cb) def _unregister_cb(self, connection): print ("Unregister") - def message_cb(self, connection, message): - print ("Message %s received" % (message)) - print ("MethodCall %s" % (message.get_member())) + def _message_cb(self, connection, message): + target_method_name = message.get_member() + target_method = self._method_name_to_method[target_method_name] + args = message.get_args_list() + + retval = target_method(*args) + + reply = dbus_bindings.MethodReturn(message) + if retval != None: + reply.append(retval) + self._connection.send(reply) + + def _build_method_dictionary(self, methods): + dictionary = {} + for method in methods: + if dictionionary.has_key(method.__name__): + print ('WARNING: registering DBus Object methods, already have a method named %s' % (method.__name__) + dictionary[method.__name__] = method + return dictionary class RemoteService: """A remote service providing objects. diff --git a/python/dbus_bindings.pyx.in b/python/dbus_bindings.pyx.in index 2e575edc..085a73fa 100644 --- a/python/dbus_bindings.pyx.in +++ b/python/dbus_bindings.pyx.in @@ -53,6 +53,8 @@ ctypedef struct DBusObjectPathVTable: void (* dbus_internal_pad4) (void *) +_user_data_references = [ ] + class DBusException(Exception): pass @@ -72,6 +74,7 @@ cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection, void *user_data): print ("cmessage_function_handler() called") tup = <object>user_data + print (type(tup)) print (tup) function = tup[1] message = Message(_create=0) @@ -102,7 +105,7 @@ cdef class Connection: # FIXME: this is a major major hack. We use this because casting values to # python objects and returning seemed to be corrupting them. This is a "global variable" :-( cdef char **_parsed_path - + def __init__(self, address=None, _conn=None): cdef DBusError error dbus_error_init(&error) @@ -301,7 +304,8 @@ cdef class Connection: cvtable.message_function = cmessage_function_handler user_data = [unregister_cb, message_cb] - #Py_XINCREF(user_data) + global _user_data_references + _user_data_references.append(user_data) path_element_list = path[1:].split('/') self._build_parsed_path(path_element_list) @@ -316,9 +320,8 @@ cdef class Connection: cvtable.message_function = cmessage_function_handler user_data = [unregister_cb, message_cb] - Py_XINCREF(user_data) - - print ("Ref inced") + global _user_data_references + _user_data_references.append(user_data) path_element_list = path[1:].split('/') self._build_parsed_path(path_element_list) @@ -586,8 +589,11 @@ cdef class MessageIter: cdef class Message: cdef DBusMessage *msg - def __init__(self, message_type=MESSAGE_TYPE_INVALID, service=None, path=None, interface=None, - method=None, name=None, reply_to=None, error_name=None, error_message=None, + def __init__(self, message_type=MESSAGE_TYPE_INVALID, + service=None, path=None, interface=None, method=None, + method_call=None, + name=None, + reply_to=None, error_name=None, error_message=None, _create=1): cdef char *cservice if (service == None): @@ -596,18 +602,20 @@ cdef class Message: cservice = service if not _create: - return 0 + return if message_type == MESSAGE_TYPE_METHOD_CALL: self.msg = dbus_message_new_method_call(cservice, path, interface, method) elif message_type == MESSAGE_TYPE_METHOD_RETURN: - msg = method_call._get_msg() - self.msg = dbus_message_new_method_return(<DBusMessage*>msg) + print ("Doing this") + cmsg = method_call._get_msg() + self.msg = dbus_message_new_method_return(<DBusMessage*>cmsg) + print ("Done") elif message_type == MESSAGE_TYPE_SIGNAL: self.msg = dbus_message_new_signal(path, interface, name) elif message_type == MESSAGE_TYPE_ERROR: - msg = reply_to._get_msg() - self.msg = dbus_message_new_error(<DBusMessage*>msg, error_name, error_message) + cmsg = reply_to._get_msg() + self.msg = dbus_message_new_error(<DBusMessage*>cmsg, error_name, error_message) def type_to_name(self, type): if type == MESSAGE_TYPE_SIGNAL: @@ -797,6 +805,14 @@ class MethodCall(Message): def __init__(self, mpath, minterface, mmethod): Message.__init__(self, MESSAGE_TYPE_METHOD_CALL, path=mpath, interface=minterface, method=mmethod) +class MethodReturn(Message): + def __init__(self, method_call): + Message.__init__(self, MESSAGE_TYPE_METHOD_RETURN, method_call=method_call) + +class Error(Message): + def __init__(self, reply_to, error_name, error_message): + Message.__init__(self, MESSAGE_TYPE_ERROR, reply_to=reply_to, error_name=error_name, error_message=error_message) + cdef class Server: cdef DBusServer *server def __init__(self, address): diff --git a/python/examples/example-client.py b/python/examples/example-client.py new file mode 100644 index 00000000..24906b83 --- /dev/null +++ b/python/examples/example-client.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python + +import dbus + +bus = dbus.Bus() +remote_service = bus.get_service("org.designfu.SampleService") +remote_object = remote_service.get_object("/MyObject", "org.designfu.SampleInterface") + +remote_object.HelloWorld("Hello from example-client.py!") diff --git a/python/examples/example-service.py b/python/examples/example-service.py new file mode 100644 index 00000000..eb55af44 --- /dev/null +++ b/python/examples/example-service.py @@ -0,0 +1,16 @@ +import dbus + +import pygtk +import gtk + +class MyObject(dbus.Object): + def __init__(self): + service = dbus.Service("org.designfu.SampleService") + dbus.Object("/MyObject", [self.HelloWorld], service) + + def HelloWorld(self, arg1): + print ("Hello World!: %s" % (arg1)) + +object = MyObject() + +gtk.main() |