1 #Copyright (C) 2008 Codethink Ltd
2 #copyright: Copyright (c) 2005, 2007 IBM Corporation
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.
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.
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}
20 #authors: Peter Parente, Mark Doffman
24 class DeviceEvent(object):
26 Wraps an AT-SPI device event with a more Pythonic interface. Primarily adds
27 a consume attribute which can be used to cease propagation of a device event.
29 @ivar consume: Should this event be consumed and not allowed to pass on to
30 observers further down the dispatch chain in this process or possibly
32 @type consume: boolean
33 @ivar type: Kind of event, KEY_PRESSED_EVENT or KEY_RELEASED_EVENT
34 @type type: Accessibility.EventType
35 @ivar id: Serial identifier for this key event
37 @ivar hw_code: Hardware scan code for the key
38 @type hw_code: integer
39 @ivar modifiers: Modifiers held at the time of the key event
40 @type modifiers: integer
41 @ivar timestamp: Time at which the event occurred relative to some platform
42 dependent starting point (e.g. XWindows start time)
43 @type timestamp: integer
44 @ivar event_string: String describing the key pressed (e.g. keysym)
45 @type event_string: string
46 @ivar is_text: Is the event representative of text to be inserted (True), or
47 of a control key (False)?
48 @type is_text: boolean
50 def __init__(self, event):
52 Attaches event data to this object.
54 @param event: Event object
55 @type event: Accessibility.DeviceEvent
58 self.type = event.type
60 self.hw_code = event.hw_code
61 self.modifiers = event.modifiers
62 self.timestamp = event.timestamp
63 self.event_string = event.event_string
64 self.is_text = event.is_text
68 Builds a human readable representation of the event.
70 @return: Event description
73 if self.type == constants.KEY_PRESSED_EVENT:
75 elif self.type == constants.KEY_RELEASED_EVENT:
84 \tis_text: %s""" % (kind, self.hw_code, self.event_string, self.modifiers,
85 self.id, self.timestamp, self.is_text)
89 Wraps an AT-SPI event with a more Pythonic interface managing exceptions,
90 the differences in any_data across versions, and the reference counting of
91 accessibles provided with the event.
93 @note: All unmarked attributes of this class should be considered public
94 readable and writable as the class is acting as a record object.
96 @ivar consume: Should this event be consumed and not allowed to pass on to
97 observers further down the dispatch chain in this process?
98 @type consume: boolean
99 @ivar type: The type of the AT-SPI event
100 @type type: L{EventType}
101 @ivar detail1: First AT-SPI event parameter
102 @type detail1: integer
103 @ivar detail2: Second AT-SPI event parameter
104 @type detail2: integer
105 @ivar any_data: Extra AT-SPI data payload
106 @type any_data: object
107 @ivar host_application: Application owning the event source
108 @type host_application: Accessibility.Application
109 @ivar source_name: Name of the event source at the time of event dispatch
110 @type source_name: string
111 @ivar source_role: Role of the event source at the time of event dispatch
112 @type source_role: Accessibility.Role
113 @ivar source: Source of the event
114 @type source: Accessibility.Accessible
116 def __init__(self, event):
118 Extracts information from the provided event. If the event is a "normal"
119 event, pulls the detail1, detail2, any_data, and source values out of the
120 given object and stores it in this object. If the event is a device event,
121 key ID is stored in detail1, scan code is stored in detail2, key name,
122 key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are
123 stored as a 4-tuple in any_data, and source is None (since key events are
126 @param event: Event from an AT-SPI callback
127 @type event: Accessibility.Event or Accessibility.DeviceEvent
129 # always start out assuming no consume
131 self.type = EventType(event.type)
132 self.detail1 = event.detail1
133 self.detail2 = event.detail2
134 # store the event source and increase the reference count since event
135 # sources are borrowed references; the AccessibleMixin automatically
136 # decrements it later
139 except AttributeError:
141 self.source = event.source
143 # process any_data in a at-spi version independent manner
144 details = event.any_data.value()
146 # see if we have a "new" any_data object which is an EventDetails struct
147 self.any_data = details.any_data.value()
149 # any kind of error means we have an "old" any_data object and None of
150 # the extra data so set them to None
151 self.any_data = details
152 self.host_application = None
153 self.source_name = None
154 self.source_role = None
156 # the rest of the data should be here, so retrieve it
157 self.host_application = details.host_application
158 self.source_name = details.source_name
159 self.source_role = details.source_role
161 # if we received an accessible, be sure to increment the ref count
163 except AttributeError:
166 # if we received a host application, be sure to increment the ref count
167 self.host_application.ref()
168 except AttributeError:
173 Builds a human readable representation of the event including event type,
174 parameters, and source info.
176 @return: Event description
179 return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \
180 (self.type, self.detail1, self.detail2, self.any_data,
181 self.source, self.host_application)
183 class EventType(str):
185 Wraps the AT-SPI event type string so its components can be accessed
186 individually as klass (can't use the keyword class), major, minor, and detail
187 (klass:major:minor:detail).
189 @note: All attributes of an instance of this class should be considered
190 public readable as it is acting a a struct.
191 @ivar klass: Most general event type identifier (object, window, mouse, etc.)
193 @ivar major: Second level event type description
195 @ivar minor: Third level event type description
197 @ivar detail: Lowest level event type description
199 @ivar name: Full, unparsed event name as received from AT-SPI
201 @cvar format: Names of the event string components
202 @type format: 4-tuple of string
204 format = ('klass', 'major', 'minor', 'detail')
206 def __init__(self, name):
208 Parses the full AT-SPI event name into its components
209 (klass:major:minor:detail). If the provided event name is an integer
210 instead of a string, then the event is really a device event.
212 @param name: Full AT-SPI event name
214 @raise AttributeError: When the given event name is not a valid string
216 # get rid of any leading and trailing ':' separators
217 self.value = name.strip(':')
218 self.name = self.value # Backward compatability
224 # split type according to delimiters
225 split = self.value.split(':', 3)
226 # loop over all the components
227 for i in xrange(len(split)):
228 # store values of attributes in this object
229 setattr(self, self.format[i], split[i])