diff options
Diffstat (limited to 'js/ui/magnifierDBus.js')
-rw-r--r-- | js/ui/magnifierDBus.js | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/js/ui/magnifierDBus.js b/js/ui/magnifierDBus.js new file mode 100644 index 0000000..6f962d1 --- /dev/null +++ b/js/ui/magnifierDBus.js @@ -0,0 +1,351 @@ +// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- +/* exported ShellMagnifier */ + +const Gio = imports.gi.Gio; +const Main = imports.ui.main; + +const { loadInterfaceXML } = imports.misc.fileUtils; + +const MAG_SERVICE_PATH = '/org/gnome/Magnifier'; +const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion'; + +// Subset of gnome-mag's Magnifier dbus interface -- to be expanded. See: +// http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml +const MagnifierIface = loadInterfaceXML('org.gnome.Magnifier'); + +// Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded. See: +// http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml +const ZoomRegionIface = loadInterfaceXML('org.gnome.Magnifier.ZoomRegion'); + +// For making unique ZoomRegion DBus proxy object paths of the form: +// '/org/gnome/Magnifier/ZoomRegion/zoomer0', +// '/org/gnome/Magnifier/ZoomRegion/zoomer1', etc. +let _zoomRegionInstanceCount = 0; + +var ShellMagnifier = class ShellMagnifier { + constructor() { + this._zoomers = {}; + + this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this); + this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH); + } + + /** + * setActive: + * @param {bool} activate: activate or de-activate the magnifier. + */ + setActive(activate) { + Main.magnifier.setActive(activate); + } + + /** + * isActive: + * @returns {bool} Whether the magnifier is active. + */ + isActive() { + return Main.magnifier.isActive(); + } + + /** + * showCursor: + * Show the system mouse pointer. + */ + showCursor() { + Main.magnifier.showSystemCursor(); + } + + /** + * hideCursor: + * Hide the system mouse pointer. + */ + hideCursor() { + Main.magnifier.hideSystemCursor(); + } + + /** + * createZoomRegion: + * Create a new ZoomRegion and return its object path. + * @param {number} xMagFactor: + * The power to set horizontal magnification of the ZoomRegion. + * A value of 1.0 means no magnification. A value of 2.0 doubles + * the size. + * @param {number} yMagFactor: + * The power to set the vertical magnification of the + * ZoomRegion. + * @param {number[]} roi + * Array of integers defining the region of the screen/desktop + * to magnify. The array has the form [left, top, right, bottom]. + * @param {number[]} viewPort + * Array of integers, [left, top, right, bottom] that defines + * the position of the ZoomRegion on screen. + * + * FIXME: The arguments here are redundant, since the width and height of + * the ROI are determined by the viewport and magnification factors. + * We ignore the passed in width and height. + * + * @returns {ZoomRegion} The newly created ZoomRegion. + */ + createZoomRegion(xMagFactor, yMagFactor, roi, viewPort) { + let ROI = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] }; + let viewBox = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] }; + let realZoomRegion = Main.magnifier.createZoomRegion(xMagFactor, yMagFactor, ROI, viewBox); + let objectPath = `${ZOOM_SERVICE_PATH}/zoomer${_zoomRegionInstanceCount}`; + _zoomRegionInstanceCount++; + + let zoomRegionProxy = new ShellMagnifierZoomRegion(objectPath, realZoomRegion); + let proxyAndZoomRegion = {}; + proxyAndZoomRegion.proxy = zoomRegionProxy; + proxyAndZoomRegion.zoomRegion = realZoomRegion; + this._zoomers[objectPath] = proxyAndZoomRegion; + return objectPath; + } + + /** + * addZoomRegion: + * Append the given ZoomRegion to the magnifier's list of ZoomRegions. + * @param {string} zoomerObjectPath: The object path for the zoom + * region proxy. + * @returns {bool} whether the region was added successfully + */ + addZoomRegion(zoomerObjectPath) { + let proxyAndZoomRegion = this._zoomers[zoomerObjectPath]; + if (proxyAndZoomRegion && proxyAndZoomRegion.zoomRegion) { + Main.magnifier.addZoomRegion(proxyAndZoomRegion.zoomRegion); + return true; + } else { + return false; + } + } + + /** + * getZoomRegions: + * Return a list of ZoomRegion object paths for this Magnifier. + * @returns {string[]}: The Magnifier's zoom region list as an array + * of DBus object paths. + */ + getZoomRegions() { + // There may be more ZoomRegions in the magnifier itself than have + // been added through dbus. Make sure all of them are associated with + // an object path and proxy. + let zoomRegions = Main.magnifier.getZoomRegions(); + let objectPaths = []; + let thoseZoomers = this._zoomers; + zoomRegions.forEach(aZoomRegion => { + let found = false; + for (let objectPath in thoseZoomers) { + let proxyAndZoomRegion = thoseZoomers[objectPath]; + if (proxyAndZoomRegion.zoomRegion === aZoomRegion) { + objectPaths.push(objectPath); + found = true; + break; + } + } + if (!found) { + // Got a ZoomRegion with no DBus proxy, make one. + let newPath = `${ZOOM_SERVICE_PATH}/zoomer${_zoomRegionInstanceCount}`; + _zoomRegionInstanceCount++; + let zoomRegionProxy = new ShellMagnifierZoomRegion(newPath, aZoomRegion); + let proxyAndZoomer = {}; + proxyAndZoomer.proxy = zoomRegionProxy; + proxyAndZoomer.zoomRegion = aZoomRegion; + thoseZoomers[newPath] = proxyAndZoomer; + objectPaths.push(newPath); + } + }); + return objectPaths; + } + + /** + * clearAllZoomRegions: + * Remove all the zoom regions from this Magnfier's ZoomRegion list. + */ + clearAllZoomRegions() { + Main.magnifier.clearAllZoomRegions(); + for (let objectPath in this._zoomers) { + let proxyAndZoomer = this._zoomers[objectPath]; + proxyAndZoomer.proxy.destroy(); + proxyAndZoomer.proxy = null; + proxyAndZoomer.zoomRegion = null; + delete this._zoomers[objectPath]; + } + this._zoomers = {}; + } + + /** + * fullScreenCapable: + * Consult if the Magnifier can magnify in full-screen mode. + * @returns {bool} Always return true. + */ + fullScreenCapable() { + return true; + } + + /** + * setCrosswireSize: + * Set the crosswire size of all ZoomRegions. + * @param {number} size: The thickness of each line in the cross wire. + */ + setCrosswireSize(size) { + Main.magnifier.setCrosshairsThickness(size); + } + + /** + * getCrosswireSize: + * Get the crosswire size of all ZoomRegions. + * @returns {number}: The thickness of each line in the cross wire. + */ + getCrosswireSize() { + return Main.magnifier.getCrosshairsThickness(); + } + + /** + * setCrosswireLength: + * Set the crosswire length of all zoom-regions.. + * @param {number} length: The length of each line in the cross wire. + */ + setCrosswireLength(length) { + Main.magnifier.setCrosshairsLength(length); + } + + /** + * getCrosswireSize: + * Get the crosswire length of all zoom-regions. + * @returns {number} size: The length of each line in the cross wire. + */ + getCrosswireLength() { + return Main.magnifier.getCrosshairsLength(); + } + + /** + * setCrosswireClip: + * Set if the crosswire will be clipped by the cursor image.. + * @param {bool} clip: Flag to indicate whether to clip the crosswire. + */ + setCrosswireClip(clip) { + Main.magnifier.setCrosshairsClip(clip); + } + + /** + * getCrosswireClip: + * Get the crosswire clip value. + * @returns {bool}: Whether the crosswire is clipped by the cursor image. + */ + getCrosswireClip() { + return Main.magnifier.getCrosshairsClip(); + } + + /** + * setCrosswireColor: + * Set the crosswire color of all ZoomRegions. + * @param {number} color: Unsigned int of the form rrggbbaa. + */ + setCrosswireColor(color) { + Main.magnifier.setCrosshairsColor('#%08x'.format(color)); + } + + /** + * getCrosswireClip: + * Get the crosswire color of all ZoomRegions. + * @returns {number}: The crosswire color as an unsigned int in + * the form rrggbbaa. + */ + getCrosswireColor() { + let colorString = Main.magnifier.getCrosshairsColor(); + // Drop the leading '#'. + return parseInt(colorString.slice(1), 16); + } +}; + +/** + * ShellMagnifierZoomRegion: + * Object that implements the DBus ZoomRegion interface. + * @zoomerObjectPath: String that is the path to a DBus ZoomRegion. + * @zoomRegion: The actual zoom region associated with the object path. + */ +var ShellMagnifierZoomRegion = class ShellMagnifierZoomRegion { + constructor(zoomerObjectPath, zoomRegion) { + this._zoomRegion = zoomRegion; + + this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this); + this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath); + } + + /** + * setMagFactor: + * @param {number} xMagFactor: The power to set the horizontal + * magnification factor to of the magnified view. A value of + * 1.0 means no magnification. A value of 2.0 doubles the size. + * @param {number} yMagFactor: The power to set the vertical + * magnification factor to of the magnified view. + */ + setMagFactor(xMagFactor, yMagFactor) { + this._zoomRegion.setMagFactor(xMagFactor, yMagFactor); + } + + /** + * getMagFactor: + * @returns {number[]}: [xMagFactor, yMagFactor], containing the horizontal + * and vertical magnification powers. A value of 1.0 means no + * magnification. A value of 2.0 means the contents are doubled + * in size, and so on. + */ + getMagFactor() { + return this._zoomRegion.getMagFactor(); + } + + /** + * setRoi: + * Sets the "region of interest" that the ZoomRegion is magnifying. + * @param {number[]} roi: [left, top, right, bottom], defining the + * region of the screen to magnify. + * The values are in screen (unmagnified) coordinate space. + */ + setRoi(roi) { + let roiObject = { x: roi[0], y: roi[1], width: roi[2] - roi[0], height: roi[3] - roi[1] }; + this._zoomRegion.setROI(roiObject); + } + + /** + * getRoi: + * Retrieves the "region of interest" -- the rectangular bounds of that part + * of the desktop that the magnified view is showing (x, y, width, height). + * The bounds are given in non-magnified coordinates. + * @returns {Array}: [left, top, right, bottom], representing the bounding + * rectangle of what is shown in the magnified view. + */ + getRoi() { + let roi = this._zoomRegion.getROI(); + roi[2] += roi[0]; + roi[3] += roi[1]; + return roi; + } + + /** + * Set the "region of interest" by centering the given screen coordinate + * within the zoom region. + * @param {number} x: The x-coord of the point to place at the + * center of the zoom region. + * @param {number} y: The y-coord. + * @returns {bool} Whether the shift was successful (for GS-mag, this + * is always true). + */ + shiftContentsTo(x, y) { + this._zoomRegion.scrollContentsTo(x, y); + return true; + } + + /** + * moveResize + * Sets the position and size of the ZoomRegion on screen. + * @param {number[]} viewPort: [left, top, right, bottom], defining + * the position and size on screen to place the zoom region. + */ + moveResize(viewPort) { + let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] }; + this._zoomRegion.setViewPort(viewRect); + } + + destroy() { + this._dbusImpl.unexport(); + } +}; |