Index: registry.py
===================================================================
--- registry.py	(revision 1015)
+++ registry.py	(working copy)
@@ -136,7 +136,7 @@
     self.mode.synchronous = synchronous
     self.mode._global = global_    
    
-  def register(self, dc, key_set, mask, kind):
+  def registerKeystroke(self, dc, key_set, mask, kind):
     '''
     Starts keyboard event monitoring.
     
@@ -161,7 +161,7 @@
       for m in mask:
         dc.registerKeystrokeListener(self._this(), key_set, m, kind, self.mode)
 
-  def unregister(self, dc, key_set, mask, kind):
+  def unregisterKeystroke(self, dc, key_set, mask, kind):
     '''
     Stops keyboard event monitoring.
     
@@ -185,6 +185,28 @@
       for m in mask:
         dc.deregisterKeystrokeListener(self._this(), key_set, m, kind)
       
+  def registerDeviceEvent(self, dc, kind):
+    '''
+    Starts device event monitoring.
+    
+    @param dc: Reference to a device controller
+    @type dc: Accessibility.DeviceEventController
+    @param kind: Kind of events to monitor
+    @type kind: integer
+    '''
+    dc.registerDeviceEventListener(self._this(), kind)
+
+  def unregisterDeviceEvent(self, dc, kind):
+    '''
+    Stops device event monitoring.
+    
+    @param dc: Reference to a device controller
+    @type dc: Accessibility.DeviceEventController
+    @param kind: Kind of events to monitor
+    @type kind: integer
+    '''
+    dc.deregisterDeviceEventListener(self._this(), kind)
+
   def queryInterface(self, repo_id):
     '''
     Reports that this class only implements the AT-SPI DeviceEventListener 
@@ -502,7 +524,7 @@
       # None means all modifier combinations
       mask = utils.allModifiers()
     # register for new keystrokes on the observer
-    ob.register(self.dev, key_set, mask, kind)
+    ob.registerKeystroke(self.dev, key_set, mask, kind)
 
   def deregisterKeystrokeListener(self, client, key_set=[], mask=0, 
                                   kind=(constants.KEY_PRESSED_EVENT, 
@@ -533,8 +555,61 @@
       # None means all modifier combinations
       mask = utils.allModifiers()
     # register for new keystrokes on the observer
-    ob.unregister(self.dev, key_set, mask, kind)
+    ob.unregisterKeystroke(self.dev, key_set, mask, kind)
 
+  def registerDeviceEventListener(self, client,
+                                  kind=(constants.BUTTON_PRESSED_EVENT, 
+                                        constants.BUTTON_RELEASED_EVENT),
+                                  synchronous=True, preemptive=True, 
+                                  global_=False):
+    '''
+    Registers a listener for device events.
+    
+    @param client: Callable to be invoked when the event occurs
+    @type client: callable
+    @param kind: Kind of events to watch, BUTTON_PRESSED_EVENT or 
+      BUTTON_RELEASED_EVENT.
+    @type kind: list
+    @param synchronous: Should the callback notification be synchronous, giving
+      the client the chance to consume the event?
+    @type synchronous: boolean
+    @param preemptive: Should the callback be allowed to preempt / consume the
+      event?
+    @type preemptive: boolean
+    @param global_: Should callback occur even if an application not supporting
+      AT-SPI is in the foreground? (requires xevie)
+    @type global_: boolean
+    '''
+    try:
+      # see if we already have an observer for this client
+      ob = self.clients[client]
+    except KeyError:
+      # create a new device observer for this client
+      ob = _DeviceObserver(self, synchronous, preemptive, global_)
+      # store the observer to client mapping, and the inverse
+      self.clients[ob] = client
+      self.clients[client] = ob
+    # register for new device event on the observer
+    ob.registerDeviceEvent(self.dev, kind)
+
+  def deregisterDeviceEventListener(self, client,
+                                  kind=(constants.BUTTON_PRESSED_EVENT, 
+                                        constants.BUTTON_RELEASED_EVENT)):
+    '''
+    Deregisters a listener for device events.
+    
+    @param client: Callable to be invoked when the event occurs
+    @type client: callable
+    @param kind: Kind of events to stop watching, KEY_PRESSED_EVENT or 
+      KEY_RELEASED_EVENT.
+    @type kind: list
+    @raise KeyError: When the client isn't already registered for events
+    '''
+    # see if we already have an observer for this client
+    ob = self.clients[client]
+    # unregister device event.
+    ob.unregisterDeviceEvent(self.dev, key_set, mask, kind)
+
   def generateKeyboardEvent(self, keycode, keysym, kind):
     '''
     Generates a keyboard event. One of the keycode or the keysym parameters
Index: constants.py
===================================================================
--- constants.py	(revision 1015)
+++ constants.py	(working copy)
@@ -188,7 +188,7 @@
 # these are the prefixes for the variable names we want to pull out of the 
 # Accessibility module
 prefixes = ['ROLE_', 'STATE_', 'TEXT_', 'MODIFIER_', 'LOCALE_', 'RELATION_',
-            'KEY_', 'MATCH_', 'SORT_', 'LAYER_']
+            'KEY_', 'MATCH_', 'SORT_', 'LAYER_', 'BUTTON_']
 # for each variable name in the Accessibility namespace, check if it starts
 # with at least one of the prefixes above; if it does, add a 2-tuple of 
 # variable name and value to the values list
Index: event.py
===================================================================
--- event.py	(revision 1015)
+++ event.py	(working copy)
@@ -77,9 +77,13 @@
     @rtype: string
     '''
     if self.type == constants.KEY_PRESSED_EVENT:
-      kind = 'pressed'
+      kind = 'key pressed'
     elif self.type == constants.KEY_RELEASED_EVENT:
-      kind = 'released'
+      kind = 'key released'
+    elif self.type == constants.BUTTON_PRESSED_EVENT:
+      kind = 'button pressed'
+    elif self.type == constants.BUTTON_RELEASED_EVENT:
+      kind = 'button released'
     return '''\
 %s
 \thw_code: %d
