summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Peng <shawn.p.huang@gmail.com>2008-09-27 15:23:12 +0800
committerHuang Peng <shawn.p.huang@gmail.com>2008-09-27 15:23:12 +0800
commitc9d39cd617e3b766e3d0750a110d3753958a417f (patch)
tree31d078844c023b235c046f302cae917dce6f93c5
parent0b0ded27bda2a2c9ffdff6395018341d193d0f42 (diff)
downloadibus-c9d39cd617e3b766e3d0750a110d3753958a417f.tar.gz
ibus-c9d39cd617e3b766e3d0750a110d3753958a417f.tar.xz
ibus-c9d39cd617e3b766e3d0750a110d3753958a417f.zip
Support MatchRule
-rw-r--r--daemon/_dbus.py96
1 files changed, 87 insertions, 9 deletions
diff --git a/daemon/_dbus.py b/daemon/_dbus.py
index bfbe079..4a1f671 100644
--- a/daemon/_dbus.py
+++ b/daemon/_dbus.py
@@ -23,14 +23,79 @@ import dbus
import dbus.service
import ibus
+class MatchRule:
+ def __init__(self, rule):
+ m = self.__eval_rule(rule)
+ self.__type = m.get('type', None)
+ self.__sender = m.get('sender', None)
+ self.__interface = m.get('interface', None)
+ self.__member = m.get('member', None)
+ self.__path = m.get('path', None)
+ self.__destination = m.get('destination', None)
+ self.__args = []
+ for i in range(64):
+ arg = m.get('arg%d'%i, None)
+ if arg == None:
+ continue
+ self.__args.append((i, arg))
+
+ def __eval_rule(self, rule):
+ _fn = lambda **kargs: kargs
+ try:
+ return eval("_fn(%s)" % rule)
+ except:
+ raise ibus.IBusException("Parse match rule failed")
+
+ def match_message(self, dbusobj, message):
+ if self.__type == 'signale' and message.get_type() != 4:
+ return False
+ if self.__sender:
+ if self.__sender.startswith(":"):
+ sender = self.__sender
+ else:
+ try:
+ sender = dbusobj.get_name_owner(self.__sender).get_unique_name()
+ except:
+ return False
+ if sender != message.get_sender():
+ return False
+ if self.__interface and self.__interface != message.get_interface():
+ return False
+
+ if self.__member and self.__member != message.get_member():
+ return False
+
+ if self.__path and self.__path != message.get_path():
+ return False
+
+ if self.__destination:
+ if self.__destination.startswith(":"):
+ dest = self.__destination
+ else:
+ try:
+ dest = dbusobj.get_name_owner(self.__destination).get_unique_name()
+ except:
+ return False
+ if dest != message.get_destination():
+ return False
+ args = message.get_args_list()
+ for i, arg in self.__args:
+ if i >= len(args):
+ return False
+ if arg != args[i]:
+ return False
+ return True
+
class DBusReal(ibus.Object):
def __init__(self):
super(DBusReal, self).__init__()
+ self.__connections = dict()
self.__unique_name_dict = dict()
self.__name_dict = dict()
self.__id = 0
def add_connection(self, ibusconn):
+ self.__connections[ibusconn] = list()
ibusconn.connect("dbus-message", self.__dbus_message_cb)
ibusconn.connect("destroy", self.__ibusconn_destroy_cb)
@@ -76,10 +141,10 @@ class DBusReal(ibus.Object):
def get_connection_unix_user(self, connection_name):
return 0
- def add_match(self, rule):
- pass
+ def add_match(self, ibusconn, rule):
+ self.__connections[ibusconn].append(MatchRule(rule))
- def remove_match(self, rule):
+ def remove_match(self, ibusconn, rule):
pass
def request_name(self, ibusconn, name, flags):
@@ -104,14 +169,26 @@ class DBusReal(ibus.Object):
ibusconn.remove_name(name)
return 1
+ def dispatch_dbus_signal(self, message):
+ for conn, rules in self.__connections.items():
+ for rule in rules:
+ if rule.match_message(self, message):
+ conn.send_message(message)
+ break
+
def __dbus_message_cb(self, ibusconn, message):
dest = message.get_destination()
message.set_sender(ibusconn.get_unique_name())
- if dest.startswith(":"):
- destconn = self.__unique_name_dict.get(dest, None)
- else:
- destconn = self.__name_dict.get(dest, None)
+ if (not dest):
+ if message.get_type() != 4: # Is not signal
+ raise ibus.IBusException("Message without destination")
+ self.dispatch_dbus_signal(message)
+ return Trye
+
+ if not dest.startswith(":"):
+ raise ibus.IBusException("Destination of message must be an unique name")
+ destconn = self.__unique_name_dict.get(dest, None)
if destconn == None:
raise ibus.IBusException("Can not find the destination(%s)" % dest)
@@ -124,6 +201,7 @@ class DBusReal(ibus.Object):
del self.__unique_name_dict[name]
for name in ibusconn.get_names():
del self.__name_dict[name]
+ del self.__connections[ibusconn]
class DBus(dbus.service.Object):
@@ -177,11 +255,11 @@ class DBus(dbus.service.Object):
@method(in_signature="s")
def AddMatch(self, rule):
- return DBus.__bus.add_match(rule)
+ return DBus.__bus.add_match(self.__ibusconn, rule)
@method(in_signature="s")
def RemoveMatch(self, rule):
- return DBus.__bus.remove_match(rule)
+ return DBus.__bus.remove_match(self.__ibusconn, rule)
@method(out_signature="s")
def GetId(self):