From 453869e9afca7c150a3b1ed734d72f138dfda411 Mon Sep 17 00:00:00 2001 From: chrys Date: Sat, 21 Jul 2018 02:04:44 +0200 Subject: [PATCH] fix some bad stuff --- Changelog.txt | 265 ++ TODO v2.0 | 85 + TODOv3.0 | 22 + docu/Howto Configure Pulse Systemwide.txt | 1 + docu/create_manpage.sh | 13 + docu/development.txt | 4 + docu/fenrir.1 | 2764 +++++++++++++++++ docu/user.md | 1590 ++++++++++ docu/user.txt | 1332 ++++++++ play zone/argp.py | 12 + play zone/charmapTTY.py | 88 + play zone/colors.sh | 39 + play zone/consumeEvents.py | 52 + play zone/daemon.py | 12 + play zone/detectDevices.py | 48 + play zone/epollScreen.py | 37 + play zone/errorOnBrokenDevice.py | 5 + play zone/fg.sh | 48 + play zone/keypress.py | 19 + play zone/listDevices.py | 23 + play zone/listSession.py | 20 + play zone/marytts.py | 52 + play zone/parseProcessTree.py | 53 + play zone/passBrokenDevice.py | 28 + play zone/pdmenurc | 154 + play zone/print_escape.py | 41 + play zone/pyterm.py | 34 + play zone/split.txt | 34 + play zone/terminalManagement | 119 + play zone/vcsa.py | 92 + play zone/wrapWord.py | 142 + play zone/writeBrl.py | 19 + realese nots/1.9 | 71 + realese nots/1.9.2 | 9 + splits.txt | 34 + .../onCursorChange/60000-word_echo_type.py | 58 + 36 files changed, 7419 insertions(+) create mode 100644 Changelog.txt create mode 100644 TODO v2.0 create mode 100644 TODOv3.0 create mode 100644 docu/Howto Configure Pulse Systemwide.txt create mode 100755 docu/create_manpage.sh create mode 100644 docu/development.txt create mode 100644 docu/fenrir.1 create mode 100644 docu/user.md create mode 100644 docu/user.txt create mode 100755 play zone/argp.py create mode 100755 play zone/charmapTTY.py create mode 100644 play zone/colors.sh create mode 100755 play zone/consumeEvents.py create mode 100755 play zone/daemon.py create mode 100755 play zone/detectDevices.py create mode 100644 play zone/epollScreen.py create mode 100755 play zone/errorOnBrokenDevice.py create mode 100755 play zone/fg.sh create mode 100755 play zone/keypress.py create mode 100755 play zone/listDevices.py create mode 100755 play zone/listSession.py create mode 100755 play zone/marytts.py create mode 100755 play zone/parseProcessTree.py create mode 100755 play zone/passBrokenDevice.py create mode 100644 play zone/pdmenurc create mode 100644 play zone/print_escape.py create mode 100755 play zone/pyterm.py create mode 100644 play zone/split.txt create mode 100644 play zone/terminalManagement create mode 100755 play zone/vcsa.py create mode 100755 play zone/wrapWord.py create mode 100755 play zone/writeBrl.py create mode 100644 realese nots/1.9 create mode 100644 realese nots/1.9.2 create mode 100644 splits.txt create mode 100644 src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py diff --git a/Changelog.txt b/Changelog.txt new file mode 100644 index 00000000..e04ea622 --- /dev/null +++ b/Changelog.txt @@ -0,0 +1,265 @@ +# Version 1.5 +- Doku: Write a user wiki + https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir + +- initial working setup.py + +- available via pip (python packet manager) +sudo pip3 install fenrir-screenreader +https://pypi.python.org/pypi/fenrir-screenreader/1.5.post5 + +- leave review on typing + +- add dependency check (check-dependencys.py) + +- Add nice dummy drivers as template or for debugging + +- reimplement detection code for X11 + +- initial translate structure (manuelcortez Thanks!) + +- add a configurable place where you can place own commands or overwrite existing commands without need to change default code + +- implement autodetection of plugged and unplugged input devices + +- implement speechdriver generic + +- try to autodetect encoding (Easy for contribution) (Prototype "charmapTTY" in play zone) + +Braille Support (WIP): + - initial BrlTTY driver + - detect device size via driver + - output to braille device + - make flushMode configurable + - make flushTimeout configurable + - flush message after X seconds and show current line (review over text) + - tweak current commands and output + - command flush_braille + - command for scroll left + - command for scroll right + - create offset for scrolling + - respect scrolling + make cursor following configurable (brailleCursorTrackingMode) + - cell + - page + follow cursor while typing + brailleFocusMode: + - review = priority to review + +- move to an event based system + +- add initial multithreading/ multiprocessing support + +- support cli parameters + - add cli parameter for debugging "-d" + - add cli parameter to overwrite options "-o" + - add cli parameter to specify an settings.conf "-s" + +- list of bound commands in Tutorial Mode. speak name, binding and description. + +# Version: 1.00 + +- move from VCS to VCSA and parese the Attributes +http://linux.die.net/man/4/vcsa +http://man.cx/vcsa(4)/de +http://manpages.org/display-vcsa/7 +https://en.wikipedia.org/wiki/Virtual_console +every second byte is a attribute others are text. fast way: c[::2],c[1::2] +http://manpages.ubuntu.com/manpages/precise/de/man4/vcs.4.html +https://docs.python.org/3/library/fcntl.html +http://rodrigorivas.serveblog.net/en/imagenes-desde-vt-con-vcsa/ +good doku: +http://angband.oook.cz/d/eyangband-052/src/main-vcs.c +http://manpages.ubuntu.com/manpages/trusty/man1/screader.1.html + +- implement speechdriver espeak +https://github.com/relsi/python-espeak + +- detect collumns in TTYs automaticaly. +it seems we have this info in vcsa + +- get current cursor +- shortcut handling +https://docs.python.org/2/library/termios.html +http://stackoverflow.com/questions/287757/pythons-configparser-unique-keys-per-section +0=down, 1=press, 2=hold +2KEY_SHIFT, 1KEY_A = say_current_line_cursor +- implement command structure +- implement speechdriver speechd +https://git.gnome.org/browse/orca/tree/src/orca/speech.py +https://git.gnome.org/browse/orca/tree/src/orca/speechdispatcherfactory.py +http://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#Client-Programming + +- autodetect current TTY maybe with (PAM or a sys folder) +cat /sys/devices/virtual/tty/tty0/active +http://serverfault.com/questions/306854/how-to-find-out-the-currently-active-linux-virtual-terminal-while-connected-via + +- Input +http://python-evdev.readthedocs.io/en/latest/tutorial.html +http://stackoverflow.com/questions/12384772/how-can-i-capture-mouseevents-and-keyevents-using-python-in-background-on-linux +maybe TTY in RAW MODE + +- Settings (make it configureable) +- improve differ speed +- lock mechanism for threads +- restructure loops to listen for events + inputloop -> does block with an select + commands -> a new thread should spawned from inputloop + updatescreen -> maybe we could watch it with inotify vsca should support polling COMMENT: sadly not possible, poll events not fired as expected + https://github.com/seb-m/pyinotify/wiki/Tutorial + +import pyinotify +import glob +class Identity(pyinotify.ProcessEvent): + def process_default(self, event): + p = event.pathname + print(p) + +wm = pyinotify.WatchManager() + +notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(), timeout=5) +wm.add_watch('/sys/devices/virtual/tty/tty0/active', pyinotify.IN_CLOSE_WRITE) +for file in list(glob.glob('/dev/vcsa[0-64]')): + wm.add_watch(file, pyinotify.IN_CLOSE_WRITE) + print(file) + +try: + while 1: + notifier.process_events() + if notifier.check_events( timeout=1000): + notifier.read_events() + print('events') + else: + print('timeout') +except KeyboardInterrupt: + notifier.stop() + print('fin') + + + https://www.infoq.com/articles/inotify-linux-file-system-event-monitoring + https://github.com/seb-m/pyinotify/wiki/Tutorial + http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/ + +- add setting for ignore screens ( dont grab shortcuts from X or orca) +- soundIcons +- performance tuning +- add sound volume +- convert volume to percent in config +- convert pitch to percent in config +- convert rate to percent in config +- make screenUpdate rate configurable +- default soundIcon theme (soundfiles) +- debugging +- threading ReadContent, ReadShortcuts, executeCommands, listenNewTTYsForListen, controllThread (main) +- autoload plugins while starting +- implement sounddriver generic (use current sox and make it configurable) +- add setting for autodetect X +ps a -o tty,comm | grep -e Xorg | grep -v "grep -e Xorg" +- respect window mode in differ (getwindow code is already in place) +- parse punctuation setting file in conf/substitution + +- implement commands + curr_word + curr_char + next_word + next_char + prev_word + prev_char + enable_disable_speech #enable, disable speech + enable_disable_braile #enable, disable braile + enable_disable_sound #enable, disable sound + enable_disable_output #enable, disable speech, braile and sound + next_clipboard + prev_clipboard + first_clipboard + last_clipboard + curr_clipboard + paste_clipboard + define_window + remove_window + reset_review_on_screen_change + remove_clipboard_marks + copy_marked + set_mark (this could also used for area?) + read_clipboard_mark_text + curr_screen + curr_screen_before_cursor + curr_screen_after_cursor + cursor_position + indention + add_bookmark (per application) + remove_bookmark + present_bookmark + say_char_phonetic + spell_word_phonetic + "alpha", "bravo", "charlie", "delta", "echo", + "foxtrot", "golf", "hotel", "india", "juliet", + "kilo", "lima", "mike", "november", "oscar", + "papa", "quebec", "romeo", "sierra", "tango", + "uniform", "victor", "whisky", "x ray", + "yankee", "zulu" + next_char_phonetic + prev_char_phonetic + next_word_phonetic + prev_word_phonetic + toggle_highlighted_mode + +- implement onInput commands + read_line_if_cursor_change_vertical (needed if you arrow up and down, we want to announce the line) + read_char_if_cursur_change_horizontal (needed if you arrow left and right, we want to announce the char under the cursor) + echo_char (echos the last char on pressing space or return) + echo_word (echos the last word) + echo_deleted_char (echos deleted char on screen + read highlighted + +- implement onScreenChange commands + promoted text + clear_marks_on_screen_change + leve_review_mode_on_screen_change + window mode (define a area and just read that changes) + +- add screenManager + abstract screen driver +- pass environment instance in init and remove it from function calls + +- New Triggers + onAppChange + onAppProfileChange + onScreenChange + rename current onScreenChange to onScreenUpdate + +- rework inputManager + try to consume shortcuts + grab keyboard exclusive + release keyboard on error or quit + grab shortcuts with fenrir key + grab "singel key shortcuts" like numpad navigation for review + forwart nonshortcuts to system + make grabbing configuarble + possiblity to forewart shortcut [proxyshortcut] + possiblity to forewart shortcut (or use them as shortcut) [pressing twice while timeout] + cleanup inputManager + split input driver out of the handler + +- dictonary for special chars and string replacements +- punctuation +- beep on cursor to capital letters in cursor and review +- add pause handling + create pause + make it configurable when the pause the pause happens +- external scripting + load scripts from a folder as subprocess + create thread + load key definition of keybindings like SOPS did + +- add an daemonize mode +https://github.com/thesharp/daemonize +https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/ + +- announce capslock +- anounce numlock +- anounce scroll +- add the debugging to core + +- autostart systemd +https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html diff --git a/TODO v2.0 b/TODO v2.0 new file mode 100644 index 00000000..6f225914 --- /dev/null +++ b/TODO v2.0 @@ -0,0 +1,85 @@ +ToDo list for Fenrir Version 2.0 +Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :). +[] = ToDo +[W] = WIP +[X] = Done +[S] = Stopped + +Cleanups: + [] Migrate *Data.py to classes and use getter/setter (Easy for contribution) + [] commandsData.py + [] eventData.py + [] generalData.py + [] inputData.py + [] outputData.py + [] punctuationData.py + [] runtimeData.py + [w] screenData.py + [] settingsData -> defaultSettings.py + [] Unify Key Forewarding and Sticky mode for keyboard and bytecode inputDrivers. + [] replace lines by a list insteed of and \n seperated string. (currently we need to split to often) (Easy for contribution) +General (Easy for contribution) + [w] make fenrir runnable without root permissions + [] make fenrir runable without settingsfile. fallback to defaults + [] Detect progressbars and just present percent + |=============== |100% + [=================> ] 100% + ######################## 100% +Imporove attribute handling + [] beep on review by word (once for multiple, capital wins) (Easy for contribution) + [] configurable (by char, by word, none) (Easy for contribution) + https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py + +Improved Say all + [] speech callbacks + [] speech process by word + [] all the text of all pages + [] command to stop and place review cursor at this position + [] command to slow down speech on keypress + [] place say all at clipboard buffer + +Table review mode + [] toggle table mode/ select headline + [] next line + [] prev line + [] current line + [] next cell + [] prev cell + [] current cell + [] select field separator + +Braille Support: + [] brailleFocusMode: + [] manual = no automatic toggle command used + [] last = follow last used cursor + [] print cursor in review + [] print cursor in textmode + [] word wrapping (if word does not fit print it at next page) + https://docs.python.org/2/library/textwrap.html#textwrap.TextWrapper + drop_whitespace = False + replace_whitespace = False + w.fill(i).split('\n') + [] command toggle used cursor (in manual brailleFocusMode) + [] capture input from braile + [] make routing keys assignable by keyboard + [] make brailleTable configurable + [] pkg-config --variable=tablesdir liblouis + returns on Arch:/usr/share/liblouis/tables + http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html + https://git.gnome.org/browse/orca/tree/src/orca/braille.py + https://wiki.gnome.org/Attic/LSR/ScratchPad/Braille/BrlAPI + https://github.com/google/brailleback/blob/master/third_party/brltty/Bindings/Python/brlapi.pyx + +[] ATK input driver (don't grab on graphical interface) + https://git.linux-a11y.org/AIT/pyatspi2/src/master/examples/keypress.py + +Driver (speech): +[S] talkey driver ( verry unresponsive for espeak in linux) +[S] emacspeak driver (breaks for a whole screen) + https://pypi.python.org/pypi/ptyprocess#downloads +[] Dectalk SpeechDriver (Easy for contribution, device needed - i dont own one) + https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py +[] MacOS speech Driver +Settings: + [] write settings (Easy for contribution) + [] menue for settings configuration (Easy for contribution) diff --git a/TODOv3.0 b/TODOv3.0 new file mode 100644 index 00000000..8b2a843c --- /dev/null +++ b/TODOv3.0 @@ -0,0 +1,22 @@ +ToDo list for Fenrir Version 3.0 +Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :). +[] = ToDo +[W] = WIP +[X] = Done +[S] = Stopped + +__TOD___ +Application Profiles (low priority): +- reimplement process detection without subprocessing +- fenrir is not able to detect the current application inside of screen. + ps -e -H -o pid,pgrp,ppid,tty,cmd + http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213 + fd = os.open("/dev/tty5", os.O_RDONLY ) + os.tcgetpgrp(fd) +- add perApplicationTrigger trigger + per application commands + per application onScreenChange + per application onInput +- per application shortcuts + +___DONE___ diff --git a/docu/Howto Configure Pulse Systemwide.txt b/docu/Howto Configure Pulse Systemwide.txt new file mode 100644 index 00000000..3893d21b --- /dev/null +++ b/docu/Howto Configure Pulse Systemwide.txt @@ -0,0 +1 @@ +https://rudd-o.com/linux-and-free-software/how-to-make-pulseaudio-run-once-at-boot-for-all-your-users diff --git a/docu/create_manpage.sh b/docu/create_manpage.sh new file mode 100755 index 00000000..30bb538f --- /dev/null +++ b/docu/create_manpage.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# needs pandoc and php installed + +# remove old files +rm fenrir.1 +rm user.md + +# convert to markdown +php DokuWiki-to-Markdown-Converter/convert.php user.txt + +# convert markdown to manpage +pandoc user.md -f markdown -t man -s -o fenrir.1 + diff --git a/docu/development.txt b/docu/development.txt new file mode 100644 index 00000000..26d1a4ea --- /dev/null +++ b/docu/development.txt @@ -0,0 +1,4 @@ +1. Basic +2. Commands +3. Useful API + diff --git a/docu/fenrir.1 b/docu/fenrir.1 new file mode 100644 index 00000000..4f2e70e6 --- /dev/null +++ b/docu/fenrir.1 @@ -0,0 +1,2764 @@ +.\"t +.\" Automatically generated by Pandoc 1.19.2.1 +.\" +.TH "" "" "" "" "" +.hy +.SH Fenrir User Manual +.PP +Fenrir is a modern command line screen reader written in Python3. +.PP +It has a modular structure, a flexible based driver model, is highly +configurable and easy to customize and extend (see Developer +Manual (fenrir_development_manual)). +.PP +Please see the following pages for the current (fenrir_current_version) +and Git (fenrir_git_version) version of Fenrir. +.SH Support and Requirements +.PP +Fenrir requires several drivers to interact with the operating system. +.SS Speech Drivers +.PP +A speech driver is for communication with the text to speech system like +Speech\-Dispatcher (#SpeechDispatcher) or +Espeak (http://espeak.sourceforge.net). +\\ See section Speech (#Speech) in \[aq]\[aq]settings.conf\[aq]\[aq] for +more information. +.SS SpeechDispatcher +.PP +This driver is used by default. +It uses Speech\-dispatcher as its backend. +.PP +Dependencies: +.IP \[bu] 2 +Speech\-dispatcher (installed and configured, +Documentation (https///devel.freebsoft.org/speechd#sec2)) +.IP \[bu] 2 +Python\-speechd +.SS Espeak +.PP +Uses Espeak via Python bindings. +.PP +Dependencies: +.IP \[bu] 2 +Espeak or Espeak\-ng +.IP \[bu] 2 +python\-espeak (https///launchpad.net/python-espeak) +.SS Generic +.PP +This invokes speech via a sub\-process. +This is almost the same as using the commandline. +The performance depends on the overhead of the speech synthesis +application but it is really flexible. +.PP +Dependencies: +.IP \[bu] 2 +Espeak or Espeak\-ng +.PP +The Requirements are flexible, they depend on the configuration in +settings.conf. +.SS Dummy +.PP +this is just for debugging, logs are output to the screen and logged as +well. +.SS Sound Drivers +.PP +To play sound icons and similar.\\ See section Sound (#Sound) in +\[aq]\[aq]settings.conf\[aq]\[aq] for more information. +.SS Generic +.PP +This driver is used by default. +.PP +Dependencies: +.IP \[bu] 2 +Sox (http://sox.sourceforge.net/) with opus support The Requirements are +flexible, they depend on the configuration in settings.conf. +.SS Gstreamer +.PP +if you prefer to use Gstreamer for sound output. +.PP +Dependencies: +.IP \[bu] 2 +Gstreamer >= 1.x +.IP \[bu] 2 +Glibc +.SS Dummy +.PP +this is just for debugging, logs are output to the screen and logged as +well. +.SS Input Drivers +.PP +Input drivers are to capture keyboard shortcuts issued to the screen +reader +.PD 0 +.P +.PD +See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq] +for more information. +.SS Evdev +.PP +This driver is used by default. +.PP +Evdev is the low level input device framework for Linux. +.PP +Dependencies: +.IP \[bu] 2 +python\-evdev >=0.6.3 +.IP \[bu] 2 +pyudev +.IP \[bu] 2 +loaded uinput kernel module +.IP \[bu] 2 +exclusive access to the input devices Read permission to the following +files and services: +.IP \[bu] 2 +/dev/input +.IP \[bu] 2 +/dev/uinput +.SS Screen Drivers +.PP +The job of a screen driver is to get the information of current screen +content.\\ See section Screen (#Screen) in +\[aq]\[aq]settings.conf\[aq]\[aq] for more information. +.SS VCSA +.PP +This driver is used by default. +For Linux VCSA devices. +These exist on any current standard installation of Linux. +.PP +Dependencie s: +.IP \[bu] 2 +python\-dbus Read permission to the following files and services (or run +as root): +.IP \[bu] 2 +/sys/devices/virtual/tty/tty0/active +.IP \[bu] 2 +/dev/tty[1 \- 64] +.IP \[bu] 2 +/dev/vcsa[1 \- 64] (VCSA manpage (https///linux.die.net/man/4/vcsa)) +.IP \[bu] 2 +read Logind DBUS +.SS Braille Drivers +.PP +This is for Braille support. +Braille is currently a work in progress and is planned for the Fenrir +2.0 release.\\ See section Braille (#Braille) in +\[aq]\[aq]settings.conf\[aq]\[aq] for more information. +.SS BRLTTY +.PP +This driver is used by default. +It uses BrlTTY (brltty) to communicate with with a Braille device. +.PP +Dependencies: +.IP \[bu] 2 +BrlTTY (configured and running, +Documentation (http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html)) +.IP \[bu] 2 +python\-brlapi (configured, +Documentation (http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html)) +## Currently supported platforms +.PP +Currently Fenrir completely supports the following Platforms: +.IP \[bu] 2 +Linux TTY Support for further Systems are planned. +.SH Installation +.PP +Fenrir can run without installation. +It just requires the dependencies are installed first. +.PP +We recommend to try it out before installation to be sure everything +works and prevent yourself from experiencing a non\-talking environment. +.SS Try Out +.PP +Fenrir does not require installation. +You can try it and make sure everything works before you decide to +install. +In this way you can be sure that your system doesnt break or stop +talking. +for that you can just grab the code and run as root +\[aq]\[aq]src/fenrir/fenrir\[aq]\[aq] (in foreground) or +\[aq]\[aq]src/fenrir/fenrir\-daemon\[aq]\[aq] (in background, used by +systemd for autostart) +.SS Install it +.SS Documented operating systems +.SS Arch Linux +.PP +For Arch there are PKGBUILDs in the AUR: +.IP \[bu] 2 +fenrir (https///aur.archlinux.org/packages/fenrir/) +.IP \[bu] 2 +fenrir\-git (https///aur.archlinux.org/packages/fenrir-git/) +.SS Manual +.IP "1." 3 +Download the latest stable version from the +Fenrir\-Project (https///linux-a11y.org/index.php?page=fenrir-screenreader) +site. +.IP "2." 3 +Unpack the archive +.IP "3." 3 +Check the needed Dependencys by running +check\-dependencys.py (https///github.com/chrys87/fenrir/blob/master/check-dependencies.py) +script +.IP "4." 3 +install the missing dependencies an standard installation requires the +following: +.RS 4 +.IP \[bu] 2 +python3 >= 3.3 (and all the following is needed for python3 ) +.IP \[bu] 2 +python3\-speechd (screen) +.IP \[bu] 2 +python3\-dbus (screen) +.IP \[bu] 2 +python3\-evdev >= 0.6.4(input) +.IP \[bu] 2 +python3\-daemonize (background service) +.IP \[bu] 2 +python3\-brlapi (braille) +.IP \[bu] 2 +python3\-pyenchant (spellchecker) +.IP \[bu] 2 +your language for aspell (aspell\-\f[C]\f[]) (spellchecker) +.IP \[bu] 2 +sox (sound) +.IP \[bu] 2 +For an individual installation see Support and +Requirements (#Support%20and%20Requirements) or consult the +Readme (https///github.com/chrys87/fenrir/blob/master/README.md)) +.RE +.IP "5." 3 +run "install.sh" as root +.PP +this installs Fenrir as the following +.IP +.nf +\f[C] +*\ Application:\[aq]\[aq]/opt/fenrir\[aq]\[aq] +*\ Settings:\[aq]\[aq]/etc/fenrir\[aq]\[aq] +*\ Sound\ Icons:\[aq]\[aq]/usr/share/fenrirscreenreader/\[aq]\[aq] +\f[] +.fi +.PP +to remove Fenrir just run uninstall.sh as root +.SS Git +.PP +if you want to get the latest code you can use git to get a development +snapshot: +.IP +.nf +\f[C] +git\ clone\ https://github.com/chrys87/fenrir.git +\f[] +.fi +.SS Auto Start +.PP +To start Fenrir once: systemctl start fenrir +.PP +To enable auto start on system boot: systemctl enable fenrir +.SH First Steps +.PP +If you are using Fenrir for the first time you may want to take a look +at these resources: +.IP \[bu] 2 +Keybindings (#Keybindings) +.IP \[bu] 2 +Tutorial Mode (#Tutorial%20Mode) +.SH Features +.SS Commands +.SS Keybindings +.PP +Normal commands can be invoked in two ways: 1. +Using a Metakey (FenrirKey (#Fenrir%20Key)) 2. +Shortcuts with a single key +.PP +See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq] +for more information. +#### Fenrir Key +.PP +The Fenrir Key is for invoking screen reader commands. +Fenrir can utilize more than one FenrirKey at the same time. +By default the following keys are used: 1. +Insert 2. +KeyPad Insert 3. +Meta (Super, Windows) +.SS Script Key +.PP +To invoke "Scripts" the Script Key is mandatory. +The shortcut is encoded in the filename of the script. +See Scripting (#Scripting) #### Desktop Layout +.PP +.TS +tab(@); +l l. +T{ +Shortcut +T}@T{ +Command +T} +_ +T{ +FenrirKey + H +T}@T{ +toggle tutorial mode (#Tutorial%20Mode) +T} +T{ +CTRL +T}@T{ +shut up (interrupts speech) (#shut%20up) +T} +T{ +FenrirKey + KeyPad 9 +T}@T{ +reviews bottom (#review%20bottom) +T} +T{ +FenrirKey + KeyPad 7 +T}@T{ +reviews top (#review%20top) +T} +T{ +KeyPad 8 +T}@T{ +reviews current line (#review%20current%20line) +T} +T{ +KeyPad 7 +T}@T{ +reviews previous line (#review%20previous%20line) +T} +T{ +KeyPad 9 +T}@T{ +reviews next line (#review%20next%20line) +T} +T{ +FenrirKey + KeyPad 4 +T}@T{ +reviews line beginning (#review%20line%20beginning) +T} +T{ +FenrirKey + KeyPad 6 +T}@T{ +reviews line ending (#review%20line%20ending) +T} +T{ +FenrirKey + KeyPad 1 +T}@T{ +reviews line first character (#review%20line%20first%20character) +T} +T{ +FenrirKey + KeyPad 3 +T}@T{ +reviews line last character (#review%20line%20last%20character) +T} +T{ +FenrirKey + Alt + 1 +T}@T{ +presents first line (#present%20first%20line) +T} +T{ +FenrirKey + Alt + 2 +T}@T{ +presents last line (#present%20last%20line) +T} +T{ +KeyPad 5 +T}@T{ +reviews current word (#review%20current%20word) +T} +T{ +KeyPad 4 +T}@T{ +reviews previous word (#review%20previous%20word) +T} +T{ +KeyPad 6 +T}@T{ +reviews next word (#review%20next%20word) +T} +T{ +FenrirKey + Shift + KeyPad 5 +T}@T{ +reviews current word phonetic (#review%20current%20word%20phonetic) +T} +T{ +FenrirKey + Shift + KeyPad 4 +T}@T{ +reviews previous word phonetic (#review%20previous%20word%20phonetic) +T} +T{ +FenrirKey + Shift + KeyPad 6 +T}@T{ +reviews next word phonetic (#review%20next%20word%20phonetic) +T} +T{ +KeyPad 2 +T}@T{ +reviews current char (#review%20current%20character) +T} +T{ +KeyPad 1 +T}@T{ +reviews previous char (#review%20previous%20character) +T} +T{ +KeyPad 3 +T}@T{ +reviews next char (#review%20next%20character) +T} +T{ +FenrirKey + Shift + KeyPad 2 +T}@T{ +reviews current character +phonetic (#review%20current%20character%20phonetic) +T} +T{ +FenrirKey + Shift + KeyPad 1 +T}@T{ +reviews previous character +phonetic (#review%20previous%20character%20phonetic) +T} +T{ +FenrirKey + Shift + KeyPad 3 +T}@T{ +reviews next character phonetic (#review%20next%20character%20phonetic) +T} +T{ +FenrirKey + CTRL + KeyPad 8 +T}@T{ +reviews up (#review%20up) +T} +T{ +FenrirKey + CTRL + KeyPad 2 +T}@T{ +reviews down (#review%20down) +T} +T{ +FenrirKey + KeyPad dot +T}@T{ +exit review (#exit%20review) +T} +T{ +KeyPad dot +T}@T{ +cursor position (#cursor%20position) +T} +T{ +FenrirKey + I +T}@T{ +indent curr line (#indent%20current%20line) +T} +T{ +FenrirKey + KeyPad 5 +T}@T{ +current screen (#current%20screen) +T} +T{ +FenrirKey + KeyPad 8 +T}@T{ +current screen before cursor (#current%20screen%20before%20cursor) +T} +T{ +FenrirKey + KeyPad 2 +T}@T{ +current screen after cursor (#current%20screen%20after%20cursor) +T} +T{ +\f[C]\f[] +T}@T{ +cursor read to end of line (#cursor%20read%20to%20end%20of%20line) +T} +T{ +\f[C]\f[] +T}@T{ +cursor column (#cursor%20column) +T} +T{ +\f[C]\f[] +T}@T{ +cursor line number (#cursor%20line%20number) +T} +T{ +\f[C]\f[] +T}@T{ +Braille flush (#braille%20flush) +T} +T{ +\f[C]\f[] +T}@T{ +Braille pan left (#braille%20pan%20left) +T} +T{ +\f[C]\f[] +T}@T{ +Braille pan right (#braille%20pan%20right) +T} +T{ +\f[C]\f[] +T}@T{ +Braille return to cursor (#braille%20return%20to%20cursor) +T} +T{ +FenrirKey + CTRL + 1 +T}@T{ +clear bookmark 1 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 1 +T}@T{ +set bookmark 1 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 1 +T}@T{ +bookmark 1 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 2 +T}@T{ +clear bookmark 2 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 2 +T}@T{ +set bookmark 2 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 2 +T}@T{ +bookmark 2 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 3 +T}@T{ +clear bookmark 3 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 3 +T}@T{ +set bookmark 3 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 3 +T}@T{ +bookmark 3 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 4 +T}@T{ +clear bookmark 4 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 4 +T}@T{ +set bookmark 4 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 4 +T}@T{ +bookmark 4 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 5 +T}@T{ +clear bookmark 5 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 5 +T}@T{ +set bookmark 5 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 5 +T}@T{ +bookmark 5 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 6 +T}@T{ +clear bookmark 6 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 6 +T}@T{ +set bookmark 6 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 6 +T}@T{ +bookmark 6 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 7 +T}@T{ +clear bookmark 7 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 7 +T}@T{ +set bookmark 7 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 7 +T}@T{ +bookmark 7 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 8 +T}@T{ +clear bookmark 8 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 8 +T}@T{ +set bookmark 8 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 8 +T}@T{ +bookmark 8 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 9 +T}@T{ +clear bookmark 9 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 9 +T}@T{ +set bookmark 9 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 9 +T}@T{ +bookmark 9 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 0 +T}@T{ +clear bookmark 10 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 0 +T}@T{ +set bookmark 10 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 0 +T}@T{ +bookmark 10 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + KeyPad Slash +T}@T{ +set window application (#Create%20Window) +T} +T{ +2 * FenrirKey + KeyPad Slash +T}@T{ +clear window application (#Remove%20Window) +T} +T{ +KeyPad Plus +T}@T{ +read last incoming (#last%20incoming) +T} +T{ +FenrirKey + F2 +T}@T{ +toggles braille (#toggle%20braille) +T} +T{ +FenrirKey + F3 +T}@T{ +toggles sound (#toggle%20sound) +T} +T{ +FenrirKey + F4 +T}@T{ +toggles speech (#toggle%20speech) +T} +T{ +KeyPad Enter +T}@T{ +temporarily disables speech (#disable%20speech%20temporarily) +T} +T{ +FenrirKey + CTRL + P +T}@T{ +toggles punctuation level (#toggle%20punctuation%20level) +T} +T{ +FenrirKey + RightBrace +T}@T{ +toggle auto spell check (#toggle%20auto%20spell%20check) +T} +T{ +FenrirKey + Backslash +T}@T{ +toggles output (#toggle%20output) +T} +T{ +FenrirKey + CTRL + E +T}@T{ +toggles emoticons (#toggle%20emoticons) +T} +T{ +FenrirKey + KeyPad Enter +T}@T{ +toggles auto read (#toggle%20auto%20read) +T} +T{ +FenrirKey + CTRL + T +T}@T{ +toggles auto time (#toggle%20auto%20time) +T} +T{ +FenrirKey + KeyPad ASTERISK +T}@T{ +toggles highlight tracking (#toggle%20highlight%20tracking) +T} +T{ +FenrirKey + Q +T}@T{ +quits fenrir (#quit%20Fenrir) +T} +T{ +FenrirKey + T +T}@T{ +Announce time (#Time) +T} +T{ +2 * FenrirKey + T +T}@T{ +Announce date (#Date) +T} +T{ +FenrirKey + S +T}@T{ +spell check (#spell%20check) +T} +T{ +2 * FenrirKey + S +T}@T{ +add word to spell check (#add%20word%20to%20spell%20check) +T} +T{ +FenrirKey + Shift + S +T}@T{ +removes word from spell check (#removes%20word%20from%20spell%20check) +T} +T{ +FenrirKey + Backspace +T}@T{ +forward keypress (#forward%20keypress) +T} +T{ +FenrirKey + Up +T}@T{ +increase speech volume (#increase%20speech%20volume) +T} +T{ +FenrirKey + Down +T}@T{ +decrease speech volume (#decrease%20speech%20volume) +T} +T{ +FenrirKey + Right +T}@T{ +increase speech rate (#increase%20speech%20rate) +T} +T{ +FenrirKey + Left +T}@T{ +decrease speech rate (#decrease%20speech%20rate) +T} +T{ +FenrirKey + Alt + Right +T}@T{ +increase speech pitch (#increase%20speech%20pitch) +T} +T{ +FenrirKey + Alt + Left +T}@T{ +decrease speech pitch (#decrease%20speech%20pitch) +T} +T{ +FenrirKey + Alt + Up +T}@T{ +increase sound volume (#increase%20sound%20volume) +T} +T{ +FenrirKey + Alt + Down +T}@T{ +decrease sound volume (#decrease%20sound%20volume) +T} +T{ +FenrirKey + CTRL + Shift + C +T}@T{ +clears clipboard (#clear%20clipboard) +T} +T{ +FenrirKey + Home +T}@T{ +first clipboard (#first%20clipboard) +T} +T{ +FenrirKey + End +T}@T{ +last clipboard (#last%20clipboard) +T} +T{ +FenrirKey + PageUp +T}@T{ +previous clipboard (#previous%20clipboard) +T} +T{ +FenrirKey + PageDown +T}@T{ +next clipboard (#next%20clipboard) +T} +T{ +FenrirKey + Shift + C +T}@T{ +current clipboard (#read%20current%20clipboard) +T} +T{ +FenrirKey + C +T}@T{ +copy marked text to clipboard (#copy%20marked%20to%20clipboard) +T} +T{ +FenrirKey + V +T}@T{ +paste clipboard contents (#paste%20clipboard) +T} +T{ +FenrirKey + P +T}@T{ +import clipboard from file (#import%20clipboard%20from%20file) +T} +T{ +FenrirKey + Alt + Shift +C +T}@T{ +export clipboard to file (#export%20clipboard%20to%20file) +T} +T{ +FenrirKey + CTRL + Shift + X +T}@T{ +remove marks (#Remove%20Marks) +T} +T{ +FenrirKey + X +T}@T{ +set mark (#Set%20mark) +T} +T{ +FenrirKey + Shift + X +T}@T{ +announce marked text (#Get%20text%20between%20marks) +T} +T{ +Linux specific +T}@T{ +T} +T{ +\f[C]\f[] +T}@T{ +export clipboard to X +T} +T{ +FenrirKey + CTRL + Up +T}@T{ +include Alsa volume +T} +T{ +FenrirKey + CTRL + Down +T}@T{ +decrease Alsa volume +T} +.TE +.SS Laptop Layout +.PP +.TS +tab(@); +l l. +T{ +Shortcut +T}@T{ +Command +T} +_ +T{ +FenrirKey + H +T}@T{ +toggle tutorial mode (#Tutorial%20Mode) +T} +T{ +CTRL +T}@T{ +shut up (interrupts speech) (#shut%20up) +T} +T{ +FenrirKey + Shift + O +T}@T{ +reviews bottom (#review%20bottom) +T} +T{ +FenrirKey + Shift + U +T}@T{ +reviews top (#review%20top) +T} +T{ +FenrirKey + I +T}@T{ +reviews current line (#review%20current%20line) +T} +T{ +FenrirKey + U +T}@T{ +reviews previous line (#review%20previous%20line) +T} +T{ +FenrirKey + O +T}@T{ +reviews next line (#review%20next%20line) +T} +T{ +FenrirKey + Shift + J +T}@T{ +reviews line beginning (#review%20line%20beginning) +T} +T{ +FenrirKey + Shift + L +T}@T{ +reviews line ending (#review%20line%20ending) +T} +T{ +FenrirKey + CTRL + J +T}@T{ +reviews line first character (#review%20line%20first%20character) +T} +T{ +FenrirKey + CTRL + L +T}@T{ +reviews line last character (#review%20line%20last%20character) +T} +T{ +FenrirKey + Alt + 1 +T}@T{ +presents first line (#present%20first%20line) +T} +T{ +FenrirKey + Alt + 2 +T}@T{ +presents last line (#present%20last%20line) +T} +T{ +FenrirKey + K +T}@T{ +reviews current word (#review%20current%20word) +T} +T{ +FenrirKey + J +T}@T{ +reviews previous word (#review%20previous%20word) +T} +T{ +FenrirKey + L +T}@T{ +reviews next word (#review%20next%20word) +T} +T{ +FenrirKey + CTRL + ALT + K +T}@T{ +reviews current word phonetic (#review%20current%20word%20phonetic) +T} +T{ +FenrirKey + CTRL + ALT + J +T}@T{ +reviews previous word phonetic (#review%20previous%20word%20phonetic) +T} +T{ +FenrirKey + CTRL + ALT + L +T}@T{ +reviews next word phonetic (#review%20next%20word%20phonetic) +T} +T{ +FenrirKey + comma +T}@T{ +reviews current character (#review%20current%20character) +T} +T{ +FenrirKey + M +T}@T{ +reviews previous character (#review%20previous%20character) +T} +T{ +FenrirKey + dot +T}@T{ +reviews next character (#review%20next%20character) +T} +T{ +FenrirKey + CTRL + ALT + comma +T}@T{ +reviews current character +phonetic (#review%20current%20character%20phonetic) +T} +T{ +FenrirKey + CTRL + ALT + M +T}@T{ +reviews previous character +phonetic (#review%20previous%20character%20phonetic) +T} +T{ +FenrirKey + CTRL + ALT + dot +T}@T{ +reviews next character phonetic (#review%20next%20character%20phonetic) +T} +T{ +FenrirKey + CTRL + I +T}@T{ +reviews up (#review%20up) +T} +T{ +FenrirKey + CTRL + comma +T}@T{ +reviews down (#review%20down) +T} +T{ +FenrirKey + Slash +T}@T{ +exit review (#exit%20review) +T} +T{ +FenrirKey + Shift + dot +T}@T{ +cursor position (#cursor%20position) +T} +T{ +2 * FenrirKey + I +T}@T{ +indent curr line (#indent%20current%20line) +T} +T{ +FenrirKey + Shift + K +T}@T{ +current screen (#current%20screen) +T} +T{ +FenrirKey + Shift + I +T}@T{ +current screen before cursor (#current%20screen%20before%20cursor) +T} +T{ +FenrirKey + Shift + comma +T}@T{ +current screen after cursor (#current%20screen%20after%20cursor) +T} +T{ +\f[C]\f[] +T}@T{ +cursor read to end of line (#cursor%20read%20to%20end%20of%20line) +T} +T{ +\f[C]\f[] +T}@T{ +cursor column (#cursor%20column) +T} +T{ +\f[C]\f[] +T}@T{ +cursor line number (#cursor%20line%20number) +T} +T{ +\f[C]\f[] +T}@T{ +Braille flush (#braille%20flush) +T} +T{ +\f[C]\f[] +T}@T{ +Braille pan left (#braille%20pan%20left) +T} +T{ +\f[C]\f[] +T}@T{ +Braille pan right (#braille%20pan%20right) +T} +T{ +\f[C]\f[] +T}@T{ +Braille return to cursor (#braille%20return%20to%20cursor) +T} +T{ +FenrirKey + CTRL + 1 +T}@T{ +clear bookmark 1 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 1 +T}@T{ +set bookmark 1 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 1 +T}@T{ +bookmark 1 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 2 +T}@T{ +clear bookmark 2 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 2 +T}@T{ +set bookmark 2 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 2 +T}@T{ +bookmark 2 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 3 +T}@T{ +clear bookmark 3 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 3 +T}@T{ +set bookmark 3 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 3 +T}@T{ +bookmark 3 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 4 +T}@T{ +clear bookmark 4 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 4 +T}@T{ +set bookmark 4 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 4 +T}@T{ +bookmark 4 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 5 +T}@T{ +clear bookmark 5 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 5 +T}@T{ +set bookmark 5 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 5 +T}@T{ +bookmark 5 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 6 +T}@T{ +clear bookmark 6 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 6 +T}@T{ +set bookmark 6 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 6 +T}@T{ +bookmark 6 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 7 +T}@T{ +clear bookmark 7 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 7 +T}@T{ +set bookmark 7 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 7 +T}@T{ +bookmark 7 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 8 +T}@T{ +clear bookmark 8 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 8 +T}@T{ +set bookmark 8 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 8 +T}@T{ +bookmark 8 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 9 +T}@T{ +clear bookmark 9 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 9 +T}@T{ +set bookmark 9 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 9 +T}@T{ +bookmark 9 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 0 +T}@T{ +clear bookmark 10 (#clear%20Bookmark%20X) +T} +T{ +FenrirKey + Shift + 0 +T}@T{ +set bookmark 10 (#set%20Bookmark%20X) +T} +T{ +FenrirKey + 0 +T}@T{ +bookmark 10 (#read%20Bookmark%20X) +T} +T{ +FenrirKey + CTRL + 8 +T}@T{ +set window application (#Create%20Window) +T} +T{ +2 * FenrirKey + CTRL + 8 +T}@T{ +clear window application (#Remove%20Window) +T} +T{ +FenrirKey + Semicolon +T}@T{ +read last incoming (#last%20incoming) +T} +T{ +FenrirKey + F2 +T}@T{ +toggles braille (#toggle%20braille) +T} +T{ +FenrirKey + F3 +T}@T{ +toggles sound (#toggle%20sound) +T} +T{ +FenrirKey + F4 +T}@T{ +toggles speech (#toggle%20speech) +T} +T{ +FenrirKey + Enter +T}@T{ +temporarily disables speech (#disable%20speech%20temporarily) +T} +T{ +FenrirKey + Shift + CTRL + P +T}@T{ +toggles punctuation level (#toggle%20punctuation%20level) +T} +T{ +FenrirKey + RightBrace +T}@T{ +toggle auto spell check (#toggle%20auto%20spell%20check) +T} +T{ +FenrirKey + Shift + Enter +T}@T{ +toggles output (#toggle%20output) +T} +T{ +FenrirKey + Shift + E +T}@T{ +toggles emoticons (#toggle%20emoticons) +T} +T{ +FenrirKey + Enter +T}@T{ +toggles auto read (#toggle%20auto%20read) +T} +T{ +FenrirKey + CTRL + T +T}@T{ +toggles auto time (#toggle%20auto%20time) +T} +T{ +FenrirKey + Y +T}@T{ +toggles highlight tracking (#toggle%20highlight%20tracking) +T} +T{ +FenrirKey + Q +T}@T{ +quits fenrir (#quit%20Fenrir) +T} +T{ +FenrirKey + T +T}@T{ +Announce time (#Time) +T} +T{ +2 * FenrirKey + T +T}@T{ +Announce date (#Date) +T} +T{ +FenrirKey + S +T}@T{ +spell check (#spell%20check) +T} +T{ +2 * FenrirKey + S +T}@T{ +add word to spell check (#add%20word%20to%20spell%20check) +T} +T{ +FenrirKey + Shift + S +T}@T{ +removes word from spell check (#removes%20word%20from%20spell%20check) +T} +T{ +FenrirKey + Backspace +T}@T{ +forward keypress (#forward%20keypress) +T} +T{ +FenrirKey + Up +T}@T{ +increase speech volume (#increase%20speech%20volume) +T} +T{ +FenrirKey + Down +T}@T{ +decrease speech volume (#decrease%20speech%20volume) +T} +T{ +FenrirKey + Right +T}@T{ +increase speech rate (#increase%20speech%20rate) +T} +T{ +FenrirKey + Left +T}@T{ +decrease speech rate (#decrease%20speech%20rate) +T} +T{ +FenrirKey + Alt + Right +T}@T{ +increase speech pitch (#increase%20speech%20pitch) +T} +T{ +FenrirKey + Alt + Left +T}@T{ +decrease speech pitch (#decrease%20speech%20pitch) +T} +T{ +FenrirKey + Alt + Up +T}@T{ +increase sound volume (#increase%20sound%20volume) +T} +T{ +FenrirKey + Alt + Down +T}@T{ +decrease sound volume (#decrease%20sound%20volume) +T} +T{ +FenrirKey + CTRL + Shift + C +T}@T{ +clears clipboard (#clear%20clipboard) +T} +T{ +FenrirKey + Home +T}@T{ +first clipboard (#first%20clipboard) +T} +T{ +FenrirKey + End +T}@T{ +last clipboard (#last%20clipboard) +T} +T{ +FenrirKey + PageUp +T}@T{ +previous clipboard (#previous%20clipboard) +T} +T{ +FenrirKey + PageDown +T}@T{ +next clipboard (#next%20clipboard) +T} +T{ +FenrirKey + Shift + C +T}@T{ +current clipboard (#read%20current%20clipboard) +T} +T{ +FenrirKey + C +T}@T{ +copy marked text to clipboard (#copy%20marked%20to%20clipboard) +T} +T{ +FenrirKey + V +T}@T{ +paste clipboard contents (#paste%20clipboard) +T} +T{ +FenrirKey + F5 +T}@T{ +import clipboard from file (#import%20clipboard%20from%20file) +T} +T{ +FenrirKey + Alt + Shift +C +T}@T{ +export clipboard to file (#export%20clipboard%20to%20file) +T} +T{ +FenrirKey + CTRL + Shift + X +T}@T{ +remove marks (#Remove%20Marks) +T} +T{ +FenrirKey + X +T}@T{ +set mark (#Set%20mark) +T} +T{ +FenrirKey + Shift + X +T}@T{ +announce marked text (#Get%20text%20between%20marks) +T} +T{ +Linux specific +T}@T{ +T} +T{ +\f[C]\f[] +T}@T{ +export clipboard to X +T} +T{ +FenrirKey + CTRL + Up +T}@T{ +increases Alsa volume +T} +T{ +FenrirKey + CTRL + Down +T}@T{ +decreases Alsa volume +T} +.TE +.SS General +.SS quit Fenrir +.PP +Just stops fenrir. +#### shut up +.PP +Interrupt the current spoken. +### Review Modes +.PP +Fenrir provides a virtual cursor, with it you can navigate all over the +screen without changing the text cursor. +.PP +Using the review feature will open the review mode automatically. +.PP +The review cursor always starts from the text cursor. +Attention: after using the review mode, the review cursor will stay open +until you use the \[aq]\[aq]exit review\[aq]\[aq] shortcut. +.PP +Think when using clipboard operations and similar. +The review cursor is always prefered over the text cursor. +.PP +Fenrir sounds a bell sound if the used review command jumps to another +line or end of screen. +#### exit review +.PP +You can leave the review mode by pressing the \[aq]\[aq]exit +review\[aq]\[aq] shortcut. +#### review bottom +.PP +Set the review cursor to first column in the last line. +#### review top +.PP +Set the review cursor to the first column in the first line #### review +current line +.PP +Set the review cursor to the beginn of the the current line and review +it. +#### review previous line +.PP +Set the review cursor to the previous line and review it. +#### review next line +.PP +Set the review cursor to the next line and review it. +#### review line beginning +.PP +Set the review cursor to the begin of the current line #### review line +ending +.PP +Set the review cursor to the end of the current line #### review line +first character +.PP +Set the review cursor the first char (that is not space) in the current +line and review it. +#### review line last character +.PP +Set the review cursor the last char (that is not space) in the current +line and review it. +#### review current word +.PP +Sets the review cursor to the beginning of the current word and review +it. +#### review previous word +.PP +Sets the review cursor to the beginning of the previous word and review +it. +#### review next word +.PP +Sets the review cursor to the beginning of the next word and review it. +#### review current word phonetic +.PP +Sets the review cursor to the beginning of the current word and spell it +phonetic. +#### review previous word phonetic +.PP +Sets the review cursor to the beginning of the previous word and spell +it phonetic. +#### review next word phonetic +.PP +Sets the review cursor to the beginning of the next word and spell it +phonetic. +#### review current character +.PP +Does not change the review cursor. +Just announce the current char. +#### review previous character +.PP +Sets review cursor to the previous column and review it #### review next +character +.PP +Sets review cursor to the next column and review it #### review current +character phonetic +.PP +Does not change the review cursor. +Just announce the current char phonetic. +#### review previous character phonetic +.PP +Sets review cursor to the previous column and announce the char +phonetic. +#### review next character phonetic +.PP +Sets review cursor to the next column and announce the char phonetic. +#### review up +.PP +Set the review cursor in the same column one line above the current one +and review it. +#### review down +.PP +Set the review cursor in the same column one line below the current one +and review it. +### Handling marking +.PP +A mark defines a point of origin or end to prepare to copy or paste a +block of text. +\\ Examples where you need marks are: +.IP \[bu] 2 +copy to clipboard +.IP \[bu] 2 +set window application +.IP \[bu] 2 +set bookmark 1 \- X #### Set mark +.PP +How to set a mark: 1. +navigate with review or textcursor to the position you want to set the +mark. +Attention: if a review cursor is set, that is the prefered. +If you want to use text cursor, be sure that you are not in review mode. +2. +press shortcut for \[aq]\[aq]set mark\[aq]\[aq] you can set two marks +(begin and end). +Some commands allow some simpler usecases just using the whole line if +only one mark is set. +you may want to try this out. +#### Get text between marks +.PP +To get the text that is currently between your marks press shortcut for +\[aq]\[aq]marked text\[aq]\[aq].\\ #### Remove Marks +.PP +You can remove all current marks by pressing the shortcut for +\[aq]\[aq]remove marks\[aq]\[aq]. +Changing the screen also removes the marks. +### Screen Interaction +.PP +Fenrir provides several methods to interact with the current screen. +#### forward keypress +.PP +This just forwards the next shortcut to the screen Fenrir shortcut or +not. +This is useful if the currently pressed shortcut is also in use by +Fenrir. +#### Clipboard +.PP +Fenrir provides a clipboard with multible items represented by a list. +You navigate throught the list and paste the selected clipboard. +##### copy marked to clipboard +.PP +To copy something to the clipboard you need to set one or two marks. +if you set one mark, the text between the mark and your current cursor +is copied to clipboard. +Setting two marks just copies the text between the marks into the +clipboard. +If you copy something it is always placed as the first item on your +clipboard. +##### clear clipboard +.PP +You can remove all items from the current clipboard by \[aq]\[aq]clear +clipboard\[aq]\[aq] functionality. +##### first clipboard +.PP +This moves quick to the first item of the clipboard. +##### last clipboard +.PP +This moves quick to the last item of the clipboard. +##### previous clipboard +.PP +Go to previous item in the clipboard. +##### next clipboard +.PP +Go to next item on the clipboard. +##### read current clipboard +.PP +Read the content of the current item of the clipboard. +##### paste clipboard +.PP +Pass whatever item is currently selected by first, last, prev or next +clipboard commands. +if no special clipboard is selected the (last copied) is used. +##### export clipboard to file +.PP +This allows you to export the current clipboard to a configurable +filepath. +This is useful to share the clipboard with a graphical desktop. +##### import clipboard from file +.PP +Import a clipboard from a configurable file. +This is useful to share the clipboard with a graphical desktop. +### Quick Settings +.PP +Fenrir provides shortcuts to change settings temporarily and on the fly +without the need to permanently change the +\[aq]\[aq]settings.conf\[aq]\[aq] file. +#### toggle braille +.PP +Enables and disables Braille. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle sound +.PP +Enables and disables sound. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle speech +.PP +Enables and disables speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### disable speech temporarily +.PP +Disables the speech until next key press. +it might be useful if you want to listen to music or similar. +As soon as a key is pressed it is going to be enabled again. +#### toggle punctuation level +.PP +Cycle between all available punctuation levels. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle auto spell check +.PP +Enables and disables automatic spellchecker (when typing). +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle emoticons +.PP +Enables and disables emoticons. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### toggle output +.PP +Enables and disables all output at once (sound, Braille, speech). +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle auto read +.PP +Enables and disables what is automatically spoken. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle auto time +.PP +Enables and disables auto time functionality. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### toggle highlight tracking +.PP +Enables and disables highlight tracking. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during run time. +#### increase speech volume +.PP +Increase the volume of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### decrease speech volume +.PP +Decrease the volume of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### increase speech rate +.PP +Increase the rate of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### decrease speech rate +.PP +Decrease the rate of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### increase speech pitch +.PP +Increase the pitch of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### decrease speech pitch +.PP +Decrease the pitch of the speech. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### increase sound volume +.PP +Increase the volume of the sound. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +#### decrease sound volume +.PP +Decrease the volume of the sound. +This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq] +but during runtime. +### Window Mode +.PP +Fenrir supports window mode, a window is a partial area of the screen. +#### Create Window +.PP +To create a window you need to do the following: 1. +set a beginning mark (as the start of the window) 2. +set an end mark (where the window should end) 3. +press \[aq]\[aq]set window application\[aq]\[aq] shortcut. +Now Fenrir ignores anything outside of the window.\\ #### Remove Window +.PP +You can remove the window by pressing \[aq]\[aq]the clear window +application\[aq]\[aq] shortcut. +Now Fenrir will read everything on the screen again. +### Tracking Modes +.PP +Different types of tracking are currently supported See section +Focus (#Focus) in \[aq]\[aq]settings.conf\[aq]\[aq] for more +information. +#### Cursor Tracking +.PP +This follows the text cursor. +This is the typical way an application works. +This is used by: +.IP \[bu] 2 +almost any shell such as (Bash, Zsh, sh) +.IP \[bu] 2 +vim +.IP \[bu] 2 +nano +.IP \[bu] 2 +emacs +.IP \[bu] 2 +mutt +.IP \[bu] 2 +tintin++ #### Highlight Tracking +.PP +In some applications there are no text cursors. +In those applications cursor changes are represented by different colors +or attributes (underlined or bold). +This mode tracks and announces these changes for you. +This is used by: +.IP +.nf +\f[C] +*\ wifi\-menu +*\ dialog +*\ alpine +\f[] +.fi +.SS Tutorial Mode +.PP +Fenrir provides a Tutorial mode. +When you enter tutorial mode, screen reader commands are intercepted and +explained instead of executing them. +\[aq]\[aq]Arrow up\[aq]\[aq] and \[aq]\[aq]Arrow Down\[aq]\[aq] let you +navigate through a list of all available commands with shortcuts and +description. +Pressing escape leaves the tutorial mode. +.SS Information +.SS Time +.PP +Announces the current Time. +#### Date +.PP +Announces the current Date. +#### Bookmarks +.PP +Bookmarks provide quick access to part of the screen without the need to +navigate to the area. +By default Fenrir provides 10 bookmarks. +Those can be set and accessed via shortcut. +This is useful for status lines or other information where the position +does not change. +##### set Bookmark X +.PP +You need to set the bookmark first. +For that you have to set one or two lines for use. +1. +Set marks (one or two) 2. +press shortcut for \[aq]\[aq]set bookmark X\[aq]\[aq]. +X represents the number 1 \- 10. +##### read Bookmark X +.PP +If a bookmark is set you can access the area just by pressing the +\[aq]\[aq]bookmark X\[aq]\[aq] shortcut. +X represents the number 1 \- 10. +Bookmarks are dynamic. +That means the content changes with the screen. +##### clear Bookmark X +.PP +to remove a bookmark just press the \[aq]\[aq]clear bookmark X\[aq]\[aq] +shortcut. +X represents the number 1 \- 10. +Afterward the bookmark is no longer available. +#### cursor position +.PP +You can get information about the current cursor and its position by +using the "cursor position" functionality. +#### indent current line +.PP +Announce the current indent level of the current line. +It represents the number of trailing spaces of the line. +#### current screen +.PP +Reads all the current screen from the beginning to the end. +#### current screen before cursor +.PP +Reads current screen from the beginning of the screen to the current +cursor position. +#### current screen after cursor +.PP +Read anything after current cursor position to the end. +#### cursor read to end of line +.PP +Read from the current cursor position to the end of the current line. +#### cursor column +.PP +Read the current X position of a cursor (column of the current line). +#### cursor line number +.PP +Read the current Y position of a cursor (line number). +#### present first line +.PP +Reads just the first line. +this is maybe useful for status information. +#### present last line +.PP +Presets the last line. +This is maybe useful for status information. +#### last incoming +.PP +Repeat the last automatically incoming text. +## Input +.SS Echo +.PP +Fenrir provides different methods of echoing content: +.IP \[bu] 2 +Word: Will speak each word after you push space +.IP \[bu] 2 +Character: speak any letter you type on the screen +.IP \[bu] 2 +Delete Character: speaks the character prior to the cursor when you push +backspace ### Silence on Key press +.SS Spellchecker +.PP +Fenrir has a built\-in spellchecker, it can invoke automatically while +typing or be called by a shortcut. +Commands to add or remove the current word to the dictionary are +included. +As using the spellchecker is enhanced usage. +You will need dictionary aspell\-\f[C]\f[]. +See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] for +more information. +#### spell check +.PP +Invokes the spellcheck on the word that contains the Review or text +cursor. +#### add word to spell check +.PP +Adds the word under the Review or Text cursor to the dictionary. +#### removes word from spell check +.PP +Removes the word under the Review or Text cursor from the dictionary. +## Announcements +.SS Emoticons +.PP +If you want to replace ":)" emoticons with "smile" in speech you can use +this feature. +It can be toggled on or off. +You can define emoticons in a dictionary, please see Emoticon +Dictionary. +See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] to +see how to enable or disable this feature. +.SS Time +.PP +Announce the time at periodical increments, To track the time easily. +You can define 2 different ways of time announcements. +1. +periodic 2. +on fix minutes +.PP +Example periodic, every 20 minutes "delaySec=20": +.IP +.nf +\f[C] +[time] +enabled=True +presentTime=True +presentDate=True +delaySec=20 +onMinutes= +announce=True +interrupt=False\ \ \ \ +\f[] +.fi +.PP +Example on fix minutes in an hour. +example every quarter "delaySec=0" and "onMinutes=00,15,30,45": +.IP +.nf +\f[C] +[time] +enabled=True +presentTime=True +presentDate=True +#delaySec\ is\ repected\ bevore\ onMinutes\ so\ it\ need\ to\ be\ set\ to\ 0 +delaySec=0\ +onMinutes=00,15,30,45 +announce=True +interrupt=False\ \ \ \ \ \ +\f[] +.fi +.SS Promoted List +.PP +Promoted Lists are a nice feature if you are away from your computer or +performing more longer tasks. +you can define a list of words which you want to hear a sound icon for +after a period of inactivity. +Example if the word "Chrys" appears after 120 Seconds of inactivity: +[promote] enabled=True +.PD 0 +.P +.PD +inactiveTimeoutSec=120 list=Chrys See section Promote (#Promote) in +\[aq]\[aq]settings.conf\[aq]\[aq] for more information. +### Punctuation +.PP +Fenrir handles punctuation levels and names for you with several +provided dictionaries. +.PP +See levelDict See punctuationDict ## Braille +.PP +Fenrir provides Braille support in Version >= 2.0. +See section Braille (#Braille) in \[aq]\[aq]settings.conf\[aq]\[aq] for +more information. +### braille flush +.PP +If a message appears on the Braille device you can flush it to get back +to the review\- or system cursor ### Braille pan left +.PP +If a line is longer than your Braille devices you can move the view +(called panning) to the left. +So you can read stuff without the need to move the review\- or system +cursor. +### Braille pan right +.PP +If a line is longer than your Braille devices you can move the view +(called panning) to the right. +So you can read stuff without the need to move the review\- or system +cursor. +### braille return to cursor +.PP +When you have finished reading the line on the Braille device using +panning, the focus can be returned to the current used cursor by using +"return to cursor" command. +## Dictionary +.PP +You can make use of different kinds of built\-in dictionary\[aq]s. +A dictionary has a name and list of keys and values separated by :===: +Example: [customDict] Chrys:===:Chrys is cool lollipop:===:lolli that +means that every instance "chrys" is displayed, speech will say Chrys is +cool. +"lollipop" is spoken as "lolli". +Before making changes to a dictionary we recommend making a backup of +your current dictionary in case future updates overwrite your local +changes. +### Punctuation +.SS Level +.PP +The punctuation level dict contains lists with "what punctuation is +spoken in what level". +the default one looks like this: [levelDict] none:===: +some:===:.\-$~+*\-/\\\@ most:===:.,:\-$~+*\-/\@!#%^&\f[I]()[]}{\f[C]<>\f[]; +all:===:!"#$%& \[aq]()\f[]+,\-./:;\f[C]<=>\f[]?\@[\\]^_`{|}~ the level +"none" has no values. +so it should not speak any punctuation (sadly this is not respected by +every TTS system) if "some" is the current level the following are +spoken: dot dash dollar tilde plus star slash backslash at. +same for most and all, you can add new levels. +if you cycle punctuation levels they are recognized. +the default punctuation level is set in settings.conf. +The default is "some". +#### Punctuation +.PP +The punctuation dictionary "[punctDict]" contains how the punctuation is +spoken. +Example: [punctDict] \f[I]:===:line +.PD 0 +.P +.PD +speaks an \f[] as "line". +.PD 0 +.P +.PD +[punctDict] \f[I]:===:underscore speaks an \f[] as underscore. +for question mark an ? +is appended to the word that the TTS system can announce the question +correctly. +.PD 0 +.P +.PD +### Custom +.PP +The dict "[customDict]" is just for your own use, it just replace the +key with the value without any special functionality. +This might be used to fix incorrectly spoken words, make words more +common, shorter or just for fun. +:) ### Emoticons +.PP +The Emoticons dictionary "[emoticonDict]" by default contains some +emoticons. +it can replace ":)" with "smile" or "XD" with "loool" Making chat more +colorful. +A nice feature with this dictionary is that you can toggle the +substitution on or off during run time or in settings.conf. +This is useful because while doing programming or other serious work you +want to hear colons and perryns not smiles. +# Configuration +.PP +You can configure Fenrir in the following places (ordered by priority): +1. +Commandline Parameters \[aq]\[aq]\-o\[aq]\[aq] see Set settings +coption (#Set%20settings%20coption) 2. +/etc/fenrir/settings/settings.conf see Settigns (#Settings) 3. +\f[C]\f[]/config/settings/settings.conf see +Settigns (#Settings) 4. +hard coded defaults ## Commandline Arguments +.SS Set settings option +.PP +You can specify options that overwrite the setting.conf. +This is done with \[aq]\[aq]\-o \f[C]\f[] parameter. +The list of options have the following syntax fenrir \-o +"section#setting=value;section#setting=value" +.PP +For example changing the sound driver to gstreamer and disabling Braille +.PD 0 +.P +.PD +fenrir \-o "sound#driver=gstreamerDriver;braille#enabled=False=False" or +change the debug level to verbose fenrir \-o "general#debugLevel=3" You +can find the available sections and variables here <#Settings> See +Syntax #settings.conf syntax (#settings.conf%20syntax) ### settings.conf +syntax +.PP +the syntax of the settings.conf (#Settings) is quite simple and similar +to a "*.ini" file, there are 4 different elements. +1. +Sections 2. +Settings 3. +Values 4. +Comments +.PP +A comment starts with a # and is ignored by Fenrir. +# this is a comment To group settings we have sections. +A section can look like this: [Section] A setting looks like this: +settingName=Value +.PP +Example: sound (#sound) # Turn sound on or off: enabled=True # Select +the driver used to play sounds, choices are genericDriver and +gstreamerDriver. +# Sox is default. +driver=genericDriver +.SS Settings +.SS Sound +.PP +The sound is configured in section \[aq]\[aq]sound (#sound)\[aq]\[aq]. +.PP +Turn sound on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +Select the driver used to play sounds. +The genericDriver using Sox is the default. +.IP +.nf +\f[C] +driver=genericDriver +\f[] +.fi +.PP +Available Drivers: +.IP \[bu] 2 +\[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir +<1.5 just use \[aq]\[aq]generic\[aq]\[aq] +.IP \[bu] 2 +\[aq]\[aq]gstreamerDriver\[aq]\[aq] using the gstreamer, for Fenrir <1.5 +just use \[aq]\[aq]gstreamer\[aq]\[aq] +.PP +These are the pack of sounds used for sound icons. +theme=default By default we ship two sound packs. +1. +\[aq]\[aq]default\[aq]\[aq] opus encoded, for newer Sox versions 2. +\[aq]\[aq]default\-wav\[aq]\[aq] wav encoded, just for compatibility +Sound packs are located at /usr/share/sounds/fenrirscreenreader/ +.PP +Sound volume controls how loud the sounds for your selected sound pack +are. +volume=1.0 Values: \[aq]\[aq]0.0\[aq]\[aq] is quietest, +\[aq]\[aq]1.0\[aq]\[aq] is loudest. +.SS Generic Driver +.PP +The generic sound driver uses shell commands for play sound and +frequencies. +.PP +\[aq]\[aq]genericPlayFileCommand\[aq]\[aq] defines the command that is +used to play a sound file. +genericPlayFileCommand=\f[C]\f[] +\[aq]\[aq]genericFrequencyCommand\[aq]\[aq] defines the command that is +used playing frequencies. +genericFrequencyCommand=\f[C]\f[] +.PP +The following variables are substituted in +\[aq]\[aq]genericPlayFileCommand\[aq]\[aq] and +\[aq]\[aq]genericFrequencyCommand\[aq]\[aq]: +.IP \[bu] 2 +\[aq]\[aq]fenrirVolume\[aq]\[aq] = the current volume setting +.IP \[bu] 2 +\[aq]\[aq]fenrirSoundFile\[aq]\[aq] = the sound file for an sound icon +.IP \[bu] 2 +\[aq]\[aq]fenrirFrequence\[aq]\[aq] = the frequency to play +.IP \[bu] 2 +\[aq]\[aq]fenrirDuration\[aq]\[aq] = the duration of the frequency +.PP +Example genericPlayFileCommand (default) genericPlayFileCommand=play \-q +\-v fenrirVolume fenrirSoundFile Example genericFrequencyCommand +(default) genericFrequencyCommand=play \-q \-v fenrirVolume \-n \-c1 +synth fenrirDuration sine fenrirFrequence ### Speech +.PP +Speech is configured in section \[aq]\[aq][speech]\[aq]\[aq]. +Turn speech on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.SH Select speech driver, options are speechdDriver (default), +genericDriver or espeakDriver: +.PP +driver=speechdDriver #driver=espeakDriver +.SH driver=genericDriver +.PP +Select the driver used to generate speech output. +.IP +.nf +\f[C] +driver=speechdDriver +\f[] +.fi +.PP +Available Drivers: +.IP \[bu] 2 +\[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir +<1.5 this is not available +.IP \[bu] 2 +\[aq]\[aq]speechdDriver\[aq]\[aq] using speech\-dispatcher, for Fenrir +<1.5 just use \[aq]\[aq]speechd\[aq]\[aq] +.IP \[bu] 2 +\[aq]\[aq]espeakDriver\[aq]\[aq] using the espeak directly, for Fenrir +<1.5 just use \[aq]\[aq]espeak\[aq]\[aq] +.PP +The rate selects how fast Fenrir will speak. +rate=0.65 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is slowest, +Maximum:\[aq]\[aq]1.0\[aq]\[aq] is fastest. +.PP +Pitch controls the pitch of the voice. +pitch=0.5 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is lowest, +Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest. +.PP +A Pitch for capital letters can be set. +capitalPitch=0.9 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is +lowest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest. +.PP +The Volume controls the loudness of the voice. +volume=1.0 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is quietest, +Maximum:\[aq]\[aq]1.0\[aq]\[aq] is loudest. +.PP +Some speech drivers like speechdDriver can support various modules. +these can be set here. +module=espeak Values: Text, Consult speech\-dispatcher\[aq]s +configuration to see what modules are available. +.PP +Voice selects the varient you want to use, for example, f5 will use the +female voice #5 in Espeak, or if using the Espeak module in +Speech\-dispatcher. +To find out which voices are available, consult the documentation +provided with your selected synthesizer. +voice= Values: Text, see your TTS synths documentation what is +available. +.PP +Select the language you want Fenrir to use. +language=english\-us Values: Text, see your TTS synths documentation +what is available. +.PP +Read new text as it occurs autoReadIncoming=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.SS Generic Driver +.PP +The generic speech driver uses shell commands for speech synthisus. +.PP +\[aq]\[aq]genericSpeechCommand\[aq]\[aq] defines the command that is +executed for creating speech The following variables are substituted in +\[aq]\[aq]genericSpeechCommand\[aq]\[aq]: +.IP \[bu] 2 +\[aq]\[aq]FenrirText\[aq]\[aq] = is the text that should be spoken +.IP \[bu] 2 +\[aq]\[aq]fenrirModule\[aq]\[aq] = may be the speech module like used in +speech\-dispatcher, not every TTY needs this +.IP \[bu] 2 +\[aq]\[aq]fenrirLanguage\[aq]\[aq] = the language to speak in +.IP \[bu] 2 +\[aq]\[aq]fenrirVoice\[aq]\[aq] = is the current voice that should be +used +.IP \[bu] 2 +\[aq]\[aq]fenrirVolume\[aq]\[aq] = is replaced with the current volume +.IP \[bu] 2 +\[aq]\[aq]fenrirPitch\[aq]\[aq] = is replaced with the current pitch +.IP \[bu] 2 +\[aq]\[aq]fenrirRate\[aq]\[aq] = is replaced with the current speed +(speech rate) +.PP +Example genericSpeechCommand (default): genericSpeechCommand=espeak \-a +fenrirVolume \-s fenrirRate \-p fenrirPitch \-v fenrirVoice "fenrirText" +.PP +These are the minimum and maximum values of the TTS system used in +genericSpeechCommand. +They are needed to calculate the abstract range in volume, rate and +pitch 0.0 \- 1.0. +.IP +.nf +\f[C] +FenrirMinVolume=0 +fenrirMaxVolume=200 +fenrirMinPitch=0 +fenrirMaxPitch=99 +fenrirMinRate=80 +fenrirMaxRate=450 +\f[] +.fi +.PP +The current volume, pitch and rate is calculated like this value = min + +[volume,pitch,rate] * (min \- max ) ### Braille +.PP +Braille is a WIP and not ready yet. +Braille support can be configured in section +\[aq]\[aq][braille]\[aq]\[aq]. +.PP +Turn braille on or off: enabled=False Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Select the driver used for communication with a braille device. +driver=brlapiDriver Values: Text, available Driver Available Drivers: +.IP \[bu] 2 +\[aq]\[aq]brlttyDriver\[aq]\[aq] using brltty for braille communication, +for Fenrir <1.5 just use \[aq]\[aq]brltty\[aq]\[aq] +.PP +The Braille layout can be configured here layout=en Values: Text, see +braille driver for layouts. +.PP +What should the flush timeout relate to flushMode=word Values: Text, an +flushMode Existing flushModes: +.IP \[bu] 2 +\[aq]\[aq]word\[aq]\[aq] = flush after (number of words to display) * +seconds +.IP \[bu] 2 +\[aq]\[aq]char\[aq]\[aq] = flush after (number of chars to display) * +seconds +.IP \[bu] 2 +\[aq]\[aq]fix\[aq]\[aq] = flush after X seconds +.IP \[bu] 2 +\[aq]\[aq]none\[aq]\[aq] = no automatic flush (manual via shortcut) +.PP +Seconds to flush (see flushMode) flushTimeout=3 Values: Integer, in +Seconds or \[aq]\[aq]\-1\[aq]\[aq] = no automatic flush (manual via +shortcut) The total flush time calculates in relation to flushMode. +.PP +How should the Braille cursor focus be tracked? +cursorFocusMode=page Values: Text, an existing cursor focus mode +Available cursor focus modes: +.IP \[bu] 2 +\[aq]\[aq]page\[aq]\[aq] = if the cursor crosses the border move to next +page and start at begin +.IP \[bu] 2 +\[aq]\[aq]fixCell\[aq]\[aq] = ajust the cursor on a special cell where +it is always placed. +the display scroll here more smooth. +.PP +Define the cell on the Braille device where Fenrir should scroll and +keep the cursor fixCursorOnCell=\-1 Values: Integer +.IP \[bu] 2 +\[aq]\[aq]0\[aq]\[aq] = first cell on device, +.IP \[bu] 2 +\[aq]\[aq]\-1\[aq]\[aq] = last cell on device +.IP \[bu] 2 +\[aq]\[aq]>0\[aq]\[aq] = fix cell number +.PP +What cursor should Fenrir show on the Braille device +cursorFollowMode=review Values: Text, an exsiting cursor following mode. +Existing cursor following mode: +.IP \[bu] 2 +\[aq]\[aq]none\[aq]\[aq] = no automatic toggle command used +.IP \[bu] 2 +\[aq]\[aq]review\[aq]\[aq] = priority to review +.IP \[bu] 2 +\[aq]\[aq]last\[aq]\[aq] = follow last used cursor +.PP +number of cells in panning (horizontal). +How many cell should be panned on press the routing key? +panSizeHorizontal=0 Values: Integer, +.IP \[bu] 2 +\[aq]\[aq]0\[aq]\[aq] = display size +.IP \[bu] 2 +\[aq]\[aq]>0\[aq]\[aq] number of cells ### Screen +.PP +The settings for screens, (TTY, PTY) are configured in the +\[aq]\[aq][screen]\[aq]\[aq] section. +.PP +The driver to get the information from the screen: driver=vcsaDriver +Available Drivers: +.IP \[bu] 2 +\[aq]\[aq]vcsaDriver\[aq]\[aq] using the VCSA driver (for TTYs), for +Fenrir <1.5 just use \[aq]\[aq]vcsa\[aq]\[aq] The encoding of the screen +encoding=cp850 Values:\[aq]\[aq]cp850\[aq]\[aq] is used for Western +languages like USA or Europe. +.PP +The driver updates Fenrir with changes on the screen. +screenUpdateDelay=0.05 Values: in Seconds +.PP +If you want Fenrir to not be active on any screen for various reasons. +Maybe an X server or Wayland is running on that screen. +You can make Fenrir ignore it or multiple screens seperated by +\[aq]\[aq],\[aq]\[aq] with: suspendingScreen= Values: Depends on driver: +.IP \[bu] 2 +VCSA: the number of the TTY. +TTY6 is \[aq]\[aq]6\[aq]\[aq]. +Example ignore TTY1 and TTY2: suspendingScreen=1,2 +.PP +There is also the ability to let Fenrir auto detect screens that are +running an X server. +So Screens running an GUI can be ignored. +autodetectSuspendingScreen=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.SS Keyboard +.PP +The settings for keyboard and input related configuration is located in +the section \[aq]\[aq]keyboard (#keyboard)\[aq]\[aq] of the +\[aq]\[aq]settings.conf\[aq]\[aq] file. +.PP +Select the driver used for grabbing keybord input and for recieving +shortcuts. +driver=evdevDriver Values: Text, available Driver Available Drivers: +.IP \[bu] 2 +\[aq]\[aq]evdevDriver\[aq]\[aq] uses the evdev input system of linux, +for Fenrir <1.5 just use \[aq]\[aq]evdev\[aq]\[aq] +.PP +You can let Fenrir know about what input devices are to be used. +device=ALL Values: +.IP \[bu] 2 +\[aq]\[aq]ALL\[aq]\[aq] use all devices with key capabilities. +.IP \[bu] 2 +\[aq]\[aq]NOMICE\[aq]\[aq] Exclude mices from handling. +.IP \[bu] 2 +\f[C]\f[] just use the device with the given name. +.PP +Gives Fenrir exclusive access to the keyboard and lets it control +keystrokes. +This is needed to intercept Fenrir related shortcuts. +grabDevices=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +The following makes sense if you are using a second screenreader and +want to have some hooked events. +Fenrir ignores all shortcuts then. +ignoreShortcuts=False Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +The current keyboard layout used for shortcuts. +keyboardLayout=desktop Values: An absolute Path to a Keyboard definition +file or a Filename without extension located in +\[aq]\[aq]/etc/fenrir/keyboard\[aq]\[aq] +.PP +Announce characters while typing. +charEcho=False Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +Announce deleted characters charDeleteEcho=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Announce word after pressing space wordEcho=False Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Interrupt speech on any keypress interruptOnKeyPress=False Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +You can filter the keys that speech should interrupt +interruptOnKeyPressFilter= Values: (List) empty = all keys, otherwise +interrupt with specified keys +.PP +The timeout that is used for double tap shortcuts doubleTapTimeout=0.2 +Values: Seconds ### General +.PP +Overall settings can be configured from the section +\[aq]\[aq]general (#general)\[aq]\[aq]. +.PP +Set the current debug level: debugLevel=1 Values: off=0, error=1, +warning=2, info=3 +.PP +the current punctuation and dict file in use: punctuationProfile=default +Values: Text, see available profiles in +\[aq]\[aq]/etc/fenrir/punctuation\[aq]\[aq] or in +\[aq]\[aq]sourceTree/config/punctuation\[aq]\[aq] +.PP +The current punctuation level in use: punctuationLevel=some Values: +Text, See available levels in the used punctuation file. +.PP +Respect pause for punctuations: respectPunctuationPause=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Add a pause on Line break: newLinePause=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Specify the path where the clipboard should be exported to. +See export clipboard to file (#export%20clipboard%20to%20file). +The variable \[aq]\[aq]$user\[aq]\[aq] is replaced by the current logged +username. +clipboardExportPath=/tmp/fenrirClipboard Values: Text, Systemfilepath +.PP +The number of available clipboards: numberOfClipboards=10 Values: +Integer, 1 \- 999 +.PP +Replace emoticons like :) or ;) with text insertions: emoticons=True +Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Define the current Fenrir keys: fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT +Values, Text list, separated by comma. +.PP +Define the current script keys: scriptKey=KEY_COMPOSE Values, Text list, +separated by comma. +.PP +The time format to be used for (time command) output: +timeFormat=%H:%M:%P Values: see python specification for +datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) +.PP +The date format to be used for (date command) output: dateFormat=%A, %B +%d, %Y Values: see python specification for +datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) +.PP +Enable or Disable spellcheck whilst typing: autoSpellCheck=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +The use of the dictionary with spellcheck: spellCheckLanguage=en_US +Values: Text, see aspell dictionary\[aq]s. +.PP +Folder Path for your scripts "scriptKey" functionality: +scriptPath=/usr/share/fenrirscreenreader/scripts Values: Text, Existing path on file +system. +.PP +Override commands or create new ones without changing the Fenrir +defaults: commandPath=/usr/share/fenrirscreenreader/commands Values: Text, Existing +path on file system. +Subfolders in commandPath are: +.IP \[bu] 2 +\[aq]\[aq]commands\[aq]\[aq] = to create shortcut commands +.IP \[bu] 2 +\[aq]\[aq]onInput\[aq]\[aq] = executed while typing +.IP \[bu] 2 +\[aq]\[aq]onScreenChange\[aq]\[aq] = executed on change the screen +(change from TTY4 to TTY6) +.IP \[bu] 2 +\[aq]\[aq]onScreenUpdate\[aq]\[aq] = executed when the screen is +captured +.SS Focus +.PP +The configuration for basic focus is in the section +\[aq]\[aq]focus (#focus)\[aq]\[aq]. +Follow the text cursor: cursor=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +Follow highlighted text changes (Highlight Tracking): highlight=False +Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] ### +Review +.PP +Configurations for the review mode are in the section +\[aq]\[aq][review]\[aq]\[aq]. +.PP +If "next word/ char" or "prev word/char" create a linebreak, announce +it: lineBreak=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] +.PP +If "next word/ char" or "prev word/char" cannot be performed because you +reached the end of the screen, announce it: endOfScreen=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Leave the review mode when pressing a key: leaveReviewOnKeypress=False +Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Leave the review mode when changing the screen (From TTY3 to TTY4): +leaveReviewOnScreenChange=True Values: on=\[aq]\[aq]True\[aq]\[aq], +off=\[aq]\[aq]False\[aq]\[aq] ### Promote +.PP +"Promoted Lists" are configured in the section +\[aq]\[aq][promote]\[aq]\[aq]. +Turn Promoted Lists" on or off: enabled=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +The minimum time interval of inactivity to activate promoting. +By default it promotes after 120 Seconds inactivity: +inactiveTimeoutSec=120 Values: in Seconds +.PP +Define a list of promoted words comma seperated: list= Values: text +(comma seperated) Example to promote the word "nickname" or a bash +prompt: list=nickname,$:,#: +.SS Time +.PP +The automated time announcement is configured in the section +\[aq]\[aq]time (#time-2)\[aq]\[aq]. +Time announcement is disabled by default. +Turn time announcement on or off: enabled=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Should the time be announced: presentTime=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Should the date be announced (just on date change): presentDate=True +Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Announce after a given period of seconds: delaySec=0 Value: in Seconds, +0 = Deactivated +.PP +Announce after fixed minutes in an hour. +if delaySec is >0 onMinutes is ignored: onMinutes=00,30 Example every 15 +minutes: onMinutes=00,15,30,45 +.PP +Just play a soundicon, (not interrupting): announce=True Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] +.PP +Interrupt current speech for time announcement: interrupt=False Values: +on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] # +Customization +.SS Scripting +.PP +Scripts can be in any language, bash, python, sh or others. +Place your scripts in the directory /usr/share/fenrirscreenreader/scripts/ (the path +is configurable in settings.conf). +The script key is the applications key. +Usually this key can be found on the keyboard located just left of the +right most control key. +When you name a script, the key name appears in the script seperated by +the sequence \f[B]\-\f[]. +So, for example, if you have a python weather script you want assigned +to the script key plus the letter w you would name the script +/usr/share/fenrirscreenreader/scripts/weather__\-__key_w.py Then, to access the +script, simply press the script key and the letter w. +Scripts must be executable. +So, make sure to chmod 755 your script when you place it in the scripts +directory. +The script gets some parameters from fenrir when it is executed. +So that information is available in your script then. +.SS Parameterlist +.PP +.TS +tab(@); +l l. +T{ +Parameter +T}@T{ +Content +T} +_ +T{ +$1 +T}@T{ +Username of the current logged in user +T} +.TE +.SS Examples +.PP +Script that just speaks the current username when pressing ScriptKey + +H.\\ File: +\[aq]\[aq]/usr/share/fenrirscreenreader/scripts/helloWorld__\-__key_h.sh\[aq]\[aq]: +#!/bin/bash echo $1 +.SS Commands +.PP +You can place your own commands in "/usr/share/fenrirscreenreader/commands" (path is +configurable in settings.conf). +Commands are python files with a special scheme. +You can assign them to a shortcut using the filename without an +extension or place them in a hook trigger like OnInput or +OnScreenChange. +For further information see developer guide. +Good Examples: +"date.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py) +(announce the Date), +"shut_up.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py) +(interrupt output) the basic scheme for a command is as follows: +.IP +.nf +\f[C] +from\ core\ import\ debug + +class\ command(): +\ \ def\ __init__(self): +\ \ \ \ \ \ pass +\ \ def\ initialize(self,\ environment): +\ \ \ \ \ \ self.env\ =\ environment +\ \ def\ shutdown(self): +\ \ \ \ \ \ pass +\ \ def\ getDescription(self): +\ \ \ \ \ \ return\ _(\[aq]No\ description\ found\[aq]) +\ \ def\ run(self): +\ \ \ \ \ \ pass +\ \ def\ setCallback(self,\ callback): +\ \ \ \ \ \ pass +\f[] +.fi +.IP \[bu] 2 +Template lives +here (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py) +.IP \[bu] 2 +The class needs to have the name "command". +.IP \[bu] 2 +"initialize" is running once whilst loading the command. +.IP \[bu] 2 +"shutdown" is running on unload like the command (quit fenrir) +.IP \[bu] 2 +"getDescriptsion" just returns an string. +That String is used in Tutorial Mode. +.IP \[bu] 2 +"run" is executed when the command is invoked. +(shortcut is pressed, or trigger isn\[aq]t running) +.IP \[bu] 2 +setCAllback is currently not used. +and has no functionality yet. +.SH Troubleshooting +.SS Fenrir does not start +.IP " 1." 4 +Have you installed all the dependencies Support and +Requirements (#Support%20and%20Requirements) +.IP " 2." 4 +Try using master, a lot of changes take place there to make Fenrir +compatible with more systems ## Fenrir does not utilize the shortcuts +.IP " 3." 4 +Make sure you have python3\-evdev installed +.IP " 4." 4 +Use the latest Fenrir version +.IP " 5." 4 +Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or +run it as root) ## No sound at all +.IP " 6." 4 +Run the script to configure Pulseaudio once as root and once as your +user. +This will setup Pulseaudio but require a restart of Pulseaudio. +The script is located in \[aq]\[aq]tools/configure_pulse.sh\[aq]\[aq] +.IP " 7." 4 +Use ALSA +.IP " 8." 4 +Configure Pulse system +wide (https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/) +(Not recommended) +.IP " 9." 4 +Use gstreamerDriver: change \[aq]\[aq]settings.conf\[aq]\[aq] in the +section \[aq]\[aq]sound\[aq]\[aq] the line +\[aq]\[aq]driver=genericDriver\[aq]\[aq] to +\[aq]\[aq]driver=gstreamerDriver\[aq]\[aq] +.IP "10." 4 +Use wave sound\-icons: change \[aq]\[aq]settings.conf\[aq]\[aq] in the +section \[aq]\[aq]sound\[aq]\[aq] the line +\[aq]\[aq]theme=default\[aq]\[aq] to +\[aq]\[aq]theme=default\-wav\[aq]\[aq] +.IP "11." 4 +Use most current version of sox (http://sox.sourceforge.net/) with opus +support +.IP "12." 4 +Try apulse (https///github.com/i-rinat/apulse) (not tested by myself but +might work). +Please give me feedback if you try it out. +## You get sound\-icons but no speech +.IP "13." 4 +If you are using speech\-dispatcher run "spd\-conf" once as user and as +root. +.IP "14." 4 +You can test if speech\-dispatcher works by invoking it as root\\ +\[aq]\[aq]sudo spd\-say "hello world"\[aq]\[aq] ## Bugreports and +feature requests +.PP +Please report Bugs and feature requests to: +https://github.com/chrys87/fenrir/issues (https///github.com/chrys87/fenrir/issues) +.PP +for bugs please provide a debug (#Howto%20create%20a%20debug%20file) +file that shows the issue. +### How\-to create a debug file +.IP "1." 3 +Delete old debug stuff\\ \[aq]\[aq]sudo rm /var/log/fenrir.log\[aq]\[aq] +.IP "2." 3 +Start fenrir in debug mode\\ \[aq]\[aq]sudo fenrir \-d\[aq]\[aq] +.IP "3." 3 +Do your stuff to reproduce the problem +.IP "4." 3 +Stop fenrir (\[aq]\[aq]fenrirKey + q\[aq]\[aq]) the debug file is +located in \[aq]\[aq]/var/log/fenrir.log\[aq]\[aq] +.PP +Please be as precise as possible to make it easy to solve the problem. diff --git a/docu/user.md b/docu/user.md new file mode 100644 index 00000000..a789dd2d --- /dev/null +++ b/docu/user.md @@ -0,0 +1,1590 @@ +# Fenrir User Manual + +Fenrir is a modern command line screen reader written in Python3. + +It has a modular structure, a flexible based driver model, is highly configurable and easy to customize and extend ([see Developer Manual](fenrir_development_manual)). + +Please see the following pages for the [current](fenrir_current_version) and [Git](fenrir_git_version) version of Fenrir. + + +# Support and Requirements + + +Fenrir requires several drivers to interact with the operating system. + +## Speech Drivers + + +A speech driver is for communication with the text to speech system like [Speech-Dispatcher](#SpeechDispatcher) or [Espeak](http://espeak.sourceforge.net). \\ +See section [Speech](#Speech) in ''settings.conf'' for more information. + + +### SpeechDispatcher + + +This driver is used by default. +It uses Speech-dispatcher as its backend. + +Dependencies: + + +* Speech-dispatcher (installed and configured, [Documentation](https///devel.freebsoft.org/speechd#sec2)) + +* Python-speechd + +### Espeak + + +Uses Espeak via Python bindings. + +Dependencies: + +* Espeak or Espeak-ng + +* [python-espeak](https///launchpad.net/python-espeak) + +### Generic + + +This invokes speech via a sub-process. This is almost the same as using the commandline. The performance depends on the overhead of the speech synthesis application but it is really flexible. + +Dependencies: + +* Espeak or Espeak-ng + +The Requirements are flexible, they depend on the configuration in settings.conf. + +### Dummy + + +this is just for debugging, logs are output to the screen and logged as well. + +## Sound Drivers + + +To play sound icons and similar.\\ +See section [Sound](#Sound) in ''settings.conf'' for more information. + +### Generic + + +This driver is used by default. + +Dependencies: + + +* [Sox](http://sox.sourceforge.net/) with opus support +The Requirements are flexible, they depend on the configuration in settings.conf. + +### Gstreamer + +if you prefer to use Gstreamer for sound output. + +Dependencies: + +* Gstreamer >= 1.x + +* Glibc + +### Dummy + + +this is just for debugging, logs are output to the screen and logged as well. + +## Input Drivers + + +Input drivers are to capture keyboard shortcuts issued to the screen reader \ +See section [Keyboard](#Keyboard) in ''settings.conf'' for more information. + +### Evdev + + +This driver is used by default. + +Evdev is the low level input device framework for Linux. + +Dependencies: + + +* python-evdev >=0.6.3 + +* pyudev + +* loaded uinput kernel module + +* exclusive access to the input devices +Read permission to the following files and services: + +* /dev/input + +* /dev/uinput + +## Screen Drivers + + +The job of a screen driver is to get the information of current screen content.\\ +See section [Screen](#Screen) in ''settings.conf'' for more information. + +### VCSA + + +This driver is used by default. +For Linux VCSA devices. These exist on any current standard installation of Linux. + +Dependencie +s: + + +* python-dbus +Read permission to the following files and services (or run as root): + +* /sys/devices/virtual/tty/tty0/active + +* /dev/tty[1 - 64] + +* /dev/vcsa[1 - 64] ([VCSA manpage](https///linux.die.net/man/4/vcsa)) + +* read Logind DBUS + +## Braille Drivers + +This is for Braille support. +Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\ +See section [Braille](#Braille) in ''settings.conf'' for more information. + + +### BRLTTY + + +This driver is used by default. +It uses [BrlTTY](brltty) to communicate with with a Braille device. + +Dependencies: + + +* BrlTTY (configured and running, [Documentation](http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html)) + +* python-brlapi (configured, [Documentation](http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html)) +## Currently supported platforms + + +Currently Fenrir completely supports the following Platforms: + +* Linux TTY +Support for further Systems are planned. + +# Installation + + +Fenrir can run without installation. It just requires the dependencies are installed first. + +We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment. + +## Try Out + +Fenrir does not require installation. You can try it and make sure everything works before you decide to install. In this way you can be sure that your system doesnt break or stop talking. +for that you can just grab the code and run as root ''src/fenrir/fenrir'' (in foreground) or ''src/fenrir/fenrir-daemon'' (in background, used by systemd for autostart) + +## Install it + +### Documented operating systems + + +### Arch Linux + + +For Arch there are PKGBUILDs in the AUR: + +* [fenrir](https///aur.archlinux.org/packages/fenrir/) + +* [fenrir-git](https///aur.archlinux.org/packages/fenrir-git/) + +### Manual + + + 1. Download the latest stable version from the [Fenrir-Project](https///linux-a11y.org/index.php?page=fenrir-screenreader) site. + 2. Unpack the archive + 3. Check the needed Dependencys by running [check-dependencys.py](https///github.com/chrys87/fenrir/blob/master/check-dependencies.py) script + 4. install the missing dependencies an standard installation requires the following: + + * python3 >= 3.3 (and all the following is needed for python3 ) + * python3-speechd (screen) + * python3-dbus (screen) + * python3-evdev >= 0.6.4(input) + * python3-daemonize (background service) + * python3-brlapi (braille) + * python3-pyenchant (spellchecker) + * your language for aspell (aspell-``) (spellchecker) + * sox (sound) + * For an individual installation see [Support and Requirements](#Support and Requirements) or consult the [Readme](https///github.com/chrys87/fenrir/blob/master/README.md)) + 5. run "install.sh" as root + +this installs Fenrir as the following + + * Application:''/opt/fenrir'' + * Settings:''/etc/fenrir'' + * Sound Icons:''/usr/share/fenrirscreenreader/'' + +to remove Fenrir just run uninstall.sh as root + +### Git + + +if you want to get the latest code you can use git to get a development snapshot: + + git clone https://github.com/chrys87/fenrir.git + +## Auto Start + + +To start Fenrir once: + systemctl start fenrir + +To enable auto start on system boot: + systemctl enable fenrir + +# First Steps + + +If you are using Fenrir for the first time you may want to take a look at these resources: + +* [Keybindings](#Keybindings) + +* [Tutorial Mode](#Tutorial Mode) + +# Features + + +## Commands + + +### Keybindings + + +Normal commands can be invoked in two ways: + 1. Using a Metakey ([FenrirKey](#Fenrir Key)) + 2. Shortcuts with a single key + +See section [Keyboard](#Keyboard) in ''settings.conf'' for more information. +#### Fenrir Key + +The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time. +By default the following keys are used: + 1. Insert + 2. KeyPad Insert + 3. Meta (Super, Windows) + +#### Script Key + +To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [Scripting](#Scripting) +#### Desktop Layout + + | Shortcut | Command | + | -------- | ------- | + | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) | + | CTRL | [shut up (interrupts speech)](#shut up) | + | FenrirKey + KeyPad 9 | [reviews bottom](#review bottom) | + | FenrirKey + KeyPad 7 | [reviews top](#review top) | + | KeyPad 8 | [reviews current line](#review current line) | + | KeyPad 7 | [reviews previous line](#review previous line) | + | KeyPad 9 | [reviews next line](#review next line) | + | FenrirKey + KeyPad 4 | [reviews line beginning](#review line beginning) | + | FenrirKey + KeyPad 6 | [reviews line ending](#review line ending) | + | FenrirKey + KeyPad 1 | [reviews line first character](#review line first character) | + | FenrirKey + KeyPad 3 | [reviews line last character](#review line last character) | + | FenrirKey + Alt + 1 | [presents first line](#present first line) | + | FenrirKey + Alt + 2 | [presents last line](#present last line) | + | KeyPad 5 | [reviews current word](#review current word) | + | KeyPad 4 | [reviews previous word](#review previous word) | + | KeyPad 6 | [reviews next word](#review next word) | + | FenrirKey + Shift + KeyPad 5 | [reviews current word phonetic](#review current word phonetic) | + | FenrirKey + Shift + KeyPad 4 | [reviews previous word phonetic](#review previous word phonetic) | + | FenrirKey + Shift + KeyPad 6 | [reviews next word phonetic](#review next word phonetic) | + | KeyPad 2 | [reviews current char](#review current character) | + | KeyPad 1 | [reviews previous char](#review previous character) | + | KeyPad 3 | [reviews next char](#review next character) | + | FenrirKey + Shift + KeyPad 2 | [reviews current character phonetic](#review current character phonetic) | + | FenrirKey + Shift + KeyPad 1 | [reviews previous character phonetic](#review previous character phonetic) | + | FenrirKey + Shift + KeyPad 3 | [reviews next character phonetic](#review next character phonetic) | + | FenrirKey + CTRL + KeyPad 8 | [reviews up](#review up) | + | FenrirKey + CTRL + KeyPad 2 | [reviews down](#review down) | + | FenrirKey + KeyPad dot | [exit review](#exit review) | + | KeyPad dot | [cursor position](#cursor position) | + | FenrirKey + I | [indent curr line](#indent current line) | + | FenrirKey + KeyPad 5 | [current screen](#current screen) | + | FenrirKey + KeyPad 8 | [current screen before cursor](#current screen before cursor) | + | FenrirKey + KeyPad 2 | [current screen after cursor](#current screen after cursor) | + | `` | [cursor read to end of line](#cursor read to end of line) | + | `` | [cursor column](#cursor column) | + | `` | [cursor line number](#cursor line number) | + | `` | [Braille flush](#braille flush) | + | `` | [Braille pan left](#braille pan left) | + | `` | [Braille pan right](#braille pan right) | + | `` | [Braille return to cursor](#braille return to cursor) | + | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) | + | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) | + | FenrirKey + 1 | [bookmark 1](#read Bookmark X) | + | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) | + | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) | + | FenrirKey + 2 | [bookmark 2](#read Bookmark X) | + | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) | + | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) | + | FenrirKey + 3 | [bookmark 3](#read Bookmark X) | + | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) | + | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) | + | FenrirKey + 4 | [bookmark 4](#read Bookmark X) | + | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) | + | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) | + | FenrirKey + 5 | [bookmark 5](#read Bookmark X) | + | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) | + | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) | + | FenrirKey + 6 | [bookmark 6](#read Bookmark X) | + | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) | + | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) | + | FenrirKey + 7 | [bookmark 7](#read Bookmark X) | + | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) | + | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) | + | FenrirKey + 8 | [bookmark 8](#read Bookmark X) | + | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) | + | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) | + | FenrirKey + 9 | [bookmark 9](#read Bookmark X) | + | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) | + | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) | + | FenrirKey + 0 | [bookmark 10](#read Bookmark X) | + | FenrirKey + KeyPad Slash | [set window application](#Create Window) | + | 2 * FenrirKey + KeyPad Slash | [clear window application](#Remove Window) | + | KeyPad Plus | [read last incoming](#last incoming) | + | FenrirKey + F2 | [toggles braille](#toggle braille) | + | FenrirKey + F3 | [toggles sound](#toggle sound) | + | FenrirKey + F4 | [toggles speech](#toggle speech) | + | KeyPad Enter | [temporarily disables speech](#disable speech temporarily) | + | FenrirKey + CTRL + P | [toggles punctuation level](#toggle punctuation level) | + | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) | + | FenrirKey + Backslash | [toggles output](#toggle output) | + | FenrirKey + CTRL + E | [toggles emoticons](#toggle emoticons) | + | FenrirKey + KeyPad Enter | [toggles auto read](#toggle auto read) | + | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) | + | FenrirKey + KeyPad ASTERISK | [toggles highlight tracking](#toggle highlight tracking) | + | FenrirKey + Q | [quits fenrir](#quit Fenrir) | + | FenrirKey + T | [Announce time](#Time) | + | 2 * FenrirKey + T | [Announce date](#Date) | + | FenrirKey + S | [spell check](#spell check) | + | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) | + | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) | + | FenrirKey + Backspace | [forward keypress](#forward keypress) | + | FenrirKey + Up | [increase speech volume](#increase speech volume) | + | FenrirKey + Down | [decrease speech volume](#decrease speech volume) | + | FenrirKey + Right | [increase speech rate](#increase speech rate) | + | FenrirKey + Left | [decrease speech rate](#decrease speech rate) | + | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) | + | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) | + | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) | + | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) | + | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) | + | FenrirKey + Home | [first clipboard](#first clipboard) | + | FenrirKey + End | [last clipboard](#last clipboard) | + | FenrirKey + PageUp | [previous clipboard](#previous clipboard) | + | FenrirKey + PageDown | [next clipboard](#next clipboard) | + | FenrirKey + Shift + C | [current clipboard](#read current clipboard) | + | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) | + | FenrirKey + V | [paste clipboard contents](#paste clipboard) | + | FenrirKey + P | [import clipboard from file](#import clipboard from file) | + | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) | + | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) | + | FenrirKey + X | [set mark](#Set mark) | + | FenrirKey + Shift + X | [announce marked text](#Get text between marks) | + | Linux specific | + | `` | export clipboard to X | + | FenrirKey + CTRL + Up | include Alsa volume | + | FenrirKey + CTRL + Down | decrease Alsa volume | + +#### Laptop Layout + + | Shortcut | Command | + | -------- | ------- | + | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) | + | CTRL | [shut up (interrupts speech)](#shut up) | + | FenrirKey + Shift + O | [reviews bottom](#review bottom) | + | FenrirKey + Shift + U | [reviews top](#review top) | + | FenrirKey + I | [reviews current line](#review current line) | + | FenrirKey + U | [reviews previous line](#review previous line) | + | FenrirKey + O | [reviews next line](#review next line) | + | FenrirKey + Shift + J | [reviews line beginning](#review line beginning) | + | FenrirKey + Shift + L | [reviews line ending](#review line ending) | + | FenrirKey + CTRL + J | [reviews line first character](#review line first character) | + | FenrirKey + CTRL + L | [reviews line last character](#review line last character) | + | FenrirKey + Alt + 1 | [presents first line](#present first line) | + | FenrirKey + Alt + 2 | [presents last line](#present last line) | + | FenrirKey + K | [reviews current word](#review current word) | + | FenrirKey + J | [reviews previous word](#review previous word) | + | FenrirKey + L | [reviews next word](#review next word) | + | FenrirKey + CTRL + ALT + K | [reviews current word phonetic](#review current word phonetic) | + | FenrirKey + CTRL + ALT + J | [reviews previous word phonetic](#review previous word phonetic) | + | FenrirKey + CTRL + ALT + L | [reviews next word phonetic](#review next word phonetic) | + | FenrirKey + comma | [reviews current character](#review current character) | + | FenrirKey + M | [reviews previous character](#review previous character) | + | FenrirKey + dot | [reviews next character](#review next character) | + | FenrirKey + CTRL + ALT + comma | [reviews current character phonetic](#review current character phonetic) | + | FenrirKey + CTRL + ALT + M | [reviews previous character phonetic](#review previous character phonetic) | + | FenrirKey + CTRL + ALT + dot | [reviews next character phonetic](#review next character phonetic) | + | FenrirKey + CTRL + I | [reviews up](#review up) | + | FenrirKey + CTRL + comma | [reviews down](#review down) | + | FenrirKey + Slash | [exit review](#exit review) | + | FenrirKey + Shift + dot | [cursor position](#cursor position) | + | 2 * FenrirKey + I | [indent curr line](#indent current line) | + | FenrirKey + Shift + K | [current screen](#current screen) | + | FenrirKey + Shift + I | [current screen before cursor](#current screen before cursor) | + | FenrirKey + Shift + comma | [current screen after cursor](#current screen after cursor) | + | `` | [cursor read to end of line](#cursor read to end of line) | + | `` | [cursor column](#cursor column) | + | `` | [cursor line number](#cursor line number) | + | `` | [Braille flush](#braille flush) | + | `` | [Braille pan left](#braille pan left) | + | `` | [Braille pan right](#braille pan right) | + | `` | [Braille return to cursor](#braille return to cursor) | + | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) | + | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) | + | FenrirKey + 1 | [bookmark 1](#read Bookmark X) | + | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) | + | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) | + | FenrirKey + 2 | [bookmark 2](#read Bookmark X) | + | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) | + | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) | + | FenrirKey + 3 | [bookmark 3](#read Bookmark X) | + | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) | + | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) | + | FenrirKey + 4 | [bookmark 4](#read Bookmark X) | + | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) | + | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) | + | FenrirKey + 5 | [bookmark 5](#read Bookmark X) | + | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) | + | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) | + | FenrirKey + 6 | [bookmark 6](#read Bookmark X) | + | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) | + | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) | + | FenrirKey + 7 | [bookmark 7](#read Bookmark X) | + | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) | + | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) | + | FenrirKey + 8 | [bookmark 8](#read Bookmark X) | + | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) | + | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) | + | FenrirKey + 9 | [bookmark 9](#read Bookmark X) | + | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) | + | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) | + | FenrirKey + 0 | [bookmark 10](#read Bookmark X) | + | FenrirKey + CTRL + 8 | [set window application](#Create Window) | + | 2 * FenrirKey + CTRL + 8 | [clear window application](#Remove Window) | + | FenrirKey + Semicolon | [read last incoming](#last incoming) | + | FenrirKey + F2 | [toggles braille](#toggle braille) | + | FenrirKey + F3 | [toggles sound](#toggle sound) | + | FenrirKey + F4 | [toggles speech](#toggle speech) | + | FenrirKey + Enter | [temporarily disables speech](#disable speech temporarily) | + | FenrirKey + Shift + CTRL + P | [toggles punctuation level](#toggle punctuation level) | + | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) | + | FenrirKey + Shift + Enter | [toggles output](#toggle output) | + | FenrirKey + Shift + E | [toggles emoticons](#toggle emoticons) | + | FenrirKey + Enter | [toggles auto read](#toggle auto read) | + | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) | + | FenrirKey + Y | [toggles highlight tracking](#toggle highlight tracking) | + | FenrirKey + Q | [quits fenrir](#quit Fenrir) | + | FenrirKey + T | [Announce time](#Time) | + | 2 * FenrirKey + T | [Announce date](#Date) | + | FenrirKey + S | [spell check](#spell check) | + | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) | + | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) | + | FenrirKey + Backspace | [forward keypress](#forward keypress) | + | FenrirKey + Up | [increase speech volume](#increase speech volume) | + | FenrirKey + Down | [decrease speech volume](#decrease speech volume) | + | FenrirKey + Right | [increase speech rate](#increase speech rate) | + | FenrirKey + Left | [decrease speech rate](#decrease speech rate) | + | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) | + | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) | + | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) | + | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) | + | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) | + | FenrirKey + Home | [first clipboard](#first clipboard) | + | FenrirKey + End | [last clipboard](#last clipboard) | + | FenrirKey + PageUp | [previous clipboard](#previous clipboard) | + | FenrirKey + PageDown | [next clipboard](#next clipboard) | + | FenrirKey + Shift + C | [current clipboard](#read current clipboard) | + | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) | + | FenrirKey + V | [paste clipboard contents](#paste clipboard) | + | FenrirKey + F5 | [import clipboard from file](#import clipboard from file) | + | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) | + | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) | + | FenrirKey + X | [set mark](#Set mark) | + | FenrirKey + Shift + X | [announce marked text](#Get text between marks) | + | Linux specific | + | `` | export clipboard to X | + | FenrirKey + CTRL + Up | increases Alsa volume | + | FenrirKey + CTRL + Down | decreases Alsa volume | +### General + +#### quit Fenrir +Just stops fenrir. +#### shut up + +Interrupt the current spoken. +### Review Modes + +Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor. + +Using the review feature will open the review mode automatically. + +The review cursor always starts from the text cursor. Attention: after using the review mode, the review cursor will stay open until you use the ''exit review'' shortcut. + +Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor. + +Fenrir sounds a bell sound if the used review command jumps to another line or end of screen. +#### exit review + +You can leave the review mode by pressing the ''exit review'' shortcut. +#### review bottom + +Set the review cursor to first column in the last line. +#### review top + +Set the review cursor to the first column in the first line +#### review current line + +Set the review cursor to the beginn of the the current line and review it. +#### review previous line + +Set the review cursor to the previous line and review it. +#### review next line + +Set the review cursor to the next line and review it. +#### review line beginning + +Set the review cursor to the begin of the current line +#### review line ending + +Set the review cursor to the end of the current line +#### review line first character + +Set the review cursor the first char (that is not space) in the current line and review it. +#### review line last character + +Set the review cursor the last char (that is not space) in the current line and review it. +#### review current word + +Sets the review cursor to the beginning of the current word and review it. +#### review previous word + +Sets the review cursor to the beginning of the previous word and review it. +#### review next word + +Sets the review cursor to the beginning of the next word and review it. +#### review current word phonetic + +Sets the review cursor to the beginning of the current word and spell it phonetic. +#### review previous word phonetic + +Sets the review cursor to the beginning of the previous word and spell it phonetic. +#### review next word phonetic + +Sets the review cursor to the beginning of the next word and spell it phonetic. +#### review current character + +Does not change the review cursor. Just announce the current char. +#### review previous character + +Sets review cursor to the previous column and review it +#### review next character + +Sets review cursor to the next column and review it +#### review current character phonetic + +Does not change the review cursor. Just announce the current char phonetic. +#### review previous character phonetic + +Sets review cursor to the previous column and announce the char phonetic. +#### review next character phonetic + +Sets review cursor to the next column and announce the char phonetic. +#### review up + +Set the review cursor in the same column one line above the current one and review it. +#### review down + +Set the review cursor in the same column one line below the current one and review it. +### Handling marking + +A mark defines a point of origin or end to prepare to copy or paste a block of text. +\\ +Examples where you need marks are: + +* copy to clipboard + +* set window application + +* set bookmark 1 - X +#### Set mark + +How to set a mark: + 1. navigate with review or textcursor to the position you want to set the mark. Attention: if a review cursor is set, that is the prefered. If you want to use text cursor, be sure that you are not in review mode. + 2. press shortcut for ''set mark'' +you can set two marks (begin and end). Some commands allow some simpler usecases just using the whole line if only one mark is set. you may want to try this out. +#### Get text between marks + +To get the text that is currently between your marks press shortcut for ''marked text''.\\ +#### Remove Marks + +You can remove all current marks by pressing the shortcut for ''remove marks''. +Changing the screen also removes the marks. +### Screen Interaction + +Fenrir provides several methods to interact with the current screen. +#### forward keypress + +This just forwards the next shortcut to the screen Fenrir shortcut or not. This is useful if the currently pressed shortcut is also in use by Fenrir. +#### Clipboard + +Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard. +##### copy marked to clipboard + +To copy something to the clipboard you need to set one or two marks. if you set one mark, the text between the mark and your current cursor is copied to clipboard. Setting two marks just copies the text between the marks into the clipboard. If you copy something it is always placed as the first item on your clipboard. +##### clear clipboard + +You can remove all items from the current clipboard by ''clear clipboard'' functionality. +##### first clipboard + +This moves quick to the first item of the clipboard. +##### last clipboard + +This moves quick to the last item of the clipboard. +##### previous clipboard + +Go to previous item in the clipboard. +##### next clipboard + +Go to next item on the clipboard. +##### read current clipboard + +Read the content of the current item of the clipboard. +##### paste clipboard + +Pass whatever item is currently selected by first, last, prev or next clipboard commands. +if no special clipboard is selected the (last copied) is used. +##### export clipboard to file + +This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop. +##### import clipboard from file + +Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop. +### Quick Settings + +Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file. +#### toggle braille + +Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle sound + +Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle speech + +Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time. +#### disable speech temporarily + +Disables the speech until next key press. it might be useful if you want to listen to music or similar. As soon as a key is pressed it is going to be enabled again. +#### toggle punctuation level + +Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle auto spell check + +Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle emoticons + +Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime. +#### toggle output + +Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle auto read + +Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle auto time + +Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time. +#### toggle highlight tracking + +Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time. +#### increase speech volume + +Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### decrease speech volume + +Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### increase speech rate + +Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### decrease speech rate + +Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### increase speech pitch + +Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### decrease speech pitch + +Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +#### increase sound volume + +Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. +#### decrease sound volume + +Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. +### Window Mode + +Fenrir supports window mode, a window is a partial area of the screen. +#### Create Window + +To create a window you need to do the following: + 1. set a beginning mark (as the start of the window) + 2. set an end mark (where the window should end) + 3. press ''set window application'' shortcut. +Now Fenrir ignores anything outside of the window.\\ +#### Remove Window + +You can remove the window by pressing ''the clear window application'' shortcut. +Now Fenrir will read everything on the screen again. +### Tracking Modes + +Different types of tracking are currently supported +See section [Focus](#Focus) in ''settings.conf'' for more information. +#### Cursor Tracking + +This follows the text cursor. This is the typical way an application works. This is used by: + +* almost any shell such as (Bash, Zsh, sh) + +* vim + +* nano + +* emacs + +* mutt + +* tintin++ +#### Highlight Tracking + +In some applications there are no text cursors. In those applications cursor changes are represented by different colors or attributes (underlined or bold). This mode tracks and announces these changes for you. This is used by: + + * wifi-menu + * dialog + * alpine +### Tutorial Mode + +Fenrir provides a Tutorial mode. +When you enter tutorial mode, screen reader commands are intercepted and explained instead of executing them. ''Arrow up'' and ''Arrow Down'' let you navigate through a list of all available commands with shortcuts and description. Pressing escape leaves the tutorial mode. + +### Information + +#### Time +Announces the current Time. +#### Date + +Announces the current Date. +#### Bookmarks + +Bookmarks provide quick access to part of the screen without the need to navigate to the area. +By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut. +This is useful for status lines or other information where the position does not change. +##### set Bookmark X + +You need to set the bookmark first. For that you have to set one or two lines for use. + 1. Set marks (one or two) + 2. press shortcut for ''set bookmark X''. X represents the number 1 - 10. +##### read Bookmark X + +If a bookmark is set you can access the area just by pressing the ''bookmark X'' shortcut. X represents the number 1 - 10. Bookmarks are dynamic. That means the content changes with the screen. +##### clear Bookmark X + +to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10. +Afterward the bookmark is no longer available. +#### cursor position + +You can get information about the current cursor and its position by using the "cursor position" functionality. +#### indent current line + +Announce the current indent level of the current line. It represents the number of trailing spaces of the line. +#### current screen + +Reads all the current screen from the beginning to the end. +#### current screen before cursor + +Reads current screen from the beginning of the screen to the current cursor position. +#### current screen after cursor + +Read anything after current cursor position to the end. +#### cursor read to end of line + +Read from the current cursor position to the end of the current line. +#### cursor column + +Read the current X position of a cursor (column of the current line). +#### cursor line number + +Read the current Y position of a cursor (line number). +#### present first line + +Reads just the first line. this is maybe useful for status information. +#### present last line + +Presets the last line. This is maybe useful for status information. +#### last incoming + +Repeat the last automatically incoming text. +## Input + +### Echo +Fenrir provides different methods of echoing content: + +* Word: Will speak each word after you push space + +* Character: speak any letter you type on the screen + +* Delete Character: speaks the character prior to the cursor when you push backspace +### Silence on Key press + +### Spellchecker +Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut. +Commands to add or remove the current word to the dictionary are included. +As using the spellchecker is enhanced usage. You will need dictionary aspell-``. +See section [General](#General) in ''settings.conf'' for more information. +#### spell check + +Invokes the spellcheck on the word that contains the Review or text cursor. +#### add word to spell check + +Adds the word under the Review or Text cursor to the dictionary. +#### removes word from spell check + +Removes the word under the Review or Text cursor from the dictionary. +## Announcements + +### Emoticons +If you want to replace ":)" emoticons with "smile" in speech you can use this feature. +It can be toggled on or off. +You can define emoticons in a dictionary, please see Emoticon Dictionary. +See section [General](#General) in ''settings.conf'' to see how to enable or disable this feature. + +### Time + +Announce the time at periodical increments, To track the time easily. +You can define 2 different ways of time announcements. + 1. periodic + 2. on fix minutes + +Example periodic, every 20 minutes "delaySec=20": + + [time] + enabled=True + presentTime=True + presentDate=True + delaySec=20 + onMinutes= + announce=True + interrupt=False + +Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45": + + [time] + enabled=True + presentTime=True + presentDate=True + #delaySec is repected bevore onMinutes so it need to be set to 0 + delaySec=0 + onMinutes=00,15,30,45 + announce=True + interrupt=False +### Promoted List + +Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks. +you can define a list of words which you want to hear a sound icon for after a period of inactivity. +Example if the word "Chrys" appears after 120 Seconds of inactivity: + [promote] + enabled=True + inactiveTimeoutSec=120 + list=Chrys +See section [Promote](#Promote) in ''settings.conf'' for more information. +### Punctuation + +Fenrir handles punctuation levels and names for you with several provided dictionaries. + +See levelDict +See punctuationDict +## Braille + +Fenrir provides Braille support in Version >= 2.0. +See section [Braille](#Braille) in ''settings.conf'' for more information. +### braille flush + +If a message appears on the Braille device you can flush it to get back to the review- or system cursor +### Braille pan left + +If a line is longer than your Braille devices you can move the view (called panning) to the left. +So you can read stuff without the need to move the review- or system cursor. +### Braille pan right + +If a line is longer than your Braille devices you can move the view (called panning) to the right. +So you can read stuff without the need to move the review- or system cursor. +### braille return to cursor + +When you have finished reading the line on the Braille device using panning, the focus can be returned to the current used cursor by using "return to cursor" command. +## Dictionary + +You can make use of different kinds of built-in dictionary's. +A dictionary has a name and list of keys and values separated by :===: +Example: + [customDict] + Chrys:===:Chrys is cool + lollipop:===:lolli +that means that every instance "chrys" is displayed, speech will say Chrys is cool. +"lollipop" is spoken as "lolli". +Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes. +### Punctuation + +#### Level +The punctuation level dict contains lists with "what punctuation is spoken in what level". +the default one looks like this: + [levelDict] + none:===: + some:===:.-$~+*-/\@ + most:===:.,:-$~+*-/\@!#%^&*()[]}{`<>`; + all:===:!"#$%& \'()*+,-./:;`<=>`?@[\\]^_`{|}~ +the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system) +if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at. +same for most and all, you can add new levels. if you cycle punctuation levels they are recognized. the default punctuation level is set in settings.conf. The default is "some". +#### Punctuation + +The punctuation dictionary "[punctDict]" contains how the punctuation is spoken. +Example: + [punctDict] + _:===:line +speaks an _ as "line". + [punctDict] + _:===:underscore +speaks an _ as underscore. +for question mark an ? is appended to the word that the TTS system can announce the question correctly. +### Custom + +The dict "[customDict]" is just for your own use, it just replace the key with the value without any special functionality. This might be used to fix incorrectly spoken words, make words more common, shorter or just for fun. :) +### Emoticons + +The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful. +A nice feature with this dictionary is that you can toggle the substitution on or off during run time or in settings.conf. This is useful because while doing programming or other serious work you want to hear colons and perryns not smiles. +# Configuration + +You can configure Fenrir in the following places (ordered by priority): + 1. Commandline Parameters ''-o'' see [Set settings coption](#Set settings coption) + 2. /etc/fenrir/settings/settings.conf see [Settigns](#Settings) + 3. ``/config/settings/settings.conf see [Settigns](#Settings) + 4. hard coded defaults +## Commandline Arguments + +### Set settings option +You can specify options that overwrite the setting.conf. +This is done with ''-o `` parameter. +The list of options have the following syntax + fenrir -o "section#setting=value;section#setting=value" + +For example changing the sound driver to gstreamer and disabling Braille + fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False" +or change the debug level to verbose + fenrir -o "general#debugLevel=3" +You can find the available sections and variables here [#Settings](#Settings) +See Syntax [#settings.conf syntax](#settings.conf syntax) +### settings.conf syntax + +the syntax of the [settings.conf](#Settings) is quite simple and similar to a "*.ini" file, there are 4 different elements. + 1. Sections + 2. Settings + 3. Values + 4. Comments + +A comment starts with a # and is ignored by Fenrir. + # this is a comment +To group settings we have sections. +A section can look like this: + [Section] +A setting looks like this: + settingName=Value + +Example: + [sound] + # Turn sound on or off: + enabled=True + # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. + # Sox is default. + driver=genericDriver + +## Settings + +### Sound +The sound is configured in section ''[sound]''. + +Turn sound on or off: + enabled=True +Values: on=''True'', off=''False'' + +Select the driver used to play sounds. +The genericDriver using Sox is the default. + + driver=genericDriver + +Available Drivers: + +* ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic'' + +* ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer'' + +These are the pack of sounds used for sound icons. + theme=default +By default we ship two sound packs. + 1. ''default'' opus encoded, for newer Sox versions + 2. ''default-wav'' wav encoded, just for compatibility +Sound packs are located at /usr/share/sounds/fenrirscreenreader/ + +Sound volume controls how loud the sounds for your selected sound pack are. + volume=1.0 +Values: ''0.0'' is quietest, ''1.0'' is loudest. + +#### Generic Driver + +The generic sound driver uses shell commands for play sound and frequencies. + +''genericPlayFileCommand'' defines the command that is used to play a sound file. + genericPlayFileCommand=`` +''genericFrequencyCommand'' defines the command that is used playing frequencies. + genericFrequencyCommand=`` + +The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'': + +* ''fenrirVolume'' = the current volume setting + +* ''fenrirSoundFile'' = the sound file for an sound icon + +* ''fenrirFrequence'' = the frequency to play + +* ''fenrirDuration'' = the duration of the frequency + +Example genericPlayFileCommand (default) + genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile +Example genericFrequencyCommand (default) + genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence +### Speech + +Speech is configured in section ''[speech]''. +Turn speech on or off: + enabled=True +Values: on=''True'', off=''False'' + +# Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: + +driver=speechdDriver +#driver=espeakDriver + +#driver=genericDriver + +Select the driver used to generate speech output. + + driver=speechdDriver + +Available Drivers: + +* ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available + +* ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd'' + +* ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak'' + +The rate selects how fast Fenrir will speak. + rate=0.65 +Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest. + +Pitch controls the pitch of the voice. + pitch=0.5 +Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. + +A Pitch for capital letters can be set. + capitalPitch=0.9 +Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. + +The Volume controls the loudness of the voice. + volume=1.0 +Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest. + +Some speech drivers like speechdDriver can support various modules. these can be set here. + module=espeak +Values: Text, Consult speech-dispatcher's configuration to see what modules are available. + +Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, +or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. + voice= +Values: Text, see your TTS synths documentation what is available. + +Select the language you want Fenrir to use. + language=english-us +Values: Text, see your TTS synths documentation what is available. + +Read new text as it occurs +autoReadIncoming=True +Values: on=''True'', off=''False'' + +#### Generic Driver + +The generic speech driver uses shell commands for speech synthisus. + +''genericSpeechCommand'' defines the command that is executed for creating speech +The following variables are substituted in ''genericSpeechCommand'': + +* ''FenrirText'' = is the text that should be spoken + +* ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this + +* ''fenrirLanguage'' = the language to speak in + +* ''fenrirVoice'' = is the current voice that should be used + +* ''fenrirVolume'' = is replaced with the current volume + +* ''fenrirPitch'' = is replaced with the current pitch + +* ''fenrirRate'' = is replaced with the current speed (speech rate) + +Example genericSpeechCommand (default): + genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" + +These are the minimum and maximum values of the TTS system used in genericSpeechCommand. They are needed to calculate the abstract range in volume, rate and pitch 0.0 - 1.0. + + FenrirMinVolume=0 + fenrirMaxVolume=200 + fenrirMinPitch=0 + fenrirMaxPitch=99 + fenrirMinRate=80 + fenrirMaxRate=450 + +The current volume, pitch and rate is calculated like this +value = min + [volume,pitch,rate] * (min - max ) +### Braille + +Braille is a WIP and not ready yet. +Braille support can be configured in section ''[braille]''. + +Turn braille on or off: + enabled=False +Values: on=''True'', off=''False'' + +Select the driver used for communication with a braille device. + driver=brlapiDriver +Values: Text, available Driver +Available Drivers: + +* ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty'' + +The Braille layout can be configured here + layout=en +Values: Text, see braille driver for layouts. + +What should the flush timeout relate to + flushMode=word +Values: Text, an flushMode +Existing flushModes: + +* ''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) + +Seconds to flush (see flushMode) + flushTimeout=3 +Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut) +The total flush time calculates in relation to flushMode. + +How should the Braille cursor focus be tracked? + cursorFocusMode=page +Values: Text, an existing cursor focus mode +Available cursor focus modes: + +* ''page'' = if the cursor crosses the border move to next page and start at begin + +* ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth. + + +Define the cell on the Braille device where Fenrir should scroll and keep the cursor + fixCursorOnCell=-1 +Values: Integer + +* ''0'' = first cell on device, + +* ''-1'' = last cell on device + +* ''>0'' = fix cell number + +What cursor should Fenrir show on the Braille device + cursorFollowMode=review +Values: Text, an exsiting cursor following mode. +Existing cursor following mode: + +* ''none'' = no automatic toggle command used + +* ''review'' = priority to review + +* ''last'' = follow last used cursor + +number of cells in panning (horizontal). How many cell should be panned on press the routing key? + panSizeHorizontal=0 +Values: Integer, + +* ''0'' = display size + +* ''>0'' number of cells +### Screen + +The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section. + +The driver to get the information from the screen: + driver=vcsaDriver +Available Drivers: + +* ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa'' +The encoding of the screen + encoding=cp850 +Values:''cp850'' is used for Western languages like USA or Europe. + +The driver updates Fenrir with changes on the screen. + screenUpdateDelay=0.05 +Values: in Seconds + +If you want Fenrir to not be active on any screen for various reasons. Maybe an X server or Wayland is running on that screen. You can make Fenrir ignore it or multiple screens seperated by '','' with: + suspendingScreen= +Values: Depends on driver: + +* VCSA: the number of the TTY. TTY6 is ''6''. +Example ignore TTY1 and TTY2: + suspendingScreen=1,2 + +There is also the ability to let Fenrir auto detect screens that are running an X server. So Screens running an GUI can be ignored. + autodetectSuspendingScreen=True +Values: on=''True'', off=''False'' + +### Keyboard + +The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file. + +Select the driver used for grabbing keybord input and for recieving shortcuts. + driver=evdevDriver +Values: Text, available Driver +Available Drivers: + +* ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev'' + +You can let Fenrir know about what input devices are to be used. + device=ALL +Values: + +* ''ALL'' use all devices with key capabilities. + +* ''NOMICE'' Exclude mices from handling. + +* `` just use the device with the given name. + +Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts. + grabDevices=True +Values: on=''True'', off=''False'' + +The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then. + ignoreShortcuts=False +Values: on=''True'', off=''False'' + +The current keyboard layout used for shortcuts. + keyboardLayout=desktop + Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard'' + +Announce characters while typing. + charEcho=False +Values: on=''True'', off=''False'' + +Announce deleted characters + charDeleteEcho=True +Values: on=''True'', off=''False'' + +Announce word after pressing space + wordEcho=False +Values: on=''True'', off=''False'' + +Interrupt speech on any keypress + interruptOnKeyPress=False +Values: on=''True'', off=''False'' + +You can filter the keys that speech should interrupt + interruptOnKeyPressFilter= +Values: (List) empty = all keys, otherwise interrupt with specified keys + +The timeout that is used for double tap shortcuts + doubleTapTimeout=0.2 +Values: Seconds +### General + +Overall settings can be configured from the section ''[general]''. + +Set the current debug level: + debugLevel=1 +Values: off=0, error=1, warning=2, info=3 + +the current punctuation and dict file in use: + punctuationProfile=default +Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation'' + +The current punctuation level in use: + punctuationLevel=some +Values: Text, See available levels in the used punctuation file. + +Respect pause for punctuations: + respectPunctuationPause=True +Values: on=''True'', off=''False'' + +Add a pause on Line break: + newLinePause=True +Values: on=''True'', off=''False'' + +Specify the path where the clipboard should be exported to. +See [export clipboard to file](#export clipboard to file). +The variable ''$user'' is replaced by the current logged username. + clipboardExportPath=/tmp/fenrirClipboard +Values: Text, Systemfilepath + +The number of available clipboards: + numberOfClipboards=10 +Values: Integer, 1 - 999 + +Replace emoticons like :) or ;) with text insertions: + emoticons=True +Values: on=''True'', off=''False'' + +Define the current Fenrir keys: + fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT +Values, Text list, separated by comma. + +Define the current script keys: + scriptKey=KEY_COMPOSE +Values, Text list, separated by comma. + +The time format to be used for (time command) output: + timeFormat=%H:%M:%P +Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) + +The date format to be used for (date command) output: + dateFormat=%A, %B %d, %Y +Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior) + +Enable or Disable spellcheck whilst typing: + autoSpellCheck=True +Values: on=''True'', off=''False'' + +The use of the dictionary with spellcheck: + spellCheckLanguage=en_US +Values: Text, see aspell dictionary's. + +Folder Path for your scripts "scriptKey" functionality: + scriptPath=/usr/share/fenrirscreenreader/scripts +Values: Text, Existing path on file system. + +Override commands or create new ones without changing the Fenrir defaults: + commandPath=/usr/share/fenrirscreenreader/commands +Values: Text, Existing path on file system. +Subfolders in commandPath are: + +* ''commands'' = to create shortcut commands + +* ''onInput'' = executed while typing + +* ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6) + +* ''onScreenUpdate'' = executed when the screen is captured + +### Focus + +The configuration for basic focus is in the section ''[focus]''. +Follow the text cursor: + cursor=True +Values: on=''True'', off=''False'' + +Follow highlighted text changes (Highlight Tracking): + highlight=False +Values: on=''True'', off=''False'' +### Review + +Configurations for the review mode are in the section ''[review]''. + +If "next word/ char" or "prev word/char" create a linebreak, announce it: + lineBreak=True +Values: on=''True'', off=''False'' + +If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it: + endOfScreen=True +Values: on=''True'', off=''False'' + +Leave the review mode when pressing a key: + leaveReviewOnKeypress=False +Values: on=''True'', off=''False'' + +Leave the review mode when changing the screen (From TTY3 to TTY4): + leaveReviewOnScreenChange=True +Values: on=''True'', off=''False'' +### Promote + +"Promoted Lists" are configured in the section ''[promote]''. +Turn Promoted Lists" on or off: + enabled=True +Values: on=''True'', off=''False'' + +The minimum time interval of inactivity to activate promoting. +By default it promotes after 120 Seconds inactivity: + inactiveTimeoutSec=120 +Values: in Seconds + +Define a list of promoted words comma seperated: + list= +Values: text (comma seperated) +Example to promote the word "nickname" or a bash prompt: + list=nickname,$:,#: + +### Time + +The automated time announcement is configured in the section ''[time]''. +Time announcement is disabled by default. +Turn time announcement on or off: + enabled=True +Values: on=''True'', off=''False'' + +Should the time be announced: + presentTime=True +Values: on=''True'', off=''False'' + +Should the date be announced (just on date change): + presentDate=True +Values: on=''True'', off=''False'' + +Announce after a given period of seconds: + delaySec=0 +Value: in Seconds, 0 = Deactivated + +Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored: + onMinutes=00,30 +Example every 15 minutes: + onMinutes=00,15,30,45 + +Just play a soundicon, (not interrupting): + announce=True +Values: on=''True'', off=''False'' + +Interrupt current speech for time announcement: + interrupt=False +Values: on=''True'', off=''False'' +# Customization + +## Scripting +Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrirscreenreader/scripts/ (the path is configurable in settings.conf). +The script key is the applications key. Usually this key can be found on the keyboard located just left of the right most control key. +When you name a script, the key name appears in the script seperated by the sequence __-__. So, for example, if you have a python weather script you want assigned to the script key plus the letter w you would name the script /usr/share/fenrirscreenreader/scripts/weather__-__key_w.py +Then, to access the script, simply press the script key and the letter w. +Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory. +The script gets some parameters from fenrir when it is executed. So that information is available in your script then. + +### Parameterlist + + | Parameter | Content | + | --------- | ------- | + | $1 | Username of the current logged in user | + +### Examples + +Script that just speaks the current username when pressing ScriptKey + H.\\ +File: ''/usr/share/fenrirscreenreader/scripts/helloWorld__-__key_h.sh'': + #!/bin/bash + echo $1 + + +## Commands + +You can place your own commands in "/usr/share/fenrirscreenreader/commands" (path is configurable in settings.conf). +Commands are python files with a special scheme. You can assign them to a shortcut using the filename without an extension or place them in a hook trigger like OnInput or OnScreenChange. For further information see developer guide. +Good Examples: ["date.py"](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py) (announce the Date), ["shut_up.py"](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py) (interrupt output) +the basic scheme for a command is as follows: + + from core import debug + + class command(): + def __init__(self): + pass + def initialize(self, environment): + self.env = environment + def shutdown(self): + pass + def getDescription(self): + return _('No description found') + def run(self): + pass + def setCallback(self, callback): + pass + + +* [Template lives here](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py) + +* The class needs to have the name "command". + +* "initialize" is running once whilst loading the command. + +* "shutdown" is running on unload like the command (quit fenrir) + +* "getDescriptsion" just returns an string. That String is used in Tutorial Mode. + +* "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running) + +* setCAllback is currently not used. and has no functionality yet. + + +# Troubleshooting + +## Fenrir does not start + 1. Have you installed all the dependencies [Support and Requirements](#Support and Requirements) + 2. Try using master, a lot of changes take place there to make Fenrir compatible with more systems +## Fenrir does not utilize the shortcuts + + 1. Make sure you have python3-evdev installed + 2. Use the latest Fenrir version + 3. Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root) +## No sound at all + + 1. Run the script to configure Pulseaudio once as root and once as your user. This will setup Pulseaudio but require a restart of Pulseaudio. The script is located in ''tools/configure_pulse.sh'' + 2. Use ALSA + 3. [Configure Pulse system wide](https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/) (Not recommended) + 4. Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver'' + 5. Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav'' + 6. Use most current version of [sox](http://sox.sourceforge.net/) with opus support + 7. Try [apulse](https///github.com/i-rinat/apulse) (not tested by myself but might work). Please give me feedback if you try it out. +## You get sound-icons but no speech + + 1. If you are using speech-dispatcher run "spd-conf" once as user and as root. + 2. You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"'' +## Bugreports and feature requests + +Please report Bugs and feature requests to: +[https://github.com/chrys87/fenrir/issues](https///github.com/chrys87/fenrir/issues) + +for bugs please provide a [debug](#Howto create a debug file) file that shows the issue. +### How-to create a debug file + + 1. Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log'' + 2. Start fenrir in debug mode\\ ''sudo fenrir -d'' + 3. Do your stuff to reproduce the problem + 4. Stop fenrir (''fenrirKey + q'') +the debug file is located in ''/var/log/fenrir.log'' + +Please be as precise as possible to make it easy to solve the problem. + diff --git a/docu/user.txt b/docu/user.txt new file mode 100644 index 00000000..ce8e7780 --- /dev/null +++ b/docu/user.txt @@ -0,0 +1,1332 @@ +====== Fenrir User Manual ====== + +Fenrir is a modern command line screen reader written in Python3. + +It has a modular structure, a flexible based driver model, is highly configurable and easy to customize and extend ([[fenrir_development_manual|see Developer Manual]]). + +Please see the following pages for the [[fenrir_current_version|current]] and [[fenrir_git_version|Git]] version of Fenrir. + + +====== Support and Requirements ====== + +Fenrir requires several drivers to interact with the operating system. + +===== Speech Drivers ===== + +A speech driver is for communication with the text to speech system like [[#SpeechDispatcher|Speech-Dispatcher]] or [[http://espeak.sourceforge.net|Espeak]]. \\ +See section [[#Speech|Speech]] in ''settings.conf'' for more information. + + +==== SpeechDispatcher ==== + +This driver is used by default. +It uses Speech-dispatcher as its backend. + +Dependencies: + + * Speech-dispatcher (installed and configured, [[https://devel.freebsoft.org/speechd#sec2|Documentation]]) + * Python-speechd + +==== Espeak ==== + +Uses Espeak via Python bindings. + +Dependencies: + * Espeak or Espeak-ng + * [[https://launchpad.net/python-espeak|python-espeak]] + +==== Generic ==== + +This invokes speech via a sub-process. This is almost the same as using the commandline. The performance depends on the overhead of the speech synthesis application but it is really flexible. + +Dependencies: + * Espeak or Espeak-ng + +The Requirements are flexible, they depend on the configuration in settings.conf. + +==== Dummy ==== + +this is just for debugging, logs are output to the screen and logged as well. + +===== Sound Drivers ===== + +To play sound icons and similar.\\ +See section [[#Sound|Sound]] in ''settings.conf'' for more information. + +==== Generic ==== + +This driver is used by default. + +Dependencies: + + * [[http://sox.sourceforge.net/|Sox]] with opus support +The Requirements are flexible, they depend on the configuration in settings.conf. + +==== Gstreamer ==== + +if you prefer to use Gstreamer for sound output. + +Dependencies: + * Gstreamer >= 1.x + * Glibc + +==== Dummy ==== + +this is just for debugging, logs are output to the screen and logged as well. + +===== Input Drivers ===== + +Input drivers are to capture keyboard shortcuts issued to the screen reader \ +See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information. + +==== Evdev ==== + +This driver is used by default. + +Evdev is the low level input device framework for Linux. + +Dependencies: + + * python-evdev >=0.6.3 + * pyudev + * loaded uinput kernel module + * exclusive access to the input devices +Read permission to the following files and services: + * /dev/input + * /dev/uinput + +===== Screen Drivers ===== + +The job of a screen driver is to get the information of current screen content.\\ +See section [[#Screen|Screen]] in ''settings.conf'' for more information. + +==== VCSA ==== + +This driver is used by default. +For Linux VCSA devices. These exist on any current standard installation of Linux. + +Dependencie +s: + + * python-dbus +Read permission to the following files and services (or run as root): + * /sys/devices/virtual/tty/tty0/active + * /dev/tty[1 - 64] + * /dev/vcsa[1 - 64] ([[https://linux.die.net/man/4/vcsa|VCSA manpage]]) + * read Logind DBUS + +===== Braille Drivers ===== +This is for Braille support. +Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\ +See section [[#Braille|Braille]] in ''settings.conf'' for more information. + + +==== BRLTTY ==== + +This driver is used by default. +It uses [[brltty|BrlTTY]] to communicate with with a Braille device. + +Dependencies: + + * BrlTTY (configured and running, [[http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html|Documentation]]) + * python-brlapi (configured, [[http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html|Documentation]]) +===== Currently supported platforms ===== + +Currently Fenrir completely supports the following Platforms: + * Linux TTY +Support for further Systems are planned. + +====== Installation ====== + +Fenrir can run without installation. It just requires the dependencies are installed first. + +We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment. + +===== Try Out ===== +Fenrir does not require installation. You can try it and make sure everything works before you decide to install. In this way you can be sure that your system doesnt break or stop talking. +for that you can just grab the code and run as root ''src/fenrir/fenrir'' (in foreground) or ''src/fenrir/fenrir-daemon'' (in background, used by systemd for autostart) + +===== Install it ===== + +==== Documented operating systems ==== + +==== Arch Linux ==== + +For Arch there are PKGBUILDs in the AUR: + * [[https://aur.archlinux.org/packages/fenrir/|fenrir]] + * [[https://aur.archlinux.org/packages/fenrir-git/|fenrir-git]] + +==== Manual ==== + + - Download the latest stable version from the [[https://linux-a11y.org/index.php?page=fenrir-screenreader|Fenrir-Project]] site. + - Unpack the archive + - Check the needed Dependencys by running [[https://github.com/chrys87/fenrir/blob/master/check-dependencies.py|check-dependencys.py]] script + - install the missing dependencies an standard installation requires the following: + * python3 >= 3.3 (and all the following is needed for python3 ) + * python3-speechd (screen) + * python3-dbus (screen) + * python3-evdev >= 0.6.4(input) + * python3-daemonize (background service) + * python3-brlapi (braille) + * python3-pyenchant (spellchecker) + * your language for aspell (aspell-) (spellchecker) + * sox (sound) + * For an individual installation see [[#Support and Requirements|Support and Requirements]] or consult the [[https://github.com/chrys87/fenrir/blob/master/README.md|Readme]]) + - run "install.sh" as root + +this installs Fenrir as the following + * Application:''/opt/fenrir'' + * Settings:''/etc/fenrir'' + * Sound Icons:''/usr/share/fenrirscreenreader/'' + +to remove Fenrir just run uninstall.sh as root + +==== Git ==== + +if you want to get the latest code you can use git to get a development snapshot: + + git clone https://github.com/chrys87/fenrir.git + +===== Auto Start ===== + +To start Fenrir once: + systemctl start fenrir + +To enable auto start on system boot: + systemctl enable fenrir + +====== First Steps ====== + +If you are using Fenrir for the first time you may want to take a look at these resources: + * [[#Keybindings|Keybindings]] + * [[#Tutorial Mode|Tutorial Mode]] + +====== Features ====== + +===== Commands ===== + +==== Keybindings ==== + +Normal commands can be invoked in two ways: + - Using a Metakey ([[#Fenrir Key|FenrirKey]]) + - Shortcuts with a single key + +See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information. +=== Fenrir Key === +The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time. +By default the following keys are used: + - Insert + - KeyPad Insert + - Meta (Super, Windows) + +=== Script Key === +To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [[#Scripting|Scripting]] +=== Desktop Layout === +^Shortcut ^Command ^ +|FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]| +|CTRL|[[#shut up|shut up (interrupts speech)]]| +|FenrirKey + KeyPad 9|[[#review bottom|reviews bottom]]| +|FenrirKey + KeyPad 7|[[#review top|reviews top]]| +|KeyPad 8|[[#review current line|reviews current line]]| +|KeyPad 7|[[#review previous line|reviews previous line]]| +|KeyPad 9|[[#review next line|reviews next line]]| +|FenrirKey + KeyPad 4|[[#review line beginning|reviews line beginning]]| +|FenrirKey + KeyPad 6|[[#review line ending|reviews line ending]]| +|FenrirKey + KeyPad 1|[[#review line first character|reviews line first character]]| +|FenrirKey + KeyPad 3|[[#review line last character|reviews line last character]]| +|FenrirKey + Alt + 1|[[#present first line|presents first line]]| +|FenrirKey + Alt + 2|[[#present last line|presents last line]]| +|KeyPad 5|[[#review current word|reviews current word]]| +|KeyPad 4|[[#review previous word|reviews previous word]]| +|KeyPad 6|[[#review next word|reviews next word]]| +|FenrirKey + Shift + KeyPad 5|[[#review current word phonetic|reviews current word phonetic]]| +|FenrirKey + Shift + KeyPad 4|[[#review previous word phonetic|reviews previous word phonetic]]| +|FenrirKey + Shift + KeyPad 6|[[#review next word phonetic|reviews next word phonetic]]| +|KeyPad 2|[[#review current character|reviews current char]]| +|KeyPad 1|[[#review previous character|reviews previous char]]| +|KeyPad 3|[[#review next character|reviews next char]]| +|FenrirKey + Shift + KeyPad 2|[[#review current character phonetic|reviews current character phonetic]]| +|FenrirKey + Shift + KeyPad 1|[[#review previous character phonetic|reviews previous character phonetic]]| +|FenrirKey + Shift + KeyPad 3|[[#review next character phonetic|reviews next character phonetic]]| +|FenrirKey + CTRL + KeyPad 8|[[#review up|reviews up]]| +|FenrirKey + CTRL + KeyPad 2|[[#review down|reviews down]]| +|FenrirKey + KeyPad dot|[[#exit review|exit review]]| +|KeyPad dot|[[#cursor position|cursor position]]| +|FenrirKey + I|[[#indent current line|indent curr line]]| +|FenrirKey + KeyPad 5|[[#current screen|current screen]]| +|FenrirKey + KeyPad 8|[[#current screen before cursor|current screen before cursor]]| +|FenrirKey + KeyPad 2|[[#current screen after cursor|current screen after cursor]]| +||[[#cursor read to end of line|cursor read to end of line]]| +||[[#cursor column|cursor column]]| +||[[#cursor line number|cursor line number]]| +||[[#braille flush|Braille flush]]| +||[[#braille pan left|Braille pan left]]| +||[[#braille pan right|Braille pan right]]| +||[[#braille return to cursor|Braille return to cursor]]| +|FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]| +|FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]| +|FenrirKey + 1|[[#read Bookmark X|bookmark 1]]| +|FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]| +|FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]| +|FenrirKey + 2|[[#read Bookmark X|bookmark 2]]| +|FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]| +|FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]| +|FenrirKey + 3|[[#read Bookmark X|bookmark 3]]| +|FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]| +|FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]| +|FenrirKey + 4|[[#read Bookmark X|bookmark 4]]| +|FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]| +|FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]| +|FenrirKey + 5|[[#read Bookmark X|bookmark 5]]| +|FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]| +|FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]| +|FenrirKey + 6|[[#read Bookmark X|bookmark 6]]| +|FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]| +|FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]| +|FenrirKey + 7|[[#read Bookmark X|bookmark 7]]| +|FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]| +|FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]| +|FenrirKey + 8|[[#read Bookmark X|bookmark 8]]| +|FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]| +|FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]| +|FenrirKey + 9|[[#read Bookmark X|bookmark 9]]| +|FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]| +|FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]| +|FenrirKey + 0|[[#read Bookmark X|bookmark 10]]| +|FenrirKey + KeyPad Slash|[[#Create Window|set window application]]| +|2 * FenrirKey + KeyPad Slash|[[#Remove Window|clear window application]]| +|KeyPad Plus|[[#last incoming|read last incoming]]| +|FenrirKey + F2|[[#toggle braille|toggles braille]]| +|FenrirKey + F3|[[#toggle sound|toggles sound]]| +|FenrirKey + F4|[[#toggle speech|toggles speech]]| +|KeyPad Enter|[[#disable speech temporarily|temporarily disables speech]]| +|FenrirKey + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]| +|FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]| +|FenrirKey + Backslash|[[#toggle output|toggles output]]| +|FenrirKey + CTRL + E|[[#toggle emoticons|toggles emoticons]]| +|FenrirKey + KeyPad Enter|[[#toggle auto read|toggles auto read]]| +|FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]| +|FenrirKey + KeyPad ASTERISK|[[#toggle highlight tracking|toggles highlight tracking]]| +|FenrirKey + Q|[[#quit Fenrir|quits fenrir]]| +|FenrirKey + T|[[#Time|Announce time]]| +|2 * FenrirKey + T|[[#Date|Announce date]]| +|FenrirKey + S|[[#spell check|spell check]]| +|2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]| +|FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]| +|FenrirKey + Backspace|[[#forward keypress|forward keypress]]| +|FenrirKey + Up|[[#increase speech volume|increase speech volume]]| +|FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]| +|FenrirKey + Right|[[#increase speech rate|increase speech rate]]| +|FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]| +|FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]| +|FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]| +|FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]| +|FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]| +|FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]| +|FenrirKey + Home|[[#first clipboard|first clipboard]]| +|FenrirKey + End|[[#last clipboard|last clipboard]]| +|FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]| +|FenrirKey + PageDown|[[#next clipboard|next clipboard]]| +|FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]| +|FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]| +|FenrirKey + V|[[#paste clipboard|paste clipboard contents]]| +|FenrirKey + P|[[#import clipboard from file|import clipboard from file]]| +|FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]| +|FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]| +|FenrirKey + X|[[#Set mark|set mark]]| +|FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]| +^Linux specific ^ +||export clipboard to X| +|FenrirKey + CTRL + Up|include Alsa volume| +|FenrirKey + CTRL + Down|decrease Alsa volume| + +=== Laptop Layout === +^Shortcut ^Command ^ +|FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]| +|CTRL|[[#shut up|shut up (interrupts speech)]]| +|FenrirKey + Shift + O|[[#review bottom|reviews bottom]]| +|FenrirKey + Shift + U|[[#review top|reviews top]]| +|FenrirKey + I|[[#review current line|reviews current line]]| +|FenrirKey + U|[[#review previous line|reviews previous line]]| +|FenrirKey + O|[[#review next line|reviews next line]]| +|FenrirKey + Shift + J|[[#review line beginning|reviews line beginning]]| +|FenrirKey + Shift + L|[[#review line ending|reviews line ending]]| +|FenrirKey + CTRL + J|[[#review line first character|reviews line first character]]| +|FenrirKey + CTRL + L|[[#review line last character|reviews line last character]]| +|FenrirKey + Alt + 1|[[#present first line|presents first line]]| +|FenrirKey + Alt + 2|[[#present last line|presents last line]]| +|FenrirKey + K|[[#review current word|reviews current word]]| +|FenrirKey + J|[[#review previous word|reviews previous word]]| +|FenrirKey + L|[[#review next word|reviews next word]]| +|FenrirKey + CTRL + ALT + K|[[#review current word phonetic|reviews current word phonetic]]| +|FenrirKey + CTRL + ALT + J|[[#review previous word phonetic|reviews previous word phonetic]]| +|FenrirKey + CTRL + ALT + L|[[#review next word phonetic|reviews next word phonetic]]| +|FenrirKey + comma|[[#review current character|reviews current character]]| +|FenrirKey + M|[[#review previous character|reviews previous character]]| +|FenrirKey + dot|[[#review next character|reviews next character]]| +|FenrirKey + CTRL + ALT + comma|[[#review current character phonetic|reviews current character phonetic]]| +|FenrirKey + CTRL + ALT + M|[[#review previous character phonetic|reviews previous character phonetic]]| +|FenrirKey + CTRL + ALT + dot|[[#review next character phonetic|reviews next character phonetic]]| +|FenrirKey + CTRL + I|[[#review up|reviews up]]| +|FenrirKey + CTRL + comma|[[#review down|reviews down]]| +|FenrirKey + Slash|[[#exit review|exit review]]| +|FenrirKey + Shift + dot|[[#cursor position|cursor position]]| +|2 * FenrirKey + I|[[#indent current line|indent curr line]]| +|FenrirKey + Shift + K|[[#current screen|current screen]]| +|FenrirKey + Shift + I|[[#current screen before cursor|current screen before cursor]]| +|FenrirKey + Shift + comma|[[#current screen after cursor|current screen after cursor]]| +||[[#cursor read to end of line|cursor read to end of line]]| +||[[#cursor column|cursor column]]| +||[[#cursor line number|cursor line number]]| +||[[#braille flush|Braille flush]]| +||[[#braille pan left|Braille pan left]]| +||[[#braille pan right|Braille pan right]]| +||[[#braille return to cursor|Braille return to cursor]]| +|FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]| +|FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]| +|FenrirKey + 1|[[#read Bookmark X|bookmark 1]]| +|FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]| +|FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]| +|FenrirKey + 2|[[#read Bookmark X|bookmark 2]]| +|FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]| +|FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]| +|FenrirKey + 3|[[#read Bookmark X|bookmark 3]]| +|FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]| +|FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]| +|FenrirKey + 4|[[#read Bookmark X|bookmark 4]]| +|FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]| +|FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]| +|FenrirKey + 5|[[#read Bookmark X|bookmark 5]]| +|FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]| +|FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]| +|FenrirKey + 6|[[#read Bookmark X|bookmark 6]]| +|FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]| +|FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]| +|FenrirKey + 7|[[#read Bookmark X|bookmark 7]]| +|FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]| +|FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]| +|FenrirKey + 8|[[#read Bookmark X|bookmark 8]]| +|FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]| +|FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]| +|FenrirKey + 9|[[#read Bookmark X|bookmark 9]]| +|FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]| +|FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]| +|FenrirKey + 0|[[#read Bookmark X|bookmark 10]]| +|FenrirKey + CTRL + 8|[[#Create Window|set window application]]| +|2 * FenrirKey + CTRL + 8|[[#Remove Window|clear window application]]| +|FenrirKey + Semicolon|[[#last incoming|read last incoming]]| +|FenrirKey + F2|[[#toggle braille|toggles braille]]| +|FenrirKey + F3|[[#toggle sound|toggles sound]]| +|FenrirKey + F4|[[#toggle speech|toggles speech]]| +|FenrirKey + Enter|[[#disable speech temporarily|temporarily disables speech]]| +|FenrirKey + Shift + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]| +|FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]| +|FenrirKey + Shift + Enter|[[#toggle output|toggles output]]| +|FenrirKey + Shift + E|[[#toggle emoticons|toggles emoticons]]| +|FenrirKey + Enter|[[#toggle auto read|toggles auto read]]| +|FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]| +|FenrirKey + Y|[[#toggle highlight tracking|toggles highlight tracking]]| +|FenrirKey + Q|[[#quit Fenrir|quits fenrir]]| +|FenrirKey + T|[[#Time|Announce time]]| +|2 * FenrirKey + T|[[#Date|Announce date]]| +|FenrirKey + S|[[#spell check|spell check]]| +|2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]| +|FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]| +|FenrirKey + Backspace|[[#forward keypress|forward keypress]]| +|FenrirKey + Up|[[#increase speech volume|increase speech volume]]| +|FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]| +|FenrirKey + Right|[[#increase speech rate|increase speech rate]]| +|FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]| +|FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]| +|FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]| +|FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]| +|FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]| +|FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]| +|FenrirKey + Home|[[#first clipboard|first clipboard]]| +|FenrirKey + End|[[#last clipboard|last clipboard]]| +|FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]| +|FenrirKey + PageDown|[[#next clipboard|next clipboard]]| +|FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]| +|FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]| +|FenrirKey + V|[[#paste clipboard|paste clipboard contents]]| +|FenrirKey + F5|[[#import clipboard from file|import clipboard from file]]| +|FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]| +|FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]| +|FenrirKey + X|[[#Set mark|set mark]]| +|FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]| +^Linux specific ^ +||export clipboard to X| +|FenrirKey + CTRL + Up|increases Alsa volume| +|FenrirKey + CTRL + Down|decreases Alsa volume| +==== General ==== +=== quit Fenrir === +Just stops fenrir. +=== shut up === +Interrupt the current spoken. +==== Review Modes ==== +Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor. + +Using the review feature will open the review mode automatically. + +The review cursor always starts from the text cursor. Attention: after using the review mode, the review cursor will stay open until you use the ''exit review'' shortcut. + +Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor. + +Fenrir sounds a bell sound if the used review command jumps to another line or end of screen. +=== exit review === +You can leave the review mode by pressing the ''exit review'' shortcut. +=== review bottom === +Set the review cursor to first column in the last line. +=== review top === +Set the review cursor to the first column in the first line +=== review current line === +Set the review cursor to the beginn of the the current line and review it. +=== review previous line === +Set the review cursor to the previous line and review it. +=== review next line === +Set the review cursor to the next line and review it. +=== review line beginning === +Set the review cursor to the begin of the current line +=== review line ending === +Set the review cursor to the end of the current line +=== review line first character === +Set the review cursor the first char (that is not space) in the current line and review it. +=== review line last character === +Set the review cursor the last char (that is not space) in the current line and review it. +=== review current word === +Sets the review cursor to the beginning of the current word and review it. +=== review previous word === +Sets the review cursor to the beginning of the previous word and review it. +=== review next word === +Sets the review cursor to the beginning of the next word and review it. +=== review current word phonetic === +Sets the review cursor to the beginning of the current word and spell it phonetic. +=== review previous word phonetic === +Sets the review cursor to the beginning of the previous word and spell it phonetic. +=== review next word phonetic === +Sets the review cursor to the beginning of the next word and spell it phonetic. +=== review current character === +Does not change the review cursor. Just announce the current char. +=== review previous character === +Sets review cursor to the previous column and review it +=== review next character === +Sets review cursor to the next column and review it +=== review current character phonetic === +Does not change the review cursor. Just announce the current char phonetic. +=== review previous character phonetic === +Sets review cursor to the previous column and announce the char phonetic. +=== review next character phonetic === +Sets review cursor to the next column and announce the char phonetic. +=== review up === +Set the review cursor in the same column one line above the current one and review it. +=== review down === +Set the review cursor in the same column one line below the current one and review it. +==== Handling marking ==== +A mark defines a point of origin or end to prepare to copy or paste a block of text. +\\ +Examples where you need marks are: + * copy to clipboard + * set window application + * set bookmark 1 - X +=== Set mark === +How to set a mark: + - navigate with review or textcursor to the position you want to set the mark. Attention: if a review cursor is set, that is the prefered. If you want to use text cursor, be sure that you are not in review mode. + - press shortcut for ''set mark'' +you can set two marks (begin and end). Some commands allow some simpler usecases just using the whole line if only one mark is set. you may want to try this out. +=== Get text between marks === +To get the text that is currently between your marks press shortcut for ''marked text''.\\ +=== Remove Marks === +You can remove all current marks by pressing the shortcut for ''remove marks''. +Changing the screen also removes the marks. +==== Screen Interaction ==== +Fenrir provides several methods to interact with the current screen. +=== forward keypress === +This just forwards the next shortcut to the screen Fenrir shortcut or not. This is useful if the currently pressed shortcut is also in use by Fenrir. +=== Clipboard === +Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard. +== copy marked to clipboard == +To copy something to the clipboard you need to set one or two marks. if you set one mark, the text between the mark and your current cursor is copied to clipboard. Setting two marks just copies the text between the marks into the clipboard. If you copy something it is always placed as the first item on your clipboard. +== clear clipboard == +You can remove all items from the current clipboard by ''clear clipboard'' functionality. +== first clipboard == +This moves quick to the first item of the clipboard. +== last clipboard == +This moves quick to the last item of the clipboard. +== previous clipboard == +Go to previous item in the clipboard. +== next clipboard == +Go to next item on the clipboard. +== read current clipboard == +Read the content of the current item of the clipboard. +== paste clipboard == +Pass whatever item is currently selected by first, last, prev or next clipboard commands. +if no special clipboard is selected the (last copied) is used. +== export clipboard to file == +This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop. +== import clipboard from file == +Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop. +==== Quick Settings ==== +Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file. +=== toggle braille === +Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle sound === +Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle speech === +Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time. +=== disable speech temporarily === +Disables the speech until next key press. it might be useful if you want to listen to music or similar. As soon as a key is pressed it is going to be enabled again. +=== toggle punctuation level === +Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle auto spell check === +Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle emoticons === +Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime. +=== toggle output === +Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle auto read === +Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle auto time === +Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time. +=== toggle highlight tracking === +Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time. +=== increase speech volume === +Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== decrease speech volume === +Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== increase speech rate === +Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== decrease speech rate === +Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== increase speech pitch === +Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== decrease speech pitch === +Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime. +=== increase sound volume === +Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. +=== decrease sound volume === +Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime. +==== Window Mode ==== +Fenrir supports window mode, a window is a partial area of the screen. +=== Create Window === +To create a window you need to do the following: + - set a beginning mark (as the start of the window) + - set an end mark (where the window should end) + - press ''set window application'' shortcut. +Now Fenrir ignores anything outside of the window.\\ +=== Remove Window === +You can remove the window by pressing ''the clear window application'' shortcut. +Now Fenrir will read everything on the screen again. +==== Tracking Modes ==== +Different types of tracking are currently supported +See section [[#Focus|Focus]] in ''settings.conf'' for more information. +=== Cursor Tracking === +This follows the text cursor. This is the typical way an application works. This is used by: + * almost any shell such as (Bash, Zsh, sh) + * vim + * nano + * emacs + * mutt + * tintin++ +=== Highlight Tracking === +In some applications there are no text cursors. In those applications cursor changes are represented by different colors or attributes (underlined or bold). This mode tracks and announces these changes for you. This is used by: + * wifi-menu + * dialog + * alpine +==== Tutorial Mode ==== +Fenrir provides a Tutorial mode. +When you enter tutorial mode, screen reader commands are intercepted and explained instead of executing them. ''Arrow up'' and ''Arrow Down'' let you navigate through a list of all available commands with shortcuts and description. Pressing escape leaves the tutorial mode. + +==== Information ==== +=== Time === +Announces the current Time. +=== Date === +Announces the current Date. +=== Bookmarks === +Bookmarks provide quick access to part of the screen without the need to navigate to the area. +By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut. +This is useful for status lines or other information where the position does not change. +== set Bookmark X == +You need to set the bookmark first. For that you have to set one or two lines for use. + - Set marks (one or two) + - press shortcut for ''set bookmark X''. X represents the number 1 - 10. +== read Bookmark X == +If a bookmark is set you can access the area just by pressing the ''bookmark X'' shortcut. X represents the number 1 - 10. Bookmarks are dynamic. That means the content changes with the screen. +== clear Bookmark X == +to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10. +Afterward the bookmark is no longer available. +=== cursor position === +You can get information about the current cursor and its position by using the "cursor position" functionality. +=== indent current line === +Announce the current indent level of the current line. It represents the number of trailing spaces of the line. +=== current screen === +Reads all the current screen from the beginning to the end. +=== current screen before cursor === +Reads current screen from the beginning of the screen to the current cursor position. +=== current screen after cursor === +Read anything after current cursor position to the end. +=== cursor read to end of line === +Read from the current cursor position to the end of the current line. +=== cursor column === +Read the current X position of a cursor (column of the current line). +=== cursor line number === +Read the current Y position of a cursor (line number). +=== present first line === +Reads just the first line. this is maybe useful for status information. +=== present last line === +Presets the last line. This is maybe useful for status information. +=== last incoming === +Repeat the last automatically incoming text. +===== Input ===== +==== Echo ==== +Fenrir provides different methods of echoing content: + * Word: Will speak each word after you push space + * Character: speak any letter you type on the screen + * Delete Character: speaks the character prior to the cursor when you push backspace +==== Silence on Key press ==== +==== Spellchecker ==== +Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut. +Commands to add or remove the current word to the dictionary are included. +As using the spellchecker is enhanced usage. You will need dictionary aspell-. +See section [[#General|General]] in ''settings.conf'' for more information. +=== spell check === +Invokes the spellcheck on the word that contains the Review or text cursor. +=== add word to spell check === +Adds the word under the Review or Text cursor to the dictionary. +=== removes word from spell check === +Removes the word under the Review or Text cursor from the dictionary. +===== Announcements ===== +==== Emoticons ==== +If you want to replace ":)" emoticons with "smile" in speech you can use this feature. +It can be toggled on or off. +You can define emoticons in a dictionary, please see Emoticon Dictionary. +See section [[#General|General]] in ''settings.conf'' to see how to enable or disable this feature. + +==== Time ==== +Announce the time at periodical increments, To track the time easily. +You can define 2 different ways of time announcements. + - periodic + - on fix minutes + +Example periodic, every 20 minutes "delaySec=20": + + [time] + enabled=True + presentTime=True + presentDate=True + delaySec=20 + onMinutes= + announce=True + interrupt=False + +Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45": + + [time] + enabled=True + presentTime=True + presentDate=True + #delaySec is repected bevore onMinutes so it need to be set to 0 + delaySec=0 + onMinutes=00,15,30,45 + announce=True + interrupt=False +==== Promoted List ==== +Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks. +you can define a list of words which you want to hear a sound icon for after a period of inactivity. +Example if the word "Chrys" appears after 120 Seconds of inactivity: + [promote] + enabled=True + inactiveTimeoutSec=120 + list=Chrys +See section [[#Promote|Promote]] in ''settings.conf'' for more information. +==== Punctuation ==== +Fenrir handles punctuation levels and names for you with several provided dictionaries. + +See levelDict +See punctuationDict +===== Braille ===== +Fenrir provides Braille support in Version >= 2.0. +See section [[#Braille|Braille]] in ''settings.conf'' for more information. +==== braille flush ==== +If a message appears on the Braille device you can flush it to get back to the review- or system cursor +==== Braille pan left ==== +If a line is longer than your Braille devices you can move the view (called panning) to the left. +So you can read stuff without the need to move the review- or system cursor. +==== Braille pan right ==== +If a line is longer than your Braille devices you can move the view (called panning) to the right. +So you can read stuff without the need to move the review- or system cursor. +==== braille return to cursor ==== +When you have finished reading the line on the Braille device using panning, the focus can be returned to the current used cursor by using "return to cursor" command. +===== Dictionary ===== +You can make use of different kinds of built-in dictionary's. +A dictionary has a name and list of keys and values separated by :===: +Example: + [customDict] + Chrys:===:Chrys is cool + lollipop:===:lolli +that means that every instance "chrys" is displayed, speech will say Chrys is cool. +"lollipop" is spoken as "lolli". +Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes. +==== Punctuation ==== +=== Level === +The punctuation level dict contains lists with "what punctuation is spoken in what level". +the default one looks like this: + [levelDict] + none:===: + some:===:.-$~+*-/\@ + most:===:.,:-$~+*-/\@!#%^&*()[]}{<>; + all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~ +the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system) +if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at. +same for most and all, you can add new levels. if you cycle punctuation levels they are recognized. the default punctuation level is set in settings.conf. The default is "some". +=== Punctuation === +The punctuation dictionary "[punctDict]" contains how the punctuation is spoken. +Example: + [punctDict] + _:===:line +speaks an _ as "line". + [punctDict] + _:===:underscore +speaks an _ as underscore. +for question mark an ? is appended to the word that the TTS system can announce the question correctly. +==== Custom ==== +The dict "[customDict]" is just for your own use, it just replace the key with the value without any special functionality. This might be used to fix incorrectly spoken words, make words more common, shorter or just for fun. :) +==== Emoticons ==== +The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful. +A nice feature with this dictionary is that you can toggle the substitution on or off during run time or in settings.conf. This is useful because while doing programming or other serious work you want to hear colons and perryns not smiles. +====== Configuration ====== +You can configure Fenrir in the following places (ordered by priority): + - Commandline Parameters ''-o'' see [[#Set settings coption|Set settings coption]] + - /etc/fenrir/settings/settings.conf see [[#Settings|Settigns]] + - /config/settings/settings.conf see [[#Settings|Settigns]] + - hard coded defaults +===== Commandline Arguments ===== +==== Set settings option ==== +You can specify options that overwrite the setting.conf. +This is done with ''-o '' parameter. +The list of options have the following syntax + fenrir -o "section#setting=value;section#setting=value" + +For example changing the sound driver to gstreamer and disabling Braille + fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False" +or change the debug level to verbose + fenrir -o "general#debugLevel=3" +You can find the available sections and variables here [[#Settings]] +See Syntax [[#settings.conf syntax]] +==== settings.conf syntax ==== +the syntax of the [[#Settings|settings.conf]] is quite simple and similar to a "*.ini" file, there are 4 different elements. + - Sections + - Settings + - Values + - Comments + +A comment starts with a # and is ignored by Fenrir. + # this is a comment +To group settings we have sections. +A section can look like this: + [Section] +A setting looks like this: + settingName=Value + +Example: + [sound] + # Turn sound on or off: + enabled=True + # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver. + # Sox is default. + driver=genericDriver + +===== Settings ===== +==== Sound ==== +The sound is configured in section ''[sound]''. + +Turn sound on or off: + enabled=True +Values: on=''True'', off=''False'' + +Select the driver used to play sounds. +The genericDriver using Sox is the default. + + driver=genericDriver + +Available Drivers: + * ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic'' + * ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer'' + +These are the pack of sounds used for sound icons. + theme=default +By default we ship two sound packs. + - ''default'' opus encoded, for newer Sox versions + - ''default-wav'' wav encoded, just for compatibility +Sound packs are located at /usr/share/sounds/fenrirscreenreader/ + +Sound volume controls how loud the sounds for your selected sound pack are. + volume=1.0 +Values: ''0.0'' is quietest, ''1.0'' is loudest. + +=== Generic Driver === +The generic sound driver uses shell commands for play sound and frequencies. + +''genericPlayFileCommand'' defines the command that is used to play a sound file. + genericPlayFileCommand= +''genericFrequencyCommand'' defines the command that is used playing frequencies. + genericFrequencyCommand= + +The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'': + * ''fenrirVolume'' = the current volume setting + * ''fenrirSoundFile'' = the sound file for an sound icon + * ''fenrirFrequence'' = the frequency to play + * ''fenrirDuration'' = the duration of the frequency + +Example genericPlayFileCommand (default) + genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile +Example genericFrequencyCommand (default) + genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence +==== Speech ==== +Speech is configured in section ''[speech]''. +Turn speech on or off: + enabled=True +Values: on=''True'', off=''False'' + +# Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver: +driver=speechdDriver +#driver=espeakDriver +#driver=genericDriver + +Select the driver used to generate speech output. + + driver=speechdDriver + +Available Drivers: + * ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available + * ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd'' + * ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak'' + +The rate selects how fast Fenrir will speak. + rate=0.65 +Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest. + +Pitch controls the pitch of the voice. + pitch=0.5 +Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. + +A Pitch for capital letters can be set. + capitalPitch=0.9 +Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest. + +The Volume controls the loudness of the voice. + volume=1.0 +Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest. + +Some speech drivers like speechdDriver can support various modules. these can be set here. + module=espeak +Values: Text, Consult speech-dispatcher's configuration to see what modules are available. + +Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak, +or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer. + voice= +Values: Text, see your TTS synths documentation what is available. + +Select the language you want Fenrir to use. + language=english-us +Values: Text, see your TTS synths documentation what is available. + +Read new text as it occurs +autoReadIncoming=True +Values: on=''True'', off=''False'' + +=== Generic Driver === +The generic speech driver uses shell commands for speech synthisus. + +''genericSpeechCommand'' defines the command that is executed for creating speech +The following variables are substituted in ''genericSpeechCommand'': + * ''FenrirText'' = is the text that should be spoken + * ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this + * ''fenrirLanguage'' = the language to speak in + * ''fenrirVoice'' = is the current voice that should be used + * ''fenrirVolume'' = is replaced with the current volume + * ''fenrirPitch'' = is replaced with the current pitch + * ''fenrirRate'' = is replaced with the current speed (speech rate) + +Example genericSpeechCommand (default): + genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText" + +These are the minimum and maximum values of the TTS system used in genericSpeechCommand. They are needed to calculate the abstract range in volume, rate and pitch 0.0 - 1.0. + + FenrirMinVolume=0 + fenrirMaxVolume=200 + fenrirMinPitch=0 + fenrirMaxPitch=99 + fenrirMinRate=80 + fenrirMaxRate=450 + +The current volume, pitch and rate is calculated like this +value = min + [volume,pitch,rate] * (min - max ) +==== Braille ==== +Braille is a WIP and not ready yet. +Braille support can be configured in section ''[braille]''. + +Turn braille on or off: + enabled=False +Values: on=''True'', off=''False'' + +Select the driver used for communication with a braille device. + driver=brlapiDriver +Values: Text, available Driver +Available Drivers: + * ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty'' + +The Braille layout can be configured here + layout=en +Values: Text, see braille driver for layouts. + +What should the flush timeout relate to + flushMode=word +Values: Text, an flushMode +Existing flushModes: + * ''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) + +Seconds to flush (see flushMode) + flushTimeout=3 +Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut) +The total flush time calculates in relation to flushMode. + +How should the Braille cursor focus be tracked? + cursorFocusMode=page +Values: Text, an existing cursor focus mode +Available cursor focus modes: + * ''page'' = if the cursor crosses the border move to next page and start at begin + * ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth. + + +Define the cell on the Braille device where Fenrir should scroll and keep the cursor + fixCursorOnCell=-1 +Values: Integer + * ''0'' = first cell on device, + * ''-1'' = last cell on device + * ''>0'' = fix cell number + +What cursor should Fenrir show on the Braille device + cursorFollowMode=review +Values: Text, an exsiting cursor following mode. +Existing cursor following mode: + * ''none'' = no automatic toggle command used + * ''review'' = priority to review + * ''last'' = follow last used cursor + +number of cells in panning (horizontal). How many cell should be panned on press the routing key? + panSizeHorizontal=0 +Values: Integer, + * ''0'' = display size + * ''>0'' number of cells +==== Screen ==== +The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section. + +The driver to get the information from the screen: + driver=vcsaDriver +Available Drivers: + * ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa'' +The encoding of the screen + encoding=cp850 +Values:''cp850'' is used for Western languages like USA or Europe. + +The driver updates Fenrir with changes on the screen. + screenUpdateDelay=0.05 +Values: in Seconds + +If you want Fenrir to not be active on any screen for various reasons. Maybe an X server or Wayland is running on that screen. You can make Fenrir ignore it or multiple screens seperated by '','' with: + suspendingScreen= +Values: Depends on driver: + * VCSA: the number of the TTY. TTY6 is ''6''. +Example ignore TTY1 and TTY2: + suspendingScreen=1,2 + +There is also the ability to let Fenrir auto detect screens that are running an X server. So Screens running an GUI can be ignored. + autodetectSuspendingScreen=True +Values: on=''True'', off=''False'' + +==== Keyboard ==== +The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file. + +Select the driver used for grabbing keybord input and for recieving shortcuts. + driver=evdevDriver +Values: Text, available Driver +Available Drivers: + * ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev'' + +You can let Fenrir know about what input devices are to be used. + device=ALL +Values: + * ''ALL'' use all devices with key capabilities. + * ''NOMICE'' Exclude mices from handling. + * '''' just use the device with the given name. + +Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts. + grabDevices=True +Values: on=''True'', off=''False'' + +The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then. + ignoreShortcuts=False +Values: on=''True'', off=''False'' + +The current keyboard layout used for shortcuts. + keyboardLayout=desktop + Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard'' + +Announce characters while typing. + charEcho=False +Values: on=''True'', off=''False'' + +Announce deleted characters + charDeleteEcho=True +Values: on=''True'', off=''False'' + +Announce word after pressing space + wordEcho=False +Values: on=''True'', off=''False'' + +Interrupt speech on any keypress + interruptOnKeyPress=False +Values: on=''True'', off=''False'' + +You can filter the keys that speech should interrupt + interruptOnKeyPressFilter= +Values: (List) empty = all keys, otherwise interrupt with specified keys + +The timeout that is used for double tap shortcuts + doubleTapTimeout=0.2 +Values: Seconds +==== General ==== +Overall settings can be configured from the section ''[general]''. + +Set the current debug level: + debugLevel=1 +Values: off=0, error=1, warning=2, info=3 + +the current punctuation and dict file in use: + punctuationProfile=default +Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation'' + +The current punctuation level in use: + punctuationLevel=some +Values: Text, See available levels in the used punctuation file. + +Respect pause for punctuations: + respectPunctuationPause=True +Values: on=''True'', off=''False'' + +Add a pause on Line break: + newLinePause=True +Values: on=''True'', off=''False'' + +Specify the path where the clipboard should be exported to. +See [[#export clipboard to file|export clipboard to file]]. +The variable ''$user'' is replaced by the current logged username. + clipboardExportPath=/tmp/fenrirClipboard +Values: Text, Systemfilepath + +The number of available clipboards: + numberOfClipboards=10 +Values: Integer, 1 - 999 + +Replace emoticons like :) or ;) with text insertions: + emoticons=True +Values: on=''True'', off=''False'' + +Define the current Fenrir keys: + fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT +Values, Text list, separated by comma. + +Define the current script keys: + scriptKey=KEY_COMPOSE +Values, Text list, separated by comma. + +The time format to be used for (time command) output: + timeFormat=%H:%M:%P +Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]] + +The date format to be used for (date command) output: + dateFormat=%A, %B %d, %Y +Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]] + +Enable or Disable spellcheck whilst typing: + autoSpellCheck=True +Values: on=''True'', off=''False'' + +The use of the dictionary with spellcheck: + spellCheckLanguage=en_US +Values: Text, see aspell dictionary's. + +Folder Path for your scripts "scriptKey" functionality: + scriptPath=/usr/share/fenrirscreenreader/scripts +Values: Text, Existing path on file system. + +Override commands or create new ones without changing the Fenrir defaults: + commandPath=/usr/share/fenrirscreenreader/commands +Values: Text, Existing path on file system. +Subfolders in commandPath are: + * ''commands'' = to create shortcut commands + * ''onInput'' = executed while typing + * ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6) + * ''onScreenUpdate'' = executed when the screen is captured + +==== Focus ==== +The configuration for basic focus is in the section ''[focus]''. +Follow the text cursor: + cursor=True +Values: on=''True'', off=''False'' + +Follow highlighted text changes (Highlight Tracking): + highlight=False +Values: on=''True'', off=''False'' +==== Review ==== +Configurations for the review mode are in the section ''[review]''. + +If "next word/ char" or "prev word/char" create a linebreak, announce it: + lineBreak=True +Values: on=''True'', off=''False'' + +If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it: + endOfScreen=True +Values: on=''True'', off=''False'' + +Leave the review mode when pressing a key: + leaveReviewOnKeypress=False +Values: on=''True'', off=''False'' + +Leave the review mode when changing the screen (From TTY3 to TTY4): + leaveReviewOnScreenChange=True +Values: on=''True'', off=''False'' +==== Promote ==== +"Promoted Lists" are configured in the section ''[promote]''. +Turn Promoted Lists" on or off: + enabled=True +Values: on=''True'', off=''False'' + +The minimum time interval of inactivity to activate promoting. +By default it promotes after 120 Seconds inactivity: + inactiveTimeoutSec=120 +Values: in Seconds + +Define a list of promoted words comma seperated: + list= +Values: text (comma seperated) +Example to promote the word "nickname" or a bash prompt: + list=nickname,$:,#: + +==== Time ==== +The automated time announcement is configured in the section ''[time]''. +Time announcement is disabled by default. +Turn time announcement on or off: + enabled=True +Values: on=''True'', off=''False'' + +Should the time be announced: + presentTime=True +Values: on=''True'', off=''False'' + +Should the date be announced (just on date change): + presentDate=True +Values: on=''True'', off=''False'' + +Announce after a given period of seconds: + delaySec=0 +Value: in Seconds, 0 = Deactivated + +Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored: + onMinutes=00,30 +Example every 15 minutes: + onMinutes=00,15,30,45 + +Just play a soundicon, (not interrupting): + announce=True +Values: on=''True'', off=''False'' + +Interrupt current speech for time announcement: + interrupt=False +Values: on=''True'', off=''False'' +====== Customization ====== +===== Scripting ===== +Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrirscreenreader/scripts/ (the path is configurable in settings.conf). +The script key is the applications key. Usually this key can be found on the keyboard located just left of the right most control key. +When you name a script, the key name appears in the script seperated by the sequence __-__. So, for example, if you have a python weather script you want assigned to the script key plus the letter w you would name the script /usr/share/fenrirscreenreader/scripts/weather__-__key_w.py +Then, to access the script, simply press the script key and the letter w. +Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory. +The script gets some parameters from fenrir when it is executed. So that information is available in your script then. + +==== Parameterlist ==== +^Parameter ^Content ^ +|$1|Username of the current logged in user| + +==== Examples ==== +Script that just speaks the current username when pressing ScriptKey + H.\\ +File: ''/usr/share/fenrirscreenreader/scripts/helloWorld__-__key_h.sh'': + #!/bin/bash + echo $1 + + +===== Commands ===== +You can place your own commands in "/usr/share/fenrirscreenreader/commands" (path is configurable in settings.conf). +Commands are python files with a special scheme. You can assign them to a shortcut using the filename without an extension or place them in a hook trigger like OnInput or OnScreenChange. For further information see developer guide. +Good Examples: [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py|"date.py"]] (announce the Date), [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py|"shut_up.py"]] (interrupt output) +the basic scheme for a command is as follows: + + from core import debug + + class command(): + def __init__(self): + pass + def initialize(self, environment): + self.env = environment + def shutdown(self): + pass + def getDescription(self): + return _('No description found') + def run(self): + pass + def setCallback(self, callback): + pass + + * [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py|Template lives here]] + * The class needs to have the name "command". + * "initialize" is running once whilst loading the command. + * "shutdown" is running on unload like the command (quit fenrir) + * "getDescriptsion" just returns an string. That String is used in Tutorial Mode. + * "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running) + * setCAllback is currently not used. and has no functionality yet. + + +====== Troubleshooting ====== +===== Fenrir does not start ===== + - Have you installed all the dependencies [[#Support and Requirements|Support and Requirements]] + - Try using master, a lot of changes take place there to make Fenrir compatible with more systems +===== Fenrir does not utilize the shortcuts ===== + - Make sure you have python3-evdev installed + - Use the latest Fenrir version + - Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root) +===== No sound at all ===== + - Run the script to configure Pulseaudio once as root and once as your user. This will setup Pulseaudio but require a restart of Pulseaudio. The script is located in ''tools/configure_pulse.sh'' + - Use ALSA + - [[https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/|Configure Pulse system wide]] (Not recommended) + - Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver'' + - Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav'' + - Use most current version of [[http://sox.sourceforge.net/|sox]] with opus support + - Try [[https://github.com/i-rinat/apulse|apulse]] (not tested by myself but might work). Please give me feedback if you try it out. +===== You get sound-icons but no speech ===== + - If you are using speech-dispatcher run "spd-conf" once as user and as root. + - You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"'' +===== Bugreports and feature requests ===== +Please report Bugs and feature requests to: +[[https://github.com/chrys87/fenrir/issues|https://github.com/chrys87/fenrir/issues]] + +for bugs please provide a [[#Howto create a debug file|debug]] file that shows the issue. +==== How-to create a debug file ==== + - Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log'' + - Start fenrir in debug mode\\ ''sudo fenrir -d'' + - Do your stuff to reproduce the problem + - Stop fenrir (''fenrirKey + q'') +the debug file is located in ''/var/log/fenrir.log'' + +Please be as precise as possible to make it easy to solve the problem. diff --git a/play zone/argp.py b/play zone/argp.py new file mode 100755 index 00000000..f97130d1 --- /dev/null +++ b/play zone/argp.py @@ -0,0 +1,12 @@ +#!/bin/python3 +import argparse + +parser = argparse.ArgumentParser(description="Fenrir Help") + +parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile') +parser.add_argument('-o', '--options', metavar='SECTION:SETTING=VALUE,..', default='', help='Overwrite options in given settings file') + +args = parser.parse_args() +parser.print_help() + +print(args.setting) diff --git a/play zone/charmapTTY.py b/play zone/charmapTTY.py new file mode 100755 index 00000000..981331f7 --- /dev/null +++ b/play zone/charmapTTY.py @@ -0,0 +1,88 @@ +import time +from fcntl import ioctl +from array import array +from struct import unpack_from +from struct import unpack +from struct import pack +import errno +import sys +charmap = {} +hichar = None +def updateCharMap(screen): + global hichar + ttyno = '4' + tty = open('/dev/tty' + screen, 'rb') + GIO_UNIMAP = 0x4B66 + VT_GETHIFONTMASK = 0x560D + himask = array("H", (0,)) + ioctl(tty, VT_GETHIFONTMASK, himask) + hichar, = unpack_from("@H", himask) + sz = 512 + line = '' + while True: + try: + unipairs = array("H", [0]*(2*sz)) + unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0])) + ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) + break + except IOError as e: + if e.errno != errno.ENOMEM: + raise + sz *= 2 + tty.close() + ncodes, = unpack_from("@H", unimapdesc) + utable = unpack_from("@%dH" % (2*ncodes), unipairs) + for u, b in zip(utable[::2], utable[1::2]): + if charmap.get(b) is None: + charmap[b] = chr(u) + + +def autoDecodeVCSA(allData, rows, cols): + allText = [] + allAttrib = [] + for y in range(rows): + lineText = '' + lineAttrib = [] + i = 0 + for x in range(cols): + data = allData[i: i + 2] + i += 2 + if data == b' \x07': + #attr = 7 + #ink = 7 + #paper = 0 + #ch = ' ' + lineAttrib.append(7) + lineText += ' ' + continue + (sh,) = unpack("=H", data) + attr = (sh >> 8) & 0xFF + ch = sh & 0xFF + if hichar == 0x100: + attr >>= 1 + lineAttrib.append(attr) + ink = attr & 0x0F + paper = (attr>>4) & 0x0F + #if (ink != 7) or (paper != 0): + # print(ink,paper) + if sh & hichar: + ch |= 0x100 + try: + lineText += charmap[ch] + except: + lineText += chr('?') + allText.append(lineText) + allAttrib.append(lineAttrib) + return allText, allAttrib + +def m(screen): + s = time.time() + updateCharMap(str(screen)) + print(time.time() -s ) + vcsa = open('/dev/vcsa' + str(screen), 'rb') + head = vcsa.read(4) + rows = int(head[0]) + cols = int(head[1]) + text, attrib = autoDecodeVCSA(vcsa.read(), rows, cols) + print(time.time() -s ) + diff --git a/play zone/colors.sh b/play zone/colors.sh new file mode 100644 index 00000000..7459faf3 --- /dev/null +++ b/play zone/colors.sh @@ -0,0 +1,39 @@ +#!/bin/bash +echo "foreground colors" +echo -e "\e[39mDefault" +echo -e "\e[30mBlack" +echo -e "\e[31mRed" +echo -e "\e[32mGreen" +echo -e "\e[33mYellow" +echo -e "\e[34mBlue" +echo -e "\e[35mMagenta" +echo -e "\e[36mCyan" +echo -e "\e[37mLight gray" +echo -e "\e[90mDark gray" +echo -e "\e[91mLight red" +echo -e "\e[92mLight green" +echo -e "\e[93mLight yellow" +echo -e "\e[94mLight blue" +echo -e "\e[95mLight magenta" +echo -e "\e[96mLight cyan" +echo -e "\e[97mWhite" + +echo "background colors" +echo -e "\e[49mDefault" +echo -e "\e[40mBlack" +echo -e "\e[41mRed" +echo -e "\e[42mGreen" +echo -e "\e[43mYellow" +echo -e "\e[44mBlue" +echo -e "\e[45mMagenta" +echo -e "\e[46mCyan" +echo -e "\e[47mLight gray" +echo -e "\e[100mDark gray" +echo -e "\e[101mLight red" +echo -e "\e[102mLight green" +echo -e "\e[103mLight yellow" +echo -e "\e[104mLight blue" +echo -e "\e[105mLight magenta" +echo -e "\e[106mLight cyan" +echo -e "\e[107mWhite" + diff --git a/play zone/consumeEvents.py b/play zone/consumeEvents.py new file mode 100755 index 00000000..c2e110bf --- /dev/null +++ b/play zone/consumeEvents.py @@ -0,0 +1,52 @@ +#!/bin/python +import evdev +from evdev import InputDevice, UInput +from select import select +import time + +iDevices = map(evdev.InputDevice, (evdev.list_devices())) +iDevices = {dev.fd: dev for dev in iDevices if evdev.events.EV_KEY in dev.capabilities()} + +uDevices = {} +for fd in iDevices: + dev = iDevices[fd] + cap = dev.capabilities() + del cap[0] + uDevices[fd] = UInput( + cap, + dev.name, + dev.info.vendor, +# dev.info.product, +# dev.version, +# dev.info.bustype, + # '/dev/uinput' + ) + dev.grab() + + +i = 0 +while i < 100: + r, w, x = select(iDevices, [], []) + if r != []: + i += 1 + for fd in r: + for event in iDevices[fd].read(): + if event.code != 30: # a + print(event) + uDevices[fd].write_event(event) + uDevices[fd].syn() + #print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value)) + else: + print('this key is consumed') + +for fd in iDevices: + iDevices[fd].ungrab() + iDevices[fd].close() + uDevices[fd].close() + + +iDevices.clear() +uDevices.clear() + + + diff --git a/play zone/daemon.py b/play zone/daemon.py new file mode 100755 index 00000000..52a58e3d --- /dev/null +++ b/play zone/daemon.py @@ -0,0 +1,12 @@ +from time import sleep +from daemonize import Daemonize + +pid = "/tmp/test.pid" + + +def main(): + while True: + sleep(5) + +daemon = Daemonize(app="test_app", pid=pid, action=main) +daemon.start() diff --git a/play zone/detectDevices.py b/play zone/detectDevices.py new file mode 100755 index 00000000..c4ca8ec5 --- /dev/null +++ b/play zone/detectDevices.py @@ -0,0 +1,48 @@ +#!/bin/python +iDevices = {} +iDeviceNo = 0 +def updateInputDevices(force = False, init = False): + global iDeviceNo + if init: + iDevices = {} + iDeviceNo = 0 + deviceFileList = evdev.list_devices() + if not force: + if len(deviceFileList) == iDeviceNo: + return + iDeviceNo = len(deviceFileList) + mode = 'ALL' + iDevicesFiles = [] + for device in iDevices: + iDevicesFiles.append(iDevices[device].fn) + print(len(iDevicesFiles),len(deviceFileList)) + if len(iDevicesFiles) == len(deviceFileList): + return + for deviceFile in deviceFileList: + try: + if deviceFile in iDevicesFiles: + print('skip') + continue + open(deviceFile) + # 3 pos absolute + # 2 pos relative + # 1 Keys + currDevice = evdev.InputDevice(deviceFile) + cap = currDevice.capabilities() + if mode in ['ALL','NOMICE']: + if 1 in cap: + if 116 in cap[1] and len(cap[1]) < 5: + print('power') + continue + if mode == 'ALL': + iDevices[currDevice.fd] = currDevice + print('Device added:' + iDevices[currDevice.fd].name) + elif mode == 'NOMICE': + if not ((2 in cap) or (3 in cap)): + iDevices[currDevice.fd] = currDevice + print('Device added:' + iDevices[currDevice.fd].name) + elif currDevice.name.upper() in mode.split(','): + iDevices[currDevice.fd] = currDevice + print('Device added:' + iDevices[currDevice.fd].name) + except Exception as e: + print("Skip Inputdevice : " + deviceFile +' ' + str(e)) diff --git a/play zone/epollScreen.py b/play zone/epollScreen.py new file mode 100644 index 00000000..cf406113 --- /dev/null +++ b/play zone/epollScreen.py @@ -0,0 +1,37 @@ +#!/bin/python + +import select +import time + +currScreen = '2' +vcsa = {} +for i in range(1,7): + vcsa[str(i)] = open('/dev/vcs'+str(i),'rb') + +tty = open('/sys/devices/virtual/tty/tty0/active','r') +currScreen = str(tty.read()[3:-1]) +oldScreen = currScreen +watchdog = select.epoll() +watchdog.register(vcsa[currScreen], select.EPOLLPRI) +watchdog.register(tty, select.EPOLLPRI) + +while True: + changes = watchdog.poll() + print('-----------------------------') + print(changes) + for change in changes: + fileno = change[0] + event = change[1] + print(change,fileno, tty.fileno()) + if fileno == tty.fileno(): + tty.seek(0) + currScreen = str(tty.read()[3:-1]) + if currScreen != oldScreen: + watchdog.unregister(vcsa[ oldScreen ]) + watchdog.register(vcsa[ currScreen ], select.EPOLLPRI) + oldScreen = currScreen + print('new screen '+ currScreen) + else: + vcsa[currScreen].seek(0) + content = vcsa[currScreen].read() + print('update '+ str(time.time())) diff --git a/play zone/errorOnBrokenDevice.py b/play zone/errorOnBrokenDevice.py new file mode 100755 index 00000000..05955dbb --- /dev/null +++ b/play zone/errorOnBrokenDevice.py @@ -0,0 +1,5 @@ +#!/bin/python + +# in case that event13 is still the broken device +f = open('/dev/input/event13') +print('OK /dev/input/event13') diff --git a/play zone/fg.sh b/play zone/fg.sh new file mode 100755 index 00000000..ebf15118 --- /dev/null +++ b/play zone/fg.sh @@ -0,0 +1,48 @@ +#!/bin/bash +echo "foreground colors" +echo -e "\e[39mDefault" +echo -e "\e[30mBlack" +echo -e "\e[31mRed" +echo -e "\e[32mGreen" +echo -e "\e[33mYellow" +echo -e "\e[34mBlue" +echo -e "\e[35mMagenta" +echo -e "\e[36mCyan" +echo -e "\e[37mLight gray" +echo -e "\e[90mDark gray" +echo -e "\e[91mLight red" +echo -e "\e[92mLight green" +echo -e "\e[93mLight yellow" +echo -e "\e[94mLight blue" +echo -e "\e[95mLight magenta" +echo -e "\e[96mLight cyan" +echo -e "\e[97mWhite" +#7: _('Default'), 0: _('Black'), 4: _('Red'), 2: _('Green'), 6: _('Yellow'), 1: _('Blue'), 5: _('Magenta'), 3: _('Cyan'), 7: _('Light gray'), 8: _('Dark gray'), 12: _('Light red'), 10: , ('Light green'), 14: _('Light yellow'), 9: _('Light blue'), 13: _('Light magenta'), 11: _('Light cyan'), 15: _('White') + +echo "background colors" +echo -e "\e[49mDefault" +echo -e "\e[40mBlack" +echo -e "\e[41mRed" +echo -e "\e[42mGreen" +echo -e "\e[43mYellow" +echo -e "\e[44mBlue" +echo -e "\e[45mMagenta" +echo -e "\e[46mCyan" +echo -e "\e[47mLight gray" +echo -e "\e[100mDark gray" +echo -e "\e[101mLight red" +echo -e "\e[102mLight green" +echo -e "\e[103mLight yellow" +echo -e "\e[104mLight blue" +echo -e "\e[105mLight magenta" +echo -e "\e[106mLight cyan" +echo -e "\e[107mWhite" + +echo "format" +echo -e "\e[1mBold" +echo -e "\e[2mDim" +echo -e "\e[4mUnderlined" +echo -e "\e[5mBlink" +echo -e "\e[7minverted" +echo -e "\e[8mHidden" + diff --git a/play zone/keypress.py b/play zone/keypress.py new file mode 100755 index 00000000..7729b464 --- /dev/null +++ b/play zone/keypress.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +import gi +from gi.repository import GLib +gi.require_version('Gst', '1.0') +from gi.repository import Gst +import time, threading +gi.require_version('Atspi', '2.0') +import pyatspi + +# Callback to print the active window on key press amd filter out the key release +def on_key_input(event): + print(event) + +mainloop = GLib.MainLoop() +thread = threading.Thread(target=mainloop.run) +thread.start() +#pyatspi.Registry.registerKeystrokeListener(on_key_input, kind=(pyatspi.KEY_PRESSED_EVENT, pyatspi.KEY_RELEASED_EVENT)) +pyatspi.Registry.registerKeystrokeListener(on_key_input,mask=pyatspi.allModifiers(), kind=(pyatspi.KEY_PRESS,pyatspi.KEY_RELEASE,pyatspi.KEY_PRESSRELEASE), synchronous=True, preemptive=True) +pyatspi.Registry.start() diff --git a/play zone/listDevices.py b/play zone/listDevices.py new file mode 100755 index 00000000..1ddd629b --- /dev/null +++ b/play zone/listDevices.py @@ -0,0 +1,23 @@ +#!/bin/python +import evdev +from evdev import InputDevice, UInput +from select import select +import time + +iDevices = map(evdev.InputDevice, (evdev.list_devices())) +iDevices = {dev.fd: dev for dev in iDevices} +print('----------------------') +for fd in iDevices: + dev = iDevices[fd] + cap = dev.capabilities() + print('Name: ' + str(dev.name)) + print('LEDs: ' + str(dev.leds())) + print('Has Keys: '+ str(evdev.events.EV_KEY in cap)) + if evdev.events.EV_KEY in cap: + print('No. of keys: ' + str(len(cap[evdev.events.EV_KEY]))) + print('has Key 116: ' + str(116 in cap[evdev.events.EV_KEY])) + print('Is Mouse: ' + str(((evdev.events.EV_REL in cap) or (evdev.events.EV_ABS in cap)))) + print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!') + print(dev.capabilities(verbose=True)) + print('----------------------') + diff --git a/play zone/listSession.py b/play zone/listSession.py new file mode 100755 index 00000000..7a0d0da3 --- /dev/null +++ b/play zone/listSession.py @@ -0,0 +1,20 @@ +#!/bin/python +import dbus +try: + bus = dbus.SystemBus() + obj = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') + inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager') + ListSessions = inf.get_dbus_method('ListSessions') + sessions = ListSessions() + for session in sessions: + obj = bus.get_object('org.freedesktop.login1', session[4]) + inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties') + sessionType = inf.Get('org.freedesktop.login1.Session', 'Type') + screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr')) + if screen == '': + screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY')) + print('Session:', screen, 'Type:', sessionType.upper(), 'Details:', session) + else: + print('Session:', screen, 'Type:', sessionType.upper(), 'Details:', session) +except: + print('no access') diff --git a/play zone/marytts.py b/play zone/marytts.py new file mode 100755 index 00000000..8cbffbc1 --- /dev/null +++ b/play zone/marytts.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# HTTP + URL packages +import httplib2 +from urllib.parse import urlencode, quote # For URL creation +import time +# To play wave files +import pygame +import math # For ceiling + + +# Mary server informations +mary_host = "127.0.0.1" +mary_port = "59125" + +# Input text +input_text = "das ist ein test das ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testdas ist ein testd" +# Build the query +query_hash = {"INPUT_TEXT":input_text, + "INPUT_TYPE":"TEXT", # Input text + "LOCALE":"de", + "VOICE":"bits3", # Voice informations (need to be compatible) + "OUTPUT_TYPE":"AUDIO", + "AUDIO":"WAVE", # Audio informations (need both) + } +starttime = time.time() +query = urlencode(query_hash) +#print("query = \"http://%s:%s/process?%s\"" % (mary_host, mary_port, query)) + +# Run the query to mary http server +h_mary = httplib2.Http() +#print("http://%s:%s/process?" % (mary_host, mary_port), "POST", query) +resp, content = h_mary.request("http://%s:%s/process?" % (mary_host, mary_port), "POST", query) + +# Decode the wav file or raise an exception if no wav files +if (resp["content-type"] == "audio/x-wav"): + # Write the wav file + f = open("/tmp/output_wav.wav", "wb") + f.write(content) + f.close() + # Play the wav file + pygame.mixer.init(frequency=16000) # Initialise the mixer + #s = pygame.mixer.Sound(content) + s = pygame.mixer.Sound("/tmp/output_wav.wav") + print(str(time.time() -starttime)) + s.play() + print(str(time.time() -starttime)) + pygame.time.wait(int(math.ceil(s.get_length() * 1000))) + +else: + raise Exception(content) diff --git a/play zone/parseProcessTree.py b/play zone/parseProcessTree.py new file mode 100755 index 00000000..1303f46e --- /dev/null +++ b/play zone/parseProcessTree.py @@ -0,0 +1,53 @@ +#!/bin/python +import os +import time +start = time.time() +pids = [pid for pid in os.listdir('/proc') if pid.isdigit()] +#pids = ['5960'] + +tty = os.open('/dev/tty2', os.O_RDWR) +fg = str(os.tcgetpgrp(tty)) +tty.close() +print(fg) +for pid in pids: + try: + currStat = str(open('/proc/' + pid + '/stat', 'rb').read()) + currStat = currStat.split(' ') + if int(currStat[4]) == 0: + continue + #print(currStat) + #print(fg,int(currStat[4])) + if fg == currStat[4]: + print(currStat[1]) + #print( currStat ) + #print(currStat[0]) + major = os.major(int(currStat[6])) + minor = os.minor(int(currStat[6])) + ueventContent = open('/sys/dev/char/' + str(major) + ':' + str(minor) + '/uevent','r').read().split() + #print(ueventContent) + #print(int(currStat[4]),currStat[1]) + except IOError: # proc has already terminated + continue + +print(time.time()-start) + + +''' +Table 1-4: Contents of the stat files (as of 2.6.30-rc7) +.............................................................................. + Field Content + pid process id + tcomm filename of the executable + state state (R is running, S is sleeping, D is sleeping in an + uninterruptible wait, Z is zombie, T is traced or stopped) + ppid process id of the parent process + pgrp pgrp of the process + sid session id + tty_nr tty the process uses + tty_pgrp pgrp of the tty + flags task flags + min_flt number of minor faults + cmin_flt number of minor faults with child's + maj_flt number of major faults + cmaj_flt number of major faults with child's +''' diff --git a/play zone/passBrokenDevice.py b/play zone/passBrokenDevice.py new file mode 100755 index 00000000..ec033434 --- /dev/null +++ b/play zone/passBrokenDevice.py @@ -0,0 +1,28 @@ +#!/bin/python +import evdev +from evdev import InputDevice +from select import select +import time + +deviceList = evdev.list_devices() +readableDevices = [] +for dev in deviceList: + try: + open(dev) + readableDevices.append(dev) + print('OK '+dev) + except Exception as e: + print('skip ' + dev + ' Error ' + str(e)) + + +devices = map(evdev.InputDevice, (readableDevices)) +devices = {dev.fd: dev for dev in devices} + +while True: + r, w, x = select(devices, [], []) + if r != []: + for fd in r: + for event in devices[fd].read(): + print('Devicename:'+ devices[fd].name + ' Devicepath:' + devices[fd].fn + ' Events:' + str(devices[fd].active_keys(verbose=True)) + ' Value:' + str(event.value)) + + diff --git a/play zone/pdmenurc b/play zone/pdmenurc new file mode 100644 index 00000000..7f00595c --- /dev/null +++ b/play zone/pdmenurc @@ -0,0 +1,154 @@ +#!/usr/bin/pdmenu +# +# Note that the above bang-path isn't required, but it lets you run this +# file directly as a sort of pdmenu script. + +# F123 menu + +title:Welcome to F123 + +# Define the main menu. +menu:main:F123 Main Menu:Please make a selection + show:_Games Menu..::games + show:_Internet menu..::internet + show:_Media menu..::media + show:_Office menu..::office + show:_System Configuration Menu..::configuration + show:_Tools Menu..::tools + nop + show:_Power Options..::power + nop + exit:_Exit + + +# Submenu for games. +menu:games:Games:Command line games + exec:_Adventure::clear;adventure + exec:_Arithmetic::clear;arithmetic + exec:_Air Traffic Controler (Not screen reader friendly)::clear;atc + exec:_Backgammon (Not screen reader friendly)::clear;backgammon + exec:_Battlestar::clear;battlestar + exec:_Boggle (Not screen reader friendly)::clear;boggle + exec:_Canfield (Not screen reader friendly)::clear;canfield + exec:_Cribbage (Not screen reader friendly)::clear;cribbage + exec:_Go Fish:pause:clear;go-fish + exec:_Gomoku::clear;gomoku + exec:_Hangman::clear;hangman + exec:_Hunt (Not screen reader friendly)::clear;hunt + exec:_Mille Bornes::clear;mille + exec:_Number::clear;number + exec:_Phantasia::clear;phantasia + exec:_Phase of the Moon:pause:clear;pom + exec:_Primes::clear;primes + exec:_Robots (Not screen reader friendly)::clear;robots + exec:_Sail::clear;sail + exec:_Snake (Not screen reader friendly)::clear;snake + exec:_Tetris (Not screen reader friendly)::clear;tetris-bsd + exec:_Trek::clear;trek + exec:_Worm (Not screen reader friendly)::clear;worm + exec:_Wumpus::clear;wump + + nop + exit:_Main menu.. + +# submenu for internet applications. +menu:internet:Internet:Internet programs + exec:_E-Mail::clear;mutt + exec:_Basic Web Browser (W3M)::clear;w3m -v + group:Full _Web browser (Firefox) + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher firefox + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:_Mumble Voice Chat + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher mumble + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + nop + exit:_Main menu.. + +menu:media:Media:Multi-media applications + exec:_CD Audio Ripper (ripit)::ripit + exec:_Music Player (cmus)::cmus + exec:_Youtube (audio only)::youtube-viewer -novideo + group:Youtube (full _video) + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher lxterminal -e youtube-viewer + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + nop + exit:_Main menu.. + +menu:office:Office:Word processing, calendar, etc + exec:_Month Calendar:pause:clear;ncal + exec:_Year Calendar:pause:clear;ncal -y + exec:Text Editor::clear;${EDITOR:-nano} + nop:Office Suite + group:Database + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher lobase + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:Diagrams + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher lodraw + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:Formula Editor + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher lomath + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:Presentation + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher loimpress + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:Spreadsheet + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher localc + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + group:Word Processor + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher lowriter + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup + nop + exit:_Main menu.. + +# submenu for configuring the computer. +menu:configuration:Configuration:System Configuration + exec:_Change Passwords::clear;/usr/lib/F123-wrappers/configure-passwords + exec:_Email Configuration::clear;fleacollar + exec:_Security Configuration::clear;/usr/lib/F123-wrappers/configure-security + exec:_Wireless Internet Connection::clear;sudo configure-wifi + nop + exit:_Main menu.. + +menu:tools:Tools:System Tools + group:Bluetooth manager + exec:::clear + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-ignore-screen + exec:::startx /usr/lib/F123-wrappers/xlauncher blueman-assistant + exec:::python /usr/share/fenrirscreenreader/tools/fenrir-unignore-screen + endgroup +exec:_Search:edit,pause:recoll -t ~Search for what? :~ + nop + exit:_Main menu.. + +menu:power:Shutdown or Restart Your Computer:Shutdown or restart your computer + exec:_Power Off::poweroff + exec:_Restart::reboot + nop + exit:_Main menu.. diff --git a/play zone/print_escape.py b/play zone/print_escape.py new file mode 100644 index 00000000..7ccb1e54 --- /dev/null +++ b/play zone/print_escape.py @@ -0,0 +1,41 @@ +#!/bin/python3 +import sys, os +import pty +import pyte + +class FenrirTermStream(pyte.Stream): + def __init__(self): + super().__init__() + def attach(self, screen): + super().attach(screen) + def feed(self, text): + super().feed(text) + +class FenrirTermEmu(): + def __init__(self): + self.shell = '/bin/bash' + if 'SHELL' in os.environ: + self.shell = os.environ['SHELL'] + self.screen = pyte.Screen(80,24) + self.stream = FenrirTermStream() + self.stream.attach(self.screen) + def outputCallback(self, fd): + data = os.read(fd, 1024) + self.stream.feed(data.decode('UTF8')) + # alles + #print(self.screen.display) + # input + #print(data.decode('UTF8')) + return data + def inputCallback(self, fd): + data = os.read(fd, 1024) + print('|'+str(data)+'|') + if data == b'q': + print('quit') + return b'exit\r' + return data + def startEmulator(self): + pty.spawn(self.shell, self.outputCallback, self.inputCallback) + +t = FenrirTermEmu() +t.startEmulator() diff --git a/play zone/pyterm.py b/play zone/pyterm.py new file mode 100755 index 00000000..7be1844a --- /dev/null +++ b/play zone/pyterm.py @@ -0,0 +1,34 @@ +#!/bin/python3 +import sys, os +import pty +import pyte + +class FenrirTermStream(pyte.Stream): + def __init__(self): + super().__init__() + def attach(self, screen): + super().attach(screen) + def feed(self, text): + super().feed(text) + +class FenrirTermEmu(): + def __init__(self): + self.shell = '/bin/bash' + if 'SHELL' in os.environ: + self.shell = os.environ['SHELL'] + self.screen = pyte.Screen(80,24) + self.stream = FenrirTermStream() + self.stream.attach(self.screen) + def outputCallback(self, fd): + data = os.read(fd, 1024) + self.stream.feed(data.decode('UTF8')) + # alles + print(self.screen.display) + # input + print(data.decode('UTF8')) + return data + def inputCallback(self, fd): + data = os.read(fd, 1024) + return data + def startEmulator(self): + pty.spawn(self.shell, self.outputCallback, self.inputCallback) diff --git a/play zone/split.txt b/play zone/split.txt new file mode 100644 index 00000000..74dfc21d --- /dev/null +++ b/play zone/split.txt @@ -0,0 +1,34 @@ +./play zone/wrapWord.py:21: wrappedLines = currText.split('\n') +./play zone/wrapWord.py:50: wrappedLines = currText.split('\n') +./play zone/wrapWord.py:93: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n') +./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n') +./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']] +./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n') +./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n'] +./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\ +./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n')) +./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n') +./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./TODO v2.0:72: w.fill(i).split('\n') diff --git a/play zone/terminalManagement b/play zone/terminalManagement new file mode 100644 index 00000000..59fdab46 --- /dev/null +++ b/play zone/terminalManagement @@ -0,0 +1,119 @@ +import os +import struct +import sys +import pty +import tty +import termios +import shlex +import signal +import select +import pyte +import time + +class Terminal: + def __init__(self, columns, lines, p_in): + self.screen = pyte.HistoryScreen(columns, lines) + self.screen.set_mode(pyte.modes.LNM) + self.screen.write_process_input = \ + lambda data: p_in.write(data.encode()) + self.stream = pyte.ByteStream() + self.stream.attach(self.screen) + def feed(self, data): + self.stream.feed(data) + def dump(self): + cursor = self.screen.cursor + lines = [] + for y in self.screen.dirty: + line = self.screen.buffer[y] + data = [(char.data, char.reverse, char.fg, char.bg) + for char in (line[x] for x in range(self.screen.columns))] + lines.append((y, data)) + self.screen.dirty.clear() + return {"c": (cursor.x, cursor.y), "lines": lines} + + +def open_terminal(command="bash", columns=80, lines=24): + p_pid, master_fd = pty.fork() + if p_pid == 0: # Child. + argv = shlex.split(command) + env = os.environ.copy() + env["TERM"] = 'vt100' + os.execvpe(argv[0], argv, env) + # File-like object for I/O with the child process aka command. + p_out = os.fdopen(master_fd, "w+b", 0) + return Terminal(columns, lines, p_out), p_pid, p_out + +def HandleTerminal(): + debug = False + running = True + try: + old_attr = termios.tcgetattr(sys.stdin) + tty.setraw(0) + terminal, p_pid, p_out = open_terminal() + std_out = os.fdopen(sys.stdout.fileno(), "w+b", 0) + while running: + r, w, x = select.select([sys.stdin, p_out],[],[]) + if r == []: + continue + if p_out in r: + if debug: + print('pre p_out') + try: + msgBytes = read_all(p_out.fileno()) + except (EOFError, OSError): + running = False + break + terminal.feed(msgBytes) + os.write(sys.stdout.fileno(), msgBytes) + if debug: + print('after p_out') + if sys.stdin in r: + if debug: + print('pre stdin') + try: + msgBytes = read_all(sys.stdin.fileno()) + except (EOFError, OSError): + running = False + break + terminal.feed(msgBytes) + os.write(p_out.fileno(), msgBytes) + if debug: + print('after stdin') + except Exception as e: # Process died? + print(e) + running = False + finally: + os.kill(p_pid, signal.SIGTERM) + p_out.close() + termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr) + sys.exit(0) + +def get_terminal_size(fd): + s = struct.pack('HHHH', 0, 0, 0, 0) + rows, cols, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s)) + return rows, cols + +def resize_terminal(fd): + s = struct.pack('HHHH', 0, 0, 0, 0) + s = fcntl.ioctl(0, termios.TIOCGWINSZ, s) + fcntl.ioctl(fd, termios.TIOCSWINSZ, s) + rows, cols, _, _ = struct.unpack('hhhh', s) + return rows, cols + +def read_all(fd): + bytes = os.read(fd, 65536) + if bytes == b'': + raise EOFError + while has_more(fd): + data = os.read(fd, 65536) + if data == b'': + raise EOFError + bytes += data + return bytes + +def has_more(fd): + r, w, e = select.select([fd], [], [], 0) + return (fd in r) + +if __name__ == "__main__": + HandleTerminal() diff --git a/play zone/vcsa.py b/play zone/vcsa.py new file mode 100755 index 00000000..6742fd6f --- /dev/null +++ b/play zone/vcsa.py @@ -0,0 +1,92 @@ +#!/usr/bin/python + +from cairo import * +from fcntl import ioctl +from array import array +import struct +import errno +import sys + +GIO_UNIMAP = 0x4B66 +VT_GETHIFONTMASK = 0x560D + +if len(sys.argv) != 3: + print "Usage: %s " % sys.argv[0] + exit() + +ttyno = int(sys.argv[1]) +png = sys.argv[2] + +tty = open('/dev/tty%d' % ttyno, 'rb') +himask = array("H", (0,)) +ioctl(tty, VT_GETHIFONTMASK, himask) +hichar, = struct.unpack_from("@H", himask) + +sz = 512 +while True: + try: + unipairs = array("H", [0]*(2*sz)) + unimapdesc = array("B", struct.pack("@HP", sz, unipairs.buffer_info()[0])) + ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc) + break + except IOError as e: + if e.errno != errno.ENOMEM: + raise + sz *= 2 +tty.close() + +ncodes, = struct.unpack_from("@H", unimapdesc) +utable = struct.unpack_from("@%dH" % (2*ncodes), unipairs) + +charmap = {} +for u, b in zip(utable[::2], utable[1::2]): + if charmap.get(b) is None: + charmap[b] = unichr(u) + +vcs = open('/dev/vcsa%d' % ttyno, 'rb') + +head = vcs.read(4) +rows = ord(head[0]) +cols = ord(head[1]) +caretX = ord(head[2]) +caretY = ord(head[3]) + +surf = ImageSurface(FORMAT_RGB24, cols * 8, rows * 16) + +cr = Context(surf) +cr.set_source_rgb(1,1,1) +cr.set_font_face(ToyFontFace("Mono", FONT_SLANT_NORMAL, FONT_WEIGHT_NORMAL)); +m = Matrix() +m.scale(10.0, 12.0) +cr.set_font_matrix(m) + +def CairoColor(b, a): + return (b if a & 4 else 0, b if a & 2 else 0, b if a & 1 else 0) + +for y in range(rows): + for x in range(cols): + data = vcs.read(2) + (sh,) = struct.unpack("=H", data) + attr = (sh >> 8) & 0xFF + ch = sh & 0xFF + if hichar == 0x100: + attr >>= 1 + + ink = attr & 0x0F + paper = (attr>>4) & 0x0F + b = 1.0 if attr & 0x80 else 0.75 + if sh & hichar: + ch |= 0x100 + + cr.set_source_rgb(*CairoColor(b, paper)) + cr.rectangle(x*8, y*16, 8, 16) + cr.fill() + + cr.set_source_rgb(*CairoColor(b, ink)) + cr.move_to(x*8, 12 + y*16) + cr.show_text(charmap.get(ch, u'?')) + cr.stroke() +vcs.close() + +surf.write_to_png(png) + diff --git a/play zone/wrapWord.py b/play zone/wrapWord.py new file mode 100755 index 00000000..27dbc466 --- /dev/null +++ b/play zone/wrapWord.py @@ -0,0 +1,142 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +# Fenrir TTY screen reader +# By Chrys, Storm Dragon, and contributers. + +#from fenrirscreenreader.core import debug +import string +# X Y Word END BREAK +# -1, -1, '', True False +def getPrevWord(currX,currY, currText): + lineBreak = False + endOfScreen = False + if currText == '': + return -1, -1, '', endOfScreen, lineBreak + if currText.strip( string.whitespace) == '': + return currX, currY, '', endOfScreen, lineBreak + x, y, currWord, endOfScreen, lineBreakCurrWord = getCurrentWord(currX,currY,currText) + if endOfScreen: + return x, y, currWord, endOfScreen, lineBreak + wrappedLines = currText.split('\n') + currLine = wrappedLines[y] + if x - 1 < 0: + if y - 1 < 0: + lineBreak = False + endOfScreen = True + return currX, currY, '', endOfScreen, lineBreak + else: + y -= 1 + currLine = wrappedLines[y] + x = len( wrappedLines[y]) - 1 + lineBreak = True + else: + x -= 1 + lineBreakCurrWord = lineBreak or lineBreakCurrWord + x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,currText) + lineBreak = lineBreak or lineBreakCurrWord + return x, y, currWord, endOfScreen, lineBreak + +def getCurrentWord(currX,currY, currText): + lineBreak = False + endOfScreen = False + if currText == '': + return -1, -1, '', endOfScreen, lineBreak + if currText.strip( string.whitespace) == '': + return currX, currY, '', endOfScreen, lineBreak + x = currX + y = currY + currWord = '' + wrappedLines = currText.split('\n') + currLine = wrappedLines[y] + Found = False + while(not Found): + if not currLine[x] in string.whitespace: + if x == 0: + Found = True + else: + if currLine[x - 1] in string.whitespace: + Found = True + if not Found: + if x - 1 < 0: + if y - 1 < 0: + lineBreak = False + endOfScreen = True + return currX, currY, '', endOfScreen, lineBreak + else: + y -= 1 + currLine = wrappedLines[y] + x = len( wrappedLines[y]) - 1 + lineBreak = True + else: + x -= 1 + if Found: + currWord = currLine[x:] + for d in string.whitespace: + delimiterPos = currWord.find(d) + if delimiterPos != -1: + currWord = currWord[:delimiterPos] + + return x, y, currWord, endOfScreen, lineBreak + return currX, currY, '', False, False + +def getNextWord(currX,currY, currText): + lineBreak = False + endOfScreen = False + if currText == '': + return -1, -1, '', endOfScreen, lineBreak + if currText.strip( string.whitespace) == '': + return currX, currY, '', endOfScreen, lineBreak + x = currX + y = currY + currWord = '' + wrappedLines = currText.split('\n') + currLine = wrappedLines[y] + Found = False + while(not Found): + if not Found: + if x + 1 > len( currLine ) - 1: + if y + 1 > len( wrappedLines ) - 1: + lineBreak = False + endOfScreen = True + return currX, currY, '', endOfScreen, lineBreak + else: + y += 1 + currLine = wrappedLines[y] + x = 0 + lineBreak = True + else: + x += 1 + if not currLine[x] in string.whitespace: + if x == 0: + Found = True + else: + if currLine[x - 1] in string.whitespace: + Found = True + if Found: + currWord = currLine[x:] + for d in string.whitespace: + delimiterPos = currWord.find(d) + if delimiterPos != -1: + currWord = currWord[:delimiterPos] + return x, y, currWord, endOfScreen, lineBreak + return currX, currY, '', False, False + + + +data = """das ist ein test lol + das ist ein test l + das ist ein test + + asdf asdf a +test test + te test""" +print('__DATA START__') +print(data) +print('__DATA END__\n\n') + +x = 3 +y = 0 +x, y, currWord, endOfScreen, lineBreak = getCurrentWord(x,y,data) +print(x,y,currWord) + diff --git a/play zone/writeBrl.py b/play zone/writeBrl.py new file mode 100755 index 00000000..08fefcd3 --- /dev/null +++ b/play zone/writeBrl.py @@ -0,0 +1,19 @@ +#!/bin/python + +import brlapi +import time + +brl = brlapi.Connection() +brl.enterTtyModeWithPath() +print('display size' + str(brl.displaySize)) +print('driver name'+str(brl.driverName)) + +t = time.time() +#while(time.time() - t <= 5): +try: + brl.writeText( 'this is a 5 second test') +except Exception as e: + print(e) +time.sleep(5) +brl.leaveTtyMode() + diff --git a/realese nots/1.9 b/realese nots/1.9 new file mode 100644 index 00000000..5cf6a670 --- /dev/null +++ b/realese nots/1.9 @@ -0,0 +1,71 @@ +Cleanups: + [X] re.sub(' +,' ',text) -> text.lstrip()? check this? +- inheritation for drivers + [X] Speech (All) + [X] Braille (All) + [X] Sound (All) + [X] Input (All) + [X] Screen (All) +- generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution) - core.memoryManager + [X] next item + [X] prev item + [X] curr item + [X] first item + [X] last item +General: + [X] make it runable using pypy3 + [X] play sound on plugging device + [X] interrupt speech while entering an ignored screen + [X] read ignorescreens from an file to be able to halt fenrir from outside +- commands + [X] place last spoken to clipboard (Easy for contribution) +- Improvend Headline Seperator and Multible Char Support + [X]read "13 #" insteed of ################### +- autospeak indentation changes (useful for python programming) +Braille Support: +Driver: +[X] evdev InputDriver + [X] grab/ ungrab devices on ignored screens + Driver (screen, input): +[X] PTY Screen driver (to use gnome-terminal and other terminal emulators) + [X] emulation + [X] basic reading + [X] detect colum/ lines + [X] resize on colum / line change + [X] make shell command configurable (or detect it) + [X] stop emulation properly + [X] attributes + [X] unify hilgight tracking + [X] make pasteing text work again + [X] make double tap work again + [X] new event for byte shortcuts (escape sequences) + [X] create driver + [X] handle byte shortcuts + [X] detect shortcuts + [X] Load escape sequence shortcuts + [X] controll modes (vim like mode to not collide with application shortcuts) + [X] create keyboard layout + [X]set flag that it is used in emulation + [X] write/ consume them (controll it at all) + https://docs.python.org/3.2/library/pty.html + http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/ + https://blog.konpat.me/pythons-pseudo-terminal-pty-examples/ + +[X] make generic speech driver default +[X] pyttsx3 speech driver +- get information already in watchdogs insteed of mainloop (use eventloop to transport) + [X] InputDriver +Settings: +Application Profiles: +Translation: +- German (thanks to schulle4u and Jenny) https://robbinaer.info/index.php?article101/fenrir +Fixes: +- no shell in generic speech Driver +- imporove validity checks for speech driver +- handle thread and process shutdown more gracefully +- cleanup +- a lot more fixes +- better device detection +[X] (not conflict with other applications) find . -iname "*.py" -exec sed 's/from \(core.*\) import/from fenrir-screenreader.\1 import/g' {} \; + + diff --git a/realese nots/1.9.2 b/realese nots/1.9.2 new file mode 100644 index 00000000..c5d4df3f --- /dev/null +++ b/realese nots/1.9.2 @@ -0,0 +1,9 @@ +- import clipboard from x (xclip) +- barrier mode (respect pseudo cli window borders like used in dialog or pdmenu) +- toggle for barrier mode +- soundicon for barrier mode when enter and leave the barrier detection +- imporove accuracy of speak history (arrow up/ down in bash) +- higher accuracy for hilight tracking +- soundicon for attribute +- overall improved attribute code +- variouse speedups and bugfixes diff --git a/splits.txt b/splits.txt new file mode 100644 index 00000000..74dfc21d --- /dev/null +++ b/splits.txt @@ -0,0 +1,34 @@ +./play zone/wrapWord.py:21: wrappedLines = currText.split('\n') +./play zone/wrapWord.py:50: wrappedLines = currText.split('\n') +./play zone/wrapWord.py:93: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/screenDriver/vcsaDriver.py:281: apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n') +./src/fenrirscreenreader/utils/line_utils.py:14: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/line_utils.py:30: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/line_utils.py:41: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:14: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:35: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:43: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:58: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:73: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/char_utils.py:85: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/mark_utils.py:13: inText = inText.split('\n') +./src/fenrirscreenreader/utils/mark_utils.py:59: inText = inText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:20: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:62: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/utils/word_utils.py:91: wrappedLines = currText.split('\n') +./src/fenrirscreenreader/core/outputManager.py:173: currline = text.split('\n')[offset['y']] +./src/fenrirscreenreader/core/attributeManager.py:250: textLines = text.split('\n') +./src/fenrirscreenreader/core/screenManager.py:166: diffList = ['+ ' + self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +'\n'] +./src/fenrirscreenreader/core/screenManager.py:169: diff = self.differ.compare(oldScreenText.split('\n'),\ +./src/fenrirscreenreader/core/screenManager.py:170: newScreenText.split('\n')) +./src/fenrirscreenreader/core/screenManager.py:225: windowList = text.split('\n') +./src/fenrirscreenreader/commands/onCursorChange/62000-spell_check.py:66: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py:39: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/50000-present_char_if_cursor_change_horizontal.py:41: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onCursorChange/61000-word_echo_navigation.py:37: newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/commands/spell_check.py:47: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/commands/remove_word_from_spell_check.py:45: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/commands/add_word_to_spell_check.py:43: newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']] +./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:38: prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./src/fenrirscreenreader/commands/onScreenUpdate/60000-history.py:39: currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] +./TODO v2.0:72: w.fill(i).split('\n') diff --git a/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py b/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py new file mode 100644 index 00000000..57a530fd --- /dev/null +++ b/src/fenrirscreenreader/commands/onCursorChange/60000-word_echo_type.py @@ -0,0 +1,58 @@ +#!/bin/python +# -*- coding: utf-8 -*- + +# Fenrir TTY screen reader +# By Chrys, Storm Dragon, and contributers. + +from fenrirscreenreader.core import debug +from fenrirscreenreader.utils import word_utils +import string + +class command(): + def __init__(self): + pass + def initialize(self, environment): + self.env = environment + def shutdown(self): + pass + def getDescription(self): + return 'No Description found' + + def run(self): + # is it enabled? + if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'): + return + # is naviation? + if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1: + return + # just when cursor move worddetection is needed + if not self.env['runtime']['cursorManager'].isCursorHorizontalMove(): + return + # for now no new line + if self.env['runtime']['cursorManager'].isCursorVerticalMove(): + return + # currently writing + if self.env['runtime']['screenManager'].isDelta(): + return + + # get the word + newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']] + x, y, currWord, endOfScreen, lineBreak = \ + word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent) + + # is there a word? + if currWord == '': + return + # at the end of a word + if not newContent[self.env['screen']['newCursor']['x']].isspace(): + return + # at the end of a word + if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \ + (x + len(currWord) != self.env['screen']['newCursor']['x']-1): + return + + self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False) + + def setCallback(self, callback): + pass +