fenrir/src/fenrirscreenreader/core/inputManager.py
chrys b5f7526345 Revert "Merge pull request #21 from chrys87/nocrash"
This reverts commit ddecf331f6, reversing
changes made to 9ff73d67bc.
2018-04-13 23:42:18 +02:00

269 lines
13 KiB
Python

#!/bin/python
# -*- coding: utf-8 -*-
# Fenrir TTY screen reader
# By Chrys, Storm Dragon, and contributers.
from fenrirscreenreader.core import debug
from fenrirscreenreader.core import inputData
import os, inspect, time
currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
fenrirPath = os.path.dirname(currentdir)
class inputManager():
def __init__(self):
self.setLedState = True
self.shortcutType = 'KEY'
def setShortcutType(self, shortcutType = 'KEY'):
if shortcutType in ['KEY', 'BYTE']:
self.shortcutType = shortcutType
def getShortcutType(self):
return self.shortcutType
def initialize(self, environment):
self.env = environment
self.env['runtime']['settingsManager'].loadDriver(\
self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver')
# init LEDs with current state
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1)
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
self.lastDeepestInput = []
self.env['input']['shortcutRepeat'] = 1
self.lastInputTime = time.time()
def shutdown(self):
self.removeAllDevices()
self.env['runtime']['settingsManager'].shutdownDriver('inputDriver')
def getInputEvent(self):
return self.env['runtime']['inputDriver'].getInputEvent()
def handleInputEvent(self, eventData):
self.env['runtime']['debug'].writeDebugOut('DEBUG INPUT inputMan:' + str(eventData),debug.debugLevel.INFO)
if not eventData:
return
self.env['input']['prevInput'] = self.env['input']['currInput'].copy()
if eventData['EventState'] == 0:
if eventData['EventName'] in self.env['input']['currInput']:
self.env['input']['currInput'].remove(eventData['EventName'])
if len(self.env['input']['currInput']) > 1:
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
elif len(self.env['input']['currInput']) == 0:
self.env['input']['shortcutRepeat'] = 1
self.setLedState = self.handleLedStates(eventData)
self.lastInputTime = time.time()
elif eventData['EventState'] == 1:
if not eventData['EventName'] in self.env['input']['currInput']:
self.env['input']['currInput'].append(eventData['EventName'])
if len(self.env['input']['currInput']) > 1:
self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
if len(self.lastDeepestInput) < len(self.env['input']['currInput']):
self.setLastDeepestInput( self.env['input']['currInput'].copy())
elif self.lastDeepestInput == self.env['input']['currInput']:
if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'):
self.env['input']['shortcutRepeat'] += 1
else:
self.env['input']['shortcutRepeat'] = 1
self.setLedState = self.handleLedStates(eventData)
self.lastInputTime = time.time()
elif eventData['EventState'] == 2:
self.lastInputTime = time.time()
self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
self.env['input']['newCapsLock'] = self.env['runtime']['inputDriver'].getLedState(1)
self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
self.env['runtime']['debug'].writeDebugOut("currInput " + str(self.env['input']['currInput'] ) ,debug.debugLevel.INFO)
if self.noKeyPressed():
self.env['input']['prevInput'] = []
self.setLedState = True
def handleLedStates(self, mEvent):
if not self.setLedState:
return self.setLedState
if mEvent['EventName'] == 'KEY_NUMLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newNumLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState()
return False
if mEvent['EventState'] == 0 and not self.env['input']['newNumLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState()
return False
if mEvent['EventName'] == 'KEY_CAPSLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newCapsLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState(1)
return False
if mEvent['EventState'] == 0 and not self.env['input']['newCapsLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState(1)
return False
if mEvent['EventName'] == 'KEY_SCROLLLOCK':
if mEvent['EventState'] == 1 and not self.env['input']['newScrollLock'] == 1:
self.env['runtime']['inputDriver'].toggleLedState(2)
return False
if mEvent['EventState'] == 0 and not self.env['input']['newScrollLock'] == 0:
self.env['runtime']['inputDriver'].toggleLedState(2)
return False
return self.setLedState
def grabAllDevices(self):
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
self.env['runtime']['inputDriver'].grabAllDevices()
def updateInputDevices(self):
try:
self.env['runtime']['inputDriver'].updateInputDevices()
except:
pass
def removeAllDevices(self):
try:
self.env['runtime']['inputDriver'].removeAllDevices()
except:
pass
def convertEventName(self, eventName):
if not eventName:
return ''
if eventName == '':
return ''
eventName = eventName.upper()
if eventName == 'KEY_LEFTCTRL':
eventName = 'KEY_CTRL'
elif eventName == 'KEY_RIGHTCTRL':
eventName = 'KEY_CTRL'
elif eventName == 'KEY_LEFTSHIFT':
eventName = 'KEY_SHIFT'
elif eventName == 'KEY_RIGHTSHIFT':
eventName = 'KEY_SHIFT'
elif eventName == 'KEY_LEFTALT':
eventName = 'KEY_ALT'
elif eventName == 'KEY_RIGHTALT':
eventName = 'KEY_ALT'
elif eventName == 'KEY_LEFTMETA':
eventName = 'KEY_META'
elif eventName == 'KEY_RIGHTMETA':
eventName = 'KEY_META'
if self.isFenrirKey(eventName):
eventName = 'KEY_FENRIR'
if self.isScriptKey(eventName):
eventName = 'KEY_SCRIPT'
return eventName
def clearEventBuffer(self):
self.env['runtime']['inputDriver'].clearEventBuffer()
def setLastDeepestInput(self, currentDeepestInput):
self.lastDeepestInput = currentDeepestInput
def clearLastDeepInput(self):
self.lastDeepestInput = []
def getLastInputTime(self):
return self.lastInputTime
def getLastDeepestInput(self):
return self.lastDeepestInput
def writeEventBuffer(self):
try:
if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
self.env['runtime']['inputDriver'].writeEventBuffer()
self.clearEventBuffer()
except Exception as e:
self.env['runtime']['debug'].writeDebugOut("Error while writeUInput",debug.debugLevel.ERROR)
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
def noKeyPressed(self):
return self.env['input']['currInput'] == []
def isKeyPress(self):
return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != [])
def getPrevDeepestShortcut(self):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.getLastDeepestInput())
return str(shortcut)
def getPrevShortcut(self):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.env['input']['prevInput'])
return str(shortcut)
def getCurrShortcut(self, inputSequence = None):
shortcut = []
shortcut.append(self.env['input']['shortcutRepeat'])
if inputSequence:
shortcut.append(inputSequence)
else:
shortcut.append(self.env['input']['currInput'])
if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']):
if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)):
shortcut = []
self.env['input']['shortcutRepeat'] = 1
shortcut.append(self.env['input']['shortcutRepeat'])
shortcut.append(self.env['input']['currInput'])
self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO)
return str(shortcut)
def currKeyIsModifier(self):
if len(self.getLastDeepestInput()) != 1:
return False
return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT')
def isFenrirKey(self, eventName):
return eventName in self.env['input']['fenrirKey']
def isScriptKey(self, eventName):
return eventName in self.env['input']['scriptKey']
def getCommandForShortcut(self, shortcut):
if not self.shortcutExists(shortcut):
return ''
return self.env['bindings'][shortcut]
def shortcutExists(self, shortcut):
return(shortcut in self.env['bindings'])
def loadShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/desktop.conf'):
kbConfig = open(kbConfigPath,"r")
while(True):
invalid = False
line = kbConfig.readline()
if not line:
break
line = line.replace('\n','')
if line.replace(" ","") == '':
continue
if line.replace(" ","").startswith("#"):
continue
if line.count("=") != 1:
continue
sepLine = line.split('=')
commandName = sepLine[1].upper()
sepLine[0] = sepLine[0].replace(" ","")
sepLine[0] = sepLine[0].replace("'","")
sepLine[0] = sepLine[0].replace('"',"")
keys = sepLine[0].split(',')
shortcutKeys = []
shortcutRepeat = 1
shortcut = []
for key in keys:
try:
shortcutRepeat = int(key)
except:
if not self.isValidKey(key.upper()):
self.env['runtime']['debug'].writeDebugOut("invalid key : "+ key.upper() + ' command:' +commandName ,debug.debugLevel.WARNING)
invalid = True
break
shortcutKeys.append(key.upper())
if invalid:
continue
shortcut.append(shortcutRepeat)
shortcut.append(sorted(shortcutKeys))
if len(shortcutKeys) != 1 and not 'KEY_FENRIR' in shortcutKeys:
self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR)
continue
self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True)
self.env['bindings'][str(shortcut)] = commandName
kbConfig.close()
# fix bindings
self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE'
def isValidKey(self, key):
return key in inputData.keyNames