diff --git a/src/fenrirscreenreader/core/remoteManager.py b/src/fenrirscreenreader/core/remoteManager.py index 3dc16327..6c0ba400 100644 --- a/src/fenrirscreenreader/core/remoteManager.py +++ b/src/fenrirscreenreader/core/remoteManager.py @@ -57,6 +57,35 @@ class remoteManager(): def shutdown(self): self.env['runtime']['settingsManager'].shutdownDriver('remoteDriver') + def handleSettingsChangeWithResponse(self, settingsText): + if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableSettingsRemote'): + return {"success": False, "message": "Settings remote control is disabled"} + + upperSettingsText = settingsText.upper() + try: + # set setting + if upperSettingsText.startswith(self.setSettingConst): + parameterText = settingsText[len(self.setSettingConst):] + self.setSettings(parameterText) + return {"success": True, "message": f"Setting applied: {parameterText}"} + # save as setting + elif upperSettingsText.startswith(self.saveAsSettingConst): + parameterText = settingsText[len(self.saveAsSettingConst):] + self.saveSettings(parameterText) + return {"success": True, "message": f"Settings saved to: {parameterText}"} + # save setting + elif upperSettingsText == self.saveSettingConst: + self.saveSettings() + return {"success": True, "message": "Settings saved"} + # reset setting + elif upperSettingsText == self.resetSettingConst: + self.resetSettings() + return {"success": True, "message": "Settings reset to defaults"} + else: + return {"success": False, "message": f"Unknown settings command: {settingsText}"} + except Exception as e: + return {"success": False, "message": f"Settings error: {str(e)}"} + def handleSettingsChange(self, settingsText): if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableSettingsRemote'): return @@ -77,6 +106,61 @@ class remoteManager(): elif upperSettingsText == self.resetSettingConst: self.resetSettings() + def handleCommandExecutionWithResponse(self, commandText): + if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableCommandRemote'): + return {"success": False, "message": "Command remote control is disabled"} + + upperCommandText = commandText.upper() + + try: + # say + if upperCommandText.startswith(self.sayConst): + parameterText = commandText[len(self.sayConst):] + self.say(parameterText) + return {"success": True, "message": f"Speaking: {parameterText[:50]}{'...' if len(parameterText) > 50 else ''}"} + # interrupt + elif upperCommandText == self.interruptConst: + self.interruptSpeech() + return {"success": True, "message": "Speech interrupted"} + # temp disable speech + elif upperCommandText == self.tempDisableSpeechConst: + self.tempDisableSpeech() + return {"success": True, "message": "Speech temporarily disabled"} + # set vmenu + elif upperCommandText.startswith(self.vmenuConst): + parameterText = commandText[len(self.vmenuConst):] + self.setVMenu(parameterText) + return {"success": True, "message": f"VMenu set to: {parameterText}"} + # reset vmenu + elif upperCommandText == self.resetVmenuConst: + self.resetVMenu() + return {"success": True, "message": "VMenu reset"} + # quit fenrir + elif upperCommandText == self.quitAppConst: + self.quitFenrir() + return {"success": True, "message": "Fenrir shutting down"} + # define window + elif upperCommandText.startswith(self.defineWindowConst): + parameterText = commandText[len(self.defineWindowConst):] + self.defineWindow(parameterText) + return {"success": True, "message": f"Window defined: {parameterText}"} + # reset window + elif upperCommandText == self.resetWindowConst: + self.resetWindow() + return {"success": True, "message": "Window reset"} + # set clipboard + elif upperCommandText.startswith(self.setClipboardConst): + parameterText = commandText[len(self.setClipboardConst):] + self.setClipboard(parameterText) + return {"success": True, "message": f"Clipboard set: {parameterText[:50]}{'...' if len(parameterText) > 50 else ''}"} + elif upperCommandText.startswith(self.exportClipboardConst): + self.exportClipboard() + return {"success": True, "message": "Clipboard exported to file"} + else: + return {"success": False, "message": f"Unknown command: {commandText}"} + except Exception as e: + return {"success": False, "message": f"Command error: {str(e)}"} + def handleCommandExecution(self, commandText): if not self.env['runtime']['settingsManager'].getSettingAsBool('remote', 'enableCommandRemote'): return @@ -185,6 +269,25 @@ class remoteManager(): self.env['runtime']['settingsManager'].parseSettingArgs(settingsArgs) self.env['runtime']['screenManager'].updateScreenIgnored() self.env['runtime']['inputManager'].handleDeviceGrab(force = True) + def handleRemoteIncommingWithResponse(self, eventData): + if not eventData: + return {"success": False, "message": "No data received"} + + upperEventData = eventData.upper() + self.env['runtime']['debug'].writeDebugOut('remoteManager:handleRemoteIncommingWithResponse: event: ' + str(eventData),debug.debugLevel.INFO) + + try: + if upperEventData.startswith(self.settingConst): + settingsText = eventData[len(self.settingConst):] + return self.handleSettingsChangeWithResponse(settingsText) + elif upperEventData.startswith(self.commandConst): + commandText = eventData[len(self.commandConst):] + return self.handleCommandExecutionWithResponse(commandText) + else: + return {"success": False, "message": "Unknown command format. Use 'COMMAND ...' or 'SETTING ...'"} + except Exception as e: + return {"success": False, "message": f"Exception: {str(e)}"} + def handleRemoteIncomming(self, eventData): if not eventData: return diff --git a/src/fenrirscreenreader/remoteDriver/unixDriver.py b/src/fenrirscreenreader/remoteDriver/unixDriver.py index 40968366..addfd05f 100644 --- a/src/fenrirscreenreader/remoteDriver/unixDriver.py +++ b/src/fenrirscreenreader/remoteDriver/unixDriver.py @@ -33,7 +33,7 @@ class driver(remoteDriver): os.unlink(socketFile) self.fenrirSock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.fenrirSock.bind(socketFile) - os.chmod(socketFile, 0o222) + os.chmod(socketFile, 0o666) self.fenrirSock.listen(1) while active.value: # Check if the client is still connected and if data is available: @@ -45,17 +45,28 @@ class driver(remoteDriver): continue if self.fenrirSock in r: client_sock, client_addr = self.fenrirSock.accept() + response = "ERROR: Failed to process command\n" try: rawdata = client_sock.recv(8129) - except: - pass - try: data = rawdata.decode("utf-8").rstrip().lstrip() - eventQueue.put({"Type":fenrirEventType.RemoteIncomming, - "Data": data - }) + if data: + # Process the command and get response + result = self.env['runtime']['remoteManager'].handleRemoteIncommingWithResponse(data) + if result['success']: + response = f"OK: {result['message']}\n" + else: + response = f"ERROR: {result['message']}\n" + else: + response = "ERROR: Empty command\n" + except Exception as e: + response = f"ERROR: {str(e)}\n" + + # Send response back to client + try: + client_sock.send(response.encode("utf-8")) except: pass + try: client_sock.close() except: