Commit c5cf3857 authored by Seth Nickell's avatar Seth Nickell
Browse files

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.
parent 9f2ff915
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
......
......@@ -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.
......
......@@ -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
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()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment