1 #Copyright (C) 2008 Codethink Ltd
3 #This library is free software; you can redistribute it and/or
4 #modify it under the terms of the GNU Lesser General Public
5 #License version 2 as published by the Free Software Foundation.
7 #This program is distributed in the hope that it will be useful,
8 #but WITHOUT ANY WARRANTY; without even the implied warranty of
9 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 #GNU General Public License for more details.
11 #You should have received a copy of the GNU Lesser General Public License
12 #along with this program; if not, write to the Free Software
13 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 from base import AccessibleObjectNoLongerExists
16 from factory import interfaceFactory
18 ATSPI_DEVICE_EVENT_CONTROLLER = 'org.freedesktop.atspi.DeviceEventController'
19 ATSPI_DEVICE_EVENT_LISTENER = 'org.freedesktop.atspi.DeviceEventListener'
20 ATSPI_REGISTRY = 'org.freedesktop.atspi.Registry'
21 ATSPI_TREE = 'org.freedesktop.atspi.Tree'
23 #------------------------------------------------------------------------------
25 class _CacheData(object):
35 def __init__(self, data):
38 def update(self, data):
39 #Don't cache the path here, used as lookup in cache object dict.
46 self.description) = data
48 #------------------------------------------------------------------------------
50 class ApplicationCache(object):
52 Caches the bus names of all applications.
54 Makes calls and recieves updates from the registry
55 daemon to keep the cache up to date.
58 _UPDATE_SIGNAL = 'updateApplications'
59 _REGISTRY_PATH = '/org/freedesktop/atspi/registry'
61 def __init__(self, connection, busName):
63 Create a cache for application caches.
64 BusName -> ApplicationCache
66 self._connection = connection
67 self._busName = busName
69 registryObject = connection.get_object(busName, self._REGISTRY_PATH)
70 registryInterface = dbus.Interface(registryObject, ATSPI_REGISTRY)
72 self._applications = {}
74 self._updateApplications(registryInterface.getApplications())
76 #Connect to update signal
77 self._signalMatch = self.registryInterface.connect_to_signal(self._UPDATE_SIGNAL,
80 def _updateApplications(self, names):
82 Updates the application cache from an
83 array of dbus bus names.
86 if name not in self._applications:
87 self._applications[name] = AccessibleCache(self._connection,
91 def _removeApplications(self, names):
93 Removes application caches given by names.
96 del(self._applications[name])
98 def _updateHandler(self, updates):
99 update, remove = updates
100 self._removeApplications(update)
101 self._updateApplications(remove)
103 #------------------------------------------------------------------------------
105 class AccessibleCache(object):
107 Caches data for a collection of accessible object proxies.
109 Makes calls and recieves updates from applications
110 to update the cache of accessible object data.
113 _UPDATE_SIGNAL = 'updateTree'
114 _TREE_PATH = '/org/freedesktop/atspi/tree'
117 def __init__(self, connection, busName):
119 Creates a cache for accessible object data.
121 All accessible object proxies are created and accessed through this cache.
123 connection - DBus connection.
124 busName - DBus bus name where accessible tree resides.
126 self._connection = connection
127 self._busName = busName
129 treeObject = connection.get_object(busName, self._TREE_PATH)
130 treeInterface = dbus.Interface(treeObject, ATSPI_TREE)
134 self._root = treeObject.getRoot()
135 self._updateObjects(treeInterface.getTree())
137 #Connect to update signal
138 self._signalMatch = treeInterface.connect_to_signal(self._UPDATE_SIGNAL,
141 def getRootAccessible(self):
143 Gets the accessible object at the root of the tree.
145 return self.getAccessible(self._root)
147 def getAccessible(self, path):
149 Gets a D-Bus proxy object for the given object path.
150 The object that is returned implements the accessible
153 path - The D-Bus path of the remote object.
155 if path in self._objects:
156 proxy = self._connection.get_object(self._busName, path, introspect=False)
157 return interfaceFactory(proxy, self, self._busName, path, ATSPI_ACCESSIBLE)
159 raise AccessibleObjectNoLongerExists, "D-Bus reference not found in cache"
161 def _updateObjects(self, objects):
163 Updates the object cache from an
164 array of accessible object cache data.
167 #First element is the object path.
169 if path in self._objects:
170 cachedata = self._objects[path]
171 cachedata.update(data)
173 self._objects[path] = _CacheData(data)
175 def _removeObjects(self, paths):
177 Removes the object data from the cache.
180 del(self._objects[path])
182 def _updateHandler(self, updates):
183 update, remove = updates
184 self._removeObjects(update)
185 self._updateObjects(remove)
187 #END---------------------------------------------------------------------------