diff options
| -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()  | 
