#!/usr/bin/env python2

import sys
from Xlib.display import Display
from Xlib import X
from Xlib.error import ConnectionClosedError
from gi.repository.Gio import Settings

class ZOOM_MODE:
	# original values are 0.04 and 5
	SMOOTH = {"name": "smooth", "mag-factor": 0.10, "num-iters": 1}
	NORMAL = {"name": "normal", "mag-factor": 0.01, "num-iters": 3}
	FAST = {"name": "fast", "mag-factor": 0.2, "num-iters": 1}

class Zoomer(object):
	def __init__(self, zoomMode = ZOOM_MODE.NORMAL):
		self.magFactor = 1.00
		self.zoomMode = zoomMode
		self.settings = Settings('org.gnome.desktop.a11y.magnifier')

		self.settings.set_double('mag-factor', self.magFactor)
		self.settings.sync()
	
	def zoomIn(self):
		for i in range(self.zoomMode['num-iters']):
			self.magFactor = min(self.magFactor * (1 + self.zoomMode["mag-factor"]), 32.0)
			self.magFactor = float("%.2f" % self.magFactor)

			self.settings.sync()
			print >> sys.stderr, "IN", self.magFactor
			self.settings.set_double("mag-factor", self.magFactor)
			self.settings.sync()

			if self.magFactor == 32.0:
				break
	
	def zoomOut(self):
		for i in range(self.zoomMode['num-iters']):
			self.magFactor = max(self.magFactor / (1 + self.zoomMode["mag-factor"]), 1.0)
			self.magFactor = float("%.2f" % self.magFactor)

			self.settings.sync()
			print >> sys.stderr, "OUT", self.magFactor
			self.settings.set_double("mag-factor", self.magFactor)
			self.settings.sync()
			
			if self.magFactor == 1.0:
				break

def main():
	# Set up zoomer and xlib.
	zoomer = Zoomer(ZOOM_MODE.SMOOTH)
	buttons = [X.Button4, X.Button5]
	masks = [0, X.LockMask, X.Mod2Mask, X.LockMask | X.Mod2Mask]
	display = Display()
	root = display.screen().root

	# grab a buttons with a modifier
	for mask in masks:
		for button in buttons:
			root.grab_button(button, X.Mod1Mask | mask, root, False, X.GrabModeAsync, X.GrabModeAsync, X.NONE, X.NONE)

	while True:
		try:		
			event = display.next_event()
			
			print >> sys.stderr, event
			
			if event.detail == X.Button4:
				zoomer.zoomIn()

			elif event.detail == X.Button5:
				zoomer.zoomOut()

			display.sync()
			display.flush()

		except KeyboardInterrupt:
			break

		except ConnectionClosedError:
			break
			
		except:
			break

	if display:
		display.sync()
		display.flush()
		display.close()

if __name__ == '__main__':
	main()

