From 09391bfe84eec561836668baca73a286e56e81a2 Mon Sep 17 00:00:00 2001 From: Storm Dragon Date: Sun, 2 Mar 2025 17:24:45 -0500 Subject: [PATCH] Experimental fix for evdev failures. --- .../inputDriver/evdevDriver.py | 131 +++++++++++------- 1 file changed, 79 insertions(+), 52 deletions(-) diff --git a/src/fenrirscreenreader/inputDriver/evdevDriver.py b/src/fenrirscreenreader/inputDriver/evdevDriver.py index 837d0f29..701a5d9f 100644 --- a/src/fenrirscreenreader/inputDriver/evdevDriver.py +++ b/src/fenrirscreenreader/inputDriver/evdevDriver.py @@ -59,7 +59,7 @@ class driver(inputDriver): self.env['runtime']['processManager'].addCustomEventThread(self.inputWatchdog) self._initialized = True - def plugInputDeviceWatchdogUdev(self,active , eventQueue): + def plugInputDeviceWatchdogUdev(self, active, eventQueue): context = pyudev.Context() monitor = pyudev.Monitor.from_netlink(context) monitor.filter_by(subsystem='input') @@ -72,31 +72,33 @@ class driver(inputDriver): self.env['runtime']['debug'].writeDebugOut('plugInputDeviceWatchdogUdev:' + str(device), debug.debugLevel.INFO) try: try: - if device.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']: + # FIX: Check if attributes exist before accessing them + if hasattr(device, 'name') and device.name and device.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']: ignorePlug = True - if device.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']: + if hasattr(device, 'phys') and device.phys and device.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']: ignorePlug = True - if 'BRLTTY' in device.name.upper(): + if hasattr(device, 'name') and device.name and 'BRLTTY' in device.name.upper(): ignorePlug = True except Exception as e: - self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev CHECK NAME CRASH: " + str(e),debug.debugLevel.ERROR) + self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev CHECK NAME CRASH: " + str(e), debug.debugLevel.ERROR) + if not ignorePlug: virtual = '/sys/devices/virtual/input/' in device.sys_path if device.device_node: validDevices.append({'device': device.device_node, 'virtual': virtual}) except Exception as e: - self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev APPEND CRASH: " + str(e),debug.debugLevel.ERROR) + self.env['runtime']['debug'].writeDebugOut("plugInputDeviceWatchdogUdev APPEND CRASH: " + str(e), debug.debugLevel.ERROR) try: pollTimeout = 1 device = monitor.poll(pollTimeout) - except: + except Exception: device = None ignorePlug = False if validDevices: - eventQueue.put({"Type":fenrirEventType.PlugInputDevice,"Data":validDevices}) + eventQueue.put({"Type": fenrirEventType.PlugInputDevice, "Data": validDevices}) return time.time() - def inputWatchdog(self,active , eventQueue): + def inputWatchdog(self, active, eventQueue): try: while active.value: r, w, x = select(self.iDevices, [], [], 0.8) @@ -111,7 +113,7 @@ class driver(inputDriver): self.removeDevice(fd) while(event): self.env['runtime']['debug'].writeDebugOut('inputWatchdog: EVENT:' + str(event), debug.debugLevel.INFO) - self.env['input']['eventBuffer'].append( [self.iDevices[fd], self.uDevices[fd], event]) + self.env['input']['eventBuffer'].append([self.iDevices[fd], self.uDevices[fd], event]) if event.type == evdev.events.EV_KEY: if not foundKeyInSequence: foundKeyInSequence = True @@ -123,11 +125,11 @@ class driver(inputDriver): if not isinstance(currMapEvent['EventName'], str): event = self.iDevices[fd].read_one() continue - if currMapEvent['EventState'] in [0,1,2]: - eventQueue.put({"Type":fenrirEventType.KeyboardInput,"Data":currMapEvent.copy()}) + if currMapEvent['EventState'] in [0, 1, 2]: + eventQueue.put({"Type": fenrirEventType.KeyboardInput, "Data": currMapEvent.copy()}) eventFired = True else: - if event.type in [2,3]: + if event.type in [2, 3]: foreward = True event = self.iDevices[fd].read_one() @@ -136,7 +138,7 @@ class driver(inputDriver): self.writeEventBuffer() self.clearEventBuffer() except Exception as e: - self.env['runtime']['debug'].writeDebugOut("INPUT WATCHDOG CRASH: "+str(e),debug.debugLevel.ERROR) + self.env['runtime']['debug'].writeDebugOut("INPUT WATCHDOG CRASH: " + str(e), debug.debugLevel.ERROR) def writeEventBuffer(self): if not self._initialized: @@ -146,7 +148,7 @@ class driver(inputDriver): if uDevice: if self.gDevices[iDevice.fd]: self.writeUInput(uDevice, event) - except Exception as e: + except Exception: pass def writeUInput(self, uDevice, event): @@ -156,7 +158,7 @@ class driver(inputDriver): time.sleep(0.0000002) uDevice.syn() - def updateInputDevices(self, newDevices = None, init = False): + def updateInputDevices(self, newDevices=None, init=False): if init: self.removeAllDevices() @@ -191,7 +193,7 @@ class driver(inputDriver): try: with open(deviceFile) as f: pass - except Exception as e: + except Exception: continue # 3 pos absolute # 2 pos relative @@ -201,22 +203,23 @@ class driver(inputDriver): except: continue try: - if currDevice.name.upper() in ['','SPEAKUP','FENRIR-UINPUT']: + # FIX: Check if attributes exist before accessing them + if hasattr(currDevice, 'name') and currDevice.name and currDevice.name.upper() in ['', 'SPEAKUP', 'FENRIR-UINPUT']: continue - if currDevice.phys.upper() in ['','SPEAKUP','FENRIR-UINPUT']: + if hasattr(currDevice, 'phys') and currDevice.phys and currDevice.phys.upper() in ['', 'SPEAKUP', 'FENRIR-UINPUT']: continue - if 'BRLTTY' in currDevice.name.upper(): + if hasattr(currDevice, 'name') and currDevice.name and 'BRLTTY' in currDevice.name.upper(): continue except: pass cap = currDevice.capabilities() - if mode in ['ALL','NOMICE']: + if mode in ['ALL', 'NOMICE']: if eventType.EV_KEY in cap: 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) + self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name, debug.debugLevel.INFO) continue if len(cap[eventType.EV_KEY]) < 60: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name,debug.debugLevel.INFO) + self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 60 keys):' + currDevice.name, debug.debugLevel.INFO) continue if mode == 'ALL': self.addDevice(currDevice) @@ -224,16 +227,20 @@ class driver(inputDriver): elif mode == 'NOMICE': if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)): self.addDevice(currDevice) - self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) + 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) + self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name, debug.debugLevel.INFO) else: - self.env['runtime']['debug'].writeDebugOut('Device Skipped (no EV_KEY):' + currDevice.name,debug.debugLevel.INFO) + self.env['runtime']['debug'].writeDebugOut('Device Skipped (no EV_KEY):' + currDevice.name, debug.debugLevel.INFO) elif currDevice.name.upper() in mode.split(','): self.addDevice(currDevice) - self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO) + 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) + try: + device_name = currDevice.name if hasattr(currDevice, 'name') else "unknown" + self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile + ' ' + device_name + ' ' + str(e), debug.debugLevel.INFO) + except: + self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile + ' ' + str(e), debug.debugLevel.INFO) self.iDeviceNo = len(evdev.list_devices()) self.updateMPiDevicesFD() @@ -247,6 +254,7 @@ class driver(inputDriver): self.iDevicesFD.remove(fd) except: pass + def mapEvent(self, event): if not self._initialized: return None @@ -266,12 +274,12 @@ class driver(inputDriver): mEvent['EventSec'] = event.sec mEvent['EventUsec'] = event.usec mEvent['EventState'] = event.value - mEvent['EventType'] = event.type + mEvent['EventType'] = event.type return mEvent - except Exception as e: + except Exception: return None - def getLedState(self, led = 0): + def getLedState(self, led=0): if not self.hasIDevices(): return False # 0 = Numlock @@ -281,7 +289,8 @@ class driver(inputDriver): if led in dev.leds(): return True return False - def toggleLedState(self, led = 0): + + def toggleLedState(self, led=0): if not self.hasIDevices(): return False ledState = self.getLedState(led) @@ -290,9 +299,10 @@ class driver(inputDriver): # 17 LEDs if 17 in self.iDevices[i].capabilities(): if ledState == 1: - self.iDevices[i].set_led(led , 0) + self.iDevices[i].set_led(led, 0) else: - self.iDevices[i].set_led(led , 1) + self.iDevices[i].set_led(led, 1) + def grabAllDevices(self): if not self._initialized: return True @@ -301,6 +311,7 @@ class driver(inputDriver): if not self.gDevices[fd]: ok = ok and self.grabDevice(fd) return ok + def ungrabAllDevices(self): if not self._initialized: return True @@ -309,6 +320,7 @@ class driver(inputDriver): if self.gDevices[fd]: ok = ok and self.ungrabDevice(fd) return ok + def createUInputDev(self, fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): self.uDevices[fd] = None @@ -324,20 +336,21 @@ class driver(inputDriver): self.uDevices[fd] = UInput.from_device(self.iDevices[fd], name='fenrir-uinput', phys='fenrir-uinput') except Exception as e: try: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback: ' + str(e),debug.debugLevel.WARNING) + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback: ' + str(e), debug.debugLevel.WARNING) dev = self.iDevices[fd] cap = dev.capabilities() del cap[0] self.uDevices[fd] = UInput( cap, - name = 'fenrir-uinput', - phys = 'fenrir-uinput' + name='fenrir-uinput', + phys='fenrir-uinput' ) except Exception as e: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e),debug.debugLevel.ERROR) + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e), debug.debugLevel.ERROR) return + def addDevice(self, newDevice): - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device added: ' + str(newDevice.fd) + ' ' +str(newDevice),debug.debugLevel.INFO) + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device added: ' + str(newDevice.fd) + ' ' + str(newDevice), debug.debugLevel.INFO) try: self.iDevices[newDevice.fd] = newDevice self.createUInputDev(newDevice.fd) @@ -360,10 +373,13 @@ class driver(inputDriver): def grabDevice(self, fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): return True + + # FIX: Handle exception variable scope correctly + grab_error = None try: self.iDevices[fd].grab() self.gDevices[fd] = True - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grab device ('+ str(self.iDevices[fd].name) + ')',debug.debugLevel.INFO) + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grab device (' + str(self.iDevices[fd].name) + ')', debug.debugLevel.INFO) # Reset modifier keys on successful grab if self.uDevices[fd]: modifierKeys = [e.KEY_LEFTCTRL, e.KEY_RIGHTCTRL, e.KEY_LEFTALT, e.KEY_RIGHTALT, e.KEY_LEFTSHIFT, e.KEY_RIGHTSHIFT] @@ -371,33 +387,44 @@ class driver(inputDriver): try: self.uDevices[fd].write(e.EV_KEY, key, 0) # 0 = key up self.uDevices[fd].syn() - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('Failed to reset modifier key: ' + str(e), debug.debugLevel.WARNING) + except Exception as mod_error: + self.env['runtime']['debug'].writeDebugOut('Failed to reset modifier key: ' + str(mod_error), debug.debugLevel.WARNING) except IOError: if not self.gDevices[fd]: return False - except Exception as e: - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR) + except Exception as ex: + grab_error = ex + + if grab_error: + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(grab_error), debug.debugLevel.ERROR) return False + return True - def ungrabDevice(self,fd): + def ungrabDevice(self, fd): if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'): return True + + # FIX: Handle exception variable scope correctly + ungrab_error = None try: self.iDevices[fd].ungrab() self.gDevices[fd] = False - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrab device ('+ str(self.iDevices[fd].name) + ')',debug.debugLevel.INFO) + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrab device (' + str(self.iDevices[fd].name) + ')', debug.debugLevel.INFO) except IOError: if self.gDevices[fd]: return False - # self.gDevices[fd] = False - # #self.removeDevice(fd) - except Exception as e: + except Exception as ex: + ungrab_error = ex + + if ungrab_error: + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: ungrabing not possible: ' + str(ungrab_error), debug.debugLevel.ERROR) return False + return True - def removeDevice(self,fd): - self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed: ' + str(fd) + ' ' +str(self.iDevices[fd]),debug.debugLevel.INFO) + + def removeDevice(self, fd): + self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: device removed: ' + str(fd) + ' ' + str(self.iDevices[fd]), debug.debugLevel.INFO) self.clearEventBuffer() try: self.ungrabDevice(fd) @@ -452,4 +479,4 @@ class driver(inputDriver): self.iDevices.clear() self.uDevices.clear() self.gDevices.clear() - self.iDeviceNo = 0 + self.iDeviceNo = 0