[orca] Fix for bgo#621020 - Fix DBus interface to GNOME Shell Magnifier (GNOME Shell 2.31.2).



commit 178103bb8ea399d6d3f78295d1477ca70311ca45
Author: Joseph Scheuhammer <clown utoronto ca>
Date:   Tue Jun 8 16:32:49 2010 -0400

    Fix for bgo#621020 - Fix DBus interface to GNOME Shell Magnifier (GNOME Shell 2.31.2).

 src/orca/gsmag.py |  277 ++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 223 insertions(+), 54 deletions(-)
---
diff --git a/src/orca/gsmag.py b/src/orca/gsmag.py
index 0059376..2f344ee 100644
--- a/src/orca/gsmag.py
+++ b/src/orca/gsmag.py
@@ -2,6 +2,8 @@
 #
 # Copyright 2009 Sun Microsystems Inc.
 # Copyright 2010 Willie Walker
+#  * Contributor: Willie Walker <walker willie gmail com>
+#  * Contributor: Joseph Scheuhammer <clown utoronto ca>
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Library General Public
@@ -30,18 +32,29 @@ __license__   = "LGPL"
 
 import dbus
 _bus = dbus.SessionBus()
-_proxy_obj = _bus.get_object("org.freedesktop.Magnifier",
-                             "/org/freedesktop/Magnifier")
-_magnifier = dbus.Interface(_proxy_obj, "org.freedesktop.Magnifier")
+_proxy_obj = _bus.get_object("org.gnome.Magnifier",
+                             "/org/gnome/Magnifier")
+_magnifier = dbus.Interface(_proxy_obj, "org.gnome.Magnifier")
 _zoomer = None
 
 import debug
 import eventsynthesizer
 import settings
 import speech
+import orca_state
+import gconf
 
 from orca_i18n import _
 
+# Some GConf settings that gs-mag uses
+#
+A11Y_MAG_PREFS_DIR  = "/desktop/gnome/accessibility/magnifier"
+MOUSE_MODE_KEY      = A11Y_MAG_PREFS_DIR + "/mouse_tracking"
+GS_MAG_NONE         = 0
+GS_MAG_CENTERED     = 1
+GS_MAG_PUSH         = 2
+GS_MAG_PROPORTIONAL = 3
+
 # If True, the magnifier is active
 #
 _isActive = False
@@ -66,6 +79,12 @@ _screen = _display.get_default_screen()
 _screenWidth = _screen.get_width()
 _screenHeight = _screen.get_height()
 
+# If True, this module has been initialized.
+#
+_initialized = False
+_fullScreenCapable = False
+_wasActiveOnInit = False
+
 # The width and height, in unzoomed system coordinates of the rectangle that,
 # when magnified, will fill the viewport of the magnifier - this needs to be
 # sync'd with the magnification factors of the zoom area.
@@ -98,9 +117,7 @@ def _setROICenter(x, y):
     - x: integer in unzoomed system coordinates representing x component
     - y: integer in unzoomed system coordinates representing y component
     """
-    x = max(0, x - (_roiWidth / 2))
-    y = max(0, y - (_roiHeight / 2))
-    _zoomer.setRoi([x, y, _roiWidth, _roiHeight])
+    _zoomer.shiftContentsTo(x, y)
 
 def _setROICursorPush(x, y, width, height, edgeMargin = 0):
     """Nudges the ROI if the caret or control is not visible.
@@ -272,6 +289,15 @@ def updateMouseTracking(newMode):
     global _mouseTracking
     _mouseTracking = newMode
 
