Resolved version conflict. I need to automate this somehow.
This commit is contained in:
commit
f6d3baebc1
10
README.md
10
README.md
@ -16,7 +16,7 @@ This software is licensed under the LGPL v3.
|
|||||||
# Core Requirements
|
# Core Requirements
|
||||||
|
|
||||||
- python3 >= 3.3
|
- python3 >= 3.3
|
||||||
- screen, input, speech, sound or braille drivers dependencies see "Features, Drivers, Extras".
|
- screen, input, speech, sound drivers dependencies see "Features, Drivers, Extras".
|
||||||
|
|
||||||
|
|
||||||
# Features, Drivers, Extras, Dependencies
|
# Features, Drivers, Extras, Dependencies
|
||||||
@ -59,13 +59,6 @@ This software is licensed under the LGPL v3.
|
|||||||
- emacspeak
|
- emacspeak
|
||||||
|
|
||||||
|
|
||||||
# Braille Drivers:
|
|
||||||
|
|
||||||
1. "BrlttyDriver" braille driver (WIP):
|
|
||||||
- brltty (configured and running)
|
|
||||||
- python-brlapi
|
|
||||||
|
|
||||||
|
|
||||||
# Sound Drivers:
|
# Sound Drivers:
|
||||||
|
|
||||||
1. "genericDriver" (default) sound driver for sound as subprocess:
|
1. "genericDriver" (default) sound driver for sound as subprocess:
|
||||||
@ -113,7 +106,6 @@ Take care to use drivers from the config matching your installed drivers.
|
|||||||
By default it uses:
|
By default it uses:
|
||||||
- sound driver: genericDriver (via sox, could configured in settings.conf)
|
- sound driver: genericDriver (via sox, could configured in settings.conf)
|
||||||
- speech driver: genericDriver (via espeak or espeak-ng, could configured in settings.conf)
|
- speech driver: genericDriver (via espeak or espeak-ng, could configured in settings.conf)
|
||||||
- braille driver: brlttyDriver (WIP)
|
|
||||||
- input driver: evdevDriver
|
- input driver: evdevDriver
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from typing import List, Optional
|
|||||||
@dataclass
|
@dataclass
|
||||||
class Dependency:
|
class Dependency:
|
||||||
name: str
|
name: str
|
||||||
depType: str # screen, braille, input, sound, speech, core
|
depType: str # screen, input, sound, speech, core
|
||||||
moduleName: str
|
moduleName: str
|
||||||
checkCommands: Optional[List[str]] = None # Command-line tools to check
|
checkCommands: Optional[List[str]] = None # Command-line tools to check
|
||||||
pythonImports: Optional[List[str]] = None # Python packages to check
|
pythonImports: Optional[List[str]] = None # Python packages to check
|
||||||
@ -60,12 +60,6 @@ dependencyList = [
|
|||||||
Dependency('PTY', 'screen', 'ptyDriver',
|
Dependency('PTY', 'screen', 'ptyDriver',
|
||||||
pythonImports=['pyte']),
|
pythonImports=['pyte']),
|
||||||
|
|
||||||
# Braille drivers
|
|
||||||
Dependency('DummyBraille', 'braille', 'dummyDriver'),
|
|
||||||
Dependency('DebugBraille', 'braille', 'debugDriver'),
|
|
||||||
Dependency('BRLAPI', 'braille', 'brlapiDriver',
|
|
||||||
pythonImports=['brlapi']),
|
|
||||||
|
|
||||||
# Input drivers
|
# Input drivers
|
||||||
Dependency('DummyInput', 'input', 'dummyDriver'),
|
Dependency('DummyInput', 'input', 'dummyDriver'),
|
||||||
Dependency('DebugInput', 'input', 'debugDriver'),
|
Dependency('DebugInput', 'input', 'debugDriver'),
|
||||||
@ -94,7 +88,6 @@ dependencyList = [
|
|||||||
defaultModules = {
|
defaultModules = {
|
||||||
'FenrirCore',
|
'FenrirCore',
|
||||||
'VCSA',
|
'VCSA',
|
||||||
'DummyBraille',
|
|
||||||
'Evdev',
|
'Evdev',
|
||||||
'GenericSpeech',
|
'GenericSpeech',
|
||||||
'GenericSound'
|
'GenericSound'
|
||||||
@ -105,7 +98,7 @@ def check_all_dependencies():
|
|||||||
availableModules = []
|
availableModules = []
|
||||||
|
|
||||||
# Group dependencies by type for organized output
|
# Group dependencies by type for organized output
|
||||||
for depType in ['core', 'screen', 'braille', 'input', 'sound', 'speech']:
|
for depType in ['core', 'screen', 'input', 'sound', 'speech']:
|
||||||
print(f'{depType.upper()} DRIVERS')
|
print(f'{depType.upper()} DRIVERS')
|
||||||
print('-' * 20)
|
print('-' * 20)
|
||||||
|
|
||||||
|
@ -91,37 +91,6 @@ fenrirMaxPitch=99
|
|||||||
fenrirMinRate=80
|
fenrirMinRate=80
|
||||||
fenrirMaxRate=450
|
fenrirMaxRate=450
|
||||||
|
|
||||||
[braille]
|
|
||||||
enabled=False
|
|
||||||
driver=dummyDriver
|
|
||||||
layout=en
|
|
||||||
# to what should the flush timeout relate to
|
|
||||||
# word = flush after (number of words to display) * seconds
|
|
||||||
# char = flush after (number of chars to display) * seconds
|
|
||||||
# fix = flush after X seconds
|
|
||||||
# none = no automatic flush (manual via shortcut)
|
|
||||||
flushMode=word
|
|
||||||
# seconds to flush or
|
|
||||||
# -1 = no automatic flush (manual via shortcut)
|
|
||||||
flushTimeout=3
|
|
||||||
# how should the cursor be focused?
|
|
||||||
# page = if cursor cross the border move to next page and start at beginn
|
|
||||||
# fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
|
|
||||||
cursorFocusMode=page
|
|
||||||
# define the cell on the Braille device where fenrir should scroll and keep the cursor
|
|
||||||
# 0 = first cell on device
|
|
||||||
# -1 = last cell on device
|
|
||||||
# >0 = fix cell number
|
|
||||||
fixCursorOnCell=-1
|
|
||||||
#How should the braille follow the focus
|
|
||||||
# none = no automatic toggle command used
|
|
||||||
# review = priority to review
|
|
||||||
# last = follow last used cursor
|
|
||||||
cursorFollowMode=review
|
|
||||||
# number of cells in panning (horizontal)
|
|
||||||
# 0 = display size, >0 number of cells
|
|
||||||
panSizeHorizontal=0
|
|
||||||
|
|
||||||
[screen]
|
[screen]
|
||||||
driver=vcsaDriver
|
driver=vcsaDriver
|
||||||
encoding=auto
|
encoding=auto
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
# needs pandoc and php installed
|
# needs pandoc and php installed
|
||||||
|
|
||||||
# remove old files
|
# remove old files
|
||||||
|
3
setup.py
3
setup.py
@ -76,7 +76,7 @@ setup(
|
|||||||
# Packages
|
# Packages
|
||||||
packages=find_packages('src/'),
|
packages=find_packages('src/'),
|
||||||
package_dir={'': 'src/'},
|
package_dir={'': 'src/'},
|
||||||
scripts=['src/fenrir','src/fenrir-daemon'],
|
scripts=['src/fenrir'],
|
||||||
|
|
||||||
# Include additional files into the package
|
# Include additional files into the package
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
@ -119,5 +119,4 @@ print('once as their user account and once as root to configure Pulseaudio.')
|
|||||||
print('Please install the following packages manually:')
|
print('Please install the following packages manually:')
|
||||||
print('- Speech-dispatcher: for the default speech driver')
|
print('- Speech-dispatcher: for the default speech driver')
|
||||||
print('- Espeak: as basic TTS engine')
|
print('- Espeak: as basic TTS engine')
|
||||||
print('- BrlTTY: for Braille')
|
|
||||||
print('- sox: is a player for the generic sound driver')
|
print('- sox: is a player for the generic sound driver')
|
||||||
|
107
src/fenrir
107
src/fenrir
@ -2,20 +2,115 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
import os, sys, inspect
|
import os
|
||||||
|
import sys
|
||||||
|
import inspect
|
||||||
|
import argparse
|
||||||
|
from daemonize import Daemonize
|
||||||
|
|
||||||
|
# Get the fenrir installation path
|
||||||
fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
||||||
|
|
||||||
if not fenrirPath in sys.path:
|
if not fenrirPath in sys.path:
|
||||||
sys.path.append(fenrirPath)
|
sys.path.append(fenrirPath)
|
||||||
|
|
||||||
from fenrirscreenreader.core import fenrirManager
|
from fenrirscreenreader.core import fenrirManager
|
||||||
|
from fenrirscreenreader import fenrirVersion
|
||||||
|
|
||||||
|
def create_argument_parser():
|
||||||
|
"""Create and return the argument parser for Fenrir"""
|
||||||
|
argumentParser = argparse.ArgumentParser(
|
||||||
|
description="Fenrir - A console screen reader for Linux",
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-v', '--version',
|
||||||
|
action='version',
|
||||||
|
version=f'Fenrir screen reader version {fenrirVersion.version}-{fenrirVersion.codeName}',
|
||||||
|
help='Show version information and exit'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-f', '--foreground',
|
||||||
|
action='store_true',
|
||||||
|
help='Run Fenrir in the foreground (default: run as daemon)'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-s', '--setting',
|
||||||
|
metavar='SETTING-FILE',
|
||||||
|
default='/etc/fenrir/settings/settings.conf',
|
||||||
|
help='Path to custom settings file'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-o', '--options',
|
||||||
|
metavar='SECTION#SETTING=VALUE;..',
|
||||||
|
default='',
|
||||||
|
help='Override settings file options. Format: SECTION#SETTING=VALUE;... (case sensitive)'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-d', '--debug',
|
||||||
|
action='store_true',
|
||||||
|
help='Enable debug mode'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-p', '--print',
|
||||||
|
action='store_true',
|
||||||
|
help='Print debug messages to screen'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-e', '--emulated-pty',
|
||||||
|
action='store_true',
|
||||||
|
help='Use PTY emulation with escape sequences for input (enables desktop/X/Wayland usage)'
|
||||||
|
)
|
||||||
|
argumentParser.add_argument(
|
||||||
|
'-E', '--emulated-evdev',
|
||||||
|
action='store_true',
|
||||||
|
help='Use PTY emulation with evdev for input (single instance)'
|
||||||
|
)
|
||||||
|
return argumentParser
|
||||||
|
|
||||||
|
def validate_arguments(cliArgs):
|
||||||
|
"""Validate command line arguments"""
|
||||||
|
if cliArgs.options:
|
||||||
|
for option in cliArgs.options.split(';'):
|
||||||
|
if option and ('#' not in option or '=' not in option):
|
||||||
|
return False, f"Invalid option format: {option}\nExpected format: SECTION#SETTING=VALUE"
|
||||||
|
|
||||||
|
if cliArgs.emulated_pty and cliArgs.emulated_evdev:
|
||||||
|
return False, "Cannot use both --emulated-pty and --emulated-evdev simultaneously"
|
||||||
|
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
def run_fenrir():
|
||||||
|
"""Main function that runs Fenrir"""
|
||||||
|
fenrirApp = fenrirManager.fenrirManager(cliArgs)
|
||||||
|
fenrirApp.proceed()
|
||||||
|
del fenrirApp
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
app = fenrirManager.fenrirManager()
|
global cliArgs
|
||||||
app.proceed()
|
argumentParser = create_argument_parser()
|
||||||
del app
|
cliArgs = argumentParser.parse_args()
|
||||||
|
|
||||||
|
# Validate arguments
|
||||||
|
isValid, errorMsg = validate_arguments(cliArgs)
|
||||||
|
if not isValid:
|
||||||
|
argumentParser.error(errorMsg)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if cliArgs.foreground:
|
||||||
|
# Run directly in foreground
|
||||||
|
run_fenrir()
|
||||||
|
else:
|
||||||
|
# Run as daemon
|
||||||
|
pidFile = "/run/fenrir.pid"
|
||||||
|
daemonProcess = Daemonize(
|
||||||
|
app="fenrir",
|
||||||
|
pid=pidFile,
|
||||||
|
action=run_fenrir,
|
||||||
|
chdir=fenrirPath
|
||||||
|
)
|
||||||
|
daemonProcess.start()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
import os, sys, inspect
|
|
||||||
fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
|
||||||
|
|
||||||
if not fenrirPath in sys.path:
|
|
||||||
sys.path.append(fenrirPath)
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import fenrirManager
|
|
||||||
from daemonize import Daemonize
|
|
||||||
|
|
||||||
pidFile = "/run/fenrir.pid"
|
|
||||||
|
|
||||||
def main():
|
|
||||||
app = fenrirManager.fenrirManager()
|
|
||||||
app.proceed()
|
|
||||||
del app
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# for debug in foreground
|
|
||||||
#daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, foreground=True,chdir=fenrirPath)
|
|
||||||
daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, chdir=fenrirPath)
|
|
||||||
daemon.start()
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
|||||||
#!/usr/bin/env pypy3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
import os, sys, inspect
|
|
||||||
fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
|
||||||
|
|
||||||
if not fenrirPath in sys.path:
|
|
||||||
sys.path.append(fenrirPath)
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import fenrirManager
|
|
||||||
from daemonize import Daemonize
|
|
||||||
|
|
||||||
pidFile = "/run/fenrir.pid"
|
|
||||||
|
|
||||||
def main():
|
|
||||||
app = fenrirManager.fenrirManager()
|
|
||||||
app.proceed()
|
|
||||||
del app
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# for debug in foreground
|
|
||||||
#daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, foreground=True,chdir=os.path.dirname(os.path.realpath(fenrirVersion.__file__)))
|
|
||||||
daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, chdir=fenrirPath)
|
|
||||||
daemon.start()
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env pypy3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
import os, sys, inspect
|
|
||||||
fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
|
|
||||||
|
|
||||||
if not fenrirPath in sys.path:
|
|
||||||
sys.path.append(fenrirPath)
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import fenrirManager
|
|
||||||
|
|
||||||
def main():
|
|
||||||
app = fenrirManager.fenrirManager()
|
|
||||||
app.proceed()
|
|
||||||
del app
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
@ -1,66 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
from fenrirscreenreader.core.brailleDriver import brailleDriver
|
|
||||||
|
|
||||||
class driver(brailleDriver):
|
|
||||||
def __init__(self):
|
|
||||||
brailleDriver.__init__(self)
|
|
||||||
self._brl = None
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
try:
|
|
||||||
import brlapi
|
|
||||||
self._brl = brlapi.Connection()
|
|
||||||
self._deviceSize = self._brl.displaySize
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
|
|
||||||
return
|
|
||||||
self._isInitialized = True
|
|
||||||
|
|
||||||
def getDeviceSize(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return (0,0)
|
|
||||||
if not self._deviceSize:
|
|
||||||
return (0,0)
|
|
||||||
return self._deviceSize
|
|
||||||
|
|
||||||
def flush(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._brl.writeText('',0)
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('BRAILLE.flush '+str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def writeText(self,text):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._brl.writeText(text)
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('BRAILLE.writeText '+str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def connectDevice(self):
|
|
||||||
self._brl = brlapi.Connection()
|
|
||||||
|
|
||||||
def enterScreen(self, screen):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
self._brl.enterTtyMode(int(screen))
|
|
||||||
|
|
||||||
def leveScreen(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
self._brl.leaveTtyMode()
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
self.leveScreen()
|
|
@ -1,49 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
from fenrirscreenreader.core.brailleDriver import brailleDriver
|
|
||||||
|
|
||||||
class driver(brailleDriver):
|
|
||||||
def __init__(self):
|
|
||||||
brailleDriver.__init__(self)
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
self._isInitialized = True
|
|
||||||
self.deviceSize = (40,0)
|
|
||||||
print('Braille Debug Driver: Initialized')
|
|
||||||
|
|
||||||
def getDeviceSize(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return (0,0)
|
|
||||||
print('Braille Debug Driver: getDeviceSize ' + str(self.deviceSize))
|
|
||||||
return self.deviceSize
|
|
||||||
|
|
||||||
def writeText(self,text):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
print('Braille Debug Driver: writeText:' + str(text))
|
|
||||||
print('Braille Debug Driver: -----------------------------------')
|
|
||||||
|
|
||||||
def connectDevice(self):
|
|
||||||
print('Braille Debug Driver: connectDevice')
|
|
||||||
|
|
||||||
def enterScreen(self, screen):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
print('Braille Debug Driver: enterScreen')
|
|
||||||
|
|
||||||
def leveScreen(self):
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
print('Braille Debug Driver: leveScreen')
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
if self._isInitialized:
|
|
||||||
self.leveScreen()
|
|
||||||
self._isInitialized = False
|
|
||||||
print('Braille Debug Driver: Shutdown')
|
|
@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
from fenrirscreenreader.core.brailleDriver import brailleDriver
|
|
||||||
|
|
||||||
class driver(brailleDriver):
|
|
||||||
def __init__(self):
|
|
||||||
brailleDriver.__init__(self)
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class command():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
def getDescription(self):
|
|
||||||
return _('Clear the Braille device if it is displaying a message')
|
|
||||||
def run(self):
|
|
||||||
self.env['runtime']['outputManager'].clearFlushTime()
|
|
||||||
def setCallback(self, callback):
|
|
||||||
pass
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class command():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
def getDescription(self):
|
|
||||||
return _('Move braille view to the left.')
|
|
||||||
def run(self):
|
|
||||||
panned = self.env['runtime']['outputManager'].setPanLeft()
|
|
||||||
def setCallback(self, callback):
|
|
||||||
pass
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class command():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
def getDescription(self):
|
|
||||||
return _('Move braille view to the right.')
|
|
||||||
def run(self):
|
|
||||||
panned = self.env['runtime']['outputManager'].setPanRight()
|
|
||||||
def setCallback(self, callback):
|
|
||||||
pass
|
|
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class command():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
def getDescription(self):
|
|
||||||
return _('Set the braille view back to cursor.')
|
|
||||||
def run(self):
|
|
||||||
self.env['runtime']['outputManager'].removePanning()
|
|
||||||
def setCallback(self, callback):
|
|
||||||
pass
|
|
@ -1,27 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class command():
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
def initialize(self, environment):
|
|
||||||
self.env = environment
|
|
||||||
def shutdown(self):
|
|
||||||
pass
|
|
||||||
def getDescription(self):
|
|
||||||
return _('Enables and disables Braille output')
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
|
||||||
self.env['runtime']['outputManager'].presentText(_('braille disabled'), soundIcon='BrailleOff', interrupt=True)
|
|
||||||
self.env['runtime']['settingsManager'].setSetting('braille', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled')))
|
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
|
||||||
self.env['runtime']['outputManager'].presentText(_('braille enabled'), soundIcon='BrailleOn', interrupt=True)
|
|
||||||
|
|
||||||
def setCallback(self, callback):
|
|
||||||
pass
|
|
@ -18,16 +18,13 @@ class command():
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled') or \
|
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled') or \
|
||||||
self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled') or \
|
self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
|
||||||
self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
|
||||||
self.env['runtime']['outputManager'].presentText(_('Fenrir muted'), soundIcon='Accept', interrupt=True)
|
self.env['runtime']['outputManager'].presentText(_('Fenrir muted'), soundIcon='Accept', interrupt=True)
|
||||||
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','False')
|
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','False')
|
||||||
self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','False')
|
self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','False')
|
||||||
self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','False')
|
|
||||||
else:
|
else:
|
||||||
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','True')
|
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','True')
|
||||||
self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','True')
|
self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','True')
|
||||||
self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','True')
|
|
||||||
self.env['runtime']['outputManager'].presentText(_('Fenrir unmuted'), soundIcon='Cancel', interrupt=True)
|
self.env['runtime']['outputManager'].presentText(_('Fenrir unmuted'), soundIcon='Cancel', interrupt=True)
|
||||||
|
|
||||||
def setCallback(self, callback):
|
def setCallback(self, callback):
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Fenrir TTY screen reader
|
|
||||||
# By Chrys, Storm Dragon, and contributors.
|
|
||||||
|
|
||||||
import brlapi
|
|
||||||
from fenrirscreenreader.core import debug
|
|
||||||
|
|
||||||
class brailleDriver():
|
|
||||||
def __init__(self):
|
|
||||||
self._isInitialized = False
|
|
||||||
self._brl = None
|
|
||||||
self.deviceSize = None
|
|
||||||
|
|
||||||
def initialize(self, environment):
|
|
||||||
"""Initialize the BRLTTY connection."""
|
|
||||||
self.env = environment
|
|
||||||
try:
|
|
||||||
self._brl = brlapi.Connection()
|
|
||||||
self._brl.enterTtyMode()
|
|
||||||
self.deviceSize = self._brl.displaySize
|
|
||||||
self._isInitialized = True
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Initializing braille failed:' + str(e),debug.debugLevel.ERROR)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getDeviceSize(self):
|
|
||||||
"""Get the size of the braille display."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return (0, 0)
|
|
||||||
return self.deviceSize if self.deviceSize else (0, 0)
|
|
||||||
|
|
||||||
def writeText(self, text):
|
|
||||||
"""Write text to the braille display."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._brl.writeText(text)
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Writing braille failed:' + str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def readKeypress(self):
|
|
||||||
"""Read a keypress from the braille display."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return None
|
|
||||||
try:
|
|
||||||
return self._brl.readKey(wait=0)
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Reading key failed:' + str(e),debug.debugLevel.ERROR)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def enterScreen(self, screen):
|
|
||||||
"""Enter a new screen context."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._brl.enterTtyModeWithPath(screen)
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Entering screen failed:' + str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def leaveScreen(self):
|
|
||||||
"""Leave the current screen context."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self._brl.leaveTtyMode()
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Leaving screen failed:' + str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
"""Shutdown the braille driver."""
|
|
||||||
if not self._isInitialized:
|
|
||||||
return
|
|
||||||
try:
|
|
||||||
self.leaveScreen()
|
|
||||||
if self._brl:
|
|
||||||
self._brl.closeConnection()
|
|
||||||
self._brl = None
|
|
||||||
self._isInitialized = False
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('ERROR: Shutting down braille failed:' + str(e),debug.debugLevel.ERROR)
|
|
@ -12,14 +12,12 @@ class fenrirEventType(Enum):
|
|||||||
StopMainLoop = 1
|
StopMainLoop = 1
|
||||||
ScreenUpdate = 2
|
ScreenUpdate = 2
|
||||||
KeyboardInput = 3
|
KeyboardInput = 3
|
||||||
BrailleInput = 4
|
PlugInputDevice = 4
|
||||||
PlugInputDevice = 5
|
ScreenChanged = 5
|
||||||
BrailleFlush = 6
|
HeartBeat = 6
|
||||||
ScreenChanged = 7
|
ExecuteCommand = 7
|
||||||
HeartBeat = 8 # for time based scheduling
|
ByteInput = 8
|
||||||
ExecuteCommand = 9
|
RemoteIncomming = 9
|
||||||
ByteInput = 10
|
|
||||||
RemoteIncomming = 11
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
return self.value
|
return self.value
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -42,12 +42,8 @@ class eventManager():
|
|||||||
self.env['runtime']['fenrirManager'].handleScreenUpdate(event)
|
self.env['runtime']['fenrirManager'].handleScreenUpdate(event)
|
||||||
elif event['Type'] == fenrirEventType.KeyboardInput:
|
elif event['Type'] == fenrirEventType.KeyboardInput:
|
||||||
self.env['runtime']['fenrirManager'].handleInput(event)
|
self.env['runtime']['fenrirManager'].handleInput(event)
|
||||||
elif event['Type'] == fenrirEventType.BrailleInput:
|
|
||||||
pass
|
|
||||||
elif event['Type'] == fenrirEventType.PlugInputDevice:
|
elif event['Type'] == fenrirEventType.PlugInputDevice:
|
||||||
self.env['runtime']['fenrirManager'].handlePlugInputDevice(event)
|
self.env['runtime']['fenrirManager'].handlePlugInputDevice(event)
|
||||||
elif event['Type'] == fenrirEventType.BrailleFlush:
|
|
||||||
pass
|
|
||||||
elif event['Type'] == fenrirEventType.ScreenChanged:
|
elif event['Type'] == fenrirEventType.ScreenChanged:
|
||||||
self.env['runtime']['fenrirManager'].handleScreenChange(event)
|
self.env['runtime']['fenrirManager'].handleScreenChange(event)
|
||||||
elif event['Type'] == fenrirEventType.HeartBeat:
|
elif event['Type'] == fenrirEventType.HeartBeat:
|
||||||
|
@ -2,109 +2,50 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
import signal, time, argparse, os, sys
|
import signal
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from fenrirscreenreader.core import i18n
|
from fenrirscreenreader.core import i18n
|
||||||
from fenrirscreenreader.core import settingsManager
|
from fenrirscreenreader.core import settingsManager
|
||||||
from fenrirscreenreader.core import debug
|
from fenrirscreenreader.core import debug
|
||||||
from fenrirscreenreader.core.eventData import fenrirEventType
|
from fenrirscreenreader.core.eventData import fenrirEventType
|
||||||
from fenrirscreenreader import fenrirVersion
|
|
||||||
|
|
||||||
class fenrirManager():
|
class fenrirManager():
|
||||||
def __init__(self):
|
def __init__(self, cliArgs):
|
||||||
self.initialized = False
|
self.isInitialized = False
|
||||||
cliArgs = self.handleArgs()
|
|
||||||
if not cliArgs:
|
|
||||||
return
|
|
||||||
try:
|
try:
|
||||||
self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self)
|
self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self)
|
||||||
if not self.environment:
|
if not self.environment:
|
||||||
raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
|
raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True)
|
self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True)
|
||||||
signal.signal(signal.SIGINT, self.captureSignal)
|
signal.signal(signal.SIGINT, self.captureSignal)
|
||||||
signal.signal(signal.SIGTERM, self.captureSignal)
|
signal.signal(signal.SIGTERM, self.captureSignal)
|
||||||
self.initialized = True
|
|
||||||
|
self.isInitialized = True
|
||||||
self.modifierInput = False
|
self.modifierInput = False
|
||||||
self.singleKeyCommand = False
|
self.singleKeyCommand = False
|
||||||
self.command = ''
|
self.command = ''
|
||||||
self.setProcessName()
|
self.setProcessName()
|
||||||
def handleArgs(self):
|
|
||||||
"""
|
|
||||||
Parse and handle command line arguments for Fenrir.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
argparse.Namespace: Parsed command line arguments
|
|
||||||
None: If argument parsing fails
|
|
||||||
"""
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Fenrir - A console screen reader for Linux",
|
|
||||||
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-v', '--version',
|
|
||||||
action='version',
|
|
||||||
version=f'Fenrir screen reader version {fenrirVersion.version}-{fenrirVersion.codeName}',
|
|
||||||
help='Show version information and exit'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-s', '--setting',
|
|
||||||
metavar='SETTING-FILE',
|
|
||||||
default='/etc/fenrir/settings/settings.conf',
|
|
||||||
help='Path to custom settings file'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-o', '--options',
|
|
||||||
metavar='SECTION#SETTING=VALUE;..',
|
|
||||||
default='',
|
|
||||||
help='Override settings file options. Format: SECTION#SETTING=VALUE;... (case sensitive)'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-d', '--debug',
|
|
||||||
action='store_true',
|
|
||||||
help='Enable debug mode'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-p', '--print',
|
|
||||||
action='store_true',
|
|
||||||
help='Print debug messages to screen'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-e', '--emulated-pty',
|
|
||||||
action='store_true',
|
|
||||||
help='Use PTY emulation with escape sequences for input (enables desktop/X/Wayland usage)'
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'-E', '--emulated-evdev',
|
|
||||||
action='store_true',
|
|
||||||
help='Use PTY emulation with evdev for input (single instance)'
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
args = parser.parse_args()
|
|
||||||
# Only do format validation, let file existence be handled by the config initialization
|
|
||||||
if args.options:
|
|
||||||
for option in args.options.split(';'):
|
|
||||||
if option and ('#' not in option or '=' not in option):
|
|
||||||
parser.error(f"Invalid option format: {option}\nExpected format: SECTION#SETTING=VALUE")
|
|
||||||
if args.emulated_pty and args.emulated_evdev:
|
|
||||||
parser.error("Cannot use both --emulated-pty and --emulated-evdev simultaneously")
|
|
||||||
return args
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error parsing arguments: {str(e)}", file=sys.stderr)
|
|
||||||
return None
|
|
||||||
def proceed(self):
|
def proceed(self):
|
||||||
if not self.initialized:
|
if not self.isInitialized:
|
||||||
return
|
return
|
||||||
self.environment['runtime']['eventManager'].startMainEventLoop()
|
self.environment['runtime']['eventManager'].startMainEventLoop()
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def handleInput(self, event):
|
def handleInput(self, event):
|
||||||
#startTime = time.time()
|
|
||||||
self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event), debug.debugLevel.INFO)
|
self.environment['runtime']['debug'].writeDebugOut('DEBUG INPUT fenrirMan:' + str(event), debug.debugLevel.INFO)
|
||||||
|
|
||||||
if not event['Data']:
|
if not event['Data']:
|
||||||
event['Data'] = self.environment['runtime']['inputManager'].getInputEvent()
|
event['Data'] = self.environment['runtime']['inputManager'].getInputEvent()
|
||||||
|
|
||||||
if event['Data']:
|
if event['Data']:
|
||||||
event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName'])
|
event['Data']['EventName'] = self.environment['runtime']['inputManager'].convertEventName(event['Data']['EventName'])
|
||||||
self.environment['runtime']['inputManager'].handleInputEvent(event['Data'])
|
self.environment['runtime']['inputManager'].handleInputEvent(event['Data'])
|
||||||
@ -113,6 +54,7 @@ class fenrirManager():
|
|||||||
|
|
||||||
if self.environment['runtime']['inputManager'].noKeyPressed():
|
if self.environment['runtime']['inputManager'].noKeyPressed():
|
||||||
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
||||||
|
|
||||||
if self.environment['runtime']['screenManager'].isSuspendingScreen():
|
if self.environment['runtime']['screenManager'].isSuspendingScreen():
|
||||||
self.environment['runtime']['inputManager'].writeEventBuffer()
|
self.environment['runtime']['inputManager'].writeEventBuffer()
|
||||||
else:
|
else:
|
||||||
@ -132,6 +74,7 @@ class fenrirManager():
|
|||||||
self.environment['runtime']['inputManager'].clearEventBuffer()
|
self.environment['runtime']['inputManager'].clearEventBuffer()
|
||||||
else:
|
else:
|
||||||
self.environment['runtime']['inputManager'].writeEventBuffer()
|
self.environment['runtime']['inputManager'].writeEventBuffer()
|
||||||
|
|
||||||
if self.environment['runtime']['inputManager'].noKeyPressed():
|
if self.environment['runtime']['inputManager'].noKeyPressed():
|
||||||
self.modifierInput = False
|
self.modifierInput = False
|
||||||
self.singleKeyCommand = False
|
self.singleKeyCommand = False
|
||||||
@ -140,72 +83,58 @@ class fenrirManager():
|
|||||||
|
|
||||||
if self.environment['input']['keyForeward'] > 0:
|
if self.environment['input']['keyForeward'] > 0:
|
||||||
self.environment['input']['keyForeward'] -= 1
|
self.environment['input']['keyForeward'] -= 1
|
||||||
|
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
|
||||||
#print('handleInput:',time.time() - startTime)
|
|
||||||
def handleByteInput(self, event):
|
def handleByteInput(self, event):
|
||||||
if not event['Data']:
|
if not event['Data'] or event['Data'] == b'':
|
||||||
return
|
|
||||||
if event['Data'] == b'':
|
|
||||||
return
|
return
|
||||||
self.environment['runtime']['byteManager'].handleByteInput(event['Data'])
|
self.environment['runtime']['byteManager'].handleByteInput(event['Data'])
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onByteInput')
|
||||||
|
|
||||||
def handleExecuteCommand(self, event):
|
def handleExecuteCommand(self, event):
|
||||||
if not event['Data']:
|
if not event['Data'] or event['Data'] == '':
|
||||||
return
|
return
|
||||||
if event['Data'] == '':
|
currentCommand = event['Data']
|
||||||
return
|
|
||||||
command = event['Data']
|
|
||||||
|
|
||||||
# special modes
|
# special modes
|
||||||
if self.environment['runtime']['helpManager'].isTutorialMode():
|
if self.environment['runtime']['helpManager'].isTutorialMode():
|
||||||
if self.environment['runtime']['commandManager'].commandExists( command, 'help'):
|
if self.environment['runtime']['commandManager'].commandExists(currentCommand, 'help'):
|
||||||
self.environment['runtime']['commandManager'].executeCommand( command, 'help')
|
self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'help')
|
||||||
return
|
return
|
||||||
elif self.environment['runtime']['vmenuManager'].getActive():
|
elif self.environment['runtime']['vmenuManager'].getActive():
|
||||||
if self.environment['runtime']['commandManager'].commandExists( command, 'vmenu-navigation'):
|
if self.environment['runtime']['commandManager'].commandExists(currentCommand, 'vmenu-navigation'):
|
||||||
self.environment['runtime']['commandManager'].executeCommand( command, 'vmenu-navigation')
|
self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'vmenu-navigation')
|
||||||
return
|
return
|
||||||
|
|
||||||
# default
|
# default
|
||||||
self.environment['runtime']['commandManager'].executeCommand( command, 'commands')
|
self.environment['runtime']['commandManager'].executeCommand(currentCommand, 'commands')
|
||||||
|
|
||||||
def handleRemoteIncomming(self, event):
|
def handleRemoteIncomming(self, event):
|
||||||
if not event['Data']:
|
if not event['Data']:
|
||||||
return
|
return
|
||||||
self.environment['runtime']['remoteManager'].handleRemoteIncomming(event['Data'])
|
self.environment['runtime']['remoteManager'].handleRemoteIncomming(event['Data'])
|
||||||
|
|
||||||
def handleScreenChange(self, event):
|
def handleScreenChange(self, event):
|
||||||
self.environment['runtime']['screenManager'].hanldeScreenChange(event['Data'])
|
self.environment['runtime']['screenManager'].hanldeScreenChange(event['Data'])
|
||||||
'''
|
|
||||||
if self.environment['runtime']['applicationManager'].isApplicationChange():
|
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
|
|
||||||
self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
|
|
||||||
self.environment['runtime']['applicationManager'].getPrevApplication(), \
|
|
||||||
self.environment['runtime']['applicationManager'].getCurrentApplication())
|
|
||||||
'''
|
|
||||||
if self.environment['runtime']['vmenuManager'].getActive():
|
if self.environment['runtime']['vmenuManager'].getActive():
|
||||||
return
|
return
|
||||||
|
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
|
||||||
self.environment['runtime']['screenDriver'].getCurrScreen()
|
self.environment['runtime']['screenDriver'].getCurrScreen()
|
||||||
|
|
||||||
def handleScreenUpdate(self, event):
|
def handleScreenUpdate(self, event):
|
||||||
#startTime = time.time()
|
|
||||||
self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data'])
|
self.environment['runtime']['screenManager'].handleScreenUpdate(event['Data'])
|
||||||
'''
|
|
||||||
if self.environment['runtime']['applicationManager'].isApplicationChange():
|
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
|
|
||||||
self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
|
|
||||||
self.environment['runtime']['applicationManager'].getPrevApplication(), \
|
|
||||||
self.environment['runtime']['applicationManager'].getCurrentApplication())
|
|
||||||
'''
|
|
||||||
# timout for the last keypress
|
|
||||||
if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
|
if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
|
||||||
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
||||||
# has cursor changed?
|
|
||||||
if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \
|
if (self.environment['runtime']['cursorManager'].isCursorVerticalMove() or
|
||||||
self.environment['runtime']['cursorManager'].isCursorHorizontalMove():
|
self.environment['runtime']['cursorManager'].isCursorHorizontalMove()):
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
|
||||||
|
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
|
||||||
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
self.environment['runtime']['inputManager'].clearLastDeepInput()
|
||||||
#print('handleScreenUpdate:',time.time() - startTime)
|
|
||||||
def handlePlugInputDevice(self, event):
|
def handlePlugInputDevice(self, event):
|
||||||
try:
|
try:
|
||||||
self.environment['runtime']['inputManager'].setLastDetectedDevices(event['Data'])
|
self.environment['runtime']['inputManager'].setLastDetectedDevices(event['Data'])
|
||||||
@ -214,26 +143,27 @@ class fenrirManager():
|
|||||||
self.environment['runtime']['inputManager'].handlePlugInputDevice(event['Data'])
|
self.environment['runtime']['inputManager'].handlePlugInputDevice(event['Data'])
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)
|
||||||
self.environment['runtime']['inputManager'].setLastDetectedDevices(None)
|
self.environment['runtime']['inputManager'].setLastDetectedDevices(None)
|
||||||
|
|
||||||
def handleHeartBeat(self, event):
|
def handleHeartBeat(self, event):
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat', force=True)
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat', force=True)
|
||||||
#self.environment['runtime']['outputManager'].brailleText(flush=False)
|
|
||||||
|
|
||||||
|
|
||||||
def detectShortcutCommand(self):
|
def detectShortcutCommand(self):
|
||||||
if self.environment['input']['keyForeward'] > 0:
|
if self.environment['input']['keyForeward'] > 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(self.environment['input']['prevInput']) > len(self.environment['input']['currInput']):
|
if len(self.environment['input']['prevInput']) > len(self.environment['input']['currInput']):
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.environment['runtime']['inputManager'].isKeyPress():
|
if self.environment['runtime']['inputManager'].isKeyPress():
|
||||||
self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier()
|
self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier()
|
||||||
else:
|
else:
|
||||||
if not self.environment['runtime']['inputManager'].noKeyPressed():
|
if not self.environment['runtime']['inputManager'].noKeyPressed():
|
||||||
if self.singleKeyCommand:
|
if self.singleKeyCommand:
|
||||||
self.singleKeyCommand = len(self.environment['input']['currInput']) == 1
|
self.singleKeyCommand = len(self.environment['input']['currInput']) == 1
|
||||||
# key is already released. we need the old one
|
|
||||||
if not(self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
|
if not(self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
|
||||||
shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
|
currentShortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
|
||||||
self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut)
|
self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(currentShortcut)
|
||||||
|
|
||||||
if not self.modifierInput:
|
if not self.modifierInput:
|
||||||
if self.environment['runtime']['inputManager'].isKeyPress():
|
if self.environment['runtime']['inputManager'].isKeyPress():
|
||||||
@ -252,6 +182,7 @@ class fenrirManager():
|
|||||||
if self.singleKeyCommand:
|
if self.singleKeyCommand:
|
||||||
self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
|
self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
|
||||||
self.command = ''
|
self.command = ''
|
||||||
|
|
||||||
def setProcessName(self, name='fenrir'):
|
def setProcessName(self, name='fenrir'):
|
||||||
"""Attempts to set the process name to 'fenrir'."""
|
"""Attempts to set the process name to 'fenrir'."""
|
||||||
try:
|
try:
|
||||||
@ -273,12 +204,14 @@ class fenrirManager():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def shutdownRequest(self):
|
def shutdownRequest(self):
|
||||||
try:
|
try:
|
||||||
self.environment['runtime']['eventManager'].stopMainEventLoop()
|
self.environment['runtime']['eventManager'].stopMainEventLoop()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
def captureSignal(self, siginit, frame):
|
|
||||||
|
def captureSignal(self, sigInit, frame):
|
||||||
self.shutdownRequest()
|
self.shutdownRequest()
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
@ -287,10 +220,10 @@ class fenrirManager():
|
|||||||
self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
|
self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
|
||||||
self.environment['runtime']['eventManager'].cleanEventQueue()
|
self.environment['runtime']['eventManager'].cleanEventQueue()
|
||||||
time.sleep(0.6)
|
time.sleep(0.6)
|
||||||
for currManager in self.environment['general']['managerList']:
|
|
||||||
if self.environment['runtime'][currManager]:
|
for currentManager in self.environment['general']['managerList']:
|
||||||
self.environment['runtime'][currManager].shutdown()
|
if self.environment['runtime'][currentManager]:
|
||||||
del self.environment['runtime'][currManager]
|
self.environment['runtime'][currentManager].shutdown()
|
||||||
|
del self.environment['runtime'][currentManager]
|
||||||
|
|
||||||
self.environment = None
|
self.environment = None
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env python3
|
#!/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
# By Chrys, Storm Dragon, and contributers.
|
# By Chrys, Storm Dragon, and contributors.
|
||||||
|
|
||||||
from fenrirscreenreader.core import debug
|
from fenrirscreenreader.core import debug
|
||||||
from fenrirscreenreader.utils import line_utils
|
from fenrirscreenreader.utils import line_utils
|
||||||
@ -11,20 +11,19 @@ import string, time, re
|
|||||||
class outputManager():
|
class outputManager():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.lastEcho = ''
|
self.lastEcho = ''
|
||||||
|
|
||||||
def initialize(self, environment):
|
def initialize(self, environment):
|
||||||
self.env = environment
|
self.env = environment
|
||||||
self.env['runtime']['settingsManager'].loadDriver(\
|
self.env['runtime']['settingsManager'].loadDriver(
|
||||||
self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver')
|
self.env['runtime']['settingsManager'].getSetting('speech', 'driver'), 'speechDriver')
|
||||||
self.env['runtime']['settingsManager'].loadDriver(\
|
self.env['runtime']['settingsManager'].loadDriver(
|
||||||
self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver')
|
self.env['runtime']['settingsManager'].getSetting('sound', 'driver'), 'soundDriver')
|
||||||
self.env['runtime']['settingsManager'].loadDriver(\
|
|
||||||
self.env['runtime']['settingsManager'].getSetting('braille', 'driver'), 'brailleDriver')
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
|
self.env['runtime']['settingsManager'].shutdownDriver('soundDriver')
|
||||||
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
|
self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
|
||||||
self.env['runtime']['settingsManager'].shutdownDriver('brailleDriver')
|
|
||||||
|
|
||||||
def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False, flush=True, brailleAlternative = ''):
|
def presentText(self, text, interrupt=True, soundIcon='', ignorePunctuation=False, announceCapital=False, flush=True):
|
||||||
if text == '':
|
if text == '':
|
||||||
return
|
return
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'readNumbersAsDigits') and len(text.strip()) > 1:
|
if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'readNumbersAsDigits') and len(text.strip()) > 1:
|
||||||
@ -41,14 +40,10 @@ class outputManager():
|
|||||||
toAnnounceCapital = False
|
toAnnounceCapital = False
|
||||||
self.lastEcho = text
|
self.lastEcho = text
|
||||||
self.speakText(text, interrupt, ignorePunctuation, toAnnounceCapital)
|
self.speakText(text, interrupt, ignorePunctuation, toAnnounceCapital)
|
||||||
if flush:
|
|
||||||
if brailleAlternative != '':
|
|
||||||
brlText = brailleAlternative
|
|
||||||
else:
|
|
||||||
brlText = text
|
|
||||||
self.brailleText(brlText, flush)
|
|
||||||
def getLastEcho(self):
|
def getLastEcho(self):
|
||||||
return self.lastEcho
|
return self.lastEcho
|
||||||
|
|
||||||
def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False):
|
def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False):
|
||||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
|
if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
|
||||||
self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText", debug.debugLevel.INFO)
|
self.env['runtime']['debug'].writeDebugOut("Speech disabled in outputManager.speakText", debug.debugLevel.INFO)
|
||||||
@ -112,132 +107,6 @@ class outputManager():
|
|||||||
self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ", debug.debugLevel.ERROR)
|
self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ", debug.debugLevel.ERROR)
|
||||||
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
|
self.env['runtime']['debug'].writeDebugOut(str(e), debug.debugLevel.ERROR)
|
||||||
|
|
||||||
def brailleText(self, text='', flush=True):
|
|
||||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
|
||||||
return
|
|
||||||
if self.env['runtime']['brailleDriver'] == None:
|
|
||||||
return
|
|
||||||
if flush:
|
|
||||||
self.env['output']['nextFlush'] = time.time() + self.getFlushTime(text)
|
|
||||||
self.env['output']['messageOffset'] = {'x':0,'y':0}
|
|
||||||
self.env['output']['messageText'] = text
|
|
||||||
displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
|
|
||||||
self.env['runtime']['brailleDriver'].writeText('flush '+ displayText)
|
|
||||||
else:
|
|
||||||
if self.env['output']['nextFlush'] < time.time():
|
|
||||||
if self.env['output']['messageText'] != '':
|
|
||||||
self.env['output']['messageText'] = ''
|
|
||||||
if self.env['output']['messageOffset'] != None:
|
|
||||||
self.env['output']['messageOffset'] = None
|
|
||||||
cursor = self.getBrailleCursor()
|
|
||||||
x, y, self.env['output']['brlText'] = \
|
|
||||||
line_utils.getCurrentLine(cursor['x'], cursor['y'], self.env['screen']['newContentText'])
|
|
||||||
displayText = self.getBrailleTextWithOffset(self.env['screen']['newContentText'], self.env['output']['cursorOffset'], cursor)
|
|
||||||
self.env['runtime']['brailleDriver'].writeText('notflush ' + displayText)
|
|
||||||
else:
|
|
||||||
displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
|
|
||||||
self.env['runtime']['brailleDriver'].writeText('flush'+displayText)
|
|
||||||
def resetSpeechDriver(self):
|
|
||||||
try:
|
|
||||||
self.env['runtime']['speechDriver'].reset()
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut("reset " + str(e),debug.debugLevel.ERROR)
|
|
||||||
|
|
||||||
def getBrailleCursor(self):
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'REVIEW':
|
|
||||||
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'MANUAL':
|
|
||||||
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'LAST':
|
|
||||||
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
|
||||||
return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
|
||||||
|
|
||||||
def getFixCursorCell(self):
|
|
||||||
size = self.env['runtime']['brailleDriver'].getDeviceSize()[0]
|
|
||||||
fixCell = self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'fixCursorOnCell')
|
|
||||||
if fixCell <= -1:
|
|
||||||
return size[0]
|
|
||||||
if fixCell >= size[0]:
|
|
||||||
return size[0]
|
|
||||||
return fixCell
|
|
||||||
def getActiveOffsetAndText(self):
|
|
||||||
if self.env['output']['messageOffset']:
|
|
||||||
return self.env['output']['messageOffset'], self.env['output']['messageText']
|
|
||||||
if not self.env['output']['cursorOffset']:
|
|
||||||
return self.getBrailleCursor(), self.env['screen']['newContentText']
|
|
||||||
return self.env['output']['cursorOffset'], self.env['screen']['newContentText']
|
|
||||||
def getHorizontalPanSize(self):
|
|
||||||
size = self.env['runtime']['brailleDriver'].getDeviceSize()
|
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') <= 0:
|
|
||||||
return size[0]
|
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') >= size[0]:
|
|
||||||
return size[0]
|
|
||||||
return self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal')
|
|
||||||
def getHorizontalPanLevel(self,offsetChange = 0):
|
|
||||||
panned = True
|
|
||||||
panSize = self.getHorizontalPanSize()
|
|
||||||
offset, text = self.getActiveOffsetAndText()
|
|
||||||
currline = text.split('\n')[offset['y']]
|
|
||||||
newOffsetStart = (int(offset['x'] / panSize) + offsetChange) * panSize
|
|
||||||
if newOffsetStart < 0:
|
|
||||||
newOffsetStart = 0
|
|
||||||
panned = False
|
|
||||||
if newOffsetStart >= len(text):
|
|
||||||
newOffsetStart = int((len(text) - panSize - 1) / panSize)
|
|
||||||
panned = False
|
|
||||||
return newOffsetStart, panned
|
|
||||||
def setPanLeft(self):
|
|
||||||
newPan, panned = self.getHorizontalPanLevel(-1)
|
|
||||||
if self.env['output']['messageOffset']:
|
|
||||||
self.env['output']['messageOffset'] = newPan.copy()
|
|
||||||
else:
|
|
||||||
self.env['output']['cursorOffset'] = newPan.copy()
|
|
||||||
return panned
|
|
||||||
def setPanRight(self):
|
|
||||||
newPan, panned = self.getHorizontalPanLevel(1)
|
|
||||||
if self.env['output']['messageOffset']:
|
|
||||||
self.env['output']['messageOffset'] = newPan.copy()
|
|
||||||
else:
|
|
||||||
self.env['output']['cursorOffset'] = newPan.copy()
|
|
||||||
return panned
|
|
||||||
def removePanning(self):
|
|
||||||
if self.env['output']['messageOffset']:
|
|
||||||
self.env['output']['messageOffset'] = None
|
|
||||||
else:
|
|
||||||
self.env['output']['cursorOffset'] = None
|
|
||||||
def getBrailleTextWithOffset(self, text, offset = None, cursor = None):
|
|
||||||
if text == '':
|
|
||||||
return ''
|
|
||||||
size = self.env['runtime']['brailleDriver'].getDeviceSize()
|
|
||||||
offsetText = text
|
|
||||||
|
|
||||||
if cursor and not offset:
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'FIXCELL':
|
|
||||||
#fix cell
|
|
||||||
cursorCell = self.getFixCursorCell()
|
|
||||||
offsetStart = cursor['x']
|
|
||||||
if offsetStart < size[0]:
|
|
||||||
if offsetStart <= cursorCell:
|
|
||||||
return offsetText[0: size[0]]
|
|
||||||
|
|
||||||
offsetStart -= cursorCell
|
|
||||||
if offsetStart >= len(offsetText):
|
|
||||||
offsetStart = len(offsetText) - 1
|
|
||||||
else:
|
|
||||||
# page and fallback
|
|
||||||
offsetStart = int(cursor['x'] / size[0]) * size[0]
|
|
||||||
else:
|
|
||||||
if not offset:
|
|
||||||
offset = {'x':0,'y':0}
|
|
||||||
offsetStart = offset['x']
|
|
||||||
if offsetStart >= len(offsetText):
|
|
||||||
offsetStart = len(offsetText) - size[0]
|
|
||||||
|
|
||||||
if offsetStart < 0:
|
|
||||||
offsetStart = 0
|
|
||||||
offsetEnd = offsetStart + size[0]
|
|
||||||
offsetText = offsetText[offsetStart: offsetEnd]
|
|
||||||
return offsetText
|
|
||||||
def interruptOutput(self):
|
def interruptOutput(self):
|
||||||
try:
|
try:
|
||||||
self.env['runtime']['speechDriver'].cancel()
|
self.env['runtime']['speechDriver'].cancel()
|
||||||
@ -245,24 +114,6 @@ class outputManager():
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def clearFlushTime(self):
|
|
||||||
self.setFlushTime(0.0)
|
|
||||||
|
|
||||||
def setFlushTime(self,newTime):
|
|
||||||
self.env['output']['nextFlush'] = newTime
|
|
||||||
|
|
||||||
def getFlushTime(self,text=''):
|
|
||||||
if self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') < 0 or \
|
|
||||||
self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'NONE':
|
|
||||||
return 999999999999
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'FIX':
|
|
||||||
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout')
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'CHAR':
|
|
||||||
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len(text)
|
|
||||||
if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'WORD':
|
|
||||||
wordsList = text.split(' ')
|
|
||||||
return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len( list( filter(None, wordsList) ) )
|
|
||||||
|
|
||||||
def playSoundIcon(self, soundIcon='', interrupt=True):
|
def playSoundIcon(self, soundIcon='', interrupt=True):
|
||||||
if soundIcon == '':
|
if soundIcon == '':
|
||||||
return False
|
return False
|
||||||
@ -335,9 +186,9 @@ class outputManager():
|
|||||||
self.env['commandBuffer']['enableSpeechOnKeypress'] = True
|
self.env['commandBuffer']['enableSpeechOnKeypress'] = True
|
||||||
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
|
self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
|
||||||
self.interruptOutput()
|
self.interruptOutput()
|
||||||
|
|
||||||
def announceActiveCursor(self, interrupt_p=False):
|
def announceActiveCursor(self, interrupt_p=False):
|
||||||
if self.env['runtime']['cursorManager'].isReviewMode():
|
if self.env['runtime']['cursorManager'].isReviewMode():
|
||||||
self.presentText(' review cursor ', interrupt=interrupt_p)
|
self.presentText(' review cursor ', interrupt=interrupt_p)
|
||||||
else:
|
else:
|
||||||
self.presentText(' text cursor ', interrupt=interrupt_p)
|
self.presentText(' text cursor ', interrupt=interrupt_p)
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ runtimeData = {
|
|||||||
'soundDriver': None,
|
'soundDriver': None,
|
||||||
'inputDriver': None,
|
'inputDriver': None,
|
||||||
'remoteDriver': None,
|
'remoteDriver': None,
|
||||||
'brailleDriver': None,
|
|
||||||
'inputManager': None,
|
'inputManager': None,
|
||||||
'commandManager': None,
|
'commandManager': None,
|
||||||
'screenManager': None,
|
'screenManager': None,
|
||||||
|
@ -59,8 +59,6 @@ class screenManager():
|
|||||||
if self.isCurrScreenIgnoredChanged():
|
if self.isCurrScreenIgnoredChanged():
|
||||||
self.env['runtime']['inputManager'].setExecuteDeviceGrab()
|
self.env['runtime']['inputManager'].setExecuteDeviceGrab()
|
||||||
self.env['runtime']['inputManager'].handleDeviceGrab()
|
self.env['runtime']['inputManager'].handleDeviceGrab()
|
||||||
if self.isScreenChange():
|
|
||||||
self.changeBrailleScreen()
|
|
||||||
if not self.isSuspendingScreen(self.env['screen']['newTTY']):
|
if not self.isSuspendingScreen(self.env['screen']['newTTY']):
|
||||||
self.update(eventData, 'onScreenChange')
|
self.update(eventData, 'onScreenChange')
|
||||||
self.env['screen']['lastScreenUpdate'] = time.time()
|
self.env['screen']['lastScreenUpdate'] = time.time()
|
||||||
@ -74,9 +72,6 @@ class screenManager():
|
|||||||
self.env['runtime']['inputManager'].handleDeviceGrab()
|
self.env['runtime']['inputManager'].handleDeviceGrab()
|
||||||
if not self.getCurrScreenIgnored():
|
if not self.getCurrScreenIgnored():
|
||||||
self.update(eventData, 'onScreenUpdate')
|
self.update(eventData, 'onScreenUpdate')
|
||||||
#if trigger == 'onUpdate' or self.isScreenChange() \
|
|
||||||
# or len(self.env['screen']['newDelta']) > 6:
|
|
||||||
# self.env['runtime']['screenDriver'].getCurrApplication()
|
|
||||||
self.env['screen']['lastScreenUpdate'] = time.time()
|
self.env['screen']['lastScreenUpdate'] = time.time()
|
||||||
elif self.isCurrScreenIgnoredChanged():
|
elif self.isCurrScreenIgnoredChanged():
|
||||||
self.env['runtime']['outputManager'].interruptOutput()
|
self.env['runtime']['outputManager'].interruptOutput()
|
||||||
@ -145,14 +140,10 @@ class screenManager():
|
|||||||
self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]:
|
self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]:
|
||||||
cursorLineStartOffset = cursorLineStart
|
cursorLineStartOffset = cursorLineStart
|
||||||
cursorLineEndOffset = cursorLineEnd
|
cursorLineEndOffset = cursorLineEnd
|
||||||
#if cursorLineStart < cursorLineStart + self.env['screen']['newCursor']['x'] - 4:
|
|
||||||
# cursorLineStartOffset = cursorLineStart + self.env['screen']['newCursor']['x'] - 4
|
|
||||||
if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
|
if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
|
||||||
cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
|
cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
|
||||||
oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
||||||
# oldScreenText = re.sub(' +',' ',oldScreenText)
|
|
||||||
newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
|
||||||
#newScreenText = re.sub(' +',' ',newScreenText)
|
|
||||||
diff = self.differ.compare(oldScreenText, newScreenText)
|
diff = self.differ.compare(oldScreenText, newScreenText)
|
||||||
diffList = list(diff)
|
diffList = list(diff)
|
||||||
typing = True
|
typing = True
|
||||||
@ -222,20 +213,3 @@ class screenManager():
|
|||||||
self.env['runtime']['screenDriver'].injectTextToScreen(text, screen)
|
self.env['runtime']['screenDriver'].injectTextToScreen(text, screen)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR)
|
self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR)
|
||||||
|
|
||||||
def changeBrailleScreen(self):
|
|
||||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
|
|
||||||
return
|
|
||||||
if not self.env['runtime']['brailleDriver']:
|
|
||||||
return
|
|
||||||
if self.env['screen']['oldTTY']:
|
|
||||||
if not self.isSuspendingScreen(self.env['screen']['oldTTY']):
|
|
||||||
try:
|
|
||||||
self.env['runtime']['brailleDriver'].leveScreen()
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:leveScreen ' + str(e),debug.debugLevel.ERROR)
|
|
||||||
if not self.isSuspendingScreen():
|
|
||||||
try:
|
|
||||||
self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY'])
|
|
||||||
except Exception as e:
|
|
||||||
self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:enterScreen ' + str(e),debug.debugLevel.ERROR)
|
|
||||||
|
@ -36,17 +36,6 @@ settingsData = {
|
|||||||
'fenrirMinRate':80,
|
'fenrirMinRate':80,
|
||||||
'fenrirMaxRate':450,
|
'fenrirMaxRate':450,
|
||||||
},
|
},
|
||||||
'braille':{
|
|
||||||
'enabled': False,
|
|
||||||
'driver':'brlapiDriver',
|
|
||||||
'layout': 'en',
|
|
||||||
'flushMode': 'word', #NONE,FIX,CHAR,WORD
|
|
||||||
'flushTimeout': 3,
|
|
||||||
'cursorFocusMode':'page', # page,fixCell
|
|
||||||
'fixCursorOnCell': -1,
|
|
||||||
'cursorFollowMode': 'review', # none, review, last, text
|
|
||||||
'panSizeHorizontal': 0 # 0 = display size
|
|
||||||
},
|
|
||||||
'screen':{
|
'screen':{
|
||||||
'driver': 'vcsaDriver',
|
'driver': 'vcsaDriver',
|
||||||
'encoding': 'auto',
|
'encoding': 'auto',
|
||||||
|
@ -31,13 +31,9 @@ class FenrirConfigTool:
|
|||||||
self.presetOptions = {
|
self.presetOptions = {
|
||||||
'sound.driver': ['genericDriver', 'gstreamerDriver'],
|
'sound.driver': ['genericDriver', 'gstreamerDriver'],
|
||||||
'speech.driver': ['speechdDriver', 'genericDriver'],
|
'speech.driver': ['speechdDriver', 'genericDriver'],
|
||||||
'braille.driver': ['dummyDriver', 'brailttyDriver', 'brlapiDriver'],
|
|
||||||
'screen.driver': ['vcsaDriver', 'dummyDriver', 'ptyDriver', 'debugDriver'],
|
'screen.driver': ['vcsaDriver', 'dummyDriver', 'ptyDriver', 'debugDriver'],
|
||||||
'keyboard.driver': ['evdevDriver', 'dummyDriver'],
|
'keyboard.driver': ['evdevDriver', 'dummyDriver'],
|
||||||
'remote.driver': ['unixDriver', 'tcpDriver'],
|
'remote.driver': ['unixDriver', 'tcpDriver'],
|
||||||
'braille.flushMode': ['word', 'char', 'fix', 'none'],
|
|
||||||
'braille.cursorFocusMode': ['page', 'fixCell'],
|
|
||||||
'braille.cursorFollowMode': ['review', 'last', 'none'],
|
|
||||||
'keyboard.charEchoMode': ['0', '1', '2'],
|
'keyboard.charEchoMode': ['0', '1', '2'],
|
||||||
'general.punctuationLevel': ['none', 'some', 'most', 'all'],
|
'general.punctuationLevel': ['none', 'some', 'most', 'all'],
|
||||||
'general.debugMode': ['File', 'Print']
|
'general.debugMode': ['File', 'Print']
|
||||||
@ -47,8 +43,7 @@ class FenrirConfigTool:
|
|||||||
'sound.volume': 'Volume level from 0 (quietest) to 1.0 (loudest)',
|
'sound.volume': 'Volume level from 0 (quietest) to 1.0 (loudest)',
|
||||||
'speech.rate': 'Speech rate from 0 (slowest) to 1.0 (fastest)',
|
'speech.rate': 'Speech rate from 0 (slowest) to 1.0 (fastest)',
|
||||||
'speech.pitch': 'Voice pitch from 0 (lowest) to 1.0 (highest)',
|
'speech.pitch': 'Voice pitch from 0 (lowest) to 1.0 (highest)',
|
||||||
'keyboard.charEchoMode': '0 = None, 1 = always, 2 = only while capslock',
|
'keyboard.charEchoMode': '0 = None, 1 = always, 2 = only while capslock'
|
||||||
'braille.flushMode': 'word = flush after words, char = flush after chars, fix = flush after time, none = manual flush'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def check_root(self) -> bool:
|
def check_root(self) -> bool:
|
||||||
|
Loading…
Reference in New Issue
Block a user