[pyatspi2] Add re-entrancy to method calls using a pool of gobject main loops



commit ab605bb1dfa167bad6fd614a35d04c94b8b4cdb3
Author: Mark Doffman <mark doffman codethink co uk>
Date:   Mon Nov 30 06:19:58 2009 -0800

    Add re-entrancy to method calls using a pool of gobject main loops
    and a main-loop idle function to dispatch d-bus signals.

 configure.ac                 |    3 +-
 pyatspi/Makefile.am          |    5 +-
 pyatspi/__init__.py          |    6 ++
 pyatspi/appevent.py          |   84 ++++++++++++++++++++-----------
 pyatspi/busutils/Makefile.am |   12 +++++
 pyatspi/busutils/__init__.py |    2 +
 pyatspi/busutils/bus.py      |   77 ++++++++++++++++++++++++++++
 pyatspi/busutils/proxy.py    |  113 ++++++++++++++++++++++++++++++++++++++++++
 pyatspi/cache.py             |   57 +++++++++++----------
 pyatspi/desktop.py           |    9 ++--
 pyatspi/deviceevent.py       |   15 +++--
 pyatspi/factory.py           |    8 ++--
 pyatspi/loop.py              |   82 ------------------------------
 pyatspi/registry.py          |   48 ++++++------------
 14 files changed, 332 insertions(+), 189 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 5d6313f..6affe38 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,7 +74,7 @@ fi
 
 AC_PATH_XTRA
 
-AC_ARG_ENABLE(relocate, [  --enable-relocate  Relocate to coexist with CORBA [default=no]], enable_relocate="$enableval", enable_relocate=no)
+AC_ARG_ENABLE(relocate, [--enable-relocate  Relocate to coexist with CORBA [default=no]], enable_relocate="$enableval", enable_relocate=no)
 if test x$enable_relocate = xyes ; then
 	AC_DEFINE(RELOCATE, , [Relocate to coexist with CORBA])
 fi
@@ -88,6 +88,7 @@ AC_CONFIG_FILES([Makefile
 		 tests/pyatspi/pasytest/Makefile
 		 tests/apps/Makefile
 		 pyatspi/Makefile
+		 pyatspi/busutils/Makefile
 		 pyatspi/pyatspi-dbus.pth
 		])
 
diff --git a/pyatspi/Makefile.am b/pyatspi/Makefile.am
index 8522259..3f7f142 100644
--- a/pyatspi/Makefile.am
+++ b/pyatspi/Makefile.am
@@ -1,4 +1,4 @@
-
+SUBDIRS=busutils
 if RELOCATE
 pyatspidir = $(pythondir)/pyatspi-dbus/pyatspi
 else
@@ -27,7 +27,6 @@ pyatspi_PYTHON = \
 		image.py		\
 		__init__.py		\
 		interfaces.py		\
-                loop.py                 \
 		registry.py		\
 		relation.py		\
 		role.py			\
@@ -36,7 +35,7 @@ pyatspi_PYTHON = \
 		table.py		\
 		text.py			\
 		utils.py		\
-		value.py
+		value.py		
 
 if RELOCATE
 install-exec-local: Makefile
diff --git a/pyatspi/__init__.py b/pyatspi/__init__.py
index 1abe86a..9b508e3 100644
--- a/pyatspi/__init__.py
+++ b/pyatspi/__init__.py
@@ -17,9 +17,15 @@ __version__ = (1, 9, 0)
 import constants
 from Accessibility import *
 
+from dbus.mainloop.glib import DBusGMainLoop
+DBusGMainLoop (set_as_default=True)
+del DBusGMainLoop
+
 #This is a re-creation of the namespace pollution implemented
 #by PyORBit.
 import sys
 import Accessibility
 sys.modules['Accessibility'] = Accessibility
 del sys
+
+import appevent as event
diff --git a/pyatspi/appevent.py b/pyatspi/appevent.py
index 2493408..de40efe 100644
--- a/pyatspi/appevent.py
+++ b/pyatspi/appevent.py
@@ -17,6 +17,8 @@ import interfaces
 from accessible import BoundingBox
 from exceptions import *
 
+from busutils import AccessibilityBus
+
 __all__ = [
                 "Event",
                 "EventType",
@@ -159,7 +161,7 @@ def event_type_to_signal_reciever(bus, factory, event_handler, event_type):
 
         def handler_wrapper(minor, detail1, detail2, any_data,
                             sender=None, interface=None, member=None, path=None):
-                event = Event(factory, path, sender, interface, member, (minor, detail1, detail2, any_data))
+                event = Event((minor, detail1, detail2, any_data), factory, path, sender, interface, member)
                 return event_handler(event)
 
         return bus.add_signal_receiver(handler_wrapper, **kwargs)
@@ -208,7 +210,12 @@ class Event(object):
         @ivar source: Source of the event
         @type source: Accessibility.Accessible
         """
-        def __init__(self, acc_factory, source_path, source_application, interface, name, event):
+        def __init__(self, event,
+		     acc_factory=None,
+	             source_path=None,
+		     source_application=None,
+		     interface=None,
+		     name=None):
                 """
                 Extracts information from the provided event. If the event is a "normal" 
                 event, pulls the detail1, detail2, any_data, and source values out of the
@@ -221,23 +228,38 @@ class Event(object):
                 @param event: Event from an AT-SPI callback
                 @type event: Accessibility.Event or Accessibility.DeviceEvent
                 """
-                self._acc_factory = acc_factory
-                self._source_path = source_path
-                self._source_application = source_application
 
-                self._source = None
-                self._application = None
+		if acc_factory == None:
+			#This alternative init is provided for compatibility with the old API.
+			#The old API apparently allowed the event to be delivered as a class with
+			#named parameters. (Something like a copy constructor)
+			#Old API used in orca - focus_tracking_presenter.py line 1106
+			self._source = event.source
+			self._application = event.source
+
+			self.type = event.type
+			self.detail1 = event.detail1
+			self.detail2 = event.detail2
+			self.any_data = event.any_data
+		else:
+                	self._acc_factory = acc_factory
+                	self._source_path = source_path
+                	self._source_application = source_application
 
-                self.type = EventType(signal_spec_to_event_string(interface, name, event[0]))
+                	self._source = None
+                	self._application = None
 
-                self.detail1 = event[1]
-                self.detail2 = event[2]
+                	self.type = EventType(signal_spec_to_event_string(interface, name, event[0]))
 
-                data = event[3]
-                if name == "object_bounds_changed":
-                        self.any_data = BoundingBox(*data)
-                else:
-                        self.any_data = data
+                	self.detail1 = event[1]
+                	self.detail2 = event[2]
+
+                	data = event[3]
+
+                	if name == "object_bounds_changed":
+                        	self.any_data = BoundingBox(*data)
+                	else:
+                        	self.any_data = data
 
         @property
         def host_application(self):
@@ -284,8 +306,8 @@ class Event(object):
 
 class _ApplicationEventRegister (object):
 
-        def __init__ (self, bus):
-                self._bus = bus
+        def __init__ (self):
+                self._bus = AccessibilityBus ()
                 self._cache = None
                 self._factory = None
                 self._event_listeners = {}
@@ -313,30 +335,33 @@ class _ApplicationEventRegister (object):
                 self._factory = factory
 
         def notifyNameChange(self, name, path, acc_name):
-                event = Event(self._factory,
+                event = Event(("accessible-name", 0, 0, acc_name),
+			      self._factory,
                               path,
                               name,
                               "org.freedesktop.atspi.Event.Object",
-                              "property-change",
-                              ("accessible-name", 0, 0, acc_name))
+                              "property-change")
+                              
                 self._callClients(self._name_listeners, event)
 
         def notifyDescriptionChange(self, name, path, acc_desc):
-                event = Event(self._factory,
+                event = Event(("accessible-description", 0, 0, acc_desc),
+			      self._factory,
                               path,
                               name,
                               "org.freedesktop.atspi.Event.Object",
-                              "property-change",
-                              ("accessible-description", 0, 0, acc_desc))
+                              "property-change")
+                              
                 self._callClients(self._description_listeners, event)
 
         def notifyParentChange(self, name, path):
-                event = Event(self._factory,
+                event = Event(("accessible-parent", 0, 0, ""),
+			      self._factory,
                               path,
                               name,
                               "org.freedesktop.atspi.Event.Object",
-                              "property-change",
-                              ("accessible-parent", 0, 0, ""))
+                              "property-change")
+                              
                 self._callClients(self._parent_listeners, event)
 
         def notifyChildrenChange(self, name, path, added):
@@ -344,12 +369,13 @@ class _ApplicationEventRegister (object):
                         detail = "add"
                 else:
                         detail = "remove"
-                event = Event(self._factory,
+                event = Event((detail, 0, 0, ""),
+			      self._factory,
                               path,
                               name,
                               "org.freedesktop.atspi.Event.Object",
-                              "children-changed",
-                              (detail, 0, 0, ""))
+                              "children-changed")
+                              
                 self._callClients(self._children_changed_listeners, event)
 
         def _registerFake(self, type, register, client, *names):
diff --git a/pyatspi/busutils/Makefile.am b/pyatspi/busutils/Makefile.am
new file mode 100644
index 0000000..3ab8c3a
--- /dev/null
+++ b/pyatspi/busutils/Makefile.am
@@ -0,0 +1,12 @@
+if RELOCATE
+pyatspidir = $(pythondir)/pyatspi-dbus/pyatspi
+else
+pyatspidir = $(pythondir)/pyatspi
+endif
+
+busutilsdir = $(pyatspidir)/busutils
+
+busutils_PYTHON = \
+		bus.py		\
+		proxy.py	\
+		__init__.py	
diff --git a/pyatspi/busutils/__init__.py b/pyatspi/busutils/__init__.py
new file mode 100644
index 0000000..41655cd
--- /dev/null
+++ b/pyatspi/busutils/__init__.py
@@ -0,0 +1,2 @@
+from bus import *
+from proxy import *
diff --git a/pyatspi/busutils/bus.py b/pyatspi/busutils/bus.py
new file mode 100644
index 0000000..d152ec1
--- /dev/null
+++ b/pyatspi/busutils/bus.py
@@ -0,0 +1,77 @@
+#Copyright (C) 2009 Codethink Ltd
+
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License version 2 as published by the Free Software Foundation.
+
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#GNU General Public License for more details.
+#You should have received a copy of the GNU Lesser General Public License
+#along with this program; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import Queue as _queue
+
+import dbus.bus as _bus
+import dbus.connection as _connection
+
+import gobject
+
+from proxy import AccessibilityProxy
+
+class _AccessibilityBus (_bus.BusConnection):
+	"""
+	The bus used for accessibility
+
+	This bus derives from a normal D-Bus bus but has
+	re-entrant signal dispatching.
+
+	Signal callback methods are wrapped so that they deliver to
+	a re-entrant queue which is dispatched later in the main loop.
+
+	This class exists because D-Bus signal dispatching is not
+	normally re-entrant. The 'dbus_connection_read_write_dispatch'
+	method blocks while a message has been borrowed, which is
+	normal during signal delivery.
+	"""
+
+	def __init__ (self):
+                _bus.BusConnection.__init__(self, _bus.BusConnection.TYPE_SESSION, mainloop=None)
+
+		self._signal_queue = _queue.Queue ()
+
+                gobject.idle_add(self._event_dispatch)
+
+	def _event_dispatch (self):
+		while not self._signal_queue.empty():
+			(func, args, kwargs) = self._signal_queue.get (False)
+			func (*args, **kwargs)
+		return True
+
+	def add_signal_receiver (self, func, *args, **kwargs):
+		
+		def wrapper (*iargs, **ikwargs):
+			self._signal_queue.put ((func, iargs, ikwargs))
+
+		return _bus.BusConnection.add_signal_receiver (self, wrapper, *args, **kwargs)
+
+	def get_object (self, name, path):
+		#return _connection.ProxyObject (self, name, path, introspect=False)
+		return AccessibilityProxy (self, name, path, introspect=False)
+
+
+class AccessibilityBus (_AccessibilityBus):
+	"""
+	Shared instance of the D-Bus bus used for accessibility.
+	"""
+
+	_shared_instance = None
+	
+	def __new__ (cls):
+		if AccessibilityBus._shared_instance:
+			return AccessibilityBus._shared_instance
+		else:
+			AccessibilityBus._shared_instance = _AccessibilityBus.__new__ (cls)
+			return AccessibilityBus._shared_instance
diff --git a/pyatspi/busutils/proxy.py b/pyatspi/busutils/proxy.py
new file mode 100644
index 0000000..0d9fb0a
--- /dev/null
+++ b/pyatspi/busutils/proxy.py
@@ -0,0 +1,113 @@
+#Copyright (C) 2009 Codethink Ltd
+
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU Lesser General Public
+#License version 2 as published by the Free Software Foundation.
+
+#This program is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#GNU General Public License for more details.
+#You should have received a copy of the GNU Lesser General Public License
+#along with this program; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import dbus.connection as _connection
+import gobject
+import gtk
+
+import Queue
+
+class _MainLoopPool (Queue.Queue):
+	_RE_ENTRANCY_LIMIT = 15
+	
+	def __init__ (self):
+		Queue.Queue.__init__(self)
+		for i in range (0, _MainLoopPool._RE_ENTRANCY_LIMIT):
+			self.put(gobject.MainLoop())
+
+class AccessibilityProxy (_connection.ProxyObject):
+	"""
+	Wrapper for the D-Bus Proxy object that makes re-entrant D-Bus calls.
+
+	This class enforces only one level of re-entrancy. This should be all
+	that is required as requests for a11y information about the current
+	process should not make further D-Bus calls.
+	"""
+
+	# We need a pool here as we end up creating so many main loops that we
+	# run out of file descriptors!
+	_main_loop_pool = _MainLoopPool ()
+
+        class DBusMethodCallbackData (object):
+                def __init__ (self):
+			# Will raise the Empty exception if we have hit
+			# The re-entrancy limit
+			self.loop  = AccessibilityProxy._main_loop_pool.get_nowait ()
+                        self.error = None
+                        self.args  = None
+        
+        def get_dbus_method (self, *args, **kwargs):
+                method = _connection.ProxyObject.get_dbus_method (self, *args, **kwargs)
+
+                def dbus_method_func (*iargs, **ikwargs):
+
+			#depth = gobject.main_depth()
+			#print ("\t" * depth) + "---------------"
+			#print ("\t" * depth) + "Pre-recurse"
+			#print ("\t" * depth) + "Args=" + str(args)
+			#print ("\t" * depth) + "Depth=" + str(gobject.main_depth())
+			#print
+
+                        data = AccessibilityProxy.DBusMethodCallbackData()
+
+                        def method_error_callback (e):
+                                data.error = e
+				def main_quit ():
+					data.loop.quit()
+					return False
+				gobject.idle_add (main_quit)
+
+                        def method_reply_callback (*jargs):
+
+				#depth = gobject.main_depth()
+				#print ("\t" * depth) + "Callback"
+				#print ("\t" * depth) + "Args=" + str(args)
+				#print ("\t" * depth) + "Depth=" + str(gobject.main_depth())
+				#print
+
+                                data.args = jargs
+				def main_quit ():
+					data.loop.quit()
+					return False
+				gobject.idle_add (main_quit)
+
+                        method (reply_handler=method_reply_callback,
+                                error_handler=method_error_callback,
+                                *iargs,
+                                **ikwargs)
+
+			data.loop.run ()
+			AccessibilityProxy._main_loop_pool.put_nowait (data.loop)
+
+			#depth = gobject.main_depth()
+			#print ("\t" * depth) + "Post-recurse"
+			#print ("\t" * depth) + "Depth=" + str(gobject.main_depth())
+			#print ("\t" * depth) + "---------------"
+			#print
+
+                        if data.error:
+                                raise data.error
+
+			if data.args == None:
+				raise Exception ("Return arguments not set")
+
+                        if len (data.args) == 0:
+                                return None
+                        elif len (data.args) == 1:
+                                return data.args[0]
+                        else:
+                                return data.args
+
+
+                return dbus_method_func
diff --git a/pyatspi/cache.py b/pyatspi/cache.py
index 74e2f8f..129b09e 100644
--- a/pyatspi/cache.py
+++ b/pyatspi/cache.py
@@ -19,6 +19,8 @@ from appevent import Event
 
 from interfaces import *
 
+from busutils import AccessibilityBus
+
 __all__ = [
            "ApplicationCache",
            "TestApplicationCache",
@@ -79,38 +81,38 @@ class ApplicationCache(object):
         _APPLICATIONS_ADD = 1
         _APPLICATIONS_REMOVE = 0
 
-        def __init__(self, event_dispatcher, connection):
-                self._connection = connection
+        def __init__(self, event_dispatcher):
+                self._connection = AccessibilityBus ()
                 self._event_dispatcher = event_dispatcher
                 self._factory = None
 
                 self._application_list = []
                 self._application_cache = {}
 
-                self._bus_object = connection.get_object("org.freedesktop.DBus",
-                                                         "/org/freedesktop/DBus",
-                                                         "org.freedektop.DBus")
+                self._bus_object = self._connection.get_object("org.freedesktop.DBus",
+                                                               "/org/freedesktop/DBus")
 
-                this_pid = os.getpid()
 
-                self._regsig = connection.add_signal_receiver(self._update_handler,
-                                                              dbus_interface=ATSPI_REGISTRY_INTERFACE,
-                                                              signal_name="UpdateApplications")
+                self._regsig = self._connection.add_signal_receiver(self._update_handler,
+                                                                    dbus_interface=ATSPI_REGISTRY_INTERFACE,
+                                                                    signal_name="UpdateApplications")
 
-                obj = connection.get_object(ATSPI_REGISTRY_NAME,
-                                            ATSPI_REGISTRY_PATH,
-                                            introspect=False)
+                obj = self._connection.get_object(ATSPI_REGISTRY_NAME,
+                                                  ATSPI_REGISTRY_PATH)
                 self._app_register = dbus.Interface(obj, ATSPI_REGISTRY_INTERFACE)
 
                 apps = self._app_register.GetApplications()
-                for app in apps:
-                        that_pid = self._bus_object.GetConnectionUnixProcessID(app)
-                        if this_pid != that_pid:
-                                self._application_list.append(app)
+
+                #this_pid = os.getpid()
+                #for app in apps:
+                #        that_pid = self._bus_object.GetConnectionUnixProcessID(app)
+                #        if not this_pid == that_pid:
+                #                self._application_list.append(app)
+
+		self._application_list.extend(apps)
                         
                 for bus_name in self._application_list:
                                 self._application_cache[bus_name] = AccessibleCache(self._event_dispatcher,
-                                                                                    self._connection,
                                                                                     bus_name)
 
         def set_factory (self, factory):
@@ -135,24 +137,25 @@ class ApplicationCache(object):
                         #TODO Check that app does not already exist
                         self._application_list.append(bus_name)
                         self._application_cache[bus_name] = AccessibleCache(self._event_dispatcher,
-                                                                            self._connection,
                                                                             bus_name)
-                        event = Event(self._factory,
+                        event = Event(("add", 0, 0, ""),
+				      self._factory,
                                       ATSPI_DESKTOP_PATH,
                                       ATSPI_REGISTRY_NAME,
                                       "org.freedesktop.atspi.Event.Object",
-                                      "children-changed",
-                                      ("add", 0, 0, ""))
+                                      "children-changed")
+                                      
                 elif update_type == ApplicationCache._APPLICATIONS_REMOVE:
                         #TODO Fail safely if app does not exist
                         self._application_list.remove(bus_name)
                         del(self._application_cache[bus_name])
-                        event = Event(self._factory,
+                        event = Event(("remove", 0, 0, ""),
+				      self._factory,
                                       ATSPI_DESKTOP_PATH,
                                       ATSPI_REGISTRY_NAME,
                                       "org.freedesktop.atspi.Event.Object",
-                                      "children-changed",
-                                      ("remove", 0, 0, ""))
+                                      "children-changed")
+                                      
 
                 self._event_dispatcher.notifyChildrenChange(event)
 
@@ -240,7 +243,7 @@ class AccessibleCache(object):
         _UPDATE_SIGNAL = 'UpdateAccessible'
         _REMOVE_SIGNAL = 'RemoveAccessible'
 
-        def __init__(self, event_dispatcher, connection, bus_name):
+        def __init__(self, event_dispatcher, bus_name):
                 """
                 Creates a cache.
 
@@ -248,10 +251,10 @@ class AccessibleCache(object):
                 busName    - Name of DBus connection where cache interface resides.
                 """
                 self._event_dispatcher = event_dispatcher
-                self._connection = connection
+                self._connection = AccessibilityBus()
                 self._bus_name = bus_name
 
-                obj = connection.get_object(bus_name, self._PATH, introspect=False)
+                obj = self._connection.get_object(bus_name, self._PATH)
                 self._tree_itf = dbus.Interface(obj, self._INTERFACE)
 
                 self._objects = {}
diff --git a/pyatspi/desktop.py b/pyatspi/desktop.py
index d5ac1ad..34ac529 100644
--- a/pyatspi/desktop.py
+++ b/pyatspi/desktop.py
@@ -22,6 +22,8 @@ from component import LAYER_WIDGET
 
 import dbus
 
+from busutils import AccessibilityBus
+
 __all__ = [
            "Desktop",
            "CachedDesktop",
@@ -411,11 +413,10 @@ class TestDesktop (BaseDesktop):
         _TREE_PATH = '/org/freedesktop/atspi/tree'
         _TREE_INTERFACE = 'org.freedesktop.atspi.Tree'
 
-        def __init__(self, connection, app_name):
+        def __init__(self, app_name):
                 Accessible.__init__(self, *args);
-                obj = connection.get_object (app_name,
-                                             self._TREE_PATH,
-                                             introspect=False)
+                obj = AccessibilityBus().get_object (app_name,
+                                                     self._TREE_PATH)
                 tree = dbus.Interface (obj, self._TREE_INTERFACE)
 
                 self._single_app = app_name
diff --git a/pyatspi/deviceevent.py b/pyatspi/deviceevent.py
index ebbca52..4209784 100644
--- a/pyatspi/deviceevent.py
+++ b/pyatspi/deviceevent.py
@@ -18,6 +18,9 @@ import dbus as _dbus
 import dbus.service as _service
 
 from enum import Enum as _Enum
+from busutils import AccessibilityBus
+
+import traceback
 
 #------------------------------------------------------------------------------
 
@@ -251,8 +254,7 @@ class DeviceEventController(object):
 
         def __init__ (self, connection):
                 dec_object = connection.get_object(ATSPI_REGISTRY_NAME,
-                                                   ATSPI_DEVICE_EVENT_CONTROLLER_PATH,
-                                                   introspect=True)
+                                                   ATSPI_DEVICE_EVENT_CONTROLLER_PATH)
                 self._dec = _dbus.Interface(dec_object, ATSPI_DEVICE_EVENT_CONTROLLER_INTERFACE)
 
         def registerKeystrokeListener(self,
@@ -510,7 +512,8 @@ class KeyboardDeviceEventListener(_service.Object):
                 try:
                         # wrap the device event
                         event = DeviceEvent(*ev)
-                        return self._registry._handleDeviceEvent(event, self)
+                        ret = self._registry._handleDeviceEvent(event, self)
+			return ret
                 except Exception, e:
                         import traceback
                         traceback.print_exc()
@@ -520,9 +523,9 @@ class KeyboardDeviceEventListener(_service.Object):
 
 class _DeviceEventRegister (object):
         
-        def __init__ (self, bus):
-                self.dev = DeviceEventController (bus)
-                self._bus = bus
+        def __init__ (self):
+                self._bus = AccessibilityBus ()
+                self.dev = DeviceEventController (self._bus)
                 self.deviceClients = {}
 
         def registerKeystrokeListener(self,
diff --git a/pyatspi/factory.py b/pyatspi/factory.py
index 7ff666e..a2d266c 100644
--- a/pyatspi/factory.py
+++ b/pyatspi/factory.py
@@ -32,6 +32,7 @@ from table import *
 from value import *
 
 from accessible import AccessibleImpl, AccessibleImplCached
+from busutils import AccessibilityBus
 
 import dbus
 
@@ -39,10 +40,9 @@ import dbus
 
 class Factory (object):
 
-        def __init__ (self, connection, proxy_class):
+        def __init__ (self):
 
-                self._connection = connection
-                self._proxy_class = proxy_class
+                self._connection = AccessibilityBus() 
 
                 self._interfaces = { 
                         interfaces.ATSPI_ACCESSIBLE:Accessible,
@@ -67,7 +67,7 @@ class Factory (object):
 
         def create_accessible (self, name, path, itf, dbus_object=None):
                 if dbus_object == None:
-                        dbus_object = self._proxy_class (self._connection, name, path, introspect=False)
+                        dbus_object = self._connection.get_object (name, path)
         
                 # Hack to link applications 'parent' property up to the desktop object.
                 if name == interfaces.ATSPI_REGISTRY_NAME or path == interfaces.ATSPI_DESKTOP_PATH:
diff --git a/pyatspi/registry.py b/pyatspi/registry.py
index 84da7d9..e4bdf39 100644
--- a/pyatspi/registry.py
+++ b/pyatspi/registry.py
@@ -29,7 +29,6 @@ from appevent import _ApplicationEventRegister, _NullApplicationEventRegister
 from deviceevent import _DeviceEventRegister, _NullDeviceEventRegister
 from desktop import *
 from cache import *
-from loop import *
 
 from deviceevent import KEY_PRESSED_EVENT as _KEY_PRESSED_EVENT
 from deviceevent import KEY_RELEASED_EVENT as _KEY_RELEASED_EVENT
@@ -39,21 +38,17 @@ from interfaces import ATSPI_DESKTOP_PATH as _ATSPI_DESKTOP_PATH
 from interfaces import ATSPI_DESKTOP as _ATSPI_DESKTOP
 
 __all__ = ["Registry",
-           "set_default_registry",
-           "MAIN_LOOP_GLIB",
-           "MAIN_LOOP_NONE",
-           "MAIN_LOOP_QT"]
+	   "MAIN_LOOP_GLIB",
+	   "MAIN_LOOP_NONE",
+	   "set_default_registry"]
 
 import gobject
-from dbus.mainloop.glib import DBusGMainLoop
-DBusGMainLoop (set_as_default=True)
-del DBusGMainLoop
 
 #------------------------------------------------------------------------------
 
 MAIN_LOOP_GLIB = 'GLib'
-MAIN_LOOP_NONE = 'None'
 MAIN_LOOP_QT   = 'Qt'
+MAIN_LOOP_NONE = 'None'
 
 #------------------------------------------------------------------------------
 
@@ -90,7 +85,7 @@ class Registry(object):
                 self.app_event_register = None
                 self.desktop = None
                 self.accessible_factory = None
-                self.main_loop = None
+		self.main_loop = gobject.MainLoop()
 
         def __call__(self):
                 """
@@ -119,44 +114,32 @@ class Registry(object):
 
                 @param app_name: D-Bus name of the application to connect to when not using the registry daemon.
                 """
-                connection = dbus.SessionBus()
-
-                # Set up the main loop
-                if main_loop_type == MAIN_LOOP_GLIB:
-                        loop   = GObjectMain()
-                        proxy  = dbus.connection.ProxyObject
-                        #proxy  = GObjectProxy
-                elif main_loop_type == MAIN_LOOP_NONE:
-                        loop    = NullMain()
-                        proxy  = dbus.connection.ProxyObject
-                else:
-                        raise Exception ("Unknown main loop specified")
-
                 # Set up the device event controllers
                 if app_name:
                         devreg = _NullDeviceEventRegister()
                         appreg = _NullApplicationEventRegister()
                 else:
-                        devreg = _DeviceEventRegister(connection)
-                        appreg = _ApplicationEventRegister(connection)
+                        devreg = _DeviceEventRegister()
+                        appreg = _ApplicationEventRegister()
 
                 # Set up the cache / desktop and accesible factories.
                 if main_loop_type == MAIN_LOOP_GLIB:
                         if app_name:
-                                cache = AccessibleCache(appreg, connection, app_name)
+                                cache = AccessibleCache(appreg, app_name)
                         else:
-                                cache = ApplicationCache(appreg, connection)
+                                cache = ApplicationCache(appreg)
+
                         appreg.setCache (cache)
-                        factory = CachedAccessibleFactory (cache, connection, proxy)
+                        factory = CachedAccessibleFactory (cache)
                         cache.set_factory(factory)
                         desktop = CachedDesktop (cache, factory)
 
                 elif main_loop_type == MAIN_LOOP_NONE:
-                        factory = AccessibleFactory(connection, proxy)
+                        factory = AccessibleFactory()
                         if app_name:
-                                desktop = TestDesktop (connection, app_name, factory)
+                                desktop = TestDesktop (app_name, factory)
                         else:
-                                desktop = Desktop (connection, factory)
+                                desktop = Desktop (factory)
 
                 else:
                         raise Exception ("Unknown main loop specified")
@@ -170,7 +153,6 @@ class Registry(object):
                 self.app_event_register = appreg
                 self.desktop = desktop
                 self.accessible_factory = factory
-                self.main_loop = loop
 
         def _set_default_registry (self):
                 self._set_registry (MAIN_LOOP_GLIB)
@@ -201,7 +183,7 @@ class Registry(object):
                 """
                 if not self.has_implementations:
                         self._set_default_registry ()
-                self.main_loop.stop()
+                self.main_loop.quit()
 
         def getDesktopCount(self):
                 """



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]