+    # Comparing Orca and GS-mag, modes are the same, but different values:
+    # Orca:  centered=0, proportional=1, push=2, none=3
+    # GS-mag: none=0, centered=1, push=2, proportional=3
+    # Use Orca's values as index into following array (hack).
+    #
+    gsMagModes = \
+        [GS_MAG_CENTERED, GS_MAG_PROPORTIONAL, GS_MAG_PUSH, GS_MAG_NONE]
+    gconf.client_get_default().set_int(MOUSE_MODE_KEY, gsMagModes[newMode])
+
 def updatePointerFollowsFocus(enabled):
     """Updates the pointer follows focus setting.
 
@@ -330,6 +356,34 @@ def finishLiveUpdating():
 #                                                                      #
 ########################################################################
 
+def _setScreenPosition(position, left=None, top=None, right=None, bottom=None):
+
+    # full screen is the default.
+    #
+    prefLeft = 0
+    prefTop = 0
+    prefRight = prefLeft + _screenWidth
+    prefBottom = prefTop + _screenHeight
+
+    if position == settings.MAG_ZOOMER_TYPE_TOP_HALF:
+        prefBottom = prefTop + _screenHeight/2
+    elif position == settings.MAG_ZOOMER_TYPE_BOTTOM_HALF:
+        prefTop = _screenHeight/2
+        prefBottom = prefTop + _screenHeight/2
+    elif position == settings.MAG_ZOOMER_TYPE_LEFT_HALF:
+        prefRight = prefLeft + _screenWidth/2
+    elif position == settings.MAG_ZOOMER_TYPE_RIGHT_HALF:
+        prefLeft = _screenWidth/2
+        prefRight = prefLeft + _screenWidth/2
+    elif position == settings.MAG_ZOOMER_TYPE_CUSTOM:
+        prefLeft = left or settings.magZoomerLeft
+        prefTop = top or settings.magZoomerTop
+        prefRight = right or settings.magZoomerRight
+        prefBottom = bottom or settings.magZoomerBottom
+
+    viewPort = [prefLeft, prefTop, prefRight - prefLeft, prefBottom - prefTop]
+    _zoomer.moveResize(viewPort)
+
 def applySettings():
     """Looks at the user settings and applies them to the magnifier."""
     global _mouseTracking
@@ -339,6 +393,9 @@ def applySettings():
     global _pointerFollowsZoomer
     global _pointerFollowsFocus
 
+    __setupMagnifier(settings.magZoomerType)
+    __setupZoomer()
+
     _mouseTracking = settings.magMouseTrackingMode
     _controlTracking = settings.magControlTrackingMode
     _textTracking = settings.magTextTrackingMode
@@ -360,75 +417,115 @@ def hideSystemPointer(hidePointer):
     except:
         debug.printException(debug.LEVEL_FINEST)
 
-def __setupMagnifier(position, left=None, top=None, right=None, bottom=None,
-                     restore=None):
+def __setupMagnifier(position, restore=None):
     """Creates the magnifier in the position specified.
 
     Arguments:
     - position: the position/type of zoomer (full, left half, etc.)
-    - left:     the left edge of the zoomer (only applicable for custom)
-    - top:      the top edge of the zoomer (only applicable for custom)
-    - right:    the right edge of the zoomer (only applicable for custom)
-    - bottom:   the top edge of the zoomer (only applicable for custom)
     - restore:  a dictionary of all of the settings which should be restored
     """
 
-    # [[[WDW - just go full screen for now.]]]
-    #
-    try:
-        _magnifier.clearAllZoomRegions()
-    except:
-        pass
+    global _fullScreenCapable
 
     if not restore:
         restore = {}
 
+    # Find out if we're using composite.
+    #
+    try:
+        _fullScreenCapable = _magnifier.fullScreenCapable()
+    except:
+        debug.printException(debug.LEVEL_WARNING)
+
     # If we are running in full screen mode, try to hide the original cursor
     # (assuming the user wants to). See bug #533095 for more details.
     # Depends upon new functionality in gnome-mag, so just catch the
     # exception if this functionality isn't there.
     #
     hideCursor = restore.get('magHideCursor', settings.magHideCursor)
-    if hideCursor:
+    if hideCursor \
+       and _fullScreenCapable \
+       and position == settings.MAG_ZOOMER_TYPE_FULL_SCREEN:
         hideSystemPointer(True)
     else:
         hideSystemPointer(False)
 
-def __setupZoomer(restore=None):
+    orca_state.zoomerType = position
+    updateTarget = True
+
+    value = restore.get('magCrossHairColor', settings.magCrossHairColor)
+    setMagnifierObjectColor("crosswire-color", value, False)
+
+    enableCrossHair = restore.get('enableMagCrossHair',
+                                  settings.enableMagCrossHair)
+    setMagnifierCrossHair(enableCrossHair, False)
+
+    value = restore.get('enableMagCrossHairClip',
+                        settings.enableMagCrossHairClip)
+    setMagnifierCrossHairClip(value, False)
+
+    orca_state.mouseEnhancementsEnabled = enableCrossHair
+
+def __setupZoomer(restore=None, left=None, top=None, right=None, bottom=None):
     """Creates a zoomer in the magnifier
     Arguments:
     - restore:  a dictionary of all of the settings which should be restored
     """
 
-    # [[[WDW - just go full screen for now.]]]
-    #
     global _zoomer
     global _roiWidth
     global _roiHeight
 
-    if not restore:
-        restore = {}
+    viewWidth = 0
+    viewHeight = 0
+    zoomerType = settings.magZoomerType
+
+    # Assume custom position of zoomer if rectangle coords are passed.
+    # Otherwise, if restore is passed, use its zoomer type and coords.  Default
+    # is full screen.
+    if left and right and bottom and top:
+        zoomerType = settings.MAG_ZOOMER_TYPE_CUSTOM
+    elif restore:
+        zoomerType = restore["magZoomerType"]
+        left = restore["magZoomerLeft"]
+        top = restore["magZoomerTop"]
+        right = restore["magZoomerRight"]
+        bottom = restore["magZoomerBottom"]
+    else:
+        zoomerType = settings.MAG_ZOOMER_TYPE_FULL_SCREEN
+        left = 0
+        right = _screenWidth
+        top = 0
+        bottom = _screenHeight
 
-    _roiWidth = _screenWidth / settings.magZoomFactor
-    _roiHeight = _screenHeight / settings.magZoomFactor
+    viewWidth = right = left
+    viewHeight = bottom - top
+    _roiWidth = viewWidth / settings.magZoomFactor
+    _roiHeight = viewHeight / settings.magZoomFactor
 
     debug.println(debug.LEVEL_ALL,
                   "Magnifier zoomer ROI size desired: width=%d, height=%d)" \
                   % (_roiWidth, _roiHeight))
 
-    zoomerPath = _magnifier.createZoomRegion(
-        settings.magZoomFactor, settings.magZoomFactor,
-	[0, 0, _roiWidth, _roiHeight],
-	[0, 0, _screenWidth, _screenHeight])
+    # If there are zoom regions, use the first one; otherwise create one.
+    #
+    zoomerPaths = _magnifier.getZoomRegions()
+    if len(zoomerPaths) > 0:
+        _zoomer = _bus.get_object('org.gnome.Magnifier', zoomerPaths[0])
+        _zoomer.setMagFactor(settings.magZoomFactor, settings.magZoomFactor)
+        _setScreenPosition(zoomerType, left, top, right, bottom)
+    else:
+        zoomerPath = _magnifier.createZoomRegion(
+            settings.magZoomFactor, settings.magZoomFactor,
+	        [0, 0, _roiWidth, _roiHeight],
+	        [left, right, viewWidth, viewHeight])
+        _zoomer = _bus.get_object('org.gnome.Magnifier', zoomerPath)
+        _magnifier.addZoomRegion(zoomerPath)
     __updateROIDimensions()
-    _magnifier.addZoomRegion(zoomerPath)
-    _zoomer = _bus.get_object('org.freedesktop.Magnifier', zoomerPath)
 
 def __updateROIDimensions():
     """Updates the ROI width, height, and maximum and minimum values.
     """
-    # [[[WDW - full screen for now.]]]
-    #
     global _roiWidth
     global _roiHeight
     global _minROIX
@@ -436,8 +533,9 @@ def __updateROIDimensions():
     global _maxROIX
     global _maxROIY
 
-    _roiWidth = _screenWidth / settings.magZoomFactor
-    _roiHeight = _screenHeight / settings.magZoomFactor
+    roi = _zoomer.getRoi()
+    _roiWidth = roi[2]
+    _roiHeight = roi[3]
 
     _minROIX = _roiWidth / 2
     _minROIY = _roiHeight / 2
@@ -461,11 +559,10 @@ def setupMagnifier(position, left=None, top=None, right=None, bottom=None,
     - bottom:   the top edge of the zoomer (only applicable for custom)
     - restore:  a dictionary of all of the settings that should be restored
     """
-    # [[[WDW - To be implemented - full screen for now]]]
     global _liveUpdatingMagnifier
     _liveUpdatingMagnifier = True
-    __setupMagnifier(position, left, top, right, bottom, restore)
-    __setupZoomer(restore)
+    __setupMagnifier(position, restore)
+    __setupZoomer(restore, left, top, right, bottom)
 
 def setMagnifierCursor(enabled, customEnabled, size, updateScreen=True):
     """Sets the cursor.
@@ -484,31 +581,63 @@ def setMagnifierCrossHair(enabled, updateScreen=True):
 
     Arguments:
     - enabled: Whether or not the cross-hair should be enabled
-    - updateScreen:  Whether or not to update the screen
+    - updateScreen:  Whether or not to update the screen.
     """
-    # [[[WDW - To be implemented]]]
-    pass
+
+    if not _initialized:
+        return
+
+    size = 0
+    if enabled:
+        size = settings.magCrossHairSize
+
+    _magnifier.setCrosswireSize(size)
 
 def setMagnifierCrossHairClip(enabled, updateScreen=True):
     """Sets the cross-hair clip.
 
     Arguments:
     - enabled: Whether or not the cross-hair clip should be enabled
-    - updateScreen:   Whether or not to update the screen
+    - updateScreen:   Whether or not to update the screen (ignored)
     """
-    # [[[WDW - To be implemented]]]
-    pass
+
+    if not _initialized:
+        return
+
+    _magnifier.setCrosswireClip(enabled)
 
 def setMagnifierObjectColor(magProperty, colorSetting, updateScreen=True):
-    """Sets the specified magnifier property to the specified color.
+    """Sets the specified zoomer property to the specified color.
 
     Arguments:
-    - magProperty:  The property to set (as a string)
+    - magProperty:  The property to set (as a string).  Only 'crosswire-color'.
     - colorSetting: The Orca color setting to apply
     - updateScreen:  Whether or not to update the screen
     """
+
+    colorPreference = gtk.gdk.color_parse(colorSetting)
+    # Convert the colorPreference string to something we can use.
+    # The main issue here is that the color preferences are saved
+    # as 4 byte values per color.  We only need 2 bytes, so we
+    # get rid of the bottom 8 bits.  Default 'ff' for alpha.
+    #
+    colorPreference.red   = colorPreference.red   >> 8
+    colorPreference.blue  = colorPreference.blue  >> 8
+    colorPreference.green = colorPreference.green >> 8
+    colorString = "0x%02X%02X%02Xff" \
+                  % (colorPreference.red,
+                     colorPreference.green,
+                     colorPreference.blue)
+
+    # [[[JS - Handle only 'crosswire-color' for now]]]
+    # Shift left 8 bits to put in alpha value.
+    if magProperty == 'crosswire-color':
+        crossWireColor = int(colorString, 16)
+        _magnifier.setCrosswireColor(crossWireColor & 0xffffffff)
+
     # [[[WDW - To be implemented]]]
-    pass
+    else:
+        pass
 
 def setMagnifierObjectSize(magProperty, size, updateScreen=True):
     """Sets the specified magnifier property to the specified size.
@@ -518,8 +647,14 @@ def setMagnifierObjectSize(magProperty, size, updateScreen=True):
     - size:          The size to apply
     - updateScreen:  Whether or not to update the screen
     """
+
+    # [[[JS - Handle only 'crosswire-size' for now]]]
+    if magProperty == 'crosswire-size':
+        _magnifier.setCrosswireSize(size)
+
     # [[[WDW - To be implemented]]]
-    pass
+    else:
+        pass
 
 def setZoomerBrightness(red=0, green=0, blue=0, updateScreen=True):
     """Increases/Decreases the brightness level by the specified
@@ -685,13 +820,47 @@ def isFullScreenCapable():
 ########################################################################
 
 def init():
+    """Initializes the magnifier, bringing the magnifier up on the
+    display.
+
+    Returns True if the initialization procedure was run or False if this
+    module has already been initialized.
+    """
+    global _initialized
     global _isActive
-    setupMagnifier(settings.magZoomerType)
-    applySettings()
-    _magnifier.setActive(True)
-    _isActive = _magnifier.isActive()
+    global _wasActiveOnInit
+
+    if _initialized:
+        return False
+
+    try:
+        _initialized = True
+        _wasActiveOnInit = _magnifier.isActive()
+        applySettings()
+        _magnifier.setActive(True)
+        _isActive = _magnifier.isActive()
+        return True
+
+    except:
+        _initialized = False
+        raise
     
 def shutdown():
+    """Shuts down the magnifier module.
+    Returns True if the shutdown procedure was run or False if this
+    module has not been initialized.
+    """
+
+    global _initialized
     global _isActive
-    _magnifier.setActive(False)
+
+    if not _initialized:
+        return False
+
+    _magnifier.setActive(_wasActiveOnInit)
     _isActive = _magnifier.isActive()
+    if not _isActive:
+        hideSystemPointer(False)
+
+    _initialized = False
+    return True



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