summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Nickell <seth@gnome.org>2003-09-26 10:27:59 +0000
committerSeth Nickell <seth@gnome.org>2003-09-26 10:27:59 +0000
commitc5cf3857b114d0008a6d8191abf389064b5a66fc (patch)
treee89751f02010ba858424769d2cb9f501ea51099c
parent9f2ff915a181585ddeaca079a7cfe057d10a3aed (diff)
2003-09-26 Seth Nickell <seth@gnome.org>
* python/dbus.py: * python/examples/example-signals.py: Start implementing some notions of signals. The API is really terrible, but they sort of work (with the exception of being able to filter by service, and to transmit signals *as* a particular service). Need to figure out how to make messages come from the service we registered :-( * python/dbus_bindings.pyx.in: Removed duplicate message_handler callbacks.
-rw-r--r--ChangeLog16
-rw-r--r--python/dbus.py55
-rw-r--r--python/dbus_bindings.pyx.in50
-rw-r--r--python/examples/example-signals.py27
4 files changed, 124 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 91c7c195..4f68da09 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2003-09-26 Seth Nickell <seth@gnome.org>
+
+ * python/dbus.py:
+ * python/examples/example-signals.py:
+
+ Start implementing some notions of signals. The API
+ is really terrible, but they sort of work (with the
+ exception of being able to filter by service, and to
+ transmit signals *as* a particular service). Need to
+ figure out how to make messages come from the service
+ we registered :-(
+
+ * python/dbus_bindings.pyx.in:
+
+ Removed duplicate message_handler callbacks.
+
2003-09-25 Havoc Pennington <hp@redhat.com>
* bus/session.conf.in: fix my mess
diff --git a/python/dbus.py b/python/dbus.py
index d09b3fec..c7ab5dd3 100644
--- a/python/dbus.py
+++ b/python/dbus.py
@@ -56,6 +56,8 @@ class Bus:
def __init__(self, bus_type=TYPE_SESSION, glib_mainloop=True):
self._connection = dbus_bindings.bus_get(bus_type)
+ self._connection.add_filter(self._signal_func)
+ self._match_rule_to_receivers = { }
if (glib_mainloop):
self._connection.setup_with_g_main()
@@ -65,10 +67,46 @@ class Bus:
"""
return RemoteService(self._connection, service_name)
+ def add_signal_receiver(self, receiver, interface=None, service=None, path=None):
+ match_rule = self._get_match_rule(interface, service, path)
+
+ if (not self._match_rule_to_receivers.has_key(match_rule)):
+ self._match_rule_to_receivers[match_rule] = [ ]
+ self._match_rule_to_receivers[match_rule].append(receiver)
+
+ dbus_bindings.bus_add_match(self._connection, match_rule)
+
def get_connection(self):
"""Get the dbus_bindings.Connection object associated with this Bus"""
return self._connection
+ def _get_match_rule(self, interface, service, path):
+## if (interface):
+## match_rule = match_rule + ",interface='%s'" % (interface)
+## if (service):
+## match_rule = match_rule + ",service='%s'" % (service)
+## if (path):
+## match_rule = match_rule + ",path='%s'" % (path)
+ # FIXME: use the service here too!!!
+ return "type='signal',interface='%s',path='%s'" % (interface, path)
+
+ def _signal_func(self, connection, message):
+ if (message.get_type() != dbus_bindings.MESSAGE_TYPE_SIGNAL):
+ return
+
+ interface = message.get_interface()
+ service = message.get_sender()
+ path = message.get_path()
+ member = message.get_member()
+
+ match_rule = self._get_match_rule(interface, service, path)
+
+ if (self._match_rule_to_receivers.has_key(match_rule)):
+ receivers = self._match_rule_to_receivers[match_rule]
+ args = [interface, member, service, path]
+ for receiver in receivers:
+ receiver(*args)
+
class RemoteObject:
"""A remote Object.
@@ -144,6 +182,10 @@ class Service:
"""Get the Bus this Service is on"""
return self._bus
+ def get_service_name(self):
+ """Get the name of this service"""
+ return self._service_name
+
class Object:
"""A base class for exporting your own Objects across the Bus.
@@ -161,6 +203,12 @@ class Object:
self._connection.register_object_path(object_path, self._unregister_cb, self._message_cb)
+ def broadcast_signal(self, interface, signal_name):
+ message = dbus_bindings.Signal(self._object_path, interface, signal_name)
+ #FIXME: need to set_sender, but it always disconnects when we do this
+ #message.set_sender(self._service.get_service_name())
+ self._connection.send(message)
+
def _unregister_cb(self, connection):
print ("Unregister")
@@ -173,9 +221,10 @@ class Object:
retval = target_method(*args)
except Exception, e:
if e.__module__ == '__main__':
- error_name = e.__class__
+ # FIXME: is it right to use .__name__ here?
+ error_name = e.__class__.__name__
else:
- error_name = e.__module__ + '.' + str(e.__class__)
+ error_name = e.__module__ + '.' + str(e.__class__.__name__)
error_contents = str(e)
reply = dbus_bindings.Error(message, error_name, error_contents)
else:
@@ -193,7 +242,7 @@ class Object:
print ('WARNING: registering DBus Object methods, already have a method named %s' % (method.__name__))
method_dict[method.__name__] = method
return method_dict
-
+
class RemoteService:
"""A remote service providing objects.
diff --git a/python/dbus_bindings.pyx.in b/python/dbus_bindings.pyx.in
index 8feb8678..4ae056c5 100644
--- a/python/dbus_bindings.pyx.in
+++ b/python/dbus_bindings.pyx.in
@@ -65,7 +65,7 @@ cdef void cunregister_function_handler (DBusConnection *connection,
void *user_data):
tup = <object>user_data
assert (type(tup) == list)
- function = tup[0]
+ function = tup[1]
args = [Connection(_conn=<object>connection)]
function(*args)
@@ -74,7 +74,7 @@ cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
void *user_data):
tup = <object>user_data
assert (type(tup) == list)
- function = tup[1]
+ function = tup[0]
message = Message(_create=0)
message._set_msg(<object>msg)
args = [Connection(_conn=<object>connection),
@@ -84,20 +84,6 @@ cdef DBusHandlerResult cmessage_function_handler (DBusConnection *connection,
retval = DBUS_HANDLER_RESULT_HANDLED
return retval
-cdef DBusHandlerResult chandle_message_function_handler (DBusConnection *connection,
- DBusMessage *msg,
- void *user_data):
- function = <object>user_data
- assert (type(function) == function)
- messagein = Message(_create=0)
- messagein._set_msg(<object>msg)
- args = [Connection(_conn=<object>connection),
- messagein]
- retval = function(*args)
- if (retval == None):
- retval = DBUS_HANDLER_RESULT_HANDLED
- return retval
-
cdef class Connection:
cdef DBusConnection *conn
@@ -258,10 +244,14 @@ cdef class Connection:
# FIXME: set_dispatch_status_function, get_unix_user, set_unix_user_function
- def add_filter(self, function):
+ def add_filter(self, filter_function):
+ user_data = [ filter_function ]
+ global _user_data_references
+ _user_data_references.append(user_data)
+
return dbus_connection_add_filter(self.conn,
- chandle_message_function_handler,
- <void*>function,
+ cmessage_function_handler,
+ <void*>user_data,
NULL)
@@ -298,7 +288,7 @@ cdef class Connection:
cvtable.unregister_function = cunregister_function_handler
cvtable.message_function = cmessage_function_handler
- user_data = [unregister_cb, message_cb]
+ user_data = [message_cb, unregister_cb]
global _user_data_references
_user_data_references.append(user_data)
@@ -314,7 +304,7 @@ cdef class Connection:
cvtable.unregister_function = cunregister_function_handler
cvtable.message_function = cmessage_function_handler
- user_data = [unregister_cb, message_cb]
+ user_data = [message_cb, unregister_cb]
global _user_data_references
_user_data_references.append(user_data)
@@ -906,4 +896,22 @@ def bus_service_exists(connection, service_name):
raise DBusException, error.message
return retval
+def bus_add_match(connection, rule):
+ cdef DBusError error
+ dbus_error_init(&error)
+
+ conn = connection._get_conn()
+ dbus_bus_add_match (<DBusConnection*>conn, rule, &error)
+
+ if dbus_error_is_set(&error):
+ raise DBusException, error.message
+
+def bus_remove_match(connection, rule):
+ cdef DBusError error
+ dbus_error_init(&error)
+ conn = connection._get_conn()
+ dbus_bus_remove_match (<DBusConnection*>conn, rule, &error)
+
+ if dbus_error_is_set(&error):
+ raise DBusException, error.message
diff --git a/python/examples/example-signals.py b/python/examples/example-signals.py
new file mode 100644
index 00000000..8e319569
--- /dev/null
+++ b/python/examples/example-signals.py
@@ -0,0 +1,27 @@
+import pygtk
+import gtk
+
+import dbus
+
+class SignalFrom(dbus.Object):
+ def __init__(self, service):
+ dbus.Object.__init__(self, "/", [], service)
+
+def signal_to(interface, signal_name, service, path):
+ print ("Received signal '%s.%s' from '%s%s'" % (interface, signal_name, service, path))
+
+bus = dbus.Bus()
+bus.add_signal_receiver(signal_to,
+ "org.designfu.SignalInterface",
+ "org.designfu.SignalService",
+ "/")
+
+
+service = dbus.Service("org.designfu.SignalService", bus)
+signal_from = SignalFrom(service)
+
+signal_from.broadcast_signal("org.designfu.SignalInterface", "HelloWorld")
+
+gtk.main()
+
+