2008-08-25 Mark Doffman <mark.doffman@codethink.co.uk>
[platform/core/uifw/at-spi2-atk.git] / pyatspi / event.py
1 #Copyright (C) 2008 Codethink Ltd
2 #copyright: Copyright (c) 2005, 2007 IBM Corporation
3
4 #This library is free software; you can redistribute it and/or
5 #modify it under the terms of the GNU Lesser General Public
6 #License version 2 as published by the Free Software Foundation.
7
8 #This program is distributed in the hope that it will be useful,
9 #but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #GNU General Public License for more details.
12 #You should have received a copy of the GNU Lesser General Public License
13 #along with this program; if not, write to the Free Software
14 #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15
16 #Portions of this code originally licensed and copyright (c) 2005, 2007
17 #IBM Corporation under the BSD license, available at
18 #U{http://www.opensource.org/licenses/bsd-license.php}
19
20 #authors: Peter Parente, Mark Doffman
21
22 #import signal
23 #import time
24 #import weakref
25 #import Queue
26 #import traceback
27 #import gobject
28 #import utils
29 #import constants
30 #import event
31
32 ATSPI_DEVICE_EVENT_CONTROLLER = 'org.freedesktop.atspi.DeviceEventController'
33 ATSPI_DEVICE_EVENT_LISTENER = 'org.freedesktop.atspi.DeviceEventListener'
34
35 import constants
36
37 class _Observer(object):
38         """
39         Parent class for all event observers. Dispatches all received events to the 
40         L{Registry} that created this L{_Observer}. Provides basic reference counting
41         functionality needed by L{Registry} to determine when an L{_Observer} can be
42         released for garbage collection. 
43         
44         The reference counting provided by this class is independent of the reference
45         counting used by CORBA. Keeping the counts separate makes it easier for the
46         L{Registry} to detect when an L{_Observer} can be freed in the 
47         L{Registry._unregisterObserver} method.
48         
49         @ivar registry: Reference to the L{Registry} that created this L{_Observer}
50         @type registry: weakref.proxy to L{Registry}
51         @ivar ref_count: Reference count on this L{_Observer}
52         @type ref_count: integer
53         """
54         def __init__(self, registry):
55                 """
56                 Stores a reference to the creating L{Registry}. Intializes the reference
57                 count on this object to zero.
58                 
59                 @param registry: The L{Registry} that created this observer
60                 @type registry: weakref.proxy to L{Registry}
61                 """
62                 self.registry = weakref.proxy(registry)
63                 self.ref_count = 0
64
65         def clientRef(self):
66                 """
67                 Increments the Python reference count on this L{_Observer} by one. This
68                 method is called when a new client is registered in L{Registry} to receive
69                 notification of an event type monitored by this L{_Observer}.
70                 """
71                 self.ref_count += 1
72                 
73         def clientUnref(self):
74                 """             
75                 Decrements the pyatspi reference count on this L{_Observer} by one. This
76                 method is called when a client is unregistered in L{Registry} to stop
77                 receiving notifications of an event type monitored by this L{_Observer}.
78                 """
79                 self.ref_count -= 1
80                 
81         def getClientRefCount(self):
82                 """
83                 @return: Current Python reference count on this L{_Observer}
84                 @rtype: integer
85                 """
86                 return self.ref_count
87         
88         def ref(self): 
89                 """Required by CORBA. Does nothing."""
90                 pass
91                 
92         def unref(self): 
93                 """Required by CORBA. Does nothing."""
94                 pass
95
96 class _DeviceObserver(_Observer, Accessibility__POA.DeviceEventListener):
97         """
98         Observes keyboard press and release events.
99         
100         @ivar registry: The L{Registry} that created this observer
101         @type registry: L{Registry}
102         @ivar key_set: Set of keys to monitor
103         @type key_set: list of integer
104         @ivar mask: Watch for key events while these modifiers are held
105         @type mask: integer
106         @ivar kind: Kind of events to monitor
107         @type kind: integer
108         @ivar mode: Keyboard event mode
109         @type mode: Accessibility.EventListenerMode
110         """
111         def __init__(self, registry, synchronous, preemptive, global_):
112                 """
113                 Creates a mode object that defines when key events will be received from 
114                 the system. Stores all other information for later registration.
115                 
116                 @param registry: The L{Registry} that created this observer
117                 @type registry: L{Registry}
118                 @param synchronous: Handle the key event synchronously?
119                 @type synchronous: boolean
120                 @param preemptive: Allow event to be consumed?
121                 @type preemptive: boolean
122                 @param global_: Watch for events on inaccessible applications too?
123                 @type global_: boolean
124                 """
125                 _Observer.__init__(self, registry)       
126                 self.mode = Accessibility.EventListenerMode()
127                 self.mode.preemptive = preemptive
128                 self.mode.synchronous = synchronous
129                 self.mode._global = global_             
130          
131         def register(self, dc, key_set, mask, kind):
132                 """
133                 Starts keyboard event monitoring.
134                 
135                 @param dc: Reference to a device controller
136                 @type dc: Accessibility.DeviceEventController
137                 @param key_set: Set of keys to monitor
138                 @type key_set: list of integer
139                 @param mask: Integer modifier mask or an iterable over multiple masks to
140                         unapply all at once
141                 @type mask: integer, iterable, or None
142                 @param kind: Kind of events to monitor
143                 @type kind: integer
144                 """
145                 try:
146                         # check if the mask is iterable
147                         iter(mask)
148                 except TypeError:
149                         # register a single integer if not
150                         dc.registerKeystrokeListener(self._this(), key_set, mask, kind, 
151                                                                                                                                          self.mode)
152                 else:
153                         for m in mask:
154                                 dc.registerKeystrokeListener(self._this(), key_set, m, kind, self.mode)
155
156         def unregister(self, dc, key_set, mask, kind):
157                 """
158                 Stops keyboard event monitoring.
159                 
160                 @param dc: Reference to a device controller
161                 @type dc: Accessibility.DeviceEventController
162                 @param key_set: Set of keys to monitor
163                 @type key_set: list of integer
164                 @param mask: Integer modifier mask or an iterable over multiple masks to
165                         unapply all at once
166                 @type mask: integer, iterable, or None
167                 @param kind: Kind of events to monitor
168                 @type kind: integer
169                 """
170                 try:
171                         # check if the mask is iterable
172                         iter(mask)
173                 except TypeError:
174                         # unregister a single integer if not
175                         dc.deregisterKeystrokeListener(self._this(), key_set, mask, kind)
176                 else:
177                         for m in mask:
178                                 dc.deregisterKeystrokeListener(self._this(), key_set, m, kind)
179                         
180         def queryInterface(self, repo_id):
181                 """
182                 Reports that this class only implements the AT-SPI DeviceEventListener 
183                 interface. Required by AT-SPI.
184                 
185                 @param repo_id: Request for an interface 
186                 @type repo_id: string
187                 @return: The underlying CORBA object for the device event listener
188                 @rtype: Accessibility.EventListener
189                 """
190                 if repo_id == utils.getInterfaceIID(Accessibility.DeviceEventListener):
191                         return self._this()
192                 else:
193                         return None
194
195         def notifyEvent(self, ev):
196                 """
197                 Notifies the L{Registry} that an event has occurred. Wraps the raw event 
198                 object in our L{Event} class to support automatic ref and unref calls. An
199                 observer can return True to indicate this event should not be allowed to pass 
200                 to other AT-SPI observers or the underlying application.
201                 
202                 @param ev: Keyboard event
203                 @type ev: Accessibility.DeviceEvent
204                 @return: Should the event be consumed (True) or allowed to pass on to other
205                         AT-SPI observers (False)?
206                 @rtype: boolean
207                 """
208                 # wrap the device event
209                 ev = event.DeviceEvent(ev)
210                 return self.registry.handleDeviceEvent(ev, self)
211
212 class _EventObserver(_Observer, Accessibility__POA.EventListener):
213         """
214         Observes all non-keyboard AT-SPI events. Can be reused across event types.
215         """
216         def register(self, reg, name):
217                 """
218                 Starts monitoring for the given event.
219                 
220                 @param name: Name of the event to start monitoring
221                 @type name: string
222                 @param reg: Reference to the raw registry object
223                 @type reg: Accessibility.Registry
224                 """
225                 reg.registerGlobalEventListener(self._this(), name)
226                 
227         def unregister(self, reg, name):
228                 """
229                 Stops monitoring for the given event.
230                 
231                 @param name: Name of the event to stop monitoring
232                 @type name: string
233                 @param reg: Reference to the raw registry object
234                 @type reg: Accessibility.Registry
235                 """
236                 reg.deregisterGlobalEventListener(self._this(), name)
237
238         def queryInterface(self, repo_id):
239                 """
240                 Reports that this class only implements the AT-SPI DeviceEventListener 
241                 interface. Required by AT-SPI.
242
243                 @param repo_id: Request for an interface 
244                 @type repo_id: string
245                 @return: The underlying CORBA object for the device event listener
246                 @rtype: Accessibility.EventListener
247                 """
248                 if repo_id == utils.getInterfaceIID(Accessibility.EventListener):
249                         return self._this()
250                 else:
251                         return None
252
253         def notifyEvent(self, ev):
254                 """
255                 Notifies the L{Registry} that an event has occurred. Wraps the raw event 
256                 object in our L{Event} class to support automatic ref and unref calls.
257                 Aborts on any exception indicating the event could not be wrapped.
258                 
259                 @param ev: AT-SPI event signal (anything but keyboard)
260                 @type ev: Accessibility.Event
261                 """
262                 # wrap raw event so ref counts are correct before queueing
263                 ev = event.Event(ev)
264                 self.registry.handleEvent(ev)
265
266 class DeviceEvent(object):
267         """
268         Wraps an AT-SPI device event with a more Pythonic interface. Primarily adds
269         a consume attribute which can be used to cease propagation of a device event.
270         
271         @ivar consume: Should this event be consumed and not allowed to pass on to
272                 observers further down the dispatch chain in this process or possibly
273                 system wide?
274         @type consume: boolean
275         @ivar type: Kind of event, KEY_PRESSED_EVENT or KEY_RELEASED_EVENT
276         @type type: Accessibility.EventType
277         @ivar id: Serial identifier for this key event
278         @type id: integer
279         @ivar hw_code: Hardware scan code for the key
280         @type hw_code: integer
281         @ivar modifiers: Modifiers held at the time of the key event
282         @type modifiers: integer
283         @ivar timestamp: Time at which the event occurred relative to some platform
284                 dependent starting point (e.g. XWindows start time)
285         @type timestamp: integer
286         @ivar event_string: String describing the key pressed (e.g. keysym)
287         @type event_string: string
288         @ivar is_text: Is the event representative of text to be inserted (True), or 
289                 of a control key (False)?
290         @type is_text: boolean
291         """
292         def __init__(self, event):
293                 """
294                 Attaches event data to this object.
295                 
296                 @param event: Event object
297                 @type event: Accessibility.DeviceEvent
298                 """
299                 self.consume = False
300                 self.type = event.type
301                 self.id = event.id
302                 self.hw_code = event.hw_code
303                 self.modifiers = event.modifiers
304                 self.timestamp = event.timestamp
305                 self.event_string = event.event_string
306                 self.is_text = event.is_text
307                 
308         def __str__(self):
309                 """
310                 Builds a human readable representation of the event.
311
312                 @return: Event description
313                 @rtype: string
314                 """
315                 if self.type == constants.KEY_PRESSED_EVENT:
316                         kind = 'pressed'
317                 elif self.type == constants.KEY_RELEASED_EVENT:
318                         kind = 'released'
319                 return """\
320 %s
321 \thw_code: %d
322 \tevent_string: %s
323 \tmodifiers: %d
324 \tid: %d
325 \ttimestamp: %d
326 \tis_text: %s""" % (kind, self.hw_code, self.event_string, self.modifiers,
327                 self.id, self.timestamp, self.is_text)
328
329 class Event(object):
330         """
331         Wraps an AT-SPI event with a more Pythonic interface managing exceptions,
332         the differences in any_data across versions, and the reference counting of
333         accessibles provided with the event.
334         
335         @note: All unmarked attributes of this class should be considered public
336                 readable and writable as the class is acting as a record object.
337                 
338         @ivar consume: Should this event be consumed and not allowed to pass on to
339                 observers further down the dispatch chain in this process?
340         @type consume: boolean
341         @ivar type: The type of the AT-SPI event
342         @type type: L{EventType}
343         @ivar detail1: First AT-SPI event parameter
344         @type detail1: integer
345         @ivar detail2: Second AT-SPI event parameter
346         @type detail2: integer
347         @ivar any_data: Extra AT-SPI data payload
348         @type any_data: object
349         @ivar host_application: Application owning the event source
350         @type host_application: Accessibility.Application
351         @ivar source_name: Name of the event source at the time of event dispatch
352         @type source_name: string
353         @ivar source_role: Role of the event source at the time of event dispatch
354         @type source_role: Accessibility.Role
355         @ivar source: Source of the event
356         @type source: Accessibility.Accessible
357         """
358         def __init__(self, event):
359                 """
360                 Extracts information from the provided event. If the event is a "normal" 
361                 event, pulls the detail1, detail2, any_data, and source values out of the
362                 given object and stores it in this object. If the event is a device event,
363                 key ID is stored in detail1, scan code is stored in detail2, key name, 
364                 key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are 
365                 stored as a 4-tuple in any_data, and source is None (since key events are
366                 global).
367
368                 @param event: Event from an AT-SPI callback
369                 @type event: Accessibility.Event or Accessibility.DeviceEvent
370                 """
371                 # always start out assuming no consume
372                 self.consume = False
373                 self.type = EventType(event.type)
374                 self.detail1 = event.detail1
375                 self.detail2 = event.detail2
376                 # store the event source and increase the reference count since event 
377                 # sources are borrowed references; the AccessibleMixin automatically
378                 # decrements it later
379                 try:
380                         event.source.ref()
381                 except AttributeError:
382                         pass
383                 self.source = event.source
384
385                 # process any_data in a at-spi version independent manner
386                 details = event.any_data.value()
387                 try:
388                         # see if we have a "new" any_data object which is an EventDetails struct
389                         self.any_data = details.any_data.value()
390                 except Exception:
391                         # any kind of error means we have an "old" any_data object and None of
392                         # the extra data so set them to None
393                         self.any_data = details
394                         self.host_application = None
395                         self.source_name = None
396                         self.source_role = None
397                 else:
398                         # the rest of the data should be here, so retrieve it
399                         self.host_application = details.host_application
400                         self.source_name = details.source_name
401                         self.source_role = details.source_role
402                 try:
403                         # if we received an accessible, be sure to increment the ref count
404                         self.any_data.ref()
405                 except AttributeError:
406                         pass
407                 try:
408                         # if we received a host application, be sure to increment the ref count
409                         self.host_application.ref()
410                 except AttributeError:
411                         pass
412
413         def __str__(self):
414                 """
415                 Builds a human readable representation of the event including event type,
416                 parameters, and source info.
417
418                 @return: Event description
419                 @rtype: string
420                 """
421                 return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \
422                                          (self.type, self.detail1, self.detail2, self.any_data,
423                                                 self.source, self.host_application)
424         
425 class EventType(str):
426         """
427         Wraps the AT-SPI event type string so its components can be accessed 
428         individually as klass (can't use the keyword class), major, minor, and detail 
429         (klass:major:minor:detail).
430         
431         @note: All attributes of an instance of this class should be considered 
432                 public readable as it is acting a a struct.
433         @ivar klass: Most general event type identifier (object, window, mouse, etc.)
434         @type klass: string
435         @ivar major: Second level event type description
436         @type major: string
437         @ivar minor: Third level event type description
438         @type minor: string
439         @ivar detail: Lowest level event type description
440         @type detail: string
441         @ivar name: Full, unparsed event name as received from AT-SPI
442         @type name: string
443         @cvar format: Names of the event string components
444         @type format: 4-tuple of string
445         """
446         format = ('klass', 'major', 'minor', 'detail')
447
448         def __init__(self, name):
449                 """             
450                 Parses the full AT-SPI event name into its components
451                 (klass:major:minor:detail). If the provided event name is an integer
452                 instead of a string, then the event is really a device event.
453                 
454                 @param name: Full AT-SPI event name
455                 @type name: string
456                 @raise AttributeError: When the given event name is not a valid string 
457                 """
458                 # get rid of any leading and trailing ':' separators
459                 self.value = name.strip(':')
460                 self.name = self.value # Backward compatability
461                 self.klass = None
462                 self.major = None
463                 self.minor = None
464                 self.detail = None
465                 
466                 # split type according to delimiters
467                 split = self.value.split(':', 3)
468                 # loop over all the components
469                 for i in xrange(len(split)):
470                         # store values of attributes in this object
471                         setattr(self, self.format[i], split[i])
472
473 class Registry(object):
474         """
475         Wraps the Accessibility.Registry to provide more Pythonic registration for
476         events. 
477         
478         This object should be treated as a singleton, but such treatment is not
479         enforced. You can construct another instance of this object and give it a
480         reference to the Accessibility.Registry singleton. Doing so is harmless and
481         has no point.
482         
483         @ivar async: Should event dispatch to local listeners be decoupled from event
484                 receiving from the registry?
485         @type async: boolean
486         @ivar reg: Reference to the real, wrapped registry object
487         @type reg: Accessibility.Registry
488         @ivar dev: Reference to the device controller
489         @type dev: Accessibility.DeviceEventController
490         @ivar queue: Queue of events awaiting local dispatch
491         @type queue: Queue.Queue
492         @ivar clients: Map of event names to client listeners
493         @type clients: dictionary
494         @ivar observers: Map of event names to AT-SPI L{_Observer} objects
495         @type observers: dictionary
496         """
497
498         _REGISTRY_NAME = 'org.freedesktop.atspi.Registry'
499
500         def __init__(self, app_name=None):
501                 """
502                 Stores a reference to the AT-SPI registry. Gets and stores a reference
503                 to the DeviceEventController.
504                 
505                 @param reg: Reference to the AT-SPI registry daemon
506                 @type reg: Accessibility.Registry
507                 """
508                 self._bus = dbus.SessionBus()
509                 if app_path:
510                         self._app_name = app_name
511                         self._cache = TestApplicationCache(self._bus, app_name)
512
513                 #self.async = None
514                 #self.reg = reg
515                 #self.dev = self.reg.getDeviceEventController()
516                 #self.queue = Queue.Queue()
517                 #self.clients = {}
518                 #self.observers = {}
519                 
520         def __call__(self):
521                 """
522                 @return: This instance of the registry
523                 @rtype: L{Registry}
524                 """
525                 return self
526         
527         def start(self, async=False, gil=True):
528                 """
529                 Enter the main loop to start receiving and dispatching events.
530                 
531                 @param async: Should event dispatch be asynchronous (decoupled) from 
532                         event receiving from the AT-SPI registry?
533                 @type async: boolean
534                 @param gil: Add an idle callback which releases the Python GIL for a few
535                         milliseconds to allow other threads to run? Necessary if other threads
536                         will be used in this process.
537                         Note - No Longer used.
538                 @type gil: boolean
539                 """
540                 self._loop = gobject.MainLoop()
541                 self._loop.run()
542
543         def stop(self, *args):
544                 """Quits the main loop."""
545                 self._loop.quit()
546                 self.flushEvents()
547                 
548         def getDesktopCount(self):
549                 """
550                 Gets the number of available desktops.
551                 
552                 @return: Number of desktops
553                 @rtype: integer
554                 """
555                 return 1
556                 
557         def getDesktop(self, i):
558                 """
559                 Gets a reference to the i-th desktop.
560                 
561                 @param i: Which desktop to get
562                 @type i: integer
563                 @return: Desktop reference
564                 @rtype: Accessibility.Desktop
565                 """
566                 return Desktop(self._cache)
567                 
568         def registerEventListener(self, client, *names):
569                 """
570                 Registers a new client callback for the given event names. Supports 
571                 registration for all subevents if only partial event name is specified.
572                 Do not include a trailing colon.
573                 
574                 For example, 'object' will register for all object events, 
575                 'object:property-change' will register for all property change events,
576                 and 'object:property-change:accessible-parent' will register only for the
577                 parent property change event.
578                 
579                 Registered clients will not be automatically removed when the client dies.
580                 To ensure the client is properly garbage collected, call 
581                 L{deregisterEventListener}.
582
583                 @param client: Callable to be invoked when the event occurs
584                 @type client: callable
585                 @param names: List of full or partial event names
586                 @type names: list of string
587                 """
588                 for name in names:
589                         # store the callback for each specific event name
590                         self._registerClients(client, name)
591
592         def deregisterEventListener(self, client, *names):
593                 """
594                 Unregisters an existing client callback for the given event names. Supports 
595                 unregistration for all subevents if only partial event name is specified.
596                 Do not include a trailing colon.
597                 
598                 This method must be called to ensure a client registered by
599                 L{registerEventListener} is properly garbage collected.
600
601                 @param client: Client callback to remove
602                 @type client: callable
603                 @param names: List of full or partial event names
604                 @type names: list of string
605                 @return: Were event names specified for which the given client was not
606                         registered?
607                 @rtype: boolean
608                 """
609                 missed = False
610                 for name in names:
611                         # remove the callback for each specific event name
612                         missed |= self._unregisterClients(client, name)
613                 return missed
614
615         def registerKeystrokeListener(self, client, key_set=[], mask=0, 
616                                                                                                                                 kind=(constants.KEY_PRESSED_EVENT, 
617                                                                                                                                                         constants.KEY_RELEASED_EVENT),
618                                                                                                                                 synchronous=True, preemptive=True, 
619                                                                                                                                 global_=False):
620                 """
621                 Registers a listener for key stroke events.
622                 
623                 @param client: Callable to be invoked when the event occurs
624                 @type client: callable
625                 @param key_set: Set of hardware key codes to stop monitoring. Leave empty
626                         to indicate all keys.
627                 @type key_set: list of integer
628                 @param mask: When the mask is None, the codes in the key_set will be 
629                         monitored only when no modifier is held. When the mask is an 
630                         integer, keys in the key_set will be monitored only when the modifiers in
631                         the mask are held. When the mask is an iterable over more than one 
632                         integer, keys in the key_set will be monitored when any of the modifier
633                         combinations in the set are held.
634                 @type mask: integer, iterable, None
635                 @param kind: Kind of events to watch, KEY_PRESSED_EVENT or 
636                         KEY_RELEASED_EVENT.
637                 @type kind: list
638                 @param synchronous: Should the callback notification be synchronous, giving
639                         the client the chance to consume the event?
640                 @type synchronous: boolean
641                 @param preemptive: Should the callback be allowed to preempt / consume the
642                         event?
643                 @type preemptive: boolean
644                 @param global_: Should callback occur even if an application not supporting
645                         AT-SPI is in the foreground? (requires xevie)
646                 @type global_: boolean
647                 """
648                 try:
649                         # see if we already have an observer for this client
650                         ob = self.clients[client]
651                 except KeyError:
652                         # create a new device observer for this client
653                         ob = _DeviceObserver(self, synchronous, preemptive, global_)
654                         # store the observer to client mapping, and the inverse
655                         self.clients[ob] = client
656                         self.clients[client] = ob
657                 if mask is None:
658                         # None means all modifier combinations
659                         mask = utils.allModifiers()
660                 # register for new keystrokes on the observer
661                 ob.register(self.dev, key_set, mask, kind)
662
663         def deregisterKeystrokeListener(self, client, key_set=[], mask=0, 
664                                                                                                                                         kind=(constants.KEY_PRESSED_EVENT, 
665                                                                                                                                                                 constants.KEY_RELEASED_EVENT)):
666                 """
667                 Deregisters a listener for key stroke events.
668                 
669                 @param client: Callable to be invoked when the event occurs
670                 @type client: callable
671                 @param key_set: Set of hardware key codes to stop monitoring. Leave empty
672                         to indicate all keys.
673                 @type key_set: list of integer
674                 @param mask: When the mask is None, the codes in the key_set will be 
675                         monitored only when no modifier is held. When the mask is an 
676                         integer, keys in the key_set will be monitored only when the modifiers in
677                         the mask are held. When the mask is an iterable over more than one 
678                         integer, keys in the key_set will be monitored when any of the modifier
679                         combinations in the set are held.
680                 @type mask: integer, iterable, None
681                 @param kind: Kind of events to stop watching, KEY_PRESSED_EVENT or 
682                         KEY_RELEASED_EVENT.
683                 @type kind: list
684                 @raise KeyError: When the client isn't already registered for events
685                 """
686                 # see if we already have an observer for this client
687                 ob = self.clients[client]
688                 if mask is None:
689                         # None means all modifier combinations
690                         mask = utils.allModifiers()
691                 # register for new keystrokes on the observer
692                 ob.unregister(self.dev, key_set, mask, kind)
693
694         def generateKeyboardEvent(self, keycode, keysym, kind):
695                 """
696                 Generates a keyboard event. One of the keycode or the keysym parameters
697                 should be specified and the other should be None. The kind parameter is 
698                 required and should be one of the KEY_PRESS, KEY_RELEASE, KEY_PRESSRELEASE,
699                 KEY_SYM, or KEY_STRING.
700                 
701                 @param keycode: Hardware keycode or None
702                 @type keycode: integer
703                 @param keysym: Symbolic key string or None
704                 @type keysym: string
705                 @param kind: Kind of event to synthesize
706                 @type kind: integer
707                 """
708                 if keysym is None:
709                         self.dev.generateKeyboardEvent(keycode, '', kind)
710                 else:
711                         self.dev.generateKeyboardEvent(None, keysym, kind)
712         
713         def generateMouseEvent(self, x, y, name):
714                 """
715                 Generates a mouse event at the given absolute x and y coordinate. The kind
716                 of event generated is specified by the name. For example, MOUSE_B1P 
717                 (button 1 press), MOUSE_REL (relative motion), MOUSE_B3D (butten 3 
718                 double-click).
719                 
720                 @param x: Horizontal coordinate, usually left-hand oriented
721                 @type x: integer
722                 @param y: Vertical coordinate, usually left-hand oriented
723                 @type y: integer
724                 @param name: Name of the event to generate
725                 @type name: string
726                 """
727                 self.dev.generateMouseEvent(x, y, name)
728                 
729         def handleDeviceEvent(self, event, ob):
730                 """
731                 Dispatches L{event.DeviceEvent}s to registered clients. Clients are called
732                 in the order they were registered for the given AT-SPI event. If any
733                 client returns True, callbacks cease for the event for clients of this registry 
734                 instance. Clients of other registry instances and clients in other processes may 
735                 be affected depending on the values of synchronous and preemptive used when invoking
736                 L{registerKeystrokeListener}. 
737                 
738                 @note: Asynchronous dispatch of device events is not supported.
739                 
740                 @param event: AT-SPI device event
741                 @type event: L{event.DeviceEvent}
742                 @param ob: Observer that received the event
743                 @type ob: L{_DeviceObserver}
744
745                 @return: Should the event be consumed (True) or allowed to pass on to other
746                         AT-SPI observers (False)?
747                 @rtype: boolean
748                 """
749                 try:
750                         # try to get the client registered for this event type
751                         client = self.clients[ob]
752                 except KeyError:
753                         # client may have unregistered recently, ignore event
754                         return False
755                 # make the call to the client
756                 try:
757                         return client(event) or event.consume
758                 except Exception:
759                         # print the exception, but don't let it stop notification
760                         traceback.print_exc()
761  
762         def handleEvent(self, event):
763                 """             
764                 Handles an AT-SPI event by either queuing it for later dispatch when the
765                 L{Registry.async} flag is set, or dispatching it immediately.
766
767                 @param event: AT-SPI event
768                 @type event: L{event.Event}
769                 """
770                 if self.async:
771                         # queue for now
772                         self.queue.put_nowait(event)
773                 else:
774                         # dispatch immediately
775                         self._dispatchEvent(event)
776
777         def _dispatchEvent(self, event):
778                 """
779                 Dispatches L{event.Event}s to registered clients. Clients are called in
780                 the order they were registered for the given AT-SPI event. If any client
781                 returns True, callbacks cease for the event for clients of this registry 
782                 instance. Clients of other registry instances and clients in other processes 
783                 are unaffected.
784
785                 @param event: AT-SPI event
786                 @type event: L{event.Event}
787                 """
788                 et = event.type
789                 try:
790                         # try to get the client registered for this event type
791                         clients = self.clients[et.name]
792                 except KeyError:
793                         try:
794                                 # we may not have registered for the complete subtree of events
795                                 # if our tree does not list all of a certain type (e.g.
796                                 # object:state-changed:*); try again with klass and major only
797                                 if et.detail is not None:
798                                         # Strip the 'detail' field.
799                                         clients = self.clients['%s:%s:%s' % (et.klass, et.major, et.minor)]
800                                 elif et.minor is not None:
801                                         # The event could possibly be object:state-changed:*.
802                                         clients = self.clients['%s:%s' % (et.klass, et.major)]
803                         except KeyError:
804                                 # client may have unregistered recently, ignore event
805                                 return
806                 # make the call to each client
807                 consume = False
808                 for client in clients:
809                         try:
810                                 consume = client(event) or False
811                         except Exception:
812                                 # print the exception, but don't let it stop notification
813                                 traceback.print_exc()
814                         if consume or event.consume:
815                                 # don't allow further processing if a client returns True
816                                 break
817
818         def flushEvents(self):
819                 """
820                 Flushes the event queue by destroying it and recreating it.
821                 """
822                 self.queue = Queue.Queue()
823
824         def pumpQueuedEvents(self, num=-1):
825                 """
826                 Provides asynch processing of events in the queue by executeing them with 
827                 _dispatchEvent() (as is done immediately when synch processing). 
828                 This method would normally be called from a main loop or idle function.
829
830                 @param num: Number of events to pump. If number is negative it pumps
831                 the entire queue. Default is -1.
832                 @type num: integer
833                 @return: True if queue is not empty after events were pumped.
834                 @rtype: boolean
835                 """
836                 if num < 0:
837                         # Dequeue as many events as currently in the queue.
838                         num = self.queue.qsize()
839                 for i in xrange(num):
840                         try:
841                                 # get next waiting event
842                                 event = self.queue.get_nowait()
843                         except Queue.Empty:
844                                 break
845                         self._dispatchEvent(event)
846
847                 return not self.queue.empty()
848  
849         def _registerClients(self, client, name):
850                 """
851                 Internal method that recursively associates a client with AT-SPI event 
852                 names. Allows a client to incompletely specify an event name in order to 
853                 register for subevents without specifying their full names manually.
854                 
855                 @param client: Client callback to receive event notifications
856                 @type client: callable
857                 @param name: Partial or full event name
858                 @type name: string
859                 """
860                 try:
861                         # look for an event name in our event tree dictionary
862                         events = constants.EVENT_TREE[name]
863                 except KeyError:
864                         # if the event name doesn't exist, it's a leaf event meaning there are
865                         # no subtypes for that event
866                         # add this client to the list of clients already in the dictionary 
867                         # using the event name as the key; if there are no clients yet for this 
868                         # event, insert an empty list into the dictionary before appending 
869                         # the client
870                         et = event.EventType(name)
871                         clients = self.clients.setdefault(et.name, [])
872                         try:
873                                 # if this succeeds, this client is already registered for the given
874                                 # event type, so ignore the request
875                                 clients.index(client)
876                         except ValueError:
877                                 # else register the client
878                                 clients.append(client)
879                                 self._registerObserver(name)
880                 else:
881                                 # if the event name does exist in the tree, there are subevents for
882                                 # this event; loop through them calling this method again to get to
883                                 # the leaf events
884                                 for e in events:
885                                         self._registerClients(client, e)
886                         
887         def _unregisterClients(self, client, name):
888                 """
889                 Internal method that recursively unassociates a client with AT-SPI event 
890                 names. Allows a client to incompletely specify an event name in order to 
891                 unregister for subevents without specifying their full names manually.
892                 
893                 @param client: Client callback to receive event notifications
894                 @type client: callable
895                 @param name: Partial or full event name
896                 @type name: string
897                 """
898                 missed = False
899                 try:
900                         # look for an event name in our event tree dictionary
901                         events = constants.EVENT_TREE[name]
902                 except KeyError:
903                         try:
904                                 # if the event name doesn't exist, it's a leaf event meaning there are
905                                 # no subtypes for that event
906                                 # get the list of registered clients and try to remove the one provided
907                                 et = event.EventType(name)
908                                 clients = self.clients[et.name]
909                                 clients.remove(client)
910                                 self._unregisterObserver(name)
911                         except (ValueError, KeyError):
912                                 # ignore any exceptions indicating the client is not registered
913                                 missed = True
914                         return missed
915                 # if the event name does exist in the tree, there are subevents for this 
916                 # event; loop through them calling this method again to get to the leaf
917                 # events
918                 for e in events:
919                         missed |= self._unregisterClients(client, e)
920                 return missed
921         
922         def _registerObserver(self, name):
923                 """             
924                 Creates a new L{_Observer} to watch for events of the given type or
925                 returns the existing observer if one is already registered. One
926                 L{_Observer} is created for each leaf in the L{constants.EVENT_TREE} or
927                 any event name not found in the tree.
928          
929                 @param name: Raw name of the event to observe
930                 @type name: string
931                 @return: L{_Observer} object that is monitoring the event
932                 @rtype: L{_Observer}
933                 """
934                 et = event.EventType(name)
935                 try:
936                         # see if an observer already exists for this event
937                         ob = self.observers[et.name]
938                 except KeyError:
939                         # build a new observer if one does not exist
940                         ob = _EventObserver(self)
941                         # we have to register for the raw name because it may be different from
942                         # the parsed name determined by EventType (e.g. trailing ':' might be 
943                         # missing)
944                         ob.register(self.reg, name)
945                         self.observers[et.name] = ob
946                 # increase our client ref count so we know someone new is watching for the 
947                 # event
948                 ob.clientRef()
949                 return ob
950                 
951         def _unregisterObserver(self, name):
952                 """             
953                 Destroys an existing L{_Observer} for the given event type only if no
954                 clients are registered for the events it is monitoring.
955                 
956                 @param name: Name of the event to observe
957                 @type name: string
958                 @raise KeyError: When an observer for the given event is not regist
959                 """
960                 et = event.EventType(name)
961                 # see if an observer already exists for this event
962                 ob = self.observers[et.name]
963                 ob.clientUnref()
964                 if ob.getClientRefCount() == 0:
965                         ob.unregister(self.reg, name)
966                         del self.observers[et.name]
967
968 class DeviceEvent(list):
969     def __new__(cls, type, id, hw_code, modifiers, timestamp, event_string, is_text):
970         list.__new__(cls, (type, id, hw_code, modifiers, timestamp, event_string, is_text))
971     def __init__(self, type, id, hw_code, modifiers, timestamp, event_string, is_text):
972         list.__init__(self, (type, id, hw_code, modifiers, timestamp, event_string, is_text))
973     
974     def _get_type(self):
975         return self[0]
976     def _set_type(self, val):
977         self[0] = val
978     type = property(fget=_get_type, fset=_set_type)
979     def _get_id(self):
980         return self[1]
981     def _set_id(self, val):
982         self[1] = val
983     id = property(fget=_get_id, fset=_set_id)
984     def _get_hw_code(self):
985         return self[2]
986     def _set_hw_code(self, val):
987         self[2] = val
988     hw_code = property(fget=_get_hw_code, fset=_set_hw_code)
989     def _get_modifiers(self):
990         return self[3]
991     def _set_modifiers(self, val):
992         self[3] = val
993     modifiers = property(fget=_get_modifiers, fset=_set_modifiers)
994     def _get_timestamp(self):
995         return self[4]
996     def _set_timestamp(self, val):
997         self[4] = val
998     timestamp = property(fget=_get_timestamp, fset=_set_timestamp)
999     def _get_event_string(self):
1000         return self[5]
1001     def _set_event_string(self, val):
1002         self[5] = val
1003     event_string = property(fget=_get_event_string, fset=_set_event_string)
1004     def _get_is_text(self):
1005         return self[6]
1006     def _set_is_text(self, val):
1007         self[6] = val
1008     is_text = property(fget=_get_is_text, fset=_set_is_text)
1009
1010 class DeviceEventController(_BaseProxy):
1011     """
1012     The interface via which clients request notification of device
1013     events, and through which device events may be simulated.
1014     """
1015
1016     def deregisterDeviceEventListener(self, *args, **kwargs):
1017         """
1018         De-register a previously registered keyboard eventlistener. 
1019         @param : listener
1020         a DeviceEventListener which will intercept events. 
1021         @param : typeseq
1022         an EventTypeSeq indicating which event types to stop listening
1023         for.
1024         """
1025         func = self.get_dbus_method("deregisterDeviceEventListener")
1026         return func(*args, **kwargs)
1027     
1028     def deregisterKeystrokeListener(self, *args, **kwargs):
1029         """
1030         De-register a previously registered keyboard eventlistener. 
1031         @param : listener
1032         a DeviceEventListener which will intercept key events. 
1033         @param : keys
1034         a KeySet indicating which keys to intercept, or KEYSET_ALL_KEYS.
1035         @param : mask
1036         a ControllerEventMask filtering the intercepted key events. 
1037         @param : type
1038         an EventType mask that may created by ORing event types together.
1039         """
1040         func = self.get_dbus_method("deregisterKeystrokeListener")
1041         return func(*args, **kwargs)
1042     
1043     def generateKeyboardEvent(self, *args, **kwargs):
1044         """
1045         Synthesize a keyboard event. 
1046         @param : keycode
1047         a long integer indicating the keycode of the keypress to be synthesized.
1048         @param : keystring
1049         an optional UTF-8 string indicating a complex keyboard input
1050         event. 
1051         @param : type
1052         a KeySynthType indicating the type of event(s) to be synthesized:
1053         a key press, release, press-release pair, or a complex input
1054         string (for instance from an internationalized or complex text
1055         input method, or a composed character).
1056         """
1057         func = self.get_dbus_method("generateKeyboardEvent")
1058         return func(*args, **kwargs)
1059     
1060     def generateMouseEvent(self, *args, **kwargs):
1061         """
1062         Synthesize a mouse event. 
1063         @param : x
1064         a long integer indicating the screen x coord for the mouse event.
1065         @param : y
1066         a long integer indicating the screen y coord for the mouse event.
1067         @param : eventName
1068         a string indicating the type of mouse event, e.g. "button1up"
1069         """
1070         func = self.get_dbus_method("generateMouseEvent")
1071         return func(*args, **kwargs)
1072     
1073     def notifyListenersAsync(self, *args, **kwargs):
1074         """
1075         Notify the Registry instance that a device event has taken place
1076         in an asynchronous manner. This is the method used by accessibility
1077         bridges to forward "toolkit dependent" device events to the Registry
1078         from the application's process space. If the event in question
1079         is potentially pre-emptible. notifyListenersSync should be used
1080         instead.
1081         """
1082         func = self.get_dbus_method("notifyListenersAsync")
1083         return func(*args, **kwargs)
1084     
1085     def notifyListenersSync(self, *args, **kwargs):
1086         """
1087         Notify the Registry instance that a device event has taken place,
1088         and allow pre-emptive listeners the opportunity to 'consume'
1089         the event and thus prevent its further issuance/forwarding. This
1090         is the method used by accessibility bridges to forward "toolkit
1091         dependent" device events to the Registry from the application's
1092         process space.
1093         @return True if the event was consumed by a (pre-emptive) listener,
1094         False if not (in which case the device event will be forwarded
1095         as normal to any application which would normally receive it,
1096         e.g. the currently active application in the case of mouse or
1097         keyboard events).
1098         """
1099         func = self.get_dbus_method("notifyListenersSync")
1100         return func(*args, **kwargs)
1101     
1102     def registerDeviceEventListener(self, *args, **kwargs):
1103         """
1104         Register to intercept events, and either pass them on or consume
1105         them. To listen to keyboard events use registerKeystrokeListener
1106         instead. 
1107         @param : listener
1108         a DeviceEventListener which will intercept events. 
1109         @param : typeseq
1110         an EventTypeSeq indicating which event types to listen for. 
1111         @return True if successful, False if not
1112         """
1113         func = self.get_dbus_method("registerDeviceEventListener")
1114         return func(*args, **kwargs)
1115     
1116     def registerKeystrokeListener(self, *args, **kwargs):
1117         """
1118         Register to intercept keyboard events, and either pass them on
1119         or consume them.
1120         @param : listener
1121         a DeviceEventListener which will intercept key events. 
1122         @param : keys
1123         a KeySet indicating which keys to intercept, or KEYSET_ALL_KEYS.
1124         @param : mask
1125         a ControllerEventMask filtering the intercepted key events. 
1126         @param : type
1127         a KeyEventTypeSeq that may created by ORing event types together.
1128         @param : mode
1129         an EventListenerMode indicating whether the listener should receive
1130         the events synchronously, potentially consuming them, or just
1131         be notified asynchronously of those events that have been generated.
1132         @return True if the DeviceEventListener was successfully registered
1133         for the requested KeySet, ControllerEventMask, event types, and
1134         EventListenerMode; otherwise returns False.
1135         """
1136         func = self.get_dbus_method("registerKeystrokeListener")
1137         return func(*args, **kwargs)
1138     
1139 class DeviceEventListener(_BaseProxy):
1140     """
1141     This interface should be implemented by AT-SPI clients who wish
1142     to make use of the DeviceEventController to receive device event
1143     notifications. DeviceEvents include keyboard events and mouse
1144     button/motion events.
1145     """
1146     
1147     def notifyEvent(self, *args, **kwargs):
1148         """
1149         Notify an interested DeviceEventListener that a DeviceEvent has
1150         occurred. 
1151         @return True if the recipient/consumer wishes to consume the
1152         event, i.e. prevent it from being delivered to the desktop, False
1153         if the event should continue to be delivered as normal.
1154         """
1155         func = self.get_dbus_method("notifyEvent")
1156         return func(*args, **kwargs)
1157     
1158
1159 class Event(list):
1160     def __new__(cls, type, source, detail1, detail2, any_data):
1161         list.__new__(cls, (type, source, detail1, detail2, any_data))
1162     def __init__(self, type, source, detail1, detail2, any_data):
1163         list.__init__(self, (type, source, detail1, detail2, any_data))
1164     
1165     def _get_type(self):
1166         return self[0]
1167     def _set_type(self, val):
1168         self[0] = val
1169     type = property(fget=_get_type, fset=_set_type)
1170     def _get_source(self):
1171         return self[1]
1172     def _set_source(self, val):
1173         self[1] = val
1174     source = property(fget=_get_source, fset=_set_source)
1175     def _get_detail1(self):
1176         return self[2]
1177     def _set_detail1(self, val):
1178         self[2] = val
1179     detail1 = property(fget=_get_detail1, fset=_set_detail1)
1180     def _get_detail2(self):
1181         return self[3]
1182     def _set_detail2(self, val):
1183         self[3] = val
1184     detail2 = property(fget=_get_detail2, fset=_set_detail2)
1185     def _get_any_data(self):
1186         return self[4]
1187     def _set_any_data(self, val):
1188         self[4] = val
1189     any_data = property(fget=_get_any_data, fset=_set_any_data)
1190
1191
1192 class EventDetails(list):
1193     def __new__(cls, host_application, source_role, source_name, any_data):
1194         list.__new__(cls, (host_application, source_role, source_name, any_data))
1195     def __init__(self, host_application, source_role, source_name, any_data):
1196         list.__init__(self, (host_application, source_role, source_name, any_data))
1197     
1198     def _get_host_application(self):
1199         return self[0]
1200     def _set_host_application(self, val):
1201         self[0] = val
1202     host_application = property(fget=_get_host_application, fset=_set_host_application)
1203     def _get_source_role(self):
1204         return self[1]
1205     def _set_source_role(self, val):
1206         self[1] = val
1207     source_role = property(fget=_get_source_role, fset=_set_source_role)
1208     def _get_source_name(self):
1209         return self[2]
1210     def _set_source_name(self, val):
1211         self[2] = val
1212     source_name = property(fget=_get_source_name, fset=_set_source_name)
1213     def _get_any_data(self):
1214         return self[3]
1215     def _set_any_data(self, val):
1216         self[3] = val
1217     any_data = property(fget=_get_any_data, fset=_set_any_data)
1218
1219 class EventListener(_BaseProxy):
1220     """
1221     A generic interface implemented by objects for the receipt of
1222     event notifications. EventListener is the interface from which
1223     Accessibility::Registry is derived, and via which clients of
1224     the Registry receive notification of changes to an application's
1225     user interface and content.
1226     """
1227     
1228     def notifyEvent(self, *args, **kwargs):
1229         """
1230         Synchronously notify an EventListener that an event has occurred,
1231         by passing it an Event struct. 
1232         @param : e
1233         The Event about which the listener is being notified.
1234         """
1235         func = self.get_dbus_method("notifyEvent")
1236         return func(*args, **kwargs)
1237     
1238     def unImplemented2_(self, *args, **kwargs):
1239         func = self.get_dbus_method("unImplemented2_")
1240         return func(*args, **kwargs)
1241     
1242     def unImplemented3_(self, *args, **kwargs):
1243         func = self.get_dbus_method("unImplemented3_")
1244         return func(*args, **kwargs)
1245     
1246     def unImplemented4_(self, *args, **kwargs):
1247         func = self.get_dbus_method("unImplemented4_")
1248         return func(*args, **kwargs)
1249     
1250     def unImplemented_(self, *args, **kwargs):
1251         func = self.get_dbus_method("unImplemented_")
1252         return func(*args, **kwargs)
1253
1254
1255 class EventListenerMode(list):
1256     def __new__(cls, synchronous, preemptive, global_):
1257         list.__new__(cls, (synchronous, preemptive, global_))
1258     def __init__(self, synchronous, preemptive, global_):
1259         list.__init__(self, (synchronous, preemptive, global_))
1260     
1261     def _get_synchronous(self):
1262         return self[0]
1263     def _set_synchronous(self, val):
1264         self[0] = val
1265     synchronous = property(fget=_get_synchronous, fset=_set_synchronous)
1266     def _get_preemptive(self):
1267         return self[1]
1268     def _set_preemptive(self, val):
1269         self[1] = val
1270     preemptive = property(fget=_get_preemptive, fset=_set_preemptive)
1271     def _get_global_(self):
1272         return self[2]
1273     def _set_global_(self, val):
1274         self[2] = val
1275     global_ = property(fget=_get_global_, fset=_set_global_)
1276
1277
1278 class EventType(_Enum):
1279     _enum_lookup = {
1280         0:'KEY_PRESSED_EVENT',
1281         1:'KEY_RELEASED_EVENT',
1282         2:'BUTTON_PRESSED_EVENT',
1283         3:'BUTTON_RELEASED_EVENT',
1284     }
1285
1286
1287
1288     
1289
1290
1291 class KeyDefinition(list):
1292     def __new__(cls, keycode, keysym, keystring, unused):
1293         list.__new__(cls, (keycode, keysym, keystring, unused))
1294     def __init__(self, keycode, keysym, keystring, unused):
1295         list.__init__(self, (keycode, keysym, keystring, unused))
1296     
1297     def _get_keycode(self):
1298         return self[0]
1299     def _set_keycode(self, val):
1300         self[0] = val
1301     keycode = property(fget=_get_keycode, fset=_set_keycode)
1302     def _get_keysym(self):
1303         return self[1]
1304     def _set_keysym(self, val):
1305         self[1] = val
1306     keysym = property(fget=_get_keysym, fset=_set_keysym)
1307     def _get_keystring(self):
1308         return self[2]
1309     def _set_keystring(self, val):
1310         self[2] = val
1311     keystring = property(fget=_get_keystring, fset=_set_keystring)
1312     def _get_unused(self):
1313         return self[3]
1314     def _set_unused(self, val):
1315         self[3] = val
1316     unused = property(fget=_get_unused, fset=_set_unused)
1317
1318 class KeyEventType(_Enum):
1319     _enum_lookup = {
1320         0:'KEY_PRESSED',
1321         1:'KEY_RELEASED',
1322     }
1323
1324 class KeySynthType(_Enum):
1325     _enum_lookup = {
1326         0:'KEY_PRESS',
1327         1:'KEY_RELEASE',
1328         2:'KEY_PRESSRELEASE',
1329         3:'KEY_SYM',
1330         4:'KEY_STRING',
1331     }
1332
1333
1334
1335 class ModifierType(_Enum):
1336     _enum_lookup = {
1337         0:'MODIFIER_SHIFT',
1338         1:'MODIFIER_SHIFTLOCK',
1339         2:'MODIFIER_CONTROL',
1340         3:'MODIFIER_ALT',
1341         4:'MODIFIER_META',
1342         5:'MODIFIER_META2',
1343         6:'MODIFIER_META3',
1344         7:'MODIFIER_NUMLOCK',
1345     }
1346
1347 class Registry(EventListener):
1348     """
1349     The Registry is a service through which applications providing
1350     accessibility services (servers) can rendezvous with consumers
1351     of those services (Assistive Technologies). The Registry is the
1352     first "port of call" for accessible applications and for assistive
1353     technologies wishing to query and interact with those applications.
1354     The Registry service provides four basic functions to Assistive
1355     Technology (AT) clients: 
1356     it provides a list of the applications who have registered with
1357     the AT-SPI framework, thereby announcing their participation
1358     in the AT-SPI framework; 
1359     it allows AT clients to register for notification of changes
1360     in application state (at-spi Events); 
1361     it dispatches/relays said events from participating applications
1362     to the registered listeners; 
1363     it gives access to system device events via the associated DeviceEventController
1364     interface.
1365     From the point of view of accessible applications (i.e. AT-SPI
1366     service producers), the Registry is primarily a registration
1367     and event delivery service. Applications normally only call the
1368     registerApplication and deregisterApplication Registry methods,
1369     and its inherited EventListener::notifyEvent method.
1370     The Registry normally lives in its own process space; communication
1371     via Registry and both application services and AT clients takes
1372     place via IPC. A process space diagram illustrating the relationship
1373     between applications, Registry, and AT is shown below.
1374     """
1375     
1376     def deregisterApplication(self, *args, **kwargs):
1377         """
1378         De-register an application previously registered with the broker.
1379         deregisterApplication: 
1380         @param : app
1381         a reference to the Application to be deregistered.
1382         """
1383         func = self.get_dbus_method("deregisterApplication")
1384         return func(*args, **kwargs)
1385     
1386     def deregisterGlobalEventListener(self, *args, **kwargs):
1387         """
1388         deregisterGlobalEventListener: 
1389         @param : listener
1390         the requesting EventListener 
1391         @param : eventName
1392         a string indicating the type of events
1393         Request that a previously registered client stop receiving global
1394         notifications for events of a certain type.
1395         """
1396         func = self.get_dbus_method("deregisterGlobalEventListener")
1397         return func(*args, **kwargs)
1398     
1399     def deregisterGlobalEventListenerAll(self, *args, **kwargs):
1400         """
1401         deregisterGlobalEventListenerAll: 
1402         @param : listener
1403         the requesting EventListener
1404         Request that a previously registered client stop receiving global
1405         notifications for all events for which it was registered.
1406         """
1407         func = self.get_dbus_method("deregisterGlobalEventListenerAll")
1408         return func(*args, **kwargs)
1409     
1410     def getDesktop(self, *args, **kwargs):
1411         """
1412         getDesktop: 
1413         : the index of the requested Desktop.
1414         Get the nth accessible desktop.
1415         @return a reference to the requested Desktop.
1416         """
1417         func = self.get_dbus_method("getDesktop")
1418         return func(*args, **kwargs)
1419     
1420     def getDesktopCount(self, *args, **kwargs):
1421         """
1422         event types: "Window" "Desktop" "Window:Create" "Window:Destroy"
1423         "Window:Iconify" "Window:Restore" "Window:Fullscreen" "Window:Resize"
1424         "Desktop:Create" "Desktop:Destroy" "Desktop:Focus" "Desktop:Defocus"
1425         "Desktop:Reorder" "Focus" "GtkWidget:show" "GObject:notify:<propertyname>"
1426         ( not sure we should allow these last 2 forms, since they are
1427         toolkit-specific, but they're powerful ) getDesktopCount:
1428         Get the current number of desktops. 
1429         @return a short integer indicating the current number of Desktops.
1430         """
1431         func = self.get_dbus_method("getDesktopCount")
1432         return func(*args, **kwargs)
1433     
1434     def getDesktopList(self, *args, **kwargs):
1435         """
1436         Get a list of accessible desktops.
1437         @return : a sequence containing references to the Desktops.
1438         """
1439         func = self.get_dbus_method("getDesktopList")
1440         return func(*args, **kwargs)
1441     
1442     def getDeviceEventController(self, *args, **kwargs):
1443         """
1444         Obtain an object which can be used to request device event notifications.
1445         @return : an object implementing DeviceEventController
1446         """
1447         func = self.get_dbus_method("getDeviceEventController")
1448         return func(*args, **kwargs)
1449     
1450     def registerApplication(self, *args, **kwargs):
1451         """
1452         Register a new application with the accessibility broker. 
1453         @param : app
1454         a reference to the requesting Application
1455         """
1456         func = self.get_dbus_method("registerApplication")
1457         return func(*args, **kwargs)
1458     
1459     def registerGlobalEventListener(self, *args, **kwargs):
1460         """
1461         Register a client's interest in (all) application events of a
1462         certain type. 
1463         @param : listener
1464         a reference to the requesting EventListener. 
1465         @param : eventName
1466         a string which indicates the type of events about which the client
1467         desires notification.
1468         """
1469         func = self.get_dbus_method("registerGlobalEventListener")
1470         return func(*args, **kwargs)
1471
1472     
1473
1474
1475
1476
1477
1478
1479
1480 class Table(_BaseProxy):
1481     """
1482     An interface used by containers whose contained data is arranged
1483     in a "tabular" (i.e. row-column) fashion. Tables may resemble
1484     a two-dimensional grid, as in a spreadsheet, or may feature objects
1485     which span multiple rows and/or columns, but whose bounds are
1486     aligned on a row/column matrix. Thus, the Table interface may
1487     be used to represent "spreadsheets" as well as "frames".
1488     Objects within tables are children of the Table instance, and
1489     they may be referenced either via a child index or via a row/column
1490     pair. Their role may be ROLE_TABLE_CELL, but table 'cells' may
1491     have other roles as well. These 'cells' may implement other interfaces,
1492     such as Text, Action, Image, and Component, and should do so
1493     as appropriate to their onscreen representation and/or behavior.
1494     """
1495     
1496     def addColumnSelection(self, *args, **kwargs):
1497         """
1498         Select the specified column, adding it to the current column
1499         selection, if the table's selection model permits it.
1500         @param : column
1501         @return True if the specified column was successfully selected,
1502         False if not.
1503         """
1504         func = self.get_dbus_method("addColumnSelection")
1505         return func(*args, **kwargs)
1506     
1507     def addRowSelection(self, *args, **kwargs):
1508         """
1509         Select the specified row, adding it to the current row selection,
1510         if the table's selection model permits it.
1511         @param : row
1512         @return True if the specified row was successfully selected,
1513         False if not.
1514         """
1515         func = self.get_dbus_method("addRowSelection")
1516         return func(*args, **kwargs)
1517     
1518     def getAccessibleAt(self, *args, **kwargs):
1519         """
1520         Get the table cell at the specified row and column indices. 
1521         @param : row
1522         the specified table row, zero-indexed. 
1523         @param : column
1524         the specified table column, zero-indexed.
1525         @return an Accessible object representing the specified table
1526         cell.
1527         """
1528         func = self.get_dbus_method("getAccessibleAt")
1529         return func(*args, **kwargs)
1530     
1531     def getColumnAtIndex(self, *args, **kwargs):
1532         """
1533         Get the table column index occupied by the child at a particular
1534         1-D child index.
1535         @param : index
1536         the specified child index, zero-indexed.
1537         @return a long integer indicating the first column spanned by
1538         the child of a table, at the specified 1-D (zero-offset) index.
1539         """
1540         func = self.get_dbus_method("getColumnAtIndex")
1541         return func(*args, **kwargs)
1542     
1543     def getColumnDescription(self, *args, **kwargs):
1544         """
1545         Get a text description of a particular table column. This differs
1546         from AccessibleTable_getColumnHeader, which returns an Accessible.
1547         @param : column
1548         the specified table column, zero-indexed.
1549         @return a UTF-8 string describing the specified table column,
1550         if available.
1551         """
1552         func = self.get_dbus_method("getColumnDescription")
1553         return func(*args, **kwargs)
1554     
1555     def getColumnExtentAt(self, *args, **kwargs):
1556         """
1557         Get the number of columns spanned by the table cell at the specific
1558         row and column. (some tables can have cells which span multiple
1559         rows and/or columns).
1560         @param : row
1561         the specified table row, zero-indexed. 
1562         @param : column
1563         the specified table column, zero-indexed.
1564         @return a long integer indicating the number of columns spanned
1565         by the specified cell.
1566         """
1567         func = self.get_dbus_method("getColumnExtentAt")
1568         return func(*args, **kwargs)
1569     
1570     def getColumnHeader(self, *args, **kwargs):
1571         """
1572         Get the header associated with a table column, if available,
1573         as an instance of Accessible. This differs from getColumnDescription,
1574         which returns a string.
1575         @param : column
1576         the specified table column, zero-indexed.
1577         @return an Accessible representatin of the specified table column,
1578         if available.
1579         """
1580         func = self.get_dbus_method("getColumnHeader")
1581         return func(*args, **kwargs)
1582     
1583     def getIndexAt(self, *args, **kwargs):
1584         """
1585         Get the 1-D child index corresponding to the specified 2-D row
1586         and column indices. 
1587         @param : row
1588         the specified table row, zero-indexed. 
1589         @param : column
1590         the specified table column, zero-indexed.
1591         @return a long integer which serves as the index of a specified
1592         cell in the table, in a form usable by Accessible::getChildAtIndex.
1593         """
1594         func = self.get_dbus_method("getIndexAt")
1595         return func(*args, **kwargs)
1596     
1597     def getRowAtIndex(self, *args, **kwargs):
1598         """
1599         Get the table row index occupied by the child at a particular
1600         1-D child index.
1601         @param : index
1602         the specified child index, zero-indexed.
1603         @return a long integer indicating the first row spanned by the
1604         child of a table, at the specified 1-D (zero-offset) index.
1605         """
1606         func = self.get_dbus_method("getRowAtIndex")
1607         return func(*args, **kwargs)
1608     
1609     def getRowColumnExtentsAtIndex(self, *args, **kwargs):
1610         """
1611         Given a child index, determine the row and column indices and
1612         extents, and whether the cell is currently selected. If the child
1613         at index is not a cell (for instance, if it is a summary, caption,
1614         etc.), False is returned.
1615         @param : index
1616         the index of the Table child whose row/column extents are requested.
1617         @param : row
1618         back-filled with the first table row associated with the cell
1619         with child index index. 
1620         @param : col
1621         back-filled with the first table column associated with the cell
1622         with child index index. 
1623         @param : row_extents
1624         back-filled with the number of table rows across which child
1625         i extends. 
1626         @param : col_extents
1627         back-filled with the number of table columns across which child
1628         i extends. 
1629         @param : is_selected
1630         a boolean which is back-filled with True if the child at index
1631         i corresponds to a selected table cell, False otherwise.
1632         Example: If the Table child at index '6' extends across columns
1633         5 and 6 of row 2 of a Table instance, and is currently selected,
1634         then retval=table::getRowColumnExtentsAtIndex(6,row,col,
1635         row_extents,
1636         col_extents,
1637         is_selected);
1638          will return True, and after the call row, col, row_extents,
1639         col_extents, and is_selected will contain 2, 5, 1, 2, and True,
1640         respectively.
1641         @return True if the index is associated with a valid table cell,
1642         False if the index does not correspond to a cell. If False is
1643         returned, the values of the out parameters are undefined.
1644         """
1645         func = self.get_dbus_method("getRowColumnExtentsAtIndex")
1646         return func(*args, **kwargs)
1647     
1648     def getRowDescription(self, *args, **kwargs):
1649         """
1650         Get a text description of a particular table row. This differs
1651         from AccessibleTable_getRowHeader, which returns an Accessible.
1652         @param : row
1653         the specified table row, zero-indexed.
1654         @return a UTF-8 string describing the specified table row, if
1655         available.
1656         """
1657         func = self.get_dbus_method("getRowDescription")
1658         return func(*args, **kwargs)
1659     
1660     def getRowExtentAt(self, *args, **kwargs):
1661         """
1662         Get the number of rows spanned by the table cell at the specific
1663         row and column. (some tables can have cells which span multiple
1664         rows and/or columns).
1665         @param : row
1666         the specified table row, zero-indexed. 
1667         @param : column
1668         the specified table column, zero-indexed.
1669         @return a long integer indicating the number of rows spanned
1670         by the specified cell.
1671         """
1672         func = self.get_dbus_method("getRowExtentAt")
1673         return func(*args, **kwargs)
1674     
1675     def getRowHeader(self, *args, **kwargs):
1676         """
1677         Get the header associated with a table row, if available. This
1678         differs from getRowDescription, which returns a string.
1679         @param : row
1680         the specified table row, zero-indexed.
1681         @return an Accessible representatin of the specified table row,
1682         if available.
1683         """
1684         func = self.get_dbus_method("getRowHeader")
1685         return func(*args, **kwargs)
1686     
1687     def getSelectedColumns(self, *args, **kwargs):
1688         """
1689         Obtain the indices of all columns which are currently selected.
1690         @return a sequence of integers comprising the indices of columns
1691         currently selected.
1692         """
1693         func = self.get_dbus_method("getSelectedColumns")
1694         return func(*args, **kwargs)
1695     
1696     def getSelectedRows(self, *args, **kwargs):
1697         """
1698         Obtain the indices of all rows which are currently selected.
1699         @return a sequence of integers comprising the indices of rows
1700         currently selected.
1701         """
1702         func = self.get_dbus_method("getSelectedRows")
1703         return func(*args, **kwargs)
1704     
1705     def isColumnSelected(self, *args, **kwargs):
1706         """
1707         Determine whether a table column is selected. 
1708         @param : column
1709         the column being queried.
1710         @return True if the specified column is currently selected, False
1711         if not.
1712         """
1713         func = self.get_dbus_method("isColumnSelected")
1714         return func(*args, **kwargs)
1715     
1716     def isRowSelected(self, *args, **kwargs):
1717         """
1718         Determine whether a table row is selected. 
1719         @param : row
1720         the row being queried.
1721         @return True if the specified row is currently selected, False
1722         if not.
1723         """
1724         func = self.get_dbus_method("isRowSelected")
1725         return func(*args, **kwargs)
1726     
1727     def isSelected(self, *args, **kwargs):
1728         """
1729         Determine whether the cell at a specific row and column is selected.
1730         @param : row
1731         a row occupied by the cell whose state is being queried. 
1732         @param : column
1733         a column occupied by the cell whose state is being queried.
1734         @return True if the specified cell is currently selected, False
1735         if not.
1736         """
1737         func = self.get_dbus_method("isSelected")
1738         return func(*args, **kwargs)
1739     
1740     def removeColumnSelection(self, *args, **kwargs):
1741         """
1742         Remove the specified column from current column selection, if
1743         the table's selection model permits it.
1744         @param : column
1745         @return True if the specified column was successfully de-selected,
1746         False if not.
1747         """
1748         func = self.get_dbus_method("removeColumnSelection")
1749         return func(*args, **kwargs)
1750     
1751     def removeRowSelection(self, *args, **kwargs):
1752         """
1753         Remove the specified row from current row selection, if the table's
1754         selection model permits it.
1755         @param : row
1756         @return True if the specified row was successfully de-selected,
1757         False if not.
1758         """
1759         func = self.get_dbus_method("removeRowSelection")
1760         return func(*args, **kwargs)
1761     
1762     def unImplemented(self, *args, **kwargs):
1763         func = self.get_dbus_method("unImplemented")
1764         return func(*args, **kwargs)
1765     
1766     def unImplemented2(self, *args, **kwargs):
1767         func = self.get_dbus_method("unImplemented2")
1768         return func(*args, **kwargs)
1769     
1770     def unImplemented3(self, *args, **kwargs):
1771         func = self.get_dbus_method("unImplemented3")
1772         return func(*args, **kwargs)
1773     
1774     def unImplemented4(self, *args, **kwargs):
1775         func = self.get_dbus_method("unImplemented4")
1776         return func(*args, **kwargs)
1777     
1778     def unImplemented5(self, *args, **kwargs):
1779         func = self.get_dbus_method("unImplemented5")
1780         return func(*args, **kwargs)
1781     
1782     def unImplemented6(self, *args, **kwargs):
1783         func = self.get_dbus_method("unImplemented6")
1784         return func(*args, **kwargs)
1785     
1786     def unImplemented7(self, *args, **kwargs):
1787         func = self.get_dbus_method("unImplemented7")
1788         return func(*args, **kwargs)
1789     
1790     def get_caption(self):
1791         self._pgetter(self._dbus_interface, "caption")
1792     def set_caption(self, value):
1793         self._psetter(self._dbus_interface, "caption", value)
1794     _captionDoc = \
1795         """
1796         An Accessible which represents of a caption for a Table.
1797         """
1798     caption = property(fget=get_caption, fset=set_caption, doc=_captionDoc)
1799     
1800     def get_nColumns(self):
1801         self._pgetter(self._dbus_interface, "nColumns")
1802     def set_nColumns(self, value):
1803         self._psetter(self._dbus_interface, "nColumns", value)
1804     _nColumnsDoc = \
1805         """
1806         The total number of columns in this table (including empty columns),
1807         exclusive of columns which are programmatically hidden. Columns
1808         which are scrolled out of view or clipped by the current viewport
1809         are included.
1810         """
1811     nColumns = property(fget=get_nColumns, fset=set_nColumns, doc=_nColumnsDoc)
1812     
1813     def get_nRows(self):
1814         self._pgetter(self._dbus_interface, "nRows")
1815     def set_nRows(self, value):
1816         self._psetter(self._dbus_interface, "nRows", value)
1817     _nRowsDoc = \
1818         """
1819         The total number of rows in this table (including empty rows),
1820         exclusive of any rows which are programmatically hidden. Rows
1821         which are merely scrolled out of view are included.
1822         """
1823     nRows = property(fget=get_nRows, fset=set_nRows, doc=_nRowsDoc)
1824     
1825     def get_nSelectedColumns(self):
1826         self._pgetter(self._dbus_interface, "nSelectedColumns")
1827     def set_nSelectedColumns(self, value):
1828         self._psetter(self._dbus_interface, "nSelectedColumns", value)
1829     _nSelectedColumnsDoc = \
1830         """
1831         The number of columns currently selected. A selected column is
1832         one in which all included cells are selected.
1833         """
1834     nSelectedColumns = property(fget=get_nSelectedColumns, fset=set_nSelectedColumns, doc=_nSelectedColumnsDoc)
1835     
1836     def get_nSelectedRows(self):
1837         self._pgetter(self._dbus_interface, "nSelectedRows")
1838     def set_nSelectedRows(self, value):
1839         self._psetter(self._dbus_interface, "nSelectedRows", value)
1840     _nSelectedRowsDoc = \
1841         """
1842         The number of rows currently selected. A selected row is one
1843         in which all included cells are selected.
1844         """
1845     nSelectedRows = property(fget=get_nSelectedRows, fset=set_nSelectedRows, doc=_nSelectedRowsDoc)
1846     
1847     def get_summary(self):
1848         self._pgetter(self._dbus_interface, "summary")
1849     def set_summary(self, value):
1850         self._psetter(self._dbus_interface, "summary", value)
1851     _summaryDoc = \
1852         """
1853         An accessible object which summarizes the contents of a Table.
1854         This object is frequently itself a Table instance, albeit a simplified
1855         one.
1856         """
1857     summary = property(fget=get_summary, fset=set_summary, doc=_summaryDoc)
1858
1859
1860
1861
1862 BUTTON_PRESSED_EVENT = EventType(2)
1863
1864 BUTTON_RELEASED_EVENT = EventType(3)
1865
1866 KEY_PRESS = KeySynthType(0)
1867
1868 KEY_PRESSED = KeyEventType(0)
1869
1870 KEY_PRESSED_EVENT = EventType(0)
1871
1872 KEY_PRESSRELEASE = KeySynthType(2)
1873
1874 KEY_RELEASE = KeySynthType(1)
1875
1876 KEY_RELEASED = KeyEventType(1)
1877
1878 KEY_RELEASED_EVENT = EventType(1)
1879
1880 KEY_STRING = KeySynthType(4)
1881
1882 KEY_SYM = KeySynthType(3)
1883
1884
1885 MODIFIER_ALT = ModifierType(3)
1886
1887 MODIFIER_CONTROL = ModifierType(2)
1888
1889 MODIFIER_META = ModifierType(4)
1890
1891 MODIFIER_META2 = ModifierType(5)
1892
1893 MODIFIER_META3 = ModifierType(6)
1894
1895 MODIFIER_NUMLOCK = ModifierType(7)
1896
1897 MODIFIER_SHIFT = ModifierType(0)
1898
1899 MODIFIER_SHIFTLOCK = ModifierType(1)
1900