1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2005-2007 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Manages the magnifier for orca. [[[TODO: WDW - this is very very |
21 |
1 |
early in development. One might even say it is pre-prototype.]]]""" |
22 |
|
|
23 |
1 |
__id__ = "$Id: mag.py 2076 2007-03-02 23:01:44Z wwalker $" |
24 |
1 |
__version__ = "$Revision: 2076 $" |
25 |
1 |
__date__ = "$Date: 2007-03-02 15:01:44 -0800 (Fri, 02 Mar 2007) $" |
26 |
1 |
__copyright__ = "Copyright (c) 2005-2007 Sun Microsystems Inc." |
27 |
1 |
__license__ = "LGPL" |
28 |
|
|
29 |
1 |
import bonobo |
30 |
1 |
try: |
31 |
|
# This can fail due to gtk not being available. We want to |
32 |
|
# be able to recover from that if possible. The main driver |
33 |
|
# for this is to allow "orca --text-setup" to work even if |
34 |
|
# the desktop is not running. |
35 |
|
# |
36 |
1 |
import gtk |
37 |
0 |
except: |
38 |
0 |
pass |
39 |
1 |
import time |
40 |
|
|
41 |
1 |
import atspi |
42 |
1 |
import debug |
43 |
1 |
import settings |
44 |
|
|
45 |
1 |
_magnifierAvailable = False |
46 |
|
|
47 |
1 |
try: |
48 |
1 |
atspi.ORBit.load_typelib('GNOME_Magnifier') |
49 |
1 |
import GNOME.Magnifier |
50 |
1 |
_magnifierAvailable = True |
51 |
0 |
except: |
52 |
0 |
pass |
53 |
|
|
54 |
1 |
import time |
55 |
|
|
56 |
|
# If True, this module has been initialized. |
57 |
|
# |
58 |
1 |
_initialized = False |
59 |
|
|
60 |
|
# The Magnifier |
61 |
|
# |
62 |
1 |
_magnifier = None |
63 |
|
|
64 |
|
# The width and height, in unzoomed system coordinates of the rectangle that, |
65 |
|
# when magnified, will fill the viewport of the magnifier - this needs to be |
66 |
|
# sync'd with the magnification factors of the zoom area. |
67 |
|
# |
68 |
1 |
_roiWidth = 0 |
69 |
1 |
_roiHeight = 0 |
70 |
|
|
71 |
|
# Minimum values for the center of the ROI |
72 |
|
# |
73 |
1 |
_minROIX = 0 |
74 |
1 |
_maxROIX = 0 |
75 |
1 |
_minROIY = 0 |
76 |
1 |
_maxROIY = 0 |
77 |
|
|
78 |
|
# The current region of interest. |
79 |
|
# |
80 |
1 |
_roi = None |
81 |
|
|
82 |
|
# The area we are magnifying |
83 |
|
# |
84 |
1 |
_sourceDisplayBounds = None |
85 |
|
|
86 |
|
# The area where we are magnifying |
87 |
|
# |
88 |
1 |
_targetDisplayBounds = None |
89 |
|
|
90 |
|
# The ZoomRegion we care about [[[TODO: WDW - we should be more careful about |
91 |
|
# just what we're doing here. The Magnifier allows more than one ZoomRegion |
92 |
|
# and we're just picking up the first one.]]] |
93 |
|
# |
94 |
1 |
_zoomer = None |
95 |
|
|
96 |
|
# The time of the last mouse event. |
97 |
|
# |
98 |
1 |
_lastMouseEventTime = time.time() |
99 |
|
|
100 |
|
# If True, we're using gnome-mag >= 0.13.1 that allows us to control |
101 |
|
# where to draw the cursor and crosswires. |
102 |
|
# |
103 |
1 |
_pollMouseDisabled = False |
104 |
|
|
105 |
1 |
def __setROI(rect): |
106 |
|
"""Sets the region of interest. |
107 |
|
|
108 |
|
Arguments: |
109 |
|
- rect: A GNOME.Magnifier.RectBounds object. |
110 |
|
""" |
111 |
|
|
112 |
0 |
global _roi |
113 |
|
|
114 |
0 |
_roi = rect |
115 |
0 |
_zoomer.setROI(_roi) |
116 |
0 |
_zoomer.markDirty(_roi) # [[[TODO: WDW - for some reason, this seems |
117 |
|
# necessary.]]] |
118 |
1 |
def __setROICenter(x, y): |
119 |
|
"""Centers the region of interest around the given point. |
120 |
|
|
121 |
|
Arguments: |
122 |
|
- x: integer in unzoomed system coordinates representing x component |
123 |
|
- y: integer in unzoomed system coordinates representing y component |
124 |
|
""" |
125 |
|
|
126 |
0 |
if not _initialized: |
127 |
0 |
return |
128 |
|
|
129 |
0 |
if x < _minROIX: |
130 |
0 |
x = _minROIX |
131 |
0 |
elif x > _maxROIX: |
132 |
0 |
x = _maxROIX |
133 |
|
|
134 |
0 |
if y < _minROIY: |
135 |
0 |
y = _minROIY |
136 |
0 |
elif y > _maxROIY: |
137 |
0 |
y = _maxROIY |
138 |
|
|
139 |
0 |
x1 = x - (_roiWidth / 2) |
140 |
0 |
y1 = y - (_roiHeight / 2) |
141 |
|
|
142 |
0 |
x2 = x1 + _roiWidth |
143 |
0 |
y2 = y1 + _roiHeight |
144 |
|
|
145 |
0 |
__setROI(GNOME.Magnifier.RectBounds(x1, y1, x2, y2)) |
146 |
|
|
147 |
1 |
def __setROIPush(x, y): |
148 |
|
"""Nudges the ROI if the pointer bumps into the edge of it. The point |
149 |
|
given is assumed to be the point where the mouse pointer is. |
150 |
|
|
151 |
|
Arguments: |
152 |
|
- x: integer in unzoomed system coordinates representing x component |
153 |
|
- y: integer in unzoomed system coordinates representing y component |
154 |
|
""" |
155 |
|
|
156 |
0 |
needNewROI = False |
157 |
0 |
newROI = GNOME.Magnifier.RectBounds(_roi.x1, _roi.y1, _roi.x2, _roi.y2) |
158 |
0 |
if x < _roi.x1: |
159 |
0 |
needNewROI = True |
160 |
0 |
newROI.x1 = x |
161 |
0 |
newROI.x2 = x + _roiWidth |
162 |
0 |
elif x > _roi.x2: |
163 |
0 |
needNewROI = True |
164 |
0 |
newROI.x2 = x |
165 |
0 |
newROI.x1 = x - _roiWidth |
166 |
0 |
if y < _roi.y1: |
167 |
0 |
needNewROI = True |
168 |
0 |
newROI.y1 = y |
169 |
0 |
newROI.y2 = y + _roiHeight |
170 |
0 |
elif y > _roi.y2: |
171 |
0 |
needNewROI = True |
172 |
0 |
newROI.y2 = y |
173 |
0 |
newROI.y1 = y - _roiHeight |
174 |
|
|
175 |
|
# Well...we'll always update the ROI so the new gnome-mag API |
176 |
|
# will redraw the crosswires for us. |
177 |
|
# |
178 |
|
#if needNewROI: |
179 |
0 |
if True: |
180 |
0 |
__setROI(newROI) |
181 |
|
|
182 |
1 |
def __setROIProportional(x, y): |
183 |
|
"""Positions the ROI proportionally to where the pointer is on the screen. |
184 |
|
|
185 |
|
Arguments: |
186 |
|
- x: integer in unzoomed system coordinates representing x component |
187 |
|
- y: integer in unzoomed system coordinates representing y component |
188 |
|
""" |
189 |
|
|
190 |
0 |
if not _initialized: |
191 |
0 |
return |
192 |
|
|
193 |
0 |
if not _sourceDisplayBounds: |
194 |
0 |
__setROICenter(x, y) |
195 |
|
else: |
196 |
0 |
halfScreenWidth = (_sourceDisplayBounds.x2 \ |
197 |
|
- _sourceDisplayBounds.x1) / 2.0 |
198 |
0 |
halfScreenHeight = (_sourceDisplayBounds.y2 \ |
199 |
|
- _sourceDisplayBounds.y1) / 2.0 |
200 |
|
|
201 |
0 |
proportionX = (halfScreenWidth - x) / halfScreenWidth |
202 |
0 |
proportionY = (halfScreenHeight - y) / halfScreenHeight |
203 |
|
|
204 |
0 |
centerX = x + int(proportionX * _roiWidth / 2.0) |
205 |
0 |
centerY = y + int(proportionY * _roiHeight / 2.0) |
206 |
|
|
207 |
0 |
__setROICenter(centerX, centerY) |
208 |
|
|
209 |
|
# Used for tracking the pointer. |
210 |
|
# |
211 |
1 |
def __onMouseEvent(e): |
212 |
|
""" |
213 |
|
Arguments: |
214 |
|
- e: at-spi event from the at-api registry |
215 |
|
""" |
216 |
|
|
217 |
0 |
global _lastMouseEventTime |
218 |
|
|
219 |
0 |
_lastMouseEventTime = time.time() |
220 |
|
|
221 |
0 |
[x, y] = [e.detail1, e.detail2] |
222 |
|
|
223 |
|
# If True, we're using gnome-mag >= 0.13.1 that allows us to |
224 |
|
# control where to draw the cursor and crosswires. |
225 |
|
# |
226 |
0 |
if _pollMouseDisabled: |
227 |
0 |
_zoomer.setPointerPos(x, y) |
228 |
|
|
229 |
0 |
if settings.magMouseTrackingMode == settings.MAG_MOUSE_TRACKING_MODE_PUSH: |
230 |
0 |
__setROIPush(x, y) |
231 |
0 |
elif settings.magMouseTrackingMode == settings.MAG_MOUSE_TRACKING_MODE_PROPORTIONAL: |
232 |
0 |
__setROIProportional(x, y) |
233 |
0 |
elif settings.magMouseTrackingMode == settings.MAG_MOUSE_TRACKING_MODE_CENTERED: |
234 |
0 |
__setROICenter(x, y) |
235 |
|
|
236 |
1 |
def __getValueText(slot, value): |
237 |
0 |
valueText = "" |
238 |
0 |
if slot == "cursor-hotspot": |
239 |
0 |
valueText = "(%d, %d)" % (value.x, value.y) |
240 |
0 |
elif slot == "source-display-bounds": |
241 |
0 |
valueText = "(%d, %d),(%d, %d)" \ |
242 |
|
% (value.x1, value.y1, value.x2, value.y2) |
243 |
0 |
elif slot == "target-display-bounds": |
244 |
0 |
valueText = "(%d, %d),(%d, %d)" \ |
245 |
|
% (value.x1, value.y1, value.x2, value.y2) |
246 |
0 |
elif slot == "viewport": |
247 |
0 |
valueText = "(%d, %d),(%d, %d)" \ |
248 |
|
% (value.x1, value.y1, value.x2, value.y2) |
249 |
0 |
return valueText |
250 |
|
|
251 |
1 |
def __dumpPropertyBag(obj): |
252 |
0 |
pbag = obj.getProperties() |
253 |
0 |
slots = pbag.getKeys("") |
254 |
0 |
print " Available slots: ", pbag.getKeys("") |
255 |
0 |
for slot in slots: |
256 |
|
# These crash the magnifier since it doesn't know how to marshall |
257 |
|
# them to us. |
258 |
|
# |
259 |
0 |
if slot in ["cursor-set", "smoothing-type"]: |
260 |
0 |
continue |
261 |
0 |
print " About '%s':" % slot |
262 |
0 |
print " Doc Title:", pbag.getDocTitle(slot) |
263 |
0 |
print " Type:", pbag.getType(slot) |
264 |
0 |
value = pbag.getDefault(slot).value() |
265 |
0 |
print " Default value:", value, __getValueText(slot, value) |
266 |
0 |
value = pbag.getValue(slot).value() |
267 |
0 |
print " Current value:", value, __getValueText(slot, value) |
268 |
0 |
print |
269 |
|
|
270 |
1 |
def applySettings(): |
271 |
|
"""Looks at the user settings and applies them to the magnifier.""" |
272 |
|
|
273 |
0 |
global _sourceDisplayBounds |
274 |
0 |
global _targetDisplayBounds |
275 |
0 |
global _zoomer |
276 |
0 |
global _roiWidth |
277 |
0 |
global _roiHeight |
278 |
0 |
global _minROIX |
279 |
0 |
global _minROIY |
280 |
0 |
global _maxROIX |
281 |
0 |
global _maxROIY |
282 |
0 |
global _pollMouseDisabled |
283 |
|
|
284 |
|
######################################################################## |
285 |
|
# # |
286 |
|
# First set up the magnifier properties. # |
287 |
|
# # |
288 |
|
######################################################################## |
289 |
|
|
290 |
0 |
_magnifier.clearAllZoomRegions() |
291 |
|
|
292 |
0 |
try: |
293 |
0 |
_magnifier.TargetDisplay = settings.magTargetDisplay |
294 |
0 |
except: |
295 |
0 |
pass |
296 |
|
|
297 |
0 |
try: |
298 |
0 |
_magnifier.SourceDisplay = settings.magSourceDisplay |
299 |
0 |
except: |
300 |
0 |
pass |
301 |
|
|
302 |
0 |
magnifierPBag = _magnifier.getProperties() |
303 |
|
|
304 |
0 |
try: |
305 |
0 |
tdb = magnifierPBag.getValue("target-display-bounds").value() |
306 |
0 |
magnifierPBag.setValue( |
307 |
|
"target-display-bounds", |
308 |
0 |
atspi.ORBit.CORBA.Any( |
309 |
|
atspi.ORBit.CORBA.TypeCode( |
310 |
|
tdb.__typecode__.repo_id), |
311 |
0 |
GNOME.Magnifier.RectBounds(settings.magZoomerLeft, |
312 |
0 |
settings.magZoomerTop, |
313 |
0 |
settings.magZoomerRight, |
314 |
0 |
settings.magZoomerBottom))) |
315 |
0 |
except: |
316 |
0 |
debug.printException(debug.LEVEL_OFF) |
317 |
|
|
318 |
0 |
if settings.enableMagCursor: |
319 |
0 |
bonobo.pbclient_set_float( |
320 |
|
magnifierPBag, "cursor-scale-factor", 1.0 * settings.magZoomFactor) |
321 |
|
else: |
322 |
0 |
bonobo.pbclient_set_float( |
323 |
|
magnifierPBag, "cursor-scale-factor", 0.0) |
324 |
|
|
325 |
0 |
if settings.enableMagCursorExplicitSize: |
326 |
0 |
bonobo.pbclient_set_long( |
327 |
|
magnifierPBag, "cursor-size", settings.magCursorSize) |
328 |
|
else: |
329 |
0 |
bonobo.pbclient_set_long( |
330 |
|
magnifierPBag, "cursor-size", 0) |
331 |
|
|
332 |
0 |
bonobo.pbclient_set_string(magnifierPBag, "cursor-set", "default") |
333 |
|
|
334 |
|
# Convert the colorPreference string to something we can use. |
335 |
|
# The main issue here is that the color preferences are saved |
336 |
|
# as 4 byte values per color. We only need 2 bytes, so we |
337 |
|
# get rid of the bottom 8 bits. |
338 |
|
# |
339 |
0 |
colorPreference = gtk.gdk.color_parse(settings.magCursorColor) |
340 |
0 |
colorPreference.red = colorPreference.red >> 8 |
341 |
0 |
colorPreference.blue = colorPreference.blue >> 8 |
342 |
0 |
colorPreference.green = colorPreference.green >> 8 |
343 |
0 |
colorString = "0x%02X%02X%02X" \ |
344 |
|
% (colorPreference.red, |
345 |
|
colorPreference.green, |
346 |
|
colorPreference.blue) |
347 |
|
|
348 |
0 |
color = magnifierPBag.getValue("cursor-color") |
349 |
0 |
magnifierPBag.setValue( |
350 |
|
"cursor-color", |
351 |
0 |
atspi.ORBit.CORBA.Any( |
352 |
|
color.typecode(), |
353 |
0 |
long(colorString, 0))) |
354 |
|
|
355 |
0 |
color = magnifierPBag.getValue("crosswire-color") |
356 |
0 |
magnifierPBag.setValue( |
357 |
|
"crosswire-color", |
358 |
0 |
atspi.ORBit.CORBA.Any( |
359 |
|
color.typecode(), |
360 |
0 |
long(colorString, 0))) |
361 |
|
|
362 |
0 |
if settings.enableMagCrossHair: |
363 |
0 |
bonobo.pbclient_set_long( |
364 |
|
magnifierPBag, "crosswire-size", settings.magCrossHairSize) |
365 |
|
else: |
366 |
0 |
bonobo.pbclient_set_long( |
367 |
|
magnifierPBag, "crosswire-size", 0) |
368 |
|
|
369 |
0 |
bonobo.pbclient_set_boolean( |
370 |
|
magnifierPBag, "crosswire-clip", settings.enableMagCrossHairClip) |
371 |
|
|
372 |
|
######################################################################## |
373 |
|
# # |
374 |
|
# Now set up the zoomer properties. # |
375 |
|
# # |
376 |
|
######################################################################## |
377 |
|
|
378 |
0 |
_sourceDisplayBounds = magnifierPBag.getValue( |
379 |
|
"source-display-bounds").value() |
380 |
|
|
381 |
0 |
_targetDisplayBounds = magnifierPBag.getValue( |
382 |
|
"target-display-bounds").value() |
383 |
|
|
384 |
0 |
_zoomer = _magnifier.createZoomRegion( |
385 |
|
settings.magZoomFactor, settings.magZoomFactor, |
386 |
0 |
GNOME.Magnifier.RectBounds(0, |
387 |
0 |
0, |
388 |
0 |
-1, |
389 |
0 |
-1), |
390 |
0 |
GNOME.Magnifier.RectBounds(0, |
391 |
0 |
0, |
392 |
0 |
_targetDisplayBounds.x2 \ |
393 |
|
- _targetDisplayBounds.x1, |
394 |
0 |
_targetDisplayBounds.y2 \ |
395 |
|
- _targetDisplayBounds.y1)) |
396 |
|
|
397 |
0 |
zoomerPBag = _zoomer.getProperties() |
398 |
0 |
bonobo.pbclient_set_boolean(zoomerPBag, "is-managed", True) |
399 |
|
|
400 |
|
# Try to use gnome-mag >= 0.13.1 to allow us to control where to |
401 |
|
# draw the cursor and crosswires. |
402 |
|
# |
403 |
0 |
try: |
404 |
0 |
bonobo.pbclient_set_boolean(zoomerPBag, "poll-mouse", False) |
405 |
0 |
_pollMouseDisabled = True |
406 |
0 |
except: |
407 |
0 |
_pollMouseDisabled = False |
408 |
|
|
409 |
0 |
_zoomer.setMagFactor(settings.magZoomFactor, settings.magZoomFactor) |
410 |
|
|
411 |
0 |
bonobo.pbclient_set_boolean( |
412 |
|
zoomerPBag, "inverse-video", settings.enableMagZoomerColorInversion) |
413 |
|
|
414 |
0 |
if settings.magSmoothingMode == settings.MAG_SMOOTHING_MODE_BILINEAR: |
415 |
0 |
try: |
416 |
0 |
bonobo.pbclient_set_string( |
417 |
|
zoomerPBag, "smoothing-type", "bilinear") |
418 |
0 |
except: |
419 |
0 |
pass |
420 |
|
|
421 |
0 |
viewport = zoomerPBag.getValue("viewport").value() |
422 |
|
|
423 |
0 |
magx = zoomerPBag.getValue("mag-factor-x").value() |
424 |
0 |
magy = zoomerPBag.getValue("mag-factor-y").value() |
425 |
|
|
426 |
0 |
_roiWidth = (viewport.x2 - viewport.x1) / magx |
427 |
0 |
_roiHeight = (viewport.y2 - viewport.y1) / magy |
428 |
|
|
429 |
0 |
_minROIX = _sourceDisplayBounds.x1 + (_roiWidth / 2) |
430 |
0 |
_minROIY = _sourceDisplayBounds.y1 + (_roiHeight / 2) |
431 |
|
|
432 |
0 |
_maxROIX = _sourceDisplayBounds.x2 - (_roiWidth / 2) |
433 |
0 |
_maxROIY = _sourceDisplayBounds.y2 - (_roiHeight / 2) |
434 |
|
|
435 |
0 |
_magnifier.addZoomRegion(_zoomer) |
436 |
|
|
437 |
|
#print "MAGNIFIER PROPERTIES:", _magnifier |
438 |
|
#__dumpPropertyBag(_magnifier) |
439 |
|
#print "ZOOMER PROPERTIES:", _zoomer |
440 |
|
#__dumpPropertyBag(_zoomer) |
441 |
|
|
442 |
1 |
def magnifyAccessible(event, obj, extents=None): |
443 |
|
"""Sets the region of interest to the upper left of the given |
444 |
|
accessible, if it implements the Component interface. Otherwise, |
445 |
|
does nothing. |
446 |
|
|
447 |
|
Arguments: |
448 |
|
- event: the Event that caused this to be called |
449 |
|
- obj: the accessible |
450 |
|
""" |
451 |
|
|
452 |
1732 |
if not _initialized: |
453 |
1732 |
return |
454 |
|
|
455 |
0 |
if extents: |
456 |
0 |
[x, y, width, height] = extents |
457 |
0 |
elif event and (event.type == "object:text-caret-moved") \ |
458 |
|
and obj.text and (obj.text.caretOffset >= 0): |
459 |
0 |
offset = obj.text.caretOffset |
460 |
0 |
[x, y, width, height] = obj.text.getCharacterExtents(offset, |
461 |
0 |
0) # coord type screen |
462 |
0 |
elif obj.extents: |
463 |
0 |
extents = obj.extents |
464 |
0 |
[x, y, width, height] = [extents.x, extents.y, extents.width, extents.height] |
465 |
|
else: |
466 |
0 |
return |
467 |
|
|
468 |
|
# Avoid jerking the display around if the mouse is what ended up causing |
469 |
|
# this event. We guess this by seeing if this request has come in within |
470 |
|
# a close period of time. [[[TODO: WDW - this is a hack and really |
471 |
|
# doesn't belong here. Plus, the delta probably should be adjustable.]]] |
472 |
|
# |
473 |
0 |
currentTime = time.time() |
474 |
0 |
if (currentTime - _lastMouseEventTime) < 0.2: # 200 milliseconds |
475 |
0 |
return |
476 |
|
|
477 |
|
# Determine if the accessible is partially to the left, right, |
478 |
|
# above, or below the current region of interest (ROI). |
479 |
|
# |
480 |
0 |
leftOfROI = x < _roi.x1 |
481 |
0 |
rightOfROI = (x + width) > _roi.x2 |
482 |
0 |
aboveROI = y < _roi.y1 |
483 |
0 |
belowROI = (y + height) > _roi.y2 |
484 |
|
|
485 |
|
# If it is already completely showing, do nothing. |
486 |
|
# |
487 |
0 |
visibleX = not(leftOfROI or rightOfROI) |
488 |
0 |
visibleY = not(aboveROI or belowROI) |
489 |
|
|
490 |
0 |
if visibleX and visibleY: |
491 |
0 |
_zoomer.markDirty(_roi) |
492 |
|
|
493 |
|
# The algorithm is devised to move the ROI as little as possible, yet |
494 |
|
# favor the top left side of the object [[[TODO: WDW - the left/right |
495 |
|
# top/bottom favoring should probably depend upon the locale. Also, |
496 |
|
# I had the notion of including a floating point snap factor between |
497 |
|
# 0.0 and 1.0 that would determine how to position the object in the |
498 |
|
# window relative to the ROI edges. A snap factor of -1 would mean to |
499 |
|
# snap to the closest edge. A snap factor of 0.0 would snap to the |
500 |
|
# left most or top most edge, a snap factor of 1.0 would snap to the |
501 |
|
# right most or bottom most edge. Any number in between would divide |
502 |
|
# the two.]]] |
503 |
|
# |
504 |
0 |
x1 = _roi.x1 |
505 |
0 |
x2 = _roi.x2 |
506 |
0 |
y1 = _roi.y1 |
507 |
0 |
y2 = _roi.y2 |
508 |
|
|
509 |
0 |
if leftOfROI: |
510 |
0 |
x1 = x |
511 |
0 |
x2 = x1 + _roiWidth |
512 |
0 |
elif rightOfROI: |
513 |
0 |
if width > _roiWidth: |
514 |
0 |
x1 = x |
515 |
0 |
x2 = x1 + _roiWidth |
516 |
|
else: |
517 |
0 |
x2 = x + width |
518 |
0 |
x1 = x2 - _roiWidth |
519 |
|
|
520 |
0 |
if aboveROI: |
521 |
0 |
y1 = y |
522 |
0 |
y2 = y1 + _roiHeight |
523 |
0 |
elif belowROI: |
524 |
0 |
if height > _roiHeight: |
525 |
0 |
y1 = y |
526 |
0 |
y2 = y1 + _roiHeight |
527 |
|
else: |
528 |
0 |
y2 = y + height |
529 |
0 |
y1 = y2 - _roiHeight |
530 |
|
|
531 |
0 |
__setROI(GNOME.Magnifier.RectBounds(x1, y1, x2, y2)) |
532 |
|
|
533 |
1 |
def init(): |
534 |
|
"""Initializes the magnifier, bringing the magnifier up on the |
535 |
|
display. |
536 |
|
|
537 |
|
Returns True if the initialization procedure was run or False if this |
538 |
|
module has already been initialized. |
539 |
|
""" |
540 |
|
|
541 |
0 |
global _initialized |
542 |
0 |
global _magnifier |
543 |
|
|
544 |
0 |
if not _magnifierAvailable: |
545 |
0 |
return False |
546 |
|
|
547 |
0 |
if _initialized: |
548 |
0 |
return False |
549 |
|
|
550 |
0 |
_magnifier = bonobo.get_object("OAFIID:GNOME_Magnifier_Magnifier:0.9", |
551 |
0 |
"GNOME/Magnifier/Magnifier") |
552 |
|
|
553 |
0 |
try: |
554 |
0 |
applySettings() |
555 |
0 |
except: |
556 |
0 |
debug.printException(debug.LEVEL_SEVERE) |
557 |
|
|
558 |
0 |
atspi.Registry().registerEventListener(__onMouseEvent, "mouse:abs") |
559 |
|
|
560 |
0 |
_initialized = True |
561 |
|
|
562 |
|
# Zoom to the upper left corner of the display for now. |
563 |
|
# |
564 |
0 |
__setROICenter(0, 0) |
565 |
|
|
566 |
0 |
return True |
567 |
|
|
568 |
1 |
def shutdown(): |
569 |
|
"""Shuts down the magnifier module. |
570 |
|
Returns True if the shutdown procedure was run or False if this |
571 |
|
module has not been initialized. |
572 |
|
""" |
573 |
|
|
574 |
0 |
global _initialized |
575 |
0 |
global _magnifier |
576 |
|
|
577 |
1 |
if not _magnifierAvailable: |
578 |
0 |
return False |
579 |
|
|
580 |
1 |
if not _initialized: |
581 |
1 |
return False |
582 |
|
|
583 |
0 |
atspi.Registry().deregisterEventListener(__onMouseEvent,"mouse:abs") |
584 |
|
|
585 |
0 |
_magnifier.clearAllZoomRegions() |
586 |
0 |
_magnifier.dispose() |
587 |
0 |
_magnifier = None |
588 |
|
|
589 |
0 |
_initialized = False |
590 |
|
|
591 |
0 |
return True |