diff --git a/TODO v2.0 b/TODO v2.0 index 35d3c736..1fa49d45 100644 --- a/TODO v2.0 +++ b/TODO v2.0 @@ -129,9 +129,9 @@ Cleanups: [X] first item [X] last item General: -- [X] make it runable using pypy3 - -- [X] read ignorescreens from an file to be able to halt fenrir from outside + [X] make it runable using pypy3 + [X] interrupt speech while entering an ignored screen + [X] read ignorescreens from an file to be able to halt fenrir from outside - commands [X] place last spoken to clipboard (Easy for contribution) - Improvend Headline Seperator and Multible Char Support @@ -139,6 +139,8 @@ General: - autospeak indentation changes (useful for python programming) Braille Support: Driver: +[X] evdev InputDriver + [X] grab/ ungrab devices on ignored screens [X] PTY Input driver [X] new event for byte shortcuts (escape sequences) [X] create driver diff --git a/play zone/listDevices.py b/play zone/listDevices.py index 9af5a7e7..1ddd629b 100755 --- a/play zone/listDevices.py +++ b/play zone/listDevices.py @@ -17,5 +17,7 @@ for fd in iDevices: print('No. of keys: ' + str(len(cap[evdev.events.EV_KEY]))) print('has Key 116: ' + str(116 in cap[evdev.events.EV_KEY])) print('Is Mouse: ' + str(((evdev.events.EV_REL in cap) or (evdev.events.EV_ABS in cap)))) + print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + print(dev.capabilities(verbose=True)) print('----------------------') diff --git a/src/fenrirscreenreader/core/fenrirManager.py b/src/fenrirscreenreader/core/fenrirManager.py index 5254bf9e..9f2a885a 100644 --- a/src/fenrirscreenreader/core/fenrirManager.py +++ b/src/fenrirscreenreader/core/fenrirManager.py @@ -4,7 +4,7 @@ # Fenrir TTY screen reader # By Chrys, Storm Dragon, and contributers. -import signal, time, argparse +import signal, time, argparse, sys from fenrirscreenreader.core import i18n from fenrirscreenreader.core import settingsManager @@ -32,6 +32,7 @@ class fenrirManager(): self.command = '' self.controlMode = True self.switchCtrlModeOnce = 0 + self.setProcessName() def handleArgs(self): args = None parser = argparse.ArgumentParser(description="Fenrir Help") @@ -212,7 +213,32 @@ class fenrirManager(): if self.environment['runtime']['inputManager'].noKeyPressed(): self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command) self.command = '' + def setProcessName(self, name = 'fenrir'): + """Attempts to set the process name to 'fenrir'.""" + #sys.argv[0] = name + + # Disabling the import error of setproctitle. + # pylint: disable-msg=F0401 + try: + from setproctitle import setproctitle + except ImportError: + pass + else: + setproctitle(name) + return True + + try: + from ctypes import cdll, byref, create_string_buffer + libc = cdll.LoadLibrary('libc.so.6') + stringBuffer = create_string_buffer(len(name) + 1) + stringBuffer.value = bytes(name, 'UTF-8') + libc.prctl(15, byref(stringBuffer), 0, 0, 0) + return True + except: + pass + + return False def shutdownRequest(self): try: self.environment['runtime']['eventManager'].stopMainEventLoop() diff --git a/src/fenrirscreenreader/core/inputDriver.py b/src/fenrirscreenreader/core/inputDriver.py index ab91483e..bc4bff62 100644 --- a/src/fenrirscreenreader/core/inputDriver.py +++ b/src/fenrirscreenreader/core/inputDriver.py @@ -40,14 +40,17 @@ class inputDriver(): return False def toggleLedState(self, led = 0): if not self._initialized: - return None - def grabDevices(self): + return + def grabAllDevices(self): if not self._initialized: - return None - def releaseDevices(self): + return + def ungrabAllDevices(self): if not self._initialized: - return None + return + def removeAllDevices(self): + if not self._initialized: + return def __del__(self): if not self._initialized: - return None - self.releaseDevices() + return + self.removeAllDevices() diff --git a/src/fenrirscreenreader/core/inputManager.py b/src/fenrirscreenreader/core/inputManager.py index 9977c8a7..579c4db4 100644 --- a/src/fenrirscreenreader/core/inputManager.py +++ b/src/fenrirscreenreader/core/inputManager.py @@ -109,10 +109,16 @@ class inputManager(): def grabAllDevices(self): if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): - self.env['runtime']['inputDriver'].grabAllDevices() + try: + self.env['runtime']['inputDriver'].grabAllDevices() + except Exception as e: + pass def ungrabAllDevices(self): if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): - self.env['runtime']['inputDriver'].ungrabAllDevices() + try: + self.env['runtime']['inputDriver'].ungrabAllDevices() + except Exception as e: + pass def updateInputDevices(self): try: @@ -155,7 +161,10 @@ class inputManager(): return eventName def clearEventBuffer(self): - self.env['runtime']['inputDriver'].clearEventBuffer() + try: + self.env['runtime']['inputDriver'].clearEventBuffer() + except Exception as e: + pass def setLastDeepestInput(self, currentDeepestInput): self.lastDeepestInput = currentDeepestInput def clearLastDeepInput(self): diff --git a/src/fenrirscreenreader/core/screenManager.py b/src/fenrirscreenreader/core/screenManager.py index 426e086c..449ecade 100644 --- a/src/fenrirscreenreader/core/screenManager.py +++ b/src/fenrirscreenreader/core/screenManager.py @@ -12,6 +12,7 @@ class screenManager(): def __init__(self): self.currScreenIgnored = False self.prevScreenIgnored = False + self.toggleDeviceGrab = False def initialize(self, environment): self.env = environment self.env['runtime']['settingsManager'].loadDriver(\ @@ -40,15 +41,24 @@ class screenManager(): if not self.isSuspendingScreen(self.env['screen']['newTTY']): self.update(eventData, 'onScreenChange') self.env['screen']['lastScreenUpdate'] = time.time() + def handleDeviceGrab(self): + if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + return + if self.getCurrScreenIgnored() != self.getPrevScreenIgnored(): + self.toggleDeviceGrab = True + if self.toggleDeviceGrab: + if self.env['runtime']['inputManager'].noKeyPressed(): + if self.getCurrScreenIgnored(): + self.env['runtime']['inputManager'].ungrabAllDevices() + self.env['runtime']['outputManager'].interruptOutput() + else: + self.env['runtime']['inputManager'].grabAllDevices() + self.toggleDeviceGrab = False + def handleScreenUpdate(self, eventData): self.env['screen']['oldApplication'] = self.env['screen']['newApplication'] self.updateScreenIgnored() - if self.getCurrScreenIgnored() != self.getPrevScreenIgnored(): - if self.getCurrScreenIgnored(): - self.env['runtime']['inputManager'].ungrabAllDevices() - self.env['runtime']['outputManager'].interruptOutput() - else: - self.env['runtime']['inputManager'].grabAllDevices() + self.handleDeviceGrab() if not self.getCurrScreenIgnored(): self.update(eventData, 'onScreenUpdate') #if trigger == 'onUpdate' or self.isScreenChange() \ @@ -158,13 +168,34 @@ class screenManager(): return '' if attributeFormatString == '': return '' - attributeFormatString = attributeFormatString.replace('fenrirBGColor', self.env['runtime']['screenDriver'].getFenrirBGColor(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirFGColor', self.env['runtime']['screenDriver'].getFenrirFGColor(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirUnderline', self.env['runtime']['screenDriver'].getFenrirUnderline(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirBold', self.env['runtime']['screenDriver'].getFenrirBold(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirBlink', self.env['runtime']['screenDriver'].getFenrirBlink(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirFontSize', self.env['runtime']['screenDriver'].getFenrirFontSize(attribute)) - attributeFormatString = attributeFormatString.replace('fenrirFont', self.env['runtime']['screenDriver'].getFenrirFont(attribute)) + try: + attributeFormatString = attributeFormatString.replace('fenrirBGColor', self.env['runtime']['screenDriver'].getFenrirBGColor(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirFGColor', self.env['runtime']['screenDriver'].getFenrirFGColor(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirUnderline', self.env['runtime']['screenDriver'].getFenrirUnderline(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirBold', self.env['runtime']['screenDriver'].getFenrirBold(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirBlink', self.env['runtime']['screenDriver'].getFenrirBlink(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirFontSize', self.env['runtime']['screenDriver'].getFenrirFontSize(attribute)) + except Exception as e: + pass + try: + attributeFormatString = attributeFormatString.replace('fenrirFont', self.env['runtime']['screenDriver'].getFenrirFont(attribute)) + except Exception as e: + pass return attributeFormatString def isSuspendingScreen(self, screen = None): if screen == None: @@ -212,7 +243,6 @@ class screenManager(): try: self.env['runtime']['screenDriver'].injectTextToScreen(text, screen) except Exception as e: - print(e) self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR) def changeBrailleScreen(self): diff --git a/src/fenrirscreenreader/core/settingsManager.py b/src/fenrirscreenreader/core/settingsManager.py index 16691f9a..27eff00e 100644 --- a/src/fenrirscreenreader/core/settingsManager.py +++ b/src/fenrirscreenreader/core/settingsManager.py @@ -153,7 +153,10 @@ class settingsManager(): def shutdownDriver(self, driverType): if self.env['runtime'][driverType] == None: return - self.env['runtime'][driverType].shutdown() + try: + self.env['runtime'][driverType].shutdown() + except Exception as e: + pass del self.env['runtime'][driverType] def setFenrirKeys(self, keys): diff --git a/src/fenrirscreenreader/inputDriver/debugDriver.py b/src/fenrirscreenreader/inputDriver/debugDriver.py index d825cb8b..582813fd 100644 --- a/src/fenrirscreenreader/inputDriver/debugDriver.py +++ b/src/fenrirscreenreader/inputDriver/debugDriver.py @@ -20,7 +20,7 @@ class driver(inputDriver): def shutdown(self): if self._initialized: - self.releaseDevices() + self.removeAllDevices() self._initialized = False print('Input Debug Driver: Shutdown') @@ -51,17 +51,22 @@ class driver(inputDriver): if not self._initialized: return print('Input Debug Driver: toggleLedState') - def grabDevices(self): + def grabAllDevices(self): if not self._initialized: return - print('Input Debug Driver: grabDevices') - def releaseDevices(self): + print('Input Debug Driver: grabAllDevices') + def ungrabAllDevices(self): if not self._initialized: return - print('Input Debug Driver: releaseDevices') + print('Input Debug Driver: ungrabAllDevices') + + def removeAllDevices(self): + if not self._initialized: + return + print('Input Debug Driver: removeAllDevices') def __del__(self): if self._initialized: - self.releaseDevices() + self.removeAllDevices() print('Input Debug Driver: __del__') diff --git a/src/fenrirscreenreader/inputDriver/evdevDriver.py b/src/fenrirscreenreader/inputDriver/evdevDriver.py index ff317cd7..85e12c9a 100644 --- a/src/fenrirscreenreader/inputDriver/evdevDriver.py +++ b/src/fenrirscreenreader/inputDriver/evdevDriver.py @@ -54,10 +54,10 @@ class driver(inputDriver): self.env['runtime']['debug'].writeDebugOut('InputDriver: ' + _evdevAvailableError,debug.debugLevel.ERROR) return self.updateInputDevices() - if _udevAvailable: - self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev) - else: - self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.PlugInputDevice, self.plugInputDeviceWatchdogTimer) + #if _udevAvailable: + # self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev) + #else: + # self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.PlugInputDevice, self.plugInputDeviceWatchdogTimer) self.env['runtime']['processManager'].addCustomEventThread(self.inputWatchdog) def plugInputDeviceWatchdogUdev(self,active , eventQueue): context = pyudev.Context() @@ -67,8 +67,8 @@ class driver(inputDriver): while active.value: devices = monitor.poll(2) if devices: - while monitor.poll(0.2): - time.sleep(0.2) + while monitor.poll(1): + pass eventQueue.put({"Type":fenrirEventType.PlugInputDevice,"Data":None}) return time.time() def plugInputDeviceWatchdogTimer(self, active): @@ -119,8 +119,9 @@ class driver(inputDriver): return for iDevice, uDevice, event in self.env['input']['eventBuffer']: try: - if self.gDevices[iDevice.fd]: - self.writeUInput(uDevice, event) + if uDevice: + if self.gDevices[iDevice.fd]: + self.writeUInput(uDevice, event) except Exception as e: pass @@ -134,7 +135,6 @@ class driver(inputDriver): return uDevice.write_event(event) uDevice.syn() - time.sleep(0.00001) def updateInputDevices(self, force = False, init = False): if init: @@ -173,23 +173,20 @@ class driver(inputDriver): if 116 in cap[eventType.EV_KEY] and len(cap[eventType.EV_KEY]) < 10: self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name,debug.debugLevel.INFO) continue - if len(cap[eventType.EV_KEY]) < 30: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 30 keys):' + currDevice.name,debug.debugLevel.INFO) + if len(cap[eventType.EV_KEY]) < 60: + self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name,debug.debugLevel.INFO) continue if mode == 'ALL': - self.iDevices[currDevice.fd] = currDevice - self.grabDevice(currDevice.fd) + self.addDevice(currDevice) self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO) elif mode == 'NOMICE': if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)): - self.iDevices[currDevice.fd] = currDevice - self.grabDevice(currDevice.fd) + self.addDevice(currDevice) self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) else: self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name,debug.debugLevel.INFO) elif currDevice.name.upper() in mode.split(','): - self.iDevices[currDevice.fd] = currDevice - self.grabDevice(currDevice.fd) + self.addDevice(currDevice) self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) except Exception as e: self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile +' ' + currDevice.name +' '+ str(e),debug.debugLevel.INFO) @@ -250,12 +247,19 @@ class driver(inputDriver): if not self._initialized: return for fd in self.iDevices: - self.ungrabDevices(fd) - def grabDevice(self, fd): + self.ungrabDevice(fd) + def createUInputDev(self, fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.uDevices[fd] = None return - try: + try: + test = self.uDevices[fd] + return + except KeyError: + self.uDevices[fd] = None + if self.uDevices[fd] != None: + return + try: self.uDevices[fd] = UInput.from_device(self.iDevices[fd]) except Exception as e: try: @@ -269,24 +273,31 @@ class driver(inputDriver): ) except Exception as e: self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e),debug.debugLevel.ERROR) - return + return + def addDevice(self, newDevice): + self.iDevices[newDevice.fd] = newDevice + self.createUInputDev(newDevice.fd) + self.grabDevice(newDevice.fd) + def grabDevice(self, fd): + if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): + return try: self.iDevices[fd].grab() self.gDevices[fd] = True except Exception as e: self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR) - def ungrabDevices(self,fd): + def ungrabDevice(self,fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): return try: + self.gDevices[fd] = False self.iDevices[fd].ungrab() - self.gDevices[fd] = False except: pass def removeDevice(self,fd): self.clearEventBuffer() try: - self.ungrabDevices(fd) + self.ungrabDevice(fd) except: pass try: @@ -309,7 +320,7 @@ class driver(inputDriver): del(self.gDevices[fd]) except: pass - self.MPiDevicesFD() + self.updateMPiDevicesFD() def hasIDevices(self): if not self._initialized: