Codebase list fenrir / e2d6bf6
New upstream version 1.5.1 Samuel Thibault 6 years ago
285 changed file(s) with 14764 addition(s) and 3960 deletion(s). Raw diff Collapse all Expand all
00 __pycache__/
11 *\.pyc
22 fenrir.egg-info/
3 fenrir_screenreader.egg-info/
34 dist/
5 build/
+0
-204
Changelog v1.0.txt less more
0 - move from VCS to VCSA and parese the Attributes
1 http://linux.die.net/man/4/vcsa
2 http://man.cx/vcsa(4)/de
3 http://manpages.org/display-vcsa/7
4 https://en.wikipedia.org/wiki/Virtual_console
5 every second byte is a attribute others are text. fast way: c[::2],c[1::2]
6 http://manpages.ubuntu.com/manpages/precise/de/man4/vcs.4.html
7 https://docs.python.org/3/library/fcntl.html
8 http://rodrigorivas.serveblog.net/en/imagenes-desde-vt-con-vcsa/
9 good doku:
10 http://angband.oook.cz/d/eyangband-052/src/main-vcs.c
11 http://manpages.ubuntu.com/manpages/trusty/man1/screader.1.html
12
13 - implement speechdriver espeak
14 https://github.com/relsi/python-espeak
15
16 - detect collumns in TTYs automaticaly.
17 it seems we have this info in vcsa
18
19 - get current cursor
20 - shortcut handling
21 https://docs.python.org/2/library/termios.html
22 http://stackoverflow.com/questions/287757/pythons-configparser-unique-keys-per-section
23 0=down, 1=press, 2=hold
24 2KEY_SHIFT, 1KEY_A = say_current_line_cursor
25 - implement command structure
26 - implement speechdriver speechd
27 https://git.gnome.org/browse/orca/tree/src/orca/speech.py
28 https://git.gnome.org/browse/orca/tree/src/orca/speechdispatcherfactory.py
29 http://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#Client-Programming
30
31 - autodetect current TTY maybe with (PAM or a sys folder)
32 cat /sys/devices/virtual/tty/tty0/active
33 http://serverfault.com/questions/306854/how-to-find-out-the-currently-active-linux-virtual-terminal-while-connected-via
34
35 - Input
36 http://python-evdev.readthedocs.io/en/latest/tutorial.html
37 http://stackoverflow.com/questions/12384772/how-can-i-capture-mouseevents-and-keyevents-using-python-in-background-on-linux
38 maybe TTY in RAW MODE
39
40 - Settings (make it configureable)
41 - improve differ speed
42 - lock mechanism for threads
43 - restructure loops to listen for events
44 inputloop -> does block with an select
45 commands -> a new thread should spawned from inputloop
46 updatescreen -> maybe we could watch it with inotify vsca should support polling COMMENT: sadly not possible, poll events not fired as expected
47 https://github.com/seb-m/pyinotify/wiki/Tutorial
48 <Example Code>
49 import pyinotify
50 import glob
51 class Identity(pyinotify.ProcessEvent):
52 def process_default(self, event):
53 p = event.pathname
54 print(p)
55
56 wm = pyinotify.WatchManager()
57
58 notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(), timeout=5)
59 wm.add_watch('/sys/devices/virtual/tty/tty0/active', pyinotify.IN_CLOSE_WRITE)
60 for file in list(glob.glob('/dev/vcsa[0-64]')):
61 wm.add_watch(file, pyinotify.IN_CLOSE_WRITE)
62 print(file)
63
64 try:
65 while 1:
66 notifier.process_events()
67 if notifier.check_events( timeout=1000):
68 notifier.read_events()
69 print('events')
70 else:
71 print('timeout')
72 except KeyboardInterrupt:
73 notifier.stop()
74 print('fin')
75 </Example Code>
76
77 https://www.infoq.com/articles/inotify-linux-file-system-event-monitoring
78 https://github.com/seb-m/pyinotify/wiki/Tutorial
79 http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/
80
81 - add setting for ignore screens ( dont grab shortcuts from X or orca)
82 - soundIcons
83 - performance tuning
84 - add sound volume
85 - convert volume to percent in config
86 - convert pitch to percent in config
87 - convert rate to percent in config
88 - make screenUpdate rate configurable
89 - default soundIcon theme (soundfiles)
90 - debugging
91 - threading ReadContent, ReadShortcuts, executeCommands, listenNewTTYsForListen, controllThread (main)
92 - autoload plugins while starting
93 - implement sounddriver generic (use current sox and make it configurable)
94 - add setting for autodetect X
95 ps a -o tty,comm | grep -e Xorg | grep -v "grep -e Xorg"
96 - respect window mode in differ (getwindow code is already in place)
97 - parse punctuation setting file in conf/substitution
98
99 - implement commands
100 curr_word
101 curr_char
102 next_word
103 next_char
104 prev_word
105 prev_char
106 enable_disable_speech #enable, disable speech
107 enable_disable_braile #enable, disable braile
108 enable_disable_sound #enable, disable sound
109 enable_disable_output #enable, disable speech, braile and sound
110 next_clipboard
111 prev_clipboard
112 first_clipboard
113 last_clipboard
114 curr_clipboard
115 paste_clipboard
116 define_window
117 remove_window
118 reset_review_on_screen_change
119 remove_clipboard_marks
120 copy_marked
121 set_mark (this could also used for area?)
122 read_clipboard_mark_text
123 curr_screen
124 curr_screen_before_cursor
125 curr_screen_after_cursor
126 cursor_position
127 indention
128 add_bookmark (per application)
129 remove_bookmark
130 present_bookmark
131 say_char_phonetic
132 spell_word_phonetic
133 "alpha", "bravo", "charlie", "delta", "echo",
134 "foxtrot", "golf", "hotel", "india", "juliet",
135 "kilo", "lima", "mike", "november", "oscar",
136 "papa", "quebec", "romeo", "sierra", "tango",
137 "uniform", "victor", "whisky", "x ray",
138 "yankee", "zulu"
139 next_char_phonetic
140 prev_char_phonetic
141 next_word_phonetic
142 prev_word_phonetic
143 toggle_highlighted_mode
144
145 - implement onInput commands
146 read_line_if_cursor_change_vertical (needed if you arrow up and down, we want to announce the line)
147 read_char_if_cursur_change_horizontal (needed if you arrow left and right, we want to announce the char under the cursor)
148 echo_char (echos the last char on pressing space or return)
149 echo_word (echos the last word)
150 echo_deleted_char (echos deleted char on screen
151 read highlighted
152
153 - implement onScreenChange commands
154 promoted text
155 clear_marks_on_screen_change
156 leve_review_mode_on_screen_change
157 window mode (define a area and just read that changes)
158
159 - add screenManager
160 abstract screen driver
161 - pass environment instance in init and remove it from function calls
162
163 - New Triggers
164 onAppChange
165 onAppProfileChange
166 onScreenChange
167 rename current onScreenChange to onScreenUpdate
168
169 - rework inputManager
170 try to consume shortcuts
171 grab keyboard exclusive
172 release keyboard on error or quit
173 grab shortcuts with fenrir key
174 grab "singel key shortcuts" like numpad navigation for review
175 forwart nonshortcuts to system
176 make grabbing configuarble
177 possiblity to forewart shortcut [proxyshortcut]
178 possiblity to forewart shortcut (or use them as shortcut) [pressing twice while timeout]
179 cleanup inputManager
180 split input driver out of the handler
181
182 - dictonary for special chars and string replacements
183 - punctuation
184 - beep on cursor to capital letters in cursor and review
185 - add pause handling
186 create pause
187 make it configurable when the pause the pause happens
188 - external scripting
189 load scripts from a folder as subprocess
190 create thread
191 load key definition of keybindings like SOPS did
192
193 - add an daemonize mode
194 https://github.com/thesharp/daemonize
195 https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
196
197 - announce capslock
198 - anounce numlock
199 - anounce scroll
200 - add the debugging to core
201
202 - autostart systemd
203 https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html
0 # Version 1.5
1 - Doku: Write a user wiki
2 https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir
3
4 - initial working setup.py
5
6 - available via pip (python packet manager)
7 sudo pip3 install fenrir-screenreader
8 https://pypi.python.org/pypi/fenrir-screenreader/1.5.post5
9
10 - leave review on typing
11
12 - add dependency check (check-dependencys.py)
13
14 - Add nice dummy drivers as template or for debugging
15
16 - reimplement detection code for X11
17
18 - initial translate structure (manuelcortez Thanks!)
19
20 - add a configurable place where you can place own commands or overwrite existing commands without need to change default code
21
22 - implement autodetection of plugged and unplugged input devices
23
24 - implement speechdriver generic
25
26 - try to autodetect encoding (Easy for contribution) (Prototype "charmapTTY" in play zone)
27
28 Braille Support (WIP):
29 - initial BrlTTY driver
30 - detect device size via driver
31 - output to braille device
32 - make flushMode configurable
33 - make flushTimeout configurable
34 - flush message after X seconds and show current line (review over text)
35 - tweak current commands and output
36 - command flush_braille
37 - command for scroll left
38 - command for scroll right
39 - create offset for scrolling
40 - respect scrolling
41 make cursor following configurable (brailleCursorTrackingMode)
42 - cell
43 - page
44 follow cursor while typing
45 brailleFocusMode:
46 - review = priority to review
47
48 - move to an event based system
49
50 - add initial multithreading/ multiprocessing support
51
52 - support cli parameters
53 - add cli parameter for debugging "-d"
54 - add cli parameter to overwrite options "-o"
55 - add cli parameter to specify an settings.conf "-s"
56
57 - list of bound commands in Tutorial Mode. speak name, binding and description.
58
59 # Version: 1.00
60
61 - move from VCS to VCSA and parese the Attributes
62 http://linux.die.net/man/4/vcsa
63 http://man.cx/vcsa(4)/de
64 http://manpages.org/display-vcsa/7
65 https://en.wikipedia.org/wiki/Virtual_console
66 every second byte is a attribute others are text. fast way: c[::2],c[1::2]
67 http://manpages.ubuntu.com/manpages/precise/de/man4/vcs.4.html
68 https://docs.python.org/3/library/fcntl.html
69 http://rodrigorivas.serveblog.net/en/imagenes-desde-vt-con-vcsa/
70 good doku:
71 http://angband.oook.cz/d/eyangband-052/src/main-vcs.c
72 http://manpages.ubuntu.com/manpages/trusty/man1/screader.1.html
73
74 - implement speechdriver espeak
75 https://github.com/relsi/python-espeak
76
77 - detect collumns in TTYs automaticaly.
78 it seems we have this info in vcsa
79
80 - get current cursor
81 - shortcut handling
82 https://docs.python.org/2/library/termios.html
83 http://stackoverflow.com/questions/287757/pythons-configparser-unique-keys-per-section
84 0=down, 1=press, 2=hold
85 2KEY_SHIFT, 1KEY_A = say_current_line_cursor
86 - implement command structure
87 - implement speechdriver speechd
88 https://git.gnome.org/browse/orca/tree/src/orca/speech.py
89 https://git.gnome.org/browse/orca/tree/src/orca/speechdispatcherfactory.py
90 http://devel.freebsoft.org/doc/speechd/speech-dispatcher.html#Client-Programming
91
92 - autodetect current TTY maybe with (PAM or a sys folder)
93 cat /sys/devices/virtual/tty/tty0/active
94 http://serverfault.com/questions/306854/how-to-find-out-the-currently-active-linux-virtual-terminal-while-connected-via
95
96 - Input
97 http://python-evdev.readthedocs.io/en/latest/tutorial.html
98 http://stackoverflow.com/questions/12384772/how-can-i-capture-mouseevents-and-keyevents-using-python-in-background-on-linux
99 maybe TTY in RAW MODE
100
101 - Settings (make it configureable)
102 - improve differ speed
103 - lock mechanism for threads
104 - restructure loops to listen for events
105 inputloop -> does block with an select
106 commands -> a new thread should spawned from inputloop
107 updatescreen -> maybe we could watch it with inotify vsca should support polling COMMENT: sadly not possible, poll events not fired as expected
108 https://github.com/seb-m/pyinotify/wiki/Tutorial
109 <Example Code>
110 import pyinotify
111 import glob
112 class Identity(pyinotify.ProcessEvent):
113 def process_default(self, event):
114 p = event.pathname
115 print(p)
116
117 wm = pyinotify.WatchManager()
118
119 notifier = pyinotify.Notifier(wm, default_proc_fun=Identity(), timeout=5)
120 wm.add_watch('/sys/devices/virtual/tty/tty0/active', pyinotify.IN_CLOSE_WRITE)
121 for file in list(glob.glob('/dev/vcsa[0-64]')):
122 wm.add_watch(file, pyinotify.IN_CLOSE_WRITE)
123 print(file)
124
125 try:
126 while 1:
127 notifier.process_events()
128 if notifier.check_events( timeout=1000):
129 notifier.read_events()
130 print('events')
131 else:
132 print('timeout')
133 except KeyboardInterrupt:
134 notifier.stop()
135 print('fin')
136 </Example Code>
137
138 https://www.infoq.com/articles/inotify-linux-file-system-event-monitoring
139 https://github.com/seb-m/pyinotify/wiki/Tutorial
140 http://www.saltycrane.com/blog/2010/04/monitoring-filesystem-python-and-pyinotify/
141
142 - add setting for ignore screens ( dont grab shortcuts from X or orca)
143 - soundIcons
144 - performance tuning
145 - add sound volume
146 - convert volume to percent in config
147 - convert pitch to percent in config
148 - convert rate to percent in config
149 - make screenUpdate rate configurable
150 - default soundIcon theme (soundfiles)
151 - debugging
152 - threading ReadContent, ReadShortcuts, executeCommands, listenNewTTYsForListen, controllThread (main)
153 - autoload plugins while starting
154 - implement sounddriver generic (use current sox and make it configurable)
155 - add setting for autodetect X
156 ps a -o tty,comm | grep -e Xorg | grep -v "grep -e Xorg"
157 - respect window mode in differ (getwindow code is already in place)
158 - parse punctuation setting file in conf/substitution
159
160 - implement commands
161 curr_word
162 curr_char
163 next_word
164 next_char
165 prev_word
166 prev_char
167 enable_disable_speech #enable, disable speech
168 enable_disable_braile #enable, disable braile
169 enable_disable_sound #enable, disable sound
170 enable_disable_output #enable, disable speech, braile and sound
171 next_clipboard
172 prev_clipboard
173 first_clipboard
174 last_clipboard
175 curr_clipboard
176 paste_clipboard
177 define_window
178 remove_window
179 reset_review_on_screen_change
180 remove_clipboard_marks
181 copy_marked
182 set_mark (this could also used for area?)
183 read_clipboard_mark_text
184 curr_screen
185 curr_screen_before_cursor
186 curr_screen_after_cursor
187 cursor_position
188 indention
189 add_bookmark (per application)
190 remove_bookmark
191 present_bookmark
192 say_char_phonetic
193 spell_word_phonetic
194 "alpha", "bravo", "charlie", "delta", "echo",
195 "foxtrot", "golf", "hotel", "india", "juliet",
196 "kilo", "lima", "mike", "november", "oscar",
197 "papa", "quebec", "romeo", "sierra", "tango",
198 "uniform", "victor", "whisky", "x ray",
199 "yankee", "zulu"
200 next_char_phonetic
201 prev_char_phonetic
202 next_word_phonetic
203 prev_word_phonetic
204 toggle_highlighted_mode
205
206 - implement onInput commands
207 read_line_if_cursor_change_vertical (needed if you arrow up and down, we want to announce the line)
208 read_char_if_cursur_change_horizontal (needed if you arrow left and right, we want to announce the char under the cursor)
209 echo_char (echos the last char on pressing space or return)
210 echo_word (echos the last word)
211 echo_deleted_char (echos deleted char on screen
212 read highlighted
213
214 - implement onScreenChange commands
215 promoted text
216 clear_marks_on_screen_change
217 leve_review_mode_on_screen_change
218 window mode (define a area and just read that changes)
219
220 - add screenManager
221 abstract screen driver
222 - pass environment instance in init and remove it from function calls
223
224 - New Triggers
225 onAppChange
226 onAppProfileChange
227 onScreenChange
228 rename current onScreenChange to onScreenUpdate
229
230 - rework inputManager
231 try to consume shortcuts
232 grab keyboard exclusive
233 release keyboard on error or quit
234 grab shortcuts with fenrir key
235 grab "singel key shortcuts" like numpad navigation for review
236 forwart nonshortcuts to system
237 make grabbing configuarble
238 possiblity to forewart shortcut [proxyshortcut]
239 possiblity to forewart shortcut (or use them as shortcut) [pressing twice while timeout]
240 cleanup inputManager
241 split input driver out of the handler
242
243 - dictonary for special chars and string replacements
244 - punctuation
245 - beep on cursor to capital letters in cursor and review
246 - add pause handling
247 create pause
248 make it configurable when the pause the pause happens
249 - external scripting
250 load scripts from a folder as subprocess
251 create thread
252 load key definition of keybindings like SOPS did
253
254 - add an daemonize mode
255 https://github.com/thesharp/daemonize
256 https://web.archive.org/web/20131017130434/http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
257
258 - announce capslock
259 - anounce numlock
260 - anounce scroll
261 - add the debugging to core
262
263 - autostart systemd
264 https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/sect-Managing_Services_with_systemd-Unit_Files.html
0 # fenrir 1.0
1 An TTY screenreader for Linux.
2 Its an early alpha version. You can test it. It is not recommended for production use. In theorie its not limited to linux. but i currently only provide drivers for that because I have no ohter system here. If you want to help or write drivers to make it work on other systems, just let me know.
0 # Fenrir
1 A TTY screenreader for Linux.
2 In theory it's not just limited to Linux. but i currently only provide drivers for that since I do not have another system here. If you want to help, or write drivers to make it work on other systems, just let me know.
33 This software is licensed under the LGPL v3 .
44
5 # requirements (core)
6 - linux
7 - python3
8 - python-evdev >=0.6.3
9 - loaded uinput kernel module
10 - Read permission to the following files:
11 - /sys/devices/virtual/tty/tty0/active
12 - /dev/vcsa[1-64]
13 - ReadWrite permission
14 - /dev/input
15 - /dev/uinput
16 - speech, sound or braille drivers see "optional (features, drivers)".
5 # Requirements (core)
6 - Linux (currently only screen and input drivers available)
7 - python3 >= 3.3
8 - python-configargparse
9 - screen, input, speech, sound or braille drivers see "Features, Drivers, Extras".
1710
18 # optional (features, drivers)
19 - "espeak" speech driver:
11 # Features, Drivers, Extras, Dependencies
12 # Input Drivers:
13 1. "evdevDriver" input driver for linux evdev
14 - python-evdev >=0.6.3
15 - python-pyudev
16 - This is commonly referred to as python3-evdev by your distribution
17 - loaded uinput kernel module
18 - ReadWrite permission
19 - /dev/input
20 - /dev/uinput
21
22 # Screen Drivers:
23 1. "vcsaDriver" screen driver for linux VCSA devices
24 - python-dbus
25 - Read permission to the following files and services:
26 - /sys/devices/virtual/tty/tty0/active
27 - /dev/tty[1-64]
28 - /dev/vcsa[1-64]
29 - read logind DBUS
30
31 # Speech Drivers:
32 1. "EspeakDriver" speech driver for Espeak:
2033 - python-espeak
21 - "speechd" speech driver:
22 - speech-dispatcher
34 - "speechdDriver" speech driver for Speech-dispatcher:
35 - Speech-dispatcher
2336 - python-speechd
24 - brltty braille driver (not implemented yet, WIP):
37 2. "dummyDriver" speech driver for debugging
38
39 # Braille Drivers:
40 1. "BrlttyDriver" braille driver (WIP):
2541 - brltty (configured and running)
2642 - python-brlapi
27 - "generic" sound driver:
28 - sox
29 - "gstreamer" sound driver
30 - gstreamer 1.x
43 2. "dummyDriver" Braille driver for debugging
44
45 # Sound Drivers:
46 1. "genericDriver" sound driver for sound as subprocess:
47 - Sox
48 2. "gstreamerDriver" sound driver for gstreamer
49 - gstreamer >=1.0
3150 - GLib
32 - spellchecker
51 3. "dummyDriver" sound driver for debugging
52
53 # Extras:
54 1. spellchecker
3355 - python-pyenchant
34 - aspell-YourLanguageCode (example aspell-en for us english)
35 - unix daemon:
56 - aspell-YourLanguageCode (example aspell-en for us English)
57 2. Unix daemon (also needed for Systemd):
3658 - python-daemonize
59 3. Modify system volume:
60 - pyalsaaudio (needs libasound2's headers).
3761
3862 # installation
3963 - Archlinux: PKGBUILD in AUR
40 - install.sh (there is currently no uninstall)
41 - run from git:
64 - Manual: run install.sh and uninstall.sh as root
65 - you also can just run it from Git without installing:
4266 You can just run the following as root:
43 cd src/fenrir-package/
67 if you are in Fenrir Git rootfolder:
68 cd src/fenrir/
4469 sudo ./fenrir
45 Settings "settings.conf" is located in the "config" directory.
46 Take care that the used drivers in the config matching your installed drivers.
70 Settings "settings.conf" is located in the "config" directory or after installation in /etc/fenrir/settings.
71 Take care to use drivers from the config matching your installed drivers.
4772 By default it uses:
48 - sound driver: generic (via sox, could configured in settings.conf)
49 - speech driver: speechd
50 - braille driver: brltty (WIP)
73 - sound driver: genericDriver (via sox, could configured in settings.conf)
74 - speech driver: speechdDriver
75 - braille driver: brlttyDriver (WIP)
76 - input driver: evdevDriver
77
78 # Documentation
79 You can see all information on the Wiki:
80 https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual&s[]=fenrir
00 ToDo list for Fenrir Version 2.0
1
1 Things needing little knowledge are marked with "(Easy for contribution)". so just start with those :).
2 [] = ToDo
3 [W] = WIP
4 [X] = Done
5
6 Cleanups:
7 - split oldValues := newValues out to helper function (Easy for contribution)
8 [] split it out
9 [] use it in vcsa driver
10 [] Migrate *Data.py to classes and use getter/setter (Easy for contribution)
11 [] commandsData.py
12 [] eventData.py
13 [] generalData.py
14 [] inputData.py
15 [] outputData.py
16 [] punctuationData.py
17 [] runtimeData.py
18 [] screenData.py
19 [] settingsData -> defaultSettings.py
20
221 General:
3 - implement onScreenUpdate commands
4 read highlighted text mode
5 - translateable
6 - be more event based
7 - try to make it more asynchronus
8 - multpible threads
9
10 - implement commands
11 attributes_curr_char
12 generic list command (convert clipboard management)
13 next item
14 pref item
15 curr item
16 first item
17 last item
22 - commands
23 [] place last spoken to clipboard
24 - imporove attribute handling
25 [] improve attributes_curr_char
26 [] add an attribute sound
27 [] beep on cursor/ review by char (capital wins)
28 [] beep on review by word (once for multiple, capital wins)
29 [] configurable (by char, by word, none)
30 https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
31
32 - Improved Say all
33 [] all the text of all pages
34 [] command to stop and place review cursor at this position
35 [] command to slow down speech on keypress
36
37 - generic list or see Tutorial mode list (convert clipboard management) (Easy for contribution)
38 [] next item
39 [] prev item
40 [] curr item
41 [] first item
42 [] last item
43
44 - make it runnable via pypy3
45 [] wrapper script for running Fenrir to check if pypy exists, use python3 as fallback.
1846
1947 Braille Support:
20 output to braille device
21 virtual buffer area for scroll left/right if the line is to long for device
22 commands for scroll left/right
23 print cursor in review
24 print cursor in textmode
25 flush message after X seconds and show current line (review over text)
26 make flush configurable
27 leve review mode on typing (show current textline)
28 capture input from braile
29 make routing keys assignable in keyboard
30 tweak current commands and output
31 http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html
32 https://git.gnome.org/browse/orca/tree/src/orca/braille.py
33 https://wiki.gnome.org/Attic/LSR/ScratchPad/Braille/BrlAPI
48 [] brailleFocusMode:
49 [] manual = no automatic toggle command used
50 [] last = follow last used cursor
51 [] print cursor in review
52 [] print cursor in textmode
53 [] word wrapping (if word does not fit print it at next page)
54 [] command toggle used cursor (in manual brailleFocusMode)
55 [] capture input from braile
56 [] make routing keys assignable by keyboard
57 [] make brailleTable configurable
58 [] pkg-config --variable=tablesdir liblouis
59 returns on Arch:/usr/share/liblouis/tables
60 http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html
61 https://git.gnome.org/browse/orca/tree/src/orca/braille.py
62 https://wiki.gnome.org/Attic/LSR/ScratchPad/Braille/BrlAPI
63 https://github.com/google/brailleback/blob/master/third_party/brltty/Bindings/Python/brlapi.pyx
3464
3565 Driver:
36 - implement PTY Screen driver (to use gnome-terminal and other terminal emulators)
37 - ATK input driver (dont grab on graphical interface)
38 - BrlTTY driver
66 [W] PTY Screen driver (to use gnome-terminal and other terminal emulators)
3967 https://docs.python.org/3.2/library/pty.html
40 - implement speechdriver generic
41 - implement autodetection of plugged and removed input devices (python-pyudev) for evdev driver
42 http://askubuntu.com/questions/508236/how-can-i-run-code-whenever-a-usb-device-is-unplugged-without-requiring-root
68 http://sqizit.bartletts.id.au/2011/02/14/pseudo-terminals-in-python/
69 https://blog.konpat.me/pythons-pseudo-terminal-pty-examples/
70 [] talkey driver
71 [W] emacspeak driver
72 [W] PTY Input driver
73 [] ATK input driver (don't grab on graphical interface)
74 https://git.linux-a11y.org/AIT/pyatspi2/src/master/examples/keypress.py
75 [] Dectalk SpeechDriver (Easy for contribution, device needed - i dont own one)
76 https://github.com/tvraman/emacspeak/blob/master/servers/obsolete/python/dectalk.py
4377
4478 Settings:
45 - configuration should be overwriteable with parameter and alternative paths
46 - write settings
47 - menue for settings configuration #storm
79 [] write settings (Easy for contribution)
80 [] menue for settings configuration (Easy for contribution)
4881
49 Application Profiles
82 Application Profiles (low priority):
83 - reimplement process detection without subprocessing // this is started by chrys
5084 - fenrir is not able to detect the current application inside of screen.
5185 ps -e -H -o pid,pgrp,ppid,tty,cmd
5286 http://stackoverflow.com/questions/24861351/how-to-detect-if-python-script-is-being-run-as-a-background-process/24862213
5690 per application commands
5791 per application onScreenChange
5892 per application onInput
59 - per application shortcuts
93 - per application shortcuts
94
95 -----------DONE----------------
96 General:
97 Braille Support:
98 Driver:
99 Settings:
100 Application Profiles:
0 #!/bin/sh
1 exec fenrir
0 Please report Bugs and feature requests to:
1 https://github.com/chrys87/fenrir/issues
2
3 For bugs, please provide a debug file that shows the issue.
4 How to create a debug file:
5 1. first delete old stuff:
6 sudo rm /var/log/fenrir.log
7 2. start fenrir in debug mode
8 sudo fenrir -d
9 <do your stuff>
10 3.
11 stop fenrir (fenrirKey + q)
12 the debug file is in /var/log/fenrir.log
13
14 plese be as precise as possible to make it easy to solve the problem.
0 #!/bin/env python3
1 import os, sys
2
3 # default installation
4 # core
5 # speech: speech-dispatcher
6 # sound: sox
7 # braille: brltty:
8 defaultInstallation = ['FenrirCore','vcsaDriver','brlapiDriver','evdevDriver','speechdDriver', 'genericDriver']
9 currentInstallation = []
10
11 print('checking dependencys...')
12 # CORE
13 print('')
14 print('fenrir core:')
15 available = True
16 try:
17 from daemonize import Daemonize
18 print('python3-daemonize: OK')
19 except:
20 print('python3-daemonize: FAIL')
21 available = available and False
22
23 try:
24 import enchant
25 print('pyenchant: OK')
26 except:
27 print('pyenchant: FAIL')
28 available = available and False
29
30 if available:
31 currentInstallation.append('FenrirCore')
32
33 # SCREEN
34 print('')
35 print('screen driver')
36 # VCSA (screen driver)
37 print('vcsaDriver')
38 available = True
39 try:
40 import dbus
41 print('python3-dbus: OK')
42 except:
43 print('python3-dbus: FAIL')
44 available = available and False
45 if os.path.exists('/dev/vcsa'):
46 print('VCSA Device: OK')
47 else:
48 print('VCSA Device: FAIL')
49 available = available and False
50 if available:
51 currentInstallation.append('vcsaDriver')
52
53 # BRAILLE
54 print('')
55 print('braille driver')
56 # brltty (braille driver)
57 print('brlapiDriver')
58 available = True
59 try:
60 import brlapi
61 print('python3-brlapi: OK')
62 except:
63 print('python3-brlapi: FAIL')
64 available = available and False
65
66 if available:
67 currentInstallation.append('brlapiDriver')
68 # INPUT
69 print('')
70 print('input driver')
71 # evdev (input driver)
72 print('evdevDriver')
73 available = True
74 try:
75 import evdev
76 from evdev import InputDevice, UInput
77 print('python3-evdev: OK')
78 except:
79 print('python3-evdev: FAIL')
80 available = available and False
81 try:
82 import pyudev
83 print('python3-pyudev: OK')
84 except:
85 print('python3-pyudev: FAIL')
86 available = available and False
87 if available:
88 currentInstallation.append('evdevDriver')
89 # SOUND
90 print('')
91 print('sound driver')
92 print('genericDriver (uses sox by default)')
93 available = True
94 if os.path.exists('/usr/bin/play') and os.path.exists('/usr/bin/sox'):
95 print('sox: OK')
96 else:
97 print('sox: FAIL')
98 available = available and False
99 if available:
100 currentInstallation.append('genericDriver')
101 # gstreamer (sound driver)
102 print('gstreamerDriver')
103 available = True
104 try:
105 import gi
106 print('gi: OK')
107 except:
108 print('gi: FAIL')
109 available = available and False
110 try:
111 from gi.repository import GLib
112 print('gi GLib: OK')
113 except:
114 print('gi GLib: FAIL')
115 available = available and False
116 try:
117 gi.require_version('Gst', '1.0')
118 from gi.repository import Gst
119 print('gi Gst: OK')
120 except:
121 print('gi Gst: FAIL')
122 available = available and False
123 if available:
124 currentInstallation.append('gstreamerDriver')
125
126 # SPEECH
127 print('')
128 print('speech driver')
129 # speechd (speech driver)
130 print('speechdDriver')
131 available = True
132 try:
133 import speechd
134 print('python3-speechd: OK')
135 except:
136 print('python3-speechd: FAIL')
137 available = available and False
138 if available:
139 currentInstallation.append('speechdDriver')
140 # espeak (speech driver)
141 print('espeakDriver')
142 available = True
143 try:
144 from espeak import espeak
145 print('python3-espeak: OK')
146 except:
147 print('python3-espeak: FAIL')
148 available = available and False
149 if available:
150 currentInstallation.append('espeakDriver')
151
152 # SUMMERY
153 print('')
154 available = True
155 missing = []
156 for element in defaultInstallation:
157 if not element in currentInstallation:
158 available = False
159 missing.append(element)
160 if available:
161 print('Default Setup: OK')
162 else:
163 print('Default Setup: FAIL')
164 print('Unavailable Default Modules:')
165 for e in missing:
166 print(e)
167 print('you may need to install the missing dependencys for the modules above or reconfigure fenrir to not use them')
168 print('')
169 print('Available Modules:')
170 for element in currentInstallation:
171 print(element)
172
00
1 Keymap for fenrir
1 Keymap for Fenrir
22 KEY_RESERVED
33 KEY_ESC
44 KEY_1
0 KEY_FENRIR,KEY_H=toggle_tutorial_mode
1 KEY_CTRL=shut_up
2 KEY_FENRIR,KEY_KP9=review_bottom
3 KEY_FENRIR,KEY_KP7=review_top
4 KEY_KP8=review_curr_line
5 KEY_KP7=review_prev_line
6 KEY_KP9=review_next_line
7 KEY_FENRIR,KEY_KP4=review_line_begin
8 KEY_FENRIR,KEY_KP6=review_line_end
9 KEY_FENRIR,KEY_KP1=review_line_first_char
10 KEY_FENRIR,KEY_KP3=review_line_last_char
11 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
12 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
13 KEY_KP5=review_curr_word
14 KEY_KP4=review_prev_word
15 KEY_KP6=review_next_word
16 KEY_FENRIR,KEY_SHIFT,KEY_KP5=review_curr_word_phonetic
17 KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic
18 KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic
19 KEY_KP2=review_curr_char
20 KEY_KP1=review_prev_char
21 KEY_KP3=review_next_char
22 KEY_FENRIR,KEY_SHIFT,KEY_KP2=review_curr_char_phonetic
23 KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic
24 KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic
25 KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
26 KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
27 KEY_KPDOT=cursor_position
28 KEY_FENRIR,KEY_I=indent_curr_line
29 KEY_FENRIR,KEY_KPDOT=exit_review
30 KEY_FENRIR,KEY_KP5=curr_screen
31 KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
32 KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
33 #=cursor_read_to_end_of_line
34 #=cursor_column
35 #=cursor_lineno
36 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
37 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
38 KEY_FENRIR,KEY_1=bookmark_1
39 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
40 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
41 KEY_FENRIR,KEY_2=bookmark_2
42 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
43 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
44 KEY_FENRIR,KEY_3=bookmark_3
45 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
46 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
47 KEY_FENRIR,KEY_4=bookmark_4
48 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
49 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
50 KEY_FENRIR,KEY_5=bookmark_5
51 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
52 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
53 KEY_FENRIR,KEY_6=bookmark_6
54 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
55 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
56 KEY_FENRIR,KEY_7=bookmark_7
57 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
58 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
59 KEY_FENRIR,KEY_8=bookmark_8
60 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
61 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
62 KEY_FENRIR,KEY_9=bookmark_9
63 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
64 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
65 KEY_FENRIR,KEY_0=bookmark_10
66 KEY_FENRIR,KEY_KPSLASH=set_window_application
67 2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
68 KEY_KPPLUS=last_incoming
69 KEY_FENRIR,KEY_F2=toggle_braille
70 KEY_FENRIR,KEY_F3=toggle_sound
71 KEY_FENRIR,KEY_F4=toggle_speech
72 KEY_KPENTER=temp_disable_speech
73 KEY_FENRIR,KEY_CTRL,KEY_P=toggle_punctuation_level
74 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
75 KEY_FENRIR,KEY_BACKSLASH=toggle_output
76 KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons
77 key_FENRIR,KEY_KPENTER=toggle_auto_read
78 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
79 KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking
80 KEY_FENRIR,KEY_Q=quit_fenrir
81 KEY_FENRIR,KEY_T=time
82 2,KEY_FENRIR,KEY_T=date
83 KEY_FENRIR,KEY_S=spell_check
84 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
85 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
86 KEY_FENRIR,KEY_BACKSPACE=forward_keypress
87 KEY_FENRIR,KEY_UP=inc_speech_volume
88 KEY_FENRIR,KEY_DOWN=dec_speech_volume
89 KEY_FENRIR,KEY_RIGHT=inc_speech_rate
90 KEY_FENRIR,KEY_LEFT=dec_speech_rate
91 KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
92 KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
93 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
94 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
95 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
96 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
97 KEY_FENRIR,KEY_HOME=first_clipboard
98 KEY_FENRIR,KEY_END=last_clipboard
99 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
100 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
101 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
102 KEY_FENRIR,KEY_X=set_mark
103 KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
104 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
105 KEY_FENRIR,KEY_V=paste_clipboard
0 KEY_FENRIR,KEY_H=toggle_tutorial_mode
1 KEY_CTRL=shut_up
2 KEY_FENRIR,KEY_KP9=review_bottom
3 KEY_FENRIR,KEY_KP7=review_top
4 KEY_KP8=review_curr_line
5 KEY_KP7=review_prev_line
6 KEY_KP9=review_next_line
7 KEY_FENRIR,KEY_KP4=review_line_begin
8 KEY_FENRIR,KEY_KP6=review_line_end
9 KEY_FENRIR,KEY_KP1=review_line_first_char
10 KEY_FENRIR,KEY_KP3=review_line_last_char
11 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
12 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
13 KEY_KP5=review_curr_word
14 KEY_KP4=review_prev_word
15 KEY_KP6=review_next_word
16 KEY_FENRIR,KEY_SHIFT,KEY_KP5=review_curr_word_phonetic
17 KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic
18 KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic
19 KEY_KP2=review_curr_char
20 KEY_KP1=review_prev_char
21 KEY_KP3=review_next_char
22 KEY_FENRIR,KEY_SHIFT,KEY_KP2=review_curr_char_phonetic
23 KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic
24 KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic
25 KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
26 KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
27 KEY_FENRIR,KEY_KPDOT=exit_review
28 KEY_KPDOT=cursor_position
29 KEY_FENRIR,KEY_I=indent_curr_line
30 KEY_FENRIR,KEY_KP5=curr_screen
31 KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
32 KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
33 #=cursor_read_to_end_of_line
34 #=cursor_column
35 #=cursor_lineno
36 #=braille_flush
37 #=braille_return_to_cursor
38 #=braille_pan_left
39 #=braille_pan_right
40 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
41 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
42 KEY_FENRIR,KEY_1=bookmark_1
43 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
44 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
45 KEY_FENRIR,KEY_2=bookmark_2
46 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
47 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
48 KEY_FENRIR,KEY_3=bookmark_3
49 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
50 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
51 KEY_FENRIR,KEY_4=bookmark_4
52 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
53 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
54 KEY_FENRIR,KEY_5=bookmark_5
55 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
56 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
57 KEY_FENRIR,KEY_6=bookmark_6
58 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
59 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
60 KEY_FENRIR,KEY_7=bookmark_7
61 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
62 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
63 #KEY_FENRIR,KEY_8=bookmark_8
64 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
65 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
66 KEY_FENRIR,KEY_9=bookmark_9
67 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
68 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
69 KEY_FENRIR,KEY_0=bookmark_10
70 KEY_FENRIR,KEY_KPSLASH=set_window_application
71 2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
72 KEY_KPPLUS=last_incoming
73 KEY_FENRIR,KEY_F2=toggle_braille
74 KEY_FENRIR,KEY_F3=toggle_sound
75 KEY_FENRIR,KEY_F4=toggle_speech
76 KEY_KPENTER=temp_disable_speech
77 KEY_FENRIR,KEY_CTRL,KEY_P=toggle_punctuation_level
78 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
79 KEY_FENRIR,KEY_BACKSLASH=toggle_output
80 KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons
81 key_FENRIR,KEY_KPENTER=toggle_auto_read
82 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
83 KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking
84 KEY_FENRIR,KEY_Q=quit_fenrir
85 KEY_FENRIR,KEY_T=time
86 2,KEY_FENRIR,KEY_T=date
87 KEY_KPMINUS=attribute_cursor
88 KEY_FENRIR,KEY_S=spell_check
89 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
90 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
91 KEY_FENRIR,KEY_BACKSPACE=forward_keypress
92 KEY_FENRIR,KEY_UP=inc_speech_volume
93 KEY_FENRIR,KEY_DOWN=dec_speech_volume
94 KEY_FENRIR,KEY_RIGHT=inc_speech_rate
95 KEY_FENRIR,KEY_LEFT=dec_speech_rate
96 KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
97 KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
98 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
99 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
100 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
101 KEY_FENRIR,KEY_HOME=first_clipboard
102 KEY_FENRIR,KEY_END=last_clipboard
103 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
104 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
105 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
106 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
107 KEY_FENRIR,KEY_V=paste_clipboard
108 KEY_FENRIR,KEY_F5=import_clipboard_from_file
109 KEY_FENRIR,KEY_F6=export_clipboard_to_file
110 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
111 KEY_FENRIR,KEY_X=set_mark
112 KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
113 # linux specific
114 KEY_FENRIR,KEY_F7=export_clipboard_to_x
115 KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
116 KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
0 KEY_FENRIR,KEY_H=toggle_tutorial_mode
1 KEY_CTRL=shut_up
2 KEY_FENRIR,KEY_SHIFT,KEY_O=review_bottom
3 KEY_FENRIR,KEY_SHIFT,KEY_U=review_top
4 KEY_FENRIR,KEY_I=review_curr_line
5 KEY_FENRIR,KEY_U=review_prev_line
6 KEY_FENRIR,KEY_O=review_next_line
7 KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin
8 KEY_FENRIR,KEY_SHFIT,KEY_L=review_line_end
9 KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
10 KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
11 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
12 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
13 KEY_FENRIR,KEY_K=review_curr_word
14 KEY_FENRIR,KEY_J=review_prev_word
15 KEY_FENRIR,KEY_L=review_next_word
16 2,KEY_FENRIR,KEY_K=review_curr_word_phonetic
17 2,KEY_FENRIR,KEY_J=review_prev_word_phonetic
18 2,KEY_FENRIR,KEY_L=review_next_word_phonetic
19 KEY_FENRIR,KEY_COMMA=review_curr_char
20 KEY_FENRIR,KEY_M=review_prev_char
21 KEY_FENRIR,KEY_DOT=review_next_char
22 2,KEY_FENRIR,KEY_COMMA=curr_char_phonetic
23 2,KEY_FENRIR,KEY_M=prev_char_phonetic
24 2,KEY_FENRIR,KEY_DOT=prev_char_phonetic
25 KEY_FENRIR,KEY_CTRL,KEY_I=review_up
26 KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
27 KEY_FENRIR,KEY_SLASH=exit_review
28 KEY_FENRIR,KEY_SHIFT,KEY_DOT=cursor_position
29 KEY_FENRIR,KEY_SHIFT,KEY_K=curr_screen
30 KEY_FENRIR,KEY_SHIFT,KEY_I=curr_screen_before_cursor
31 KEY_FENRIR,KEY_SHIFT,KEY_COMMA=curr_screen_after_cursor
32 #=cursor_read_to_end_of_line
33 #=cursor_column
34 #=cursor_lineno
35 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
36 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
37 KEY_FENRIR,KEY_1=bookmark_1
38 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
39 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
40 KEY_FENRIR,KEY_2=bookmark_2
41 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
42 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
43 KEY_FENRIR,KEY_3=bookmark_3
44 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
45 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
46 KEY_FENRIR,KEY_4=bookmark_4
47 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
48 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
49 KEY_FENRIR,KEY_5=bookmark_5
50 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
51 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
52 KEY_FENRIR,KEY_6=bookmark_6
53 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
54 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
55 KEY_FENRIR,KEY_7=bookmark_7
56 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
57 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
58 KEY_FENRIR,KEY_8=bookmark_8
59 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
60 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
61 KEY_FENRIR,KEY_9=bookmark_9
62 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
63 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
64 KEY_FENRIR,KEY_0=bookmark_10
65 KEY_FENRIR,KEY_CTRL,KEY_8=set_window_application
66 2,KEY_FENRIR,KEY_CTRL,KEY_8=clear_window_application
67 2,KEY_FENRIR,KEY_I=indent_curr_line
68 KEY_FENRIR,KEY_SEMICOLON=last_incoming
69 KEY_FENRIR,KEY_F2=toggle_braille
70 KEY_FENRIR,KEY_F3=toggle_sound
71 KEY_FENRIR,KEY_F4=toggle_speech
72 KEY_FENRIR,KEY_ENTER=temp_disable_speech
73 KEY_FENRIR,KEY_SHIFT,KEY_CTRL,KEY_P=toggle_punctuation_level
74 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
75 KEY_FENRIR,KEY_SHIFT,KEY_ENTER=toggle_output
76 KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons
77 KEY_FENRIR,KEY_ENTER=toggle_auto_read
78 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
79 KEY_FENRIR,KEY_Y=toggle_highlight_tracking
80 KEY_FENRIR,KEY_Q=quit_fenrir
81 KEY_FENRIR,KEY_T=time
82 2,KEY_FENRIR,KEY_T=date
83 KEY_FENRIR,KEY_S=spell_check
84 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
85 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
86 KEY_FENRIR,KEY_BACKSPACE=forward_keypress
87 KEY_FENRIR,KEY_UP=inc_speech_volume
88 KEY_FENRIR,KEY_DOWN=dec_speech_volume
89 KEY_FENRIR,KEY_RIGHT=inc_speech_rate
90 KEY_FENRIR,KEY_LEFT=dec_speech_rate
91 KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
92 KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
93 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
94 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
95 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
96 KEY_FENRIR,KEY_CTRL,KEY_SHIFT<KEY_X=remove_marks
97 KEY_FENRIR,KEY_HOME=first_clipboard
98 KEY_FENRIR,KEY_END=last_clipboard
99 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
100 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
101 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
102 KEY_FENRIR,KEY_X=set_mark
103 KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
104 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
105 KEY_FENRIR,KEY_V=paste_clipboard
0 KEY_FENRIR,KEY_H=toggle_tutorial_mode
1 KEY_CTRL=shut_up
2 KEY_FENRIR,KEY_SHIFT,KEY_O=review_bottom
3 KEY_FENRIR,KEY_SHIFT,KEY_U=review_top
4 KEY_FENRIR,KEY_I=review_curr_line
5 KEY_FENRIR,KEY_U=review_prev_line
6 KEY_FENRIR,KEY_O=review_next_line
7 KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin
8 KEY_FENRIR,KEY_SHFIT,KEY_L=review_line_end
9 KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
10 KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
11 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
12 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
13 KEY_FENRIR,KEY_K=review_curr_word
14 KEY_FENRIR,KEY_J=review_prev_word
15 KEY_FENRIR,KEY_L=review_next_word
16 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_K=review_curr_word_phonetic
17 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_J=review_prev_word_phonetic
18 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_L=review_next_word_phonetic
19 KEY_FENRIR,KEY_COMMA=review_curr_char
20 KEY_FENRIR,KEY_M=review_prev_char
21 KEY_FENRIR,KEY_DOT=review_next_char
22 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_COMMA=curr_char_phonetic
23 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_M=prev_char_phonetic
24 KEY_FENRIR,KEY_ALT,KEY_CTRL,KEY_DOT=prev_char_phonetic
25 KEY_FENRIR,KEY_CTRL,KEY_I=review_up
26 KEY_FENRIR,KEY_CTRL,KEY_COMMA=review_down
27 KEY_FENRIR,KEY_SLASH=exit_review
28 KEY_FENRIR,KEY_SHIFT,KEY_DOT=cursor_position
29 2,KEY_FENRIR,KEY_I=indent_curr_line
30 KEY_FENRIR,KEY_SHIFT,KEY_K=curr_screen
31 KEY_FENRIR,KEY_SHIFT,KEY_I=curr_screen_before_cursor
32 KEY_FENRIR,KEY_SHIFT,KEY_COMMA=curr_screen_after_cursor
33 #=cursor_read_to_end_of_line
34 #=cursor_column
35 #=cursor_lineno
36 #=braille_flush
37 #=braille_return_to_cursor
38 #=braille_pan_left
39 #=braille_pan_right
40 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
41 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
42 KEY_FENRIR,KEY_1=bookmark_1
43 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
44 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
45 KEY_FENRIR,KEY_2=bookmark_2
46 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
47 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
48 KEY_FENRIR,KEY_3=bookmark_3
49 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
50 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
51 KEY_FENRIR,KEY_4=bookmark_4
52 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
53 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
54 KEY_FENRIR,KEY_5=bookmark_5
55 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
56 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
57 KEY_FENRIR,KEY_6=bookmark_6
58 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
59 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
60 KEY_FENRIR,KEY_7=bookmark_7
61 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
62 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
63 KEY_FENRIR,KEY_8=bookmark_8
64 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
65 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
66 KEY_FENRIR,KEY_9=bookmark_9
67 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
68 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
69 KEY_FENRIR,KEY_0=bookmark_10
70 KEY_FENRIR,KEY_CTRL,KEY_8=set_window_application
71 2,KEY_FENRIR,KEY_CTRL,KEY_8=clear_window_application
72 KEY_FENRIR,KEY_SEMICOLON=last_incoming
73 KEY_FENRIR,KEY_F2=toggle_braille
74 KEY_FENRIR,KEY_F3=toggle_sound
75 KEY_FENRIR,KEY_F4=toggle_speech
76 KEY_FENRIR,KEY_ENTER=temp_disable_speech
77 KEY_FENRIR,KEY_SHIFT,KEY_CTRL,KEY_P=toggle_punctuation_level
78 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
79 KEY_FENRIR,KEY_SHIFT,KEY_ENTER=toggle_output
80 KEY_FENRIR,KEY_SHIFT,KEY_E=toggle_emoticons
81 KEY_FENRIR,KEY_ENTER=toggle_auto_read
82 KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
83 KEY_FENRIR,KEY_Y=toggle_highlight_tracking
84 KEY_FENRIR,KEY_Q=quit_fenrir
85 KEY_FENRIR,KEY_T=time
86 2,KEY_FENRIR,KEY_T=date
87 KEY_FENRIR<KEY_MINUS=attribute_cursor
88 KEY_FENRIR,KEY_S=spell_check
89 2,KEY_FENRIR,KEY_S=add_word_to_spell_check
90 KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
91 KEY_FENRIR,KEY_BACKSPACE=forward_keypress
92 KEY_FENRIR,KEY_UP=inc_speech_volume
93 KEY_FENRIR,KEY_DOWN=dec_speech_volume
94 KEY_FENRIR,KEY_RIGHT=inc_speech_rate
95 KEY_FENRIR,KEY_LEFT=dec_speech_rate
96 KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
97 KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
98 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
99 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
100 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
101 KEY_FENRIR,KEY_HOME=first_clipboard
102 KEY_FENRIR,KEY_END=last_clipboard
103 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
104 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
105 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
106 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
107 KEY_FENRIR,KEY_V=paste_clipboard
108 KEY_FENRIR,KEY_F5=import_clipboard_from_file
109 KEY_FENRIR,KEY_F6=export_clipboard_to_file
110 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
111 KEY_FENRIR,KEY_X=set_mark
112 KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
113 # linux specific
114 KEY_FENRIR,KEY_F7=export_clipboard_to_x
115 KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
116 KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
+0
-105
config/keyboard/test.conf less more
0 KEY_FENRIR,KEY_H=toggle_tutorial_mode
1 KEY_CTRL=shut_up
2 KEY_FENRIR,KEY_KP9=review_bottom
3 KEY_FENRIR,KEY_KP7=review_top
4 KEY_KP8=review_curr_line
5 KEY_KP7=review_prev_line
6 KEY_KP9=review_next_line
7 KEY_FENRIR,KEY_KP4=review_line_begin
8 KEY_FENRIR,KEY_KP6=review_line_end
9 KEY_FENRIR,KEY_KP1=review_line_first_char
10 KEY_FENRIR,KEY_KP3=review_line_last_char
11 KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
12 KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
13 #KEY_KP5=review_curr_word
14 #KEY_KP4=review_prev_word
15 #KEY_KP6=review_next_word
16 KEY_KP5=review_curr_word_phonetic
17 KEY_KP4=review_prev_word_phonetic
18 KEY_KP6=review_next_word_phonetic
19 #KEY_KP2=review_curr_char
20 #KEY_KP1=review_prev_char
21 #KEY_KP3=review_next_char
22 #KEY_KP2=review_curr_char_phonetic
23 #KEY_KP1=review_prev_char_phonetic
24 #KEY_KP3=review_next_char_phonetic
25 #=review_up
26 #=review_down
27 KEY_KPDOT=cursor_position
28 KEY_FENRIR,KEY_I=indent_curr_line
29 KEY_FENRIR,KEY_KPDOT=exit_review
30 KEY_FENRIR,KEY_KP5=curr_screen
31 #KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
32 #KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
33 #=cursor_read_to_end_of_line
34 KEY_FENRIR,KEY_KP2=cursor_column
35 KEY_FENRIR,KEY_KP8=cursor_lineno
36 KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
37 KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
38 KEY_FENRIR,KEY_1=bookmark_1
39 KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
40 KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
41 KEY_FENRIR,KEY_2=bookmark_2
42 KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
43 KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
44 KEY_FENRIR,KEY_3=bookmark_3
45 KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
46 KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
47 KEY_FENRIR,KEY_4=bookmark_4
48 KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
49 KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
50 KEY_FENRIR,KEY_5=bookmark_5
51 KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
52 KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
53 KEY_FENRIR,KEY_6=bookmark_6
54 KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
55 KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
56 KEY_FENRIR,KEY_7=bookmark_7
57 KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
58 KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
59 KEY_FENRIR,KEY_8=bookmark_8
60 KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
61 KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
62 KEY_FENRIR,KEY_9=bookmark_9
63 KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
64 KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
65 KEY_FENRIR,KEY_0=bookmark_10
66 KEY_FENRIR,KEY_KPSLASH=set_window_application
67 2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
68 KEY_KPPLUS=last_incoming
69 KEY_FENRIR,KEY_F2=toggle_braille
70 KEY_FENRIR,KEY_F3=toggle_sound
71 #=toggle_speech
72 KEY_FENRIR,KEY_F4=temp_disable_speech
73 KEY_FENRIR,KEY_CTRL,KEY_P=toggle_punctuation_level
74 KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
75 KEY_FENRIR,KEY_BACKSLASH=toggle_output
76 #=toggle_emoticons
77 key_FENRIR,KEY_KPENTER=toggle_auto_read
78 #=toggle_auto_time
79 #=toggle_highlight_tracking
80 KEY_FENRIR,KEY_Q=quit_fenrir
81 KEY_FENRIR,KEY_T=time
82 2,KEY_FENRIR,KEY_T=date
83 KEY_KP1=add_word_to_spell_check
84 KEY_KP2=remove_word_from_spell_check
85 KEY_FENRIR,KEY_BACKSPACE=forward_keypress
86 KEY_FENRIR,KEY_UP=inc_speech_volume
87 KEY_FENRIR,KEY_DOWN=dec_speech_volume
88 KEY_FENRIR,KEY_RIGHT=inc_speech_rate
89 KEY_FENRIR,KEY_LEFT=dec_speech_rate
90 KEY_FENRIR,KEY_ALT,KEY_RIGHT=inc_speech_pitch
91 KEY_FENRIR,KEY_ALT,KEY_LEFT=dec_speech_pitch
92 KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
93 KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
94 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
95 KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
96 KEY_FENRIR,KEY_HOME=first_clipboard
97 KEY_FENRIR,KEY_END=last_clipboard
98 KEY_FENRIR,KEY_PAGEUP=prev_clipboard
99 KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
100 KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
101 KEY_FENRIR,KEY_X=set_mark
102 KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
103 KEY_FENRIR,KEY_C=copy_marked_to_clipboard
104 KEY_FENRIR,KEY_V=paste_clipboard
0 # how to use this file?
1 # the # on the beginning of the line is a comment
2 # the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
3 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
4 [levelDict]
5 none:===:
6 some:===:.-$~+*-/\@
7 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
8 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
9
10 [punctDict]
11 :===:Leer
12 &:===:Und
13 ':===:Apostroph
14 @:===:At
15 \:===:Backslash
16 |:===:Pipe
17 !:===:Ausrufezeichen
18 ^:===:Hoch
19 ::===:Doppelpunkt
20 ,:===:Komma
21 -:===:Minus
22 $:===:Dollar
23 .:===:Punkt
24 >:===:Größer als
25 `:===:Grave
26 #:===:Hash
27 {:===:Geschweifte Klammer auf
28 [:===:eckige Klammer auf
29 (:===:Klammer auf
30 <:===:Kleiner als
31 %:===:Prozent
32 +:===:Plus
33 ?:===:Fragezeichen?
34 ":===:Gänsefüßchen
35 ):===:Klammer zu
36 }:===:Geschweifte Klammer zu
37 ]:===:Eckige Klammer zu
38 ;:===:Semikolon
39 /:===:Geteilt durch
40 *:===:Mal
41 ~:===:Tilde
42 _:===:Lienie unten
43 =:===:Istgleich
44
45 [customDict]
46
47 [emoticonDict]
48 :):===:Grins
49 ;):===:Zwinker
50 XD:===:loool
51 :D:===:Lach
52 <{-.-}>:===:Raves
33 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
44 [levelDict]
55 none:===:
6 some:===:.-$~+*-/\@
6 some:===:-$~+*-/\@
77 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
88 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
99
4646
4747 [emoticonDict]
4848 :):===:smile
49 ;):===:twinker
50 XD:===:loool
51 :D:===:lought
49 ;):===:wink
50 XD:===:LOL
51 :D:===:laugh
52 <{-.-}>:===:Raves
53 \o/:===:Hurray
0 # how to use this file?
1 # the # on the beginning of the line is a comment
2 # the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
3 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
4 [levelDict]
5 none:===:
6 some:===:-$~+*-/\@
7 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
8 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
9
10 [punctDict]
11 :===:space
12 &:===:and
13 ':===:apostrophe
14 @:===:at
15 \:===:backslash
16 |:===:bar
17 !:===:bang
18 ^:===:carrot
19 ::===:colon
20 ,:===:comma
21 -:===:dash
22 $:===:dollar
23 .:===:dot
24 >:===:greater
25 `:===:grave
26 #:===:hash
27 {:===:left brace
28 [:===:left bracket
29 (:===:left paren
30 <:===:less
31 %:===:percent
32 +:===:plus
33 ?:===:question?
34 ":===:quote
35 ):===:right paren
36 }:===:right brace
37 ]:===:right bracket
38 ;:===:semicolon
39 /:===:slash
40 *:===:star
41 ~:===:tilde
42 _:===:line
43 =:===:equals
44
45 [customDict]
46
47 [emoticonDict]
48 :):===:smile
49 ;):===:twinker
50 XD:===:loool
51 :D:===:lought
52 <{-.-}>:===:Raves
0 # how to use this file?
1 # the # on the beginning of the line is a comment
2 # the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
3 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
4 [levelDict]
5 none:===:
6 some:===:.-$~+*-/\@
7 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
8 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
9
10 [punctDict]
11 :===:espacio
12 &:===:et
13 ':===:apóstrofo
14 @:===:arroba
15 \:===:barra inversa
16 |:===:barra vertical
17 !:===:Cerrar exclamación
18 ^:===:circumplejo
19 ::===:dos puntos
20 ,:===:coma
21 -:===:guion
22 $:===:dólar
23 .:===:punto
24 >:===:mayor que
25 `:===:grave
26 #:===:signo de número
27 {:===:abrir yave
28 [:===:abrir corchete
29 (:===:abrir paréntesis
30 <:===:menor que
31 %:===:porciento
32 +:===:más
33 ?:===:cerrar interrogación?
34 ":===:comillas
35 ):===:cerrar paréntesis
36 }:===:cerrar yave
37 ]:===:cerrar corchete
38 ;:===:punto y coma
39 /:===:barra
40 *:===:asterisco
41 ~:===:tilde
42 _:===:subrayado
43 =:===:igual
44
45 [customDict]
46
47 [emoticonDict]
48 :):===:sonrisa
49 ;):===:twinker
50 XD:===:loool
51 :D:===:lought
52 <{-.-}>:===:Raves
0 # how to use this file?
1 # the # on the beginning of the line is a comment
2 # the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
3 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
4 [levelDict]
5 none:===:
6 some:===:.-$~+*-/\@
7 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
8 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
9
10 [punctDict]
11 :===:espace
12 &:===:et
13 ':===:apostrophe
14 @:===:arobase
15 \:===:barre oblique inversée
16 |:===:barre verticale
17 !:===:point d'exclamation
18 ^:===:accent circonflexe
19 ::===:deux points
20 ,:===:virgule
21 -:===:tiret
22 $:===:dollar
23 .:===:point
24 >:===:suppérieur à
25 `:===:accent grave
26 #:===:dièse
27 {:===:accolade ouvrante
28 [:===:crochet ouvrant
29 (:===:parenthèse ouvrante
30 <:===:inférieur à
31 %:===:pourcent
32 +:===:plus
33 ?:===:point d'interrogation
34 ":===:guillemet
35 ):===:parenthèse fermante
36 }:===:accolade fermante
37 ]:===:crochet fermant
38 ;:===:point virgule
39 /:===:barre oblique
40 *:===:astérisque
41 ~:===:tildé
42 _:===:souligné
43 =:===:égale à
44
45 [customDict]
46
47 [emoticonDict]
48 :):===:sourire
49 ;):===:clin d'oeil
50 XD:===:explosé de rire
51 :D:===:rire
52 <{-.-}>:===:Raves
0 # how to use this file?
1 # the # on the beginning of the line is a comment
2 # the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
3 # the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
4 [levelDict]
5 none:===:
6 some:===:.-$~+*-/\@
7 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
8 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
9
10 [punctDict]
11 :===:spacja
12 &:===:ampersant
13 ':===:apostrof
14 @:===:małpa
15 \:===:bekslesz
16 |:===:pionowa kreska
17 !:===:wykrzyknik
18 ^:===:daszek
19 ::===:dwukropek
20 ,:===:przecinek
21 -:===:myślnik
22 $:===:dolar
23 .:===:kropka
24 >:===:większe
25 `:===:akcent
26 #:===:hasz
27 {:===:lewa klamra
28 [:===:lewy nawias kwadratowy
29 (:===:lewy nawias
30 <:===:mniejsze
31 %:===:procent
32 +:===:plus
33 ?:===:pytajnik
34 ":===:cudzysłów
35 ):===:prawy nawias
36 }:===:prawa klamra
37 ]:===:prawy nawias kwadratowy
38 ;:===:średnik
39 /:===:slesz
40 *:===:gwiazdka
41 ~:===:tylda
42 _:===:podkreślnik
43 =:===:równa się
44
45 [customDict]
46
47 [emoticonDict]
48 :):===:smile
49 ;):===:twinker
50 XD:===:loool
51 :D:===:lought
52 <{-.-}>:===:Raves
33
44 # Select the driver used to play sounds, choices are generic and gstreamer.
55 # Sox is the default.
6 driver=generic
7
8 # Sound themes. This is the pack of sounds used for sound alerts.
6 driver=genericDriver
7
8 # Sound themes. These are the pack of sounds used for sound alerts.
99 # Sound packs may be located at /usr/share/sounds
1010 # For system wide availability, or ~/.local/share/fenrir/sounds
1111 # For the current user.
12 theme=default
12 theme=default-wav
1313
1414 # Sound volume controls how loud the sounds for your chosen soundpack are.
1515 # 0 is quietest, 1.0 is loudest.
2323 # fenrirDuration = the duration of the frequence
2424 # the following command is used for play a soundfile
2525 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile 2>/dev/null
26 #the following command is used for generating a frequence beep
26 #the following command is used for generating a frequency beep
2727 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence 2>/dev/null
2828
2929 [speech]
3030 # Turn speech on or off:
3131 enabled=True
3232
33 # Select speech driver, options are speechd (default) or espeak:
34 #driver=speechd
35 driver=espeak
36
37
38 # The rate selects how fast fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
33 # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
34 #driver=speechdDriver
35 #driver=genericDriver
36 driver=espeakDriver
37
38 # server path for emacspeak
39 serverPath=
40
41 # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
3942 rate=0.35
4043
4144 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
4649 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
4750 volume=1.0
4851
49 # Module is used for speech-dispatcher, to select the speech module you want to use.
50 # Consult speech-dispatcher's configuration and help ti find out which modules are available.
51 # The default is espeak.
52 # Module is used for Speech-dispatcher, to select the speech module you want to use.
53 # Consult Speech-dispatcher's configuration and help ti find out which modules are available.
54 # The default is Espeak.
5255 module=espeak
5356
54 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak,
55 # or if using the espeak module in speech-dispatcher. To find out which voices are available, consult the documentation provided with your chosen synthesizer.
57 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
58 # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
5659 voice=f3
5760
58 # Select the language you want fenrir to use.
61 # Select the language you want Fenrir to use.
5962 language=en_US
6063
6164 # Read new text as it happens?
6265 autoReadIncoming=True
6366
67 # genericSpeechCommand is the command that is executed for talking
68 # the following variables are replaced with values
69 # fenrirText = is the text that should be spoken
70 # fenrirModule = may be the speech module used in Speech-dispatcher, not every TTY needs this
71 # fenrirLanguage = the language
72 # fenrirVoice = is the current voice that should be used
73 # the current volume, pitch and rate is calculated like this
74 # value = min + settingValue * (min - max )
75 # fenrirVolume = is replaced with the current volume
76 # fenrirPitch = is replaced with the current pitch
77 # fenrirRate = is replaced with the current speed (speech rate)
78 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
79
80 # these are the minimum and maximum values of the TTS system used in genericSpeechCommand
81 fenrirMinVolume=0
82 fenrirMaxVolume=200
83 fenrirMinPitch=0
84 fenrirMaxPitch=99
85 fenrirMinRate=80
86 fenrirMaxRate=450
87
6488 [braille]
65 #braille is not implemented yet
6689 enabled=False
67 driver=brlapi
90 driver=dummyDriver
6891 layout=en
92 # to what should the flush timeout relate to
93 # word = flush after (number of words to display) * seconds
94 # char = flush after (number of chars to display) * seconds
95 # fix = flush after X seconds
96 # none = no automatic flush (manual via shortcut)
97 flushMode=word
98 # seconds to flush or
99 # -1 = no automatic flush (manual via shortcut)
100 flushTimeout=3
101 # how should the cursor be focused?
102 # page = if cursor cross the border move to next page and start at beginn
103 # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
104 cursorFocusMode=page
105 # define the cell on the Braille device where fenrir should scroll and keep the cursor
106 # 0 = first cell on device
107 # -1 = last cell on device
108 # >0 = fix cell number
109 fixCursorOnCell=-1
110 #How should the braille follow the focus
111 # none = no automatic toggle command used
112 # review = priority to review
113 # last = follow last used cursor
114 cursorFollowMode=review
115 # number of cells in panning (horizontal)
116 # 0 = display size, >0 number of cells
117 panSizeHorizontal=0
69118
70119 [screen]
71 driver=vcsa
72 encoding=UTF-8
120 driver=vcsaDriver
121 encoding=auto
73122 screenUpdateDelay=0.05
74123 suspendingScreen=
75124 autodetectSuspendingScreen=True
76125
77126 [keyboard]
78 driver=evdev
127 driver=evdevDriver
79128 # filter input devices NOMICE, ALL or a DEVICE NAME
80129 device=ALL
81 # gives fenrir exclusive access to the keyboard and let consume keystrokes.
130 # gives Fenrir exclusive access to the keyboard and let consume keystrokes.
82131 grabDevices=True
83132 ignoreShortcuts=False
84133 # the current shortcut layout located in /etc/fenrir/keyboard
98147
99148 [general]
100149 debugLevel=0
150 debugMode=File
101151 punctuationProfile=default
102152 punctuationLevel=some
103153 respectPunctuationPause=True
104154 newLinePause=True
105155 numberOfClipboards=10
156 # used path for "export_clipboard_to_file"
157 # $user is replaced by username
158 clipboardExportPath=/tmp/fenrirClipboard
106159 emoticons=True
107 # define the current fenrir key
160 # define the current Fenrir key
108161 fenrirKeys=KEY_KP0,KEY_META
109162 scriptKey=KEY_COMPOSE
110163 timeFormat=%H:%M:%P
112165 autoSpellCheck=True
113166 spellCheckLanguage=en_US
114167 scriptPath=/usr/share/fenrir/scripts
168 commandPath=
169 #fenrirBGColor = the backgroundcolor
170 #fenrirFGColor = the foregroundcolor
171 #fenrirUnderline = speak the underline attribute
172 #fenrirBold = speak the bold attribute
173 #fenrirBlink = speak the blink attribute
174 #fenrirFont = the font
175 #fenrirFontSize = the fontsize
176 attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
115177
116178 [focus]
117179 cursor=True
120182 [review]
121183 lineBreak=True
122184 endOfScreen=True
185 # leave the review when pressing a key
186 leaveReviewOnCursorChange=True
187 # leave the review when changing the screen
188 leaveReviewOnScreenChange=True
123189
124190 [promote]
125191 enabled=True
0 [sound]
1 # Turn sound on or off:
2 enabled=True
3
4 # Select the driver used to play sounds, choices are generic and gstreamer.
5 # Sox is the default.
6 #driver=gstreamer
7 driver=generic
8
9 # Sound themes. This is the pack of sounds used for sound alerts.
10 # Sound packs may be located at /usr/share/sounds
11 # For system wide availability, or ~/.local/share/fenrir/sounds
12 # For the current user.
13 theme=default
14
15 # Sound volume controls how loud the sounds for your chosen soundpack are.
16 # 0 is quietest, 1.0 is loudest.
17 volume=1.0
18
19 # shell commands for generic sound driver
20 # the folowing variable are substituded
21 # fenrirVolume = the current volume setting
22 # fenrirSoundFile = the soundfile for an soundicon
23 # fenrirFrequence = the frequence to play
24 # fenrirDuration = the duration of the frequence
25 # the following command is used for play a soundfile
26 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
27 #the following command is used for generating a frequence beep
28 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
29
30 [speech]
31 # Turn speech on or off:
32 enabled=True
33
34 # Select speech driver, options are speechd (default) or espeak:
35 driver=speechd
36 #driver=espeak
37
38
39 # The rate selects how fast fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
40 rate=0.65
41
42 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
43 pitch=0.5
44 # Pitch for capital letters
45 capitalPitch=0.9
46
47 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
48 volume=1.0
49
50 # Module is used for speech-dispatcher, to select the speech module you want to use.
51 # Consult speech-dispatcher's configuration and help ti find out which modules are available.
52 # The default is espeak.
53 module=espeak
54
55 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak,
56 # or if using the espeak module in speech-dispatcher. To find out which voices are available, consult the documentation provided with your chosen synthesizer.
57 voice=
58
59 # Select the language you want fenrir to use.
60 language=english-us
61
62 # Read new text as it happens?
63 autoReadIncoming=True
64
65 [braille]
66 #braille is not implemented yet
67 enabled=False
68 driver=brlapi
69 layout=en
70
71 [screen]
72 driver=vcsa
73 encoding=cp850
74 screenUpdateDelay=0.05
75 suspendingScreen=
76 autodetectSuspendingScreen=True
77
78 [keyboard]
79 driver=evdev
80 # filter input devices NOMICE, ALL or a DEVICE NAME
81 device=ALL
82 # gives fenrir exclusive access to the keyboard and let consume keystrokes.
83 grabDevices=True
84 ignoreShortcuts=False
85 # the current shortcut layout located in /etc/fenrir/keyboard
86 keyboardLayout=desktop
87 # echo chars while typing.
88 charEcho=False
89 # echo deleted chars
90 charDeleteEcho=True
91 # echo word after pressing space
92 wordEcho=False
93 # interrupt speech on any keypress
94 interruptOnKeyPress=False
95 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
96 interruptOnKeyPressFilter=
97 # timeout for double tap in sec
98 doubleTapTimeout=0.2
99
100 [general]
101 debugLevel=1
102 punctuationProfile=default
103 punctuationLevel=some
104 respectPunctuationPause=True
105 newLinePause=True
106 numberOfClipboards=10
107 emoticons=True
108 # define the current fenrir key
109 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
110 scriptKey=KEY_COMPOSE
111 timeFormat=%H:%M:%P
112 dateFormat=%A, %B %d, %Y
113 autoSpellCheck=True
114 spellCheckLanguage=en_US
115 scriptPath=/usr/share/fenrir/scripts
116
117 [focus]
118 #follow the text cursor
119 cursor=True
120 #follow highlighted text changes
121 highlight=False
122
123 [review]
124 lineBreak=True
125 endOfScreen=True
126
127 [promote]
128 enabled=True
129 inactiveTimeoutSec=120
130 list=
131
132 [time]
133 # automatic time anouncement
134 enabled=False
135 # present time
136 presentTime=True
137 # present date (on change)
138 presentDate=True
139 # present time after a given period of seconds
140 delaySec=0
141 # present time after to given minutes example every 15 minutes: 00,15,30,45
142 # if delaySec is >0 onMinutes is ignored
143 onMinutes=00,30
144 # announce via soundicon (not interrupting)
145 announce=True
146 # interrupt current speech for time announcement
147 interrupt=False
0 [sound]
1 # Turn sound on or off:
2 enabled=True
3
4 # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
5 # Sox is the default.
6 #driver=gstreamerDriver
7 driver=genericDriver
8
9 # Sound themes. These are the pack of sounds used for sound alerts.
10 # Sound packs may be located at /usr/share/sounds
11 # For system wide availability, or ~/.local/share/fenrir/sounds
12 # For the current user.
13 theme=default-wav
14
15 # Sound volume controls how loud the sounds for your selected soundpack are.
16 # 0 is quietest, 1.0 is loudest.
17 volume=1.0
18
19 # shell commands for generic sound driver
20 # the folowing variable are substituted
21 # fenrirVolume = the current volume setting
22 # fenrirSoundFile = the soundfile for an soundicon
23 # fenrirFrequence = the frequency to play
24 # fenrirDuration = the duration of the frequency
25 # the following command is used to play a soundfile
26 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
27 #the following command is used to generate a frequency beep
28 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
29
30 [speech]
31 # Turn speech on or off:
32 enabled=True
33
34 # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
35 driver=speechdDriver
36 #driver=espeakDriver
37 #driver=genericDriver
38
39 # server path for emacspeak
40 serverPath=/home/chrys/Projekte/emacspeak/servers/espeak
41
42 # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
43 rate=0.65
44
45 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
46 pitch=0.5
47 # Pitch for capital letters
48 capitalPitch=0.9
49
50 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
51 volume=1.0
52
53 # Module is used for Speech-dispatcher, to select the speech module you want to use.
54 # Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available.
55 # The default is espeak.
56 module=espeak
57
58 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
59 # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
60 # This also sets the voice used in the generic driver.
61 voice=
62
63 # Select the language you want Fenrir to use.
64 language=english-us
65
66 # Read new text as it happens?
67 autoReadIncoming=True
68
69 # genericSpeechCommand is the command that is executed for talking
70 # the following variables are replaced with values
71 # fenrirText = is the text that should be spoken
72 # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this
73 # fenrirLanguage = the language
74 # fenrirVoice = is the current voice that should be used. Set the voice variable above.
75 # the current volume, pitch and rate is calculated like this
76 # value = min + settingValue * (min - max )
77 # fenrirVolume = is replaced with the current volume
78 # fenrirPitch = is replaced with the current pitch
79 # fenrirRate = is replaced with the current speed (speech rate)
80 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
81
82 # those are the min and max values of the TTS system that is used in genericSpeechCommand
83 fenrirMinVolume=0
84 fenrirMaxVolume=200
85 fenrirMinPitch=0
86 fenrirMaxPitch=99
87 fenrirMinRate=80
88 fenrirMaxRate=450
89
90 [braille]
91 enabled=False
92 driver=dummyDriver
93 layout=en
94 # to what should the flush timeout relate to
95 # word = flush after (number of words to display) * seconds
96 # char = flush after (number of chars to display) * seconds
97 # fix = flush after X seconds
98 # none = no automatic flush (manual via shortcut)
99 flushMode=word
100 # seconds to flush or
101 # -1 = no automatic flush (manual via shortcut)
102 flushTimeout=3
103 # how should the cursor be focused?
104 # page = if cursor cross the border move to next page and start at beginn
105 # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
106 cursorFocusMode=page
107 # define the cell on the Braille device where fenrir should scroll and keep the cursor
108 # 0 = first cell on device
109 # -1 = last cell on device
110 # >0 = fix cell number
111 fixCursorOnCell=-1
112 #How should the braille follow the focus
113 # none = no automatic toggle command used
114 # review = priority to review
115 # last = follow last used cursor
116 cursorFollowMode=review
117 # number of cells in panning (horizontal)
118 # 0 = display size, >0 number of cells
119 panSizeHorizontal=0
120
121 [screen]
122 driver=vcsaDriver
123 encoding=auto
124 screenUpdateDelay=0.05
125 suspendingScreen=
126 autodetectSuspendingScreen=True
127
128 [keyboard]
129 driver=evdevDriver
130 # filter input devices NOMICE, ALL or a DEVICE NAME
131 device=ALL
132 # gives Fenrir exclusive access to the keyboard and lets it control keystrokes.
133 grabDevices=True
134 ignoreShortcuts=False
135 # the current shortcut layout located in /etc/fenrir/keyboard
136 keyboardLayout=desktop
137 # echo chars while typing.
138 charEcho=False
139 # echo deleted chars
140 charDeleteEcho=True
141 # echo word after pressing space
142 wordEcho=False
143 # interrupt speech on any keypress
144 interruptOnKeyPress=False
145 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
146 interruptOnKeyPressFilter=
147 # timeout for double tap in sec
148 doubleTapTimeout=0.2
149
150 [general]
151 debugLevel=0
152 # debugMode sets where the debug output should send to:
153 # debugMode=File writes to /var/log/fenrir.log
154 # debugMode=Print just prints on the screen
155 debugMode=File
156 punctuationProfile=default
157 punctuationLevel=some
158 respectPunctuationPause=True
159 newLinePause=True
160 numberOfClipboards=10
161 # used path for "export_clipboard_to_file"
162 # $user is replaced by username
163 #clipboardExportPath=/home/$user/fenrirClipboard
164 clipboardExportPath=/tmp/fenrirClipboard
165 emoticons=True
166 # define the current Fenrir key
167 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
168 scriptKey=KEY_COMPOSE
169 timeFormat=%H:%M:%P
170 dateFormat=%A, %B %d, %Y
171 autoSpellCheck=True
172 spellCheckLanguage=en_US
173 # path for your scripts "scriptKey" functionality
174 scriptPath=/usr/share/fenrir/scripts
175 # overload commands, and create new one without changing Fenrir default
176 commandPath=
177 #fenrirBGColor = the backgroundcolor
178 #fenrirFGColor = the foregroundcolor
179 #fenrirUnderline = speak the underline attribute
180 #fenrirBold = speak the bold attribute
181 #fenrirBlink = speak the blink attribute
182 #fenrirFont = the font
183 #fenrirFontSize = the fontsize
184 attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
185
186 [focus]
187 #follow the text cursor
188 cursor=True
189 #follow highlighted text changes
190 highlight=False
191
192 [review]
193 lineBreak=True
194 endOfScreen=True
195 # leave the review when pressing a key
196 leaveReviewOnCursorChange=True
197 # leave the review when changing the screen
198 leaveReviewOnScreenChange=True
199
200 [promote]
201 enabled=True
202 inactiveTimeoutSec=120
203 list=
204
205 [time]
206 # automatic time anouncement
207 enabled=False
208 # present time
209 presentTime=True
210 # present date (on change)
211 presentDate=True
212 # present time after a given period of seconds
213 delaySec=0
214 # present time after to given minutes example every 15 minutes: 00,15,30,45
215 # if delaySec is >0 onMinutes is ignored
216 onMinutes=00,30
217 # announce via soundicon (not interrupting)
218 announce=True
219 # interrupt current speech for time announcement
220 interrupt=False
+0
-147
config/settings/settings.conf.chrys less more
0 [sound]
1 # Turn sound on or off:
2 enabled=True
3
4 # Select the driver used to play sounds, choices are generic and gstreamer.
5 # Sox is the default.
6 driver=generic
7
8 # Sound themes. This is the pack of sounds used for sound alerts.
9 # Sound packs may be located at /usr/share/sounds
10 # For system wide availability, or ~/.local/share/fenrir/sounds
11 # For the current user.
12 theme=default
13
14 # Sound volume controls how loud the sounds for your chosen soundpack are.
15 # 0 is quietest, 1.0 is loudest.
16 volume=1.0
17
18 # shell commands for generic sound driver
19 # the folowing variable are substituded
20 # fenrirVolume = the current volume setting
21 # fenrirSoundFile = the soundfile for an soundicon
22 # fenrirFrequence = the frequence to play
23 # fenrirDuration = the duration of the frequence
24 # the following command is used for play a soundfile
25 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
26 #the following command is used for generating a frequence beep
27 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
28
29 [speech]
30 # Turn speech on or off:
31 enabled=True
32
33 # Select speech driver, options are speechd (default) or espeak:
34 driver=speechd
35 #driver=espeak
36
37
38 # The rate selects how fast fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
39 rate=0.65
40
41 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
42 pitch=0.5
43 # Pitch for capital letters
44 capitalPitch=0.9
45
46 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
47 volume=1.0
48
49 # Module is used for speech-dispatcher, to select the speech module you want to use.
50 # Consult speech-dispatcher's configuration and help ti find out which modules are available.
51 # The default is espeak.
52 module=espeak
53
54 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak,
55 # or if using the espeak module in speech-dispatcher. To find out which voices are available, consult the documentation provided with your chosen synthesizer.
56 voice=
57
58 # Select the language you want fenrir to use.
59 language=de
60
61 # Read new text as it happens?
62 autoReadIncoming=True
63
64 [braille]
65 #braille is not implemented yet
66 enabled=True
67 driver=brlapi
68 layout=en
69
70 [screen]
71 driver=vcsa
72 encoding=cp850
73 screenUpdateDelay=0.05
74 suspendingScreen=
75 autodetectSuspendingScreen=True
76
77 [keyboard]
78 driver=evdev
79 # filter input devices NOMICE, ALL or a DEVICE NAME
80 device=ALL
81 # gives fenrir exclusive access to the keyboard and let consume keystrokes. just disable on problems.
82 grabDevices=True
83 ignoreShortcuts=False
84 # the current shortcut layout located in /etc/fenrir/keyboard
85 keyboardLayout=test
86 # echo chars while typing.
87 charEcho=False
88 # echo deleted chars
89 charDeleteEcho=True
90 # echo word after pressing space
91 wordEcho=False
92 # interrupt speech on any keypress
93 interruptOnKeyPress=False
94 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
95 interruptOnKeyPressFilter=
96 # timeout for double tap in sec
97 doubleTapTimeout=0.2
98
99 [general]
100 debugLevel=2
101 punctuationProfile=default
102 punctuationLevel=some
103 respectPunctuationPause=True
104 newLinePause=True
105 numberOfClipboards=10
106 emoticons=True
107 # define the current fenrir key
108 fenrirKeys=KEY_KP0,KEY_META
109 scriptKey=KEY_COMPOSE
110 timeFormat=%H:%M:%P
111 dateFormat=%A, %B %d, %Y
112 autoSpellCheck=True
113 spellCheckLanguage=en_US
114 scriptPath=/usr/share/fenrir/scripts
115
116 [focus]
117 #follow the text cursor
118 cursor=True
119 #follow highlighted text changes
120 highlight=False
121
122 [review]
123 lineBreak=True
124 endOfScreen=True
125
126 [promote]
127 enabled=True
128 inactiveTimeoutSec=120
129 list=
130
131 [time]
132 # automatic time anouncement
133 enabled=False
134 # present time
135 presentTime=True
136 # present date (on change)
137 presentDate=True
138 # present time after x seconds
139 delaySec=0
140 # present time after to given minutes example every 15 minutes: 00,15,30,45
141 # if delaySec is >0 onMinutes is ignored
142 onMinutes=00,30
143 # announce via soundicon
144 announce=True
145 # interrupt current speech for time announcement
146 interrupt=False
0 [sound]
1 # Turn sound on or off:
2 enabled=True
3
4 # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
5 # Sox is the default.
6 #driver=gstreamerDriver
7 driver=genericDriver
8
9 # Sound themes. These are the pack of sounds used for sound alerts.
10 # Sound packs may be located at /usr/share/sounds
11 # For system wide availability, or ~/.local/share/fenrir/sounds
12 # For the current user.
13 theme=default-wav
14
15 # Sound volume controls how loud the sounds for your selected soundpack are.
16 # 0 is quietest, 1.0 is loudest.
17 volume=1.0
18
19 # shell commands for generic sound driver
20 # the folowing variable are substituted
21 # fenrirVolume = the current volume setting
22 # fenrirSoundFile = the soundfile for an soundicon
23 # fenrirFrequence = the frequency to play
24 # fenrirDuration = the duration of the frequency
25 # the following command is used to play a soundfile
26 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
27 #the following command is used to generate a frequency beep
28 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
29
30 [speech]
31 # Turn speech on or off:
32 enabled=True
33
34 # Select speech driver, options are speechdDriver (default), genericDriver, emacspeak or espeakDriver:
35 driver=speechdDriver
36 #driver=espeakDriver
37 #driver=genericDriver
38 #driver=emacspeakDriver
39
40 # server path for emacspeak
41 serverPath=/home/chrys/Projekte/emacspeak/servers/espeak
42
43 # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
44 rate=0.65
45
46 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
47 pitch=0.5
48 # Pitch for capital letters
49 capitalPitch=0.9
50
51 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
52 volume=1.0
53
54 # Module is used for Speech-dispatcher, to select the speech module you want to use.
55 # Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available.
56 # The default is espeak.
57 module=espeak
58
59 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
60 # or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
61 # This also sets the voice used in the generic driver.
62 voice=
63
64 # Select the language you want Fenrir to use.
65 language=english-us
66
67 # Read new text as it happens?
68 autoReadIncoming=True
69
70 # genericSpeechCommand is the command that is executed for talking
71 # the following variables are replaced with values
72 # fenrirText = is the text that should be spoken
73 # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this
74 # fenrirLanguage = the language
75 # fenrirVoice = is the current voice that should be used. Set the voice variable above.
76 # the current volume, pitch and rate is calculated like this
77 # value = min + settingValue * (min - max )
78 # fenrirVolume = is replaced with the current volume
79 # fenrirPitch = is replaced with the current pitch
80 # fenrirRate = is replaced with the current speed (speech rate)
81 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
82
83 # those are the min and max values of the TTS system that is used in genericSpeechCommand
84 fenrirMinVolume=0
85 fenrirMaxVolume=200
86 fenrirMinPitch=0
87 fenrirMaxPitch=99
88 fenrirMinRate=80
89 fenrirMaxRate=450
90
91 [braille]
92 enabled=False
93 driver=dummyDriver
94 layout=en
95 # to what should the flush timeout relate to
96 # word = flush after (number of words to display) * seconds
97 # char = flush after (number of chars to display) * seconds
98 # fix = flush after X seconds
99 # none = no automatic flush (manual via shortcut)
100 flushMode=word
101 # seconds to flush or
102 # -1 = no automatic flush (manual via shortcut)
103 flushTimeout=3
104 # how should the cursor be focused?
105 # page = if cursor cross the border move to next page and start at beginn
106 # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
107 cursorFocusMode=page
108 # define the cell on the Braille device where fenrir should scroll and keep the cursor
109 # 0 = first cell on device
110 # -1 = last cell on device
111 # >0 = fix cell number
112 fixCursorOnCell=-1
113 #How should the braille follow the focus
114 # none = no automatic toggle command used
115 # review = priority to review
116 # last = follow last used cursor
117 cursorFollowMode=review
118 # number of cells in panning (horizontal)
119 # 0 = display size, >0 number of cells
120 panSizeHorizontal=0
121
122 [screen]
123 driver=vcsaDriver
124 encoding=auto
125 screenUpdateDelay=0.05
126 suspendingScreen=
127 autodetectSuspendingScreen=True
128
129 [keyboard]
130 driver=evdevDriver
131 # filter input devices NOMICE, ALL or a DEVICE NAME
132 device=ALL
133 # gives Fenrir exclusive access to the keyboard and lets it control keystrokes.
134 grabDevices=True
135 ignoreShortcuts=False
136 # the current shortcut layout located in /etc/fenrir/keyboard
137 keyboardLayout=desktop
138 # echo chars while typing.
139 charEcho=False
140 # echo deleted chars
141 charDeleteEcho=True
142 # echo word after pressing space
143 wordEcho=False
144 # interrupt speech on any keypress
145 interruptOnKeyPress=False
146 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
147 interruptOnKeyPressFilter=
148 # timeout for double tap in sec
149 doubleTapTimeout=0.2
150
151 [general]
152 debugLevel=0
153 # debugMode sets where the debug output should send to:
154 # debugMode=File writes to /var/log/fenrir.log
155 # debugMode=Print just prints on the screen
156 debugMode=File
157 punctuationProfile=default
158 punctuationLevel=some
159 respectPunctuationPause=True
160 newLinePause=True
161 numberOfClipboards=10
162 # used path for "export_clipboard_to_file"
163 # $user is replaced by username
164 #clipboardExportPath=/home/$user/fenrirClipboard
165 clipboardExportPath=/tmp/fenrirClipboard
166 emoticons=True
167 # define the current Fenrir key
168 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
169 scriptKey=KEY_COMPOSE
170 timeFormat=%H:%M:%P
171 dateFormat=%A, %B %d, %Y
172 autoSpellCheck=True
173 spellCheckLanguage=en_US
174 # path for your scripts "scriptKey" functionality
175 scriptPath=/usr/share/fenrir/scripts
176 # overload commands, and create new one without changing Fenrir default
177 commandPath=
178 #fenrirBGColor = the backgroundcolor
179 #fenrirFGColor = the foregroundcolor
180 #fenrirUnderline = speak the underline attribute
181 #fenrirBold = speak the bold attribute
182 #fenrirBlink = speak the blink attribute
183 #fenrirFont = the font
184 #fenrirFontSize = the fontsize
185 attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
186
187 [focus]
188 #follow the text cursor
189 cursor=True
190 #follow highlighted text changes
191 highlight=False
192
193 [review]
194 lineBreak=True
195 endOfScreen=True
196 # leave the review when pressing a key
197 leaveReviewOnCursorChange=True
198 # leave the review when changing the screen
199 leaveReviewOnScreenChange=True
200
201 [promote]
202 enabled=True
203 inactiveTimeoutSec=120
204 list=
205
206 [time]
207 # automatic time anouncement
208 enabled=False
209 # present time
210 presentTime=True
211 # present date (on change)
212 presentDate=True
213 # present time after a given period of seconds
214 delaySec=0
215 # present time after to given minutes example every 15 minutes: 00,15,30,45
216 # if delaySec is >0 onMinutes is ignored
217 onMinutes=00,30
218 # announce via soundicon (not interrupting)
219 announce=True
220 # interrupt current speech for time announcement
221 interrupt=False
0 [sound]
1 enabled=True
2 driver=generic
3 theme=default
4 volume=1.0
5 # shell commands for generic sound driver
6 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
7 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
8
9 [speech]
10 enabled=True
11 driver=speechd
12 rate=0.85
13 pitch=0.5
14 # Pitch for capital letters
15 capitalPitch=0.9
16 module=espeak
17 voice=
18 language=english-us
19 volume=1.0
20 autoReadIncoming=True
21
22 [braille]
23 enabled=False
24 driver=brlapi
25 layout=en
26
27 [screen]
28 driver=vcsa
29 encoding=cp850
30 screenUpdateDelay=0.05
31 suspendingScreen=7
32 autodetectSuspendingScreen=False
33
34 [keyboard]
35 driver=evdev
36 # filter input devices NOMICE, ALL or a DEVICE NAME
37 device=ALL
38 grabDevices=True
39 ignoreShortcuts=False
40 keyboardLayout=desktop
41 charEcho=False
42 charDeleteEcho=True
43 wordEcho=False
44 interruptOnKeyPress=True
45 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
46 interruptOnKeyPressFilter=
47 # timeout for double tap in sec
48 doubleTapTimeout=0.2
49
50 [general]
51 debugLevel=0
52 punctuationProfile=default
53 punctuationLevel=some
54 respectPunctuationPause=True
55 newLinePause=True
56 numberOfClipboards=10
57 emoticons=True
58 fenrirKeys=KEY_KP0,KEY_META
59 scriptKey=KEY_COMPOSE
60 timeFormat=%H:%M:%P
61 dateFormat="%A, %B %d, %Y"
62 autoSpellCheck=True
63 spellCheckLanguage=en_US
64 scriptPath=/usr/share/fenrir/scripts
65
66 [focus]
67 #follow the text cursor
68 cursor=True
69 #follow highlighted text changes
70 highlight=False
71
72 [review]
73 lineBreak=True
74 endOfScreen=True
75
76 [promote]
77 enabled=True
78 inactiveTimeoutSec=120
79 list=
80
81 [time]
82 # automatic time anouncement
83 enabled=False
84 # present time
85 presentTime=True
86 # present date (on change)
87 presentDate=True
88 # present time after x seconds
89 delaySec=0
90 # present time after to given minutes example every 15 minutes: 00,15,30,45
91 # if delaySec is >0 onMinutes is ignored
92 onMinutes=00,30
93 # announce via soundicon
94 announce=True
95 # interrupt current speech for time announcement
96 interrupt=False
0 [sound]
1 enabled=True
2 driver=genericDriver
3 theme=default
4 volume=1.0
5 # shell commands for generic sound driver
6 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
7 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
8
9 [speech]
10 enabled=True
11 driver=speechdDriver
12 #driver=genericDriver
13 serverPath=
14 rate=0.95
15 pitch=0.5
16 # Pitch for capital letters
17 capitalPitch=0.9
18 module=espeak
19 voice=en-us
20 language=english-us
21 volume=1.0
22 autoReadIncoming=True
23
24 # genericSpeechCommand is the command that is executed for talking
25 # the following variables are replaced with values
26 # fenrirText = is the text that should be spoken
27 # fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this
28 # fenrirLanguage = the language
29 # fenrirVoice = is the current voice that should be used
30 # the current volume, pitch and rate is calculated like this
31 # value = min + settingValue * (min - max )
32 # fenrirVolume = is replaced with the current volume
33 # fenrirPitch = is replaced with the current pitch
34 # fenrirRate = is replaced with the current speed (speech rate)
35 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
36
37 # these are the min and max values of the TTS system that is used in genericSpeechCommand
38 fenrirMinVolume=0
39 fenrirMaxVolume=200
40 fenrirMinPitch=0
41 fenrirMaxPitch=99
42 fenrirMinRate=80
43 fenrirMaxRate=890
44
45 [braille]
46 enabled=False
47 driver=dummyDriver
48 layout=en
49 # to what should the flush timeout relate to
50 # word = flush after (number of words to display) * seconds
51 # char = flush after (number of chars to display) * seconds
52 # fix = flush after X seconds
53 # none = no automatic flush (manual via shortcut)
54 flushMode=word
55 # seconds to flush or
56 # -1 = no automatic flush (manual via shortcut)
57 flushTimeout=3
58 # how should the cursor be focused?
59 # page = if cursor cross the border move to next page and start at beginn
60 # fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
61 cursorFocusMode=page
62 # define the cell on the Braille device where fenrir should scroll and keep the cursor
63 # 0 = first cell on device
64 # -1 = last cell on device
65 # >0 = fix cell number
66 fixCursorOnCell=-1
67 #How should the braille follow the focus
68 # none = no automatic toggle command used
69 # review = priority to review
70 # last = follow last used cursor
71 cursorFollowMode=review
72 # number of cells in panning (horizontal)
73 # 0 = display size, >0 number of cells
74 panSizeHorizontal=0
75
76 [screen]
77 driver=vcsaDriver
78 encoding=auto
79 screenUpdateDelay=0.05
80 suspendingScreen=
81 autodetectSuspendingScreen=True
82
83 [keyboard]
84 driver=evdevDriver
85 # filter input devices NOMICE, ALL or a DEVICE NAME
86 device=ALL
87 grabDevices=True
88 ignoreShortcuts=False
89 keyboardLayout=desktop
90 charEcho=False
91 charDeleteEcho=True
92 wordEcho=False
93 interruptOnKeyPress=True
94 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
95 interruptOnKeyPressFilter=
96 # timeout for double tap in sec
97 doubleTapTimeout=0.2
98
99 [general]
100 debugLevel=1
101 # debugMode sets where the debug output should send to:
102 # debugMode=File writes to /var/log/fenrir.log
103 # debugMode=Print just prints on the screen
104 debugMode=File
105 punctuationProfile=default
106 punctuationLevel=some
107 respectPunctuationPause=True
108 newLinePause=True
109 numberOfClipboards=10
110 # used path for "export_clipboard_to_file"
111 # $user is replaced by username
112 clipboardExportPath=/tmp/fenrirClipboard
113 emoticons=True
114 fenrirKeys=KEY_KP0,KEY_META
115 scriptKey=KEY_COMPOSE
116 timeFormat=%H:%M:%P
117 dateFormat="%A, %B %d, %Y"
118 autoSpellCheck=True
119 spellCheckLanguage=en_US
120 scriptPath=/usr/share/fenrir/scripts
121 # overload commands, and create new one without changing Fenrir default
122 commandPath=
123 #fenrirBGColor = the backgroundcolor
124 #fenrirFGColor = the foregroundcolor
125 #fenrirUnderline = speak the underline attribute
126 #fenrirBold = speak the bold attribute
127 #fenrirBlink = speak the blink attribute
128 #fenrirFont = the font
129 #fenrirFontSize = the fontsize
130 attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
131
132 [focus]
133 #follow the text cursor
134 cursor=True
135 #follow highlighted text changes
136 highlight=False
137
138 [review]
139 lineBreak=True
140 endOfScreen=True
141 # leave the review when pressing a key
142 leaveReviewOnCursorChange=True
143 # leave the review when changing the screen
144 leaveReviewOnScreenChange=True
145
146 [promote]
147 enabled=True
148 inactiveTimeoutSec=120
149 list=
150
151 [time]
152 # automatic time anouncement
153 enabled=False
154 # present time
155 presentTime=True
156 # present date (on change)
157 presentDate=True
158 # present time after x seconds
159 delaySec=0
160 # present time after to given minutes example every 15 minutes: 00,15,30,45
161 # if delaySec is >0 onMinutes is ignored
162 onMinutes=00,30
163 # announce via soundicon
164 announce=True
165 # interrupt current speech for time announcement
166 interrupt=False
+0
-53
contrib/fenrir-git/PKGBUILD less more
0 # Maintainer: Storm Dragon <stormdragon2976@gmail.com>
1 # Maintainer: Chrys <mail@chrys.de>
2
3 _gitname='fenrir'
4 pkgname="${_gitname}-git"
5 pkgver=v0.2.5.g33af5b6
6 pkgrel=3
7 pkgdesc='A user space console screen reader written in python3'
8 arch=('any')
9 url='https://github.com/chrys87/${_pkgname}'
10 license=('MIT')
11 depends=('python' 'python-daemonize' 'python-evdev')
12 optdepends=('brltty: For Braille support'
13 'gstreamer: for soundicons via gstreamer'
14 'sox: The default sound driver'
15 'python-espeak: TTS support'
16 'python-pyenchant: for spell check functionality'
17 'speech-dispatcher: TTS support')
18 makedepends=('git')
19 provides=('fenrir')
20 conflicts=('fenrir')
21 install="$pkgname".install
22 source=("git+https://github.com/chrys87/${_gitname}.git"
23 'fenrir-git.install')
24 md5sums=('SKIP'
25 '1387fd3851040d03816e2fb6b8fa631f')
26
27 pkgver()
28 {
29 cd "$srcdir/$_gitname"
30 local ver="$(git describe --tags)"
31 echo "${ver//-/.}"
32 }
33
34 package()
35 {
36 cd "$srcdir/$_gitname"
37 install -m755 -d "$pkgdir/opt/fenrir"
38 install -m755 -d "$pkgdir/usr/share/fenrir/scripts"
39 install -m755 -d "$pkgdir/usr/share/fenrir/tools"
40 install -m644 -D "config/keyboard/desktop.conf" "$pkgdir/etc/fenrir/keyboard/desktop.conf"
41 install -m644 -D "config/keyboard/laptop.conf" "$pkgdir/etc/fenrir/keyboard/laptop.conf"
42 install -m644 -D "config/punctuation/default.conf" "$pkgdir/etc/fenrir/punctuation/default.conf"
43 install -m644 -D "config/settings/settings.conf" "$pkgdir/etc/fenrir/settings/settings.conf"
44 install -d "$pkgdir/usr/share/sounds/fenrir"
45 install -m644 -D "autostart/systemd/fenrir.service" "$pkgdir/usr/lib/systemd/system/fenrir.service"
46 cp -a src/fenrir/* "$pkgdir/opt/fenrir"
47 cp -a config/scripts/* "$pkgdir/usr/share/fenrir/scripts"
48 cp -a tools/* "$pkgdir/usr/share/fenrir/tools"
49 cp -a config/sound/* "$pkgdir/usr/share/sounds/fenrir"
50 }
51
52 # vim: set ts=2 sw=2 et:
+0
-15
contrib/fenrir-git/fenrir-git.install less more
0 post_install() {
1 ln -s /opt/fenrir/fenrir-daemon /usr/bin/fenrir
2 _alert
3 }
4
5 _alert() {
6 cat << EOF
7 To have fenrir start at boot:
8 sudo systemctl enable fenrir
9 Pulseaudio users may want to run
10 /usr/share/fenrir/tools/configure-pulseaudio
11 once as their user account and once as root.
12 EOF
13 }
14
0 https://stackoverflow.com/questions/880227/what-is-the-minimum-i-have-to-do-to-create-an-rpm-file
0 #!/bin/bash
1 # needs pandoc and php installed
2
3 # remove old files
4 rm fenrir.1
5 rm user.md
6
7 # convert to markdown
8 php DokuWiki-to-Markdown-Converter/convert.php user.txt
9
10 # convert markdown to manpage
11 pandoc user.md -f markdown -t man -s -o fenrir.1
12
0 .\"t
1 .\" Automatically generated by Pandoc 1.19.2.1
2 .\"
3 .TH "" "" "" "" ""
4 .hy
5 .SH Fenrir User Manual
6 .PP
7 Fenrir is a modern command line screen reader written in Python3.
8 .PP
9 It has a modular structure, a flexible based driver model, is highly
10 configurable and easy to customize and extend (see Developer
11 Manual (fenrir_development_manual)).
12 .PP
13 Please see the following pages for the current (fenrir_current_version)
14 and Git (fenrir_git_version) version of Fenrir.
15 .SH Support and Requirements
16 .PP
17 Fenrir requires several drivers to interact with the operating system.
18 .SS Speech Drivers
19 .PP
20 A speech driver is for communication with the text to speech system like
21 Speech\-Dispatcher (#SpeechDispatcher) or
22 Espeak (http://espeak.sourceforge.net).
23 \\ See section Speech (#Speech) in \[aq]\[aq]settings.conf\[aq]\[aq] for
24 more information.
25 .SS SpeechDispatcher
26 .PP
27 This driver is used by default.
28 It uses Speech\-dispatcher as its backend.
29 .PP
30 Dependencies:
31 .IP \[bu] 2
32 Speech\-dispatcher (installed and configured,
33 Documentation (https///devel.freebsoft.org/speechd#sec2))
34 .IP \[bu] 2
35 Python\-speechd
36 .SS Espeak
37 .PP
38 Uses Espeak via Python bindings.
39 .PP
40 Dependencies:
41 .IP \[bu] 2
42 Espeak or Espeak\-ng
43 .IP \[bu] 2
44 python\-espeak (https///launchpad.net/python-espeak)
45 .SS Generic
46 .PP
47 This invokes speech via a sub\-process.
48 This is almost the same as using the commandline.
49 The performance depends on the overhead of the speech synthesis
50 application but it is really flexible.
51 .PP
52 Dependencies:
53 .IP \[bu] 2
54 Espeak or Espeak\-ng
55 .PP
56 The Requirements are flexible, they depend on the configuration in
57 settings.conf.
58 .SS Dummy
59 .PP
60 this is just for debugging, logs are output to the screen and logged as
61 well.
62 .SS Sound Drivers
63 .PP
64 To play sound icons and similar.\\ See section Sound (#Sound) in
65 \[aq]\[aq]settings.conf\[aq]\[aq] for more information.
66 .SS Generic
67 .PP
68 This driver is used by default.
69 .PP
70 Dependencies:
71 .IP \[bu] 2
72 Sox (http://sox.sourceforge.net/) with opus support The Requirements are
73 flexible, they depend on the configuration in settings.conf.
74 .SS Gstreamer
75 .PP
76 if you prefer to use Gstreamer for sound output.
77 .PP
78 Dependencies:
79 .IP \[bu] 2
80 Gstreamer >= 1.x
81 .IP \[bu] 2
82 Glibc
83 .SS Dummy
84 .PP
85 this is just for debugging, logs are output to the screen and logged as
86 well.
87 .SS Input Drivers
88 .PP
89 Input drivers are to capture keyboard shortcuts issued to the screen
90 reader
91 .PD 0
92 .P
93 .PD
94 See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq]
95 for more information.
96 .SS Evdev
97 .PP
98 This driver is used by default.
99 .PP
100 Evdev is the low level input device framework for Linux.
101 .PP
102 Dependencies:
103 .IP \[bu] 2
104 python\-evdev >=0.6.3
105 .IP \[bu] 2
106 pyudev
107 .IP \[bu] 2
108 loaded uinput kernel module
109 .IP \[bu] 2
110 exclusive access to the input devices Read permission to the following
111 files and services:
112 .IP \[bu] 2
113 /dev/input
114 .IP \[bu] 2
115 /dev/uinput
116 .SS Screen Drivers
117 .PP
118 The job of a screen driver is to get the information of current screen
119 content.\\ See section Screen (#Screen) in
120 \[aq]\[aq]settings.conf\[aq]\[aq] for more information.
121 .SS VCSA
122 .PP
123 This driver is used by default.
124 For Linux VCSA devices.
125 These exist on any current standard installation of Linux.
126 .PP
127 Dependencie s:
128 .IP \[bu] 2
129 python\-dbus Read permission to the following files and services (or run
130 as root):
131 .IP \[bu] 2
132 /sys/devices/virtual/tty/tty0/active
133 .IP \[bu] 2
134 /dev/tty[1 \- 64]
135 .IP \[bu] 2
136 /dev/vcsa[1 \- 64] (VCSA manpage (https///linux.die.net/man/4/vcsa))
137 .IP \[bu] 2
138 read Logind DBUS
139 .SS Braille Drivers
140 .PP
141 This is for Braille support.
142 Braille is currently a work in progress and is planned for the Fenrir
143 2.0 release.\\ See section Braille (#Braille) in
144 \[aq]\[aq]settings.conf\[aq]\[aq] for more information.
145 .SS BRLTTY
146 .PP
147 This driver is used by default.
148 It uses BrlTTY (brltty) to communicate with with a Braille device.
149 .PP
150 Dependencies:
151 .IP \[bu] 2
152 BrlTTY (configured and running,
153 Documentation (http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html))
154 .IP \[bu] 2
155 python\-brlapi (configured,
156 Documentation (http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html))
157 ## Currently supported platforms
158 .PP
159 Currently Fenrir completely supports the following Platforms:
160 .IP \[bu] 2
161 Linux TTY Support for further Systems are planned.
162 .SH Installation
163 .PP
164 Fenrir can run without installation.
165 It just requires the dependencies are installed first.
166 .PP
167 We recommend to try it out before installation to be sure everything
168 works and prevent yourself from experiencing a non\-talking environment.
169 .SS Try Out
170 .PP
171 Fenrir does not require installation.
172 You can try it and make sure everything works before you decide to
173 install.
174 In this way you can be sure that your system doesnt break or stop
175 talking.
176 for that you can just grab the code and run as root
177 \[aq]\[aq]src/fenrir/fenrir\[aq]\[aq] (in foreground) or
178 \[aq]\[aq]src/fenrir/fenrir\-daemon\[aq]\[aq] (in background, used by
179 systemd for autostart)
180 .SS Install it
181 .SS Documented operating systems
182 .SS Arch Linux
183 .PP
184 For Arch there are PKGBUILDs in the AUR:
185 .IP \[bu] 2
186 fenrir (https///aur.archlinux.org/packages/fenrir/)
187 .IP \[bu] 2
188 fenrir\-git (https///aur.archlinux.org/packages/fenrir-git/)
189 .SS Manual
190 .IP "1." 3
191 Download the latest stable version from the
192 Fenrir\-Project (https///linux-a11y.org/index.php?page=fenrir-screenreader)
193 site.
194 .IP "2." 3
195 Unpack the archive
196 .IP "3." 3
197 Check the needed Dependencys by running
198 check\-dependencys.py (https///github.com/chrys87/fenrir/blob/master/check-dependencies.py)
199 script
200 .IP "4." 3
201 install the missing dependencies an standard installation requires the
202 following:
203 .RS 4
204 .IP \[bu] 2
205 python3 >= 3.3 (and all the following is needed for python3 )
206 .IP \[bu] 2
207 python3\-speechd (screen)
208 .IP \[bu] 2
209 python3\-dbus (screen)
210 .IP \[bu] 2
211 python3\-evdev >= 0.6.4(input)
212 .IP \[bu] 2
213 python3\-daemonize (background service)
214 .IP \[bu] 2
215 python3\-brlapi (braille)
216 .IP \[bu] 2
217 python3\-pyenchant (spellchecker)
218 .IP \[bu] 2
219 your language for aspell (aspell\-\f[C]<lang>\f[]) (spellchecker)
220 .IP \[bu] 2
221 sox (sound)
222 .IP \[bu] 2
223 For an individual installation see Support and
224 Requirements (#Support%20and%20Requirements) or consult the
225 Readme (https///github.com/chrys87/fenrir/blob/master/README.md))
226 .RE
227 .IP "5." 3
228 run "install.sh" as root
229 .PP
230 this installs Fenrir as the following
231 .IP
232 .nf
233 \f[C]
234 *\ Application:\[aq]\[aq]/opt/fenrir\[aq]\[aq]
235 *\ Settings:\[aq]\[aq]/etc/fenrir\[aq]\[aq]
236 *\ Sound\ Icons:\[aq]\[aq]/usr/share/fenrir/\[aq]\[aq]
237 \f[]
238 .fi
239 .PP
240 to remove Fenrir just run uninstall.sh as root
241 .SS Git
242 .PP
243 if you want to get the latest code you can use git to get a development
244 snapshot:
245 .IP
246 .nf
247 \f[C]
248 git\ clone\ https://github.com/chrys87/fenrir.git
249 \f[]
250 .fi
251 .SS Auto Start
252 .PP
253 To start Fenrir once: systemctl start fenrir
254 .PP
255 To enable auto start on system boot: systemctl enable fenrir
256 .SH First Steps
257 .PP
258 If you are using Fenrir for the first time you may want to take a look
259 at these resources:
260 .IP \[bu] 2
261 Keybindings (#Keybindings)
262 .IP \[bu] 2
263 Tutorial Mode (#Tutorial%20Mode)
264 .SH Features
265 .SS Commands
266 .SS Keybindings
267 .PP
268 Normal commands can be invoked in two ways: 1.
269 Using a Metakey (FenrirKey (#Fenrir%20Key)) 2.
270 Shortcuts with a single key
271 .PP
272 See section Keyboard (#Keyboard) in \[aq]\[aq]settings.conf\[aq]\[aq]
273 for more information.
274 #### Fenrir Key
275 .PP
276 The Fenrir Key is for invoking screen reader commands.
277 Fenrir can utilize more than one FenrirKey at the same time.
278 By default the following keys are used: 1.
279 Insert 2.
280 KeyPad Insert 3.
281 Meta (Super, Windows)
282 .SS Script Key
283 .PP
284 To invoke "Scripts" the Script Key is mandatory.
285 The shortcut is encoded in the filename of the script.
286 See Scripting (#Scripting) #### Desktop Layout
287 .PP
288 .TS
289 tab(@);
290 l l.
291 T{
292 Shortcut
293 T}@T{
294 Command
295 T}
296 _
297 T{
298 FenrirKey + H
299 T}@T{
300 toggle tutorial mode (#Tutorial%20Mode)
301 T}
302 T{
303 CTRL
304 T}@T{
305 shut up (interrupts speech) (#shut%20up)
306 T}
307 T{
308 FenrirKey + KeyPad 9
309 T}@T{
310 reviews bottom (#review%20bottom)
311 T}
312 T{
313 FenrirKey + KeyPad 7
314 T}@T{
315 reviews top (#review%20top)
316 T}
317 T{
318 KeyPad 8
319 T}@T{
320 reviews current line (#review%20current%20line)
321 T}
322 T{
323 KeyPad 7
324 T}@T{
325 reviews previous line (#review%20previous%20line)
326 T}
327 T{
328 KeyPad 9
329 T}@T{
330 reviews next line (#review%20next%20line)
331 T}
332 T{
333 FenrirKey + KeyPad 4
334 T}@T{
335 reviews line beginning (#review%20line%20beginning)
336 T}
337 T{
338 FenrirKey + KeyPad 6
339 T}@T{
340 reviews line ending (#review%20line%20ending)
341 T}
342 T{
343 FenrirKey + KeyPad 1
344 T}@T{
345 reviews line first character (#review%20line%20first%20character)
346 T}
347 T{
348 FenrirKey + KeyPad 3
349 T}@T{
350 reviews line last character (#review%20line%20last%20character)
351 T}
352 T{
353 FenrirKey + Alt + 1
354 T}@T{
355 presents first line (#present%20first%20line)
356 T}
357 T{
358 FenrirKey + Alt + 2
359 T}@T{
360 presents last line (#present%20last%20line)
361 T}
362 T{
363 KeyPad 5
364 T}@T{
365 reviews current word (#review%20current%20word)
366 T}
367 T{
368 KeyPad 4
369 T}@T{
370 reviews previous word (#review%20previous%20word)
371 T}
372 T{
373 KeyPad 6
374 T}@T{
375 reviews next word (#review%20next%20word)
376 T}
377 T{
378 FenrirKey + Shift + KeyPad 5
379 T}@T{
380 reviews current word phonetic (#review%20current%20word%20phonetic)
381 T}
382 T{
383 FenrirKey + Shift + KeyPad 4
384 T}@T{
385 reviews previous word phonetic (#review%20previous%20word%20phonetic)
386 T}
387 T{
388 FenrirKey + Shift + KeyPad 6
389 T}@T{
390 reviews next word phonetic (#review%20next%20word%20phonetic)
391 T}
392 T{
393 KeyPad 2
394 T}@T{
395 reviews current char (#review%20current%20character)
396 T}
397 T{
398 KeyPad 1
399 T}@T{
400 reviews previous char (#review%20previous%20character)
401 T}
402 T{
403 KeyPad 3
404 T}@T{
405 reviews next char (#review%20next%20character)
406 T}
407 T{
408 FenrirKey + Shift + KeyPad 2
409 T}@T{
410 reviews current character
411 phonetic (#review%20current%20character%20phonetic)
412 T}
413 T{
414 FenrirKey + Shift + KeyPad 1
415 T}@T{
416 reviews previous character
417 phonetic (#review%20previous%20character%20phonetic)
418 T}
419 T{
420 FenrirKey + Shift + KeyPad 3
421 T}@T{
422 reviews next character phonetic (#review%20next%20character%20phonetic)
423 T}
424 T{
425 FenrirKey + CTRL + KeyPad 8
426 T}@T{
427 reviews up (#review%20up)
428 T}
429 T{
430 FenrirKey + CTRL + KeyPad 2
431 T}@T{
432 reviews down (#review%20down)
433 T}
434 T{
435 FenrirKey + KeyPad dot
436 T}@T{
437 exit review (#exit%20review)
438 T}
439 T{
440 KeyPad dot
441 T}@T{
442 cursor position (#cursor%20position)
443 T}
444 T{
445 FenrirKey + I
446 T}@T{
447 indent curr line (#indent%20current%20line)
448 T}
449 T{
450 FenrirKey + KeyPad 5
451 T}@T{
452 current screen (#current%20screen)
453 T}
454 T{
455 FenrirKey + KeyPad 8
456 T}@T{
457 current screen before cursor (#current%20screen%20before%20cursor)
458 T}
459 T{
460 FenrirKey + KeyPad 2
461 T}@T{
462 current screen after cursor (#current%20screen%20after%20cursor)
463 T}
464 T{
465 \f[C]<Unbound>\f[]
466 T}@T{
467 cursor read to end of line (#cursor%20read%20to%20end%20of%20line)
468 T}
469 T{
470 \f[C]<Unbound>\f[]
471 T}@T{
472 cursor column (#cursor%20column)
473 T}
474 T{
475 \f[C]<Unbound>\f[]
476 T}@T{
477 cursor line number (#cursor%20line%20number)
478 T}
479 T{
480 \f[C]<Unbound>\f[]
481 T}@T{
482 Braille flush (#braille%20flush)
483 T}
484 T{
485 \f[C]<Unbound>\f[]
486 T}@T{
487 Braille pan left (#braille%20pan%20left)
488 T}
489 T{
490 \f[C]<Unbound>\f[]
491 T}@T{
492 Braille pan right (#braille%20pan%20right)
493 T}
494 T{
495 \f[C]<Unbound>\f[]
496 T}@T{
497 Braille return to cursor (#braille%20return%20to%20cursor)
498 T}
499 T{
500 FenrirKey + CTRL + 1
501 T}@T{
502 clear bookmark 1 (#clear%20Bookmark%20X)
503 T}
504 T{
505 FenrirKey + Shift + 1
506 T}@T{
507 set bookmark 1 (#set%20Bookmark%20X)
508 T}
509 T{
510 FenrirKey + 1
511 T}@T{
512 bookmark 1 (#read%20Bookmark%20X)
513 T}
514 T{
515 FenrirKey + CTRL + 2
516 T}@T{
517 clear bookmark 2 (#clear%20Bookmark%20X)
518 T}
519 T{
520 FenrirKey + Shift + 2
521 T}@T{
522 set bookmark 2 (#set%20Bookmark%20X)
523 T}
524 T{
525 FenrirKey + 2
526 T}@T{
527 bookmark 2 (#read%20Bookmark%20X)
528 T}
529 T{
530 FenrirKey + CTRL + 3
531 T}@T{
532 clear bookmark 3 (#clear%20Bookmark%20X)
533 T}
534 T{
535 FenrirKey + Shift + 3
536 T}@T{
537 set bookmark 3 (#set%20Bookmark%20X)
538 T}
539 T{
540 FenrirKey + 3
541 T}@T{
542 bookmark 3 (#read%20Bookmark%20X)
543 T}
544 T{
545 FenrirKey + CTRL + 4
546 T}@T{
547 clear bookmark 4 (#clear%20Bookmark%20X)
548 T}
549 T{
550 FenrirKey + Shift + 4
551 T}@T{
552 set bookmark 4 (#set%20Bookmark%20X)
553 T}
554 T{
555 FenrirKey + 4
556 T}@T{
557 bookmark 4 (#read%20Bookmark%20X)
558 T}
559 T{
560 FenrirKey + CTRL + 5
561 T}@T{
562 clear bookmark 5 (#clear%20Bookmark%20X)
563 T}
564 T{
565 FenrirKey + Shift + 5
566 T}@T{
567 set bookmark 5 (#set%20Bookmark%20X)
568 T}
569 T{
570 FenrirKey + 5
571 T}@T{
572 bookmark 5 (#read%20Bookmark%20X)
573 T}
574 T{
575 FenrirKey + CTRL + 6
576 T}@T{
577 clear bookmark 6 (#clear%20Bookmark%20X)
578 T}
579 T{
580 FenrirKey + Shift + 6
581 T}@T{
582 set bookmark 6 (#set%20Bookmark%20X)
583 T}
584 T{
585 FenrirKey + 6
586 T}@T{
587 bookmark 6 (#read%20Bookmark%20X)
588 T}
589 T{
590 FenrirKey + CTRL + 7
591 T}@T{
592 clear bookmark 7 (#clear%20Bookmark%20X)
593 T}
594 T{
595 FenrirKey + Shift + 7
596 T}@T{
597 set bookmark 7 (#set%20Bookmark%20X)
598 T}
599 T{
600 FenrirKey + 7
601 T}@T{
602 bookmark 7 (#read%20Bookmark%20X)
603 T}
604 T{
605 FenrirKey + CTRL + 8
606 T}@T{
607 clear bookmark 8 (#clear%20Bookmark%20X)
608 T}
609 T{
610 FenrirKey + Shift + 8
611 T}@T{
612 set bookmark 8 (#set%20Bookmark%20X)
613 T}
614 T{
615 FenrirKey + 8
616 T}@T{
617 bookmark 8 (#read%20Bookmark%20X)
618 T}
619 T{
620 FenrirKey + CTRL + 9
621 T}@T{
622 clear bookmark 9 (#clear%20Bookmark%20X)
623 T}
624 T{
625 FenrirKey + Shift + 9
626 T}@T{
627 set bookmark 9 (#set%20Bookmark%20X)
628 T}
629 T{
630 FenrirKey + 9
631 T}@T{
632 bookmark 9 (#read%20Bookmark%20X)
633 T}
634 T{
635 FenrirKey + CTRL + 0
636 T}@T{
637 clear bookmark 10 (#clear%20Bookmark%20X)
638 T}
639 T{
640 FenrirKey + Shift + 0
641 T}@T{
642 set bookmark 10 (#set%20Bookmark%20X)
643 T}
644 T{
645 FenrirKey + 0
646 T}@T{
647 bookmark 10 (#read%20Bookmark%20X)
648 T}
649 T{
650 FenrirKey + KeyPad Slash
651 T}@T{
652 set window application (#Create%20Window)
653 T}
654 T{
655 2 * FenrirKey + KeyPad Slash
656 T}@T{
657 clear window application (#Remove%20Window)
658 T}
659 T{
660 KeyPad Plus
661 T}@T{
662 read last incoming (#last%20incoming)
663 T}
664 T{
665 FenrirKey + F2
666 T}@T{
667 toggles braille (#toggle%20braille)
668 T}
669 T{
670 FenrirKey + F3
671 T}@T{
672 toggles sound (#toggle%20sound)
673 T}
674 T{
675 FenrirKey + F4
676 T}@T{
677 toggles speech (#toggle%20speech)
678 T}
679 T{
680 KeyPad Enter
681 T}@T{
682 temporarily disables speech (#disable%20speech%20temporarily)
683 T}
684 T{
685 FenrirKey + CTRL + P
686 T}@T{
687 toggles punctuation level (#toggle%20punctuation%20level)
688 T}
689 T{
690 FenrirKey + RightBrace
691 T}@T{
692 toggle auto spell check (#toggle%20auto%20spell%20check)
693 T}
694 T{
695 FenrirKey + Backslash
696 T}@T{
697 toggles output (#toggle%20output)
698 T}
699 T{
700 FenrirKey + CTRL + E
701 T}@T{
702 toggles emoticons (#toggle%20emoticons)
703 T}
704 T{
705 FenrirKey + KeyPad Enter
706 T}@T{
707 toggles auto read (#toggle%20auto%20read)
708 T}
709 T{
710 FenrirKey + CTRL + T
711 T}@T{
712 toggles auto time (#toggle%20auto%20time)
713 T}
714 T{
715 FenrirKey + KeyPad ASTERISK
716 T}@T{
717 toggles highlight tracking (#toggle%20highlight%20tracking)
718 T}
719 T{
720 FenrirKey + Q
721 T}@T{
722 quits fenrir (#quit%20Fenrir)
723 T}
724 T{
725 FenrirKey + T
726 T}@T{
727 Announce time (#Time)
728 T}
729 T{
730 2 * FenrirKey + T
731 T}@T{
732 Announce date (#Date)
733 T}
734 T{
735 FenrirKey + S
736 T}@T{
737 spell check (#spell%20check)
738 T}
739 T{
740 2 * FenrirKey + S
741 T}@T{
742 add word to spell check (#add%20word%20to%20spell%20check)
743 T}
744 T{
745 FenrirKey + Shift + S
746 T}@T{
747 removes word from spell check (#removes%20word%20from%20spell%20check)
748 T}
749 T{
750 FenrirKey + Backspace
751 T}@T{
752 forward keypress (#forward%20keypress)
753 T}
754 T{
755 FenrirKey + Up
756 T}@T{
757 increase speech volume (#increase%20speech%20volume)
758 T}
759 T{
760 FenrirKey + Down
761 T}@T{
762 decrease speech volume (#decrease%20speech%20volume)
763 T}
764 T{
765 FenrirKey + Right
766 T}@T{
767 increase speech rate (#increase%20speech%20rate)
768 T}
769 T{
770 FenrirKey + Left
771 T}@T{
772 decrease speech rate (#decrease%20speech%20rate)
773 T}
774 T{
775 FenrirKey + Alt + Right
776 T}@T{
777 increase speech pitch (#increase%20speech%20pitch)
778 T}
779 T{
780 FenrirKey + Alt + Left
781 T}@T{
782 decrease speech pitch (#decrease%20speech%20pitch)
783 T}
784 T{
785 FenrirKey + Alt + Up
786 T}@T{
787 increase sound volume (#increase%20sound%20volume)
788 T}
789 T{
790 FenrirKey + Alt + Down
791 T}@T{
792 decrease sound volume (#decrease%20sound%20volume)
793 T}
794 T{
795 FenrirKey + CTRL + Shift + C
796 T}@T{
797 clears clipboard (#clear%20clipboard)
798 T}
799 T{
800 FenrirKey + Home
801 T}@T{
802 first clipboard (#first%20clipboard)
803 T}
804 T{
805 FenrirKey + End
806 T}@T{
807 last clipboard (#last%20clipboard)
808 T}
809 T{
810 FenrirKey + PageUp
811 T}@T{
812 previous clipboard (#previous%20clipboard)
813 T}
814 T{
815 FenrirKey + PageDown
816 T}@T{
817 next clipboard (#next%20clipboard)
818 T}
819 T{
820 FenrirKey + Shift + C
821 T}@T{
822 current clipboard (#read%20current%20clipboard)
823 T}
824 T{
825 FenrirKey + C
826 T}@T{
827 copy marked text to clipboard (#copy%20marked%20to%20clipboard)
828 T}
829 T{
830 FenrirKey + V
831 T}@T{
832 paste clipboard contents (#paste%20clipboard)
833 T}
834 T{
835 FenrirKey + P
836 T}@T{
837 import clipboard from file (#import%20clipboard%20from%20file)
838 T}
839 T{
840 FenrirKey + Alt + Shift +C
841 T}@T{
842 export clipboard to file (#export%20clipboard%20to%20file)
843 T}
844 T{
845 FenrirKey + CTRL + Shift + X
846 T}@T{
847 remove marks (#Remove%20Marks)
848 T}
849 T{
850 FenrirKey + X
851 T}@T{
852 set mark (#Set%20mark)
853 T}
854 T{
855 FenrirKey + Shift + X
856 T}@T{
857 announce marked text (#Get%20text%20between%20marks)
858 T}
859 T{
860 Linux specific
861 T}@T{
862 T}
863 T{
864 \f[C]<Unbound>\f[]
865 T}@T{
866 export clipboard to X
867 T}
868 T{
869 FenrirKey + CTRL + Up
870 T}@T{
871 include Alsa volume
872 T}
873 T{
874 FenrirKey + CTRL + Down
875 T}@T{
876 decrease Alsa volume
877 T}
878 .TE
879 .SS Laptop Layout
880 .PP
881 .TS
882 tab(@);
883 l l.
884 T{
885 Shortcut
886 T}@T{
887 Command
888 T}
889 _
890 T{
891 FenrirKey + H
892 T}@T{
893 toggle tutorial mode (#Tutorial%20Mode)
894 T}
895 T{
896 CTRL
897 T}@T{
898 shut up (interrupts speech) (#shut%20up)
899 T}
900 T{
901 FenrirKey + Shift + O
902 T}@T{
903 reviews bottom (#review%20bottom)
904 T}
905 T{
906 FenrirKey + Shift + U
907 T}@T{
908 reviews top (#review%20top)
909 T}
910 T{
911 FenrirKey + I
912 T}@T{
913 reviews current line (#review%20current%20line)
914 T}
915 T{
916 FenrirKey + U
917 T}@T{
918 reviews previous line (#review%20previous%20line)
919 T}
920 T{
921 FenrirKey + O
922 T}@T{
923 reviews next line (#review%20next%20line)
924 T}
925 T{
926 FenrirKey + Shift + J
927 T}@T{
928 reviews line beginning (#review%20line%20beginning)
929 T}
930 T{
931 FenrirKey + Shift + L
932 T}@T{
933 reviews line ending (#review%20line%20ending)
934 T}
935 T{
936 FenrirKey + CTRL + J
937 T}@T{
938 reviews line first character (#review%20line%20first%20character)
939 T}
940 T{
941 FenrirKey + CTRL + L
942 T}@T{
943 reviews line last character (#review%20line%20last%20character)
944 T}
945 T{
946 FenrirKey + Alt + 1
947 T}@T{
948 presents first line (#present%20first%20line)
949 T}
950 T{
951 FenrirKey + Alt + 2
952 T}@T{
953 presents last line (#present%20last%20line)
954 T}
955 T{
956 FenrirKey + K
957 T}@T{
958 reviews current word (#review%20current%20word)
959 T}
960 T{
961 FenrirKey + J
962 T}@T{
963 reviews previous word (#review%20previous%20word)
964 T}
965 T{
966 FenrirKey + L
967 T}@T{
968 reviews next word (#review%20next%20word)
969 T}
970 T{
971 FenrirKey + CTRL + ALT + K
972 T}@T{
973 reviews current word phonetic (#review%20current%20word%20phonetic)
974 T}
975 T{
976 FenrirKey + CTRL + ALT + J
977 T}@T{
978 reviews previous word phonetic (#review%20previous%20word%20phonetic)
979 T}
980 T{
981 FenrirKey + CTRL + ALT + L
982 T}@T{
983 reviews next word phonetic (#review%20next%20word%20phonetic)
984 T}
985 T{
986 FenrirKey + comma
987 T}@T{
988 reviews current character (#review%20current%20character)
989 T}
990 T{
991 FenrirKey + M
992 T}@T{
993 reviews previous character (#review%20previous%20character)
994 T}
995 T{
996 FenrirKey + dot
997 T}@T{
998 reviews next character (#review%20next%20character)
999 T}
1000 T{
1001 FenrirKey + CTRL + ALT + comma
1002 T}@T{
1003 reviews current character
1004 phonetic (#review%20current%20character%20phonetic)
1005 T}
1006 T{
1007 FenrirKey + CTRL + ALT + M
1008 T}@T{
1009 reviews previous character
1010 phonetic (#review%20previous%20character%20phonetic)
1011 T}
1012 T{
1013 FenrirKey + CTRL + ALT + dot
1014 T}@T{
1015 reviews next character phonetic (#review%20next%20character%20phonetic)
1016 T}
1017 T{
1018 FenrirKey + CTRL + I
1019 T}@T{
1020 reviews up (#review%20up)
1021 T}
1022 T{
1023 FenrirKey + CTRL + comma
1024 T}@T{
1025 reviews down (#review%20down)
1026 T}
1027 T{
1028 FenrirKey + Slash
1029 T}@T{
1030 exit review (#exit%20review)
1031 T}
1032 T{
1033 FenrirKey + Shift + dot
1034 T}@T{
1035 cursor position (#cursor%20position)
1036 T}
1037 T{
1038 2 * FenrirKey + I
1039 T}@T{
1040 indent curr line (#indent%20current%20line)
1041 T}
1042 T{
1043 FenrirKey + Shift + K
1044 T}@T{
1045 current screen (#current%20screen)
1046 T}
1047 T{
1048 FenrirKey + Shift + I
1049 T}@T{
1050 current screen before cursor (#current%20screen%20before%20cursor)
1051 T}
1052 T{
1053 FenrirKey + Shift + comma
1054 T}@T{
1055 current screen after cursor (#current%20screen%20after%20cursor)
1056 T}
1057 T{
1058 \f[C]<Unbound>\f[]
1059 T}@T{
1060 cursor read to end of line (#cursor%20read%20to%20end%20of%20line)
1061 T}
1062 T{
1063 \f[C]<Unbound>\f[]
1064 T}@T{
1065 cursor column (#cursor%20column)
1066 T}
1067 T{
1068 \f[C]<Unbound>\f[]
1069 T}@T{
1070 cursor line number (#cursor%20line%20number)
1071 T}
1072 T{
1073 \f[C]<Unbound>\f[]
1074 T}@T{
1075 Braille flush (#braille%20flush)
1076 T}
1077 T{
1078 \f[C]<Unbound>\f[]
1079 T}@T{
1080 Braille pan left (#braille%20pan%20left)
1081 T}
1082 T{
1083 \f[C]<Unbound>\f[]
1084 T}@T{
1085 Braille pan right (#braille%20pan%20right)
1086 T}
1087 T{
1088 \f[C]<Unbound>\f[]
1089 T}@T{
1090 Braille return to cursor (#braille%20return%20to%20cursor)
1091 T}
1092 T{
1093 FenrirKey + CTRL + 1
1094 T}@T{
1095 clear bookmark 1 (#clear%20Bookmark%20X)
1096 T}
1097 T{
1098 FenrirKey + Shift + 1
1099 T}@T{
1100 set bookmark 1 (#set%20Bookmark%20X)
1101 T}
1102 T{
1103 FenrirKey + 1
1104 T}@T{
1105 bookmark 1 (#read%20Bookmark%20X)
1106 T}
1107 T{
1108 FenrirKey + CTRL + 2
1109 T}@T{
1110 clear bookmark 2 (#clear%20Bookmark%20X)
1111 T}
1112 T{
1113 FenrirKey + Shift + 2
1114 T}@T{
1115 set bookmark 2 (#set%20Bookmark%20X)
1116 T}
1117 T{
1118 FenrirKey + 2
1119 T}@T{
1120 bookmark 2 (#read%20Bookmark%20X)
1121 T}
1122 T{
1123 FenrirKey + CTRL + 3
1124 T}@T{
1125 clear bookmark 3 (#clear%20Bookmark%20X)
1126 T}
1127 T{
1128 FenrirKey + Shift + 3
1129 T}@T{
1130 set bookmark 3 (#set%20Bookmark%20X)
1131 T}
1132 T{
1133 FenrirKey + 3
1134 T}@T{
1135 bookmark 3 (#read%20Bookmark%20X)
1136 T}
1137 T{
1138 FenrirKey + CTRL + 4
1139 T}@T{
1140 clear bookmark 4 (#clear%20Bookmark%20X)
1141 T}
1142 T{
1143 FenrirKey + Shift + 4
1144 T}@T{
1145 set bookmark 4 (#set%20Bookmark%20X)
1146 T}
1147 T{
1148 FenrirKey + 4
1149 T}@T{
1150 bookmark 4 (#read%20Bookmark%20X)
1151 T}
1152 T{
1153 FenrirKey + CTRL + 5
1154 T}@T{
1155 clear bookmark 5 (#clear%20Bookmark%20X)
1156 T}
1157 T{
1158 FenrirKey + Shift + 5
1159 T}@T{
1160 set bookmark 5 (#set%20Bookmark%20X)
1161 T}
1162 T{
1163 FenrirKey + 5
1164 T}@T{
1165 bookmark 5 (#read%20Bookmark%20X)
1166 T}
1167 T{
1168 FenrirKey + CTRL + 6
1169 T}@T{
1170 clear bookmark 6 (#clear%20Bookmark%20X)
1171 T}
1172 T{
1173 FenrirKey + Shift + 6
1174 T}@T{
1175 set bookmark 6 (#set%20Bookmark%20X)
1176 T}
1177 T{
1178 FenrirKey + 6
1179 T}@T{
1180 bookmark 6 (#read%20Bookmark%20X)
1181 T}
1182 T{
1183 FenrirKey + CTRL + 7
1184 T}@T{
1185 clear bookmark 7 (#clear%20Bookmark%20X)
1186 T}
1187 T{
1188 FenrirKey + Shift + 7
1189 T}@T{
1190 set bookmark 7 (#set%20Bookmark%20X)
1191 T}
1192 T{
1193 FenrirKey + 7
1194 T}@T{
1195 bookmark 7 (#read%20Bookmark%20X)
1196 T}
1197 T{
1198 FenrirKey + CTRL + 8
1199 T}@T{
1200 clear bookmark 8 (#clear%20Bookmark%20X)
1201 T}
1202 T{
1203 FenrirKey + Shift + 8
1204 T}@T{
1205 set bookmark 8 (#set%20Bookmark%20X)
1206 T}
1207 T{
1208 FenrirKey + 8
1209 T}@T{
1210 bookmark 8 (#read%20Bookmark%20X)
1211 T}
1212 T{
1213 FenrirKey + CTRL + 9
1214 T}@T{
1215 clear bookmark 9 (#clear%20Bookmark%20X)
1216 T}
1217 T{
1218 FenrirKey + Shift + 9
1219 T}@T{
1220 set bookmark 9 (#set%20Bookmark%20X)
1221 T}
1222 T{
1223 FenrirKey + 9
1224 T}@T{
1225 bookmark 9 (#read%20Bookmark%20X)
1226 T}
1227 T{
1228 FenrirKey + CTRL + 0
1229 T}@T{
1230 clear bookmark 10 (#clear%20Bookmark%20X)
1231 T}
1232 T{
1233 FenrirKey + Shift + 0
1234 T}@T{
1235 set bookmark 10 (#set%20Bookmark%20X)
1236 T}
1237 T{
1238 FenrirKey + 0
1239 T}@T{
1240 bookmark 10 (#read%20Bookmark%20X)
1241 T}
1242 T{
1243 FenrirKey + CTRL + 8
1244 T}@T{
1245 set window application (#Create%20Window)
1246 T}
1247 T{
1248 2 * FenrirKey + CTRL + 8
1249 T}@T{
1250 clear window application (#Remove%20Window)
1251 T}
1252 T{
1253 FenrirKey + Semicolon
1254 T}@T{
1255 read last incoming (#last%20incoming)
1256 T}
1257 T{
1258 FenrirKey + F2
1259 T}@T{
1260 toggles braille (#toggle%20braille)
1261 T}
1262 T{
1263 FenrirKey + F3
1264 T}@T{
1265 toggles sound (#toggle%20sound)
1266 T}
1267 T{
1268 FenrirKey + F4
1269 T}@T{
1270 toggles speech (#toggle%20speech)
1271 T}
1272 T{
1273 FenrirKey + Enter
1274 T}@T{
1275 temporarily disables speech (#disable%20speech%20temporarily)
1276 T}
1277 T{
1278 FenrirKey + Shift + CTRL + P
1279 T}@T{
1280 toggles punctuation level (#toggle%20punctuation%20level)
1281 T}
1282 T{
1283 FenrirKey + RightBrace
1284 T}@T{
1285 toggle auto spell check (#toggle%20auto%20spell%20check)
1286 T}
1287 T{
1288 FenrirKey + Shift + Enter
1289 T}@T{
1290 toggles output (#toggle%20output)
1291 T}
1292 T{
1293 FenrirKey + Shift + E
1294 T}@T{
1295 toggles emoticons (#toggle%20emoticons)
1296 T}
1297 T{
1298 FenrirKey + Enter
1299 T}@T{
1300 toggles auto read (#toggle%20auto%20read)
1301 T}
1302 T{
1303 FenrirKey + CTRL + T
1304 T}@T{
1305 toggles auto time (#toggle%20auto%20time)
1306 T}
1307 T{
1308 FenrirKey + Y
1309 T}@T{
1310 toggles highlight tracking (#toggle%20highlight%20tracking)
1311 T}
1312 T{
1313 FenrirKey + Q
1314 T}@T{
1315 quits fenrir (#quit%20Fenrir)
1316 T}
1317 T{
1318 FenrirKey + T
1319 T}@T{
1320 Announce time (#Time)
1321 T}
1322 T{
1323 2 * FenrirKey + T
1324 T}@T{
1325 Announce date (#Date)
1326 T}
1327 T{
1328 FenrirKey + S
1329 T}@T{
1330 spell check (#spell%20check)
1331 T}
1332 T{
1333 2 * FenrirKey + S
1334 T}@T{
1335 add word to spell check (#add%20word%20to%20spell%20check)
1336 T}
1337 T{
1338 FenrirKey + Shift + S
1339 T}@T{
1340 removes word from spell check (#removes%20word%20from%20spell%20check)
1341 T}
1342 T{
1343 FenrirKey + Backspace
1344 T}@T{
1345 forward keypress (#forward%20keypress)
1346 T}
1347 T{
1348 FenrirKey + Up
1349 T}@T{
1350 increase speech volume (#increase%20speech%20volume)
1351 T}
1352 T{
1353 FenrirKey + Down
1354 T}@T{
1355 decrease speech volume (#decrease%20speech%20volume)
1356 T}
1357 T{
1358 FenrirKey + Right
1359 T}@T{
1360 increase speech rate (#increase%20speech%20rate)
1361 T}
1362 T{
1363 FenrirKey + Left
1364 T}@T{
1365 decrease speech rate (#decrease%20speech%20rate)
1366 T}
1367 T{
1368 FenrirKey + Alt + Right
1369 T}@T{
1370 increase speech pitch (#increase%20speech%20pitch)
1371 T}
1372 T{
1373 FenrirKey + Alt + Left
1374 T}@T{
1375 decrease speech pitch (#decrease%20speech%20pitch)
1376 T}
1377 T{
1378 FenrirKey + Alt + Up
1379 T}@T{
1380 increase sound volume (#increase%20sound%20volume)
1381 T}
1382 T{
1383 FenrirKey + Alt + Down
1384 T}@T{
1385 decrease sound volume (#decrease%20sound%20volume)
1386 T}
1387 T{
1388 FenrirKey + CTRL + Shift + C
1389 T}@T{
1390 clears clipboard (#clear%20clipboard)
1391 T}
1392 T{
1393 FenrirKey + Home
1394 T}@T{
1395 first clipboard (#first%20clipboard)
1396 T}
1397 T{
1398 FenrirKey + End
1399 T}@T{
1400 last clipboard (#last%20clipboard)
1401 T}
1402 T{
1403 FenrirKey + PageUp
1404 T}@T{
1405 previous clipboard (#previous%20clipboard)
1406 T}
1407 T{
1408 FenrirKey + PageDown
1409 T}@T{
1410 next clipboard (#next%20clipboard)
1411 T}
1412 T{
1413 FenrirKey + Shift + C
1414 T}@T{
1415 current clipboard (#read%20current%20clipboard)
1416 T}
1417 T{
1418 FenrirKey + C
1419 T}@T{
1420 copy marked text to clipboard (#copy%20marked%20to%20clipboard)
1421 T}
1422 T{
1423 FenrirKey + V
1424 T}@T{
1425 paste clipboard contents (#paste%20clipboard)
1426 T}
1427 T{
1428 FenrirKey + F5
1429 T}@T{
1430 import clipboard from file (#import%20clipboard%20from%20file)
1431 T}
1432 T{
1433 FenrirKey + Alt + Shift +C
1434 T}@T{
1435 export clipboard to file (#export%20clipboard%20to%20file)
1436 T}
1437 T{
1438 FenrirKey + CTRL + Shift + X
1439 T}@T{
1440 remove marks (#Remove%20Marks)
1441 T}
1442 T{
1443 FenrirKey + X
1444 T}@T{
1445 set mark (#Set%20mark)
1446 T}
1447 T{
1448 FenrirKey + Shift + X
1449 T}@T{
1450 announce marked text (#Get%20text%20between%20marks)
1451 T}
1452 T{
1453 Linux specific
1454 T}@T{
1455 T}
1456 T{
1457 \f[C]<Unbound>\f[]
1458 T}@T{
1459 export clipboard to X
1460 T}
1461 T{
1462 FenrirKey + CTRL + Up
1463 T}@T{
1464 increases Alsa volume
1465 T}
1466 T{
1467 FenrirKey + CTRL + Down
1468 T}@T{
1469 decreases Alsa volume
1470 T}
1471 .TE
1472 .SS General
1473 .SS quit Fenrir
1474 .PP
1475 Just stops fenrir.
1476 #### shut up
1477 .PP
1478 Interrupt the current spoken.
1479 ### Review Modes
1480 .PP
1481 Fenrir provides a virtual cursor, with it you can navigate all over the
1482 screen without changing the text cursor.
1483 .PP
1484 Using the review feature will open the review mode automatically.
1485 .PP
1486 The review cursor always starts from the text cursor.
1487 Attention: after using the review mode, the review cursor will stay open
1488 until you use the \[aq]\[aq]exit review\[aq]\[aq] shortcut.
1489 .PP
1490 Think when using clipboard operations and similar.
1491 The review cursor is always prefered over the text cursor.
1492 .PP
1493 Fenrir sounds a bell sound if the used review command jumps to another
1494 line or end of screen.
1495 #### exit review
1496 .PP
1497 You can leave the review mode by pressing the \[aq]\[aq]exit
1498 review\[aq]\[aq] shortcut.
1499 #### review bottom
1500 .PP
1501 Set the review cursor to first column in the last line.
1502 #### review top
1503 .PP
1504 Set the review cursor to the first column in the first line #### review
1505 current line
1506 .PP
1507 Set the review cursor to the beginn of the the current line and review
1508 it.
1509 #### review previous line
1510 .PP
1511 Set the review cursor to the previous line and review it.
1512 #### review next line
1513 .PP
1514 Set the review cursor to the next line and review it.
1515 #### review line beginning
1516 .PP
1517 Set the review cursor to the begin of the current line #### review line
1518 ending
1519 .PP
1520 Set the review cursor to the end of the current line #### review line
1521 first character
1522 .PP
1523 Set the review cursor the first char (that is not space) in the current
1524 line and review it.
1525 #### review line last character
1526 .PP
1527 Set the review cursor the last char (that is not space) in the current
1528 line and review it.
1529 #### review current word
1530 .PP
1531 Sets the review cursor to the beginning of the current word and review
1532 it.
1533 #### review previous word
1534 .PP
1535 Sets the review cursor to the beginning of the previous word and review
1536 it.
1537 #### review next word
1538 .PP
1539 Sets the review cursor to the beginning of the next word and review it.
1540 #### review current word phonetic
1541 .PP
1542 Sets the review cursor to the beginning of the current word and spell it
1543 phonetic.
1544 #### review previous word phonetic
1545 .PP
1546 Sets the review cursor to the beginning of the previous word and spell
1547 it phonetic.
1548 #### review next word phonetic
1549 .PP
1550 Sets the review cursor to the beginning of the next word and spell it
1551 phonetic.
1552 #### review current character
1553 .PP
1554 Does not change the review cursor.
1555 Just announce the current char.
1556 #### review previous character
1557 .PP
1558 Sets review cursor to the previous column and review it #### review next
1559 character
1560 .PP
1561 Sets review cursor to the next column and review it #### review current
1562 character phonetic
1563 .PP
1564 Does not change the review cursor.
1565 Just announce the current char phonetic.
1566 #### review previous character phonetic
1567 .PP
1568 Sets review cursor to the previous column and announce the char
1569 phonetic.
1570 #### review next character phonetic
1571 .PP
1572 Sets review cursor to the next column and announce the char phonetic.
1573 #### review up
1574 .PP
1575 Set the review cursor in the same column one line above the current one
1576 and review it.
1577 #### review down
1578 .PP
1579 Set the review cursor in the same column one line below the current one
1580 and review it.
1581 ### Handling marking
1582 .PP
1583 A mark defines a point of origin or end to prepare to copy or paste a
1584 block of text.
1585 \\ Examples where you need marks are:
1586 .IP \[bu] 2
1587 copy to clipboard
1588 .IP \[bu] 2
1589 set window application
1590 .IP \[bu] 2
1591 set bookmark 1 \- X #### Set mark
1592 .PP
1593 How to set a mark: 1.
1594 navigate with review or textcursor to the position you want to set the
1595 mark.
1596 Attention: if a review cursor is set, that is the prefered.
1597 If you want to use text cursor, be sure that you are not in review mode.
1598 2.
1599 press shortcut for \[aq]\[aq]set mark\[aq]\[aq] you can set two marks
1600 (begin and end).
1601 Some commands allow some simpler usecases just using the whole line if
1602 only one mark is set.
1603 you may want to try this out.
1604 #### Get text between marks
1605 .PP
1606 To get the text that is currently between your marks press shortcut for
1607 \[aq]\[aq]marked text\[aq]\[aq].\\ #### Remove Marks
1608 .PP
1609 You can remove all current marks by pressing the shortcut for
1610 \[aq]\[aq]remove marks\[aq]\[aq].
1611 Changing the screen also removes the marks.
1612 ### Screen Interaction
1613 .PP
1614 Fenrir provides several methods to interact with the current screen.
1615 #### forward keypress
1616 .PP
1617 This just forwards the next shortcut to the screen Fenrir shortcut or
1618 not.
1619 This is useful if the currently pressed shortcut is also in use by
1620 Fenrir.
1621 #### Clipboard
1622 .PP
1623 Fenrir provides a clipboard with multible items represented by a list.
1624 You navigate throught the list and paste the selected clipboard.
1625 ##### copy marked to clipboard
1626 .PP
1627 To copy something to the clipboard you need to set one or two marks.
1628 if you set one mark, the text between the mark and your current cursor
1629 is copied to clipboard.
1630 Setting two marks just copies the text between the marks into the
1631 clipboard.
1632 If you copy something it is always placed as the first item on your
1633 clipboard.
1634 ##### clear clipboard
1635 .PP
1636 You can remove all items from the current clipboard by \[aq]\[aq]clear
1637 clipboard\[aq]\[aq] functionality.
1638 ##### first clipboard
1639 .PP
1640 This moves quick to the first item of the clipboard.
1641 ##### last clipboard
1642 .PP
1643 This moves quick to the last item of the clipboard.
1644 ##### previous clipboard
1645 .PP
1646 Go to previous item in the clipboard.
1647 ##### next clipboard
1648 .PP
1649 Go to next item on the clipboard.
1650 ##### read current clipboard
1651 .PP
1652 Read the content of the current item of the clipboard.
1653 ##### paste clipboard
1654 .PP
1655 Pass whatever item is currently selected by first, last, prev or next
1656 clipboard commands.
1657 if no special clipboard is selected the (last copied) is used.
1658 ##### export clipboard to file
1659 .PP
1660 This allows you to export the current clipboard to a configurable
1661 filepath.
1662 This is useful to share the clipboard with a graphical desktop.
1663 ##### import clipboard from file
1664 .PP
1665 Import a clipboard from a configurable file.
1666 This is useful to share the clipboard with a graphical desktop.
1667 ### Quick Settings
1668 .PP
1669 Fenrir provides shortcuts to change settings temporarily and on the fly
1670 without the need to permanently change the
1671 \[aq]\[aq]settings.conf\[aq]\[aq] file.
1672 #### toggle braille
1673 .PP
1674 Enables and disables Braille.
1675 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1676 but during run time.
1677 #### toggle sound
1678 .PP
1679 Enables and disables sound.
1680 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1681 but during run time.
1682 #### toggle speech
1683 .PP
1684 Enables and disables speech.
1685 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1686 but during run time.
1687 #### disable speech temporarily
1688 .PP
1689 Disables the speech until next key press.
1690 it might be useful if you want to listen to music or similar.
1691 As soon as a key is pressed it is going to be enabled again.
1692 #### toggle punctuation level
1693 .PP
1694 Cycle between all available punctuation levels.
1695 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1696 but during run time.
1697 #### toggle auto spell check
1698 .PP
1699 Enables and disables automatic spellchecker (when typing).
1700 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1701 but during run time.
1702 #### toggle emoticons
1703 .PP
1704 Enables and disables emoticons.
1705 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1706 but during runtime.
1707 #### toggle output
1708 .PP
1709 Enables and disables all output at once (sound, Braille, speech).
1710 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1711 but during run time.
1712 #### toggle auto read
1713 .PP
1714 Enables and disables what is automatically spoken.
1715 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1716 but during run time.
1717 #### toggle auto time
1718 .PP
1719 Enables and disables auto time functionality.
1720 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1721 but during run time.
1722 #### toggle highlight tracking
1723 .PP
1724 Enables and disables highlight tracking.
1725 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1726 but during run time.
1727 #### increase speech volume
1728 .PP
1729 Increase the volume of the speech.
1730 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1731 but during runtime.
1732 #### decrease speech volume
1733 .PP
1734 Decrease the volume of the speech.
1735 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1736 but during runtime.
1737 #### increase speech rate
1738 .PP
1739 Increase the rate of the speech.
1740 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1741 but during runtime.
1742 #### decrease speech rate
1743 .PP
1744 Decrease the rate of the speech.
1745 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1746 but during runtime.
1747 #### increase speech pitch
1748 .PP
1749 Increase the pitch of the speech.
1750 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1751 but during runtime.
1752 #### decrease speech pitch
1753 .PP
1754 Decrease the pitch of the speech.
1755 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1756 but during runtime.
1757 #### increase sound volume
1758 .PP
1759 Increase the volume of the sound.
1760 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1761 but during runtime.
1762 #### decrease sound volume
1763 .PP
1764 Decrease the volume of the sound.
1765 This is not persistent stored in your \[aq]\[aq]settings.conf\[aq]\[aq]
1766 but during runtime.
1767 ### Window Mode
1768 .PP
1769 Fenrir supports window mode, a window is a partial area of the screen.
1770 #### Create Window
1771 .PP
1772 To create a window you need to do the following: 1.
1773 set a beginning mark (as the start of the window) 2.
1774 set an end mark (where the window should end) 3.
1775 press \[aq]\[aq]set window application\[aq]\[aq] shortcut.
1776 Now Fenrir ignores anything outside of the window.\\ #### Remove Window
1777 .PP
1778 You can remove the window by pressing \[aq]\[aq]the clear window
1779 application\[aq]\[aq] shortcut.
1780 Now Fenrir will read everything on the screen again.
1781 ### Tracking Modes
1782 .PP
1783 Different types of tracking are currently supported See section
1784 Focus (#Focus) in \[aq]\[aq]settings.conf\[aq]\[aq] for more
1785 information.
1786 #### Cursor Tracking
1787 .PP
1788 This follows the text cursor.
1789 This is the typical way an application works.
1790 This is used by:
1791 .IP \[bu] 2
1792 almost any shell such as (Bash, Zsh, sh)
1793 .IP \[bu] 2
1794 vim
1795 .IP \[bu] 2
1796 nano
1797 .IP \[bu] 2
1798 emacs
1799 .IP \[bu] 2
1800 mutt
1801 .IP \[bu] 2
1802 tintin++ #### Highlight Tracking
1803 .PP
1804 In some applications there are no text cursors.
1805 In those applications cursor changes are represented by different colors
1806 or attributes (underlined or bold).
1807 This mode tracks and announces these changes for you.
1808 This is used by:
1809 .IP
1810 .nf
1811 \f[C]
1812 *\ wifi\-menu
1813 *\ dialog
1814 *\ alpine
1815 \f[]
1816 .fi
1817 .SS Tutorial Mode
1818 .PP
1819 Fenrir provides a Tutorial mode.
1820 When you enter tutorial mode, screen reader commands are intercepted and
1821 explained instead of executing them.
1822 \[aq]\[aq]Arrow up\[aq]\[aq] and \[aq]\[aq]Arrow Down\[aq]\[aq] let you
1823 navigate through a list of all available commands with shortcuts and
1824 description.
1825 Pressing escape leaves the tutorial mode.
1826 .SS Information
1827 .SS Time
1828 .PP
1829 Announces the current Time.
1830 #### Date
1831 .PP
1832 Announces the current Date.
1833 #### Bookmarks
1834 .PP
1835 Bookmarks provide quick access to part of the screen without the need to
1836 navigate to the area.
1837 By default Fenrir provides 10 bookmarks.
1838 Those can be set and accessed via shortcut.
1839 This is useful for status lines or other information where the position
1840 does not change.
1841 ##### set Bookmark X
1842 .PP
1843 You need to set the bookmark first.
1844 For that you have to set one or two lines for use.
1845 1.
1846 Set marks (one or two) 2.
1847 press shortcut for \[aq]\[aq]set bookmark X\[aq]\[aq].
1848 X represents the number 1 \- 10.
1849 ##### read Bookmark X
1850 .PP
1851 If a bookmark is set you can access the area just by pressing the
1852 \[aq]\[aq]bookmark X\[aq]\[aq] shortcut.
1853 X represents the number 1 \- 10.
1854 Bookmarks are dynamic.
1855 That means the content changes with the screen.
1856 ##### clear Bookmark X
1857 .PP
1858 to remove a bookmark just press the \[aq]\[aq]clear bookmark X\[aq]\[aq]
1859 shortcut.
1860 X represents the number 1 \- 10.
1861 Afterward the bookmark is no longer available.
1862 #### cursor position
1863 .PP
1864 You can get information about the current cursor and its position by
1865 using the "cursor position" functionality.
1866 #### indent current line
1867 .PP
1868 Announce the current indent level of the current line.
1869 It represents the number of trailing spaces of the line.
1870 #### current screen
1871 .PP
1872 Reads all the current screen from the beginning to the end.
1873 #### current screen before cursor
1874 .PP
1875 Reads current screen from the beginning of the screen to the current
1876 cursor position.
1877 #### current screen after cursor
1878 .PP
1879 Read anything after current cursor position to the end.
1880 #### cursor read to end of line
1881 .PP
1882 Read from the current cursor position to the end of the current line.
1883 #### cursor column
1884 .PP
1885 Read the current X position of a cursor (column of the current line).
1886 #### cursor line number
1887 .PP
1888 Read the current Y position of a cursor (line number).
1889 #### present first line
1890 .PP
1891 Reads just the first line.
1892 this is maybe useful for status information.
1893 #### present last line
1894 .PP
1895 Presets the last line.
1896 This is maybe useful for status information.
1897 #### last incoming
1898 .PP
1899 Repeat the last automatically incoming text.
1900 ## Input
1901 .SS Echo
1902 .PP
1903 Fenrir provides different methods of echoing content:
1904 .IP \[bu] 2
1905 Word: Will speak each word after you push space
1906 .IP \[bu] 2
1907 Character: speak any letter you type on the screen
1908 .IP \[bu] 2
1909 Delete Character: speaks the character prior to the cursor when you push
1910 backspace ### Silence on Key press
1911 .SS Spellchecker
1912 .PP
1913 Fenrir has a built\-in spellchecker, it can invoke automatically while
1914 typing or be called by a shortcut.
1915 Commands to add or remove the current word to the dictionary are
1916 included.
1917 As using the spellchecker is enhanced usage.
1918 You will need dictionary aspell\-\f[C]<language>\f[].
1919 See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] for
1920 more information.
1921 #### spell check
1922 .PP
1923 Invokes the spellcheck on the word that contains the Review or text
1924 cursor.
1925 #### add word to spell check
1926 .PP
1927 Adds the word under the Review or Text cursor to the dictionary.
1928 #### removes word from spell check
1929 .PP
1930 Removes the word under the Review or Text cursor from the dictionary.
1931 ## Announcements
1932 .SS Emoticons
1933 .PP
1934 If you want to replace ":)" emoticons with "smile" in speech you can use
1935 this feature.
1936 It can be toggled on or off.
1937 You can define emoticons in a dictionary, please see Emoticon
1938 Dictionary.
1939 See section General (#General) in \[aq]\[aq]settings.conf\[aq]\[aq] to
1940 see how to enable or disable this feature.
1941 .SS Time
1942 .PP
1943 Announce the time at periodical increments, To track the time easily.
1944 You can define 2 different ways of time announcements.
1945 1.
1946 periodic 2.
1947 on fix minutes
1948 .PP
1949 Example periodic, every 20 minutes "delaySec=20":
1950 .IP
1951 .nf
1952 \f[C]
1953 [time]
1954 enabled=True
1955 presentTime=True
1956 presentDate=True
1957 delaySec=20
1958 onMinutes=
1959 announce=True
1960 interrupt=False\ \ \ \
1961 \f[]
1962 .fi
1963 .PP
1964 Example on fix minutes in an hour.
1965 example every quarter "delaySec=0" and "onMinutes=00,15,30,45":
1966 .IP
1967 .nf
1968 \f[C]
1969 [time]
1970 enabled=True
1971 presentTime=True
1972 presentDate=True
1973 #delaySec\ is\ repected\ bevore\ onMinutes\ so\ it\ need\ to\ be\ set\ to\ 0
1974 delaySec=0\
1975 onMinutes=00,15,30,45
1976 announce=True
1977 interrupt=False\ \ \ \ \ \
1978 \f[]
1979 .fi
1980 .SS Promoted List
1981 .PP
1982 Promoted Lists are a nice feature if you are away from your computer or
1983 performing more longer tasks.
1984 you can define a list of words which you want to hear a sound icon for
1985 after a period of inactivity.
1986 Example if the word "Chrys" appears after 120 Seconds of inactivity:
1987 [promote] enabled=True
1988 .PD 0
1989 .P
1990 .PD
1991 inactiveTimeoutSec=120 list=Chrys See section Promote (#Promote) in
1992 \[aq]\[aq]settings.conf\[aq]\[aq] for more information.
1993 ### Punctuation
1994 .PP
1995 Fenrir handles punctuation levels and names for you with several
1996 provided dictionaries.
1997 .PP
1998 See levelDict See punctuationDict ## Braille
1999 .PP
2000 Fenrir provides Braille support in Version >= 2.0.
2001 See section Braille (#Braille) in \[aq]\[aq]settings.conf\[aq]\[aq] for
2002 more information.
2003 ### braille flush
2004 .PP
2005 If a message appears on the Braille device you can flush it to get back
2006 to the review\- or system cursor ### Braille pan left
2007 .PP
2008 If a line is longer than your Braille devices you can move the view
2009 (called panning) to the left.
2010 So you can read stuff without the need to move the review\- or system
2011 cursor.
2012 ### Braille pan right
2013 .PP
2014 If a line is longer than your Braille devices you can move the view
2015 (called panning) to the right.
2016 So you can read stuff without the need to move the review\- or system
2017 cursor.
2018 ### braille return to cursor
2019 .PP
2020 When you have finished reading the line on the Braille device using
2021 panning, the focus can be returned to the current used cursor by using
2022 "return to cursor" command.
2023 ## Dictionary
2024 .PP
2025 You can make use of different kinds of built\-in dictionary\[aq]s.
2026 A dictionary has a name and list of keys and values separated by :===:
2027 Example: [customDict] Chrys:===:Chrys is cool lollipop:===:lolli that
2028 means that every instance "chrys" is displayed, speech will say Chrys is
2029 cool.
2030 "lollipop" is spoken as "lolli".
2031 Before making changes to a dictionary we recommend making a backup of
2032 your current dictionary in case future updates overwrite your local
2033 changes.
2034 ### Punctuation
2035 .SS Level
2036 .PP
2037 The punctuation level dict contains lists with "what punctuation is
2038 spoken in what level".
2039 the default one looks like this: [levelDict] none:===:
2040 some:===:.\-$~+*\-/\\\@ most:===:.,:\-$~+*\-/\@!#%^&\f[I]()[]}{\f[C]<>\f[];
2041 all:===:!"#$%& \[aq]()\f[]+,\-./:;\f[C]<=>\f[]?\@[\\]^_`{|}~ the level
2042 "none" has no values.
2043 so it should not speak any punctuation (sadly this is not respected by
2044 every TTS system) if "some" is the current level the following are
2045 spoken: dot dash dollar tilde plus star slash backslash at.
2046 same for most and all, you can add new levels.
2047 if you cycle punctuation levels they are recognized.
2048 the default punctuation level is set in settings.conf.
2049 The default is "some".
2050 #### Punctuation
2051 .PP
2052 The punctuation dictionary "[punctDict]" contains how the punctuation is
2053 spoken.
2054 Example: [punctDict] \f[I]:===:line
2055 .PD 0
2056 .P
2057 .PD
2058 speaks an \f[] as "line".
2059 .PD 0
2060 .P
2061 .PD
2062 [punctDict] \f[I]:===:underscore speaks an \f[] as underscore.
2063 for question mark an ?
2064 is appended to the word that the TTS system can announce the question
2065 correctly.
2066 .PD 0
2067 .P
2068 .PD
2069 ### Custom
2070 .PP
2071 The dict "[customDict]" is just for your own use, it just replace the
2072 key with the value without any special functionality.
2073 This might be used to fix incorrectly spoken words, make words more
2074 common, shorter or just for fun.
2075 :) ### Emoticons
2076 .PP
2077 The Emoticons dictionary "[emoticonDict]" by default contains some
2078 emoticons.
2079 it can replace ":)" with "smile" or "XD" with "loool" Making chat more
2080 colorful.
2081 A nice feature with this dictionary is that you can toggle the
2082 substitution on or off during run time or in settings.conf.
2083 This is useful because while doing programming or other serious work you
2084 want to hear colons and perryns not smiles.
2085 # Configuration
2086 .PP
2087 You can configure Fenrir in the following places (ordered by priority):
2088 1.
2089 Commandline Parameters \[aq]\[aq]\-o\[aq]\[aq] see Set settings
2090 coption (#Set%20settings%20coption) 2.
2091 /etc/fenrir/settings/settings.conf see Settigns (#Settings) 3.
2092 \f[C]<sourceTree>\f[]/config/settings/settings.conf see
2093 Settigns (#Settings) 4.
2094 hard coded defaults ## Commandline Arguments
2095 .SS Set settings option
2096 .PP
2097 You can specify options that overwrite the setting.conf.
2098 This is done with \[aq]\[aq]\-o \f[C]<list\ of\ options>\f[] parameter.
2099 The list of options have the following syntax fenrir \-o
2100 "section#setting=value;section#setting=value"
2101 .PP
2102 For example changing the sound driver to gstreamer and disabling Braille
2103 .PD 0
2104 .P
2105 .PD
2106 fenrir \-o "sound#driver=gstreamerDriver;braille#enabled=False=False" or
2107 change the debug level to verbose fenrir \-o "general#debugLevel=3" You
2108 can find the available sections and variables here <#Settings> See
2109 Syntax #settings.conf syntax (#settings.conf%20syntax) ### settings.conf
2110 syntax
2111 .PP
2112 the syntax of the settings.conf (#Settings) is quite simple and similar
2113 to a "*.ini" file, there are 4 different elements.
2114 1.
2115 Sections 2.
2116 Settings 3.
2117 Values 4.
2118 Comments
2119 .PP
2120 A comment starts with a # and is ignored by Fenrir.
2121 # this is a comment To group settings we have sections.
2122 A section can look like this: [Section] A setting looks like this:
2123 settingName=Value
2124 .PP
2125 Example: sound (#sound) # Turn sound on or off: enabled=True # Select
2126 the driver used to play sounds, choices are genericDriver and
2127 gstreamerDriver.
2128 # Sox is default.
2129 driver=genericDriver
2130 .SS Settings
2131 .SS Sound
2132 .PP
2133 The sound is configured in section \[aq]\[aq]sound (#sound)\[aq]\[aq].
2134 .PP
2135 Turn sound on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2136 off=\[aq]\[aq]False\[aq]\[aq]
2137 .PP
2138 Select the driver used to play sounds.
2139 The genericDriver using Sox is the default.
2140 .IP
2141 .nf
2142 \f[C]
2143 driver=genericDriver
2144 \f[]
2145 .fi
2146 .PP
2147 Available Drivers:
2148 .IP \[bu] 2
2149 \[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir
2150 <1.5 just use \[aq]\[aq]generic\[aq]\[aq]
2151 .IP \[bu] 2
2152 \[aq]\[aq]gstreamerDriver\[aq]\[aq] using the gstreamer, for Fenrir <1.5
2153 just use \[aq]\[aq]gstreamer\[aq]\[aq]
2154 .PP
2155 These are the pack of sounds used for sound icons.
2156 theme=default By default we ship two sound packs.
2157 1.
2158 \[aq]\[aq]default\[aq]\[aq] opus encoded, for newer Sox versions 2.
2159 \[aq]\[aq]default\-wav\[aq]\[aq] wav encoded, just for compatibility
2160 Sound packs are located at /usr/share/sounds/fenrir/
2161 .PP
2162 Sound volume controls how loud the sounds for your selected sound pack
2163 are.
2164 volume=1.0 Values: \[aq]\[aq]0.0\[aq]\[aq] is quietest,
2165 \[aq]\[aq]1.0\[aq]\[aq] is loudest.
2166 .SS Generic Driver
2167 .PP
2168 The generic sound driver uses shell commands for play sound and
2169 frequencies.
2170 .PP
2171 \[aq]\[aq]genericPlayFileCommand\[aq]\[aq] defines the command that is
2172 used to play a sound file.
2173 genericPlayFileCommand=\f[C]<your\ command\ for\ playing\ a\ file>\f[]
2174 \[aq]\[aq]genericFrequencyCommand\[aq]\[aq] defines the command that is
2175 used playing frequencies.
2176 genericFrequencyCommand=\f[C]<your\ command\ for\ playing\ a\ frequence>\f[]
2177 .PP
2178 The following variables are substituted in
2179 \[aq]\[aq]genericPlayFileCommand\[aq]\[aq] and
2180 \[aq]\[aq]genericFrequencyCommand\[aq]\[aq]:
2181 .IP \[bu] 2
2182 \[aq]\[aq]fenrirVolume\[aq]\[aq] = the current volume setting
2183 .IP \[bu] 2
2184 \[aq]\[aq]fenrirSoundFile\[aq]\[aq] = the sound file for an sound icon
2185 .IP \[bu] 2
2186 \[aq]\[aq]fenrirFrequence\[aq]\[aq] = the frequency to play
2187 .IP \[bu] 2
2188 \[aq]\[aq]fenrirDuration\[aq]\[aq] = the duration of the frequency
2189 .PP
2190 Example genericPlayFileCommand (default) genericPlayFileCommand=play \-q
2191 \-v fenrirVolume fenrirSoundFile Example genericFrequencyCommand
2192 (default) genericFrequencyCommand=play \-q \-v fenrirVolume \-n \-c1
2193 synth fenrirDuration sine fenrirFrequence ### Speech
2194 .PP
2195 Speech is configured in section \[aq]\[aq][speech]\[aq]\[aq].
2196 Turn speech on or off: enabled=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2197 off=\[aq]\[aq]False\[aq]\[aq]
2198 .SH Select speech driver, options are speechdDriver (default),
2199 genericDriver or espeakDriver:
2200 .PP
2201 driver=speechdDriver #driver=espeakDriver
2202 .SH driver=genericDriver
2203 .PP
2204 Select the driver used to generate speech output.
2205 .IP
2206 .nf
2207 \f[C]
2208 driver=speechdDriver
2209 \f[]
2210 .fi
2211 .PP
2212 Available Drivers:
2213 .IP \[bu] 2
2214 \[aq]\[aq]genericDriver\[aq]\[aq] using the generic driver, for Fenrir
2215 <1.5 this is not available
2216 .IP \[bu] 2
2217 \[aq]\[aq]speechdDriver\[aq]\[aq] using speech\-dispatcher, for Fenrir
2218 <1.5 just use \[aq]\[aq]speechd\[aq]\[aq]
2219 .IP \[bu] 2
2220 \[aq]\[aq]espeakDriver\[aq]\[aq] using the espeak directly, for Fenrir
2221 <1.5 just use \[aq]\[aq]espeak\[aq]\[aq]
2222 .PP
2223 The rate selects how fast Fenrir will speak.
2224 rate=0.65 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is slowest,
2225 Maximum:\[aq]\[aq]1.0\[aq]\[aq] is fastest.
2226 .PP
2227 Pitch controls the pitch of the voice.
2228 pitch=0.5 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is lowest,
2229 Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest.
2230 .PP
2231 A Pitch for capital letters can be set.
2232 capitalPitch=0.9 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is
2233 lowest, Maximum:\[aq]\[aq]1.0\[aq]\[aq] is highest.
2234 .PP
2235 The Volume controls the loudness of the voice.
2236 volume=1.0 Values: Range Minimum:\[aq]\[aq]0.0\[aq]\[aq] is quietest,
2237 Maximum:\[aq]\[aq]1.0\[aq]\[aq] is loudest.
2238 .PP
2239 Some speech drivers like speechdDriver can support various modules.
2240 these can be set here.
2241 module=espeak Values: Text, Consult speech\-dispatcher\[aq]s
2242 configuration to see what modules are available.
2243 .PP
2244 Voice selects the varient you want to use, for example, f5 will use the
2245 female voice #5 in Espeak, or if using the Espeak module in
2246 Speech\-dispatcher.
2247 To find out which voices are available, consult the documentation
2248 provided with your selected synthesizer.
2249 voice= Values: Text, see your TTS synths documentation what is
2250 available.
2251 .PP
2252 Select the language you want Fenrir to use.
2253 language=english\-us Values: Text, see your TTS synths documentation
2254 what is available.
2255 .PP
2256 Read new text as it occurs autoReadIncoming=True Values:
2257 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2258 .SS Generic Driver
2259 .PP
2260 The generic speech driver uses shell commands for speech synthisus.
2261 .PP
2262 \[aq]\[aq]genericSpeechCommand\[aq]\[aq] defines the command that is
2263 executed for creating speech The following variables are substituted in
2264 \[aq]\[aq]genericSpeechCommand\[aq]\[aq]:
2265 .IP \[bu] 2
2266 \[aq]\[aq]FenrirText\[aq]\[aq] = is the text that should be spoken
2267 .IP \[bu] 2
2268 \[aq]\[aq]fenrirModule\[aq]\[aq] = may be the speech module like used in
2269 speech\-dispatcher, not every TTY needs this
2270 .IP \[bu] 2
2271 \[aq]\[aq]fenrirLanguage\[aq]\[aq] = the language to speak in
2272 .IP \[bu] 2
2273 \[aq]\[aq]fenrirVoice\[aq]\[aq] = is the current voice that should be
2274 used
2275 .IP \[bu] 2
2276 \[aq]\[aq]fenrirVolume\[aq]\[aq] = is replaced with the current volume
2277 .IP \[bu] 2
2278 \[aq]\[aq]fenrirPitch\[aq]\[aq] = is replaced with the current pitch
2279 .IP \[bu] 2
2280 \[aq]\[aq]fenrirRate\[aq]\[aq] = is replaced with the current speed
2281 (speech rate)
2282 .PP
2283 Example genericSpeechCommand (default): genericSpeechCommand=espeak \-a
2284 fenrirVolume \-s fenrirRate \-p fenrirPitch \-v fenrirVoice "fenrirText"
2285 .PP
2286 These are the minimum and maximum values of the TTS system used in
2287 genericSpeechCommand.
2288 They are needed to calculate the abstract range in volume, rate and
2289 pitch 0.0 \- 1.0.
2290 .IP
2291 .nf
2292 \f[C]
2293 FenrirMinVolume=0
2294 fenrirMaxVolume=200
2295 fenrirMinPitch=0
2296 fenrirMaxPitch=99
2297 fenrirMinRate=80
2298 fenrirMaxRate=450
2299 \f[]
2300 .fi
2301 .PP
2302 The current volume, pitch and rate is calculated like this value = min +
2303 [volume,pitch,rate] * (min \- max ) ### Braille
2304 .PP
2305 Braille is a WIP and not ready yet.
2306 Braille support can be configured in section
2307 \[aq]\[aq][braille]\[aq]\[aq].
2308 .PP
2309 Turn braille on or off: enabled=False Values:
2310 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2311 .PP
2312 Select the driver used for communication with a braille device.
2313 driver=brlapiDriver Values: Text, available Driver Available Drivers:
2314 .IP \[bu] 2
2315 \[aq]\[aq]brlttyDriver\[aq]\[aq] using brltty for braille communication,
2316 for Fenrir <1.5 just use \[aq]\[aq]brltty\[aq]\[aq]
2317 .PP
2318 The Braille layout can be configured here layout=en Values: Text, see
2319 braille driver for layouts.
2320 .PP
2321 What should the flush timeout relate to flushMode=word Values: Text, an
2322 flushMode Existing flushModes:
2323 .IP \[bu] 2
2324 \[aq]\[aq]word\[aq]\[aq] = flush after (number of words to display) *
2325 seconds
2326 .IP \[bu] 2
2327 \[aq]\[aq]char\[aq]\[aq] = flush after (number of chars to display) *
2328 seconds
2329 .IP \[bu] 2
2330 \[aq]\[aq]fix\[aq]\[aq] = flush after X seconds
2331 .IP \[bu] 2
2332 \[aq]\[aq]none\[aq]\[aq] = no automatic flush (manual via shortcut)
2333 .PP
2334 Seconds to flush (see flushMode) flushTimeout=3 Values: Integer, in
2335 Seconds or \[aq]\[aq]\-1\[aq]\[aq] = no automatic flush (manual via
2336 shortcut) The total flush time calculates in relation to flushMode.
2337 .PP
2338 How should the Braille cursor focus be tracked?
2339 cursorFocusMode=page Values: Text, an existing cursor focus mode
2340 Available cursor focus modes:
2341 .IP \[bu] 2
2342 \[aq]\[aq]page\[aq]\[aq] = if the cursor crosses the border move to next
2343 page and start at begin
2344 .IP \[bu] 2
2345 \[aq]\[aq]fixCell\[aq]\[aq] = ajust the cursor on a special cell where
2346 it is always placed.
2347 the display scroll here more smooth.
2348 .PP
2349 Define the cell on the Braille device where Fenrir should scroll and
2350 keep the cursor fixCursorOnCell=\-1 Values: Integer
2351 .IP \[bu] 2
2352 \[aq]\[aq]0\[aq]\[aq] = first cell on device,
2353 .IP \[bu] 2
2354 \[aq]\[aq]\-1\[aq]\[aq] = last cell on device
2355 .IP \[bu] 2
2356 \[aq]\[aq]>0\[aq]\[aq] = fix cell number
2357 .PP
2358 What cursor should Fenrir show on the Braille device
2359 cursorFollowMode=review Values: Text, an exsiting cursor following mode.
2360 Existing cursor following mode:
2361 .IP \[bu] 2
2362 \[aq]\[aq]none\[aq]\[aq] = no automatic toggle command used
2363 .IP \[bu] 2
2364 \[aq]\[aq]review\[aq]\[aq] = priority to review
2365 .IP \[bu] 2
2366 \[aq]\[aq]last\[aq]\[aq] = follow last used cursor
2367 .PP
2368 number of cells in panning (horizontal).
2369 How many cell should be panned on press the routing key?
2370 panSizeHorizontal=0 Values: Integer,
2371 .IP \[bu] 2
2372 \[aq]\[aq]0\[aq]\[aq] = display size
2373 .IP \[bu] 2
2374 \[aq]\[aq]>0\[aq]\[aq] number of cells ### Screen
2375 .PP
2376 The settings for screens, (TTY, PTY) are configured in the
2377 \[aq]\[aq][screen]\[aq]\[aq] section.
2378 .PP
2379 The driver to get the information from the screen: driver=vcsaDriver
2380 Available Drivers:
2381 .IP \[bu] 2
2382 \[aq]\[aq]vcsaDriver\[aq]\[aq] using the VCSA driver (for TTYs), for
2383 Fenrir <1.5 just use \[aq]\[aq]vcsa\[aq]\[aq] The encoding of the screen
2384 encoding=cp850 Values:\[aq]\[aq]cp850\[aq]\[aq] is used for Western
2385 languages like USA or Europe.
2386 .PP
2387 The driver updates Fenrir with changes on the screen.
2388 screenUpdateDelay=0.05 Values: in Seconds
2389 .PP
2390 If you want Fenrir to not be active on any screen for various reasons.
2391 Maybe an X server or Wayland is running on that screen.
2392 You can make Fenrir ignore it or multiple screens seperated by
2393 \[aq]\[aq],\[aq]\[aq] with: suspendingScreen= Values: Depends on driver:
2394 .IP \[bu] 2
2395 VCSA: the number of the TTY.
2396 TTY6 is \[aq]\[aq]6\[aq]\[aq].
2397 Example ignore TTY1 and TTY2: suspendingScreen=1,2
2398 .PP
2399 There is also the ability to let Fenrir auto detect screens that are
2400 running an X server.
2401 So Screens running an GUI can be ignored.
2402 autodetectSuspendingScreen=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2403 off=\[aq]\[aq]False\[aq]\[aq]
2404 .SS Keyboard
2405 .PP
2406 The settings for keyboard and input related configuration is located in
2407 the section \[aq]\[aq]keyboard (#keyboard)\[aq]\[aq] of the
2408 \[aq]\[aq]settings.conf\[aq]\[aq] file.
2409 .PP
2410 Select the driver used for grabbing keybord input and for recieving
2411 shortcuts.
2412 driver=evdevDriver Values: Text, available Driver Available Drivers:
2413 .IP \[bu] 2
2414 \[aq]\[aq]evdevDriver\[aq]\[aq] uses the evdev input system of linux,
2415 for Fenrir <1.5 just use \[aq]\[aq]evdev\[aq]\[aq]
2416 .PP
2417 You can let Fenrir know about what input devices are to be used.
2418 device=ALL Values:
2419 .IP \[bu] 2
2420 \[aq]\[aq]ALL\[aq]\[aq] use all devices with key capabilities.
2421 .IP \[bu] 2
2422 \[aq]\[aq]NOMICE\[aq]\[aq] Exclude mices from handling.
2423 .IP \[bu] 2
2424 \f[C]<Device\ Name>\f[] just use the device with the given name.
2425 .PP
2426 Gives Fenrir exclusive access to the keyboard and lets it control
2427 keystrokes.
2428 This is needed to intercept Fenrir related shortcuts.
2429 grabDevices=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2430 off=\[aq]\[aq]False\[aq]\[aq]
2431 .PP
2432 The following makes sense if you are using a second screenreader and
2433 want to have some hooked events.
2434 Fenrir ignores all shortcuts then.
2435 ignoreShortcuts=False Values: on=\[aq]\[aq]True\[aq]\[aq],
2436 off=\[aq]\[aq]False\[aq]\[aq]
2437 .PP
2438 The current keyboard layout used for shortcuts.
2439 keyboardLayout=desktop Values: An absolute Path to a Keyboard definition
2440 file or a Filename without extension located in
2441 \[aq]\[aq]/etc/fenrir/keyboard\[aq]\[aq]
2442 .PP
2443 Announce characters while typing.
2444 charEcho=False Values: on=\[aq]\[aq]True\[aq]\[aq],
2445 off=\[aq]\[aq]False\[aq]\[aq]
2446 .PP
2447 Announce deleted characters charDeleteEcho=True Values:
2448 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2449 .PP
2450 Announce word after pressing space wordEcho=False Values:
2451 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2452 .PP
2453 Interrupt speech on any keypress interruptOnKeyPress=False Values:
2454 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2455 .PP
2456 You can filter the keys that speech should interrupt
2457 interruptOnKeyPressFilter= Values: (List) empty = all keys, otherwise
2458 interrupt with specified keys
2459 .PP
2460 The timeout that is used for double tap shortcuts doubleTapTimeout=0.2
2461 Values: Seconds ### General
2462 .PP
2463 Overall settings can be configured from the section
2464 \[aq]\[aq]general (#general)\[aq]\[aq].
2465 .PP
2466 Set the current debug level: debugLevel=1 Values: off=0, error=1,
2467 warning=2, info=3
2468 .PP
2469 the current punctuation and dict file in use: punctuationProfile=default
2470 Values: Text, see available profiles in
2471 \[aq]\[aq]/etc/fenrir/punctuation\[aq]\[aq] or in
2472 \[aq]\[aq]sourceTree/config/punctuation\[aq]\[aq]
2473 .PP
2474 The current punctuation level in use: punctuationLevel=some Values:
2475 Text, See available levels in the used punctuation file.
2476 .PP
2477 Respect pause for punctuations: respectPunctuationPause=True Values:
2478 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2479 .PP
2480 Add a pause on Line break: newLinePause=True Values:
2481 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2482 .PP
2483 Specify the path where the clipboard should be exported to.
2484 See export clipboard to file (#export%20clipboard%20to%20file).
2485 The variable \[aq]\[aq]$user\[aq]\[aq] is replaced by the current logged
2486 username.
2487 clipboardExportPath=/tmp/fenrirClipboard Values: Text, Systemfilepath
2488 .PP
2489 The number of available clipboards: numberOfClipboards=10 Values:
2490 Integer, 1 \- 999
2491 .PP
2492 Replace emoticons like :) or ;) with text insertions: emoticons=True
2493 Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2494 .PP
2495 Define the current Fenrir keys: fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
2496 Values, Text list, separated by comma.
2497 .PP
2498 Define the current script keys: scriptKey=KEY_COMPOSE Values, Text list,
2499 separated by comma.
2500 .PP
2501 The time format to be used for (time command) output:
2502 timeFormat=%H:%M:%P Values: see python specification for
2503 datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)
2504 .PP
2505 The date format to be used for (date command) output: dateFormat=%A, %B
2506 %d, %Y Values: see python specification for
2507 datetime.strftime (https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)
2508 .PP
2509 Enable or Disable spellcheck whilst typing: autoSpellCheck=True Values:
2510 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2511 .PP
2512 The use of the dictionary with spellcheck: spellCheckLanguage=en_US
2513 Values: Text, see aspell dictionary\[aq]s.
2514 .PP
2515 Folder Path for your scripts "scriptKey" functionality:
2516 scriptPath=/usr/share/fenrir/scripts Values: Text, Existing path on file
2517 system.
2518 .PP
2519 Override commands or create new ones without changing the Fenrir
2520 defaults: commandPath=/usr/share/fenrir/commands Values: Text, Existing
2521 path on file system.
2522 Subfolders in commandPath are:
2523 .IP \[bu] 2
2524 \[aq]\[aq]commands\[aq]\[aq] = to create shortcut commands
2525 .IP \[bu] 2
2526 \[aq]\[aq]onInput\[aq]\[aq] = executed while typing
2527 .IP \[bu] 2
2528 \[aq]\[aq]onScreenChange\[aq]\[aq] = executed on change the screen
2529 (change from TTY4 to TTY6)
2530 .IP \[bu] 2
2531 \[aq]\[aq]onScreenUpdate\[aq]\[aq] = executed when the screen is
2532 captured
2533 .SS Focus
2534 .PP
2535 The configuration for basic focus is in the section
2536 \[aq]\[aq]focus (#focus)\[aq]\[aq].
2537 Follow the text cursor: cursor=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2538 off=\[aq]\[aq]False\[aq]\[aq]
2539 .PP
2540 Follow highlighted text changes (Highlight Tracking): highlight=False
2541 Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] ###
2542 Review
2543 .PP
2544 Configurations for the review mode are in the section
2545 \[aq]\[aq][review]\[aq]\[aq].
2546 .PP
2547 If "next word/ char" or "prev word/char" create a linebreak, announce
2548 it: lineBreak=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2549 off=\[aq]\[aq]False\[aq]\[aq]
2550 .PP
2551 If "next word/ char" or "prev word/char" cannot be performed because you
2552 reached the end of the screen, announce it: endOfScreen=True Values:
2553 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2554 .PP
2555 Leave the review mode when pressing a key: leaveReviewOnKeypress=False
2556 Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2557 .PP
2558 Leave the review mode when changing the screen (From TTY3 to TTY4):
2559 leaveReviewOnScreenChange=True Values: on=\[aq]\[aq]True\[aq]\[aq],
2560 off=\[aq]\[aq]False\[aq]\[aq] ### Promote
2561 .PP
2562 "Promoted Lists" are configured in the section
2563 \[aq]\[aq][promote]\[aq]\[aq].
2564 Turn Promoted Lists" on or off: enabled=True Values:
2565 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2566 .PP
2567 The minimum time interval of inactivity to activate promoting.
2568 By default it promotes after 120 Seconds inactivity:
2569 inactiveTimeoutSec=120 Values: in Seconds
2570 .PP
2571 Define a list of promoted words comma seperated: list= Values: text
2572 (comma seperated) Example to promote the word "nickname" or a bash
2573 prompt: list=nickname,$:,#:
2574 .SS Time
2575 .PP
2576 The automated time announcement is configured in the section
2577 \[aq]\[aq]time (#time-2)\[aq]\[aq].
2578 Time announcement is disabled by default.
2579 Turn time announcement on or off: enabled=True Values:
2580 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2581 .PP
2582 Should the time be announced: presentTime=True Values:
2583 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2584 .PP
2585 Should the date be announced (just on date change): presentDate=True
2586 Values: on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2587 .PP
2588 Announce after a given period of seconds: delaySec=0 Value: in Seconds,
2589 0 = Deactivated
2590 .PP
2591 Announce after fixed minutes in an hour.
2592 if delaySec is >0 onMinutes is ignored: onMinutes=00,30 Example every 15
2593 minutes: onMinutes=00,15,30,45
2594 .PP
2595 Just play a soundicon, (not interrupting): announce=True Values:
2596 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq]
2597 .PP
2598 Interrupt current speech for time announcement: interrupt=False Values:
2599 on=\[aq]\[aq]True\[aq]\[aq], off=\[aq]\[aq]False\[aq]\[aq] #
2600 Customization
2601 .SS Scripting
2602 .PP
2603 Scripts can be in any language, bash, python, sh or others.
2604 Place your scripts in the directory /usr/share/fenrir/scripts/ (the path
2605 is configurable in settings.conf).
2606 The script key is the applications key.
2607 Usually this key can be found on the keyboard located just left of the
2608 right most control key.
2609 When you name a script, the key name appears in the script seperated by
2610 the sequence \f[B]\-\f[].
2611 So, for example, if you have a python weather script you want assigned
2612 to the script key plus the letter w you would name the script
2613 /usr/share/fenrir/scripts/weather__\-__key_w.py Then, to access the
2614 script, simply press the script key and the letter w.
2615 Scripts must be executable.
2616 So, make sure to chmod 755 your script when you place it in the scripts
2617 directory.
2618 The script gets some parameters from fenrir when it is executed.
2619 So that information is available in your script then.
2620 .SS Parameterlist
2621 .PP
2622 .TS
2623 tab(@);
2624 l l.
2625 T{
2626 Parameter
2627 T}@T{
2628 Content
2629 T}
2630 _
2631 T{
2632 $1
2633 T}@T{
2634 Username of the current logged in user
2635 T}
2636 .TE
2637 .SS Examples
2638 .PP
2639 Script that just speaks the current username when pressing ScriptKey +
2640 H.\\ File:
2641 \[aq]\[aq]/usr/share/fenrir/scripts/helloWorld__\-__key_h.sh\[aq]\[aq]:
2642 #!/bin/bash echo $1
2643 .SS Commands
2644 .PP
2645 You can place your own commands in "/usr/share/fenrir/commands" (path is
2646 configurable in settings.conf).
2647 Commands are python files with a special scheme.
2648 You can assign them to a shortcut using the filename without an
2649 extension or place them in a hook trigger like OnInput or
2650 OnScreenChange.
2651 For further information see developer guide.
2652 Good Examples:
2653 "date.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/date.py)
2654 (announce the Date),
2655 "shut_up.py" (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/commands/shut_up.py)
2656 (interrupt output) the basic scheme for a command is as follows:
2657 .IP
2658 .nf
2659 \f[C]
2660 from\ core\ import\ debug
2661
2662 class\ command():
2663 \ \ def\ __init__(self):
2664 \ \ \ \ \ \ pass
2665 \ \ def\ initialize(self,\ environment):
2666 \ \ \ \ \ \ self.env\ =\ environment
2667 \ \ def\ shutdown(self):
2668 \ \ \ \ \ \ pass
2669 \ \ def\ getDescription(self):
2670 \ \ \ \ \ \ return\ _(\[aq]No\ description\ found\[aq])
2671 \ \ def\ run(self):
2672 \ \ \ \ \ \ pass
2673 \ \ def\ setCallback(self,\ callback):
2674 \ \ \ \ \ \ pass
2675 \f[]
2676 .fi
2677 .IP \[bu] 2
2678 Template lives
2679 here (https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py)
2680 .IP \[bu] 2
2681 The class needs to have the name "command".
2682 .IP \[bu] 2
2683 "initialize" is running once whilst loading the command.
2684 .IP \[bu] 2
2685 "shutdown" is running on unload like the command (quit fenrir)
2686 .IP \[bu] 2
2687 "getDescriptsion" just returns an string.
2688 That String is used in Tutorial Mode.
2689 .IP \[bu] 2
2690 "run" is executed when the command is invoked.
2691 (shortcut is pressed, or trigger isn\[aq]t running)
2692 .IP \[bu] 2
2693 setCAllback is currently not used.
2694 and has no functionality yet.
2695 .SH Troubleshooting
2696 .SS Fenrir does not start
2697 .IP " 1." 4
2698 Have you installed all the dependencies Support and
2699 Requirements (#Support%20and%20Requirements)
2700 .IP " 2." 4
2701 Try using master, a lot of changes take place there to make Fenrir
2702 compatible with more systems ## Fenrir does not utilize the shortcuts
2703 .IP " 3." 4
2704 Make sure you have python3\-evdev installed
2705 .IP " 4." 4
2706 Use the latest Fenrir version
2707 .IP " 5." 4
2708 Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or
2709 run it as root) ## No sound at all
2710 .IP " 6." 4
2711 Run the script to configure Pulseaudio once as root and once as your
2712 user.
2713 This will setup Pulseaudio but require a restart of Pulseaudio.
2714 The script is located in \[aq]\[aq]tools/configure_pulse.sh\[aq]\[aq]
2715 .IP " 7." 4
2716 Use ALSA
2717 .IP " 8." 4
2718 Configure Pulse system
2719 wide (https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/)
2720 (Not recommended)
2721 .IP " 9." 4
2722 Use gstreamerDriver: change \[aq]\[aq]settings.conf\[aq]\[aq] in the
2723 section \[aq]\[aq]sound\[aq]\[aq] the line
2724 \[aq]\[aq]driver=genericDriver\[aq]\[aq] to
2725 \[aq]\[aq]driver=gstreamerDriver\[aq]\[aq]
2726 .IP "10." 4
2727 Use wave sound\-icons: change \[aq]\[aq]settings.conf\[aq]\[aq] in the
2728 section \[aq]\[aq]sound\[aq]\[aq] the line
2729 \[aq]\[aq]theme=default\[aq]\[aq] to
2730 \[aq]\[aq]theme=default\-wav\[aq]\[aq]
2731 .IP "11." 4
2732 Use most current version of sox (http://sox.sourceforge.net/) with opus
2733 support
2734 .IP "12." 4
2735 Try apulse (https///github.com/i-rinat/apulse) (not tested by myself but
2736 might work).
2737 Please give me feedback if you try it out.
2738 ## You get sound\-icons but no speech
2739 .IP "13." 4
2740 If you are using speech\-dispatcher run "spd\-conf" once as user and as
2741 root.
2742 .IP "14." 4
2743 You can test if speech\-dispatcher works by invoking it as root\\
2744 \[aq]\[aq]sudo spd\-say "hello world"\[aq]\[aq] ## Bugreports and
2745 feature requests
2746 .PP
2747 Please report Bugs and feature requests to:
2748 https://github.com/chrys87/fenrir/issues (https///github.com/chrys87/fenrir/issues)
2749 .PP
2750 for bugs please provide a debug (#Howto%20create%20a%20debug%20file)
2751 file that shows the issue.
2752 ### How\-to create a debug file
2753 .IP "1." 3
2754 Delete old debug stuff\\ \[aq]\[aq]sudo rm /var/log/fenrir.log\[aq]\[aq]
2755 .IP "2." 3
2756 Start fenrir in debug mode\\ \[aq]\[aq]sudo fenrir \-d\[aq]\[aq]
2757 .IP "3." 3
2758 Do your stuff to reproduce the problem
2759 .IP "4." 3
2760 Stop fenrir (\[aq]\[aq]fenrirKey + q\[aq]\[aq]) the debug file is
2761 located in \[aq]\[aq]/var/log/fenrir.log\[aq]\[aq]
2762 .PP
2763 Please be as precise as possible to make it easy to solve the problem.
0 # Fenrir User Manual
1
2 Fenrir is a modern command line screen reader written in Python3.
3
4 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)).
5
6 Please see the following pages for the [current](fenrir_current_version) and [Git](fenrir_git_version) version of Fenrir.
7
8
9 # Support and Requirements
10
11
12 Fenrir requires several drivers to interact with the operating system.
13
14 ## Speech Drivers
15
16
17 A speech driver is for communication with the text to speech system like [Speech-Dispatcher](#SpeechDispatcher) or [Espeak](http://espeak.sourceforge.net). \\
18 See section [Speech](#Speech) in ''settings.conf'' for more information.
19
20
21 ### SpeechDispatcher
22
23
24 This driver is used by default.
25 It uses Speech-dispatcher as its backend.
26
27 Dependencies:
28
29
30 * Speech-dispatcher (installed and configured, [Documentation](https///devel.freebsoft.org/speechd#sec2))
31
32 * Python-speechd
33
34 ### Espeak
35
36
37 Uses Espeak via Python bindings.
38
39 Dependencies:
40
41 * Espeak or Espeak-ng
42
43 * [python-espeak](https///launchpad.net/python-espeak)
44
45 ### Generic
46
47
48 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.
49
50 Dependencies:
51
52 * Espeak or Espeak-ng
53
54 The Requirements are flexible, they depend on the configuration in settings.conf.
55
56 ### Dummy
57
58
59 this is just for debugging, logs are output to the screen and logged as well.
60
61 ## Sound Drivers
62
63
64 To play sound icons and similar.\\
65 See section [Sound](#Sound) in ''settings.conf'' for more information.
66
67 ### Generic
68
69
70 This driver is used by default.
71
72 Dependencies:
73
74
75 * [Sox](http://sox.sourceforge.net/) with opus support
76 The Requirements are flexible, they depend on the configuration in settings.conf.
77
78 ### Gstreamer
79
80 if you prefer to use Gstreamer for sound output.
81
82 Dependencies:
83
84 * Gstreamer >= 1.x
85
86 * Glibc
87
88 ### Dummy
89
90
91 this is just for debugging, logs are output to the screen and logged as well.
92
93 ## Input Drivers
94
95
96 Input drivers are to capture keyboard shortcuts issued to the screen reader \
97 See section [Keyboard](#Keyboard) in ''settings.conf'' for more information.
98
99 ### Evdev
100
101
102 This driver is used by default.
103
104 Evdev is the low level input device framework for Linux.
105
106 Dependencies:
107
108
109 * python-evdev >=0.6.3
110
111 * pyudev
112
113 * loaded uinput kernel module
114
115 * exclusive access to the input devices
116 Read permission to the following files and services:
117
118 * /dev/input
119
120 * /dev/uinput
121
122 ## Screen Drivers
123
124
125 The job of a screen driver is to get the information of current screen content.\\
126 See section [Screen](#Screen) in ''settings.conf'' for more information.
127
128 ### VCSA
129
130
131 This driver is used by default.
132 For Linux VCSA devices. These exist on any current standard installation of Linux.
133
134 Dependencie
135 s:
136
137
138 * python-dbus
139 Read permission to the following files and services (or run as root):
140
141 * /sys/devices/virtual/tty/tty0/active
142
143 * /dev/tty[1 - 64]
144
145 * /dev/vcsa[1 - 64] ([VCSA manpage](https///linux.die.net/man/4/vcsa))
146
147 * read Logind DBUS
148
149 ## Braille Drivers
150
151 This is for Braille support.
152 Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\
153 See section [Braille](#Braille) in ''settings.conf'' for more information.
154
155
156 ### BRLTTY
157
158
159 This driver is used by default.
160 It uses [BrlTTY](brltty) to communicate with with a Braille device.
161
162 Dependencies:
163
164
165 * BrlTTY (configured and running, [Documentation](http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html))
166
167 * python-brlapi (configured, [Documentation](http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html))
168 ## Currently supported platforms
169
170
171 Currently Fenrir completely supports the following Platforms:
172
173 * Linux TTY
174 Support for further Systems are planned.
175
176 # Installation
177
178
179 Fenrir can run without installation. It just requires the dependencies are installed first.
180
181 We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment.
182
183 ## Try Out
184
185 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.
186 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)
187
188 ## Install it
189
190 ### Documented operating systems
191
192
193 ### Arch Linux
194
195
196 For Arch there are PKGBUILDs in the AUR:
197
198 * [fenrir](https///aur.archlinux.org/packages/fenrir/)
199
200 * [fenrir-git](https///aur.archlinux.org/packages/fenrir-git/)
201
202 ### Manual
203
204
205 1. Download the latest stable version from the [Fenrir-Project](https///linux-a11y.org/index.php?page=fenrir-screenreader) site.
206 2. Unpack the archive
207 3. Check the needed Dependencys by running [check-dependencys.py](https///github.com/chrys87/fenrir/blob/master/check-dependencies.py) script
208 4. install the missing dependencies an standard installation requires the following:
209
210 * python3 >= 3.3 (and all the following is needed for python3 )
211 * python3-speechd (screen)
212 * python3-dbus (screen)
213 * python3-evdev >= 0.6.4(input)
214 * python3-daemonize (background service)
215 * python3-brlapi (braille)
216 * python3-pyenchant (spellchecker)
217 * your language for aspell (aspell-`<lang>`) (spellchecker)
218 * sox (sound)
219 * For an individual installation see [Support and Requirements](#Support and Requirements) or consult the [Readme](https///github.com/chrys87/fenrir/blob/master/README.md))
220 5. run "install.sh" as root
221
222 this installs Fenrir as the following
223
224 * Application:''/opt/fenrir''
225 * Settings:''/etc/fenrir''
226 * Sound Icons:''/usr/share/fenrir/''
227
228 to remove Fenrir just run uninstall.sh as root
229
230 ### Git
231
232
233 if you want to get the latest code you can use git to get a development snapshot:
234
235 git clone https://github.com/chrys87/fenrir.git
236
237 ## Auto Start
238
239
240 To start Fenrir once:
241 systemctl start fenrir
242
243 To enable auto start on system boot:
244 systemctl enable fenrir
245
246 # First Steps
247
248
249 If you are using Fenrir for the first time you may want to take a look at these resources:
250
251 * [Keybindings](#Keybindings)
252
253 * [Tutorial Mode](#Tutorial Mode)
254
255 # Features
256
257
258 ## Commands
259
260
261 ### Keybindings
262
263
264 Normal commands can be invoked in two ways:
265 1. Using a Metakey ([FenrirKey](#Fenrir Key))
266 2. Shortcuts with a single key
267
268 See section [Keyboard](#Keyboard) in ''settings.conf'' for more information.
269 #### Fenrir Key
270
271 The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time.
272 By default the following keys are used:
273 1. Insert
274 2. KeyPad Insert
275 3. Meta (Super, Windows)
276
277 #### Script Key
278
279 To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [Scripting](#Scripting)
280 #### Desktop Layout
281
282 | Shortcut | Command |
283 | -------- | ------- |
284 | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) |
285 | CTRL | [shut up (interrupts speech)](#shut up) |
286 | FenrirKey + KeyPad 9 | [reviews bottom](#review bottom) |
287 | FenrirKey + KeyPad 7 | [reviews top](#review top) |
288 | KeyPad 8 | [reviews current line](#review current line) |
289 | KeyPad 7 | [reviews previous line](#review previous line) |
290 | KeyPad 9 | [reviews next line](#review next line) |
291 | FenrirKey + KeyPad 4 | [reviews line beginning](#review line beginning) |
292 | FenrirKey + KeyPad 6 | [reviews line ending](#review line ending) |
293 | FenrirKey + KeyPad 1 | [reviews line first character](#review line first character) |
294 | FenrirKey + KeyPad 3 | [reviews line last character](#review line last character) |
295 | FenrirKey + Alt + 1 | [presents first line](#present first line) |
296 | FenrirKey + Alt + 2 | [presents last line](#present last line) |
297 | KeyPad 5 | [reviews current word](#review current word) |
298 | KeyPad 4 | [reviews previous word](#review previous word) |
299 | KeyPad 6 | [reviews next word](#review next word) |
300 | FenrirKey + Shift + KeyPad 5 | [reviews current word phonetic](#review current word phonetic) |
301 | FenrirKey + Shift + KeyPad 4 | [reviews previous word phonetic](#review previous word phonetic) |
302 | FenrirKey + Shift + KeyPad 6 | [reviews next word phonetic](#review next word phonetic) |
303 | KeyPad 2 | [reviews current char](#review current character) |
304 | KeyPad 1 | [reviews previous char](#review previous character) |
305 | KeyPad 3 | [reviews next char](#review next character) |
306 | FenrirKey + Shift + KeyPad 2 | [reviews current character phonetic](#review current character phonetic) |
307 | FenrirKey + Shift + KeyPad 1 | [reviews previous character phonetic](#review previous character phonetic) |
308 | FenrirKey + Shift + KeyPad 3 | [reviews next character phonetic](#review next character phonetic) |
309 | FenrirKey + CTRL + KeyPad 8 | [reviews up](#review up) |
310 | FenrirKey + CTRL + KeyPad 2 | [reviews down](#review down) |
311 | FenrirKey + KeyPad dot | [exit review](#exit review) |
312 | KeyPad dot | [cursor position](#cursor position) |
313 | FenrirKey + I | [indent curr line](#indent current line) |
314 | FenrirKey + KeyPad 5 | [current screen](#current screen) |
315 | FenrirKey + KeyPad 8 | [current screen before cursor](#current screen before cursor) |
316 | FenrirKey + KeyPad 2 | [current screen after cursor](#current screen after cursor) |
317 | `<Unbound>` | [cursor read to end of line](#cursor read to end of line) |
318 | `<Unbound>` | [cursor column](#cursor column) |
319 | `<Unbound>` | [cursor line number](#cursor line number) |
320 | `<Unbound>` | [Braille flush](#braille flush) |
321 | `<Unbound>` | [Braille pan left](#braille pan left) |
322 | `<Unbound>` | [Braille pan right](#braille pan right) |
323 | `<Unbound>` | [Braille return to cursor](#braille return to cursor) |
324 | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) |
325 | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) |
326 | FenrirKey + 1 | [bookmark 1](#read Bookmark X) |
327 | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) |
328 | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) |
329 | FenrirKey + 2 | [bookmark 2](#read Bookmark X) |
330 | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) |
331 | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) |
332 | FenrirKey + 3 | [bookmark 3](#read Bookmark X) |
333 | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) |
334 | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) |
335 | FenrirKey + 4 | [bookmark 4](#read Bookmark X) |
336 | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) |
337 | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) |
338 | FenrirKey + 5 | [bookmark 5](#read Bookmark X) |
339 | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) |
340 | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) |
341 | FenrirKey + 6 | [bookmark 6](#read Bookmark X) |
342 | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) |
343 | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) |
344 | FenrirKey + 7 | [bookmark 7](#read Bookmark X) |
345 | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) |
346 | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) |
347 | FenrirKey + 8 | [bookmark 8](#read Bookmark X) |
348 | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) |
349 | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) |
350 | FenrirKey + 9 | [bookmark 9](#read Bookmark X) |
351 | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) |
352 | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) |
353 | FenrirKey + 0 | [bookmark 10](#read Bookmark X) |
354 | FenrirKey + KeyPad Slash | [set window application](#Create Window) |
355 | 2 * FenrirKey + KeyPad Slash | [clear window application](#Remove Window) |
356 | KeyPad Plus | [read last incoming](#last incoming) |
357 | FenrirKey + F2 | [toggles braille](#toggle braille) |
358 | FenrirKey + F3 | [toggles sound](#toggle sound) |
359 | FenrirKey + F4 | [toggles speech](#toggle speech) |
360 | KeyPad Enter | [temporarily disables speech](#disable speech temporarily) |
361 | FenrirKey + CTRL + P | [toggles punctuation level](#toggle punctuation level) |
362 | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) |
363 | FenrirKey + Backslash | [toggles output](#toggle output) |
364 | FenrirKey + CTRL + E | [toggles emoticons](#toggle emoticons) |
365 | FenrirKey + KeyPad Enter | [toggles auto read](#toggle auto read) |
366 | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) |
367 | FenrirKey + KeyPad ASTERISK | [toggles highlight tracking](#toggle highlight tracking) |
368 | FenrirKey + Q | [quits fenrir](#quit Fenrir) |
369 | FenrirKey + T | [Announce time](#Time) |
370 | 2 * FenrirKey + T | [Announce date](#Date) |
371 | FenrirKey + S | [spell check](#spell check) |
372 | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) |
373 | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) |
374 | FenrirKey + Backspace | [forward keypress](#forward keypress) |
375 | FenrirKey + Up | [increase speech volume](#increase speech volume) |
376 | FenrirKey + Down | [decrease speech volume](#decrease speech volume) |
377 | FenrirKey + Right | [increase speech rate](#increase speech rate) |
378 | FenrirKey + Left | [decrease speech rate](#decrease speech rate) |
379 | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) |
380 | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) |
381 | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) |
382 | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) |
383 | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) |
384 | FenrirKey + Home | [first clipboard](#first clipboard) |
385 | FenrirKey + End | [last clipboard](#last clipboard) |
386 | FenrirKey + PageUp | [previous clipboard](#previous clipboard) |
387 | FenrirKey + PageDown | [next clipboard](#next clipboard) |
388 | FenrirKey + Shift + C | [current clipboard](#read current clipboard) |
389 | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) |
390 | FenrirKey + V | [paste clipboard contents](#paste clipboard) |
391 | FenrirKey + P | [import clipboard from file](#import clipboard from file) |
392 | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) |
393 | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) |
394 | FenrirKey + X | [set mark](#Set mark) |
395 | FenrirKey + Shift + X | [announce marked text](#Get text between marks) |
396 | Linux specific |
397 | `<Unbound>` | export clipboard to X |
398 | FenrirKey + CTRL + Up | include Alsa volume |
399 | FenrirKey + CTRL + Down | decrease Alsa volume |
400
401 #### Laptop Layout
402
403 | Shortcut | Command |
404 | -------- | ------- |
405 | FenrirKey + H | [toggle tutorial mode](#Tutorial Mode) |
406 | CTRL | [shut up (interrupts speech)](#shut up) |
407 | FenrirKey + Shift + O | [reviews bottom](#review bottom) |
408 | FenrirKey + Shift + U | [reviews top](#review top) |
409 | FenrirKey + I | [reviews current line](#review current line) |
410 | FenrirKey + U | [reviews previous line](#review previous line) |
411 | FenrirKey + O | [reviews next line](#review next line) |
412 | FenrirKey + Shift + J | [reviews line beginning](#review line beginning) |
413 | FenrirKey + Shift + L | [reviews line ending](#review line ending) |
414 | FenrirKey + CTRL + J | [reviews line first character](#review line first character) |
415 | FenrirKey + CTRL + L | [reviews line last character](#review line last character) |
416 | FenrirKey + Alt + 1 | [presents first line](#present first line) |
417 | FenrirKey + Alt + 2 | [presents last line](#present last line) |
418 | FenrirKey + K | [reviews current word](#review current word) |
419 | FenrirKey + J | [reviews previous word](#review previous word) |
420 | FenrirKey + L | [reviews next word](#review next word) |
421 | FenrirKey + CTRL + ALT + K | [reviews current word phonetic](#review current word phonetic) |
422 | FenrirKey + CTRL + ALT + J | [reviews previous word phonetic](#review previous word phonetic) |
423 | FenrirKey + CTRL + ALT + L | [reviews next word phonetic](#review next word phonetic) |
424 | FenrirKey + comma | [reviews current character](#review current character) |
425 | FenrirKey + M | [reviews previous character](#review previous character) |
426 | FenrirKey + dot | [reviews next character](#review next character) |
427 | FenrirKey + CTRL + ALT + comma | [reviews current character phonetic](#review current character phonetic) |
428 | FenrirKey + CTRL + ALT + M | [reviews previous character phonetic](#review previous character phonetic) |
429 | FenrirKey + CTRL + ALT + dot | [reviews next character phonetic](#review next character phonetic) |
430 | FenrirKey + CTRL + I | [reviews up](#review up) |
431 | FenrirKey + CTRL + comma | [reviews down](#review down) |
432 | FenrirKey + Slash | [exit review](#exit review) |
433 | FenrirKey + Shift + dot | [cursor position](#cursor position) |
434 | 2 * FenrirKey + I | [indent curr line](#indent current line) |
435 | FenrirKey + Shift + K | [current screen](#current screen) |
436 | FenrirKey + Shift + I | [current screen before cursor](#current screen before cursor) |
437 | FenrirKey + Shift + comma | [current screen after cursor](#current screen after cursor) |
438 | `<Unbound>` | [cursor read to end of line](#cursor read to end of line) |
439 | `<Unbound>` | [cursor column](#cursor column) |
440 | `<Unbound>` | [cursor line number](#cursor line number) |
441 | `<Unbound>` | [Braille flush](#braille flush) |
442 | `<Unbound>` | [Braille pan left](#braille pan left) |
443 | `<Unbound>` | [Braille pan right](#braille pan right) |
444 | `<Unbound>` | [Braille return to cursor](#braille return to cursor) |
445 | FenrirKey + CTRL + 1 | [clear bookmark 1](#clear Bookmark X) |
446 | FenrirKey + Shift + 1 | [set bookmark 1](#set Bookmark X) |
447 | FenrirKey + 1 | [bookmark 1](#read Bookmark X) |
448 | FenrirKey + CTRL + 2 | [clear bookmark 2](#clear Bookmark X) |
449 | FenrirKey + Shift + 2 | [set bookmark 2](#set Bookmark X) |
450 | FenrirKey + 2 | [bookmark 2](#read Bookmark X) |
451 | FenrirKey + CTRL + 3 | [clear bookmark 3](#clear Bookmark X) |
452 | FenrirKey + Shift + 3 | [set bookmark 3](#set Bookmark X) |
453 | FenrirKey + 3 | [bookmark 3](#read Bookmark X) |
454 | FenrirKey + CTRL + 4 | [clear bookmark 4](#clear Bookmark X) |
455 | FenrirKey + Shift + 4 | [set bookmark 4](#set Bookmark X) |
456 | FenrirKey + 4 | [bookmark 4](#read Bookmark X) |
457 | FenrirKey + CTRL + 5 | [clear bookmark 5](#clear Bookmark X) |
458 | FenrirKey + Shift + 5 | [set bookmark 5](#set Bookmark X) |
459 | FenrirKey + 5 | [bookmark 5](#read Bookmark X) |
460 | FenrirKey + CTRL + 6 | [clear bookmark 6](#clear Bookmark X) |
461 | FenrirKey + Shift + 6 | [set bookmark 6](#set Bookmark X) |
462 | FenrirKey + 6 | [bookmark 6](#read Bookmark X) |
463 | FenrirKey + CTRL + 7 | [clear bookmark 7](#clear Bookmark X) |
464 | FenrirKey + Shift + 7 | [set bookmark 7](#set Bookmark X) |
465 | FenrirKey + 7 | [bookmark 7](#read Bookmark X) |
466 | FenrirKey + CTRL + 8 | [clear bookmark 8](#clear Bookmark X) |
467 | FenrirKey + Shift + 8 | [set bookmark 8](#set Bookmark X) |
468 | FenrirKey + 8 | [bookmark 8](#read Bookmark X) |
469 | FenrirKey + CTRL + 9 | [clear bookmark 9](#clear Bookmark X) |
470 | FenrirKey + Shift + 9 | [set bookmark 9](#set Bookmark X) |
471 | FenrirKey + 9 | [bookmark 9](#read Bookmark X) |
472 | FenrirKey + CTRL + 0 | [clear bookmark 10](#clear Bookmark X) |
473 | FenrirKey + Shift + 0 | [set bookmark 10](#set Bookmark X) |
474 | FenrirKey + 0 | [bookmark 10](#read Bookmark X) |
475 | FenrirKey + CTRL + 8 | [set window application](#Create Window) |
476 | 2 * FenrirKey + CTRL + 8 | [clear window application](#Remove Window) |
477 | FenrirKey + Semicolon | [read last incoming](#last incoming) |
478 | FenrirKey + F2 | [toggles braille](#toggle braille) |
479 | FenrirKey + F3 | [toggles sound](#toggle sound) |
480 | FenrirKey + F4 | [toggles speech](#toggle speech) |
481 | FenrirKey + Enter | [temporarily disables speech](#disable speech temporarily) |
482 | FenrirKey + Shift + CTRL + P | [toggles punctuation level](#toggle punctuation level) |
483 | FenrirKey + RightBrace | [toggle auto spell check](#toggle auto spell check) |
484 | FenrirKey + Shift + Enter | [toggles output](#toggle output) |
485 | FenrirKey + Shift + E | [toggles emoticons](#toggle emoticons) |
486 | FenrirKey + Enter | [toggles auto read](#toggle auto read) |
487 | FenrirKey + CTRL + T | [toggles auto time](#toggle auto time) |
488 | FenrirKey + Y | [toggles highlight tracking](#toggle highlight tracking) |
489 | FenrirKey + Q | [quits fenrir](#quit Fenrir) |
490 | FenrirKey + T | [Announce time](#Time) |
491 | 2 * FenrirKey + T | [Announce date](#Date) |
492 | FenrirKey + S | [spell check](#spell check) |
493 | 2 * FenrirKey + S | [add word to spell check](#add word to spell check) |
494 | FenrirKey + Shift + S | [removes word from spell check](#removes word from spell check) |
495 | FenrirKey + Backspace | [forward keypress](#forward keypress) |
496 | FenrirKey + Up | [increase speech volume](#increase speech volume) |
497 | FenrirKey + Down | [decrease speech volume](#decrease speech volume) |
498 | FenrirKey + Right | [increase speech rate](#increase speech rate) |
499 | FenrirKey + Left | [decrease speech rate](#decrease speech rate) |
500 | FenrirKey + Alt + Right | [increase speech pitch](#increase speech pitch) |
501 | FenrirKey + Alt + Left | [decrease speech pitch](#decrease speech pitch) |
502 | FenrirKey + Alt + Up | [increase sound volume](#increase sound volume) |
503 | FenrirKey + Alt + Down | [decrease sound volume](#decrease sound volume) |
504 | FenrirKey + CTRL + Shift + C | [clears clipboard](#clear clipboard) |
505 | FenrirKey + Home | [first clipboard](#first clipboard) |
506 | FenrirKey + End | [last clipboard](#last clipboard) |
507 | FenrirKey + PageUp | [previous clipboard](#previous clipboard) |
508 | FenrirKey + PageDown | [next clipboard](#next clipboard) |
509 | FenrirKey + Shift + C | [current clipboard](#read current clipboard) |
510 | FenrirKey + C | [copy marked text to clipboard](#copy marked to clipboard) |
511 | FenrirKey + V | [paste clipboard contents](#paste clipboard) |
512 | FenrirKey + F5 | [import clipboard from file](#import clipboard from file) |
513 | FenrirKey + Alt + Shift +C | [export clipboard to file](#export clipboard to file) |
514 | FenrirKey + CTRL + Shift + X | [remove marks](#Remove Marks) |
515 | FenrirKey + X | [set mark](#Set mark) |
516 | FenrirKey + Shift + X | [announce marked text](#Get text between marks) |
517 | Linux specific |
518 | `<Unbound>` | export clipboard to X |
519 | FenrirKey + CTRL + Up | increases Alsa volume |
520 | FenrirKey + CTRL + Down | decreases Alsa volume |
521 ### General
522
523 #### quit Fenrir
524 Just stops fenrir.
525 #### shut up
526
527 Interrupt the current spoken.
528 ### Review Modes
529
530 Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor.
531
532 Using the review feature will open the review mode automatically.
533
534 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.
535
536 Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor.
537
538 Fenrir sounds a bell sound if the used review command jumps to another line or end of screen.
539 #### exit review
540
541 You can leave the review mode by pressing the ''exit review'' shortcut.
542 #### review bottom
543
544 Set the review cursor to first column in the last line.
545 #### review top
546
547 Set the review cursor to the first column in the first line
548 #### review current line
549
550 Set the review cursor to the beginn of the the current line and review it.
551 #### review previous line
552
553 Set the review cursor to the previous line and review it.
554 #### review next line
555
556 Set the review cursor to the next line and review it.
557 #### review line beginning
558
559 Set the review cursor to the begin of the current line
560 #### review line ending
561
562 Set the review cursor to the end of the current line
563 #### review line first character
564
565 Set the review cursor the first char (that is not space) in the current line and review it.
566 #### review line last character
567
568 Set the review cursor the last char (that is not space) in the current line and review it.
569 #### review current word
570
571 Sets the review cursor to the beginning of the current word and review it.
572 #### review previous word
573
574 Sets the review cursor to the beginning of the previous word and review it.
575 #### review next word
576
577 Sets the review cursor to the beginning of the next word and review it.
578 #### review current word phonetic
579
580 Sets the review cursor to the beginning of the current word and spell it phonetic.
581 #### review previous word phonetic
582
583 Sets the review cursor to the beginning of the previous word and spell it phonetic.
584 #### review next word phonetic
585
586 Sets the review cursor to the beginning of the next word and spell it phonetic.
587 #### review current character
588
589 Does not change the review cursor. Just announce the current char.
590 #### review previous character
591
592 Sets review cursor to the previous column and review it
593 #### review next character
594
595 Sets review cursor to the next column and review it
596 #### review current character phonetic
597
598 Does not change the review cursor. Just announce the current char phonetic.
599 #### review previous character phonetic
600
601 Sets review cursor to the previous column and announce the char phonetic.
602 #### review next character phonetic
603
604 Sets review cursor to the next column and announce the char phonetic.
605 #### review up
606
607 Set the review cursor in the same column one line above the current one and review it.
608 #### review down
609
610 Set the review cursor in the same column one line below the current one and review it.
611 ### Handling marking
612
613 A mark defines a point of origin or end to prepare to copy or paste a block of text.
614 \\
615 Examples where you need marks are:
616
617 * copy to clipboard
618
619 * set window application
620
621 * set bookmark 1 - X
622 #### Set mark
623
624 How to set a mark:
625 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.
626 2. press shortcut for ''set mark''
627 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.
628 #### Get text between marks
629
630 To get the text that is currently between your marks press shortcut for ''marked text''.\\
631 #### Remove Marks
632
633 You can remove all current marks by pressing the shortcut for ''remove marks''.
634 Changing the screen also removes the marks.
635 ### Screen Interaction
636
637 Fenrir provides several methods to interact with the current screen.
638 #### forward keypress
639
640 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.
641 #### Clipboard
642
643 Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard.
644 ##### copy marked to clipboard
645
646 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.
647 ##### clear clipboard
648
649 You can remove all items from the current clipboard by ''clear clipboard'' functionality.
650 ##### first clipboard
651
652 This moves quick to the first item of the clipboard.
653 ##### last clipboard
654
655 This moves quick to the last item of the clipboard.
656 ##### previous clipboard
657
658 Go to previous item in the clipboard.
659 ##### next clipboard
660
661 Go to next item on the clipboard.
662 ##### read current clipboard
663
664 Read the content of the current item of the clipboard.
665 ##### paste clipboard
666
667 Pass whatever item is currently selected by first, last, prev or next clipboard commands.
668 if no special clipboard is selected the (last copied) is used.
669 ##### export clipboard to file
670
671 This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop.
672 ##### import clipboard from file
673
674 Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop.
675 ### Quick Settings
676
677 Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file.
678 #### toggle braille
679
680 Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time.
681 #### toggle sound
682
683 Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time.
684 #### toggle speech
685
686 Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time.
687 #### disable speech temporarily
688
689 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.
690 #### toggle punctuation level
691
692 Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time.
693 #### toggle auto spell check
694
695 Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time.
696 #### toggle emoticons
697
698 Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime.
699 #### toggle output
700
701 Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time.
702 #### toggle auto read
703
704 Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time.
705 #### toggle auto time
706
707 Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time.
708 #### toggle highlight tracking
709
710 Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time.
711 #### increase speech volume
712
713 Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
714 #### decrease speech volume
715
716 Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
717 #### increase speech rate
718
719 Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
720 #### decrease speech rate
721
722 Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
723 #### increase speech pitch
724
725 Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
726 #### decrease speech pitch
727
728 Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
729 #### increase sound volume
730
731 Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime.
732 #### decrease sound volume
733
734 Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime.
735 ### Window Mode
736
737 Fenrir supports window mode, a window is a partial area of the screen.
738 #### Create Window
739
740 To create a window you need to do the following:
741 1. set a beginning mark (as the start of the window)
742 2. set an end mark (where the window should end)
743 3. press ''set window application'' shortcut.
744 Now Fenrir ignores anything outside of the window.\\
745 #### Remove Window
746
747 You can remove the window by pressing ''the clear window application'' shortcut.
748 Now Fenrir will read everything on the screen again.
749 ### Tracking Modes
750
751 Different types of tracking are currently supported
752 See section [Focus](#Focus) in ''settings.conf'' for more information.
753 #### Cursor Tracking
754
755 This follows the text cursor. This is the typical way an application works. This is used by:
756
757 * almost any shell such as (Bash, Zsh, sh)
758
759 * vim
760
761 * nano
762
763 * emacs
764
765 * mutt
766
767 * tintin++
768 #### Highlight Tracking
769
770 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:
771
772 * wifi-menu
773 * dialog
774 * alpine
775 ### Tutorial Mode
776
777 Fenrir provides a Tutorial mode.
778 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.
779
780 ### Information
781
782 #### Time
783 Announces the current Time.
784 #### Date
785
786 Announces the current Date.
787 #### Bookmarks
788
789 Bookmarks provide quick access to part of the screen without the need to navigate to the area.
790 By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut.
791 This is useful for status lines or other information where the position does not change.
792 ##### set Bookmark X
793
794 You need to set the bookmark first. For that you have to set one or two lines for use.
795 1. Set marks (one or two)
796 2. press shortcut for ''set bookmark X''. X represents the number 1 - 10.
797 ##### read Bookmark X
798
799 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.
800 ##### clear Bookmark X
801
802 to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10.
803 Afterward the bookmark is no longer available.
804 #### cursor position
805
806 You can get information about the current cursor and its position by using the "cursor position" functionality.
807 #### indent current line
808
809 Announce the current indent level of the current line. It represents the number of trailing spaces of the line.
810 #### current screen
811
812 Reads all the current screen from the beginning to the end.
813 #### current screen before cursor
814
815 Reads current screen from the beginning of the screen to the current cursor position.
816 #### current screen after cursor
817
818 Read anything after current cursor position to the end.
819 #### cursor read to end of line
820
821 Read from the current cursor position to the end of the current line.
822 #### cursor column
823
824 Read the current X position of a cursor (column of the current line).
825 #### cursor line number
826
827 Read the current Y position of a cursor (line number).
828 #### present first line
829
830 Reads just the first line. this is maybe useful for status information.
831 #### present last line
832
833 Presets the last line. This is maybe useful for status information.
834 #### last incoming
835
836 Repeat the last automatically incoming text.
837 ## Input
838
839 ### Echo
840 Fenrir provides different methods of echoing content:
841
842 * Word: Will speak each word after you push space
843
844 * Character: speak any letter you type on the screen
845
846 * Delete Character: speaks the character prior to the cursor when you push backspace
847 ### Silence on Key press
848
849 ### Spellchecker
850 Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut.
851 Commands to add or remove the current word to the dictionary are included.
852 As using the spellchecker is enhanced usage. You will need dictionary aspell-`<language>`.
853 See section [General](#General) in ''settings.conf'' for more information.
854 #### spell check
855
856 Invokes the spellcheck on the word that contains the Review or text cursor.
857 #### add word to spell check
858
859 Adds the word under the Review or Text cursor to the dictionary.
860 #### removes word from spell check
861
862 Removes the word under the Review or Text cursor from the dictionary.
863 ## Announcements
864
865 ### Emoticons
866 If you want to replace ":)" emoticons with "smile" in speech you can use this feature.
867 It can be toggled on or off.
868 You can define emoticons in a dictionary, please see Emoticon Dictionary.
869 See section [General](#General) in ''settings.conf'' to see how to enable or disable this feature.
870
871 ### Time
872
873 Announce the time at periodical increments, To track the time easily.
874 You can define 2 different ways of time announcements.
875 1. periodic
876 2. on fix minutes
877
878 Example periodic, every 20 minutes "delaySec=20":
879
880 [time]
881 enabled=True
882 presentTime=True
883 presentDate=True
884 delaySec=20
885 onMinutes=
886 announce=True
887 interrupt=False
888
889 Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45":
890
891 [time]
892 enabled=True
893 presentTime=True
894 presentDate=True
895 #delaySec is repected bevore onMinutes so it need to be set to 0
896 delaySec=0
897 onMinutes=00,15,30,45
898 announce=True
899 interrupt=False
900 ### Promoted List
901
902 Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks.
903 you can define a list of words which you want to hear a sound icon for after a period of inactivity.
904 Example if the word "Chrys" appears after 120 Seconds of inactivity:
905 [promote]
906 enabled=True
907 inactiveTimeoutSec=120
908 list=Chrys
909 See section [Promote](#Promote) in ''settings.conf'' for more information.
910 ### Punctuation
911
912 Fenrir handles punctuation levels and names for you with several provided dictionaries.
913
914 See levelDict
915 See punctuationDict
916 ## Braille
917
918 Fenrir provides Braille support in Version >= 2.0.
919 See section [Braille](#Braille) in ''settings.conf'' for more information.
920 ### braille flush
921
922 If a message appears on the Braille device you can flush it to get back to the review- or system cursor
923 ### Braille pan left
924
925 If a line is longer than your Braille devices you can move the view (called panning) to the left.
926 So you can read stuff without the need to move the review- or system cursor.
927 ### Braille pan right
928
929 If a line is longer than your Braille devices you can move the view (called panning) to the right.
930 So you can read stuff without the need to move the review- or system cursor.
931 ### braille return to cursor
932
933 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.
934 ## Dictionary
935
936 You can make use of different kinds of built-in dictionary's.
937 A dictionary has a name and list of keys and values separated by :===:
938 Example:
939 [customDict]
940 Chrys:===:Chrys is cool
941 lollipop:===:lolli
942 that means that every instance "chrys" is displayed, speech will say Chrys is cool.
943 "lollipop" is spoken as "lolli".
944 Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes.
945 ### Punctuation
946
947 #### Level
948 The punctuation level dict contains lists with "what punctuation is spoken in what level".
949 the default one looks like this:
950 [levelDict]
951 none:===:
952 some:===:.-$~+*-/\@
953 most:===:.,:-$~+*-/\@!#%^&*()[]}{`<>`;
954 all:===:!"#$%& \'()*+,-./:;`<=>`?@[\\]^_`{|}~
955 the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system)
956 if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at.
957 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".
958 #### Punctuation
959
960 The punctuation dictionary "[punctDict]" contains how the punctuation is spoken.
961 Example:
962 [punctDict]
963 _:===:line
964 speaks an _ as "line".
965 [punctDict]
966 _:===:underscore
967 speaks an _ as underscore.
968 for question mark an ? is appended to the word that the TTS system can announce the question correctly.
969 ### Custom
970
971 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. :)
972 ### Emoticons
973
974 The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful.
975 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.
976 # Configuration
977
978 You can configure Fenrir in the following places (ordered by priority):
979 1. Commandline Parameters ''-o'' see [Set settings coption](#Set settings coption)
980 2. /etc/fenrir/settings/settings.conf see [Settigns](#Settings)
981 3. `<sourceTree>`/config/settings/settings.conf see [Settigns](#Settings)
982 4. hard coded defaults
983 ## Commandline Arguments
984
985 ### Set settings option
986 You can specify options that overwrite the setting.conf.
987 This is done with ''-o `<list of options>` parameter.
988 The list of options have the following syntax
989 fenrir -o "section#setting=value;section#setting=value"
990
991 For example changing the sound driver to gstreamer and disabling Braille
992 fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False"
993 or change the debug level to verbose
994 fenrir -o "general#debugLevel=3"
995 You can find the available sections and variables here [#Settings](#Settings)
996 See Syntax [#settings.conf syntax](#settings.conf syntax)
997 ### settings.conf syntax
998
999 the syntax of the [settings.conf](#Settings) is quite simple and similar to a "*.ini" file, there are 4 different elements.
1000 1. Sections
1001 2. Settings
1002 3. Values
1003 4. Comments
1004
1005 A comment starts with a # and is ignored by Fenrir.
1006 # this is a comment
1007 To group settings we have sections.
1008 A section can look like this:
1009 [Section]
1010 A setting looks like this:
1011 settingName=Value
1012
1013 Example:
1014 [sound]
1015 # Turn sound on or off:
1016 enabled=True
1017 # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
1018 # Sox is default.
1019 driver=genericDriver
1020
1021 ## Settings
1022
1023 ### Sound
1024 The sound is configured in section ''[sound]''.
1025
1026 Turn sound on or off:
1027 enabled=True
1028 Values: on=''True'', off=''False''
1029
1030 Select the driver used to play sounds.
1031 The genericDriver using Sox is the default.
1032
1033 driver=genericDriver
1034
1035 Available Drivers:
1036
1037 * ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic''
1038
1039 * ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer''
1040
1041 These are the pack of sounds used for sound icons.
1042 theme=default
1043 By default we ship two sound packs.
1044 1. ''default'' opus encoded, for newer Sox versions
1045 2. ''default-wav'' wav encoded, just for compatibility
1046 Sound packs are located at /usr/share/sounds/fenrir/
1047
1048 Sound volume controls how loud the sounds for your selected sound pack are.
1049 volume=1.0
1050 Values: ''0.0'' is quietest, ''1.0'' is loudest.
1051
1052 #### Generic Driver
1053
1054 The generic sound driver uses shell commands for play sound and frequencies.
1055
1056 ''genericPlayFileCommand'' defines the command that is used to play a sound file.
1057 genericPlayFileCommand=`<your command for playing a file>`
1058 ''genericFrequencyCommand'' defines the command that is used playing frequencies.
1059 genericFrequencyCommand=`<your command for playing a frequence>`
1060
1061 The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'':
1062
1063 * ''fenrirVolume'' = the current volume setting
1064
1065 * ''fenrirSoundFile'' = the sound file for an sound icon
1066
1067 * ''fenrirFrequence'' = the frequency to play
1068
1069 * ''fenrirDuration'' = the duration of the frequency
1070
1071 Example genericPlayFileCommand (default)
1072 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
1073 Example genericFrequencyCommand (default)
1074 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
1075 ### Speech
1076
1077 Speech is configured in section ''[speech]''.
1078 Turn speech on or off:
1079 enabled=True
1080 Values: on=''True'', off=''False''
1081
1082 # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
1083
1084 driver=speechdDriver
1085 #driver=espeakDriver
1086
1087 #driver=genericDriver
1088
1089 Select the driver used to generate speech output.
1090
1091 driver=speechdDriver
1092
1093 Available Drivers:
1094
1095 * ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available
1096
1097 * ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd''
1098
1099 * ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak''
1100
1101 The rate selects how fast Fenrir will speak.
1102 rate=0.65
1103 Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest.
1104
1105 Pitch controls the pitch of the voice.
1106 pitch=0.5
1107 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest.
1108
1109 A Pitch for capital letters can be set.
1110 capitalPitch=0.9
1111 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest.
1112
1113 The Volume controls the loudness of the voice.
1114 volume=1.0
1115 Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest.
1116
1117 Some speech drivers like speechdDriver can support various modules. these can be set here.
1118 module=espeak
1119 Values: Text, Consult speech-dispatcher's configuration to see what modules are available.
1120
1121 Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
1122 or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
1123 voice=
1124 Values: Text, see your TTS synths documentation what is available.
1125
1126 Select the language you want Fenrir to use.
1127 language=english-us
1128 Values: Text, see your TTS synths documentation what is available.
1129
1130 Read new text as it occurs
1131 autoReadIncoming=True
1132 Values: on=''True'', off=''False''
1133
1134 #### Generic Driver
1135
1136 The generic speech driver uses shell commands for speech synthisus.
1137
1138 ''genericSpeechCommand'' defines the command that is executed for creating speech
1139 The following variables are substituted in ''genericSpeechCommand'':
1140
1141 * ''FenrirText'' = is the text that should be spoken
1142
1143 * ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this
1144
1145 * ''fenrirLanguage'' = the language to speak in
1146
1147 * ''fenrirVoice'' = is the current voice that should be used
1148
1149 * ''fenrirVolume'' = is replaced with the current volume
1150
1151 * ''fenrirPitch'' = is replaced with the current pitch
1152
1153 * ''fenrirRate'' = is replaced with the current speed (speech rate)
1154
1155 Example genericSpeechCommand (default):
1156 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
1157
1158 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.
1159
1160 FenrirMinVolume=0
1161 fenrirMaxVolume=200
1162 fenrirMinPitch=0
1163 fenrirMaxPitch=99
1164 fenrirMinRate=80
1165 fenrirMaxRate=450
1166
1167 The current volume, pitch and rate is calculated like this
1168 value = min + [volume,pitch,rate] * (min - max )
1169 ### Braille
1170
1171 Braille is a WIP and not ready yet.
1172 Braille support can be configured in section ''[braille]''.
1173
1174 Turn braille on or off:
1175 enabled=False
1176 Values: on=''True'', off=''False''
1177
1178 Select the driver used for communication with a braille device.
1179 driver=brlapiDriver
1180 Values: Text, available Driver
1181 Available Drivers:
1182
1183 * ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty''
1184
1185 The Braille layout can be configured here
1186 layout=en
1187 Values: Text, see braille driver for layouts.
1188
1189 What should the flush timeout relate to
1190 flushMode=word
1191 Values: Text, an flushMode
1192 Existing flushModes:
1193
1194 * ''word'' = flush after (number of words to display) * seconds
1195
1196 * ''char'' = flush after (number of chars to display) * seconds
1197
1198 * ''fix'' = flush after X seconds
1199
1200 * ''none'' = no automatic flush (manual via shortcut)
1201
1202 Seconds to flush (see flushMode)
1203 flushTimeout=3
1204 Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut)
1205 The total flush time calculates in relation to flushMode.
1206
1207 How should the Braille cursor focus be tracked?
1208 cursorFocusMode=page
1209 Values: Text, an existing cursor focus mode
1210 Available cursor focus modes:
1211
1212 * ''page'' = if the cursor crosses the border move to next page and start at begin
1213
1214 * ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth.
1215
1216
1217 Define the cell on the Braille device where Fenrir should scroll and keep the cursor
1218 fixCursorOnCell=-1
1219 Values: Integer
1220
1221 * ''0'' = first cell on device,
1222
1223 * ''-1'' = last cell on device
1224
1225 * ''>0'' = fix cell number
1226
1227 What cursor should Fenrir show on the Braille device
1228 cursorFollowMode=review
1229 Values: Text, an exsiting cursor following mode.
1230 Existing cursor following mode:
1231
1232 * ''none'' = no automatic toggle command used
1233
1234 * ''review'' = priority to review
1235
1236 * ''last'' = follow last used cursor
1237
1238 number of cells in panning (horizontal). How many cell should be panned on press the routing key?
1239 panSizeHorizontal=0
1240 Values: Integer,
1241
1242 * ''0'' = display size
1243
1244 * ''>0'' number of cells
1245 ### Screen
1246
1247 The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section.
1248
1249 The driver to get the information from the screen:
1250 driver=vcsaDriver
1251 Available Drivers:
1252
1253 * ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa''
1254 The encoding of the screen
1255 encoding=cp850
1256 Values:''cp850'' is used for Western languages like USA or Europe.
1257
1258 The driver updates Fenrir with changes on the screen.
1259 screenUpdateDelay=0.05
1260 Values: in Seconds
1261
1262 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:
1263 suspendingScreen=
1264 Values: Depends on driver:
1265
1266 * VCSA: the number of the TTY. TTY6 is ''6''.
1267 Example ignore TTY1 and TTY2:
1268 suspendingScreen=1,2
1269
1270 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.
1271 autodetectSuspendingScreen=True
1272 Values: on=''True'', off=''False''
1273
1274 ### Keyboard
1275
1276 The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file.
1277
1278 Select the driver used for grabbing keybord input and for recieving shortcuts.
1279 driver=evdevDriver
1280 Values: Text, available Driver
1281 Available Drivers:
1282
1283 * ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev''
1284
1285 You can let Fenrir know about what input devices are to be used.
1286 device=ALL
1287 Values:
1288
1289 * ''ALL'' use all devices with key capabilities.
1290
1291 * ''NOMICE'' Exclude mices from handling.
1292
1293 * `<Device Name>` just use the device with the given name.
1294
1295 Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts.
1296 grabDevices=True
1297 Values: on=''True'', off=''False''
1298
1299 The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then.
1300 ignoreShortcuts=False
1301 Values: on=''True'', off=''False''
1302
1303 The current keyboard layout used for shortcuts.
1304 keyboardLayout=desktop
1305 Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard''
1306
1307 Announce characters while typing.
1308 charEcho=False
1309 Values: on=''True'', off=''False''
1310
1311 Announce deleted characters
1312 charDeleteEcho=True
1313 Values: on=''True'', off=''False''
1314
1315 Announce word after pressing space
1316 wordEcho=False
1317 Values: on=''True'', off=''False''
1318
1319 Interrupt speech on any keypress
1320 interruptOnKeyPress=False
1321 Values: on=''True'', off=''False''
1322
1323 You can filter the keys that speech should interrupt
1324 interruptOnKeyPressFilter=
1325 Values: (List) empty = all keys, otherwise interrupt with specified keys
1326
1327 The timeout that is used for double tap shortcuts
1328 doubleTapTimeout=0.2
1329 Values: Seconds
1330 ### General
1331
1332 Overall settings can be configured from the section ''[general]''.
1333
1334 Set the current debug level:
1335 debugLevel=1
1336 Values: off=0, error=1, warning=2, info=3
1337
1338 the current punctuation and dict file in use:
1339 punctuationProfile=default
1340 Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation''
1341
1342 The current punctuation level in use:
1343 punctuationLevel=some
1344 Values: Text, See available levels in the used punctuation file.
1345
1346 Respect pause for punctuations:
1347 respectPunctuationPause=True
1348 Values: on=''True'', off=''False''
1349
1350 Add a pause on Line break:
1351 newLinePause=True
1352 Values: on=''True'', off=''False''
1353
1354 Specify the path where the clipboard should be exported to.
1355 See [export clipboard to file](#export clipboard to file).
1356 The variable ''$user'' is replaced by the current logged username.
1357 clipboardExportPath=/tmp/fenrirClipboard
1358 Values: Text, Systemfilepath
1359
1360 The number of available clipboards:
1361 numberOfClipboards=10
1362 Values: Integer, 1 - 999
1363
1364 Replace emoticons like :) or ;) with text insertions:
1365 emoticons=True
1366 Values: on=''True'', off=''False''
1367
1368 Define the current Fenrir keys:
1369 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
1370 Values, Text list, separated by comma.
1371
1372 Define the current script keys:
1373 scriptKey=KEY_COMPOSE
1374 Values, Text list, separated by comma.
1375
1376 The time format to be used for (time command) output:
1377 timeFormat=%H:%M:%P
1378 Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)
1379
1380 The date format to be used for (date command) output:
1381 dateFormat=%A, %B %d, %Y
1382 Values: see python specification for [datetime.strftime](https///docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)
1383
1384 Enable or Disable spellcheck whilst typing:
1385 autoSpellCheck=True
1386 Values: on=''True'', off=''False''
1387
1388 The use of the dictionary with spellcheck:
1389 spellCheckLanguage=en_US
1390 Values: Text, see aspell dictionary's.
1391
1392 Folder Path for your scripts "scriptKey" functionality:
1393 scriptPath=/usr/share/fenrir/scripts
1394 Values: Text, Existing path on file system.
1395
1396 Override commands or create new ones without changing the Fenrir defaults:
1397 commandPath=/usr/share/fenrir/commands
1398 Values: Text, Existing path on file system.
1399 Subfolders in commandPath are:
1400
1401 * ''commands'' = to create shortcut commands
1402
1403 * ''onInput'' = executed while typing
1404
1405 * ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6)
1406
1407 * ''onScreenUpdate'' = executed when the screen is captured
1408
1409 ### Focus
1410
1411 The configuration for basic focus is in the section ''[focus]''.
1412 Follow the text cursor:
1413 cursor=True
1414 Values: on=''True'', off=''False''
1415
1416 Follow highlighted text changes (Highlight Tracking):
1417 highlight=False
1418 Values: on=''True'', off=''False''
1419 ### Review
1420
1421 Configurations for the review mode are in the section ''[review]''.
1422
1423 If "next word/ char" or "prev word/char" create a linebreak, announce it:
1424 lineBreak=True
1425 Values: on=''True'', off=''False''
1426
1427 If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it:
1428 endOfScreen=True
1429 Values: on=''True'', off=''False''
1430
1431 Leave the review mode when pressing a key:
1432 leaveReviewOnKeypress=False
1433 Values: on=''True'', off=''False''
1434
1435 Leave the review mode when changing the screen (From TTY3 to TTY4):
1436 leaveReviewOnScreenChange=True
1437 Values: on=''True'', off=''False''
1438 ### Promote
1439
1440 "Promoted Lists" are configured in the section ''[promote]''.
1441 Turn Promoted Lists" on or off:
1442 enabled=True
1443 Values: on=''True'', off=''False''
1444
1445 The minimum time interval of inactivity to activate promoting.
1446 By default it promotes after 120 Seconds inactivity:
1447 inactiveTimeoutSec=120
1448 Values: in Seconds
1449
1450 Define a list of promoted words comma seperated:
1451 list=
1452 Values: text (comma seperated)
1453 Example to promote the word "nickname" or a bash prompt:
1454 list=nickname,$:,#:
1455
1456 ### Time
1457
1458 The automated time announcement is configured in the section ''[time]''.
1459 Time announcement is disabled by default.
1460 Turn time announcement on or off:
1461 enabled=True
1462 Values: on=''True'', off=''False''
1463
1464 Should the time be announced:
1465 presentTime=True
1466 Values: on=''True'', off=''False''
1467
1468 Should the date be announced (just on date change):
1469 presentDate=True
1470 Values: on=''True'', off=''False''
1471
1472 Announce after a given period of seconds:
1473 delaySec=0
1474 Value: in Seconds, 0 = Deactivated
1475
1476 Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored:
1477 onMinutes=00,30
1478 Example every 15 minutes:
1479 onMinutes=00,15,30,45
1480
1481 Just play a soundicon, (not interrupting):
1482 announce=True
1483 Values: on=''True'', off=''False''
1484
1485 Interrupt current speech for time announcement:
1486 interrupt=False
1487 Values: on=''True'', off=''False''
1488 # Customization
1489
1490 ## Scripting
1491 Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrir/scripts/ (the path is configurable in settings.conf).
1492 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.
1493 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/fenrir/scripts/weather__-__key_w.py
1494 Then, to access the script, simply press the script key and the letter w.
1495 Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory.
1496 The script gets some parameters from fenrir when it is executed. So that information is available in your script then.
1497
1498 ### Parameterlist
1499
1500 | Parameter | Content |
1501 | --------- | ------- |
1502 | $1 | Username of the current logged in user |
1503
1504 ### Examples
1505
1506 Script that just speaks the current username when pressing ScriptKey + H.\\
1507 File: ''/usr/share/fenrir/scripts/helloWorld__-__key_h.sh'':
1508 #!/bin/bash
1509 echo $1
1510
1511
1512 ## Commands
1513
1514 You can place your own commands in "/usr/share/fenrir/commands" (path is configurable in settings.conf).
1515 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.
1516 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)
1517 the basic scheme for a command is as follows:
1518
1519 from core import debug
1520
1521 class command():
1522 def __init__(self):
1523 pass
1524 def initialize(self, environment):
1525 self.env = environment
1526 def shutdown(self):
1527 pass
1528 def getDescription(self):
1529 return _('No description found')
1530 def run(self):
1531 pass
1532 def setCallback(self, callback):
1533 pass
1534
1535
1536 * [Template lives here](https///github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py)
1537
1538 * The class needs to have the name "command".
1539
1540 * "initialize" is running once whilst loading the command.
1541
1542 * "shutdown" is running on unload like the command (quit fenrir)
1543
1544 * "getDescriptsion" just returns an string. That String is used in Tutorial Mode.
1545
1546 * "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running)
1547
1548 * setCAllback is currently not used. and has no functionality yet.
1549
1550
1551 # Troubleshooting
1552
1553 ## Fenrir does not start
1554 1. Have you installed all the dependencies [Support and Requirements](#Support and Requirements)
1555 2. Try using master, a lot of changes take place there to make Fenrir compatible with more systems
1556 ## Fenrir does not utilize the shortcuts
1557
1558 1. Make sure you have python3-evdev installed
1559 2. Use the latest Fenrir version
1560 3. Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root)
1561 ## No sound at all
1562
1563 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''
1564 2. Use ALSA
1565 3. [Configure Pulse system wide](https///www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/) (Not recommended)
1566 4. Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver''
1567 5. Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav''
1568 6. Use most current version of [sox](http://sox.sourceforge.net/) with opus support
1569 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.
1570 ## You get sound-icons but no speech
1571
1572 1. If you are using speech-dispatcher run "spd-conf" once as user and as root.
1573 2. You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"''
1574 ## Bugreports and feature requests
1575
1576 Please report Bugs and feature requests to:
1577 [https://github.com/chrys87/fenrir/issues](https///github.com/chrys87/fenrir/issues)
1578
1579 for bugs please provide a [debug](#Howto create a debug file) file that shows the issue.
1580 ### How-to create a debug file
1581
1582 1. Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log''
1583 2. Start fenrir in debug mode\\ ''sudo fenrir -d''
1584 3. Do your stuff to reproduce the problem
1585 4. Stop fenrir (''fenrirKey + q'')
1586 the debug file is located in ''/var/log/fenrir.log''
1587
1588 Please be as precise as possible to make it easy to solve the problem.
1589
0
0 ====== Fenrir User Manual ======
1
2 Fenrir is a modern command line screen reader written in Python3.
3
4 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]]).
5
6 Please see the following pages for the [[fenrir_current_version|current]] and [[fenrir_git_version|Git]] version of Fenrir.
7
8
9 ====== Support and Requirements ======
10
11 Fenrir requires several drivers to interact with the operating system.
12
13 ===== Speech Drivers =====
14
15 A speech driver is for communication with the text to speech system like [[#SpeechDispatcher|Speech-Dispatcher]] or [[http://espeak.sourceforge.net|Espeak]]. \\
16 See section [[#Speech|Speech]] in ''settings.conf'' for more information.
17
18
19 ==== SpeechDispatcher ====
20
21 This driver is used by default.
22 It uses Speech-dispatcher as its backend.
23
24 Dependencies:
25
26 * Speech-dispatcher (installed and configured, [[https://devel.freebsoft.org/speechd#sec2|Documentation]])
27 * Python-speechd
28
29 ==== Espeak ====
30
31 Uses Espeak via Python bindings.
32
33 Dependencies:
34 * Espeak or Espeak-ng
35 * [[https://launchpad.net/python-espeak|python-espeak]]
36
37 ==== Generic ====
38
39 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.
40
41 Dependencies:
42 * Espeak or Espeak-ng
43
44 The Requirements are flexible, they depend on the configuration in settings.conf.
45
46 ==== Dummy ====
47
48 this is just for debugging, logs are output to the screen and logged as well.
49
50 ===== Sound Drivers =====
51
52 To play sound icons and similar.\\
53 See section [[#Sound|Sound]] in ''settings.conf'' for more information.
54
55 ==== Generic ====
56
57 This driver is used by default.
58
59 Dependencies:
60
61 * [[http://sox.sourceforge.net/|Sox]] with opus support
62 The Requirements are flexible, they depend on the configuration in settings.conf.
63
64 ==== Gstreamer ====
65
66 if you prefer to use Gstreamer for sound output.
67
68 Dependencies:
69 * Gstreamer >= 1.x
70 * Glibc
71
72 ==== Dummy ====
73
74 this is just for debugging, logs are output to the screen and logged as well.
75
76 ===== Input Drivers =====
77
78 Input drivers are to capture keyboard shortcuts issued to the screen reader \
79 See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information.
80
81 ==== Evdev ====
82
83 This driver is used by default.
84
85 Evdev is the low level input device framework for Linux.
86
87 Dependencies:
88
89 * python-evdev >=0.6.3
90 * pyudev
91 * loaded uinput kernel module
92 * exclusive access to the input devices
93 Read permission to the following files and services:
94 * /dev/input
95 * /dev/uinput
96
97 ===== Screen Drivers =====
98
99 The job of a screen driver is to get the information of current screen content.\\
100 See section [[#Screen|Screen]] in ''settings.conf'' for more information.
101
102 ==== VCSA ====
103
104 This driver is used by default.
105 For Linux VCSA devices. These exist on any current standard installation of Linux.
106
107 Dependencie
108 s:
109
110 * python-dbus
111 Read permission to the following files and services (or run as root):
112 * /sys/devices/virtual/tty/tty0/active
113 * /dev/tty[1 - 64]
114 * /dev/vcsa[1 - 64] ([[https://linux.die.net/man/4/vcsa|VCSA manpage]])
115 * read Logind DBUS
116
117 ===== Braille Drivers =====
118 This is for Braille support.
119 Braille is currently a work in progress and is planned for the Fenrir 2.0 release.\\
120 See section [[#Braille|Braille]] in ''settings.conf'' for more information.
121
122
123 ==== BRLTTY ====
124
125 This driver is used by default.
126 It uses [[brltty|BrlTTY]] to communicate with with a Braille device.
127
128 Dependencies:
129
130 * BrlTTY (configured and running, [[http://mielke.cc/brltty/doc/Manual-BRLTTY/English/BRLTTY.html|Documentation]])
131 * python-brlapi (configured, [[http://mielke.cc/brltty/doc/Manual-BrlAPI/English/BrlAPI.html|Documentation]])
132 ===== Currently supported platforms =====
133
134 Currently Fenrir completely supports the following Platforms:
135 * Linux TTY
136 Support for further Systems are planned.
137
138 ====== Installation ======
139
140 Fenrir can run without installation. It just requires the dependencies are installed first.
141
142 We recommend to try it out before installation to be sure everything works and prevent yourself from experiencing a non-talking environment.
143
144 ===== Try Out =====
145 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.
146 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)
147
148 ===== Install it =====
149
150 ==== Documented operating systems ====
151
152 ==== Arch Linux ====
153
154 For Arch there are PKGBUILDs in the AUR:
155 * [[https://aur.archlinux.org/packages/fenrir/|fenrir]]
156 * [[https://aur.archlinux.org/packages/fenrir-git/|fenrir-git]]
157
158 ==== Manual ====
159
160 - Download the latest stable version from the [[https://linux-a11y.org/index.php?page=fenrir-screenreader|Fenrir-Project]] site.
161 - Unpack the archive
162 - Check the needed Dependencys by running [[https://github.com/chrys87/fenrir/blob/master/check-dependencies.py|check-dependencys.py]] script
163 - install the missing dependencies an standard installation requires the following:
164 * python3 >= 3.3 (and all the following is needed for python3 )
165 * python3-speechd (screen)
166 * python3-dbus (screen)
167 * python3-evdev >= 0.6.4(input)
168 * python3-daemonize (background service)
169 * python3-brlapi (braille)
170 * python3-pyenchant (spellchecker)
171 * your language for aspell (aspell-<lang>) (spellchecker)
172 * sox (sound)
173 * For an individual installation see [[#Support and Requirements|Support and Requirements]] or consult the [[https://github.com/chrys87/fenrir/blob/master/README.md|Readme]])
174 - run "install.sh" as root
175
176 this installs Fenrir as the following
177 * Application:''/opt/fenrir''
178 * Settings:''/etc/fenrir''
179 * Sound Icons:''/usr/share/fenrir/''
180
181 to remove Fenrir just run uninstall.sh as root
182
183 ==== Git ====
184
185 if you want to get the latest code you can use git to get a development snapshot:
186
187 git clone https://github.com/chrys87/fenrir.git
188
189 ===== Auto Start =====
190
191 To start Fenrir once:
192 systemctl start fenrir
193
194 To enable auto start on system boot:
195 systemctl enable fenrir
196
197 ====== First Steps ======
198
199 If you are using Fenrir for the first time you may want to take a look at these resources:
200 * [[#Keybindings|Keybindings]]
201 * [[#Tutorial Mode|Tutorial Mode]]
202
203 ====== Features ======
204
205 ===== Commands =====
206
207 ==== Keybindings ====
208
209 Normal commands can be invoked in two ways:
210 - Using a Metakey ([[#Fenrir Key|FenrirKey]])
211 - Shortcuts with a single key
212
213 See section [[#Keyboard|Keyboard]] in ''settings.conf'' for more information.
214 === Fenrir Key ===
215 The Fenrir Key is for invoking screen reader commands. Fenrir can utilize more than one FenrirKey at the same time.
216 By default the following keys are used:
217 - Insert
218 - KeyPad Insert
219 - Meta (Super, Windows)
220
221 === Script Key ===
222 To invoke "Scripts" the Script Key is mandatory. The shortcut is encoded in the filename of the script. See [[#Scripting|Scripting]]
223 === Desktop Layout ===
224 ^Shortcut ^Command ^
225 |FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]|
226 |CTRL|[[#shut up|shut up (interrupts speech)]]|
227 |FenrirKey + KeyPad 9|[[#review bottom|reviews bottom]]|
228 |FenrirKey + KeyPad 7|[[#review top|reviews top]]|
229 |KeyPad 8|[[#review current line|reviews current line]]|
230 |KeyPad 7|[[#review previous line|reviews previous line]]|
231 |KeyPad 9|[[#review next line|reviews next line]]|
232 |FenrirKey + KeyPad 4|[[#review line beginning|reviews line beginning]]|
233 |FenrirKey + KeyPad 6|[[#review line ending|reviews line ending]]|
234 |FenrirKey + KeyPad 1|[[#review line first character|reviews line first character]]|
235 |FenrirKey + KeyPad 3|[[#review line last character|reviews line last character]]|
236 |FenrirKey + Alt + 1|[[#present first line|presents first line]]|
237 |FenrirKey + Alt + 2|[[#present last line|presents last line]]|
238 |KeyPad 5|[[#review current word|reviews current word]]|
239 |KeyPad 4|[[#review previous word|reviews previous word]]|
240 |KeyPad 6|[[#review next word|reviews next word]]|
241 |FenrirKey + Shift + KeyPad 5|[[#review current word phonetic|reviews current word phonetic]]|
242 |FenrirKey + Shift + KeyPad 4|[[#review previous word phonetic|reviews previous word phonetic]]|
243 |FenrirKey + Shift + KeyPad 6|[[#review next word phonetic|reviews next word phonetic]]|
244 |KeyPad 2|[[#review current character|reviews current char]]|
245 |KeyPad 1|[[#review previous character|reviews previous char]]|
246 |KeyPad 3|[[#review next character|reviews next char]]|
247 |FenrirKey + Shift + KeyPad 2|[[#review current character phonetic|reviews current character phonetic]]|
248 |FenrirKey + Shift + KeyPad 1|[[#review previous character phonetic|reviews previous character phonetic]]|
249 |FenrirKey + Shift + KeyPad 3|[[#review next character phonetic|reviews next character phonetic]]|
250 |FenrirKey + CTRL + KeyPad 8|[[#review up|reviews up]]|
251 |FenrirKey + CTRL + KeyPad 2|[[#review down|reviews down]]|
252 |FenrirKey + KeyPad dot|[[#exit review|exit review]]|
253 |KeyPad dot|[[#cursor position|cursor position]]|
254 |FenrirKey + I|[[#indent current line|indent curr line]]|
255 |FenrirKey + KeyPad 5|[[#current screen|current screen]]|
256 |FenrirKey + KeyPad 8|[[#current screen before cursor|current screen before cursor]]|
257 |FenrirKey + KeyPad 2|[[#current screen after cursor|current screen after cursor]]|
258 |<Unbound>|[[#cursor read to end of line|cursor read to end of line]]|
259 |<Unbound>|[[#cursor column|cursor column]]|
260 |<Unbound>|[[#cursor line number|cursor line number]]|
261 |<Unbound>|[[#braille flush|Braille flush]]|
262 |<Unbound>|[[#braille pan left|Braille pan left]]|
263 |<Unbound>|[[#braille pan right|Braille pan right]]|
264 |<Unbound>|[[#braille return to cursor|Braille return to cursor]]|
265 |FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]|
266 |FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]|
267 |FenrirKey + 1|[[#read Bookmark X|bookmark 1]]|
268 |FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]|
269 |FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]|
270 |FenrirKey + 2|[[#read Bookmark X|bookmark 2]]|
271 |FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]|
272 |FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]|
273 |FenrirKey + 3|[[#read Bookmark X|bookmark 3]]|
274 |FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]|
275 |FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]|
276 |FenrirKey + 4|[[#read Bookmark X|bookmark 4]]|
277 |FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]|
278 |FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]|
279 |FenrirKey + 5|[[#read Bookmark X|bookmark 5]]|
280 |FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]|
281 |FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]|
282 |FenrirKey + 6|[[#read Bookmark X|bookmark 6]]|
283 |FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]|
284 |FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]|
285 |FenrirKey + 7|[[#read Bookmark X|bookmark 7]]|
286 |FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]|
287 |FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]|
288 |FenrirKey + 8|[[#read Bookmark X|bookmark 8]]|
289 |FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]|
290 |FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]|
291 |FenrirKey + 9|[[#read Bookmark X|bookmark 9]]|
292 |FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]|
293 |FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]|
294 |FenrirKey + 0|[[#read Bookmark X|bookmark 10]]|
295 |FenrirKey + KeyPad Slash|[[#Create Window|set window application]]|
296 |2 * FenrirKey + KeyPad Slash|[[#Remove Window|clear window application]]|
297 |KeyPad Plus|[[#last incoming|read last incoming]]|
298 |FenrirKey + F2|[[#toggle braille|toggles braille]]|
299 |FenrirKey + F3|[[#toggle sound|toggles sound]]|
300 |FenrirKey + F4|[[#toggle speech|toggles speech]]|
301 |KeyPad Enter|[[#disable speech temporarily|temporarily disables speech]]|
302 |FenrirKey + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]|
303 |FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]|
304 |FenrirKey + Backslash|[[#toggle output|toggles output]]|
305 |FenrirKey + CTRL + E|[[#toggle emoticons|toggles emoticons]]|
306 |FenrirKey + KeyPad Enter|[[#toggle auto read|toggles auto read]]|
307 |FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]|
308 |FenrirKey + KeyPad ASTERISK|[[#toggle highlight tracking|toggles highlight tracking]]|
309 |FenrirKey + Q|[[#quit Fenrir|quits fenrir]]|
310 |FenrirKey + T|[[#Time|Announce time]]|
311 |2 * FenrirKey + T|[[#Date|Announce date]]|
312 |FenrirKey + S|[[#spell check|spell check]]|
313 |2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]|
314 |FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]|
315 |FenrirKey + Backspace|[[#forward keypress|forward keypress]]|
316 |FenrirKey + Up|[[#increase speech volume|increase speech volume]]|
317 |FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]|
318 |FenrirKey + Right|[[#increase speech rate|increase speech rate]]|
319 |FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]|
320 |FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]|
321 |FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]|
322 |FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]|
323 |FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]|
324 |FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]|
325 |FenrirKey + Home|[[#first clipboard|first clipboard]]|
326 |FenrirKey + End|[[#last clipboard|last clipboard]]|
327 |FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]|
328 |FenrirKey + PageDown|[[#next clipboard|next clipboard]]|
329 |FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]|
330 |FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]|
331 |FenrirKey + V|[[#paste clipboard|paste clipboard contents]]|
332 |FenrirKey + P|[[#import clipboard from file|import clipboard from file]]|
333 |FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]|
334 |FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]|
335 |FenrirKey + X|[[#Set mark|set mark]]|
336 |FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]|
337 ^Linux specific ^
338 |<Unbound>|export clipboard to X|
339 |FenrirKey + CTRL + Up|include Alsa volume|
340 |FenrirKey + CTRL + Down|decrease Alsa volume|
341
342 === Laptop Layout ===
343 ^Shortcut ^Command ^
344 |FenrirKey + H|[[#Tutorial Mode|toggle tutorial mode]]|
345 |CTRL|[[#shut up|shut up (interrupts speech)]]|
346 |FenrirKey + Shift + O|[[#review bottom|reviews bottom]]|
347 |FenrirKey + Shift + U|[[#review top|reviews top]]|
348 |FenrirKey + I|[[#review current line|reviews current line]]|
349 |FenrirKey + U|[[#review previous line|reviews previous line]]|
350 |FenrirKey + O|[[#review next line|reviews next line]]|
351 |FenrirKey + Shift + J|[[#review line beginning|reviews line beginning]]|
352 |FenrirKey + Shift + L|[[#review line ending|reviews line ending]]|
353 |FenrirKey + CTRL + J|[[#review line first character|reviews line first character]]|
354 |FenrirKey + CTRL + L|[[#review line last character|reviews line last character]]|
355 |FenrirKey + Alt + 1|[[#present first line|presents first line]]|
356 |FenrirKey + Alt + 2|[[#present last line|presents last line]]|
357 |FenrirKey + K|[[#review current word|reviews current word]]|
358 |FenrirKey + J|[[#review previous word|reviews previous word]]|
359 |FenrirKey + L|[[#review next word|reviews next word]]|
360 |FenrirKey + CTRL + ALT + K|[[#review current word phonetic|reviews current word phonetic]]|
361 |FenrirKey + CTRL + ALT + J|[[#review previous word phonetic|reviews previous word phonetic]]|
362 |FenrirKey + CTRL + ALT + L|[[#review next word phonetic|reviews next word phonetic]]|
363 |FenrirKey + comma|[[#review current character|reviews current character]]|
364 |FenrirKey + M|[[#review previous character|reviews previous character]]|
365 |FenrirKey + dot|[[#review next character|reviews next character]]|
366 |FenrirKey + CTRL + ALT + comma|[[#review current character phonetic|reviews current character phonetic]]|
367 |FenrirKey + CTRL + ALT + M|[[#review previous character phonetic|reviews previous character phonetic]]|
368 |FenrirKey + CTRL + ALT + dot|[[#review next character phonetic|reviews next character phonetic]]|
369 |FenrirKey + CTRL + I|[[#review up|reviews up]]|
370 |FenrirKey + CTRL + comma|[[#review down|reviews down]]|
371 |FenrirKey + Slash|[[#exit review|exit review]]|
372 |FenrirKey + Shift + dot|[[#cursor position|cursor position]]|
373 |2 * FenrirKey + I|[[#indent current line|indent curr line]]|
374 |FenrirKey + Shift + K|[[#current screen|current screen]]|
375 |FenrirKey + Shift + I|[[#current screen before cursor|current screen before cursor]]|
376 |FenrirKey + Shift + comma|[[#current screen after cursor|current screen after cursor]]|
377 |<Unbound>|[[#cursor read to end of line|cursor read to end of line]]|
378 |<Unbound>|[[#cursor column|cursor column]]|
379 |<Unbound>|[[#cursor line number|cursor line number]]|
380 |<Unbound>|[[#braille flush|Braille flush]]|
381 |<Unbound>|[[#braille pan left|Braille pan left]]|
382 |<Unbound>|[[#braille pan right|Braille pan right]]|
383 |<Unbound>|[[#braille return to cursor|Braille return to cursor]]|
384 |FenrirKey + CTRL + 1|[[#clear Bookmark X|clear bookmark 1]]|
385 |FenrirKey + Shift + 1|[[#set Bookmark X|set bookmark 1]]|
386 |FenrirKey + 1|[[#read Bookmark X|bookmark 1]]|
387 |FenrirKey + CTRL + 2|[[#clear Bookmark X|clear bookmark 2]]|
388 |FenrirKey + Shift + 2|[[#set Bookmark X|set bookmark 2]]|
389 |FenrirKey + 2|[[#read Bookmark X|bookmark 2]]|
390 |FenrirKey + CTRL + 3|[[#clear Bookmark X|clear bookmark 3]]|
391 |FenrirKey + Shift + 3|[[#set Bookmark X|set bookmark 3]]|
392 |FenrirKey + 3|[[#read Bookmark X|bookmark 3]]|
393 |FenrirKey + CTRL + 4|[[#clear Bookmark X|clear bookmark 4]]|
394 |FenrirKey + Shift + 4|[[#set Bookmark X|set bookmark 4]]|
395 |FenrirKey + 4|[[#read Bookmark X|bookmark 4]]|
396 |FenrirKey + CTRL + 5|[[#clear Bookmark X|clear bookmark 5]]|
397 |FenrirKey + Shift + 5|[[#set Bookmark X|set bookmark 5]]|
398 |FenrirKey + 5|[[#read Bookmark X|bookmark 5]]|
399 |FenrirKey + CTRL + 6|[[#clear Bookmark X|clear bookmark 6]]|
400 |FenrirKey + Shift + 6|[[#set Bookmark X|set bookmark 6]]|
401 |FenrirKey + 6|[[#read Bookmark X|bookmark 6]]|
402 |FenrirKey + CTRL + 7|[[#clear Bookmark X|clear bookmark 7]]|
403 |FenrirKey + Shift + 7|[[#set Bookmark X|set bookmark 7]]|
404 |FenrirKey + 7|[[#read Bookmark X|bookmark 7]]|
405 |FenrirKey + CTRL + 8|[[#clear Bookmark X|clear bookmark 8]]|
406 |FenrirKey + Shift + 8|[[#set Bookmark X|set bookmark 8]]|
407 |FenrirKey + 8|[[#read Bookmark X|bookmark 8]]|
408 |FenrirKey + CTRL + 9|[[#clear Bookmark X|clear bookmark 9]]|
409 |FenrirKey + Shift + 9|[[#set Bookmark X|set bookmark 9]]|
410 |FenrirKey + 9|[[#read Bookmark X|bookmark 9]]|
411 |FenrirKey + CTRL + 0|[[#clear Bookmark X|clear bookmark 10]]|
412 |FenrirKey + Shift + 0|[[#set Bookmark X|set bookmark 10]]|
413 |FenrirKey + 0|[[#read Bookmark X|bookmark 10]]|
414 |FenrirKey + CTRL + 8|[[#Create Window|set window application]]|
415 |2 * FenrirKey + CTRL + 8|[[#Remove Window|clear window application]]|
416 |FenrirKey + Semicolon|[[#last incoming|read last incoming]]|
417 |FenrirKey + F2|[[#toggle braille|toggles braille]]|
418 |FenrirKey + F3|[[#toggle sound|toggles sound]]|
419 |FenrirKey + F4|[[#toggle speech|toggles speech]]|
420 |FenrirKey + Enter|[[#disable speech temporarily|temporarily disables speech]]|
421 |FenrirKey + Shift + CTRL + P|[[#toggle punctuation level|toggles punctuation level]]|
422 |FenrirKey + RightBrace|[[#toggle auto spell check|toggle auto spell check]]|
423 |FenrirKey + Shift + Enter|[[#toggle output|toggles output]]|
424 |FenrirKey + Shift + E|[[#toggle emoticons|toggles emoticons]]|
425 |FenrirKey + Enter|[[#toggle auto read|toggles auto read]]|
426 |FenrirKey + CTRL + T|[[#toggle auto time|toggles auto time]]|
427 |FenrirKey + Y|[[#toggle highlight tracking|toggles highlight tracking]]|
428 |FenrirKey + Q|[[#quit Fenrir|quits fenrir]]|
429 |FenrirKey + T|[[#Time|Announce time]]|
430 |2 * FenrirKey + T|[[#Date|Announce date]]|
431 |FenrirKey + S|[[#spell check|spell check]]|
432 |2 * FenrirKey + S|[[#add word to spell check|add word to spell check]]|
433 |FenrirKey + Shift + S|[[#removes word from spell check|removes word from spell check]]|
434 |FenrirKey + Backspace|[[#forward keypress|forward keypress]]|
435 |FenrirKey + Up|[[#increase speech volume|increase speech volume]]|
436 |FenrirKey + Down|[[#decrease speech volume|decrease speech volume]]|
437 |FenrirKey + Right|[[#increase speech rate|increase speech rate]]|
438 |FenrirKey + Left|[[#decrease speech rate|decrease speech rate]]|
439 |FenrirKey + Alt + Right|[[#increase speech pitch|increase speech pitch]]|
440 |FenrirKey + Alt + Left|[[#decrease speech pitch|decrease speech pitch]]|
441 |FenrirKey + Alt + Up|[[#increase sound volume|increase sound volume]]|
442 |FenrirKey + Alt + Down|[[#decrease sound volume|decrease sound volume]]|
443 |FenrirKey + CTRL + Shift + C|[[#clear clipboard|clears clipboard]]|
444 |FenrirKey + Home|[[#first clipboard|first clipboard]]|
445 |FenrirKey + End|[[#last clipboard|last clipboard]]|
446 |FenrirKey + PageUp|[[#previous clipboard|previous clipboard]]|
447 |FenrirKey + PageDown|[[#next clipboard|next clipboard]]|
448 |FenrirKey + Shift + C|[[#read current clipboard|current clipboard]]|
449 |FenrirKey + C|[[#copy marked to clipboard|copy marked text to clipboard]]|
450 |FenrirKey + V|[[#paste clipboard|paste clipboard contents]]|
451 |FenrirKey + F5|[[#import clipboard from file|import clipboard from file]]|
452 |FenrirKey + Alt + Shift +C|[[#export clipboard to file|export clipboard to file]]|
453 |FenrirKey + CTRL + Shift + X|[[#Remove Marks|remove marks]]|
454 |FenrirKey + X|[[#Set mark|set mark]]|
455 |FenrirKey + Shift + X|[[#Get text between marks|announce marked text]]|
456 ^Linux specific ^
457 |<Unbound>|export clipboard to X|
458 |FenrirKey + CTRL + Up|increases Alsa volume|
459 |FenrirKey + CTRL + Down|decreases Alsa volume|
460 ==== General ====
461 === quit Fenrir ===
462 Just stops fenrir.
463 === shut up ===
464 Interrupt the current spoken.
465 ==== Review Modes ====
466 Fenrir provides a virtual cursor, with it you can navigate all over the screen without changing the text cursor.
467
468 Using the review feature will open the review mode automatically.
469
470 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.
471
472 Think when using clipboard operations and similar. The review cursor is always prefered over the text cursor.
473
474 Fenrir sounds a bell sound if the used review command jumps to another line or end of screen.
475 === exit review ===
476 You can leave the review mode by pressing the ''exit review'' shortcut.
477 === review bottom ===
478 Set the review cursor to first column in the last line.
479 === review top ===
480 Set the review cursor to the first column in the first line
481 === review current line ===
482 Set the review cursor to the beginn of the the current line and review it.
483 === review previous line ===
484 Set the review cursor to the previous line and review it.
485 === review next line ===
486 Set the review cursor to the next line and review it.
487 === review line beginning ===
488 Set the review cursor to the begin of the current line
489 === review line ending ===
490 Set the review cursor to the end of the current line
491 === review line first character ===
492 Set the review cursor the first char (that is not space) in the current line and review it.
493 === review line last character ===
494 Set the review cursor the last char (that is not space) in the current line and review it.
495 === review current word ===
496 Sets the review cursor to the beginning of the current word and review it.
497 === review previous word ===
498 Sets the review cursor to the beginning of the previous word and review it.
499 === review next word ===
500 Sets the review cursor to the beginning of the next word and review it.
501 === review current word phonetic ===
502 Sets the review cursor to the beginning of the current word and spell it phonetic.
503 === review previous word phonetic ===
504 Sets the review cursor to the beginning of the previous word and spell it phonetic.
505 === review next word phonetic ===
506 Sets the review cursor to the beginning of the next word and spell it phonetic.
507 === review current character ===
508 Does not change the review cursor. Just announce the current char.
509 === review previous character ===
510 Sets review cursor to the previous column and review it
511 === review next character ===
512 Sets review cursor to the next column and review it
513 === review current character phonetic ===
514 Does not change the review cursor. Just announce the current char phonetic.
515 === review previous character phonetic ===
516 Sets review cursor to the previous column and announce the char phonetic.
517 === review next character phonetic ===
518 Sets review cursor to the next column and announce the char phonetic.
519 === review up ===
520 Set the review cursor in the same column one line above the current one and review it.
521 === review down ===
522 Set the review cursor in the same column one line below the current one and review it.
523 ==== Handling marking ====
524 A mark defines a point of origin or end to prepare to copy or paste a block of text.
525 \\
526 Examples where you need marks are:
527 * copy to clipboard
528 * set window application
529 * set bookmark 1 - X
530 === Set mark ===
531 How to set a mark:
532 - 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.
533 - press shortcut for ''set mark''
534 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.
535 === Get text between marks ===
536 To get the text that is currently between your marks press shortcut for ''marked text''.\\
537 === Remove Marks ===
538 You can remove all current marks by pressing the shortcut for ''remove marks''.
539 Changing the screen also removes the marks.
540 ==== Screen Interaction ====
541 Fenrir provides several methods to interact with the current screen.
542 === forward keypress ===
543 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.
544 === Clipboard ===
545 Fenrir provides a clipboard with multible items represented by a list. You navigate throught the list and paste the selected clipboard.
546 == copy marked to clipboard ==
547 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.
548 == clear clipboard ==
549 You can remove all items from the current clipboard by ''clear clipboard'' functionality.
550 == first clipboard ==
551 This moves quick to the first item of the clipboard.
552 == last clipboard ==
553 This moves quick to the last item of the clipboard.
554 == previous clipboard ==
555 Go to previous item in the clipboard.
556 == next clipboard ==
557 Go to next item on the clipboard.
558 == read current clipboard ==
559 Read the content of the current item of the clipboard.
560 == paste clipboard ==
561 Pass whatever item is currently selected by first, last, prev or next clipboard commands.
562 if no special clipboard is selected the (last copied) is used.
563 == export clipboard to file ==
564 This allows you to export the current clipboard to a configurable filepath. This is useful to share the clipboard with a graphical desktop.
565 == import clipboard from file ==
566 Import a clipboard from a configurable file. This is useful to share the clipboard with a graphical desktop.
567 ==== Quick Settings ====
568 Fenrir provides shortcuts to change settings temporarily and on the fly without the need to permanently change the ''settings.conf'' file.
569 === toggle braille ===
570 Enables and disables Braille. This is not persistent stored in your ''settings.conf'' but during run time.
571 === toggle sound ===
572 Enables and disables sound. This is not persistent stored in your ''settings.conf'' but during run time.
573 === toggle speech ===
574 Enables and disables speech. This is not persistent stored in your ''settings.conf'' but during run time.
575 === disable speech temporarily ===
576 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.
577 === toggle punctuation level ===
578 Cycle between all available punctuation levels. This is not persistent stored in your ''settings.conf'' but during run time.
579 === toggle auto spell check ===
580 Enables and disables automatic spellchecker (when typing). This is not persistent stored in your ''settings.conf'' but during run time.
581 === toggle emoticons ===
582 Enables and disables emoticons. This is not persistent stored in your ''settings.conf'' but during runtime.
583 === toggle output ===
584 Enables and disables all output at once (sound, Braille, speech). This is not persistent stored in your ''settings.conf'' but during run time.
585 === toggle auto read ===
586 Enables and disables what is automatically spoken. This is not persistent stored in your ''settings.conf'' but during run time.
587 === toggle auto time ===
588 Enables and disables auto time functionality. This is not persistent stored in your ''settings.conf'' but during run time.
589 === toggle highlight tracking ===
590 Enables and disables highlight tracking. This is not persistent stored in your ''settings.conf'' but during run time.
591 === increase speech volume ===
592 Increase the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
593 === decrease speech volume ===
594 Decrease the volume of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
595 === increase speech rate ===
596 Increase the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
597 === decrease speech rate ===
598 Decrease the rate of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
599 === increase speech pitch ===
600 Increase the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
601 === decrease speech pitch ===
602 Decrease the pitch of the speech. This is not persistent stored in your ''settings.conf'' but during runtime.
603 === increase sound volume ===
604 Increase the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime.
605 === decrease sound volume ===
606 Decrease the volume of the sound. This is not persistent stored in your ''settings.conf'' but during runtime.
607 ==== Window Mode ====
608 Fenrir supports window mode, a window is a partial area of the screen.
609 === Create Window ===
610 To create a window you need to do the following:
611 - set a beginning mark (as the start of the window)
612 - set an end mark (where the window should end)
613 - press ''set window application'' shortcut.
614 Now Fenrir ignores anything outside of the window.\\
615 === Remove Window ===
616 You can remove the window by pressing ''the clear window application'' shortcut.
617 Now Fenrir will read everything on the screen again.
618 ==== Tracking Modes ====
619 Different types of tracking are currently supported
620 See section [[#Focus|Focus]] in ''settings.conf'' for more information.
621 === Cursor Tracking ===
622 This follows the text cursor. This is the typical way an application works. This is used by:
623 * almost any shell such as (Bash, Zsh, sh)
624 * vim
625 * nano
626 * emacs
627 * mutt
628 * tintin++
629 === Highlight Tracking ===
630 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:
631 * wifi-menu
632 * dialog
633 * alpine
634 ==== Tutorial Mode ====
635 Fenrir provides a Tutorial mode.
636 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.
637
638 ==== Information ====
639 === Time ===
640 Announces the current Time.
641 === Date ===
642 Announces the current Date.
643 === Bookmarks ===
644 Bookmarks provide quick access to part of the screen without the need to navigate to the area.
645 By default Fenrir provides 10 bookmarks. Those can be set and accessed via shortcut.
646 This is useful for status lines or other information where the position does not change.
647 == set Bookmark X ==
648 You need to set the bookmark first. For that you have to set one or two lines for use.
649 - Set marks (one or two)
650 - press shortcut for ''set bookmark X''. X represents the number 1 - 10.
651 == read Bookmark X ==
652 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.
653 == clear Bookmark X ==
654 to remove a bookmark just press the ''clear bookmark X'' shortcut. X represents the number 1 - 10.
655 Afterward the bookmark is no longer available.
656 === cursor position ===
657 You can get information about the current cursor and its position by using the "cursor position" functionality.
658 === indent current line ===
659 Announce the current indent level of the current line. It represents the number of trailing spaces of the line.
660 === current screen ===
661 Reads all the current screen from the beginning to the end.
662 === current screen before cursor ===
663 Reads current screen from the beginning of the screen to the current cursor position.
664 === current screen after cursor ===
665 Read anything after current cursor position to the end.
666 === cursor read to end of line ===
667 Read from the current cursor position to the end of the current line.
668 === cursor column ===
669 Read the current X position of a cursor (column of the current line).
670 === cursor line number ===
671 Read the current Y position of a cursor (line number).
672 === present first line ===
673 Reads just the first line. this is maybe useful for status information.
674 === present last line ===
675 Presets the last line. This is maybe useful for status information.
676 === last incoming ===
677 Repeat the last automatically incoming text.
678 ===== Input =====
679 ==== Echo ====
680 Fenrir provides different methods of echoing content:
681 * Word: Will speak each word after you push space
682 * Character: speak any letter you type on the screen
683 * Delete Character: speaks the character prior to the cursor when you push backspace
684 ==== Silence on Key press ====
685 ==== Spellchecker ====
686 Fenrir has a built-in spellchecker, it can invoke automatically while typing or be called by a shortcut.
687 Commands to add or remove the current word to the dictionary are included.
688 As using the spellchecker is enhanced usage. You will need dictionary aspell-<language>.
689 See section [[#General|General]] in ''settings.conf'' for more information.
690 === spell check ===
691 Invokes the spellcheck on the word that contains the Review or text cursor.
692 === add word to spell check ===
693 Adds the word under the Review or Text cursor to the dictionary.
694 === removes word from spell check ===
695 Removes the word under the Review or Text cursor from the dictionary.
696 ===== Announcements =====
697 ==== Emoticons ====
698 If you want to replace ":)" emoticons with "smile" in speech you can use this feature.
699 It can be toggled on or off.
700 You can define emoticons in a dictionary, please see Emoticon Dictionary.
701 See section [[#General|General]] in ''settings.conf'' to see how to enable or disable this feature.
702
703 ==== Time ====
704 Announce the time at periodical increments, To track the time easily.
705 You can define 2 different ways of time announcements.
706 - periodic
707 - on fix minutes
708
709 Example periodic, every 20 minutes "delaySec=20":
710
711 [time]
712 enabled=True
713 presentTime=True
714 presentDate=True
715 delaySec=20
716 onMinutes=
717 announce=True
718 interrupt=False
719
720 Example on fix minutes in an hour. example every quarter "delaySec=0" and "onMinutes=00,15,30,45":
721
722 [time]
723 enabled=True
724 presentTime=True
725 presentDate=True
726 #delaySec is repected bevore onMinutes so it need to be set to 0
727 delaySec=0
728 onMinutes=00,15,30,45
729 announce=True
730 interrupt=False
731 ==== Promoted List ====
732 Promoted Lists are a nice feature if you are away from your computer or performing more longer tasks.
733 you can define a list of words which you want to hear a sound icon for after a period of inactivity.
734 Example if the word "Chrys" appears after 120 Seconds of inactivity:
735 [promote]
736 enabled=True
737 inactiveTimeoutSec=120
738 list=Chrys
739 See section [[#Promote|Promote]] in ''settings.conf'' for more information.
740 ==== Punctuation ====
741 Fenrir handles punctuation levels and names for you with several provided dictionaries.
742
743 See levelDict
744 See punctuationDict
745 ===== Braille =====
746 Fenrir provides Braille support in Version >= 2.0.
747 See section [[#Braille|Braille]] in ''settings.conf'' for more information.
748 ==== braille flush ====
749 If a message appears on the Braille device you can flush it to get back to the review- or system cursor
750 ==== Braille pan left ====
751 If a line is longer than your Braille devices you can move the view (called panning) to the left.
752 So you can read stuff without the need to move the review- or system cursor.
753 ==== Braille pan right ====
754 If a line is longer than your Braille devices you can move the view (called panning) to the right.
755 So you can read stuff without the need to move the review- or system cursor.
756 ==== braille return to cursor ====
757 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.
758 ===== Dictionary =====
759 You can make use of different kinds of built-in dictionary's.
760 A dictionary has a name and list of keys and values separated by :===:
761 Example:
762 [customDict]
763 Chrys:===:Chrys is cool
764 lollipop:===:lolli
765 that means that every instance "chrys" is displayed, speech will say Chrys is cool.
766 "lollipop" is spoken as "lolli".
767 Before making changes to a dictionary we recommend making a backup of your current dictionary in case future updates overwrite your local changes.
768 ==== Punctuation ====
769 === Level ===
770 The punctuation level dict contains lists with "what punctuation is spoken in what level".
771 the default one looks like this:
772 [levelDict]
773 none:===:
774 some:===:.-$~+*-/\@
775 most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
776 all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
777 the level "none" has no values. so it should not speak any punctuation (sadly this is not respected by every TTS system)
778 if "some" is the current level the following are spoken: dot dash dollar tilde plus star slash backslash at.
779 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".
780 === Punctuation ===
781 The punctuation dictionary "[punctDict]" contains how the punctuation is spoken.
782 Example:
783 [punctDict]
784 _:===:line
785 speaks an _ as "line".
786 [punctDict]
787 _:===:underscore
788 speaks an _ as underscore.
789 for question mark an ? is appended to the word that the TTS system can announce the question correctly.
790 ==== Custom ====
791 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. :)
792 ==== Emoticons ====
793 The Emoticons dictionary "[emoticonDict]" by default contains some emoticons. it can replace ":)" with "smile" or "XD" with "loool" Making chat more colorful.
794 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.
795 ====== Configuration ======
796 You can configure Fenrir in the following places (ordered by priority):
797 - Commandline Parameters ''-o'' see [[#Set settings coption|Set settings coption]]
798 - /etc/fenrir/settings/settings.conf see [[#Settings|Settigns]]
799 - <sourceTree>/config/settings/settings.conf see [[#Settings|Settigns]]
800 - hard coded defaults
801 ===== Commandline Arguments =====
802 ==== Set settings option ====
803 You can specify options that overwrite the setting.conf.
804 This is done with ''-o <list of options>'' parameter.
805 The list of options have the following syntax
806 fenrir -o "section#setting=value;section#setting=value"
807
808 For example changing the sound driver to gstreamer and disabling Braille
809 fenrir -o "sound#driver=gstreamerDriver;braille#enabled=False=False"
810 or change the debug level to verbose
811 fenrir -o "general#debugLevel=3"
812 You can find the available sections and variables here [[#Settings]]
813 See Syntax [[#settings.conf syntax]]
814 ==== settings.conf syntax ====
815 the syntax of the [[#Settings|settings.conf]] is quite simple and similar to a "*.ini" file, there are 4 different elements.
816 - Sections
817 - Settings
818 - Values
819 - Comments
820
821 A comment starts with a # and is ignored by Fenrir.
822 # this is a comment
823 To group settings we have sections.
824 A section can look like this:
825 [Section]
826 A setting looks like this:
827 settingName=Value
828
829 Example:
830 [sound]
831 # Turn sound on or off:
832 enabled=True
833 # Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
834 # Sox is default.
835 driver=genericDriver
836
837 ===== Settings =====
838 ==== Sound ====
839 The sound is configured in section ''[sound]''.
840
841 Turn sound on or off:
842 enabled=True
843 Values: on=''True'', off=''False''
844
845 Select the driver used to play sounds.
846 The genericDriver using Sox is the default.
847
848 driver=genericDriver
849
850 Available Drivers:
851 * ''genericDriver'' using the generic driver, for Fenrir <1.5 just use ''generic''
852 * ''gstreamerDriver'' using the gstreamer, for Fenrir <1.5 just use ''gstreamer''
853
854 These are the pack of sounds used for sound icons.
855 theme=default
856 By default we ship two sound packs.
857 - ''default'' opus encoded, for newer Sox versions
858 - ''default-wav'' wav encoded, just for compatibility
859 Sound packs are located at /usr/share/sounds/fenrir/
860
861 Sound volume controls how loud the sounds for your selected sound pack are.
862 volume=1.0
863 Values: ''0.0'' is quietest, ''1.0'' is loudest.
864
865 === Generic Driver ===
866 The generic sound driver uses shell commands for play sound and frequencies.
867
868 ''genericPlayFileCommand'' defines the command that is used to play a sound file.
869 genericPlayFileCommand=<your command for playing a file>
870 ''genericFrequencyCommand'' defines the command that is used playing frequencies.
871 genericFrequencyCommand=<your command for playing a frequence>
872
873 The following variables are substituted in ''genericPlayFileCommand'' and ''genericFrequencyCommand'':
874 * ''fenrirVolume'' = the current volume setting
875 * ''fenrirSoundFile'' = the sound file for an sound icon
876 * ''fenrirFrequence'' = the frequency to play
877 * ''fenrirDuration'' = the duration of the frequency
878
879 Example genericPlayFileCommand (default)
880 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
881 Example genericFrequencyCommand (default)
882 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
883 ==== Speech ====
884 Speech is configured in section ''[speech]''.
885 Turn speech on or off:
886 enabled=True
887 Values: on=''True'', off=''False''
888
889 # Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
890 driver=speechdDriver
891 #driver=espeakDriver
892 #driver=genericDriver
893
894 Select the driver used to generate speech output.
895
896 driver=speechdDriver
897
898 Available Drivers:
899 * ''genericDriver'' using the generic driver, for Fenrir <1.5 this is not available
900 * ''speechdDriver'' using speech-dispatcher, for Fenrir <1.5 just use ''speechd''
901 * ''espeakDriver'' using the espeak directly, for Fenrir <1.5 just use ''espeak''
902
903 The rate selects how fast Fenrir will speak.
904 rate=0.65
905 Values: Range Minimum:''0.0'' is slowest, Maximum:''1.0'' is fastest.
906
907 Pitch controls the pitch of the voice.
908 pitch=0.5
909 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest.
910
911 A Pitch for capital letters can be set.
912 capitalPitch=0.9
913 Values: Range Minimum:''0.0'' is lowest, Maximum:''1.0'' is highest.
914
915 The Volume controls the loudness of the voice.
916 volume=1.0
917 Values: Range Minimum:''0.0'' is quietest, Maximum:''1.0'' is loudest.
918
919 Some speech drivers like speechdDriver can support various modules. these can be set here.
920 module=espeak
921 Values: Text, Consult speech-dispatcher's configuration to see what modules are available.
922
923 Voice selects the varient you want to use, for example, f5 will use the female voice #5 in Espeak,
924 or if using the Espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
925 voice=
926 Values: Text, see your TTS synths documentation what is available.
927
928 Select the language you want Fenrir to use.
929 language=english-us
930 Values: Text, see your TTS synths documentation what is available.
931
932 Read new text as it occurs
933 autoReadIncoming=True
934 Values: on=''True'', off=''False''
935
936 === Generic Driver ===
937 The generic speech driver uses shell commands for speech synthisus.
938
939 ''genericSpeechCommand'' defines the command that is executed for creating speech
940 The following variables are substituted in ''genericSpeechCommand'':
941 * ''FenrirText'' = is the text that should be spoken
942 * ''fenrirModule'' = may be the speech module like used in speech-dispatcher, not every TTY needs this
943 * ''fenrirLanguage'' = the language to speak in
944 * ''fenrirVoice'' = is the current voice that should be used
945 * ''fenrirVolume'' = is replaced with the current volume
946 * ''fenrirPitch'' = is replaced with the current pitch
947 * ''fenrirRate'' = is replaced with the current speed (speech rate)
948
949 Example genericSpeechCommand (default):
950 genericSpeechCommand=espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"
951
952 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.
953
954 FenrirMinVolume=0
955 fenrirMaxVolume=200
956 fenrirMinPitch=0
957 fenrirMaxPitch=99
958 fenrirMinRate=80
959 fenrirMaxRate=450
960
961 The current volume, pitch and rate is calculated like this
962 value = min + [volume,pitch,rate] * (min - max )
963 ==== Braille ====
964 Braille is a WIP and not ready yet.
965 Braille support can be configured in section ''[braille]''.
966
967 Turn braille on or off:
968 enabled=False
969 Values: on=''True'', off=''False''
970
971 Select the driver used for communication with a braille device.
972 driver=brlapiDriver
973 Values: Text, available Driver
974 Available Drivers:
975 * ''brlttyDriver'' using brltty for braille communication, for Fenrir <1.5 just use ''brltty''
976
977 The Braille layout can be configured here
978 layout=en
979 Values: Text, see braille driver for layouts.
980
981 What should the flush timeout relate to
982 flushMode=word
983 Values: Text, an flushMode
984 Existing flushModes:
985 * ''word'' = flush after (number of words to display) * seconds
986 * ''char'' = flush after (number of chars to display) * seconds
987 * ''fix'' = flush after X seconds
988 * ''none'' = no automatic flush (manual via shortcut)
989
990 Seconds to flush (see flushMode)
991 flushTimeout=3
992 Values: Integer, in Seconds or ''-1'' = no automatic flush (manual via shortcut)
993 The total flush time calculates in relation to flushMode.
994
995 How should the Braille cursor focus be tracked?
996 cursorFocusMode=page
997 Values: Text, an existing cursor focus mode
998 Available cursor focus modes:
999 * ''page'' = if the cursor crosses the border move to next page and start at begin
1000 * ''fixCell'' = ajust the cursor on a special cell where it is always placed. the display scroll here more smooth.
1001
1002
1003 Define the cell on the Braille device where Fenrir should scroll and keep the cursor
1004 fixCursorOnCell=-1
1005 Values: Integer
1006 * ''0'' = first cell on device,
1007 * ''-1'' = last cell on device
1008 * ''>0'' = fix cell number
1009
1010 What cursor should Fenrir show on the Braille device
1011 cursorFollowMode=review
1012 Values: Text, an exsiting cursor following mode.
1013 Existing cursor following mode:
1014 * ''none'' = no automatic toggle command used
1015 * ''review'' = priority to review
1016 * ''last'' = follow last used cursor
1017
1018 number of cells in panning (horizontal). How many cell should be panned on press the routing key?
1019 panSizeHorizontal=0
1020 Values: Integer,
1021 * ''0'' = display size
1022 * ''>0'' number of cells
1023 ==== Screen ====
1024 The settings for screens, (TTY, PTY) are configured in the ''[screen]'' section.
1025
1026 The driver to get the information from the screen:
1027 driver=vcsaDriver
1028 Available Drivers:
1029 * ''vcsaDriver'' using the VCSA driver (for TTYs), for Fenrir <1.5 just use ''vcsa''
1030 The encoding of the screen
1031 encoding=cp850
1032 Values:''cp850'' is used for Western languages like USA or Europe.
1033
1034 The driver updates Fenrir with changes on the screen.
1035 screenUpdateDelay=0.05
1036 Values: in Seconds
1037
1038 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:
1039 suspendingScreen=
1040 Values: Depends on driver:
1041 * VCSA: the number of the TTY. TTY6 is ''6''.
1042 Example ignore TTY1 and TTY2:
1043 suspendingScreen=1,2
1044
1045 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.
1046 autodetectSuspendingScreen=True
1047 Values: on=''True'', off=''False''
1048
1049 ==== Keyboard ====
1050 The settings for keyboard and input related configuration is located in the section ''[keyboard]'' of the ''settings.conf'' file.
1051
1052 Select the driver used for grabbing keybord input and for recieving shortcuts.
1053 driver=evdevDriver
1054 Values: Text, available Driver
1055 Available Drivers:
1056 * ''evdevDriver'' uses the evdev input system of linux, for Fenrir <1.5 just use ''evdev''
1057
1058 You can let Fenrir know about what input devices are to be used.
1059 device=ALL
1060 Values:
1061 * ''ALL'' use all devices with key capabilities.
1062 * ''NOMICE'' Exclude mices from handling.
1063 * ''<Device Name>'' just use the device with the given name.
1064
1065 Gives Fenrir exclusive access to the keyboard and lets it control keystrokes. This is needed to intercept Fenrir related shortcuts.
1066 grabDevices=True
1067 Values: on=''True'', off=''False''
1068
1069 The following makes sense if you are using a second screenreader and want to have some hooked events. Fenrir ignores all shortcuts then.
1070 ignoreShortcuts=False
1071 Values: on=''True'', off=''False''
1072
1073 The current keyboard layout used for shortcuts.
1074 keyboardLayout=desktop
1075 Values: An absolute Path to a Keyboard definition file or a Filename without extension located in ''/etc/fenrir/keyboard''
1076
1077 Announce characters while typing.
1078 charEcho=False
1079 Values: on=''True'', off=''False''
1080
1081 Announce deleted characters
1082 charDeleteEcho=True
1083 Values: on=''True'', off=''False''
1084
1085 Announce word after pressing space
1086 wordEcho=False
1087 Values: on=''True'', off=''False''
1088
1089 Interrupt speech on any keypress
1090 interruptOnKeyPress=False
1091 Values: on=''True'', off=''False''
1092
1093 You can filter the keys that speech should interrupt
1094 interruptOnKeyPressFilter=
1095 Values: (List) empty = all keys, otherwise interrupt with specified keys
1096
1097 The timeout that is used for double tap shortcuts
1098 doubleTapTimeout=0.2
1099 Values: Seconds
1100 ==== General ====
1101 Overall settings can be configured from the section ''[general]''.
1102
1103 Set the current debug level:
1104 debugLevel=1
1105 Values: off=0, error=1, warning=2, info=3
1106
1107 the current punctuation and dict file in use:
1108 punctuationProfile=default
1109 Values: Text, see available profiles in ''/etc/fenrir/punctuation'' or in ''sourceTree/config/punctuation''
1110
1111 The current punctuation level in use:
1112 punctuationLevel=some
1113 Values: Text, See available levels in the used punctuation file.
1114
1115 Respect pause for punctuations:
1116 respectPunctuationPause=True
1117 Values: on=''True'', off=''False''
1118
1119 Add a pause on Line break:
1120 newLinePause=True
1121 Values: on=''True'', off=''False''
1122
1123 Specify the path where the clipboard should be exported to.
1124 See [[#export clipboard to file|export clipboard to file]].
1125 The variable ''$user'' is replaced by the current logged username.
1126 clipboardExportPath=/tmp/fenrirClipboard
1127 Values: Text, Systemfilepath
1128
1129 The number of available clipboards:
1130 numberOfClipboards=10
1131 Values: Integer, 1 - 999
1132
1133 Replace emoticons like :) or ;) with text insertions:
1134 emoticons=True
1135 Values: on=''True'', off=''False''
1136
1137 Define the current Fenrir keys:
1138 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
1139 Values, Text list, separated by comma.
1140
1141 Define the current script keys:
1142 scriptKey=KEY_COMPOSE
1143 Values, Text list, separated by comma.
1144
1145 The time format to be used for (time command) output:
1146 timeFormat=%H:%M:%P
1147 Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]]
1148
1149 The date format to be used for (date command) output:
1150 dateFormat=%A, %B %d, %Y
1151 Values: see python specification for [[https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior|datetime.strftime]]
1152
1153 Enable or Disable spellcheck whilst typing:
1154 autoSpellCheck=True
1155 Values: on=''True'', off=''False''
1156
1157 The use of the dictionary with spellcheck:
1158 spellCheckLanguage=en_US
1159 Values: Text, see aspell dictionary's.
1160
1161 Folder Path for your scripts "scriptKey" functionality:
1162 scriptPath=/usr/share/fenrir/scripts
1163 Values: Text, Existing path on file system.
1164
1165 Override commands or create new ones without changing the Fenrir defaults:
1166 commandPath=/usr/share/fenrir/commands
1167 Values: Text, Existing path on file system.
1168 Subfolders in commandPath are:
1169 * ''commands'' = to create shortcut commands
1170 * ''onInput'' = executed while typing
1171 * ''onScreenChange'' = executed on change the screen (change from TTY4 to TTY6)
1172 * ''onScreenUpdate'' = executed when the screen is captured
1173
1174 ==== Focus ====
1175 The configuration for basic focus is in the section ''[focus]''.
1176 Follow the text cursor:
1177 cursor=True
1178 Values: on=''True'', off=''False''
1179
1180 Follow highlighted text changes (Highlight Tracking):
1181 highlight=False
1182 Values: on=''True'', off=''False''
1183 ==== Review ====
1184 Configurations for the review mode are in the section ''[review]''.
1185
1186 If "next word/ char" or "prev word/char" create a linebreak, announce it:
1187 lineBreak=True
1188 Values: on=''True'', off=''False''
1189
1190 If "next word/ char" or "prev word/char" cannot be performed because you reached the end of the screen, announce it:
1191 endOfScreen=True
1192 Values: on=''True'', off=''False''
1193
1194 Leave the review mode when pressing a key:
1195 leaveReviewOnKeypress=False
1196 Values: on=''True'', off=''False''
1197
1198 Leave the review mode when changing the screen (From TTY3 to TTY4):
1199 leaveReviewOnScreenChange=True
1200 Values: on=''True'', off=''False''
1201 ==== Promote ====
1202 "Promoted Lists" are configured in the section ''[promote]''.
1203 Turn Promoted Lists" on or off:
1204 enabled=True
1205 Values: on=''True'', off=''False''
1206
1207 The minimum time interval of inactivity to activate promoting.
1208 By default it promotes after 120 Seconds inactivity:
1209 inactiveTimeoutSec=120
1210 Values: in Seconds
1211
1212 Define a list of promoted words comma seperated:
1213 list=
1214 Values: text (comma seperated)
1215 Example to promote the word "nickname" or a bash prompt:
1216 list=nickname,$:,#:
1217
1218 ==== Time ====
1219 The automated time announcement is configured in the section ''[time]''.
1220 Time announcement is disabled by default.
1221 Turn time announcement on or off:
1222 enabled=True
1223 Values: on=''True'', off=''False''
1224
1225 Should the time be announced:
1226 presentTime=True
1227 Values: on=''True'', off=''False''
1228
1229 Should the date be announced (just on date change):
1230 presentDate=True
1231 Values: on=''True'', off=''False''
1232
1233 Announce after a given period of seconds:
1234 delaySec=0
1235 Value: in Seconds, 0 = Deactivated
1236
1237 Announce after fixed minutes in an hour. if delaySec is >0 onMinutes is ignored:
1238 onMinutes=00,30
1239 Example every 15 minutes:
1240 onMinutes=00,15,30,45
1241
1242 Just play a soundicon, (not interrupting):
1243 announce=True
1244 Values: on=''True'', off=''False''
1245
1246 Interrupt current speech for time announcement:
1247 interrupt=False
1248 Values: on=''True'', off=''False''
1249 ====== Customization ======
1250 ===== Scripting =====
1251 Scripts can be in any language, bash, python, sh or others. Place your scripts in the directory /usr/share/fenrir/scripts/ (the path is configurable in settings.conf).
1252 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.
1253 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/fenrir/scripts/weather__-__key_w.py
1254 Then, to access the script, simply press the script key and the letter w.
1255 Scripts must be executable. So, make sure to chmod 755 your script when you place it in the scripts directory.
1256 The script gets some parameters from fenrir when it is executed. So that information is available in your script then.
1257
1258 ==== Parameterlist ====
1259 ^Parameter ^Content ^
1260 |$1|Username of the current logged in user|
1261
1262 ==== Examples ====
1263 Script that just speaks the current username when pressing ScriptKey + H.\\
1264 File: ''/usr/share/fenrir/scripts/helloWorld__-__key_h.sh'':
1265 #!/bin/bash
1266 echo $1
1267
1268
1269 ===== Commands =====
1270 You can place your own commands in "/usr/share/fenrir/commands" (path is configurable in settings.conf).
1271 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.
1272 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)
1273 the basic scheme for a command is as follows:
1274
1275 from core import debug
1276
1277 class command():
1278 def __init__(self):
1279 pass
1280 def initialize(self, environment):
1281 self.env = environment
1282 def shutdown(self):
1283 pass
1284 def getDescription(self):
1285 return _('No description found')
1286 def run(self):
1287 pass
1288 def setCallback(self, callback):
1289 pass
1290
1291 * [[https://github.com/chrys87/fenrir/blob/master/src/fenrir/commands/command_template.py|Template lives here]]
1292 * The class needs to have the name "command".
1293 * "initialize" is running once whilst loading the command.
1294 * "shutdown" is running on unload like the command (quit fenrir)
1295 * "getDescriptsion" just returns an string. That String is used in Tutorial Mode.
1296 * "run" is executed when the command is invoked. (shortcut is pressed, or trigger isn't running)
1297 * setCAllback is currently not used. and has no functionality yet.
1298
1299
1300 ====== Troubleshooting ======
1301 ===== Fenrir does not start =====
1302 - Have you installed all the dependencies [[#Support and Requirements|Support and Requirements]]
1303 - Try using master, a lot of changes take place there to make Fenrir compatible with more systems
1304 ===== Fenrir does not utilize the shortcuts =====
1305 - Make sure you have python3-evdev installed
1306 - Use the latest Fenrir version
1307 - Make sure that Fenrir has permission to /dev/input/* and /dev/uinput (or run it as root)
1308 ===== No sound at all =====
1309 - 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''
1310 - Use ALSA
1311 - [[https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/SystemWide/|Configure Pulse system wide]] (Not recommended)
1312 - Use gstreamerDriver: change ''settings.conf'' in the section ''sound'' the line ''driver=genericDriver'' to ''driver=gstreamerDriver''
1313 - Use wave sound-icons: change ''settings.conf'' in the section ''sound'' the line ''theme=default'' to ''theme=default-wav''
1314 - Use most current version of [[http://sox.sourceforge.net/|sox]] with opus support
1315 - Try [[https://github.com/i-rinat/apulse|apulse]] (not tested by myself but might work). Please give me feedback if you try it out.
1316 ===== You get sound-icons but no speech =====
1317 - If you are using speech-dispatcher run "spd-conf" once as user and as root.
1318 - You can test if speech-dispatcher works by invoking it as root\\ ''sudo spd-say "hello world"''
1319 ===== Bugreports and feature requests =====
1320 Please report Bugs and feature requests to:
1321 [[https://github.com/chrys87/fenrir/issues|https://github.com/chrys87/fenrir/issues]]
1322
1323 for bugs please provide a [[#Howto create a debug file|debug]] file that shows the issue.
1324 ==== How-to create a debug file ====
1325 - Delete old debug stuff\\ ''sudo rm /var/log/fenrir.log''
1326 - Start fenrir in debug mode\\ ''sudo fenrir -d''
1327 - Do your stuff to reproduce the problem
1328 - Stop fenrir (''fenrirKey + q'')
1329 the debug file is located in ''/var/log/fenrir.log''
1330
1331 Please be as precise as possible to make it easy to solve the problem.
0 install it.
1 1. build it
2 make -f /usr/share/selinux/strict/include/Makefile fenrir.pp
3 2. install it
4 semodule -i /path/to/fenrir.pp
5
6
7 # created with that
8 # systemctl start fenrir
9 # ausearch -c '(r-daemon)' --raw | audit2allow -M fenrir
10 # semodule -X 300 -i fenrir.pp
11
0 module fenrir 1.0;
1
2 require {
3 type user_home_t;
4 type init_t;
5 class file { execute execute_no_trans open read };
6 }
7
8 #============= init_t ==============
9 allow init_t user_home_t:file { execute execute_no_trans open read };
+0
-48
experimental/setup.py less more
0 #!/bin/python
1 import os
2 from setuptools import find_packages
3 from setuptools import setup
4 def read(fname):
5 return open(os.path.join(os.path.dirname(__file__), fname)).read()
6
7
8
9 setup(
10 # Application name:
11 name="fenrir",
12 # Version number (initial):
13 version="0.1a",
14
15 # Application author details:
16 author="Chrys and others",
17 author_email="chrys87@web.de",
18
19 # Packages
20 packages=find_packages('src/fenrir'),
21 package_dir={'': 'src/fenrir'},
22 scripts=['src/fenrir/fenrir','src/fenrir/fenrir-daemon'],
23 #entry_points = {
24 # "console_scripts": ['fenrir = fenrir:main']
25 # },
26
27 # Include additional files into the package
28 include_package_data=True,
29
30 # Details
31 url="https://github.com/chrys87/fenrir/",
32 zip_safe=False,
33 #
34 # license="MIT",
35 description="An TTY Screen Reader For Linux.",
36 long_description=read('README.md'),
37 classifiers=[
38 "Development Status :: 3 - Alpha",
39 ],
40 # Dependent packages (distributions)
41 install_requires=[
42 "evdev",
43 "sox",
44 ],
45
46 )
47
00 #!/bin/bash
1 #Basic install script for fenrir.
2 read -p "This will install fenrir. Press ctrl+c to cancil, or enter to continue." continue
1 #Basic install script for Fenrir.
2 read -p "This will install Fenrir. Press ctrl+C to cancel, or enter to continue." continue
3
4 # Fenrir main application
35 install -m755 -d /opt/fenrir
6 cp -af src/fenrir/* /opt/fenrir
7 install -m644 -D "autostart/systemd/fenrir.service" /usr/lib/systemd/system/fenrir.service
8 ln -fs /opt/fenrir/fenrir-daemon /usr/bin/fenrir-daemon
9 ln -fs /opt/fenrir/fenrir /usr/bin/fenrir
10 # tools
11 install -m755 -d /usr/share/fenrir/tools
12 cp -af tools/* /usr/share/fenrir/tools
13
14 # scripts
415 install -m755 -d /usr/share/fenrir/scripts
16 cp -af "config/scripts/wlan__-__key_y.sh" /usr/share/fenrir/scripts/
17
18 # keyboard
519 install -m644 -D "config/keyboard/desktop.conf" /etc/fenrir/keyboard/desktop.conf
6 install -m644 -D "config/keyboard/desktop.conf" /etc/fenrir/keyboard/desktop.conf
7 install -m644 -D "config/punctuation/default.conf" /etc/fenrir/punctuation/default.conf
8 install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf
20 install -m644 -D "config/keyboard/laptop.conf" /etc/fenrir/keyboard/laptop.conf
21
22 # punctuation
23 install -m755 -d /etc/fenrir/punctuation
24 cp -af config/punctuation/* /etc/fenrir/punctuation
25
26 # sound
927 install -d /usr/share/sounds/fenrir
10 install -m644 -D "autostart/systemd/fenrir.service" /usr/lib/systemd/system/fenrir.service
11 cp -a src/fenrir/* /opt/fenrir
12 cp -a config/scripts/* /usr/share/fenrir/scripts
13 cp -a config/sound/* /usr/share/sounds/fenrir
14 ln -s /opt/fenrir/fenrir-daemon /usr/bin/fenrir
28 cp -af config/sound/default /usr/share/sounds/fenrir/default
29 cp -af config/sound/default-wav /usr/share/sounds/fenrir/default-wav
30 cp -af config/sound/template /usr/share/sounds/fenrir/template
31
32 # config
33 if [ -f "/etc/fenrir/settings/settings.conf" ]; then
34 echo "Do you want to overwrite your current global settings? (y/n)"
35 read yn
36 if [ $yn = "Y" -o $yn = "y" ]; then
37 mv /etc/fenrir/settings/settings.conf /etc/fenrir/settings/settings.conf.bak
38 echo "Your old settings.conf has been backed up to settings.conf.bak."
39 install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf
40 else
41 install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf.current
42 fi
43 else
44 install -m644 -D "config/settings/settings.conf" /etc/fenrir/settings/settings.conf
45 fi
46
47
48 # end message
1549 cat << EOF
16 To have fenrir start at boot:
50 Installation complete.
51 install path:/opt/fenrir
52 settings path:/etc/fenrir
53
54 To test Fenrir
55 sudo systemctl start fenrir
56 To have Fenrir start on system boot:
1757 sudo systemctl enable fenrir
58
1859 Pulseaudio users may want to run
19 /usr/share/fenrir/tools/configure-pulseaudio
20 once as their user account and once as root.
60 /usr/share/fenrir/tools/configure_pulse.sh
61 once from their user account, then once from the root.
2162 EOF
22 - spellcheck triggers twice if there are two spaces after an word and you arrow over them
33
44 Glitches (improve diff results):
5 - For example, in screen, it just tells me bell in window, but doesn't tell me which one. (southernprince)
6 - alpine seems to have problems (southernprince)
5 - currently None
6
7 wishes:
8 - whole status line in irssi is spoken insteed of just the changes (lilmike)
9 - whole status line in vim is spoken insteed of just the changes (lilmike)
10
0 # SOME DESCRIPTIVE TITLE.
1 # Copyright (C) YEAR ORGANIZATION
2 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3 #
4 msgid ""
5 msgstr ""
6 "Project-Id-Version: \n"
7 "POT-Creation-Date: 2017-02-26 22:19+UTC\n"
8 "PO-Revision-Date: 2017-02-26 17:01-0600\n"
9 "Last-Translator: \n"
10 "Language-Team: \n"
11 "Language: es\n"
12 "MIME-Version: 1.0\n"
13 "Content-Type: text/plain; charset=UTF-8\n"
14 "Content-Transfer-Encoding: 8bit\n"
15 "Generated-By: pygettext.py 1.5\n"
16 "X-Generator: Poedit 1.6.11\n"
17 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
18
19 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:27
20 msgid "adds the current word to the exceptions dictionary"
21 msgstr "añade la palabra actual al diccionario"
22
23 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:34
24 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:34
25 #: ../src/fenrir/commands/commands/spell_check.py:29
26 #: ../src/fenrir/commands/commands/spell_check.py:36
27 msgid "pyenchant is not installed"
28 msgstr "Pyenchant no está instalado"
29
30 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:49
31 msgid "{0} is already in dict"
32 msgstr "{0} ya se encuentra en el diccionario"
33
34 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:52
35 msgid "{0} added"
36 msgstr "{0} se ha añadido"
37
38 #: ../src/fenrir/commands/commands/bookmark_1.py:19
39 #: ../src/fenrir/commands/commands/bookmark_10.py:19
40 #: ../src/fenrir/commands/commands/bookmark_2.py:19
41 #: ../src/fenrir/commands/commands/bookmark_3.py:19
42 #: ../src/fenrir/commands/commands/bookmark_4.py:19
43 #: ../src/fenrir/commands/commands/bookmark_5.py:19
44 #: ../src/fenrir/commands/commands/bookmark_6.py:19
45 #: ../src/fenrir/commands/commands/bookmark_7.py:19
46 #: ../src/fenrir/commands/commands/bookmark_8.py:19
47 #: ../src/fenrir/commands/commands/bookmark_9.py:19
48 msgid "read Bookmark {0}"
49 msgstr "Leer marcador {0}"
50
51 #: ../src/fenrir/commands/commands/bookmark_1.py:24
52 #: ../src/fenrir/commands/commands/bookmark_10.py:24
53 #: ../src/fenrir/commands/commands/bookmark_2.py:24
54 #: ../src/fenrir/commands/commands/bookmark_3.py:24
55 #: ../src/fenrir/commands/commands/bookmark_4.py:24
56 #: ../src/fenrir/commands/commands/bookmark_5.py:24
57 #: ../src/fenrir/commands/commands/bookmark_6.py:24
58 #: ../src/fenrir/commands/commands/bookmark_7.py:24
59 #: ../src/fenrir/commands/commands/bookmark_8.py:24
60 #: ../src/fenrir/commands/commands/bookmark_9.py:24
61 msgid "Bookmark {0} not set"
62 msgstr "No se ha establecido el marcador {0}"
63
64 #: ../src/fenrir/commands/commands/bookmark_1.py:27
65 #: ../src/fenrir/commands/commands/bookmark_1.py:30
66 #: ../src/fenrir/commands/commands/bookmark_10.py:27
67 #: ../src/fenrir/commands/commands/bookmark_10.py:30
68 #: ../src/fenrir/commands/commands/bookmark_2.py:27
69 #: ../src/fenrir/commands/commands/bookmark_2.py:30
70 #: ../src/fenrir/commands/commands/bookmark_3.py:27
71 #: ../src/fenrir/commands/commands/bookmark_3.py:30
72 #: ../src/fenrir/commands/commands/bookmark_4.py:27
73 #: ../src/fenrir/commands/commands/bookmark_4.py:30
74 #: ../src/fenrir/commands/commands/bookmark_5.py:27
75 #: ../src/fenrir/commands/commands/bookmark_5.py:30
76 #: ../src/fenrir/commands/commands/bookmark_6.py:27
77 #: ../src/fenrir/commands/commands/bookmark_6.py:30
78 #: ../src/fenrir/commands/commands/bookmark_7.py:27
79 #: ../src/fenrir/commands/commands/bookmark_7.py:30
80 #: ../src/fenrir/commands/commands/bookmark_8.py:27
81 #: ../src/fenrir/commands/commands/bookmark_8.py:30
82 #: ../src/fenrir/commands/commands/bookmark_9.py:27
83 #: ../src/fenrir/commands/commands/bookmark_9.py:30
84 msgid "Bookmark for application {0} not set"
85 msgstr "El marcador para la aplicación {0} no se ha establecido"
86
87 #: ../src/fenrir/commands/commands/bookmark_1.py:43
88 #: ../src/fenrir/commands/commands/bookmark_10.py:43
89 #: ../src/fenrir/commands/commands/bookmark_2.py:43
90 #: ../src/fenrir/commands/commands/bookmark_3.py:43
91 #: ../src/fenrir/commands/commands/bookmark_4.py:43
92 #: ../src/fenrir/commands/commands/bookmark_5.py:43
93 #: ../src/fenrir/commands/commands/bookmark_6.py:43
94 #: ../src/fenrir/commands/commands/bookmark_7.py:43
95 #: ../src/fenrir/commands/commands/bookmark_8.py:43
96 #: ../src/fenrir/commands/commands/bookmark_9.py:43
97 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:27
98 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:30
99 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:27
100 #: ../src/fenrir/commands/commands/indent_curr_line.py:31
101 #: ../src/fenrir/commands/commands/marked_text.py:33
102 #: ../src/fenrir/commands/commands/present_first_line.py:25
103 #: ../src/fenrir/commands/commands/present_last_line.py:25
104 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:27
105 #: ../src/fenrir/commands/commands/review_curr_line.py:27
106 #: ../src/fenrir/commands/commands/review_curr_word.py:27
107 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:27
108 #: ../src/fenrir/commands/commands/review_line_begin.py:27
109 #: ../src/fenrir/commands/commands/review_next_line.py:29
110 #: ../src/fenrir/commands/commands/review_next_word.py:29
111 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:27
112 #: ../src/fenrir/commands/commands/review_prev_line.py:27
113 #: ../src/fenrir/commands/commands/review_prev_word.py:27
114 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:27
115 #: ../src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py:38
116 #: ../src/fenrir/commands/onInput/72000-history.py:50
117 msgid "blank"
118 msgstr "en blanco"
119
120 #: ../src/fenrir/commands/commands/braille_flush.py:17
121 msgid "flush the braille device if a message is written on"
122 msgstr "Limpia el dispositivo braille al escribir un mensaje en él."
123
124 #: ../src/fenrir/commands/commands/braille_pan_left.py:17
125 msgid "Move braille view to the left."
126 msgstr "Mover la vista Braille a la izquierda"
127
128 #: ../src/fenrir/commands/commands/braille_pan_right.py:17
129 msgid "Move braille view to the right."
130 msgstr "Mover la vista braille a la derecha"
131
132 #: ../src/fenrir/commands/commands/braille_return_to_cursor.py:17
133 msgid "Set the braille view back to cursor."
134 msgstr "Establecer la vista Braille en el cursor"
135
136 #: ../src/fenrir/commands/commands/clear_bookmark_1.py:17
137 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:17
138 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:17
139 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:17
140 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:17
141 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:17
142 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:17
143 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:17
144 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:17
145 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:17
146 msgid "remove Bookmark {0}"
147 msgstr "Eliminar marcador {0}"
148
149 #: ../src/fenrir/commands/commands/clear_bookmark_1.py:24
150 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:24
151 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:24
152 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:24
153 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:24
154 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:24
155 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:24
156 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:24
157 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:24
158 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:24
159 msgid "Bookmark {0} removed for application {1}"
160 msgstr "el marcador {0} de la aplicación {1} ha sido eliminado"
161
162 #: ../src/fenrir/commands/commands/clear_clipboard.py:17
163 msgid "clears the currently selected clipboard"
164 msgstr "Vacía el portapapeles seleccionado"
165
166 #: ../src/fenrir/commands/commands/clear_clipboard.py:22
167 msgid "clipboard cleared"
168 msgstr "Portapapeles vacío"
169
170 #: ../src/fenrir/commands/commands/clear_window_application.py:17
171 msgid "Turn off window mode for application"
172 msgstr "Desactiva el modo de ventana para la aplicación"
173
174 #: ../src/fenrir/commands/commands/clear_window_application.py:22
175 msgid "Window Mode off for application {0}"
176 msgstr "El modo de ventana está desactivado para la aplicación {0}"
177
178 #: ../src/fenrir/commands/commands/clear_window_application.py:24
179 msgid "Not in window Mode"
180 msgstr "No está en modo ventana"
181
182 #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:18
183 msgid "copies marked text to the currently selected clipboard"
184 msgstr "Copia el texto marcado al portapapeles en uso"
185
186 #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:22
187 msgid "one or two marks needed"
188 msgstr "se necesita una o dos marcas"
189
190 #: ../src/fenrir/commands/commands/curr_clipboard.py:17
191 msgid "speaks the contents of the currently selected clipboard"
192 msgstr "Habla el contenido del portapapeles seleccionado"
193
194 #: ../src/fenrir/commands/commands/curr_clipboard.py:21
195 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:29
196 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:32
197 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:35
198 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:38
199 #: ../src/fenrir/commands/commands/first_clipboard.py:21
200 #: ../src/fenrir/commands/commands/last_clipboard.py:21
201 #: ../src/fenrir/commands/commands/next_clipboard.py:21
202 #: ../src/fenrir/commands/commands/paste_clipboard.py:23
203 #: ../src/fenrir/commands/commands/paste_clipboard.py:26
204 #: ../src/fenrir/commands/commands/paste_clipboard.py:29
205 #: ../src/fenrir/commands/commands/paste_clipboard.py:32
206 #: ../src/fenrir/commands/commands/prev_clipboard.py:21
207 msgid "clipboard empty"
208 msgstr "Portapapeles vacío"
209
210 #: ../src/fenrir/commands/commands/curr_screen.py:17
211 msgid "reads the contents of the current screen"
212 msgstr "Lee el contenido de la pantalla actual"
213
214 #: ../src/fenrir/commands/commands/curr_screen.py:21
215 msgid "screen is empty"
216 msgstr "La pantalla está vacía"
217
218 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:18
219 msgid "reads from the cursor to the bottom of the screen"
220 msgstr "Lee desde el cursor hasta el final de la pantalla"
221
222 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:18
223 msgid "Reads from the top of the screen to the cursor position"
224 msgstr "Lee desde el inicio de la pantalla hasta la posición del cursor."
225
226 #: ../src/fenrir/commands/commands/cursor_column.py:17
227 msgid ""
228 "presents the current column number for review cursor in review mode or the "
229 "text cursor if not. Starts with 1"
230 msgstr ""
231 "Indica el número de columna actual para el cursor de revisión si se está en "
232 "el modo de revisión, o el cursor de texto si no."
233
234 #: ../src/fenrir/commands/commands/cursor_lineno.py:17
235 msgid ""
236 "presents the current line number for review cursor in review mode or the "
237 "text cursor if not. Starts with 1"
238 msgstr ""
239 "Indica el número de línea actual para el cursor de revisión si se está en el "
240 "modo de revisión, o el cursor de texto si no."
241
242 #: ../src/fenrir/commands/commands/cursor_position.py:17
243 msgid "displays the position of the review cursor"
244 msgstr "Indica la posición del cursor de revisión"
245
246 #: ../src/fenrir/commands/commands/cursor_position.py:23
247 msgid "line {0}, column {1}"
248 msgstr "Línea {0}, columna {1}"
249
250 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:18
251 msgid ""
252 "read to end of line, use review cursor if you are in review mode, otherwhise "
253 "use text cursor"
254 msgstr ""
255 "Leer hasta el fin de línea, utiliza el cursor de revisión cuando el modo de "
256 "revisión está activo, de lo contrario utiliza el cursor de texto."
257
258 #: ../src/fenrir/commands/commands/date.py:18
259 msgid "presents the date"
260 msgstr "Lee la fecha"
261
262 #: ../src/fenrir/commands/commands/dec_sound_volume.py:18
263 msgid "decrease sound volume"
264 msgstr "Reduce el volumen del sonido"
265
266 #: ../src/fenrir/commands/commands/dec_sound_volume.py:29
267 #: ../src/fenrir/commands/commands/inc_sound_volume.py:29
268 msgid "{0} percent sound volume"
269 msgstr "volumen de sonido al {0} porciento"
270
271 #: ../src/fenrir/commands/commands/dec_speech_pitch.py:18
272 msgid "decreases the pitch of the speech"
273 msgstr "Reduce el tono de voz"
274
275 #: ../src/fenrir/commands/commands/dec_speech_pitch.py:27
276 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:27
277 msgid "{0} percent speech pitch"
278 msgstr "Tono de voz al {0} porciento"
279
280 #: ../src/fenrir/commands/commands/dec_speech_rate.py:18
281 msgid "decreases the rate of the speech"
282 msgstr "Reduce la velocidad de voz"
283
284 #: ../src/fenrir/commands/commands/dec_speech_rate.py:27
285 #: ../src/fenrir/commands/commands/inc_speech_rate.py:27
286 msgid "{0} percent speech rate"
287 msgstr "Velocidad de voz al {0} porciento"
288
289 #: ../src/fenrir/commands/commands/dec_speech_volume.py:18
290 msgid "decreases the volume of the speech"
291 msgstr "Reduce el volumen de voz"
292
293 #: ../src/fenrir/commands/commands/dec_speech_volume.py:27
294 #: ../src/fenrir/commands/commands/inc_speech_volume.py:27
295 msgid "{0} percent speech volume"
296 msgstr "Volumen de voz al {0} porciento"
297
298 #: ../src/fenrir/commands/commands/exit_review.py:17
299 msgid "exits review mode"
300 msgstr "Sale del modo de revisión"
301
302 #: ../src/fenrir/commands/commands/exit_review.py:21
303 msgid "Not in review mode"
304 msgstr "No está en modo de revisión"
305
306 #: ../src/fenrir/commands/commands/exit_review.py:25
307 msgid "leave review mode"
308 msgstr "Saliendo del modo de revisión"
309
310 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:21
311 msgid "export the current fenrir clipboard to X clipboard"
312 msgstr "Exporta el contenido del portapapeles de Fenrir al servidor X"
313
314 #: ../src/fenrir/commands/commands/first_clipboard.py:17
315 msgid "selects the first clipboard"
316 msgstr "Selecciona el primer portapapeles"
317
318 #: ../src/fenrir/commands/commands/forward_keypress.py:17
319 msgid "sends the following keypress to the terminal"
320 msgstr "Envía la siguiente tecla a la terminal"
321
322 #: ../src/fenrir/commands/commands/forward_keypress.py:21
323 msgid "Forward next keypress"
324 msgstr "Enviar la siguiente tecla"
325
326 #: ../src/fenrir/commands/commands/inc_sound_volume.py:18
327 msgid "adjusts the volume for in coming sounds"
328 msgstr "aumenta el volumen del sonido"
329
330 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:18
331 msgid "increases the pitch of the speech"
332 msgstr "Aumenta el tono de voz"
333
334 #: ../src/fenrir/commands/commands/inc_speech_rate.py:18
335 msgid "increase the speech rate"
336 msgstr "Aumenta la velocidad de voz"
337
338 #: ../src/fenrir/commands/commands/inc_speech_volume.py:18
339 msgid "increase the speech volume"
340 msgstr "Aumenta el volumen de voz"
341
342 #: ../src/fenrir/commands/commands/indent_curr_line.py:18
343 msgid "shows the indention level for the current line"
344 msgstr "Lee el nivel de indentación de la línea actual"
345
346 #: ../src/fenrir/commands/commands/indent_curr_line.py:33
347 msgid "indent {0}"
348 msgstr ""
349
350 #: ../src/fenrir/commands/commands/last_clipboard.py:17
351 msgid "selects the last clipboard"
352 msgstr "Selecciona el último portapapeles"
353
354 #: ../src/fenrir/commands/commands/last_incoming.py:17
355 msgid "displays the last received text"
356 msgstr "Lee el último mensaje recibido"
357
358 #: ../src/fenrir/commands/commands/marked_text.py:18
359 msgid "speaks the currently selected text that will be copied to the clipboard"
360 msgstr "Lee el texto que será copiado al portapapeles"
361
362 #: ../src/fenrir/commands/commands/marked_text.py:23
363 msgid "please set begin and endmark"
364 msgstr "Establece una marca de principio y otra para el final de la selección."
365
366 #: ../src/fenrir/commands/commands/next_clipboard.py:17
367 msgid "selects the next clipboard"
368 msgstr "Selecciona el siguiente portapapeles"
369
370 #: ../src/fenrir/commands/commands/next_clipboard.py:26
371 msgid "First clipboard "
372 msgstr "Primer portapapeles"
373
374 #: ../src/fenrir/commands/commands/paste_clipboard.py:18
375 msgid "pastes the text from the currently selected clipboard"
376 msgstr "Pega el texto del portapapeles en uso"
377
378 #: ../src/fenrir/commands/commands/present_first_line.py:18
379 msgid "present first line"
380 msgstr "lee la primera línea"
381
382 #: ../src/fenrir/commands/commands/present_last_line.py:18
383 #: ../src/fenrir/commands/commands/review_curr_line.py:18
384 msgid "current line"
385 msgstr "línea actual"
386
387 #: ../src/fenrir/commands/commands/prev_clipboard.py:17
388 msgid "selects the previous clipboard"
389 msgstr "Selecciona el portapapeles anterior"
390
391 #: ../src/fenrir/commands/commands/prev_clipboard.py:26
392 msgid "Last clipboard "
393 msgstr "Último portapapeles"
394
395 #: ../src/fenrir/commands/commands/quit_fenrir.py:17
396 msgid "exits Fenrir"
397 msgstr "Sale de Fenrir"
398
399 #: ../src/fenrir/commands/commands/remove_marks.py:17
400 msgid "removes marks from selected text"
401 msgstr "Quitar marcas del texto seleccionado"
402
403 #: ../src/fenrir/commands/commands/remove_marks.py:21
404 msgid "Remove marks"
405 msgstr "Marcas eliminadas"
406
407 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:27
408 msgid "removes the current word from the exceptions dictionary"
409 msgstr "Quita la palabra actual del diccionario de excepciones"
410
411 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:50
412 msgid "{0} is already removed from dict"
413 msgstr "{0} no está en el diccionario"
414
415 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:53
416 msgid "{0} removed"
417 msgstr "se ha eliminado {0}"
418
419 #: ../src/fenrir/commands/commands/review_bottom.py:17
420 msgid "move review to bottom of screen"
421 msgstr "Mueve el cursor de revisión al final de la pantalla"
422
423 #: ../src/fenrir/commands/commands/review_bottom.py:21
424 msgid "Bottom"
425 msgstr "Fin"
426
427 #: ../src/fenrir/commands/commands/review_curr_char.py:18
428 msgid "presents the current character."
429 msgstr "Lee el carácter actual"
430
431 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:18
432 msgid "set review and phonetically presents the current character"
433 msgstr "Lee fonéticamente el último carácter"
434
435 #: ../src/fenrir/commands/commands/review_curr_word.py:18
436 msgid "current word."
437 msgstr "Palabra actual. "
438
439 #: ../src/fenrir/commands/commands/review_curr_word.py:32
440 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:36
441 #: ../src/fenrir/commands/commands/review_down.py:27
442 #: ../src/fenrir/commands/commands/review_next_char.py:28
443 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:30
444 #: ../src/fenrir/commands/commands/review_next_line.py:34
445 #: ../src/fenrir/commands/commands/review_next_word.py:34
446 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:36
447 #: ../src/fenrir/commands/commands/review_prev_char.py:31
448 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:30
449 #: ../src/fenrir/commands/commands/review_prev_line.py:32
450 #: ../src/fenrir/commands/commands/review_prev_word.py:32
451 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:36
452 #: ../src/fenrir/commands/commands/review_up.py:27
453 msgid "end of screen"
454 msgstr "Fin de pantalla"
455
456 #: ../src/fenrir/commands/commands/review_curr_word.py:35
457 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:39
458 #: ../src/fenrir/commands/commands/review_next_char.py:31
459 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:33
460 #: ../src/fenrir/commands/commands/review_next_word.py:37
461 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:39
462 #: ../src/fenrir/commands/commands/review_prev_char.py:34
463 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:33
464 #: ../src/fenrir/commands/commands/review_prev_word.py:35
465 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:39
466 #: ../src/fenrir/commands/commands/review_up.py:30
467 msgid "line break"
468 msgstr "Nueva línea"
469
470 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:19
471 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:19
472 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:19
473 msgid "phonetically spells the current word and set review to it"
474 msgstr "Deletrea fonéticamente la palabra actual"
475
476 #: ../src/fenrir/commands/commands/review_down.py:18
477 msgid "set review cursor to char below the current char and present it."
478 msgstr "Mueve el cursor de revisión al carácter después del actual y lo lee"
479
480 #: ../src/fenrir/commands/commands/review_line_begin.py:18
481 msgid "set review cursor to begin of current line and display the content"
482 msgstr "lee la línea actual desde el principio"
483
484 #: ../src/fenrir/commands/commands/review_line_begin.py:30
485 msgid "beginning of line"
486 msgstr "principio de línea"
487
488 #: ../src/fenrir/commands/commands/review_line_end.py:18
489 #: ../src/fenrir/commands/commands/review_line_first_char.py:19
490 #: ../src/fenrir/commands/commands/review_line_last_char.py:18
491 msgid "set review cursor to end of current line and display the content"
492 msgstr "Lee el final de la línea"
493
494 #: ../src/fenrir/commands/commands/review_line_end.py:27
495 msgid "end of line"
496 msgstr "Fin de línea"
497
498 #: ../src/fenrir/commands/commands/review_line_first_char.py:26
499 msgid "line is empty"
500 msgstr "Línea en blanco"
501
502 #: ../src/fenrir/commands/commands/review_line_first_char.py:33
503 msgid "first char in line indent {0}"
504 msgstr ""
505
506 #: ../src/fenrir/commands/commands/review_line_last_char.py:27
507 msgid "last char in line"
508 msgstr "último carácter de la línea"
509
510 #: ../src/fenrir/commands/commands/review_next_char.py:18
511 msgid "moves review to the next character and presents it"
512 msgstr "Lee el siguiente carácter"
513
514 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:18
515 msgid "phonetically presents the next character and set review to it"
516 msgstr "Lee fonéticamente el siguiente carácter"
517
518 #: ../src/fenrir/commands/commands/review_next_line.py:18
519 msgid "moves review to the next line and presents it"
520 msgstr "Lee la siguiente línea"
521
522 #: ../src/fenrir/commands/commands/review_next_word.py:18
523 msgid "moves review to the next word and presents it"
524 msgstr "Lee la siguiente palabra"
525
526 #: ../src/fenrir/commands/commands/review_prev_char.py:18
527 msgid "moves review to the previous character and presents it"
528 msgstr "Lee el carácter anterior"
529
530 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:18
531 msgid "phonetically presents the previous character and set review to it"
532 msgstr "Lee fonéticamente el carácter anterior"
533
534 #: ../src/fenrir/commands/commands/review_prev_line.py:18
535 msgid "moves review to the previous line and presents it"
536 msgstr "Lee la línea anterior"
537
538 #: ../src/fenrir/commands/commands/review_prev_word.py:18
539 msgid "moves review focus to the previous word and presents it"
540 msgstr "Lee la palabra anterior"
541
542 #: ../src/fenrir/commands/commands/review_top.py:18
543 msgid "move review to top of screen"
544 msgstr "ir al final de la pantalla"
545
546 #: ../src/fenrir/commands/commands/review_top.py:22
547 msgid "Top"
548 msgstr "Fin"
549
550 #: ../src/fenrir/commands/commands/review_up.py:18
551 msgid "set review cursor to the char in the line below and present it"
552 msgstr "Mueve el cursor de revisión al carácter en la siguiente línea y lo lee"
553
554 #: ../src/fenrir/commands/commands/set_bookmark_1.py:18
555 #: ../src/fenrir/commands/commands/set_bookmark_10.py:18
556 #: ../src/fenrir/commands/commands/set_bookmark_2.py:18
557 #: ../src/fenrir/commands/commands/set_bookmark_3.py:18
558 #: ../src/fenrir/commands/commands/set_bookmark_4.py:18
559 #: ../src/fenrir/commands/commands/set_bookmark_5.py:18
560 #: ../src/fenrir/commands/commands/set_bookmark_6.py:18
561 #: ../src/fenrir/commands/commands/set_bookmark_7.py:18
562 #: ../src/fenrir/commands/commands/set_bookmark_8.py:18
563 #: ../src/fenrir/commands/commands/set_bookmark_9.py:18
564 msgid "set Bookmark {0}"
565 msgstr "Añadir marcador {0}"
566
567 #: ../src/fenrir/commands/commands/set_bookmark_1.py:22
568 #: ../src/fenrir/commands/commands/set_bookmark_10.py:22
569 #: ../src/fenrir/commands/commands/set_bookmark_2.py:22
570 #: ../src/fenrir/commands/commands/set_bookmark_3.py:22
571 #: ../src/fenrir/commands/commands/set_bookmark_4.py:22
572 #: ../src/fenrir/commands/commands/set_bookmark_5.py:22
573 #: ../src/fenrir/commands/commands/set_bookmark_6.py:22
574 #: ../src/fenrir/commands/commands/set_bookmark_7.py:22
575 #: ../src/fenrir/commands/commands/set_bookmark_8.py:22
576 #: ../src/fenrir/commands/commands/set_bookmark_9.py:22
577 msgid "No Mark found"
578 msgstr "No se han encontrado marcas"
579
580 #: ../src/fenrir/commands/commands/set_bookmark_1.py:32
581 #: ../src/fenrir/commands/commands/set_bookmark_10.py:32
582 #: ../src/fenrir/commands/commands/set_bookmark_2.py:32
583 #: ../src/fenrir/commands/commands/set_bookmark_3.py:32
584 #: ../src/fenrir/commands/commands/set_bookmark_4.py:32
585 #: ../src/fenrir/commands/commands/set_bookmark_5.py:32
586 #: ../src/fenrir/commands/commands/set_bookmark_6.py:32
587 #: ../src/fenrir/commands/commands/set_bookmark_7.py:32
588 #: ../src/fenrir/commands/commands/set_bookmark_8.py:32
589 #: ../src/fenrir/commands/commands/set_bookmark_9.py:32
590 msgid "Bookmark {0} set for application {1}"
591 msgstr "Añadido marcador {0} para aplicación {1}"
592
593 #: ../src/fenrir/commands/commands/set_mark.py:17
594 msgid "places marks to select text to copy to the clipboard"
595 msgstr ""
596 "Establece marcas para seleccionar texto que será copiado al portapapeles"
597
598 #: ../src/fenrir/commands/commands/set_mark.py:21
599 msgid "no review cursor"
600 msgstr "No hay cursor de revisión"
601
602 #: ../src/fenrir/commands/commands/set_mark.py:26
603 #: ../src/fenrir/commands/commands/set_mark.py:28
604 msgid "set mark"
605 msgstr "Marcar"
606
607 #: ../src/fenrir/commands/commands/set_window_application.py:17
608 msgid "set Window Mode, needs 2 marks "
609 msgstr "se necesitan dos marcas para establecer el modo ventana"
610
611 #: ../src/fenrir/commands/commands/set_window_application.py:22
612 msgid "Window Mode on for application {0}"
613 msgstr "El modo de ventana está activado para la aplicación {0}"
614
615 #: ../src/fenrir/commands/commands/set_window_application.py:25
616 msgid "Set window begin and end marks"
617 msgstr "Establece una marca de principio y otra para el final de la ventana"
618
619 #: ../src/fenrir/commands/commands/shut_up.py:17
620 msgid "interrupts the current presentation"
621 msgstr "Interrumpe el habla y braille."
622
623 #: ../src/fenrir/commands/commands/spell_check.py:26
624 msgid "checks the spelling of the current word"
625 msgstr "Revisa la ortografía para la palabra actual"
626
627 #: ../src/fenrir/commands/commands/spell_check.py:52
628 #: ../src/fenrir/commands/onInput/62000-spell_check.py:132
629 msgid "misspelled"
630 msgstr "mal escrito"
631
632 #: ../src/fenrir/commands/commands/spell_check.py:54
633 msgid "correct"
634 msgstr "Correcto"
635
636 #: ../src/fenrir/commands/commands/subprocess.py:21
637 msgid "script: {0} fullpath: {1}"
638 msgstr "Script: {0} Ruta de archivo: {1}"
639
640 #: ../src/fenrir/commands/commands/subprocess.py:24
641 msgid "scriptfile does not exist"
642 msgstr "el archivo del script no existe"
643
644 #: ../src/fenrir/commands/commands/subprocess.py:27
645 msgid "scriptfile is not a file"
646 msgstr "El script no es un archivo"
647
648 #: ../src/fenrir/commands/commands/subprocess.py:30
649 msgid "scriptfile is not executable"
650 msgstr "el script no es ejecutable"
651
652 #: ../src/fenrir/commands/commands/temp_disable_speech.py:17
653 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:17
654 msgid "disables speech until next keypress"
655 msgstr "Desactiva el habla hasta la siguiente pulsación de teclas"
656
657 #: ../src/fenrir/commands/commands/temp_disable_speech.py:21
658 msgid "speech temporary disabled"
659 msgstr "Habla desactivada temporalmente"
660
661 #: ../src/fenrir/commands/commands/time.py:18
662 msgid "presents the time"
663 msgstr "Lee la hora"
664
665 #: ../src/fenrir/commands/commands/toggle_auto_read.py:16
666 msgid "enables or disables automatic reading of new text as it appears"
667 msgstr ""
668 "Activa o desactiva la lectura de texto cuando hay nuevo contenido en la "
669 "pantalla"
670
671 #: ../src/fenrir/commands/commands/toggle_auto_read.py:21
672 msgid "autoread enabled"
673 msgstr "Lectura automática activada"
674
675 #: ../src/fenrir/commands/commands/toggle_auto_read.py:23
676 msgid "autoread disabled"
677 msgstr "Lectura automática desactivada"
678
679 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:17
680 msgid "enables or disables automatic spell checking"
681 msgstr "Activa o desactiva la corrección ortográfica automática"
682
683 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:22
684 msgid "auto spellcheck enabled"
685 msgstr "corrección ortográfica automática activada"
686
687 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:24
688 msgid "auto spellcheck disabled"
689 msgstr "corrección ortográfica automática desactivada"
690
691 #: ../src/fenrir/commands/commands/toggle_auto_time.py:16
692 msgid "enables or disables automatic reading of time after an period"
693 msgstr ""
694 "Activa o desactiva la lectura automática de la hora después de un intervalo "
695 "de tiempo"
696
697 #: ../src/fenrir/commands/commands/toggle_auto_time.py:21
698 msgid "autotime enabled"
699 msgstr "lectura automática de hora activada"
700
701 #: ../src/fenrir/commands/commands/toggle_auto_time.py:23
702 msgid "autotime disabled"
703 msgstr "Lectura automática de hora desactivada"
704
705 #: ../src/fenrir/commands/commands/toggle_braille.py:17
706 msgid "enables and disables output in braille"
707 msgstr "Activa y desactiva la salida Braille"
708
709 #: ../src/fenrir/commands/commands/toggle_braille.py:21
710 msgid "braille disabled"
711 msgstr "Braille desactivado"
712
713 #: ../src/fenrir/commands/commands/toggle_braille.py:24
714 msgid "braille enabled"
715 msgstr "Braille activado"
716
717 #: ../src/fenrir/commands/commands/toggle_emoticons.py:16
718 msgid "enables or disables announcement of emoticons instead of chars"
719 msgstr "Activa o desactiva el anunciado de emoticonos en lugar de caracteres"
720
721 #: ../src/fenrir/commands/commands/toggle_emoticons.py:21
722 msgid "emoticons enabled"
723 msgstr "Emoticonos activados"
724
725 #: ../src/fenrir/commands/commands/toggle_emoticons.py:23
726 msgid "emoticons disabled"
727 msgstr "Emoticonos desactivados"
728
729 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:16
730 #: ../src/fenrir/commands/onInput/56000-highlight_tracking.py:16
731 msgid "enables or disables tracking of highlighted"
732 msgstr "Activa o desactiva el seguimiento de texto resaltado"
733
734 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:24
735 msgid "highlight tracking"
736 msgstr "Seguimiento del texto resaltado"
737
738 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:26
739 msgid "cursor tracking"
740 msgstr "Seguimiento del cursor"
741
742 #: ../src/fenrir/commands/commands/toggle_output.py:17
743 msgid "toggles all output settings"
744 msgstr "Conmuta el silencio del lector de pantalla"
745
746 #: ../src/fenrir/commands/commands/toggle_output.py:23
747 msgid "Fenrir muted"
748 msgstr "Fenrir silenciado"
749
750 #: ../src/fenrir/commands/commands/toggle_output.py:31
751 msgid "Fenrir unmuted"
752 msgstr "Desactivado el silencio"
753
754 #: ../src/fenrir/commands/commands/toggle_punctuation_level.py:23
755 msgid "No punctuation found."
756 msgstr "No se ha encontrado la puntuación"
757
758 #: ../src/fenrir/commands/commands/toggle_sound.py:17
759 msgid "enables or disables sound"
760 msgstr "Activa o desactiva el sonido"
761
762 #: ../src/fenrir/commands/commands/toggle_sound.py:21
763 msgid "sound disabled"
764 msgstr "sonido desactivado"
765
766 #: ../src/fenrir/commands/commands/toggle_sound.py:24
767 msgid "sound enabled"
768 msgstr "Sonido activado"
769
770 #: ../src/fenrir/commands/commands/toggle_speech.py:17
771 msgid "enables or disables speech"
772 msgstr "Activa o desactiva el habla"
773
774 #: ../src/fenrir/commands/commands/toggle_speech.py:21
775 msgid "speech disabled"
776 msgstr "Habla desactivada"
777
778 #: ../src/fenrir/commands/commands/toggle_speech.py:24
779 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:28
780 msgid "speech enabled"
781 msgstr "Habla activada"
782
783 #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:18
784 msgid ""
785 "You are leaving the tutorial mode. Press that shortcut again to enter the "
786 "tutorial mode again."
787 msgstr ""
788 "Has salido del tutorial. Presiona la misma combinación de teclado para "
789 "entrar al tutorial de nuevo."
790
791 #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:21
792 msgid ""
793 "you entered the tutorial mode. In that mode the commands are not executed. "
794 "but you get a description of what the shortcut does. To leave the tutorial "
795 "mode, press that shortcut again."
796 msgstr ""
797 "Has entrado al tutorial. En este modo las combinaciones de teclado no se "
798 "ejecutarán pero te darán una descripción de lo que hacen. Para salir del "
799 "tutorial, presiona la misma combinación de teclado de nuevo."
800
801 #: ../src/fenrir/commands/onInput/80000-capslock.py:22
802 msgid "Capslock on"
803 msgstr "Bloqueo mayúsculas activado"
804
805 #: ../src/fenrir/commands/onInput/80000-capslock.py:24
806 msgid "Capslock off"
807 msgstr "Bloqueo mayúsculas desactivado"
808
809 #: ../src/fenrir/commands/onInput/80300-scrolllock.py:22
810 msgid "Scrolllock on"
811 msgstr "Bloqueo de desplazamiento activado"
812
813 #: ../src/fenrir/commands/onInput/80300-scrolllock.py:24
814 msgid "Scrolllock off"
815 msgstr "Bloqueo de desplazamiento desactivado"
816
817 #: ../src/fenrir/commands/onInput/80500-numlock.py:22
818 msgid "Numlock on"
819 msgstr "Bloqueo numérico activado"
820
821 #: ../src/fenrir/commands/onInput/80500-numlock.py:24
822 msgid "Numlock off"
823 msgstr "Bloqueo numérico desactivado"
824
825 #: ../src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py:20
826 msgid "screen {0}"
827 msgstr "pantalla {0}"
828
829 #: ../src/fenrir/commands/onScreenUpdate/76000-time.py:66
830 msgid "Autotime: {0}"
831 msgstr "Hora automática: {0}"
832
833 #: ../src/fenrir/fenrir.py:24
834 msgid "Start Fenrir"
835 msgstr "Iniciando fenrir"
836
837 #: ../src/fenrir/fenrir.py:99
838 msgid "Quit Fenrir"
839 msgstr "Cerrando Fenrir"
0 #!/bin/python3
1 import argparse
2
3 parser = argparse.ArgumentParser(description="Fenrir Help")
4
5 parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile')
6 parser.add_argument('-o', '--options', metavar='SECTION:SETTING=VALUE,..', default='', help='Overwrite options in given settings file')
7
8 args = parser.parse_args()
9 parser.print_help()
10
11 print(args.setting)
0 import time
1 from fcntl import ioctl
2 from array import array
3 from struct import unpack_from
4 from struct import unpack
5 from struct import pack
6 import errno
7 import sys
8 charmap = {}
9 hichar = None
10 def updateCharMap(screen):
11 global hichar
12 ttyno = '4'
13 tty = open('/dev/tty' + screen, 'rb')
14 GIO_UNIMAP = 0x4B66
15 VT_GETHIFONTMASK = 0x560D
16 himask = array("H", (0,))
17 ioctl(tty, VT_GETHIFONTMASK, himask)
18 hichar, = unpack_from("@H", himask)
19 sz = 512
20 line = ''
21 while True:
22 try:
23 unipairs = array("H", [0]*(2*sz))
24 unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0]))
25 ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc)
26 break
27 except IOError as e:
28 if e.errno != errno.ENOMEM:
29 raise
30 sz *= 2
31 tty.close()
32 ncodes, = unpack_from("@H", unimapdesc)
33 utable = unpack_from("@%dH" % (2*ncodes), unipairs)
34 for u, b in zip(utable[::2], utable[1::2]):
35 if charmap.get(b) is None:
36 charmap[b] = chr(u)
37
38
39 def autoDecodeVCSA(allData, rows, cols):
40 allText = []
41 allAttrib = []
42 for y in range(rows):
43 lineText = ''
44 lineAttrib = []
45 i = 0
46 for x in range(cols):
47 data = allData[i: i + 2]
48 i += 2
49 if data == b' \x07':
50 #attr = 7
51 #ink = 7
52 #paper = 0
53 #ch = ' '
54 lineAttrib.append(7)
55 lineText += ' '
56 continue
57 (sh,) = unpack("=H", data)
58 attr = (sh >> 8) & 0xFF
59 ch = sh & 0xFF
60 if hichar == 0x100:
61 attr >>= 1
62 lineAttrib.append(attr)
63 ink = attr & 0x0F
64 paper = (attr>>4) & 0x0F
65 #if (ink != 7) or (paper != 0):
66 # print(ink,paper)
67 if sh & hichar:
68 ch |= 0x100
69 try:
70 lineText += charmap[ch]
71 except:
72 lineText += chr('?')
73 allText.append(lineText)
74 allAttrib.append(lineAttrib)
75 return allText, allAttrib
76
77 def m(screen):
78 s = time.time()
79 updateCharMap(str(screen))
80 print(time.time() -s )
81 vcsa = open('/dev/vcsa' + str(screen), 'rb')
82 head = vcsa.read(4)
83 rows = int(head[0])
84 cols = int(head[1])
85 text, attrib = autoDecodeVCSA(vcsa.read(), rows, cols)
86 print(time.time() -s )
87
0 #!/bin/bash
1 echo "foreground colors"
2 echo -e "\e[39mDefault"
3 echo -e "\e[30mBlack"
4 echo -e "\e[31mRed"
5 echo -e "\e[32mGreen"
6 echo -e "\e[33mYellow"
7 echo -e "\e[34mBlue"
8 echo -e "\e[35mMagenta"
9 echo -e "\e[36mCyan"
10 echo -e "\e[37mLight gray"
11 echo -e "\e[90mDark gray"
12 echo -e "\e[91mLight red"
13 echo -e "\e[92mLight green"
14 echo -e "\e[93mLight yellow"
15 echo -e "\e[94mLight blue"
16 echo -e "\e[95mLight magenta"
17 echo -e "\e[96mLight cyan"
18 echo -e "\e[97mWhite"
19
20 echo "background colors"
21 echo -e "\e[49mDefault"
22 echo -e "\e[40mBlack"
23 echo -e "\e[41mRed"
24 echo -e "\e[42mGreen"
25 echo -e "\e[43mYellow"
26 echo -e "\e[44mBlue"
27 echo -e "\e[45mMagenta"
28 echo -e "\e[46mCyan"
29 echo -e "\e[47mLight gray"
30 echo -e "\e[100mDark gray"
31 echo -e "\e[101mLight red"
32 echo -e "\e[102mLight green"
33 echo -e "\e[103mLight yellow"
34 echo -e "\e[104mLight blue"
35 echo -e "\e[105mLight magenta"
36 echo -e "\e[106mLight cyan"
37 echo -e "\e[107mWhite"
38
44 import time
55
66 iDevices = map(evdev.InputDevice, (evdev.list_devices()))
7 iDevices = {dev.fd: dev for dev in iDevices if 1 in dev.capabilities()}
7 iDevices = {dev.fd: dev for dev in iDevices if evdev.events.EV_KEY in dev.capabilities()}
8
89 uDevices = {}
910 for fd in iDevices:
1011 dev = iDevices[fd]
(No changes)
0 #!/bin/python
1 iDevices = {}
2 iDeviceNo = 0
3 def updateInputDevices(force = False, init = False):
4 global iDeviceNo
5 if init:
6 iDevices = {}
7 iDeviceNo = 0
8 deviceFileList = evdev.list_devices()
9 if not force:
10 if len(deviceFileList) == iDeviceNo:
11 return
12 iDeviceNo = len(deviceFileList)
13 mode = 'ALL'
14 iDevicesFiles = []
15 for device in iDevices:
16 iDevicesFiles.append(iDevices[device].fn)
17 print(len(iDevicesFiles),len(deviceFileList))
18 if len(iDevicesFiles) == len(deviceFileList):
19 return
20 for deviceFile in deviceFileList:
21 try:
22 if deviceFile in iDevicesFiles:
23 print('skip')
24 continue
25 open(deviceFile)
26 # 3 pos absolute
27 # 2 pos relative
28 # 1 Keys
29 currDevice = evdev.InputDevice(deviceFile)
30 cap = currDevice.capabilities()
31 if mode in ['ALL','NOMICE']:
32 if 1 in cap:
33 if 116 in cap[1] and len(cap[1]) < 5:
34 print('power')
35 continue
36 if mode == 'ALL':
37 iDevices[currDevice.fd] = currDevice
38 print('Device added:' + iDevices[currDevice.fd].name)
39 elif mode == 'NOMICE':
40 if not ((2 in cap) or (3 in cap)):
41 iDevices[currDevice.fd] = currDevice
42 print('Device added:' + iDevices[currDevice.fd].name)
43 elif currDevice.name.upper() in mode.split(','):
44 iDevices[currDevice.fd] = currDevice
45 print('Device added:' + iDevices[currDevice.fd].name)
46 except Exception as e:
47 print("Skip Inputdevice : " + deviceFile +' ' + str(e))
0 #!/bin/python
1
2 import select
3 import time
4
5 currScreen = '2'
6 vcsa = {}
7 for i in range(1,7):
8 vcsa[str(i)] = open('/dev/vcs'+str(i),'rb')
9
10 tty = open('/sys/devices/virtual/tty/tty0/active','r')
11 currScreen = str(tty.read()[3:-1])
12 oldScreen = currScreen
13 watchdog = select.epoll()
14 watchdog.register(vcsa[currScreen], select.EPOLLPRI)
15 watchdog.register(tty, select.EPOLLPRI)
16
17 while True:
18 changes = watchdog.poll()
19 print('-----------------------------')
20 print(changes)
21 for change in changes:
22 fileno = change[0]
23 event = change[1]
24 print(change,fileno, tty.fileno())
25 if fileno == tty.fileno():
26 tty.seek(0)
27 currScreen = str(tty.read()[3:-1])
28 if currScreen != oldScreen:
29 watchdog.unregister(vcsa[ oldScreen ])
30 watchdog.register(vcsa[ currScreen ], select.EPOLLPRI)
31 oldScreen = currScreen
32 print('new screen '+ currScreen)
33 else:
34 vcsa[currScreen].seek(0)
35 content = vcsa[currScreen].read()
36 print('update '+ str(time.time()))
0 #!/bin/bash
1 echo "foreground colors"
2 echo -e "\e[39mDefault"
3 echo -e "\e[30mBlack"
4 echo -e "\e[31mRed"
5 echo -e "\e[32mGreen"
6 echo -e "\e[33mYellow"
7 echo -e "\e[34mBlue"
8 echo -e "\e[35mMagenta"
9 echo -e "\e[36mCyan"
10 echo -e "\e[37mLight gray"
11 echo -e "\e[90mDark gray"
12 echo -e "\e[91mLight red"
13 echo -e "\e[92mLight green"
14 echo -e "\e[93mLight yellow"
15 echo -e "\e[94mLight blue"
16 echo -e "\e[95mLight magenta"
17 echo -e "\e[96mLight cyan"
18 echo -e "\e[97mWhite"
19 #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')
20
21 echo "background colors"
22 echo -e "\e[49mDefault"
23 echo -e "\e[40mBlack"
24 echo -e "\e[41mRed"
25 echo -e "\e[42mGreen"
26 echo -e "\e[43mYellow"
27 echo -e "\e[44mBlue"
28 echo -e "\e[45mMagenta"
29 echo -e "\e[46mCyan"
30 echo -e "\e[47mLight gray"
31 echo -e "\e[100mDark gray"
32 echo -e "\e[101mLight red"
33 echo -e "\e[102mLight green"
34 echo -e "\e[103mLight yellow"
35 echo -e "\e[104mLight blue"
36 echo -e "\e[105mLight magenta"
37 echo -e "\e[106mLight cyan"
38 echo -e "\e[107mWhite"
39
40 echo "format"
41 echo -e "\e[1mBold"
42 echo -e "\e[2mDim"
43 echo -e "\e[4mUnderlined"
44 echo -e "\e[5mBlink"
45 echo -e "\e[7minverted"
46 echo -e "\e[8mHidden"
47
0 #!/bin/python
1 import evdev
2 from evdev import InputDevice, UInput
3 from select import select
4 import time
5
6 iDevices = map(evdev.InputDevice, (evdev.list_devices()))
7 iDevices = {dev.fd: dev for dev in iDevices}
8 print('----------------------')
9 for fd in iDevices:
10 dev = iDevices[fd]
11 cap = dev.capabilities()
12 print('Name: ' + str(dev.name))
13 print('LEDs: ' + str(dev.leds()))
14 print('Has Keys: '+ str(evdev.events.EV_KEY in cap))
15 if evdev.events.EV_KEY in cap:
16 print('No. of keys: ' + str(len(cap[evdev.events.EV_KEY])))
17 print('has Key 116: ' + str(116 in cap[evdev.events.EV_KEY]))
18 print('Is Mouse: ' + str(((evdev.events.EV_REL in cap) or (evdev.events.EV_ABS in cap))))
19 print('----------------------')
20
0 #!/usr/bin/env python3
1 # -*- coding: utf-8 -*-
2
3 # HTTP + URL packages
4 import httplib2
5 from urllib.parse import urlencode, quote # For URL creation
6 import time
7 # To play wave files
8 import pygame
9 import math # For ceiling
10
11
12 # Mary server informations
13 mary_host = "127.0.0.1"
14 mary_port = "59125"
15
16 # Input text
17 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"
18 # Build the query
19 query_hash = {"INPUT_TEXT":input_text,
20 "INPUT_TYPE":"TEXT", # Input text
21 "LOCALE":"de",
22 "VOICE":"bits3", # Voice informations (need to be compatible)
23 "OUTPUT_TYPE":"AUDIO",
24 "AUDIO":"WAVE", # Audio informations (need both)
25 }
26 starttime = time.time()
27 query = urlencode(query_hash)
28 #print("query = \"http://%s:%s/process?%s\"" % (mary_host, mary_port, query))
29
30 # Run the query to mary http server
31 h_mary = httplib2.Http()
32 #print("http://%s:%s/process?" % (mary_host, mary_port), "POST", query)
33 resp, content = h_mary.request("http://%s:%s/process?" % (mary_host, mary_port), "POST", query)
34
35 # Decode the wav file or raise an exception if no wav files
36 if (resp["content-type"] == "audio/x-wav"):
37 # Write the wav file
38 f = open("/tmp/output_wav.wav", "wb")
39 f.write(content)
40 f.close()
41 # Play the wav file
42 pygame.mixer.init(frequency=16000) # Initialise the mixer
43 #s = pygame.mixer.Sound(content)
44 s = pygame.mixer.Sound("/tmp/output_wav.wav")
45 print(str(time.time() -starttime))
46 s.play()
47 print(str(time.time() -starttime))
48 pygame.time.wait(int(math.ceil(s.get_length() * 1000)))
49
50 else:
51 raise Exception(content)
0 #!/bin/python
1 import os
2 import time
3 start = time.time()
4 pids = [pid for pid in os.listdir('/proc') if pid.isdigit()]
5 #pids = ['5960']
6
7 tty = os.open('/dev/tty2', os.O_RDWR)
8 fg = str(os.tcgetpgrp(tty))
9 tty.close()
10 print(fg)
11 for pid in pids:
12 try:
13 currStat = str(open('/proc/' + pid + '/stat', 'rb').read())
14 currStat = currStat.split(' ')
15 if int(currStat[4]) == 0:
16 continue
17 #print(currStat)
18 #print(fg,int(currStat[4]))
19 if fg == currStat[4]:
20 print(currStat[1])
21 #print( currStat )
22 #print(currStat[0])
23 major = os.major(int(currStat[6]))
24 minor = os.minor(int(currStat[6]))
25 ueventContent = open('/sys/dev/char/' + str(major) + ':' + str(minor) + '/uevent','r').read().split()
26 #print(ueventContent)
27 #print(int(currStat[4]),currStat[1])
28 except IOError: # proc has already terminated
29 continue
30
31 print(time.time()-start)
32
33
34 '''
35 Table 1-4: Contents of the stat files (as of 2.6.30-rc7)
36 ..............................................................................
37 Field Content
38 pid process id
39 tcomm filename of the executable
40 state state (R is running, S is sleeping, D is sleeping in an
41 uninterruptible wait, Z is zombie, T is traced or stopped)
42 ppid process id of the parent process
43 pgrp pgrp of the process
44 sid session id
45 tty_nr tty the process uses
46 tty_pgrp pgrp of the tty
47 flags task flags
48 min_flt number of minor faults
49 cmin_flt number of minor faults with child's
50 maj_flt number of major faults
51 cmaj_flt number of major faults with child's
52 '''
0 #!/bin/python3
1 import sys, os
2 import pty
3 import pyte
4
5 class FenrirTermStream(pyte.Stream):
6 def __init__(self):
7 super().__init__()
8 def attach(self, screen):
9 super().attach(screen)
10 def feed(self, text):
11 super().feed(text)
12
13 class FenrirTermEmu():
14 def __init__(self):
15 self.shell = '/bin/bash'
16 if 'SHELL' in os.environ:
17 self.shell = os.environ['SHELL']
18 self.screen = pyte.Screen(80,24)
19 self.stream = FenrirTermStream()
20 self.stream.attach(self.screen)
21 def outputCallback(self, fd):
22 data = os.read(fd, 1024)
23 self.stream.feed(data.decode('UTF8'))
24 # alles
25 #print(self.screen.display)
26 # input
27 #print(data.decode('UTF8'))
28 return data
29 def inputCallback(self, fd):
30 data = os.read(fd, 1024)
31 print('|'+str(data)+'|')
32 if data == b'q':
33 print('quit')
34 return b'exit\r'
35 return data
36 def startEmulator(self):
37 pty.spawn(self.shell, self.outputCallback, self.inputCallback)
38
39 t = FenrirTermEmu()
40 t.startEmulator()
0 #!/bin/python3
1 import sys, os
2 import pty
3 import pyte
4
5 class FenrirTermStream(pyte.Stream):
6 def __init__(self):
7 super().__init__()
8 def attach(self, screen):
9 super().attach(screen)
10 def feed(self, text):
11 super().feed(text)
12
13 class FenrirTermEmu():
14 def __init__(self):
15 self.shell = '/bin/bash'
16 if 'SHELL' in os.environ:
17 self.shell = os.environ['SHELL']
18 self.screen = pyte.Screen(80,24)
19 self.stream = FenrirTermStream()
20 self.stream.attach(self.screen)
21 def outputCallback(self, fd):
22 data = os.read(fd, 1024)
23 self.stream.feed(data.decode('UTF8'))
24 # alles
25 print(self.screen.display)
26 # input
27 print(data.decode('UTF8'))
28 return data
29 def inputCallback(self, fd):
30 data = os.read(fd, 1024)
31 return data
32 def startEmulator(self):
33 pty.spawn(self.shell, self.outputCallback, self.inputCallback)
0 import os
1 import struct
2 import sys
3 import pty
4 import tty
5 import termios
6 import shlex
7 import signal
8 import select
9 import pyte
10 import time
11
12 class Terminal:
13 def __init__(self, columns, lines, p_in):
14 self.screen = pyte.HistoryScreen(columns, lines)
15 self.screen.set_mode(pyte.modes.LNM)
16 self.screen.write_process_input = \
17 lambda data: p_in.write(data.encode())
18 self.stream = pyte.ByteStream()
19 self.stream.attach(self.screen)
20 def feed(self, data):
21 self.stream.feed(data)
22 def dump(self):
23 cursor = self.screen.cursor
24 lines = []
25 for y in self.screen.dirty:
26 line = self.screen.buffer[y]
27 data = [(char.data, char.reverse, char.fg, char.bg)
28 for char in (line[x] for x in range(self.screen.columns))]
29 lines.append((y, data))
30 self.screen.dirty.clear()
31 return {"c": (cursor.x, cursor.y), "lines": lines}
32
33
34 def open_terminal(command="bash", columns=80, lines=24):
35 p_pid, master_fd = pty.fork()
36 if p_pid == 0: # Child.
37 argv = shlex.split(command)
38 env = os.environ.copy()
39 env["TERM"] = 'vt100'
40 os.execvpe(argv[0], argv, env)
41 # File-like object for I/O with the child process aka command.
42 p_out = os.fdopen(master_fd, "w+b", 0)
43 return Terminal(columns, lines, p_out), p_pid, p_out
44
45 def HandleTerminal():
46 debug = False
47 running = True
48 try:
49 old_attr = termios.tcgetattr(sys.stdin)
50 tty.setraw(0)
51 terminal, p_pid, p_out = open_terminal()
52 std_out = os.fdopen(sys.stdout.fileno(), "w+b", 0)
53 while running:
54 r, w, x = select.select([sys.stdin, p_out],[],[])
55 if r == []:
56 continue
57 if p_out in r:
58 if debug:
59 print('pre p_out')
60 try:
61 msgBytes = read_all(p_out.fileno())
62 except (EOFError, OSError):
63 running = False
64 break
65 terminal.feed(msgBytes)
66 os.write(sys.stdout.fileno(), msgBytes)
67 if debug:
68 print('after p_out')
69 if sys.stdin in r:
70 if debug:
71 print('pre stdin')
72 try:
73 msgBytes = read_all(sys.stdin.fileno())
74 except (EOFError, OSError):
75 running = False
76 break
77 terminal.feed(msgBytes)
78 os.write(p_out.fileno(), msgBytes)
79 if debug:
80 print('after stdin')
81 except Exception as e: # Process died?
82 print(e)
83 running = False
84 finally:
85 os.kill(p_pid, signal.SIGTERM)
86 p_out.close()
87 termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_attr)
88 sys.exit(0)
89
90 def get_terminal_size(fd):
91 s = struct.pack('HHHH', 0, 0, 0, 0)
92 rows, cols, _, _ = struct.unpack('HHHH', fcntl.ioctl(fd, termios.TIOCGWINSZ, s))
93 return rows, cols
94
95 def resize_terminal(fd):
96 s = struct.pack('HHHH', 0, 0, 0, 0)
97 s = fcntl.ioctl(0, termios.TIOCGWINSZ, s)
98 fcntl.ioctl(fd, termios.TIOCSWINSZ, s)
99 rows, cols, _, _ = struct.unpack('hhhh', s)
100 return rows, cols
101
102 def read_all(fd):
103 bytes = os.read(fd, 65536)
104 if bytes == b'':
105 raise EOFError
106 while has_more(fd):
107 data = os.read(fd, 65536)
108 if data == b'':
109 raise EOFError
110 bytes += data
111 return bytes
112
113 def has_more(fd):
114 r, w, e = select.select([fd], [], [], 0)
115 return (fd in r)
116
117 if __name__ == "__main__":
118 HandleTerminal()
0 #!/bin/python
1 #https://python-packaging.readthedocs.io/en/latest/minimal.html
2 import os, glob, sys
3 import os.path
4 from shutil import copyfile
5 from setuptools import find_packages
6 from setuptools import setup
7
8 fenrirVersion = '1.5'
9 packageVersion = 'post10'
10
11 # handle flags for package manager like yaourt and pacaur.
12 forceSettings = False
13 if "--force-settings" in sys.argv:
14 forceSettings = True
15 sys.argv.remove("--force-settings")
16
17 data_files = []
18 directories = glob.glob('config/*')
19 for directory in directories:
20 files = glob.glob(directory+'/*')
21 destDir = ''
22 if 'config/punctuation' in directory :
23 destDir = '/etc/fenrir/punctuation'
24 elif 'config/keyboard' in directory:
25 destDir = '/etc/fenrir/keyboard'
26 elif 'config/settings' in directory:
27 destDir = '/etc/fenrir/settings'
28 if not forceSettings:
29 try:
30 del(files[files.index('config/settings/settings.conf')])
31 except:
32 pass
33 elif 'config/scripts' in directory:
34 destDir = '/usr/share/fenrir/scripts'
35 if destDir != '':
36 data_files.append((destDir, files))
37
38 files = glob.glob('config/sound/default-wav/*')
39 destDir = '/usr/share/sounds/fenrir/default-wav'
40 data_files.append((destDir, files))
41 files = glob.glob('config/sound/default/*')
42 destDir = '/usr/share/sounds/fenrir/default'
43 data_files.append((destDir, files))
44 files = glob.glob('config/sound//template/*')
45 destDir = '/usr/share/sounds/fenrir/template'
46 data_files.append((destDir, files))
47 files = glob.glob('tools/*')
48 data_files.append(('/usr/share/fenrir/tools', files))
49 data_files.append(('/usr/lib/systemd/system', ['autostart/systemd/fenrir.service']))
50 data_files.append(('/usr/share/man/man1', ['docu/fenrir.1']))
51
52 def read(fname):
53 return open(os.path.join(os.path.dirname(__file__), fname)).read()
54
55 setup(
56 # Application name:
57 name="fenrir-screenreader",
58 # Version number:
59 version=fenrirVersion + '.' + packageVersion,
60 # description
61 description="A TTY Screen Reader for Linux.",
62 long_description=read('README.md'),
63 keywords=['screenreader', 'a11y', 'accessibility', 'terminal', 'TTY', 'console'],
64 license="License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
65 url="https://github.com/chrys87/fenrir/",
66 download_url = 'https://github.com/chrys87/fenrir/archive/' + fenrirVersion + '.tar.gz',
67 classifiers=[
68 "Programming Language :: Python",
69 "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
70 "Development Status :: 5 - Production/Stable",
71 "Topic :: Multimedia :: Sound/Audio :: Speech",
72 "Environment :: Console",
73 ],
74
75 # Application author details:
76 author="Chrys, Storm_dragon, Jeremiah and others",
77 author_email="chrysg@linux-a11y.org",
78
79 # Packages
80 packages=find_packages('src/fenrir'),
81 package_dir={'': 'src/fenrir'},
82 scripts=['src/fenrir/fenrir','src/fenrir/fenrir-daemon'],
83
84 # Include additional files into the package
85 include_package_data=True,
86 zip_safe=False,
87
88 data_files=data_files,
89
90 # Dependent packages (distributions)
91 install_requires=[
92 "evdev",
93 "daemonize",
94 "dbus-python",
95 "pyenchant",
96 "pyudev",
97 "setuptools",
98 "pexpect",
99 ],
100
101 )
102
103 if not forceSettings:
104 print('')
105 # create settings file from example if not exist
106 if not os.path.isfile('/etc/fenrir/settings/settings.conf'):
107 try:
108 copyfile('/etc/fenrir/settings/settings.conf.example', '/etc/fenrir/settings/settings.conf')
109 print('create settings file in /etc/fenrir/settings/settings.conf')
110 except:
111 pass
112 else:
113 print('settings.conf file found. It is not overwritten automatical')
114
115 print('')
116 print('To have Fenrir start at boot:')
117 print('sudo systemctl enable fenrir')
118 print('Pulseaudio users may want to run:')
119 print('/usr/share/fenrir/tools/configure_pulse.sh')
120 print('once as their user account and once as root to configure Pulseaudio.')
121 print('Please install the following packages manually:')
122 print('- Speech-dispatcher: for the default speech driver')
123 print('- Espeak: as basic TTS engine')
124 print('- BrlTTY: for Braille')
125 print('- sox: is a player for the generic sound driver')
+0
-63
src/fenrir/brailleDriver/brlapi.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class driver():
9 def __init__(self):
10 self._isInitialized = False
11 self._brl = None
12
13 def initialize(self, environment):
14 self.env = environment
15 try:
16 import brlapi
17 except Exception as e:
18 print(e)
19 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
20 return
21
22 try:
23 self._brl = brlapi.Connection()
24 except Exception as e:
25 print(e)
26 self.env['runtime']['debug'].writeDebugOut('BRAILLE.connectDevice '+str(e),debug.debugLevel.ERROR)
27 return
28 self._isInitialized = True
29
30 def flush(self):
31 if not self._isInitialized:
32 return
33 try:
34 self._brl.writeText('',0)
35 except Exception as e:
36 self.env['runtime']['debug'].writeDebugOut('BRAILLE.flush '+str(e),debug.debugLevel.ERROR)
37
38 def writeText(self,text):
39 if not self._isInitialized:
40 return
41 try:
42 self._brl.writeText(text)
43 except Exception as e:
44 self.env['runtime']['debug'].writeDebugOut('BRAILLE.writeText '+str(e),debug.debugLevel.ERROR)
45
46 def connectDevice(self):
47 self._brl = brlapi.Connection()
48
49 def enterScreen(self, screen):
50 if not self._isInitialized:
51 return
52 self._brl.enterTtyMode(int(screen))
53
54 def leveScreen(self):
55 if not self._isInitialized:
56 return
57 self._brl.leaveTtyMode()
58
59 def shutdown(self):
60 if not self._isInitialized:
61 return
62 self.leveScreen()
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class driver():
9 def __init__(self):
10 self._isInitialized = False
11 self._brl = None
12
13 def initialize(self, environment):
14 self.env = environment
15 try:
16 import brlapi
17 self._brl = brlapi.Connection()
18 self._deviceSize = self._brl.displaySize
19 except Exception as e:
20 print(e)
21 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
22 return
23 self._isInitialized = True
24
25 def getDeviceSize(self):
26 if not self._isInitialized:
27 return (0,0)
28 if not self._deviceSize:
29 return (0,0)
30 return self._deviceSize
31
32 def flush(self):
33 if not self._isInitialized:
34 return
35 try:
36 self._brl.writeText('',0)
37 except Exception as e:
38 self.env['runtime']['debug'].writeDebugOut('BRAILLE.flush '+str(e),debug.debugLevel.ERROR)
39
40 def writeText(self,text):
41 if not self._isInitialized:
42 return
43 try:
44 self._brl.writeText(text)
45 except Exception as e:
46 self.env['runtime']['debug'].writeDebugOut('BRAILLE.writeText '+str(e),debug.debugLevel.ERROR)
47
48 def connectDevice(self):
49 self._brl = brlapi.Connection()
50
51 def enterScreen(self, screen):
52 if not self._isInitialized:
53 return
54 self._brl.enterTtyMode(int(screen))
55
56 def leveScreen(self):
57 if not self._isInitialized:
58 return
59 self._brl.leaveTtyMode()
60
61 def shutdown(self):
62 if not self._isInitialized:
63 return
64 self.leveScreen()
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class driver():
9 def __init__(self):
10 self.printMessages = False
11
12 def initialize(self, environment):
13 self.env = environment
14 self._isInitialized = True
15 self.deviceSize = (40,0)
16 if self.printMessages:
17 print('BrailleDummyDriver: Initialize')
18
19
20 def getDeviceSize(self):
21 if not self._isInitialized:
22 return (0,0)
23 if self.printMessages:
24 print('BrailleDummyDriver: getDeviceSize ' + str(self.deviceSize))
25 return self.deviceSize
26
27 def writeText(self,text):
28 if not self._isInitialized:
29 return
30 if self.printMessages:
31 print('BrailleDummyDriver: writeText:' + str(text))
32 print('BrailleDummyDriver: -----------------------------------')
33
34 def connectDevice(self):
35 if self.printMessages:
36 print('BrailleDummyDriver: connectDevice')
37
38 def enterScreen(self, screen):
39 if not self._isInitialized:
40 return
41 if self.printMessages:
42 print('BrailleDummyDriver: enterScreen')
43
44 def leveScreen(self):
45 if not self._isInitialized:
46 return
47 if self.printMessages:
48 print('BrailleDummyDriver: leveScreen')
49
50 def shutdown(self):
51 if not self._isInitialized:
52 return
53 if self.printMessages:
54 print('BrailleDummyDriver: Shutdown')
2323 def shutdown(self):
2424 pass
2525 def getDescription(self):
26 return 'adds the current word to the exceptions dictionary'
26 return _('adds the current word to the exceptions dictionary')
2727 def updateSpellLanguage(self):
2828 self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
2929 self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')
3030
3131 def run(self):
3232 if not initialized:
33 self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True)
33 self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True)
3434 return
3535 if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
3636 try:
3939 return
4040 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
4141 # get the word
42 newContent = self.env['screenData']['newContentText'].split('\n')[cursorPos['y']]
42 newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
4343 x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent)
4444 currWord = currWord.strip(string.whitespace + '!"#$%&\()*+,-./:;<=§>?@[\\]^_{|}~')
4545
4646 if currWord != '':
4747 if self.spellChecker.is_added(currWord):
48 self.env['runtime']['outputManager'].presentText(currWord + ' is already in dict',soundIcon='Cancel', interrupt=True)
48 self.env['runtime']['outputManager'].presentText(_('{0} is already in dict').format(currWord,), soundIcon='Cancel', interrupt=True)
4949 else:
5050 self.spellChecker.add(currWord)
51 self.env['runtime']['outputManager'].presentText(currWord + ' added',soundIcon='Accept', interrupt=True)
51 self.env['runtime']['outputManager'].presentText(_('{0} added').format(currWord,), soundIcon='Accept', interrupt=True)
5252
5353 def setCallback(self, callback):
5454 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import screen_utils
8
9 class command():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self.env = environment
14 def shutdown(self):
15 pass
16 def getDescription(self):
17 return 'No description found'
18 def run(self):
19 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
20 attributes = screen_utils.splitEvery(self.env['screen']['newContentAttrib'], self.env['screen']['columns'])
21 attributes = attributes[cursorPos['y']][cursorPos['x']]
22 attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString')
23 attributeFormatString = self.env['runtime']['screenManager'].formatAttributes(attributes, attributeFormatString)
24 self.env['runtime']['outputManager'].presentText(attributeFormatString, soundIcon='', interrupt=True)
25 def setCallback(self, callback):
26 pass
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'read Bookmark ' + self.ID
18 return _('read Bookmark {0}').format(self.ID,)
1919
2020 def run(self):
2121 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2222 if not self.env['commandBuffer']['bookMarks'][self.ID]:
23 self.env['runtime']['outputManager'].presentText("Bookmark " + self.ID + "not set", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} not set').format(self.ID,), interrupt=True)
2424 return
2525 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]:
26 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
2727 return
2828 if not self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1']:
29 self.env['runtime']['outputManager'].presentText("Bookmark for application " + currApp + " not set", interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_('Bookmark for application {0} not set').format(currApp,), interrupt=True)
3030 return
3131
3232 # set marks
3434 startMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['1'].copy()
3535 if self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2']:
3636 endMark = self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'].copy()
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
37 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3838 else:
3939 x, y, marked = \
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screenData']['newContentText'])
40 line_utils.getCurrentLine(startMark['x'], startMark['y'], self.env['screen']['newContentText'])
4141 if marked.isspace():
42 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
42 self.env['runtime']['outputManager'].presentText(_('blank'), soundIcon='EmptyLine', interrupt=True)
4343 else:
4444 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
4545
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('flush the braille device if a message is written on')
17 def run(self):
18 self.env['runtime']['outputManager'].clearFlushTime()
19 def setCallback(self, callback):
20 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('Move braille view to the left.')
17 def run(self):
18 panned = self.env['runtime']['outputManager'].setPanLeft()
19 def setCallback(self, callback):
20 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('Move braille view to the right.')
17 def run(self):
18 panned = self.env['runtime']['outputManager'].setPanRight()
19 def setCallback(self, callback):
20 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('Set the braille view back to cursor.')
17 def run(self):
18 self.env['runtime']['outputManager'].removePanning()
19 def setCallback(self, callback):
20 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2020
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'remove Bookmark ' + self.ID
16 return _('remove Bookmark {0}').format(self.ID,)
1717
1818 def run(self):
1919 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
20
20
2121 del self.env['commandBuffer']['bookMarks'][self.ID][currApp]
2222
23 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " removed for application " + currApp, interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} removed for application {1}').format(self.ID, currApp), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'clears the currently selected clipboard'
16 return _('clears the currently selected clipboard')
1717
1818 def run(self):
1919 self.env['commandBuffer']['currClipboard'] = -1
2020 del self.env['commandBuffer']['clipboard'][:]
21 self.env['runtime']['outputManager'].presentText('clipboard cleared', interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_('clipboard cleared'), interrupt=True)
2222 return
2323 def setCallback(self, callback):
2424 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'Turn off window mode for application'
16 return _('Turn off window mode for application')
1717
1818 def run(self):
1919 if self.env['runtime']['cursorManager'].clearWindowForApplication():
2020 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
21 self.env['runtime']['outputManager'].presentText('Window Mode off for application ' + currApp, interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_('Window Mode off for application {0}').format(currApp,), interrupt=True)
2222 else:
23 self.env['runtime']['outputManager'].presentText("Not in window Mode", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_("Not in window Mode"), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'copies marked text to the currently selected clipboard'
17 return _('copies marked text to the currently selected clipboard')
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("one or two marks needed", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("one or two marks needed"), interrupt=True)
2222 return
2323 if not self.env['commandBuffer']['Marks']['2']:
2424 self.env['runtime']['cursorManager'].setMark()
2727 startMark = self.env['commandBuffer']['Marks']['1'].copy()
2828 endMark = self.env['commandBuffer']['Marks']['2'].copy()
2929
30 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
30 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3131
3232 self.env['commandBuffer']['clipboard'] = [marked] + self.env['commandBuffer']['clipboard'][:self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards') -1]
3333 self.env['commandBuffer']['currClipboard'] = 0
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'speaks the contents of the currently selected clipboard'
16 return _('speaks the contents of the currently selected clipboard')
1717
1818 def run(self):
1919 if len(self.env['commandBuffer']['clipboard']) == 0:
20 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2121 return
2222 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True)
2323
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'reads the contents of the current screen'
16 return _('reads the contents of the current screen')
1717
1818 def run(self):
19 if self.env['screenData']['newContentText'].isspace():
20 self.env['runtime']['outputManager'].presentText("screen is empty", soundIcon='EmptyLine', interrupt=True)
19 if self.env['screen']['newContentText'].isspace():
20 self.env['runtime']['outputManager'].presentText(_("screen is empty"), soundIcon='EmptyLine', interrupt=True)
2121 else:
22 self.env['runtime']['outputManager'].presentText(self.env['screenData']['newContentText'],interrupt=True)
22 self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'],interrupt=True)
2323
2424 def setCallback(self, callback):
2525 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'reads from the cursor to the bottom of the screen'
17 return _('reads from the cursor to the bottom of the screen')
1818
1919 def run(self):
2020 # Prefer review cursor over text cursor
2121 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
2222
23 textAfterCursor = mark_utils.getTextAfterMark(cursorPos, self.env['screenData']['newContentText'])
23 textAfterCursor = mark_utils.getTextAfterMark(cursorPos, self.env['screen']['newContentText'])
2424
2525 if textAfterCursor.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
2727 else:
2828 self.env['runtime']['outputManager'].presentText(textAfterCursor, interrupt=True)
2929
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'Reads from the top of the screen to the cursor position'
17 return _('Reads from the top of the screen to the cursor position')
1818
1919 def run(self):
2020 # Prefer review cursor over text cursor
21 if self.env['screenData']['newCursorReview']:
22 cursorPos = self.env['screenData']['newCursorReview'].copy()
21 if self.env['screen']['newCursorReview']:
22 cursorPos = self.env['screen']['newCursorReview'].copy()
2323 else:
24 cursorPos = self.env['screenData']['newCursor'].copy()
24 cursorPos = self.env['screen']['newCursor'].copy()
2525
26 textBeforeCursor = mark_utils.getTextBeforeMark(cursorPos, self.env['screenData']['newContentText'])
26 textBeforeCursor = mark_utils.getTextBeforeMark(cursorPos, self.env['screen']['newContentText'])
2727
2828 if textBeforeCursor.isspace():
29 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
29 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
3030 else:
3131 self.env['runtime']['outputManager'].presentText(textBeforeCursor, interrupt=True)
3232
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1'
16 return _('presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1')
1717 def run(self):
1818 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
1919 self.env['runtime']['outputManager'].presentText(str(cursorPos['x'] + 1) , interrupt=True)
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1'
16 return _('presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1')
1717 def run(self):
1818 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
1919 self.env['runtime']['outputManager'].presentText(str(cursorPos['y'] + 1), interrupt=True)
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'displays the position of the review cursor'
16 return _('displays the position of the review cursor')
1717
1818 def run(self):
1919 # Prefer review cursor over text cursor
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
2121
22 self.env['runtime']['outputManager'].presentText("line "+ str(cursorPos['y']+1) + " column "+ str(cursorPos['x']+1), interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_("line {0}, column {1}").format(cursorPos['y']+1, cursorPos['x']+1), interrupt=True)
2323
2424 def setCallback(self, callback):
2525 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'read to end of line, use review cursor if you are in reviewmode, otherwhise use text cursor'
17 return _('read to end of line, use review cursor if you are in review mode, otherwhise use text cursor')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
2121
2222 x, y, currLine = \
23 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screenData']['newContentText'])
23 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText'])
2424
2525 if currLine.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
2727 else:
2828 self.env['runtime']['outputManager'].presentText(currLine[cursorPos['x']], interrupt=True)
2929 self.env['runtime']['outputManager'].announceActiveCursor()
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'presents the date'
17 return _('presents the date')
1818
1919 def run(self):
2020 dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 initialized = False
7 try:
8 import alsaaudio
9 initialized = True
10 except:
11 pass
12
13 from core import debug
14
15 class command():
16 def __init__(self):
17 pass
18 def initialize(self, environment):
19 self.env = environment
20 def shutdown(self):
21 pass
22 def getDescription(self):
23 return _("Decrease system volume")
24
25 def run(self):
26 if not initialized:
27 self.env['runtime']['outputManager'].presentText(_('alsaaudio is not installed'), interrupt=True)
28 return
29 mixer = alsaaudio.Mixer()
30 value = mixer.getvolume()[0]
31 value = value - 5
32 if value < 5:
33 value = 5
34 mixer.setvolume(value)
35 self.env['runtime']['outputManager'].presentText(_("{0} percent system volume").format(value), interrupt=True)
36
37 def setCallback(self, callback):
38 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'decrease sound volume'
17 return _('decrease sound volume')
1818
1919 def run(self):
2020
2525 value = 0.1
2626 self.env['runtime']['settingsManager'].setSetting('sound', 'volume', str(value))
2727
28 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent sound volume", soundIcon='SoundOff', interrupt=True)
28 self.env['runtime']['outputManager'].presentText(_("{0} percent sound volume").format(int(value * 100)), soundIcon='SoundOff', interrupt=True)
2929
3030 def setCallback(self, callback):
3131 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'decreases the pitch of the speech'
17 return _('decreases the pitch of the speech')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch')
2222 if value < 0.0:
2323 value = 0.0
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'pitch', str(value))
25
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech pitch", soundIcon='', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('{0} percent speech pitch').format(int(value * 100)), soundIcon='', interrupt=True)
2726
2827 def setCallback(self, callback):
2928 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'decreases the rate of the speech'
17 return _('decreases the rate of the speech')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate')
2323 value = 0.0
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'rate', str(value))
2525
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech rate", soundIcon='', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("{0} percent speech rate").format(int(value * 100)), soundIcon='', interrupt=True)
2727
2828 def setCallback(self, callback):
2929 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'decreases the volume of the speech'
17 return _('decreases the volume of the speech')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume')
2323 value = 0.1
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'volume', str(value))
2525
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech volume", soundIcon='', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("{0} percent speech volume").format(int(value * 100)), soundIcon='', interrupt=True)
2727
2828 def setCallback(self, callback):
2929 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'exits review mode'
16 return _('exits review mode')
1717
1818 def run(self):
1919 if not self.env['runtime']['cursorManager'].isReviewMode():
20 self.env['runtime']['outputManager'].presentText("Not in review mode", interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_("Not in review mode"), interrupt=True)
2121 return
2222
2323 self.env['runtime']['cursorManager'].clearReviewCursor()
24 self.env['runtime']['outputManager'].presentText("leve review mode", interrupt=True)
24 self.env['runtime']['outputManager'].presentText(_("leave review mode"), interrupt=True)
2525
2626 def setCallback(self, callback):
2727 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import os
8
9 class command():
10 def __init__(self):
11 pass
12 def initialize(self, environment, scriptPath=''):
13 self.env = environment
14
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return _('export the current fenrir clipboard to a file')
19 def run(self):
20 clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath')
21 clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser'])
22 clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser'])
23 clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser'])
24 clipboardFile = open(clipboardFilePath,'w')
25 try:
26 currClipboard = self.env['commandBuffer']['currClipboard']
27 if currClipboard < 0:
28 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
29 return
30 if not self.env['commandBuffer']['clipboard']:
31 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
32 return
33 if not self.env['commandBuffer']['clipboard'][currClipboard]:
34 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
35 return
36 if self.env['commandBuffer']['clipboard'][currClipboard] == '':
37 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
38 return
39 clipboardFile.write(self.env['commandBuffer']['clipboard'][currClipboard])
40 clipboardFile.close()
41 os.chmod(clipboardFilePath, 0o666)
42 self.env['runtime']['outputManager'].presentText(_('clipboard exported to file'), interrupt=True)
43 except Exception as e:
44 self.env['runtime']['debug'].writeDebugOut('export_clipboard_to_file:run: Filepath:'+ clipboardFile +' trace:' + str(e),debug.debugLevel.ERROR)
45
46 def setCallback(self, callback):
47 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import subprocess, os
8 from subprocess import Popen, PIPE
9 import _thread
10
11 class command():
12 def __init__(self):
13 pass
14 def initialize(self, environment, scriptPath=''):
15 self.env = environment
16 self.scriptPath = scriptPath
17 def shutdown(self):
18 pass
19 def getDescription(self):
20 return _('export the current fenrir clipboard to X clipboard')
21 def run(self):
22 _thread.start_new_thread(self._threadRun , ())
23
24 def _threadRun(self):
25 try:
26 currClipboard = self.env['commandBuffer']['currClipboard']
27
28 if currClipboard < 0:
29 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
30 return
31 if not self.env['commandBuffer']['clipboard']:
32 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
33 return
34 if not self.env['commandBuffer']['clipboard'][currClipboard]:
35 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
36 return
37 if self.env['commandBuffer']['clipboard'][currClipboard] == '':
38 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
39 return
40 for display in range(10):
41 p = Popen('su ' + self.env['general']['currUser'] + ' -c "echo -n \\\"' + self.env['commandBuffer']['clipboard'][currClipboard].replace('"','\\\\\\"') +'\\\" | xclip -d :' + str(display) + ' -selection c"' , stdout=PIPE, stderr=PIPE, shell=True)
42 stdout, stderr = p.communicate()
43 self.env['runtime']['outputManager'].interruptOutput()
44 #screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
45 stderr = stderr.decode('utf-8')
46 stdout = stdout.decode('utf-8')
47 if (stderr == ''):
48 break
49 #stderr = stderr.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
50 #stdout = stdout.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
51 if stderr != '':
52 self.env['runtime']['outputManager'].presentText(stderr , soundIcon='', interrupt=False)
53 else:
54 self.env['runtime']['outputManager'].presentText('exported to the X session.', interrupt=True)
55 except Exception as e:
56 self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False)
57
58 def setCallback(self, callback):
59 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'selects the first clipboard'
16 return _('selects the first clipboard')
1717
1818 def run(self):
1919 if len(self.env['commandBuffer']['clipboard']) == 0:
20 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2121 return
2222 self.env['commandBuffer']['currClipboard'] = 0
2323 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True)
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'sends the following keypress to the terminal'
16 return _('sends the following keypress to the terminal')
1717
1818 def run(self):
1919 self.env['input']['keyForeward'] = 3
20 self.env['runtime']['outputManager'].presentText('Foreward next keypress', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('Forward next keypress'), interrupt=True)
2121
2222 def setCallback(self, callback):
2323 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import mark_utils
8 import os
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return _('imports text from clipboard file to the clipboard')
19
20 def run(self):
21 clipboardFilePath = self.env['runtime']['settingsManager'].getSetting('general', 'clipboardExportPath')
22 clipboardFilePath = clipboardFilePath.replace('$user',self.env['general']['currUser'])
23 clipboardFilePath = clipboardFilePath.replace('$USER',self.env['general']['currUser'])
24 clipboardFilePath = clipboardFilePath.replace('$User',self.env['general']['currUser'])
25 if not os.path.exists(clipboardFilePath):
26 self.env['runtime']['outputManager'].presentText(_('File does not exist'), soundIcon='', interrupt=True)
27 return
28 clipboardFile = open(clipboardFilePath,'r')
29 imported = clipboardFile.read()
30 clipboardFile.close()
31 self.env['commandBuffer']['clipboard'] = [imported] + self.env['commandBuffer']['clipboard'][:self.env['runtime']['settingsManager'].getSettingAsInt('general', 'numberOfClipboards') -1]
32 self.env['commandBuffer']['currClipboard'] = 0
33
34 self.env['runtime']['outputManager'].presentText('Import to Clipboard', soundIcon='CopyToClipboard', interrupt=True)
35 self.env['runtime']['outputManager'].presentText(imported, soundIcon='', interrupt=False)
36
37
38 def setCallback(self, callback):
39 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 initialized = False
7 try:
8 import alsaaudio
9 initialized = True
10 except:
11 pass
12
13 from core import debug
14
15 class command():
16 def __init__(self):
17 pass
18 def initialize(self, environment):
19 self.env = environment
20 def shutdown(self):
21 pass
22 def getDescription(self):
23 return _("Increase system volume")
24
25 def run(self):
26 if not initialized:
27 self.env['runtime']['outputManager'].presentText(_('alsaaudio is not installed'), interrupt=True)
28 return
29 mixer = alsaaudio.Mixer()
30 value = mixer.getvolume()[0]
31 value = value + 5
32 if value > 100:
33 value = 100
34 mixer.setvolume(value)
35 self.env['runtime']['outputManager'].presentText(_("{0} percent system volume").format(value), interrupt=True)
36
37 def setCallback(self, callback):
38 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'adjusts the volume for in coming sounds'
17 return _('adjusts the volume for in coming sounds')
1818
1919 def run(self):
2020
2525 value = 1.0
2626 self.env['runtime']['settingsManager'].setSetting('sound', 'volume', str(value))
2727
28 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent sound volume", soundIcon='SoundOn', interrupt=True)
28 self.env['runtime']['outputManager'].presentText(_("{0} percent sound volume").format(int(value * 100)), soundIcon='SoundOn', interrupt=True)
2929
3030 def setCallback(self, callback):
3131 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'increases the pitch of the speech'
17 return _('increases the pitch of the speech')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'pitch')
2323 value = 1.0
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'pitch', str(value))
2525
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech pitch", soundIcon='', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("{0} percent speech pitch").format(int(value * 100)), soundIcon='', interrupt=True)
2727
2828 def setCallback(self, callback):
2929 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'increase the speech rate'
17 return _('increase the speech rate')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'rate')
2323 value = 1.0
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'rate', str(value))
2525
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech rate", soundIcon='', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("{0} percent speech rate").format(int(value * 100)), soundIcon='', interrupt=True)
2727
2828 def setCallback(self, callback):
2929 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'increase the speech volume'
17 return _('increase the speech volume')
1818
1919 def run(self):
2020 value = self.env['runtime']['settingsManager'].getSettingAsFloat('speech', 'volume')
2323 value = 1.0
2424 self.env['runtime']['settingsManager'].setSetting('speech', 'volume', str(value))
2525
26 self.env['runtime']['outputManager'].presentText(str(int(value * 100)) + " percent speech volume", soundIcon='', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("{0} percent speech volume").format(int(value * 100)), soundIcon='', interrupt=True)
2727
2828 def setCallback(self, callback):
2929 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'shows the indention level for the current line'
17 return _('shows the indention level for the current line')
1818
1919 def run(self):
2020 # Prefer review cursor over text cursor
2121
22 if self.env['screenData']['newCursorReview']:
23 cursorPos = self.env['screenData']['newCursorReview'].copy()
22 if self.env['screen']['newCursorReview']:
23 cursorPos = self.env['screen']['newCursorReview'].copy()
2424 else:
25 cursorPos = self.env['screenData']['newCursor'].copy()
25 cursorPos = self.env['screen']['newCursor'].copy()
2626 x, y, currLine = \
27 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screenData']['newContentText'])
27 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText'])
2828
2929 if currLine.isspace():
30 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
30 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
3131 else:
32 self.env['runtime']['outputManager'].presentText("indent "+ str(len(currLine) - len(currLine.lstrip())), interrupt=True)
32 self.env['runtime']['outputManager'].presentText(_("indent {0}").format(len(currLine) - len(currLine.lstrip())), interrupt=True)
3333
3434 def setCallback(self, callback):
3535 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'selects the last clipboard'
16 return _('selects the last clipboard')
1717
1818 def run(self):
1919 if len(self.env['commandBuffer']['clipboard']) == 0:
20 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2121 return
2222 self.env['commandBuffer']['currClipboard'] = len(self.env['commandBuffer']['clipboard']) -1
2323 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True)
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'displays the last received text'
16 return _('displays the last received text')
1717
1818 def run(self):
19 self.env['runtime']['outputManager'].presentText(self.env['screenData']['newDelta'], interrupt=True)
19 self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=True)
2020
2121 def setCallback(self, callback):
2222 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'speaks the currently selected text that will be copied to the clipboard'
17 return _('speaks the currently selected text that will be copied to the clipboard')
1818
1919 def run(self):
2020 if not (self.env['commandBuffer']['Marks']['1'] and \
2121 self.env['commandBuffer']['Marks']['2']):
22 self.env['runtime']['outputManager'].presentText("please set begin and endmark", interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_("please set begin and endmark"), interrupt=True)
2323 return
2424
2525 # use the last first and the last setted mark as range
2626 startMark = self.env['commandBuffer']['Marks']['1'].copy()
2727 endMark = self.env['commandBuffer']['Marks']['2'].copy()
2828
29 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screenData']['newContentText'])
29 marked = mark_utils.getTextBetweenMarks(startMark, endMark, self.env['screen']['newContentText'])
3030
3131 if marked.isspace():
32 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
32 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
3333 else:
3434 self.env['runtime']['outputManager'].presentText(marked, interrupt=True)
3535
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'selects the next clipboard'
16 return _('selects the next clipboard')
1717
1818 def run(self):
1919 if len(self.env['commandBuffer']['clipboard']) == 0:
20 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2121 return
2222 self.env['commandBuffer']['currClipboard'] += 1
2323 if self.env['commandBuffer']['currClipboard'] > len(self.env['commandBuffer']['clipboard']) -1:
2424 self.env['commandBuffer']['currClipboard'] = 0
25 self.env['runtime']['outputManager'].presentText('First clipboard ', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('First clipboard '), interrupt=True)
2626 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=False)
2727 else:
2828 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True)
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'pastes the text from the currently selected clipboard'
17 return _('pastes the text from the currently selected clipboard')
1818
1919 def run(self):
2020 currClipboard = self.env['commandBuffer']['currClipboard']
2121 if currClipboard < 0:
22 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2323 return
2424 if not self.env['commandBuffer']['clipboard']:
25 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2626 return
2727 if not self.env['commandBuffer']['clipboard'][currClipboard]:
28 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
28 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2929 return
3030 if self.env['commandBuffer']['clipboard'][currClipboard] == '':
31 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
3232 return
3333 self.env['runtime']['outputManager'].presentText('paste clipboard', soundIcon='PasteClipboardOnScreen', interrupt=True)
3434 time.sleep(0.01)
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'present first line'
17 return _('present first line')
1818
1919 def run(self):
2020 x, y, firstLine = \
21 line_utils.getCurrentLine(0, 0, self.env['screenData']['newContentText'])
21 line_utils.getCurrentLine(0, 0, self.env['screen']['newContentText'])
2222
2323 if firstLine.isspace():
24 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
24 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
2525 else:
2626 self.env['runtime']['outputManager'].presentText(firstLine, interrupt=True)
2727 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'current line'
17 return _('current line')
1818
1919 def run(self):
2020 x, y, lastLine = \
21 line_utils.getCurrentLine(0, self.env['screenData']['lines'] -1, self.env['screenData']['newContentText'])
21 line_utils.getCurrentLine(0, self.env['screen']['lines'] -1, self.env['screen']['newContentText'])
2222
2323 if lastLine.isspace():
24 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
24 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
2525 else:
2626 self.env['runtime']['outputManager'].presentText(lastLine, interrupt=True)
2727 def setCallback(self, callback):
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'selects the previous clipboard'
16 return _('selects the previous clipboard')
1717
1818 def run(self):
1919 if len(self.env['commandBuffer']['clipboard']) == 0:
20 self.env['runtime']['outputManager'].presentText('clipboard empty', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
2121 return
2222 self.env['commandBuffer']['currClipboard'] -= 1
2323 if self.env['commandBuffer']['currClipboard'] < 0:
2424 self.env['commandBuffer']['currClipboard'] = len(self.env['commandBuffer']['clipboard']) -1
25 self.env['runtime']['outputManager'].presentText('Last clipboard ', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('Last clipboard '), interrupt=True)
2626 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=False)
2727 else:
2828 self.env['runtime']['outputManager'].presentText(self.env['commandBuffer']['clipboard'][self.env['commandBuffer']['currClipboard']], interrupt=True)
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'exits Fenrir'
16 return _('exits Fenrir')
1717
1818 def run(self):
19 self.env['generalInformation']['running'] = False
19 self.env['runtime']['eventManager'].stopMainEventLoop()
2020
2121 def setCallback(self, callback):
2222 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'removes marks from selected text'
16 return _('removes marks from selected text')
1717
1818 def run(self):
1919 self.env['runtime']['cursorManager'].clearMarks()
20 self.env['runtime']['outputManager'].presentText('Remove marks', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('Remove marks'), interrupt=True)
2121
2222 def setCallback(self, callback):
2323 pass
2323 def shutdown(self):
2424 pass
2525 def getDescription(self):
26 return 'removes the current word from the exceptions dictionary'
26 return _('removes the current word from the exceptions dictionary')
2727 def updateSpellLanguage(self):
2828 self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
2929 self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')
3030
3131 def run(self):
3232 if not initialized:
33 self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True)
33 self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True)
3434 return
3535 if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
3636 try:
4141 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
4242
4343 # get the word
44 newContent = self.env['screenData']['newContentText'].split('\n')[cursorPos['y']]
44 newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
4545 x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent)
4646 currWord = currWord.strip(string.whitespace + '!"#$%&\()*+,-./:;<=§>?@[\\]^_{|}~')
4747 if not currWord.isspace():
4848 if self.spellChecker.is_removed(currWord):
49 self.env['runtime']['outputManager'].presentText(currWord + ' is already removed from dict',soundIcon='Cancel', interrupt=True)
49 self.env['runtime']['outputManager'].presentText(_('{0} is already removed from dict').format(currWord,), soundIcon='Cancel', interrupt=True)
5050 else:
5151 self.spellChecker.remove(currWord)
52 self.env['runtime']['outputManager'].presentText(currWord + ' removed',soundIcon='Accept', interrupt=True)
52 self.env['runtime']['outputManager'].presentText(_('{0} removed').format(currWord,), soundIcon='Accept', interrupt=True)
5353 def setCallback(self, callback):
5454 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'move review to bottom of screen'
16 return _('move review to bottom of screen')
1717
1818 def run(self):
19 self.env['screenData']['newCursorReview'] = { 'x': 0, 'y':self.env['screenData']['lines'] -1}
20 self.env['runtime']['outputManager'].presentText("Bottom", interrupt=True)
19 self.env['screen']['newCursorReview'] = { 'x': 0, 'y':self.env['screen']['lines'] -1}
20 self.env['runtime']['outputManager'].presentText(_("Bottom"), interrupt=True, flush=False)
2121
2222 def setCallback(self, callback):
2323 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'presents the current character.'
17 return _('presents the current character.')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
25 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
25 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
2626
2727 def setCallback(self, callback):
2828 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review and phonetically presents the current character'
17 return _('set review and phonetically presents the current character')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if currChar.isspace():
26 self.env['runtime']['outputManager'].presentText("blank" ,interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
2828 currChar = char_utils.getPhonetic(currChar)
29 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, announceCapital=True)
29 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, announceCapital=True, flush=False)
3030
3131 def setCallback(self, callback):
3232 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'current line'
17 return _('current line')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currLine = \
23 line_utils.getCurrentLine(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currLine = \
23 line_utils.getCurrentLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if currLine.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
2727 else:
28 self.env['runtime']['outputManager'].presentText(currLine, interrupt=True)
28 self.env['runtime']['outputManager'].presentText(currLine, interrupt=True, flush=False)
2929 def setCallback(self, callback):
3030 pass
3131
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'current word.'
17 return _('current word.')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \
23 word_utils.getCurrentWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \
23 word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if currWord.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
28 self.env['runtime']['outputManager'].presentText(currWord, interrupt=True)
28 self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
2929 if endOfScreen:
3030 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
31 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
31 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3232 if lineBreak:
3333 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
34 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
34 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3535 def setCallback(self, callback):
3636 pass
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'phonetically spells the current word and set review to it'
18 return _('phonetically spells the current word and set review to it')
1919
2020 def run(self):
2121 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \
23 word_utils.getCurrentWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currWord, endOfScreen, lineBreak = \
23 word_utils.getCurrentWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if currWord.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
2828 firstSequence = True
2929 for c in currWord:
3030 currChar = char_utils.getPhonetic(c)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False)
3232 firstSequence = False
3333 if endOfScreen:
3434 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
35 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
35 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3636 if lineBreak:
3737 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
38 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
38 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3939 def setCallback(self, callback):
4040 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review cursor to char below the current char and present it.'
17 return _('set review cursor to char below the current char and present it.')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
21 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], downChar, endOfScreen = \
22 char_utils.getDownChar(self.env['screenData']['newCursorReview']['x'],self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
23 self.env['runtime']['outputManager'].presentText(downChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
21 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], downChar, endOfScreen = \
22 char_utils.getDownChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
23 self.env['runtime']['outputManager'].presentText(downChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
2424 if endOfScreen:
2525 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
26 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
26 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
2727 def setCallback(self, callback):
2828 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review cursor to begin of current line and display the content'
17 return _('set review cursor to begin of current line and display the content')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
2121 self.env['runtime']['cursorManager'].setReviewCursorPosition(0 ,cursorPos['y'])
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if currChar.isspace():
26 self.env['runtime']['outputManager'].presentText("blank" ,interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
28 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
29 self.env['runtime']['outputManager'].presentText("beginning of line", interrupt=False)
28 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
29 self.env['runtime']['outputManager'].presentText(_("beginning of line"), interrupt=False)
3030
3131 def setCallback(self, callback):
3232 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review cursor to end of current line and display the content'
17 return _('set review cursor to end of current line and display the content')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
21 self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screenData']['columns']-1 ,cursorPos['y'])
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
21 self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \
23 char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
25 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
26 self.env['runtime']['outputManager'].presentText("end of line", interrupt=False)
25 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
26 self.env['runtime']['outputManager'].presentText(_("end of line"), interrupt=False)
2727
2828 def setCallback(self, callback):
2929 pass
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'set review cursor to end of current line and display the content'
18 return _('set review cursor to end of current line and display the content')
1919
2020 def run(self):
2121 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
2222 x, y, currLine = \
23 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screenData']['newContentText'])
23 line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText'])
2424 if currLine.isspace():
25 self.env['runtime']['outputManager'].presentText("line is empty" ,interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_("line is empty"), interrupt=True)
2626 return
2727 self.env['runtime']['cursorManager'].setReviewCursorPosition((len(currLine) - len(currLine.lstrip())), cursorPos['y'])
28 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], currChar = \
29 char_utils.getCurrentChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
28 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], currChar = \
29 char_utils.getCurrentChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
3030
31 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
32 self.env['runtime']['outputManager'].presentText("first char in line indent " + str(len(currLine) - len(currLine.lstrip())), interrupt=False)
31 self.env['runtime']['outputManager'].presentText(currChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
32 self.env['runtime']['outputManager'].presentText(_("first char in line indent {0}").format(str(len(currLine) - len(currLine.lstrip()))), interrupt=False)
3333
3434 def setCallback(self, callback):
3535 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review cursor to end of current line and display the content'
17 return _('set review cursor to end of current line and display the content')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
21 self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screenData']['columns']-1 ,cursorPos['y'])
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], lastChar = \
23 char_utils.getLastCharInLine(self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
21 self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,cursorPos['y'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \
23 char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
25 self.env['runtime']['outputManager'].presentText(lastChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
26 self.env['runtime']['outputManager'].presentText("last char in line", interrupt=False)
25 self.env['runtime']['outputManager'].presentText(lastChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
26 self.env['runtime']['outputManager'].presentText(_("last char in line"), interrupt=False)
2727
2828 def setCallback(self, callback):
2929 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review to the next character and presents it'
17 return _('moves review to the next character and presents it')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
21 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \
22 char_utils.getNextChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
21 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \
22 char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2323
24 self.env['runtime']['outputManager'].presentText(nextChar, interrupt=True, ignorePunctuation=True, announceCapital=True)
24 self.env['runtime']['outputManager'].presentText(nextChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
2525 if endOfScreen:
2626 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
27 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
27 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
2828 if lineBreak:
2929 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
30 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
30 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3131 def setCallback(self, callback):
3232 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'phonetically presents the next character and set review to it'
17 return _('phonetically presents the next character and set review to it')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \
23 char_utils.getNextChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextChar, endOfScreen, lineBreak = \
23 char_utils.getNextChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 nextChar = char_utils.getPhonetic(nextChar)
26 self.env['runtime']['outputManager'].presentText(nextChar ,interrupt=True, announceCapital=True)
26 self.env['runtime']['outputManager'].presentText(nextChar ,interrupt=True, announceCapital=True, flush=False)
2727 if endOfScreen:
2828 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
29 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
29 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3030 if lineBreak:
3131 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
32 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
32 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3333 def setCallback(self, callback):
3434 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review to the next line and presents it'
17 return _('moves review to the next line and presents it')
1818
1919 def run(self):
20 self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
21 if not self.env['screenData']['newCursorReview']:
22 self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
20 self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
21 if not self.env['screen']['newCursorReview']:
22 self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy()
2323
24 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], nextLine, endOfScreen = \
25 line_utils.getNextLine(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
24 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextLine, endOfScreen = \
25 line_utils.getNextLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2626
2727 if nextLine.isspace():
28 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
28 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
2929 else:
30 self.env['runtime']['outputManager'].presentText(nextLine, interrupt=True)
30 self.env['runtime']['outputManager'].presentText(nextLine, interrupt=True, flush=False)
3131 if endOfScreen:
3232 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
33 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
33 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3434 def setCallback(self, callback):
3535 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review to the next word and presents it'
17 return _('moves review to the next word and presents it')
1818
1919 def run(self):
20 self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
21 if self.env['screenData']['newCursorReview'] == None:
22 self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
20 self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
21 if self.env['screen']['newCursorReview'] == None:
22 self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy()
2323
24 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \
25 word_utils.getNextWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
24 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \
25 word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2626
2727 if nextWord.isspace():
28 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
28 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2929 else:
30 self.env['runtime']['outputManager'].presentText(nextWord, interrupt=True)
30 self.env['runtime']['outputManager'].presentText(nextWord, interrupt=True, flush=False)
3131 if endOfScreen:
3232 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
33 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
33 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3434 if lineBreak:
3535 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
36 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
36 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3737 def setCallback(self, callback):
3838 pass
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'phonetically spells the current word and set review to it'
18 return _('phonetically spells the current word and set review to it')
1919
2020 def run(self):
2121 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \
23 word_utils.getNextWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], nextWord, endOfScreen, lineBreak = \
23 word_utils.getNextWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if nextWord.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
2828 firstSequence = True
2929 for c in nextWord:
3030 currChar = char_utils.getPhonetic(c)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False)
3232 firstSequence = False
3333 if endOfScreen:
3434 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
35 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
35 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3636 if lineBreak:
3737 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
38 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
38 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3939 def setCallback(self, callback):
4040 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review to the previous character and presents it'
17 return _('moves review to the previous character and presents it')
1818
1919 def run(self):
20 self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
21 if not self.env['screenData']['newCursorReview']:
22 self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
20 self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
21 if not self.env['screen']['newCursorReview']:
22 self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy()
2323
24 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \
25 char_utils.getPrevChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
24 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \
25 char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2626
27 self.env['runtime']['outputManager'].presentText(prevChar, interrupt=True, ignorePunctuation=True, announceCapital=True)
27 self.env['runtime']['outputManager'].presentText(prevChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
2828 if endOfScreen:
2929 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
30 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
30 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3131 if lineBreak:
3232 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
33 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
33 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3434 def setCallback(self, callback):
3535 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'phonetically presents the previous character and set review to it'
17 return _('phonetically presents the previous character and set review to it')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \
23 char_utils.getPrevChar(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevChar, endOfScreen, lineBreak = \
23 char_utils.getPrevChar(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 prevChar = char_utils.getPhonetic(prevChar)
26 self.env['runtime']['outputManager'].presentText(prevChar ,interrupt=True, announceCapital=True)
26 self.env['runtime']['outputManager'].presentText(prevChar ,interrupt=True, announceCapital=True, flush=False)
2727 if endOfScreen:
2828 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
29 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
29 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3030 if lineBreak:
3131 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
32 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
32 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3333 def setCallback(self, callback):
3434 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review to the previous line and presents it'
17 return _('moves review to the previous line and presents it')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], prevLine, endOfScreen = \
23 line_utils.getPrevLine(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevLine, endOfScreen = \
23 line_utils.getPrevLine(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if prevLine.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
2727 else:
28 self.env['runtime']['outputManager'].presentText(prevLine, interrupt=True)
28 self.env['runtime']['outputManager'].presentText(prevLine, interrupt=True, flush=False)
2929 if endOfScreen:
3030 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
31 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
31 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3232
3333 def setCallback(self, callback):
3434 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'moves review focus to the previous word and presents it'
17 return _('moves review focus to the previous word and presents it')
1818
1919 def run(self):
2020 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
2121
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \
23 word_utils.getPrevWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \
23 word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if prevWord.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
28 self.env['runtime']['outputManager'].presentText(prevWord, interrupt=True)
28 self.env['runtime']['outputManager'].presentText(prevWord, interrupt=True, flush=False)
2929 if endOfScreen:
3030 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
31 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=False, soundIcon='EndOfScreen')
31 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=False, soundIcon='EndOfScreen')
3232 if lineBreak:
3333 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
34 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
34 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3535 def setCallback(self, callback):
3636 pass
1515 def shutdown(self):
1616 pass
1717 def getDescription(self):
18 return 'phonetically spells the current word and set review to it'
18 return _('phonetically spells the current word and set review to it')
1919
2020 def run(self):
2121 self.env['runtime']['cursorManager'].enterReviewModeCurrTextCursor()
22 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \
23 word_utils.getPrevWord(self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
22 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], prevWord, endOfScreen, lineBreak = \
23 word_utils.getPrevWord(self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
2424
2525 if prevWord.isspace():
26 self.env['runtime']['outputManager'].presentText("blank", interrupt=True)
26 self.env['runtime']['outputManager'].presentText(_("blank"), interrupt=True, flush=False)
2727 else:
2828 firstSequence = True
2929 for c in prevWord:
3030 currChar = char_utils.getPhonetic(c)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True)
31 self.env['runtime']['outputManager'].presentText(currChar, interrupt=firstSequence, announceCapital=True, flush=False)
3232 firstSequence = False
3333 if endOfScreen:
3434 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
35 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
35 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
3636 if lineBreak:
3737 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
38 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
38 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3939 def setCallback(self, callback):
4040 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'move review to top of screen'
17 return _('move review to top of screen')
1818
1919 def run(self):
20 self.env['screenData']['newCursorReview'] = {'x':0,'y':0}
21 self.env['runtime']['outputManager'].presentText("Top", interrupt=True)
20 self.env['screen']['newCursorReview'] = {'x':0,'y':0}
21 self.env['runtime']['outputManager'].presentText(_("Top"), interrupt=True, flush=False)
2222
2323 def setCallback(self, callback):
2424 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set review cursor to the char in the line below and present it'
17 return _('set review cursor to the char in the line below and present it')
1818
1919 def run(self):
2020 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
21 self.env['screenData']['newCursorReview']['x'], self.env['screenData']['newCursorReview']['y'], upChar, endOfScreen = \
22 char_utils.getUpChar(self.env['screenData']['newCursorReview']['x'],self.env['screenData']['newCursorReview']['y'], self.env['screenData']['newContentText'])
23 self.env['runtime']['outputManager'].presentText(upChar ,interrupt=True, ignorePunctuation=True, announceCapital=True)
21 self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], upChar, endOfScreen = \
22 char_utils.getUpChar(self.env['screen']['newCursorReview']['x'],self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
23 self.env['runtime']['outputManager'].presentText(upChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
2424 if endOfScreen:
2525 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'endOfScreen'):
26 self.env['runtime']['outputManager'].presentText('end of screen' ,interrupt=True, soundIcon='EndOfScreen')
26 self.env['runtime']['outputManager'].presentText(_('end of screen'), interrupt=True, soundIcon='EndOfScreen')
2727 if lineBreak:
2828 if self.env['runtime']['settingsManager'].getSettingAsBool('review', 'lineBreak'):
29 self.env['runtime']['outputManager'].presentText('line break' ,interrupt=False, soundIcon='EndOfLine')
29 self.env['runtime']['outputManager'].presentText(_('line break'), interrupt=False, soundIcon='EndOfLine')
3030 def setCallback(self, callback):
3131 pass
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'set Bookmark ' + self.ID
17 return _('set Bookmark {0}').format(self.ID,)
1818
1919 def run(self):
2020 if not self.env['commandBuffer']['Marks']['1']:
21 self.env['runtime']['outputManager'].presentText("No Mark found", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("No Mark found"), interrupt=True)
2222 return
2323 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
2424 self.env['commandBuffer']['bookMarks'][self.ID][currApp] = {}
2828 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = self.env['commandBuffer']['Marks']['2'].copy()
2929 else:
3030 self.env['commandBuffer']['bookMarks'][self.ID][currApp]['2'] = None
31 self.env['runtime']['outputManager'].presentText('Bookmark ' + self.ID + " set for application " + currApp, interrupt=True)
31 self.env['runtime']['outputManager'].presentText(_('Bookmark {0} set for application {1}').format(self.ID, currApp), interrupt=True)
3232 self.env['commandBuffer']['Marks']['1'] = None
3333 self.env['commandBuffer']['Marks']['2'] = None
3434 def setCallback(self, callback):
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'places marks to select text to copy to the clipboard'
16 return _('places marks to select text to copy to the clipboard')
1717
1818 def run(self):
1919 if not self.env['runtime']['cursorManager'].isReviewMode():
20 self.env['runtime']['outputManager'].presentText('no review cursor', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('no review cursor'), interrupt=True)
2121 return
2222
2323 currMark = self.env['runtime']['cursorManager'].setMark()
2424 if currMark == 1:
25 self.env['runtime']['outputManager'].presentText('set mark',soundIcon='PlaceStartMark', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('set mark'), soundIcon='PlaceStartMark', interrupt=True)
2626 elif currMark == 2:
27 self.env['runtime']['outputManager'].presentText('set mark',soundIcon='PlaceEndMark', interrupt=True)
27 self.env['runtime']['outputManager'].presentText(_('set mark'),soundIcon='PlaceEndMark', interrupt=True)
2828 def setCallback(self, callback):
2929 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'set Window Mode, needs 2 marks '
16 return _('set Window Mode, needs 2 marks ')
1717
1818 def run(self):
1919 if self.env['runtime']['cursorManager'].setWindowForApplication():
2020 currApp = self.env['runtime']['applicationManager'].getCurrentApplication()
21 self.env['runtime']['outputManager'].presentText('Window Mode on for application ' + currApp, interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_('Window Mode on for application {0}').format(currApp), interrupt=True)
2222 self.env['runtime']['cursorManager'].clearMarks()
2323 else:
24 self.env['runtime']['outputManager'].presentText("Set window beginn and end marks", interrupt=True)
24 self.env['runtime']['outputManager'].presentText(_("Set window begin and end marks"), interrupt=True)
2525
2626 def setCallback(self, callback):
2727 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'interrupts the current presentation'
16 return _('interrupts the current presentation')
1717 def run(self):
1818 if len(self.env['input']['prevDeepestInput']) > len(self.env['input']['currInput']):
1919 return
2222 def shutdown(self):
2323 pass
2424 def getDescription(self):
25 return 'checks the spelling of the current word'
25 return _('checks the spelling of the current word')
2626 def updateSpellLanguage(self):
27 if not initialized:
28 self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True)
29 return
2730 self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
2831 self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')
2932
3033 def run(self):
3134 if not initialized:
32 self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True)
35 self.env['runtime']['outputManager'].presentText(_('pyenchant is not installed'), interrupt=True)
3336 return
3437 if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
3538 try:
4043 cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
4144
4245 # get the word
43 newContent = self.env['screenData']['newContentText'].split('\n')[cursorPos['y']]
46 newContent = self.env['screen']['newContentText'].split('\n')[cursorPos['y']]
4447 x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(cursorPos['x'], 0, newContent)
4548
4649 if not currWord.isspace():
4750 if not self.spellChecker.check(currWord):
48 self.env['runtime']['outputManager'].presentText('misspelled',soundIcon='mispell', interrupt=True)
51 self.env['runtime']['outputManager'].presentText(_('misspelled'),soundIcon='mispell', interrupt=True)
4952 elif not ignore:
50 self.env['runtime']['outputManager'].presentText('correct',soundIcon='', interrupt=True)
53 self.env['runtime']['outputManager'].presentText(_('correct'),soundIcon='', interrupt=True)
5154 def setCallback(self, callback):
5255 pass
1717 def shutdown(self):
1818 pass
1919 def getDescription(self):
20 return 'script: ' + os.path.basename(self.scriptPath) + ' fullpath: '+ self.scriptPath
20 return _('script: {0} fullpath: {1}').format(os.path.basename(self.scriptPath), self.scriptPath)
2121 def run(self):
2222 if not os.path.exists(self.scriptPath):
23 self.env['runtime']['outputManager'].presentText('scriptfile does not exist' , soundIcon='', interrupt=False)
23 self.env['runtime']['outputManager'].presentText(_('scriptfile does not exist'), soundIcon='', interrupt=False)
2424 return
2525 if not os.path.isfile(self.scriptPath):
26 self.env['runtime']['outputManager'].presentText('scriptfile is not a file' , soundIcon='', interrupt=False)
26 self.env['runtime']['outputManager'].presentText(_('scriptfile is not a file'), soundIcon='', interrupt=False)
2727 return
2828 if not os.access(self.scriptPath, os.X_OK):
29 self.env['runtime']['outputManager'].presentText('scriptfile is not executable' , soundIcon='', interrupt=False)
29 self.env['runtime']['outputManager'].presentText(_('scriptfile is not executable'), soundIcon='', interrupt=False)
3030 return
3131 _thread.start_new_thread(self._threadRun , ())
3232
3333 def _threadRun(self):
3434 try:
35 p = Popen(self.scriptPath , stdout=PIPE, stderr=PIPE, shell=True)
35 callstring = self.scriptPath + ' ' + self.env['general']['currUser']
36 p = Popen(callstring , stdout=PIPE, stderr=PIPE, shell=True)
3637 stdout, stderr = p.communicate()
38 stdout = stdout.decode('utf-8')
39 stderr = stderr.decode('utf-8')
3740 self.env['runtime']['outputManager'].interruptOutput()
38 screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
39 stderr = stderr.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
40 stdout = stdout.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
4141 if stderr != '':
42 self.env['runtime']['outputManager'].presentText(stdout , soundIcon='', interrupt=False)
42 self.env['runtime']['outputManager'].presentText(str(stderr) , soundIcon='', interrupt=False)
4343 if stdout != '':
44 self.env['runtime']['outputManager'].presentText(stdout , soundIcon='', interrupt=False)
44 self.env['runtime']['outputManager'].presentText(str(stdout) , soundIcon='', interrupt=False)
4545 except Exception as e:
4646 self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False)
4747
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'disables speech until next keypress'
16 return _('disables speech until next keypress')
1717
1818 def run(self):
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
20 self.env['runtime']['outputManager'].presentText("speech temporary disabled", soundIcon='SpeechOff', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_("speech temporary disabled"), soundIcon='SpeechOff', interrupt=True)
2121 self.env['commandBuffer']['enableSpeechOnKeypress'] = True
2222 self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
2323 self.env['runtime']['outputManager'].interruptOutput()
1414 def shutdown(self):
1515 pass
1616 def getDescription(self):
17 return 'presents the time'
17 return _('presents the time')
1818
1919 def run(self):
2020 timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat')
1212 def shutdown(self):
1313 pass
1414 def getDescription(self):
15 return 'enables or disables automatic reading of new text as it appears'
15 return _('enables or disables automatic reading of new text as it appears')
1616
1717 def run(self):
1818 self.env['runtime']['settingsManager'].setSetting('speech', 'autoReadIncoming', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming')))
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'):
20 self.env['runtime']['outputManager'].presentText("autoread enabled", soundIcon='', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_("autoread enabled"), soundIcon='', interrupt=True)
2121 else:
22 self.env['runtime']['outputManager'].presentText("autoread disabled", soundIcon='', interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_("autoread disabled"), soundIcon='', interrupt=True)
2323
2424 def setCallback(self, callback):
2525 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'enables or disables automatic spell checking'
16 return _('enables or disables automatic spell checking')
1717
1818 def run(self):
1919 self.env['runtime']['settingsManager'].setSetting('general', 'autoSpellCheck', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck')))
2020 if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'):
21 self.env['runtime']['outputManager'].presentText("auto spellcheck enabled", soundIcon='', interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("auto spellcheck enabled"), soundIcon='', interrupt=True)
2222 else:
23 self.env['runtime']['outputManager'].presentText("auto spellcheck disabled", soundIcon='', interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_("auto spellcheck disabled"), soundIcon='', interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1212 def shutdown(self):
1313 pass
1414 def getDescription(self):
15 return 'enables or disables automatic reading of time after an period'
15 return _('enables or disables automatic reading of time after an period')
1616
1717 def run(self):
1818 self.env['runtime']['settingsManager'].setSetting('time', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled')))
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'):
20 self.env['runtime']['outputManager'].presentText("autotime enabled", soundIcon='', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_("autotime enabled"), soundIcon='', interrupt=True)
2121 else:
22 self.env['runtime']['outputManager'].presentText("autotime disabled", soundIcon='', interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_("autotime disabled"), soundIcon='', interrupt=True)
2323
2424 def setCallback(self, callback):
2525 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'enables and disables output in braille'
16 return _('enables and disables output in braille')
1717
1818 def run(self):
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
20 self.env['runtime']['outputManager'].presentText("braille disabled", soundIcon='BrailleOff', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('braille disabled'), soundIcon='BrailleOff', interrupt=True)
2121 self.env['runtime']['settingsManager'].setSetting('braille', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled')))
2222 if self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
23 self.env['runtime']['outputManager'].presentText("braille enabled", soundIcon='BrailleOn', interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('braille enabled'), soundIcon='BrailleOn', interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1212 def shutdown(self):
1313 pass
1414 def getDescription(self):
15 return 'enables or disables announcement of emoticons insteed of chars'
15 return _('enables or disables announcement of emoticons instead of chars')
1616
1717 def run(self):
1818 self.env['runtime']['settingsManager'].setSetting('general', 'emoticons', str(not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons')))
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'):
20 self.env['runtime']['outputManager'].presentText("emoticons enabled", soundIcon='', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('emoticons enabled'), soundIcon='', interrupt=True)
2121 else:
22 self.env['runtime']['outputManager'].presentText("emoticons disabled", soundIcon='', interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_('emoticons disabled'), soundIcon='', interrupt=True)
2323
2424 def setCallback(self, callback):
2525 pass
1212 def shutdown(self):
1313 pass
1414 def getDescription(self):
15 return 'enables or disables tracking of highlighted'
15 return _('enables or disables tracking of highlighted text')
1616
1717 def run(self):
1818 currMode = self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight')
2020 self.env['runtime']['settingsManager'].setSetting('focus', 'highlight', str(not currMode))
2121 self.env['runtime']['settingsManager'].setSetting('focus', 'cursor', str(currMode))
2222 if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
23 self.env['runtime']['outputManager'].presentText("highlight tracking", soundIcon='', interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('highlight tracking'), soundIcon='', interrupt=True)
2424 else:
25 self.env['runtime']['outputManager'].presentText("cursor tracking", soundIcon='', interrupt=True)
25 self.env['runtime']['outputManager'].presentText(_('cursor tracking'), soundIcon='', interrupt=True)
2626
2727 def setCallback(self, callback):
2828 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'toggles all output settings'
16 return _('toggles all output settings')
1717
1818 def run(self):
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled') or \
2020 self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled') or \
2121 self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
22 self.env['runtime']['outputManager'].presentText("fenrir muted", soundIcon='Accept', interrupt=True)
22 self.env['runtime']['outputManager'].presentText(_('Fenrir muted'), soundIcon='Accept', interrupt=True)
2323 self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','False')
2424 self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','False')
2525 self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','False')
2727 self.env['runtime']['settingsManager'].setSetting('speech', 'enabled','True')
2828 self.env['runtime']['settingsManager'].setSetting('sound', 'enabled','True')
2929 self.env['runtime']['settingsManager'].setSetting('braille', 'enabled','True')
30 self.env['runtime']['outputManager'].presentText("fenrir unmuted", soundIcon='Cancel', interrupt=True)
30 self.env['runtime']['outputManager'].presentText(_('Fenrir unmuted'), soundIcon='Cancel', interrupt=True)
3131
3232 def setCallback(self, callback):
3333 pass
1919 if self.env['runtime']['punctuationManager'].cyclePunctuation():
2020 self.env['runtime']['outputManager'].presentText(self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel'), interrupt=True, ignorePunctuation=True)
2121 else:
22 self.env['runtime']['outputManager'].presentText('No punctuation found.', interrupt=True, ignorePunctuation=True)
22 self.env['runtime']['outputManager'].presentText(_('No punctuation found.'), interrupt=True, ignorePunctuation=True)
2323
2424 def setCallback(self, callback):
2525 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'enables or disables sound'
16 return _('enables or disables sound')
1717
1818 def run(self):
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
20 self.env['runtime']['outputManager'].presentText("sound disabled", soundIcon='SoundOff', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('sound disabled'), soundIcon='SoundOff', interrupt=True)
2121 self.env['runtime']['settingsManager'].setSetting('sound', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled')))
2222 if self.env['runtime']['settingsManager'].getSettingAsBool('sound', 'enabled'):
23 self.env['runtime']['outputManager'].presentText("sound enabled", soundIcon='SoundOn', interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('sound enabled'), soundIcon='SoundOn', interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'enables or disables speech'
16 return _('enables or disables speech')
1717
1818 def run(self):
1919 if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
20 self.env['runtime']['outputManager'].presentText("speech disabled", soundIcon='SpeechOff', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(_('speech disabled'), soundIcon='SpeechOff', interrupt=True)
2121 self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled')))
2222 if self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
23 self.env['runtime']['outputManager'].presentText("speech enabled", soundIcon='SpeechOn', interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_('speech enabled'), soundIcon='SpeechOn', interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 self.env['generalInformation']['tutorialMode'] = False
17 return 'You are leving the tutorial mode. Press that shortcut again to enter the tutorial mode again.'
18
16 self.env['runtime']['helpManager'].toggleTutorialMode()
17 #self.env['runtime']['outputManager'].presentText(, interrupt=True)
18 return _('You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again.')
1919 def run(self):
20 text = 'you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leve the tutorial mode, press that shortcut again.'
21 self.env['runtime']['outputManager'].presentText(text, interrupt=True)
22 self.env['generalInformation']['tutorialMode'] = True
23
20 self.env['runtime']['helpManager'].toggleTutorialMode()
21 self.env['runtime']['outputManager'].presentText( _('you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again.'), interrupt=True)
2422 def setCallback(self, callback):
2523 pass
0 this folder contains help and tutorial related functions.
1 those are not bindable but hard coded.
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('get current help message')
17 def run(self):
18 text = self.env['runtime']['helpManager'].getHelpForCurrentIndex()
19 self.env['runtime']['outputManager'].presentText(text, interrupt=True)
20 def setCallback(self, callback):
21 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('get next help message')
17 def run(self):
18 self.env['runtime']['helpManager'].nextIndex()
19 text = self.env['runtime']['helpManager'].getHelpForCurrentIndex()
20 self.env['runtime']['outputManager'].presentText(text, interrupt=True)
21 def setCallback(self, callback):
22 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('get prev help message')
17 def run(self):
18 self.env['runtime']['helpManager'].prevIndex()
19 text = self.env['runtime']['helpManager'].getHelpForCurrentIndex()
20 self.env['runtime']['outputManager'].presentText(text, interrupt=True)
21 def setCallback(self, callback):
22 pass
0 #!/bi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]/py[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ho[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
1 # -*- [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]odi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]g: u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f-8 -*-
2
3 # F[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] TTY [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
4 # By Ch[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]y[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], S[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]go[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ibu[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']].
5
6 f[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]om [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] impo[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]bug
7
8 [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]l[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]omm[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d():
9 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f __i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]__([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf):
10 p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
11 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]liz[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf, [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]vi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]):
12 [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v = [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]vi[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]o[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]m[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
13 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]hu[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]dow[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf):
14 p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
15 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f g[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ip[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf):
16 [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]No d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]ip[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']] fou[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
17 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]u[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf):
18 #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]w [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v[[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]][[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]wAppli[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]])
19 #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]old [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']], [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf.[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]v[[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]][[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]oldAppli[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]io[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]])
20 #p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]i[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]-----------[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']])
21 p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
22
23 d[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]f [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]C[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]llb[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]k([['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]lf, [['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]llb[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]k):
24 p[['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']][['screen']['screen']['screen']['screen']['screen']['screen']['screen']['screen']]
+0
-25
src/fenrir/commands/onApplicationChange/test.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def run(self):
18 #print('new ', self.env['screenData']['newApplication'])
19 #print('old ', self.env['screenData']['oldApplication'])
20 #print('-----------')
21 pass
22
23 def setCallback(self, callback):
24 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
20 return
21 # detect deletion or chilling
22 if self.env['screen']['newCursor']['x'] <= self.env['screen']['oldCursor']['x']:
23 return
24 # is there any change?
25 if not self.env['runtime']['screenManager'].isDelta():
26 return
27 # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now)
28 if len(self.env['screen']['newDelta'].strip(' \n\t')) > 1:
29 return
30 # filter unneded space on word begin
31 currDelta = self.env['screen']['newDelta']
32 if len(currDelta.strip()) != len(currDelta) and \
33 currDelta.strip() != '':
34 currDelta = currDelta.strip()
35 self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
36
37 def setCallback(self, callback):
38 pass
39
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import char_utils
8
9 class command():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self.env = environment
14 def shutdown(self):
15 pass
16 def getDescription(self):
17 return ''
18
19 def run(self):
20 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
21 return
22 if self.env['runtime']['screenManager'].isScreenChange():
23 return
24 # detect an change on the screen, we just want to cursor arround, so no change should appear
25 if self.env['runtime']['screenManager'].isDelta():
26 return
27 if self.env['runtime']['screenManager'].isNegativeDelta():
28 return
29 # is a vertical change?
30 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
31 return
32 # is it a horizontal change?
33 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
34 return
35 # echo word insteed of char
36 if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
37 if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) != 1:
38 # get the word
39 newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
40 x, y, currWord, endOfScreen, lineBreak = \
41 word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)
42 if self.env['screen']['newCursor']['x'] == x:
43 return
44 x, y, currChar = char_utils.getCurrentChar(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])
45 if not currChar.isspace():
46 self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
47 def setCallback(self, callback):
48 pass
49
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import line_utils
8 from utils import word_utils
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return ''
19
20 def run(self):
21 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
22 return
23 if self.env['runtime']['screenManager'].isScreenChange():
24 return
25 # this leads to problems in vim -> status line change -> no announcement, so we do check the lengh as hack
26 if self.env['runtime']['screenManager'].isDelta():
27 return
28
29 # is a vertical change?
30 if not self.env['runtime']['cursorManager'].isCursorVerticalMove():
31 return
32
33 x, y, currLine = line_utils.getCurrentLine(self.env['screen']['newCursor']['x'], self.env['screen']['newCursor']['y'], self.env['screen']['newContentText'])
34
35 if currLine.isspace():
36 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
37 else:
38 self.env['runtime']['outputManager'].presentText(currLine, interrupt=True, flush=False)
39
40 def setCallback(self, callback):
41 pass
42
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import word_utils
8 import string
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return 'No Description found'
19
20 def run(self):
21 # is it enabled?
22 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
23 return
24 # is naviation?
25 if self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'] != 1:
26 return
27 # just when cursor move worddetection is needed
28 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
29 return
30 # for now no new line
31 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
32 return
33 # currently writing
34 if self.env['runtime']['screenManager'].isDelta():
35 return
36
37 # get the word
38 newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
39 x, y, currWord, endOfScreen, lineBreak = \
40 word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)
41
42 # is there a word?
43 if currWord == '':
44 return
45 # at the end of a word
46 if not newContent[self.env['screen']['newCursor']['x']].isspace():
47 return
48 # at the end of a word
49 if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
50 (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
51 return
52
53 self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
54
55 def setCallback(self, callback):
56 pass
57
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import word_utils
8 import string
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return 'No Description found'
19
20 def run(self):
21 # is navigation?
22 if not abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) > 1:
23 return
24
25 # just when cursor move worddetection is needed
26 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
27 return
28 # for now no new line
29 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
30 return
31 # currently writing
32 if self.env['runtime']['screenManager'].isDelta():
33 return
34
35 # get the word
36 newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
37 x, y, currWord, endOfScreen, lineBreak = \
38 word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)
39
40 # is there a word?
41 if currWord == '':
42 return
43
44 # at the start of a word
45 if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
46 (self.env['screen']['newCursor']['x'] != x):
47 return
48
49 self.env['runtime']['outputManager'].presentText(currWord, interrupt=True, flush=False)
50
51 def setCallback(self, callback):
52 pass
53
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import word_utils
8 import os, string
9
10 initialized = False
11 try:
12 import enchant
13 initialized = True
14 except:
15 pass
16
17 class command():
18 def __init__(self):
19 self.language = ''
20 self.spellChecker = ''
21 def initialize(self, environment):
22 self.env = environment
23 self.updateSpellLanguage()
24 def shutdown(self):
25 pass
26 def getDescription(self):
27 return 'No Description found'
28
29 def updateSpellLanguage(self):
30 if not initialized:
31 self.env['runtime']['outputManager'].presentText('pychant is not installed', interrupt=True)
32 return
33 self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
34 self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')
35
36 def run(self):
37 if not initialized:
38 return
39 if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'):
40 return
41 if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
42 try:
43 self.updateSpellLanguage()
44 except:
45 return
46
47 # just when horizontal cursor move worddetection is needed
48 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
49 return
50
51 # for now no new line
52 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
53 return
54 # more than a keyecho?
55 if len(self.env['screen']['newDelta']) > 1:
56 return
57 # deletion
58 if self.env['runtime']['screenManager'].isNegativeDelta():
59 return
60 # first place could not be the end of a word
61 if self.env['screen']['newCursor']['x'] == 0:
62 return
63
64 # get the word (just for speedup only look at current line
65 newContent = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
66 x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screen']['newCursor']['x'], 0, newContent)
67 # was this a typed word?
68 if self.env['runtime']['screenManager'].isDelta():
69 if not(newContent[self.env['screen']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screen']['oldCursor']['x']):
70 return
71 else:
72 currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~')
73 else:
74 # or just arrow arround?
75 if not newContent[self.env['screen']['newCursor']['x']].isspace():
76 return
77 if (x + len(currWord) != self.env['screen']['newCursor']['x']) and \
78 (x + len(currWord) != self.env['screen']['newCursor']['x']-1):
79 return
80
81 # just on end of word
82 if self.env['screen']['newCursor']['x'] > 0:
83 if not newContent[self.env['screen']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase:
84 return
85
86 # ignore bash buildins
87 if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\
88 'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']:
89 return
90 # ignore the application name
91 if currWord.upper() == 'FENRIR':
92 return
93 if currWord[0] =='-':
94 return
95 if currWord[0] == '/':
96 return
97 if currWord[0] == '#':
98 return
99 if currWord.startswith('./'):
100 return
101 if '@' in currWord and '.' in currWord:
102 return
103 if currWord[0] == '@':
104 return
105 if currWord.isnumeric():
106 return
107 if currWord.isdecimal():
108 return
109 if currWord.isspace():
110 return
111
112 try:
113 if os.path.exists("/bin/"+currWord):
114 return
115 except:
116 pass
117 try:
118 if os.path.exists("/usr/bin/"+currWord):
119 return
120 except:
121 pass
122 try:
123 if os.path.exists("/sbin/"+currWord):
124 return
125 except:
126 pass
127
128 if not self.spellChecker.check(currWord):
129 self.env['runtime']['outputManager'].presentText(_('misspelled'), soundIcon='mispell', interrupt=False, flush=False)
130
131 def setCallback(self, callback):
132 pass
133
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'):
20 return
21 # detect typing or chilling
22 if self.env['screen']['newCursor']['x'] >= self.env['screen']['oldCursor']['x']:
23 return
24
25 # More than just a deletion happend
26 if self.env['runtime']['screenManager'].isDelta():
27 return
28 # no deletion
29 if not self.env['runtime']['screenManager'].isNegativeDelta():
30 return
31
32 # too much for a single backspace...
33 # word begin produce a diff wiht len == 2 |a | others with 1 |a|
34 if len(self.env['screen']['newNegativeDelta']) > 2:
35 return
36 currNegativeDelta = self.env['screen']['newNegativeDelta']
37 if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \
38 currNegativeDelta.strip() != '':
39 currNegativeDelta = currNegativeDelta.strip()
40 self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
41 def setCallback(self, callback):
42 pass
43
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return _('exits review mode')
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnCursorChange'):
20 return
21 if self.env['runtime']['cursorManager'].isReviewMode():
22 self.env['runtime']['cursorManager'].clearReviewCursor()
23
24 def setCallback(self, callback):
25 pass
0 #!/bin/python
1 import time
2 # -*- coding: utf-8 -*-
3
4 # Fenrir TTY screen reader
5 # By Chrys, Storm Dragon, and contributers.
6
7 from core import debug
8 import time
9 import datetime
10
11 class command():
12 def __init__(self):
13 pass
14 def initialize(self, environment):
15 self.env = environment
16 self.lastTime = datetime.datetime.now()
17 self.lastDateString = ''
18 self.lastTimeString = ''
19 def shutdown(self):
20 pass
21 def getDescription(self):
22 return 'No Description found'
23
24 def run(self):
25 self.env['runtime']['screenDriver'].getSessionInformation()
26 def setCallback(self, callback):
27 pass
28
0 #!/bin/python
1 import time
2 # -*- coding: utf-8 -*-
3
4 # Fenrir TTY screen reader
5 # By Chrys, Storm Dragon, and contributers.
6
7 from core import debug
8 import time
9 import datetime
10
11 class command():
12 def __init__(self):
13 pass
14 def initialize(self, environment):
15 self.env = environment
16 self.lastTime = datetime.datetime.now()
17 self.lastDateString = ''
18 self.lastTimeString = ''
19 def shutdown(self):
20 pass
21 def getDescription(self):
22 return 'No Description found'
23
24 def run(self):
25 if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'):
26 return
27 onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes')
28 delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec')
29 # no need
30 if onMinutes == '' and delaySec <= 0:
31 return
32 onMinutes = onMinutes.split(',')
33 now = datetime.datetime.now()
34 # ignore onMinutes if there is a delaySec
35 if delaySec > 0:
36 if int((now-self.lastTime).total_seconds()) < delaySec:
37 return
38 else:
39 # shoul announce?
40 if not str(now.minute) in onMinutes:
41 return
42 # already announced?
43 if now.hour == self.lastTime.hour:
44 if now.minute == self.lastTime.minute:
45 return
46 dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
47 dateString = datetime.datetime.strftime(now, dateFormat)
48
49 presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \
50 self.lastDateString != dateString
51 presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime')
52 # no changed value to announce
53 if not (presentDate or presentTime):
54 return
55 timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat')
56 timeString = datetime.datetime.strftime(now, timeFormat)
57
58 if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'interrupt'):
59 self.env['runtime']['outputManager'].interruptOutput()
60 if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'announce'):
61 self.env['runtime']['outputManager'].playSoundIcon('announce')
62
63 if presentTime:
64 # present the time
65 self.env['runtime']['outputManager'].presentText(_('Autotime: {0}').format(timeString), soundIcon='', interrupt=False)
66 # and date if changes
67 if presentDate:
68 self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=False)
69 self.lastDateString = dateString
70 self.lastTime = datetime.datetime.now()
71 self.lastTimeString = timeString
72 def setCallback(self, callback):
73 pass
0 #!/bin/python
1 import time
2 # -*- coding: utf-8 -*-
3
4 # Fenrir TTY screen reader
5 # By Chrys, Storm Dragon, and contributers.
6
7 from core import debug
8 import time
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15
16 def shutdown(self):
17 pass
18 def getDescription(self):
19 return 'No Description found'
20
21 def run(self):
22 print(time.time())
23 def setCallback(self, callback):
24 pass
25
2222 return
2323 if self.env['runtime']['screenManager'].isScreenChange():
2424 return
25 if len(self.env['input']['prevDeepestInput']) > len(self.env['input']['currInput']):
25 if len(self.env['input']['currInput']) <= len(self.env['input']['prevInput']):
2626 return
2727 # if the filter is set
2828 if self.env['runtime']['settingsManager'].getSetting('keyboard', 'interruptOnKeyPressFilter').strip() != '':
1313 def shutdown(self):
1414 pass
1515 def getDescription(self):
16 return 'disables speech until next keypress'
16 return _('disables speech until next keypress')
1717
1818 def run(self):
1919 if self.env['runtime']['inputManager'].noKeyPressed():
2424 return
2525 self.env['runtime']['settingsManager'].setSetting('speech', 'enabled', str(self.env['commandBuffer']['enableSpeechOnKeypress']))
2626 self.env['commandBuffer']['enableSpeechOnKeypress'] = False
27 self.env['runtime']['outputManager'].presentText("speech enabled", soundIcon='SpeechOn', interrupt=True)
27 self.env['runtime']['outputManager'].presentText(_("speech enabled"), soundIcon='SpeechOn', interrupt=True)
2828
2929 def setCallback(self, callback):
3030 pass
+0
-43
src/fenrir/commands/onInput/45000-present_char_if_cursor_change_horizontal.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import char_utils
8
9 class command():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self.env = environment
14 def shutdown(self):
15 pass
16 def getDescription(self):
17 return ''
18
19 def run(self):
20 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
21 return
22 if self.env['runtime']['screenManager'].isScreenChange():
23 return
24 if self.env['runtime']['inputManager'].noKeyPressed():
25 return
26 # detect an change on the screen, we just want to cursor arround, so no change should appear
27 if self.env['runtime']['screenManager'].isDelta():
28 return
29 if self.env['runtime']['screenManager'].isNegativeDelta():
30 return
31 # is a vertical change?
32 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
33 return
34 # is it a horizontal change?
35 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
36 return
37 x, y, currChar = char_utils.getCurrentChar(self.env['screenData']['newCursor']['x'], self.env['screenData']['newCursor']['y'], self.env['screenData']['newContentText'])
38 if not currChar.isspace():
39 self.env['runtime']['outputManager'].presentText(currChar, interrupt=True, ignorePunctuation=True, announceCapital=True)
40 def setCallback(self, callback):
41 pass
42
+0
-40
src/fenrir/commands/onInput/50000-char_echo.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
20 return
21 # detect deletion or chilling
22 if self.env['screenData']['newCursor']['x'] <= self.env['screenData']['oldCursor']['x']:
23 return
24 # is there any change?
25 if not self.env['runtime']['screenManager'].isDelta():
26 return
27 # big changes are no char (but the value is bigger than one maybe the differ needs longer than you can type, so a little strange random buffer for now)
28 if len(self.env['screenData']['newDelta']) > 3:
29 return
30 # filter unneded space on word begin
31 currDelta = self.env['screenData']['newDelta']
32 if len(currDelta.strip()) != len(currDelta) and \
33 currDelta.strip() != '':
34 currDelta = currDelta.strip()
35 self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True)
36
37 def setCallback(self, callback):
38 pass
39
+0
-42
src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import line_utils
8
9 class command():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self.env = environment
14 def shutdown(self):
15 pass
16 def getDescription(self):
17 return ''
18
19 def run(self):
20 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'cursor'):
21 return
22 if self.env['runtime']['inputManager'].noKeyPressed():
23 return
24 if self.env['runtime']['screenManager'].isScreenChange():
25 return
26 if self.env['runtime']['screenManager'].isDelta():
27 return
28 # is a vertical change?
29 if not self.env['runtime']['cursorManager'].isCursorVerticalMove():
30 return
31
32 x, y, currLine = line_utils.getCurrentLine(self.env['screenData']['newCursor']['x'], self.env['screenData']['newCursor']['y'], self.env['screenData']['newContentText'])
33
34 if currLine.isspace():
35 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
36 else:
37 self.env['runtime']['outputManager'].presentText(currLine, interrupt=True)
38
39 def setCallback(self, callback):
40 pass
41
+0
-24
src/fenrir/commands/onInput/56000-highlight_tracking.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 class command():
8 def __init__(self):
9 pass
10 def initialize(self, environment):
11 self.env = environment
12 def shutdown(self):
13 pass
14 def getDescription(self):
15 return 'enables or disables tracking of highlighted'
16
17 def run(self):
18 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
19 return
20 self.env['runtime']['outputManager'].presentText(self.env['screenData']['newAttribDelta'], soundIcon='', interrupt=True)
21
22 def setCallback(self, callback):
23 pass
+0
-57
src/fenrir/commands/onInput/60000-word_echo.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import word_utils
8 import string
9
10 class command():
11 def __init__(self):
12 pass
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def getDescription(self):
18 return 'No Description found'
19
20 def run(self):
21 # first place could not be the end of a word
22 if self.env['screenData']['newCursor']['x'] == 0:
23 return
24 # is it enabled?
25 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'wordEcho'):
26 return
27
28 # just when cursor move worddetection is needed
29 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
30 return
31 if self.env['runtime']['inputManager'].noKeyPressed():
32 return
33 # for now no new line
34 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
35 return
36 # get the word
37 newContent = self.env['screenData']['newContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
38 x, y, currWord, endOfScreen, lineBreak = \
39 word_utils.getCurrentWord(self.env['screenData']['newCursor']['x'], 0, newContent)
40 # currently writing
41 if self.env['runtime']['screenManager'].isDelta():
42 return
43 else:
44 # at the end of a word
45 if not newContent[self.env['screenData']['newCursor']['x']].isspace():
46 return
47 if (x + len(currWord) != self.env['screenData']['newCursor']['x']) and \
48 (x + len(currWord) != self.env['screenData']['newCursor']['x']-1):
49 return
50
51 if currWord != '':
52 self.env['runtime']['outputManager'].presentText(currWord, interrupt=True)
53
54 def setCallback(self, callback):
55 pass
56
+0
-133
src/fenrir/commands/onInput/62000-spell_check.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from utils import word_utils
8 import os, string
9
10 initialized = False
11 try:
12 import enchant
13 initialized = True
14 except:
15 pass
16
17 class command():
18 def __init__(self):
19 self.language = ''
20 self.spellChecker = ''
21 def initialize(self, environment):
22 self.env = environment
23 self.updateSpellLanguage()
24 def shutdown(self):
25 pass
26 def getDescription(self):
27 return 'No Description found'
28
29 def updateSpellLanguage(self):
30 self.spellChecker = enchant.Dict(self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage'))
31 self.language = self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage')
32
33 def run(self):
34 if not initialized:
35 return
36 if not self.env['runtime']['settingsManager'].getSettingAsBool('general', 'autoSpellCheck'):
37 return
38 if self.env['runtime']['inputManager'].noKeyPressed():
39 return
40 if self.env['runtime']['settingsManager'].getSetting('general', 'spellCheckLanguage') != self.language:
41 try:
42 self.updateSpellLanguage()
43 except:
44 return
45
46 # just when horizontal cursor move worddetection is needed
47 if not self.env['runtime']['cursorManager'].isCursorHorizontalMove():
48 return
49
50 # for now no new line
51 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
52 return
53 # more than a keyecho?
54 if len(self.env['screenData']['newDelta']) > 1:
55 return
56 # deletion
57 if self.env['runtime']['screenManager'].isNegativeDelta():
58 return
59 # first place could not be the end of a word
60 if self.env['screenData']['newCursor']['x'] == 0:
61 return
62
63 # get the word (just for speedup only look at current line
64 newContent = self.env['screenData']['newContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
65 x, y, currWord, endOfScreen, lineBreak = word_utils.getCurrentWord(self.env['screenData']['newCursor']['x'], 0, newContent)
66 # was this a typed word?
67 if self.env['runtime']['screenManager'].isDelta():
68 if not(newContent[self.env['screenData']['oldCursor']['x']] in string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~' and x != self.env['screenData']['oldCursor']['x']):
69 return
70 else:
71 currWord = currWord.strip(string.whitespace + '!"#$%&()*+,-./:;<=>?@[\\]^_{|}~')
72 else:
73 # or just arrow arround?
74 if not newContent[self.env['screenData']['newCursor']['x']].isspace():
75 return
76 if (x + len(currWord) != self.env['screenData']['newCursor']['x']) and \
77 (x + len(currWord) != self.env['screenData']['newCursor']['x']-1):
78 return
79
80 # just on end of word
81 if self.env['screenData']['newCursor']['x'] > 0:
82 if not newContent[self.env['screenData']['oldCursor']['x'] - 1].lower() in string.ascii_lowercase:
83 return
84
85 # ignore bash buildins
86 if currWord in ['cd','fg','bg','alias','bind','dir','caller','buildin','command','declare','echo','enable','help','let','local','logout',\
87 'mapfile','printf','read','readarray','source','type','typeset','ulimit','unalias']:
88 return
89 # ignore the application name
90 if currWord.upper() == 'FENRIR':
91 return
92 if currWord[0] =='-':
93 return
94 if currWord[0] == '/':
95 return
96 if currWord[0] == '#':
97 return
98 if currWord.startswith('./'):
99 return
100 if '@' in currWord and '.' in currWord:
101 return
102 if currWord[0] == '@':
103 return
104 if currWord.isnumeric():
105 return
106 if currWord.isdecimal():
107 return
108 if currWord.isspace():
109 return
110
111 try:
112 if os.path.exists("/bin/"+currWord):
113 return
114 except:
115 pass
116 try:
117 if os.path.exists("/usr/bin/"+currWord):
118 return
119 except:
120 pass
121 try:
122 if os.path.exists("/sbin/"+currWord):
123 return
124 except:
125 pass
126
127 if not self.spellChecker.check(currWord):
128 self.env['runtime']['outputManager'].presentText('misspelled',soundIcon='mispell', interrupt=False)
129
130 def setCallback(self, callback):
131 pass
132
+0
-49
src/fenrir/commands/onInput/65000-char_delete_echo.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charDeleteEcho'):
20 return
21
22 # detect typing or chilling
23 if self.env['screenData']['newCursor']['x'] >= self.env['screenData']['oldCursor']['x']:
24 return
25
26 # More than just a deletion happend
27
28 if self.env['runtime']['screenManager'].isDelta():
29 return
30 # no deletion
31 if not self.env['runtime']['screenManager'].isNegativeDelta():
32 return
33 if self.env['runtime']['inputManager'].noKeyPressed():
34 return
35
36 # too much for a single backspace...
37 # word begin produce a diff wiht len == 2 |a | others with 1 |a|
38 if len(self.env['screenData']['newNegativeDelta']) > 2:
39 return
40 currNegativeDelta = self.env['screenData']['newNegativeDelta']
41 if len(currNegativeDelta.strip()) != len(currNegativeDelta) and \
42 currNegativeDelta.strip() != '':
43 currNegativeDelta = currNegativeDelta.strip()
44 self.env['runtime']['outputManager'].presentText(currNegativeDelta, interrupt=True, ignorePunctuation=True, announceCapital=True)
45
46 def setCallback(self, callback):
47 pass
48
+0
-58
src/fenrir/commands/onInput/72000-history.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return ''
17
18 def run(self):
19 if self.env['runtime']['inputManager'].noKeyPressed():
20 return
21 if self.env['screenData']['newAttribDelta'] != '':
22 return
23 if self.env['runtime']['screenManager'].isScreenChange():
24 return
25 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
26 return
27 if len(self.env['input']['currInput']) != 1:
28 return
29 if not self.env['input']['currInput'][0] in ['KEY_UP','KEY_DOWN']:
30 return
31 prevLine = self.env['screenData']['oldContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
32 currLine = self.env['screenData']['newContentText'].split('\n')[self.env['screenData']['newCursor']['y']]
33 if not currLine.isspace():
34 currPrompt = currLine.find('$')
35 rootPrompt = currLine.find('#')
36 if currPrompt <= 0:
37 if rootPrompt > 0:
38 currPrompt = rootPrompt
39 else:
40 announce = currLine
41 if currPrompt > 0:
42 remove_digits = str.maketrans('0123456789', ' ')
43 if prevLine[:currPrompt].translate(remove_digits) == currLine[:currPrompt].translate(remove_digits):
44 announce = currLine[currPrompt+1:]
45 else:
46 announce = currLine
47
48 if currLine.isspace():
49 self.env['runtime']['outputManager'].presentText("blank", soundIcon='EmptyLine', interrupt=True)
50 else:
51 self.env['runtime']['outputManager'].presentText(announce, interrupt=True)
52 self.env['commandsIgnore']['onScreenUpdate']['CHAR_DELETE_ECHO'] = True
53 self.env['commandsIgnore']['onScreenUpdate']['CHAR_ECHO'] = True
54 self.env['commandsIgnore']['onScreenUpdate']['INCOMING_IGNORE'] = True
55 def setCallback(self, callback):
56 pass
57
1818 if self.env['input']['oldCapsLock'] == self.env['input']['newCapsLock']:
1919 return
2020 if self.env['input']['newCapsLock']:
21 self.env['runtime']['outputManager'].presentText("Capslock on", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("Capslock on"), interrupt=True)
2222 else:
23 self.env['runtime']['outputManager'].presentText("Capslock off", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_("Capslock off"), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1818 if self.env['input']['oldScrollLock'] == self.env['input']['newScrollLock']:
1919 return
2020 if self.env['input']['newScrollLock']:
21 self.env['runtime']['outputManager'].presentText("Scrolllock on", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("Scrolllock on"), interrupt=True)
2222 else:
23 self.env['runtime']['outputManager'].presentText("Scrolllock off", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_("Scrolllock off"), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
1818 if self.env['input']['oldNumLock'] == self.env['input']['newNumLock']:
1919 return
2020 if self.env['input']['newNumLock']:
21 self.env['runtime']['outputManager'].presentText("Numlock on", interrupt=True)
21 self.env['runtime']['outputManager'].presentText(_("Numlock on"), interrupt=True)
2222 else:
23 self.env['runtime']['outputManager'].presentText("Numlock off", interrupt=True)
23 self.env['runtime']['outputManager'].presentText(_("Numlock off"), interrupt=True)
2424
2525 def setCallback(self, callback):
2626 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def run(self):
18 self.env['runtime']['inputManager'].updateInputDevices()
19 def setCallback(self, callback):
20 pass
1616 return 'No Description found'
1717
1818 def run(self):
19 self.env['runtime']['outputManager'].presentText("screen " + str(self.env['screenData']['newTTY']),soundIcon='ChangeTTY', interrupt=True)
20 self.env['runtime']['outputManager'].presentText(self.env['screenData']['newContentText'], interrupt=False)
19 self.env['runtime']['outputManager'].presentText(_("screen {0}").format(self.env['screen']['newTTY']),soundIcon='ChangeTTY', interrupt=True, flush=False)
20 self.env['runtime']['outputManager'].presentText(self.env['screen']['newContentText'], interrupt=False, flush=False)
2121
2222 def setCallback(self, callback):
2323 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 self.env['runtime']['cursorManager'].clearMarks()
20
21 def setCallback(self, callback):
22 pass
23
+0
-24
src/fenrir/commands/onScreenChanged/85000-screen_chnage_reset_marks.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 self.env['runtime']['cursorManager'].clearMarks()
20
21 def setCallback(self, callback):
22 pass
23
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 if not self.env['runtime']['settingsManager'].getSettingAsBool('review', 'leaveReviewOnScreenChange'):
20 return
21 self.env['runtime']['cursorManager'].clearReviewCursor()
22
23 def setCallback(self, callback):
24 pass
25
+0
-24
src/fenrir/commands/onScreenChanged/89000-screen_chnage_leve_review_mode.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No Description found'
17
18 def run(self):
19 self.env['runtime']['cursorManager'].clearReviewCursor()
20
21 def setCallback(self, callback):
22 pass
23
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 class command():
8 def __init__(self):
9 pass
10 def initialize(self, environment):
11 self.env = environment
12 def shutdown(self):
13 pass
14 def getDescription(self):
15 return _('enables or disables tracking of highlighted')
16
17 def run(self):
18 if not self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
19 return
20 self.env['runtime']['outputManager'].presentText(self.env['screen']['newAttribDelta'], soundIcon='', interrupt=True, flush=False)
21
22 def setCallback(self, callback):
23 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return ''
17
18 def run(self):
19 if self.env['screen']['newAttribDelta'] != '':
20 return
21 if self.env['runtime']['screenManager'].isScreenChange():
22 return
23 if self.env['runtime']['cursorManager'].isCursorVerticalMove():
24 return
25 if not (self.env['runtime']['inputManager'].getLastDeepestInput() in [['KEY_UP'],['KEY_DOWN']]):
26 return
27 prevLine = self.env['screen']['oldContentText'].split('\n')[self.env['screen']['newCursor']['y']]
28 currLine = self.env['screen']['newContentText'].split('\n')[self.env['screen']['newCursor']['y']]
29 if prevLine == currLine:
30 if self.env['screen']['newDelta'] != '':
31 return
32 if not currLine.isspace():
33 currPrompt = currLine.find('$')
34 rootPrompt = currLine.find('#')
35 if currPrompt <= 0:
36 if rootPrompt > 0:
37 currPrompt = rootPrompt
38 else:
39 announce = currLine
40 if currPrompt > 0:
41 remove_digits = str.maketrans('0123456789', ' ')
42 if prevLine[:currPrompt].translate(remove_digits) == currLine[:currPrompt].translate(remove_digits):
43 announce = currLine[currPrompt+1:]
44 else:
45 announce = currLine
46
47 if currLine.isspace():
48 self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True, flush=False)
49 else:
50 self.env['runtime']['outputManager'].presentText(announce, interrupt=True, flush=False)
51 self.env['commandsIgnore']['onScreenUpdate']['CHAR_DELETE_ECHO'] = True
52 self.env['commandsIgnore']['onScreenUpdate']['CHAR_ECHO'] = True
53 self.env['commandsIgnore']['onScreenUpdate']['INCOMING_IGNORE'] = True
54 def setCallback(self, callback):
55 pass
56
1919 if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'autoReadIncoming'):
2020 return
2121 # is there something to read?
22 if self.env['screenData']['newDelta'] == '':
23 return
24
25 # its a cursor movement (experimental) - maybe also check current shortcut string?
26 if abs(self.env['screenData']['newCursor']['x'] - self.env['screenData']['oldCursor']['x']) >= 1:
27 if len(self.env['screenData']['newDelta'].strip(' \n\t')) <= 2:
22 if not self.env['runtime']['screenManager'].isDelta():
23 return
24 # this must be a keyecho or something
25 if len(self.env['screen']['newDelta'].strip(' \n\t')) <= 1:
26 if abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x']) >= 1:
27 # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2:
2828 return
29 if abs(self.env['screenData']['newCursor']['y'] - self.env['screenData']['oldCursor']['y']) == 1:
30 return
31
32 self.env['runtime']['outputManager'].presentText(self.env['screenData']['newDelta'], interrupt=False)
29 if abs(self.env['screen']['newCursor']['y'] - self.env['screen']['oldCursor']['y']) == 1:
30 # if len(self.env['screen']['newDelta'].strip(' \n\t0123456789')) <= 2:
31 return
32 self.env['runtime']['outputManager'].presentText(self.env['screen']['newDelta'], interrupt=False, flush=False)
3333
3434 def setCallback(self, callback):
3535 pass
2121 return
2222 if self.env['runtime']['settingsManager'].getSetting('promote', 'list').strip(" \t\n") == '':
2323 return
24 if self.env['screenData']['newDelta'] == '':
25 return
2624 if int(time.time() - self.env['input']['lastInputTime']) < self.env['runtime']['settingsManager'].getSettingAsInt('promote', 'inactiveTimeoutSec'):
2725 return
2826 if len(self.env['runtime']['settingsManager'].getSetting('promote', 'list')) == 0:
2927 return
3028 for promote in self.env['runtime']['settingsManager'].getSetting('promote', 'list').split(','):
31 if promote in self.env['screenData']['newDelta']:
29 if promote in self.env['screen']['newDelta']:
3230 self.env['runtime']['outputManager'].playSoundIcon('PromotedText')
3331 self.env['input']['lastInputTime'] = time.time()
3432 return
+0
-74
src/fenrir/commands/onScreenUpdate/76000-time.py less more
0 #!/bin/python
1 import time
2 # -*- coding: utf-8 -*-
3
4 # Fenrir TTY screen reader
5 # By Chrys, Storm Dragon, and contributers.
6
7 from core import debug
8 import time
9 import datetime
10
11 class command():
12 def __init__(self):
13 pass
14 def initialize(self, environment):
15 self.env = environment
16 self.lastTime = datetime.datetime.now()
17 self.lastDateString = ''
18 self.lastTimeString = ''
19 def shutdown(self):
20 pass
21 def getDescription(self):
22 return 'No Description found'
23
24 def run(self):
25 if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'):
26 return
27 onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes')
28 delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec')
29 # no need
30 if onMinutes == '' and delaySec <= 0:
31 return
32 onMinutes = onMinutes.split(',')
33 now = datetime.datetime.now()
34 # ignore onMinutes if there is a delaySec
35 if delaySec > 0:
36 if int((now-self.lastTime).total_seconds()) < delaySec:
37 return
38 else:
39 # shoul announce?
40 if not str(now.minute) in onMinutes:
41 return
42 # already announced?
43 if now.hour == self.lastTime.hour:
44 if now.minute == self.lastTime.minute:
45 return
46 dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
47 dateString = datetime.datetime.strftime(now, dateFormat)
48
49 presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \
50 self.lastDateString != dateString
51 presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime')
52 # no changed value to announce
53 if not (presentDate or presentTime):
54 return
55 timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat')
56 timeString = datetime.datetime.strftime(now, timeFormat)
57
58 if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'interrupt'):
59 self.env['runtime']['outputManager'].interruptOutput()
60 if self.env['runtime']['settingsManager'].getSettingAsBool('time', 'announce'):
61 self.env['runtime']['outputManager'].playSoundIcon('announce')
62
63 if presentTime:
64 # present the time
65 self.env['runtime']['outputManager'].presentText('Autotime: ' + timeString , soundIcon='', interrupt=False)
66 # and date if changes
67 if presentDate:
68 self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=False)
69 self.lastDateString = dateString
70 self.lastTime = datetime.datetime.now()
71 self.lastTimeString = timeString
72 def setCallback(self, callback):
73 pass
+0
-31
src/fenrir/commands/onSwitchApplicationProfile/agetty.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('agetty')
20 print('load new',self.env['screenData']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('agetty')
26 print('unload old',self.env['screenData']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
+0
-31
src/fenrir/commands/onSwitchApplicationProfile/bash.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('bash')
20 print('load new',self.env['screenData']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('bash')
26 print('unload old',self.env['screenData']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
1515 def getDescription(self):
1616 return 'No description found'
1717 def load(self):
18 return
1819 print('--------------')
1920 print('default')
20 print('load new',self.env['screenData']['newApplication'])
21 print('load new',self.env['screen']['newApplication'])
2122 print('--------------')
2223
2324 def unload(self):
25 return
2426 print('--------------')
2527 print('default')
26 print('unload old',self.env['screenData']['oldApplication'])
28 print('unload old',self.env['screen']['oldApplication'])
2729 print('--------------')
2830
2931 def setCallback(self, callback):
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('agetty')
20 print('load new',self.env['screen']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('agetty')
26 print('unload old',self.env['screen']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('bash')
20 print('load new',self.env['screen']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('bash')
26 print('unload old',self.env['screen']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('vim')
20 print('load new',self.env['screen']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('vim')
26 print('unload old',self.env['screen']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
+0
-31
src/fenrir/commands/onSwitchApplicationProfile/vim.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class command():
9 def __init__(self):
10 pass
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 pass
15 def getDescription(self):
16 return 'No description found'
17 def load(self):
18 print('--------------')
19 print('vim')
20 print('load new',self.env['screenData']['newApplication'])
21 print('--------------')
22
23 def unload(self):
24 print('--------------')
25 print('vim')
26 print('unload old',self.env['screenData']['oldApplication'])
27 print('--------------')
28
29 def setCallback(self, callback):
30 pass
1313 def shutdown(self):
1414 pass
1515 def getCurrentApplication(self):
16 currApp = self.env['screenData']['newApplication'].upper()
16 currApp = self.env['screen']['newApplication'].upper()
1717 if not currApp:
1818 currApp == 'DEFAULT'
1919 if currApp == '':
2020 currApp == 'DEFAULT'
2121 return currApp
2222 def getPrevApplication(self):
23 prevApp = self.env['screenData']['oldApplication'].upper()
23 prevApp = self.env['screen']['oldApplication'].upper()
2424 if not prevApp:
2525 prevApp == 'DEFAULT'
2626 if prevApp == '':
2727 prevApp == 'DEFAULT'
2828 return prevApp
2929 def isApplicationChange(self):
30 return self.env['screenData']['oldApplication'] != self.env['screenData']['newApplication']
30 return self.env['screen']['oldApplication'] != self.env['screen']['newApplication']
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time
8
9 # used as shared memory between commands
10 # use this in your own commands
11 commandBuffer = {
12 'enableSpeechOnKeypress': False,
13 'genericList':[],
14 'genericListSource':'',
15 'genericListSelection': 0,
16 'clipboard':[],
17 'currClipboard': 0,
18 'Marks':{'1':None, '2':None},
19 'bookMarks':{},
20 'windowArea':{},
21 }
22
23 # used by the commandManager
24 commandInfo = {
25 #'currCommand': '',
26 'lastCommandExecutionTime': time.time(),
27 'lastCommandRequestTime': time.time(),
28 }
33 # Fenrir TTY screen reader
44 # By Chrys, Storm Dragon, and contributers.
55
6 import importlib.util
7 import glob, os, time
8 import __main__
6 import glob, os, time, inspect
7 currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
8 fenrirPath = os.path.dirname(currentdir)
9
910 from core import debug
11 from utils import module_utils
1012
1113 class commandManager():
1214 def __init__(self):
1315 pass
1416 def initialize(self, environment):
1517 self.env = environment
16 self.env['runtime']['commandManager'].loadCommands('commands')
17 self.env['runtime']['commandManager'].loadCommands('onInput')
18 self.env['runtime']['commandManager'].loadCommands('onScreenUpdate')
19 self.env['runtime']['commandManager'].loadCommands('onScreenChanged')
20 self.env['runtime']['commandManager'].loadCommands('onApplicationChange')
21 self.env['runtime']['commandManager'].loadCommands('onSwitchApplicationProfile')
18 # commands
19 self.env['commands'] = {}
20 self.env['commandsIgnore'] = {}
21 for commandFolder in self.env['general']['commandFolderList']:
22 self.env['runtime']['commandManager'].loadCommands(commandFolder)
23 if self.env['runtime']['settingsManager'].getSetting('general', 'commandPath') != '':
24 self.env['runtime']['commandManager'].loadCommands(commandFolder,
25 self.env['runtime']['settingsManager'].getSetting('general', 'commandPath'))
26
27 # scripts for scriptKey
2228 self.env['runtime']['commandManager'].loadScriptCommands()
29
2330 def shutdown(self):
24 self.env['runtime']['commandManager'].shutdownCommands('commands')
25 self.env['runtime']['commandManager'].shutdownCommands('onInput')
26 self.env['runtime']['commandManager'].shutdownCommands('onScreenUpdate')
27 self.env['runtime']['commandManager'].shutdownCommands('onScreenChanged')
28 self.env['runtime']['commandManager'].shutdownCommands('onApplicationChange')
29 self.env['runtime']['commandManager'].shutdownCommands('onSwitchApplicationProfile')
31 for commandFolder in self.env['general']['commandFolderList']:
32 self.env['runtime']['commandManager'].shutdownCommands(commandFolder)
3033
31 def loadCommands(self, section='commands'):
32 commandFolder = os.path.dirname(os.path.realpath(__main__.__file__)) + "/commands/" + section +"/"
34 def loadCommands(self, section='commands',commandPath=''):
35 if commandPath =='':
36 commandPath = fenrirPath+ "/commands/"
37 if not commandPath.endswith('/'):
38 commandPath += '/'
39 commandFolder = commandPath + section +"/"
40 if not os.path.exists(commandFolder):
41 self.env['runtime']['debug'].writeDebugOut("commandFolder not exists:" + commandFolder ,debug.debugLevel.WARNING)
42 return
43 if not os.path.isdir(commandFolder):
44 self.env['runtime']['debug'].writeDebugOut("commandFolder not a directory:" + commandFolder ,debug.debugLevel.ERROR)
45 return
46 if not os.access(commandFolder, os.R_OK):
47 self.env['runtime']['debug'].writeDebugOut("commandFolder not readable:" + commandFolder ,debug.debugLevel.ERROR)
48 return
49 self.env['commands'][section] = {}
50 self.env['commandsIgnore'][section] = {}
3351 commandList = glob.glob(commandFolder+'*')
3452 for command in commandList:
3553 try:
3755 fileName = fileName.split('/')[-1]
3856 if fileName.startswith('__'):
3957 continue
58 try:
59 if self.env['commands'][section][fileName.upper()] != None:
60 continue
61 except:
62 pass
4063 if fileExtension.lower() == '.py':
41 spec = importlib.util.spec_from_file_location(fileName, command)
42 command_mod = importlib.util.module_from_spec(spec)
43 spec.loader.exec_module(command_mod)
64 command_mod = module_utils.importModule(fileName, command)
4465 self.env['commands'][section][fileName.upper()] = command_mod.command()
4566 self.env['commandsIgnore'][section][fileName.upper()[fileName.upper().find('-')+1:]+'_IGNORE'] = False
4667 self.env['commands'][section][fileName.upper()].initialize(self.env)
4768 self.env['runtime']['debug'].writeDebugOut("Load command:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)
4869 except Exception as e:
49 print(e)
5070 self.env['runtime']['debug'].writeDebugOut("Loading command:" + command ,debug.debugLevel.ERROR)
5171 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
5272 continue
5373
54 def loadScriptCommands(self, section='commands'):
55 scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath')
74 def loadScriptCommands(self, section='commands', scriptPath=''):
75 if scriptPath =='':
76 scriptPath = self.env['runtime']['settingsManager'].getSetting('general', 'scriptPath')
5677 if not scriptPath.endswith('/'):
5778 scriptPath += '/'
58 if not os.path.exists(scriptPath) or scriptPath == '/':
59 if os.path.exists(os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/scripts/'):
60 scriptPath = os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/scripts/'
79 if not os.path.exists(scriptPath):
80 if os.path.exists(fenrirPath +'/../../config/scripts/'):
81 scriptPath = fenrirPath +'/../../config/scripts/'
6182 else:
6283 self.env['runtime']['debug'].writeDebugOut("scriptpath not exists:" + scriptPath ,debug.debugLevel.WARNING)
6384 return
6889 self.env['runtime']['debug'].writeDebugOut("scriptpath not readable:" + scriptPath ,debug.debugLevel.ERROR)
6990 return
7091 commandList = glob.glob(scriptPath+'*')
71 subCommand = os.path.dirname(os.path.realpath(__main__.__file__)) + '/commands/commands/subprocess.py'
92 subCommand = fenrirPath + '/commands/commands/subprocess.py'
7293 for command in commandList:
7394 invalid = False
7495 try:
7697 fileName = fileName.split('/')[-1]
7798 if fileName.startswith('__'):
7899 continue
79 spec = importlib.util.spec_from_file_location(fileName ,subCommand)
80 command_mod = importlib.util.module_from_spec(spec)
81 spec.loader.exec_module(command_mod)
100 if fileName.upper() in self.env['commands'][section]:
101 continue
102 command_mod = module_utils.importModule(fileName ,subCommand)
82103 self.env['commands'][section][fileName.upper()] = command_mod.command()
83104 self.env['commands'][section][fileName.upper()].initialize(self.env,command)
84105 self.env['runtime']['debug'].writeDebugOut("Load script:" + section + "." + fileName.upper() ,debug.debugLevel.INFO, onAnyLevel=True)
106127 shortcut.append(sorted(shortcutKeys))
107128 self.env['bindings'][str(shortcut)] = fileName.upper()
108129 except Exception as e:
109 print(e)
110130 self.env['runtime']['debug'].writeDebugOut("Loading script:" + command ,debug.debugLevel.ERROR)
111131 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
112132 continue
142162 self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + newScript ,debug.debugLevel.ERROR)
143163 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
144164
145 def executeDefaultTrigger(self, trigger):
146 if self.env['runtime']['screenManager'].isSuspendingScreen():
147 return
165 def executeDefaultTrigger(self, trigger, force=False):
166 if not force:
167 if self.env['runtime']['screenManager'].isSuspendingScreen():
168 return
148169 for command in sorted(self.env['commands'][trigger]):
149170 if self.commandExists(command, trigger):
150171 try:
155176 self.env['runtime']['debug'].writeDebugOut("Executing trigger.command:" + trigger + "." + command ,debug.debugLevel.INFO)
156177 self.env['commands'][trigger][command].run()
157178 except Exception as e:
158 self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command ,debug.debugLevel.ERROR)
159 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
179 self.env['runtime']['debug'].writeDebugOut("Executing trigger:" + trigger + "." + command + str(e) ,debug.debugLevel.ERROR)
160180
161181 def executeCommand(self, command, section = 'commands'):
162182 if self.env['runtime']['screenManager'].isSuspendingScreen():
163183 return
164184 if self.commandExists(command, section):
165185 try:
166 if self.env['generalInformation']['tutorialMode']:
186 if self.env['runtime']['helpManager'].isTutorialMode() and section != 'help':
167187 self.env['runtime']['debug'].writeDebugOut("Tutorial for command:" + section + "." + command ,debug.debugLevel.INFO)
168 description = self.env['commands'][section][command].getDescription()
188 description = self.getCommandDescription(command, section)
169189 self.env['runtime']['outputManager'].presentText(description, interrupt=True)
170190 else:
171191 self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.INFO)
172 self.env['commands'][section][command].run()
173 except Exception as e:
174 self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command ,debug.debugLevel.ERROR)
175 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
176 self.clearCommandQueued()
192 self.runCommand(command, section)
193 except Exception as e:
194 self.env['runtime']['debug'].writeDebugOut("Executing command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
195
196
197 def runCommand(self, command, section = 'commands'):
198 if self.commandExists(command, section):
199 try:
200 self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command ,debug.debugLevel.INFO)
201 self.env['commands'][section][command].run()
202 except Exception as e:
203 self.env['runtime']['debug'].writeDebugOut("runCommand command:" + section + "." + command +' ' + str(e),debug.debugLevel.ERROR)
177204 self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
178
179 def isCommandQueued(self):
180 return self.env['commandInfo']['currCommand'] != ''
181
182 def clearCommandQueued(self):
183 self.env['commandInfo']['currCommand'] = ''
184205
185 def queueCommand(self, command):
186 if command == '':
187 return
188 self.env['commandInfo']['currCommand'] = command
206 def getCommandDescription(self, command, section = 'commands'):
207 if self.commandExists(command, section):
208 try:
209 return self.env['commands'][section][command].getDescription()
210 except Exception as e:
211 self.env['runtime']['debug'].writeDebugOut('commandManager.getCommandDescription:' + str(e),debug.debugLevel.ERROR)
212 self.env['commandInfo']['lastCommandExecutionTime'] = time.time()
189213
190214 def commandExists(self, command, section = 'commands'):
191 return( command in self.env['commands'][section])
215 return( command in self.env['commands'][section])
216 def getShortcutForCommand(self, command):
217 shortcut = ''
218 try:
219 shortcut = list(self.env['bindings'].keys())[list(self.env['bindings'].values()).index(command)]
220 except:
221 pass
222 return shortcut
+0
-62
src/fenrir/core/commands.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time
8
9
10 # used as shared memory between commands
11 # use this in your own commands
12 commandBuffer = {
13 'enableSpeechOnKeypress': False,
14 'genericList':[],
15 'genericListSource':'',
16 'genericListSelection': 0,
17 'clipboard':[],
18 'currClipboard': 0,
19 'Marks':{'1':None, '2':None},
20 'bookMarks':{},
21 'windowArea':{},
22 }
23
24 # used by the commandManager
25 commandInfo = {
26 'currCommand': '',
27 'lastCommandExecutionTime': time.time(),
28 'lastCommandRequestTime': time.time(),
29 }
30
31 # used by the commandManager
32 commands = {
33 'onInput':{
34 },
35 'onScreenChanged':{
36 },
37 'onScreenUpdate':{
38 },
39 'onApplicationChange':{
40 },
41 'commands':{
42 },
43 'onSwitchApplicationProfile':{
44 },
45 }
46
47 # used by the commandManager
48 commandsIgnore = {
49 'onInput':{
50 },
51 'onScreenChanged':{
52 },
53 'onScreenUpdate':{
54 },
55 'onApplicationChange':{
56 },
57 'commands':{
58 },
59 'onSwitchApplicationProfile':{
60 },
61 }
2525 self.env['commandBuffer']['Marks']['2'] != None
2626 def setMark(self):
2727 currCursor = None
28 if self.env['screenData']['newCursorReview']:
29 currCursor = self.env['screenData']['newCursorReview'].copy()
28 if self.env['screen']['newCursorReview']:
29 currCursor = self.env['screen']['newCursorReview'].copy()
3030 else:
31 currCursor = self.env['screenData']['newCursor'].copy()
31 currCursor = self.env['screen']['newCursor'].copy()
3232 if not self.env['commandBuffer']['Marks']['1']:
3333 self.env['commandBuffer']['Marks']['1'] = currCursor.copy()
3434 return 1
3737 return 2
3838 return 0
3939 def getReviewOrTextCursor(self):
40 if self.env['screenData']['newCursorReview']:
41 return self.env['screenData']['newCursorReview'].copy()
40 if self.env['screen']['newCursorReview']:
41 return self.env['screen']['newCursorReview'].copy()
4242 else:
43 return self.env['screenData']['newCursor'].copy()
43 return self.env['screen']['newCursor'].copy()
4444 def clearReviewCursor(self):
4545 if not self.isReviewMode():
4646 return
47 self.env['screenData']['oldCursorReview'] = None
48 self.env['screenData']['newCursorReview'] = None
47 self.env['screen']['oldCursorReview'] = None
48 self.env['screen']['newCursorReview'] = None
4949
5050 def isCursorHorizontalMove(self):
51 return self.env['screenData']['newCursor']['x'] != self.env['screenData']['oldCursor']['x']
51 return self.env['screen']['newCursor']['x'] != self.env['screen']['oldCursor']['x']
5252
5353 def isCursorVerticalMove(self):
54 return self.env['screenData']['newCursor']['y'] != self.env['screenData']['oldCursor']['y']
54 return self.env['screen']['newCursor']['y'] != self.env['screen']['oldCursor']['y']
5555
5656 def isReviewMode(self):
57 return self.env['screenData']['newCursorReview'] != None
57 return self.env['screen']['newCursorReview'] != None
5858
5959 def enterReviewModeCurrTextCursor(self, overwrite=False):
6060 if self.isReviewMode() and not overwrite:
6161 return
62 self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
63 if not self.env['screenData']['newCursorReview']:
64 self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursor'].copy()
62 self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
63 if not self.env['screen']['newCursorReview']:
64 self.env['screen']['newCursorReview'] = self.env['screen']['newCursor'].copy()
6565 if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight') and \
66 self.env['screenData']['newCursorAttrib'] != None:
67 if self.env['screenData']['newCursorAttrib']['x'] != 0 and \
68 self.env['screenData']['newCursorAttrib']['y'] != 0:
69 self.env['screenData']['newCursorReview'] = self.env['screenData']['newCursorAttrib'].copy()
66 self.env['screen']['newCursorAttrib'] != None:
67 if self.env['screen']['newCursorAttrib']['x'] != 0 and \
68 self.env['screen']['newCursorAttrib']['y'] != 0:
69 self.env['screen']['newCursorReview'] = self.env['screen']['newCursorAttrib'].copy()
7070
7171 def setReviewCursorPosition(self, x, y):
7272 if not self.isReviewMode():
7373 self.enterReviewModeCurrTextCursor()
74 self.env['screenData']['oldCursorReview'] = self.env['screenData']['newCursorReview']
75 self.env['screenData']['newCursorReview']['x'] = x
76 self.env['screenData']['newCursorReview']['y'] = y
74 self.env['screen']['oldCursorReview'] = self.env['screen']['newCursorReview']
75 self.env['screen']['newCursorReview']['x'] = x
76 self.env['screen']['newCursorReview']['y'] = y
7777
7878 def isApplicationWindowSet(self):
7979 try:
00 #!/usr/bin/python
1 # Debugger module for the Fenrir screen reader.
21
32 from enum import Enum
4 from datetime import datetime
53
64 class debugLevel(Enum):
75 DEACTIVE = 0
1210 return self.value
1311 def __str__(self):
1412 return self.name
15
16 class debug():
17 def __init__(self, fileName='/var/log/fenrir.log'):
18 self._fileName = fileName
19 self._file = None
20 self._fileOpened = False
21 def initialize(self, environment):
22 self.env = environment
23 def shutdown(self):
24 self.closeDebugFile()
25 def __del__(self):
26 try:
27 self.shutdown()
28 except:
29 pass
30
31 def openDebugFile(self, fileName = ''):
32 self._fileOpened = False
33 if fileName != '':
34 self._fileName = fileName
35 if self._fileName != '':
36 self._file = open(self._fileName,'a')
37 self._fileOpened = True
38
39 def writeDebugOut(self, text, level = debugLevel.DEACTIVE, onAnyLevel=False):
40 if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \
41 not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debugLevel.DEACTIVE)) :
42 if self._fileOpened:
43 self.closeDebugFile()
44 return
45 else:
46 if not self._fileOpened:
47 self.openDebugFile()
48 if onAnyLevel:
49 msg = 'ANY '+ str(level) + ' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f'))
50 else:
51 msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
52 )
53 msg += ': ' + text
54 print(msg)
55 self._file.write(msg + '\n')
56
57
58 def closeDebugFile(self):
59 if not self._fileOpened:
60 return False
61 if self._file != None:
62 self._file.close()
63 self._fileOpened = False
64 return True
65
66 def getDebugFile(self):
67 return self._fileName
68
69 def setDebugFile(self, fileName):
70 self.closeDebugFile()
71 self._fileName = fileName
0 #!/usr/bin/python
1 # Debugger module for the Fenrir screen reader.
2
3 from core import debug
4 from datetime import datetime
5
6 class debugManager():
7 def __init__(self, fileName='/var/log/fenrir.log'):
8 self._fileName = fileName
9 self._file = None
10 self._fileOpened = False
11 def initialize(self, environment):
12 self.env = environment
13 def shutdown(self):
14 self.closeDebugFile()
15 def __del__(self):
16 try:
17 self.shutdown()
18 except:
19 pass
20
21 def openDebugFile(self, fileName = ''):
22 self._fileOpened = False
23 if fileName != '':
24 self._fileName = fileName
25 if self._fileName != '':
26 self._file = open(self._fileName,'a')
27 self._fileOpened = True
28
29 def writeDebugOut(self, text, level = debug.debugLevel.DEACTIVE, onAnyLevel=False):
30
31 mode = self.env['runtime']['settingsManager'].getSetting('general','debugMode')
32 if mode == '':
33 mode = 'FILE'
34 mode = mode.upper().split(',')
35 fileMode = 'FILE' in mode
36 printMode = 'PRINT' in mode
37
38 if (self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') < int(level)) and \
39 not (onAnyLevel and self.env['runtime']['settingsManager'].getSettingAsInt('general','debugLevel') > int(debug.debugLevel.DEACTIVE)) :
40 if self._fileOpened:
41 self.closeDebugFile()
42 return
43 else:
44 if not self._fileOpened and fileMode:
45 self.openDebugFile()
46 if onAnyLevel:
47 msg = 'ANY '+ str(level) + ' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f'))
48 else:
49 msg = str(level) +' ' + str(datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')
50 )
51 msg += ': ' + text
52 if printMode:
53 print(msg)
54 if fileMode:
55 self._file.write(msg + '\n')
56
57 def closeDebugFile(self):
58 if not self._fileOpened:
59 return False
60 if self._file != None:
61 self._file.close()
62 self._fileOpened = False
63 return True
64
65 def getDebugFile(self):
66 return self._fileName
67
68 def setDebugFile(self, fileName):
69 self.closeDebugFile()
70 self._fileName = fileName
44 # By Chrys, Storm Dragon, and contributers.
55
66 from core import debug
7 from core import settings
8 from core import runtime
9 from core import screenData
10 from core import generalInformation
11 from core import commands
12 from core import inputEvent
13 from core import punctuation
7 from core.settingsData import settingsData
8 from core.runtimeData import runtimeData
9 from core.screenData import screenData
10 from core.outputData import outputData
11 from core.generalData import generalData
12 from core import commandData
13 from core.inputData import inputData
14 from core.punctuationData import punctuationData
1415
1516 environment = {
16 'screenData': screenData.screenData,
17 'runtime': runtime.runtime,
18 'generalInformation': generalInformation.generalInformation,
19 'settings': settings.settings,
20 'commands': commands.commands,
21 'commandsIgnore': commands.commandsIgnore,
22 'commandInfo': commands.commandInfo,
23 'commandBuffer': commands.commandBuffer,
24 'input': inputEvent.input,
25 'punctuation': punctuation.punctuation,
17 'screen': screenData,
18 'runtime': runtimeData,
19 'general': generalData,
20 'settings': settingsData,
21 'commandInfo': commandData.commandInfo,
22 'commandBuffer': commandData.commandBuffer,
23 'input': inputData,
24 'punctuation': punctuationData,
25 'output': outputData,
2626 'soundIcons': {},
2727 'bindings': {},
2828 }
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from enum import Enum
8
9 class fenrirEventType(Enum):
10 Ignore = 0
11 StopMainLoop = 1
12 ScreenUpdate = 2
13 KeyboardInput = 3
14 BrailleInput = 4
15 PlugInputDevice = 5
16 BrailleFlush = 6
17 ScreenChanged = 7
18 HeartBeat = 8 # for time based scheduling
19 ExecuteCommand = 9
20 def __int__(self):
21 return self.value
22 def __str__(self):
23 return self.name
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from core.eventData import fenrirEventType
8 from queue import Empty
9 import time
10 from multiprocessing import Queue
11 from multiprocessing.sharedctypes import Value
12 from ctypes import c_bool
13
14 class eventManager():
15 def __init__(self):
16 self.running = Value(c_bool, True)
17 self._eventQueue = Queue() # multiprocessing.Queue()
18 self.cleanEventQueue()
19 def initialize(self, environment):
20 self.env = environment
21 def shutdown(self):
22 self.cleanEventQueue()
23
24 def proceedEventLoop(self):
25 event = self._eventQueue.get()
26 st = time.time()
27 self.eventDispatcher(event)
28 #print('NET loop ' + str(time.time() - st))
29 def eventDispatcher(self, event):
30 self.env['runtime']['debug'].writeDebugOut('eventManager:eventDispatcher:start: event:' + str(event['Type']) + ' QueueSize:' + str( self._eventQueue.qsize()),debug.debugLevel.INFO)
31 if not event:
32 return
33 if not event['Type']:
34 return
35 if event['Type'] == fenrirEventType.Ignore:
36 return
37 elif event['Type'] == fenrirEventType.StopMainLoop:
38 self.handleStopMainLoop(event)
39 elif event['Type'] == fenrirEventType.ScreenUpdate:
40 self.env['runtime']['fenrirManager'].handleScreenUpdate(event)
41 elif event['Type'] == fenrirEventType.KeyboardInput:
42 self.env['runtime']['fenrirManager'].handleInput(event)
43 elif event['Type'] == fenrirEventType.BrailleInput:
44 pass
45 elif event['Type'] == fenrirEventType.PlugInputDevice:
46 self.env['runtime']['fenrirManager'].handlePlugInputDevice(event)
47 pass
48 elif event['Type'] == fenrirEventType.BrailleFlush:
49 pass
50 elif event['Type'] == fenrirEventType.ScreenChanged:
51 self.env['runtime']['fenrirManager'].handleScreenChange(event)
52 elif event['Type'] == fenrirEventType.HeartBeat:
53 self.env['runtime']['fenrirManager'].handleHeartBeat(event)
54 elif event['Type'] == fenrirEventType.ExecuteCommand:
55 self.env['runtime']['fenrirManager'].handleExecuteCommand(event)
56 def isMainEventLoopRunning(self):
57 return self.running.value == 1
58 def startMainEventLoop(self):
59 self.running.value = 1
60 while( self.isMainEventLoopRunning()):
61 self.proceedEventLoop()
62
63 def handleStopMainLoop(self, event):
64 self.running.value = 0
65 time.sleep(0.1)
66 def stopMainEventLoop(self):
67 self._eventQueue.put({"Type":fenrirEventType.StopMainLoop,"Data":None})
68 def cleanEventQueue(self):
69 if self._eventQueue.empty():
70 return
71 try:
72 while True:
73 self._eventQueue.get_nowait()
74 except Empty:
75 pass
76 def getEventQueue(self):
77 return self._eventQueue
78 def getRunning(self):
79 return self.running
80 def putToEventQueue(self,event, data):
81 if not isinstance(event, fenrirEventType):
82 return False
83 self._eventQueue.put({"Type":event,"Data":data})
84 return True
0 #!/bin/env python3
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import os, sys, signal, time
7
8 from core import i18n
9 from core import settingsManager
10 from core import debug
11 from core.eventData import fenrirEventType
12 import argparse
13
14 class fenrirManager():
15 def __init__(self):
16 self.initialized = False
17 cliArgs = self.handleArgs()
18 if not cliArgs:
19 return
20 try:
21 self.environment = settingsManager.settingsManager().initFenrirConfig(cliArgs, self)
22 if not self.environment:
23 raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
24 except RuntimeError:
25 raise
26 self.environment['runtime']['outputManager'].presentText(_("Start Fenrir"), soundIcon='ScreenReaderOn', interrupt=True)
27 signal.signal(signal.SIGINT, self.captureSignal)
28 signal.signal(signal.SIGTERM, self.captureSignal)
29 self.initialized = True
30 self.modifierInput = False
31 self.singleKeyCommand = False
32 self.command = ''
33 def handleArgs(self):
34 args = None
35 parser = argparse.ArgumentParser(description="Fenrir Help")
36 parser.add_argument('-s', '--setting', metavar='SETTING-FILE', default='/etc/fenrir/settings/settings.conf', help='Use a specified settingsfile')
37 parser.add_argument('-o', '--options', metavar='SECTION#SETTING=VALUE,..', default='', help='Overwrite options in given settings file')
38 parser.add_argument('-d', '--debug', action='store_true', help='Turns on Debugmode')
39 parser.add_argument('-p', '--print', action='store_true', help='Print debug messages on screen')
40 try:
41 args = parser.parse_args()
42 except Exception as e:
43 parser.print_help()
44 return args
45 def proceed(self):
46 if not self.initialized:
47 return
48 self.environment['runtime']['eventManager'].startMainEventLoop()
49 self.shutdown()
50 def handleInput(self, event):
51 #startTime = time.time()
52 eventReceived = self.environment['runtime']['inputManager'].getInputEvent()
53 if self.environment['runtime']['inputManager'].noKeyPressed():
54 self.environment['runtime']['inputManager'].clearLastDeepInput()
55 if eventReceived:
56
57 if self.environment['runtime']['screenManager'].isSuspendingScreen():
58 self.environment['runtime']['inputManager'].writeEventBuffer()
59 else:
60 if self.environment['runtime']['helpManager'].isTutorialMode():
61 self.environment['runtime']['inputManager'].clearEventBuffer()
62
63 self.detectCommand()
64
65 if self.modifierInput:
66 self.environment['runtime']['inputManager'].clearEventBuffer()
67 if self.singleKeyCommand:
68 if self.environment['runtime']['inputManager'].noKeyPressed():
69 self.environment['runtime']['inputManager'].clearEventBuffer()
70 else:
71 self.environment['runtime']['inputManager'].writeEventBuffer()
72 if self.environment['runtime']['inputManager'].noKeyPressed():
73 self.modifierInput = False
74 self.singleKeyCommand = False
75 if self.environment['input']['keyForeward'] > 0:
76 self.environment['input']['keyForeward'] -=1
77 self.environment['runtime']['screenManager'].update('onInput')
78 self.environment['runtime']['commandManager'].executeDefaultTrigger('onInput')
79 #print('handleInput:',time.time() - startTime)
80 def handleExecuteCommand(self, event):
81 if event['Data'] == '':
82 return
83 command = event['Data']
84 if self.environment['runtime']['helpManager'].isTutorialMode():
85 if self.environment['runtime']['commandManager'].commandExists( command, 'help'):
86 self.environment['runtime']['commandManager'].executeCommand( command, 'help')
87 return
88 self.environment['runtime']['commandManager'].executeCommand( command, 'commands')
89 def handleScreenChange(self, event):
90 self.environment['runtime']['screenManager'].update('onScreenChange')
91 '''
92 if self.environment['runtime']['applicationManager'].isApplicationChange():
93 self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
94 self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
95 self.environment['runtime']['applicationManager'].getPrevApplication(), \
96 self.environment['runtime']['applicationManager'].getCurrentApplication())
97 '''
98 self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
99 self.environment['runtime']['screenManager'].update('onScreenChange')
100 def handleScreenUpdate(self, event):
101 #startTime = time.time()
102 self.environment['runtime']['screenManager'].update('onUpdate')
103 '''
104 if self.environment['runtime']['applicationManager'].isApplicationChange():
105 self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
106 self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
107 self.environment['runtime']['applicationManager'].getPrevApplication(), \
108 self.environment['runtime']['applicationManager'].getCurrentApplication())
109 '''
110 # timout for the last keypress
111 if time.time() - self.environment['runtime']['inputManager'].getLastInputTime() >= 0.3:
112 self.environment['runtime']['inputManager'].clearLastDeepInput()
113 # has cursor changed?
114 if self.environment['runtime']['cursorManager'].isCursorVerticalMove() or \
115 self.environment['runtime']['cursorManager'].isCursorHorizontalMove():
116 self.environment['runtime']['commandManager'].executeDefaultTrigger('onCursorChange')
117 self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
118 self.environment['runtime']['inputManager'].clearLastDeepInput()
119 #print('handleScreenUpdate:',time.time() - startTime)
120
121 def handlePlugInputDevice(self, event):
122 self.environment['runtime']['commandManager'].executeDefaultTrigger('onPlugInputDevice', force=True)
123
124 def handleHeartBeat(self, event):
125 self.environment['runtime']['commandManager'].executeDefaultTrigger('onHeartBeat',force=True)
126 #self.environment['runtime']['outputManager'].brailleText(flush=False)
127
128 def detectCommand(self):
129 if self.environment['input']['keyForeward'] > 0:
130 return
131 if self.environment['runtime']['inputManager'].isKeyPress():
132 self.modifierInput = self.environment['runtime']['inputManager'].currKeyIsModifier()
133 else:
134 if not self.environment['runtime']['inputManager'].noKeyPressed():
135 if self.singleKeyCommand:
136 self.singleKeyCommand = len( self.environment['runtime']['inputManager'].getLastDeepestInput() ) == 1
137 # key is already released. we need the old one
138 if not( self.singleKeyCommand and self.environment['runtime']['inputManager'].noKeyPressed()):
139 shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
140 self.command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut)
141 if not self.modifierInput:
142 if self.environment['runtime']['inputManager'].isKeyPress():
143 if self.command != '':
144 self.singleKeyCommand = True
145
146 if not (self.singleKeyCommand or self.modifierInput):
147 return
148
149 # fire event
150 if self.command != '':
151 if self.modifierInput:
152 self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
153 self.command = ''
154 else:
155 if self.singleKeyCommand:
156 if self.environment['runtime']['inputManager'].noKeyPressed():
157 self.environment['runtime']['eventManager'].putToEventQueue(fenrirEventType.ExecuteCommand, self.command)
158 self.command = ''
159 def shutdownRequest(self):
160 try:
161 self.environment['runtime']['eventManager'].stopMainEventLoop()
162 except:
163 pass
164 def captureSignal(self, siginit, frame):
165 self.shutdownRequest()
166
167 def shutdown(self):
168 self.environment['runtime']['eventManager'].stopMainEventLoop()
169 self.environment['runtime']['outputManager'].presentText(_("Quit Fenrir"), soundIcon='ScreenReaderOff', interrupt=True)
170 self.environment['runtime']['eventManager'].cleanEventQueue()
171 time.sleep(1)
172 for currManager in self.environment['general']['managerList']:
173 if self.environment['runtime'][currManager]:
174 self.environment['runtime'][currManager].shutdown()
175 del self.environment['runtime'][currManager]
176
177 self.environment = None
178
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 generalData = {
9 'args': None,
10 'tutorialMode': False,
11 'currUser':'',
12 'prevUser':'',
13 'managerList':['processManager','punctuationManager','cursorManager','applicationManager','commandManager'
14 ,'screenManager','inputManager','outputManager','helpManager','eventManager','debug'],
15 'commandFolderList':['commands','onInput', 'onCursorChange', 'onScreenUpdate','onScreenChanged','onHeartBeat', 'onPlugInputDevice'
16 ,'onApplicationChange','onSwitchApplicationProfile','help',],
17 }
+0
-12
src/fenrir/core/generalInformation.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 generalInformation = {
9 'running': True,
10 'tutorialMode': False,
11 }
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8
9 class helpManager():
10 def __init__(self):
11 self.helpDict = {}
12 self.tutorialListIndex = None
13 def initialize(self, environment):
14 self.env = environment
15 def shutdown(self):
16 pass
17 def toggleTutorialMode(self):
18 self.setTutorialMode(not self.env['general']['tutorialMode'])
19 def setTutorialMode(self, newTutorialMode):
20 self.env['general']['tutorialMode'] = newTutorialMode
21 if newTutorialMode:
22 self.createHelpDict()
23 self.env['bindings'][str([1, ['KEY_ESC']])] = 'TOGGLE_TUTORIAL_MODE'
24 self.env['bindings'][str([1, ['KEY_UP']])] = 'PREV_HELP'
25 self.env['bindings'][str([1, ['KEY_DOWN']])] = 'NEXT_HELP'
26 self.env['bindings'][str([1, ['KEY_SPACE']])] = 'CURR_HELP'
27 else:
28 try:
29 del(self.env['bindings'][str([1, ['KEY_ESC']])])
30 del(self.env['bindings'][str([1, ['KEY_UP']])])
31 del(self.env['bindings'][str([1, ['KEY_DOWN']])])
32 del(self.env['bindings'][str([1, ['KEY_SPACE']])])
33 except:
34 pass
35 def isTutorialMode(self):
36 return self.env['general']['tutorialMode']
37 def getCommandHelpText(self, command, section = 'commands'):
38 commandName = command.lower()
39 commandName = commandName.split('__-__')[0]
40 commandName = commandName.replace('_',' ')
41 commandName = commandName.replace('_',' ')
42 if command == 'TOGGLE_TUTORIAL_MODE':
43 commandDescription = _('toggles the tutorial mode')
44 else:
45 commandDescription = self.env['runtime']['commandManager'].getCommandDescription( command, section = 'commands')
46 if commandDescription == '':
47 commandDescription = 'no Description available'
48 commandShortcut = self.env['runtime']['commandManager'].getShortcutForCommand( command)
49 commandShortcut = commandShortcut.replace('KEY_',' ')
50 commandShortcut = commandShortcut.replace('[','')
51 commandShortcut = commandShortcut.replace(']','')
52 commandShortcut = commandShortcut.replace("'",'')
53 if commandShortcut == '':
54 commandShortcut = 'unbound'
55 helptext = commandName + ', Shortcut ' + commandShortcut + ', Description ' + commandDescription
56 return helptext
57 def createHelpDict(self, section = 'commands'):
58 self.helpDict = {}
59 for command in sorted(self.env['commands'][section].keys()):
60 self.helpDict[len(self.helpDict)] = self.getCommandHelpText(command, section)
61 if len(self.helpDict) > 0:
62 self.tutorialListIndex = 0
63 else:
64 self.tutorialListIndex = None
65 def getHelpForCurrentIndex(self):
66 if self.tutorialListIndex == None:
67 return ''
68 return self.helpDict[self.tutorialListIndex]
69 def nextIndex(self):
70 if self.tutorialListIndex == None:
71 return
72 self.tutorialListIndex += 1
73 if self.tutorialListIndex >= len(self.helpDict):
74 self.tutorialListIndex = 0
75 def prevIndex(self):
76 if self.tutorialListIndex == None:
77 return
78 self.tutorialListIndex -= 1
79 if self.tutorialListIndex < 0:
80 self.tutorialListIndex = len(self.helpDict) - 1
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import gettext
7 import locale
8
9 # the only function we really need to call here is gettext.install. Python3 has simplified this.
10 gettext.install("fenrir")
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time
8
9 inputData = {
10 'currInput': [],
11 'prevDeepestInput': [],
12 'eventBuffer': [],
13 'shortcutRepeat': 0,
14 'fenrirKey': [],
15 'scriptKey': [],
16 'keyForeward': 0,
17 'lastInputTime':time.time(),
18 'oldNumLock': True,
19 'newNumLock':True,
20 'oldScrollLock': True,
21 'newScrollLock':True,
22 'oldCapsLock':False,
23 'newCapsLock':False
24 }
25
26 inputEvent = {
27 'EventName': '',
28 'EventValue': '',
29 'EventSec': 0,
30 'EventUsec': 0,
31 'EventState': 0,
32 }
33
34 keyNames = ['KEY_RESERVED', 'KEY_ESC', 'KEY_1', 'KEY_2', 'KEY_3', 'KEY_4', 'KEY_5', 'KEY_6', 'KEY_7', 'KEY_8', 'KEY_9', 'KEY_0', 'KEY_MINUS', 'KEY_EQUAL', 'KEY_BACKSPACE', 'KEY_TAB', 'KEY_Q', 'KEY_W', 'KEY_E', 'KEY_R', 'KEY_T', 'KEY_Y', 'KEY_U', 'KEY_I', 'KEY_O', 'KEY_P', 'KEY_LEFTBRACE', 'KEY_RIGHTBRACE', 'KEY_ENTER', 'KEY_LEFTCTRL', 'KEY_A', 'KEY_S', 'KEY_D', 'KEY_F', 'KEY_G', 'KEY_H', 'KEY_J', 'KEY_K', 'KEY_L', 'KEY_SEMICOLON', 'KEY_APOSTROPHE', 'KEY_GRAVE', 'KEY_LEFTSHIFT', 'KEY_BACKSLASH', 'KEY_Z', 'KEY_X', 'KEY_C', 'KEY_V', 'KEY_B', 'KEY_N', 'KEY_M', 'KEY_COMMA', 'KEY_DOT', 'KEY_SLASH', 'KEY_RIGHTSHIFT', 'KEY_KPASTERISK', 'KEY_LEFTALT', 'KEY_SPACE', 'KEY_CAPSLOCK', 'KEY_F1', 'KEY_F2', 'KEY_F3', 'KEY_F4', 'KEY_F5', 'KEY_F6', 'KEY_F7', 'KEY_F8', 'KEY_F9', 'KEY_F10', 'KEY_NUMLOCK', 'KEY_SCROLLLOCK', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9', 'KEY_KPMINUS', 'KEY_KP4', 'KEY_KP5', 'KEY_KP6', 'KEY_KPPLUS', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP0', 'KEY_KPDOT', 'KEY_ZENKAKUHANKAKU', 'KEY_102ND', 'KEY_F11', 'KEY_F12', 'KEY_RO', 'KEY_KATAKANA', 'KEY_HIRAGANA', 'KEY_HENKAN', 'KEY_KATAKANAHIRAGANA', 'KEY_MUHENKAN', 'KEY_KPJPCOMMA', 'KEY_KPENTER', 'KEY_RIGHTCTRL', 'KEY_KPSLASH', 'KEY_SYSRQ', 'KEY_RIGHTALT', 'KEY_LINEFEED', 'KEY_HOME', 'KEY_UP', 'KEY_PAGEUP', 'KEY_LEFT', 'KEY_RIGHT', 'KEY_END', 'KEY_DOWN', 'KEY_PAGEDOWN', 'KEY_INSERT', 'KEY_DELETE', 'KEY_MACRO', 'KEY_MIN_INTERESTING', 'KEY_MUTE', 'KEY_VOLUMEDOWN', 'KEY_VOLUMEUP', 'KEY_POWER', 'KEY_KPEQUAL', 'KEY_KPPLUSMINUS', 'KEY_PAUSE', 'KEY_SCALE', 'KEY_KPCOMMA', 'KEY_HANGEUL', 'KEY_HANGUEL', 'KEY_HANJA', 'KEY_YEN', 'KEY_LEFTMETA', 'KEY_RIGHTMETA', 'KEY_COMPOSE', 'KEY_STOP', 'KEY_AGAIN', 'KEY_PROPS', 'KEY_UNDO', 'KEY_FRONT', 'KEY_COPY', 'KEY_OPEN', 'KEY_PASTE', 'KEY_FIND', 'KEY_CUT', 'KEY_HELP', 'KEY_MENU', 'KEY_CALC', 'KEY_SETUP', 'KEY_SLEEP', 'KEY_WAKEUP', 'KEY_FILE', 'KEY_SENDFILE', 'KEY_DELETEFILE', 'KEY_XFER', 'KEY_PROG1', 'KEY_PROG2', 'KEY_WWW', 'KEY_MSDOS', 'KEY_COFFEE', 'KEY_SCREENLOCK', 'KEY_DIRECTION', 'KEY_ROTATE_DISPLAY', 'KEY_CYCLEWINDOWS', 'KEY_MAIL', 'KEY_BOOKMARKS', 'KEY_COMPUTER', 'KEY_BACK', 'KEY_FORWARD', 'KEY_CLOSECD', 'KEY_EJECTCD', 'KEY_EJECTCLOSECD', 'KEY_NEXTSONG', 'KEY_PLAYPAUSE', 'KEY_PREVIOUSSONG', 'KEY_STOPCD', 'KEY_RECORD', 'KEY_REWIND', 'KEY_PHONE', 'KEY_ISO', 'KEY_CONFIG', 'KEY_HOMEPAGE', 'KEY_REFRESH', 'KEY_EXIT', 'KEY_MOVE', 'KEY_EDIT', 'KEY_SCROLLUP', 'KEY_SCROLLDOWN', 'KEY_KPLEFTPAREN', 'KEY_KPRIGHTPAREN', 'KEY_NEW', 'KEY_REDO', 'KEY_F13', 'KEY_F14', 'KEY_F15', 'KEY_F16', 'KEY_F17', 'KEY_F18', 'KEY_F19', 'KEY_F20', 'KEY_F21', 'KEY_F22', 'KEY_F23', 'KEY_F24', 'KEY_PLAYCD', 'KEY_PAUSECD', 'KEY_PROG3', 'KEY_PROG4', 'KEY_DASHBOARD', 'KEY_SUSPEND', 'KEY_CLOSE', 'KEY_PLAY', 'KEY_FASTFORWARD', 'KEY_BASSBOOST', 'KEY_PRINT', 'KEY_HP', 'KEY_CAMERA', 'KEY_SOUND', 'KEY_QUESTION', 'KEY_EMAIL', 'KEY_CHAT', 'KEY_SEARCH', 'KEY_CONNECT', 'KEY_FINANCE', 'KEY_SPORT', 'KEY_SHOP', 'KEY_ALTERASE', 'KEY_CANCEL', 'KEY_BRIGHTNESSDOWN', 'KEY_BRIGHTNESSUP', 'KEY_MEDIA', 'KEY_SWITCHVIDEOMODE', 'KEY_KBDILLUMTOGGLE', 'KEY_KBDILLUMDOWN', 'KEY_KBDILLUMUP', 'KEY_SEND', 'KEY_REPLY', 'KEY_FORWARDMAIL', 'KEY_SAVE', 'KEY_DOCUMENTS', 'KEY_BATTERY', 'KEY_BLUETOOTH', 'KEY_WLAN', 'KEY_UWB', 'KEY_UNKNOWN', 'KEY_VIDEO_NEXT', 'KEY_VIDEO_PREV', 'KEY_BRIGHTNESS_CYCLE', 'KEY_BRIGHTNESS_AUTO', 'KEY_BRIGHTNESS_ZERO', 'KEY_DISPLAY_OFF', 'KEY_WIMAX', 'KEY_WWAN', 'KEY_RFKILL', 'KEY_MICMUTE', 'BTN_0', 'BTN_MISC', 'BTN_1', 'BTN_2', 'BTN_3', 'BTN_4', 'BTN_5', 'BTN_6', 'BTN_7', 'BTN_8', 'BTN_9', 'BTN_LEFT', 'BTN_MOUSE', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_SIDE', 'BTN_EXTRA', 'BTN_FORWARD', 'BTN_BACK', 'BTN_TASK', 'BTN_JOYSTICK', 'BTN_TRIGGER', 'BTN_THUMB', 'BTN_THUMB2', 'BTN_TOP', 'BTN_TOP2', 'BTN_PINKIE', 'BTN_BASE', 'BTN_BASE2', 'BTN_BASE3', 'BTN_BASE4', 'BTN_BASE5', 'BTN_BASE6', 'BTN_DEAD', 'BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH', 'BTN_B', 'BTN_EAST', 'BTN_C', 'BTN_NORTH', 'BTN_X', 'BTN_WEST', 'BTN_Y', 'BTN_Z', 'BTN_TL', 'BTN_TR', 'BTN_TL2', 'BTN_TR2', 'BTN_SELECT', 'BTN_START', 'BTN_MODE', 'BTN_THUMBL', 'BTN_THUMBR', 'BTN_DIGI', 'BTN_TOOL_PEN', 'BTN_TOOL_RUBBER', 'BTN_TOOL_BRUSH', 'BTN_TOOL_PENCIL', 'BTN_TOOL_AIRBRUSH', 'BTN_TOOL_FINGER', 'BTN_TOOL_MOUSE', 'BTN_TOOL_LENS', 'BTN_TOOL_QUINTTAP', 'BTN_TOUCH', 'BTN_STYLUS', 'BTN_STYLUS2', 'BTN_TOOL_DOUBLETAP', 'BTN_TOOL_TRIPLETAP', 'BTN_TOOL_QUADTAP', 'BTN_GEAR_DOWN', 'BTN_WHEEL', 'BTN_GEAR_UP', 'KEY_OK', 'KEY_SELECT', 'KEY_GOTO', 'KEY_CLEAR', 'KEY_POWER2', 'KEY_OPTION', 'KEY_INFO', 'KEY_TIME', 'KEY_VENDOR', 'KEY_ARCHIVE', 'KEY_PROGRAM', 'KEY_CHANNEL', 'KEY_FAVORITES', 'KEY_EPG', 'KEY_PVR', 'KEY_MHP', 'KEY_LANGUAGE', 'KEY_TITLE', 'KEY_SUBTITLE', 'KEY_ANGLE', 'KEY_ZOOM', 'KEY_MODE', 'KEY_KEYBOARD', 'KEY_SCREEN', 'KEY_PC', 'KEY_TV', 'KEY_TV2', 'KEY_VCR', 'KEY_VCR2', 'KEY_SAT', 'KEY_SAT2', 'KEY_CD', 'KEY_TAPE', 'KEY_RADIO', 'KEY_TUNER', 'KEY_PLAYER', 'KEY_TEXT', 'KEY_DVD', 'KEY_AUX', 'KEY_MP3', 'KEY_AUDIO', 'KEY_VIDEO', 'KEY_DIRECTORY', 'KEY_LIST', 'KEY_MEMO', 'KEY_CALENDAR', 'KEY_RED', 'KEY_GREEN', 'KEY_YELLOW', 'KEY_BLUE', 'KEY_CHANNELUP', 'KEY_CHANNELDOWN', 'KEY_FIRST', 'KEY_LAST', 'KEY_AB', 'KEY_NEXT', 'KEY_RESTART', 'KEY_SLOW', 'KEY_SHUFFLE', 'KEY_BREAK', 'KEY_PREVIOUS', 'KEY_DIGITS', 'KEY_TEEN', 'KEY_TWEN', 'KEY_VIDEOPHONE', 'KEY_GAMES', 'KEY_ZOOMIN', 'KEY_ZOOMOUT', 'KEY_ZOOMRESET', 'KEY_WORDPROCESSOR', 'KEY_EDITOR', 'KEY_SPREADSHEET', 'KEY_GRAPHICSEDITOR', 'KEY_PRESENTATION', 'KEY_DATABASE', 'KEY_NEWS', 'KEY_VOICEMAIL', 'KEY_ADDRESSBOOK', 'KEY_MESSENGER', 'KEY_BRIGHTNESS_TOGGLE', 'KEY_DISPLAYTOGGLE', 'KEY_SPELLCHECK', 'KEY_LOGOFF', 'KEY_DOLLAR', 'KEY_EURO', 'KEY_FRAMEBACK', 'KEY_FRAMEFORWARD', 'KEY_CONTEXT_MENU', 'KEY_MEDIA_REPEAT', 'KEY_10CHANNELSUP', 'KEY_10CHANNELSDOWN', 'KEY_IMAGES', 'KEY_DEL_EOL', 'KEY_DEL_EOS', 'KEY_INS_LINE', 'KEY_DEL_LINE', 'KEY_FN', 'KEY_FN_ESC', 'KEY_FN_F1', 'KEY_FN_F2', 'KEY_FN_F3', 'KEY_FN_F4', 'KEY_FN_F5', 'KEY_FN_F6', 'KEY_FN_F7', 'KEY_FN_F8', 'KEY_FN_F9', 'KEY_FN_F10', 'KEY_FN_F11', 'KEY_FN_F12', 'KEY_FN_1', 'KEY_FN_2', 'KEY_FN_D', 'KEY_FN_E', 'KEY_FN_F', 'KEY_FN_S', 'KEY_FN_B', 'KEY_BRL_DOT1', 'KEY_BRL_DOT2', 'KEY_BRL_DOT3', 'KEY_BRL_DOT4', 'KEY_BRL_DOT5', 'KEY_BRL_DOT6', 'KEY_BRL_DOT7', 'KEY_BRL_DOT8', 'KEY_BRL_DOT9', 'KEY_BRL_DOT10', 'KEY_NUMERIC_0', 'KEY_NUMERIC_1', 'KEY_NUMERIC_2', 'KEY_NUMERIC_3', 'KEY_NUMERIC_4', 'KEY_NUMERIC_5', 'KEY_NUMERIC_6', 'KEY_NUMERIC_7', 'KEY_NUMERIC_8', 'KEY_NUMERIC_9', 'KEY_NUMERIC_STAR', 'KEY_NUMERIC_POUND', 'KEY_NUMERIC_A', 'KEY_NUMERIC_B', 'KEY_NUMERIC_C', 'KEY_NUMERIC_D', 'KEY_CAMERA_FOCUS', 'KEY_WPS_BUTTON', 'KEY_TOUCHPAD_TOGGLE', 'KEY_TOUCHPAD_ON', 'KEY_TOUCHPAD_OFF', 'KEY_CAMERA_ZOOMIN', 'KEY_CAMERA_ZOOMOUT', 'KEY_CAMERA_UP', 'KEY_CAMERA_DOWN', 'KEY_CAMERA_LEFT', 'KEY_CAMERA_RIGHT', 'KEY_ATTENDANT_ON', 'KEY_ATTENDANT_OFF', 'KEY_ATTENDANT_TOGGLE', 'KEY_LIGHTS_TOGGLE', 'BTN_DPAD_UP', 'BTN_DPAD_DOWN', 'BTN_DPAD_LEFT', 'BTN_DPAD_RIGHT', 'KEY_ALS_TOGGLE', 'KEY_BUTTONCONFIG', 'KEY_TASKMANAGER', 'KEY_JOURNAL', 'KEY_CONTROLPANEL', 'KEY_APPSELECT', 'KEY_SCREENSAVER', 'KEY_VOICECOMMAND', 'KEY_BRIGHTNESS_MIN', 'KEY_BRIGHTNESS_MAX', 'KEY_KBDINPUTASSIST_PREV', 'KEY_KBDINPUTASSIST_NEXT', 'KEY_KBDINPUTASSIST_PREVGROUP', 'KEY_KBDINPUTASSIST_NEXTGROUP', 'KEY_KBDINPUTASSIST_ACCEPT', 'KEY_KBDINPUTASSIST_CANCEL', 'KEY_RIGHT_UP', 'KEY_RIGHT_DOWN', 'KEY_LEFT_UP', 'KEY_LEFT_DOWN', 'KEY_ROOT_MENU', 'KEY_MEDIA_TOP_MENU', 'KEY_NUMERIC_11', 'KEY_NUMERIC_12', 'KEY_AUDIO_DESC', 'KEY_3D_MODE', 'KEY_NEXT_FAVORITE', 'KEY_STOP_RECORD', 'KEY_PAUSE_RECORD', 'KEY_VOD', 'KEY_UNMUTE', 'KEY_DATA', 'KEY_FASTREVERSE', 'KEY_SLOWREVERSE', 'BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1', 'BTN_TRIGGER_HAPPY2', 'BTN_TRIGGER_HAPPY3', 'BTN_TRIGGER_HAPPY4', 'BTN_TRIGGER_HAPPY5', 'BTN_TRIGGER_HAPPY6', 'BTN_TRIGGER_HAPPY7', 'BTN_TRIGGER_HAPPY8', 'BTN_TRIGGER_HAPPY9', 'BTN_TRIGGER_HAPPY10', 'BTN_TRIGGER_HAPPY11', 'BTN_TRIGGER_HAPPY12', 'BTN_TRIGGER_HAPPY13', 'BTN_TRIGGER_HAPPY14', 'BTN_TRIGGER_HAPPY15', 'BTN_TRIGGER_HAPPY16', 'BTN_TRIGGER_HAPPY17', 'BTN_TRIGGER_HAPPY18', 'BTN_TRIGGER_HAPPY19', 'BTN_TRIGGER_HAPPY20', 'BTN_TRIGGER_HAPPY21', 'BTN_TRIGGER_HAPPY22', 'BTN_TRIGGER_HAPPY23', 'BTN_TRIGGER_HAPPY24', 'BTN_TRIGGER_HAPPY25', 'BTN_TRIGGER_HAPPY26', 'BTN_TRIGGER_HAPPY27', 'BTN_TRIGGER_HAPPY28', 'BTN_TRIGGER_HAPPY29', 'BTN_TRIGGER_HAPPY30', 'BTN_TRIGGER_HAPPY31', 'BTN_TRIGGER_HAPPY32', 'BTN_TRIGGER_HAPPY33', 'BTN_TRIGGER_HAPPY34', 'BTN_TRIGGER_HAPPY35', 'BTN_TRIGGER_HAPPY36', 'BTN_TRIGGER_HAPPY37', 'BTN_TRIGGER_HAPPY38', 'BTN_TRIGGER_HAPPY39', 'BTN_TRIGGER_HAPPY40', 'KEY_FENRIR', 'KEY_SCRIPT', 'KEY_ALT', 'KEY_CTRL', 'KEY_META', 'KEY_SHIFT']
35
+0
-37
src/fenrir/core/inputEvent.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time
8
9 input = {
10 'currInput': [],
11 'prevDeepestInput': [],
12 'eventBuffer': [],
13 'shortcutRepeat': 0,
14 'fenrirKey': [],
15 'scriptKey': [],
16 'keyForeward': 0,
17 'lastInputTime':time.time(),
18 'oldNumLock': True,
19 'newNumLock':True,
20 'oldScrollLock': True,
21 'newScrollLock':True,
22 'oldCapsLock':False,
23 'newCapsLock':False
24 }
25
26 inputEvent = {
27 'EventName': '',
28 'EventValue': '',
29 'EventSec': 0,
30 'EventUsec': 0,
31 'EventState': 0,
32 }
33
34
35 keyNames = ['KEY_RESERVED', 'KEY_ESC', 'KEY_1', 'KEY_2', 'KEY_3', 'KEY_4', 'KEY_5', 'KEY_6', 'KEY_7', 'KEY_8', 'KEY_9', 'KEY_0', 'KEY_MINUS', 'KEY_EQUAL', 'KEY_BACKSPACE', 'KEY_TAB', 'KEY_Q', 'KEY_W', 'KEY_E', 'KEY_R', 'KEY_T', 'KEY_Y', 'KEY_U', 'KEY_I', 'KEY_O', 'KEY_P', 'KEY_LEFTBRACE', 'KEY_RIGHTBRACE', 'KEY_ENTER', 'KEY_LEFTCTRL', 'KEY_A', 'KEY_S', 'KEY_D', 'KEY_F', 'KEY_G', 'KEY_H', 'KEY_J', 'KEY_K', 'KEY_L', 'KEY_SEMICOLON', 'KEY_APOSTROPHE', 'KEY_GRAVE', 'KEY_LEFTSHIFT', 'KEY_BACKSLASH', 'KEY_Z', 'KEY_X', 'KEY_C', 'KEY_V', 'KEY_B', 'KEY_N', 'KEY_M', 'KEY_COMMA', 'KEY_DOT', 'KEY_SLASH', 'KEY_RIGHTSHIFT', 'KEY_KPASTERISK', 'KEY_LEFTALT', 'KEY_SPACE', 'KEY_CAPSLOCK', 'KEY_F1', 'KEY_F2', 'KEY_F3', 'KEY_F4', 'KEY_F5', 'KEY_F6', 'KEY_F7', 'KEY_F8', 'KEY_F9', 'KEY_F10', 'KEY_NUMLOCK', 'KEY_SCROLLLOCK', 'KEY_KP7', 'KEY_KP8', 'KEY_KP9', 'KEY_KPMINUS', 'KEY_KP4', 'KEY_KP5', 'KEY_KP6', 'KEY_KPPLUS', 'KEY_KP1', 'KEY_KP2', 'KEY_KP3', 'KEY_KP0', 'KEY_KPDOT', 'KEY_ZENKAKUHANKAKU', 'KEY_102ND', 'KEY_F11', 'KEY_F12', 'KEY_RO', 'KEY_KATAKANA', 'KEY_HIRAGANA', 'KEY_HENKAN', 'KEY_KATAKANAHIRAGANA', 'KEY_MUHENKAN', 'KEY_KPJPCOMMA', 'KEY_KPENTER', 'KEY_RIGHTCTRL', 'KEY_KPSLASH', 'KEY_SYSRQ', 'KEY_RIGHTALT', 'KEY_LINEFEED', 'KEY_HOME', 'KEY_UP', 'KEY_PAGEUP', 'KEY_LEFT', 'KEY_RIGHT', 'KEY_END', 'KEY_DOWN', 'KEY_PAGEDOWN', 'KEY_INSERT', 'KEY_DELETE', 'KEY_MACRO', 'KEY_MIN_INTERESTING', 'KEY_MUTE', 'KEY_VOLUMEDOWN', 'KEY_VOLUMEUP', 'KEY_POWER', 'KEY_KPEQUAL', 'KEY_KPPLUSMINUS', 'KEY_PAUSE', 'KEY_SCALE', 'KEY_KPCOMMA', 'KEY_HANGEUL', 'KEY_HANGUEL', 'KEY_HANJA', 'KEY_YEN', 'KEY_LEFTMETA', 'KEY_RIGHTMETA', 'KEY_COMPOSE', 'KEY_STOP', 'KEY_AGAIN', 'KEY_PROPS', 'KEY_UNDO', 'KEY_FRONT', 'KEY_COPY', 'KEY_OPEN', 'KEY_PASTE', 'KEY_FIND', 'KEY_CUT', 'KEY_HELP', 'KEY_MENU', 'KEY_CALC', 'KEY_SETUP', 'KEY_SLEEP', 'KEY_WAKEUP', 'KEY_FILE', 'KEY_SENDFILE', 'KEY_DELETEFILE', 'KEY_XFER', 'KEY_PROG1', 'KEY_PROG2', 'KEY_WWW', 'KEY_MSDOS', 'KEY_COFFEE', 'KEY_SCREENLOCK', 'KEY_DIRECTION', 'KEY_ROTATE_DISPLAY', 'KEY_CYCLEWINDOWS', 'KEY_MAIL', 'KEY_BOOKMARKS', 'KEY_COMPUTER', 'KEY_BACK', 'KEY_FORWARD', 'KEY_CLOSECD', 'KEY_EJECTCD', 'KEY_EJECTCLOSECD', 'KEY_NEXTSONG', 'KEY_PLAYPAUSE', 'KEY_PREVIOUSSONG', 'KEY_STOPCD', 'KEY_RECORD', 'KEY_REWIND', 'KEY_PHONE', 'KEY_ISO', 'KEY_CONFIG', 'KEY_HOMEPAGE', 'KEY_REFRESH', 'KEY_EXIT', 'KEY_MOVE', 'KEY_EDIT', 'KEY_SCROLLUP', 'KEY_SCROLLDOWN', 'KEY_KPLEFTPAREN', 'KEY_KPRIGHTPAREN', 'KEY_NEW', 'KEY_REDO', 'KEY_F13', 'KEY_F14', 'KEY_F15', 'KEY_F16', 'KEY_F17', 'KEY_F18', 'KEY_F19', 'KEY_F20', 'KEY_F21', 'KEY_F22', 'KEY_F23', 'KEY_F24', 'KEY_PLAYCD', 'KEY_PAUSECD', 'KEY_PROG3', 'KEY_PROG4', 'KEY_DASHBOARD', 'KEY_SUSPEND', 'KEY_CLOSE', 'KEY_PLAY', 'KEY_FASTFORWARD', 'KEY_BASSBOOST', 'KEY_PRINT', 'KEY_HP', 'KEY_CAMERA', 'KEY_SOUND', 'KEY_QUESTION', 'KEY_EMAIL', 'KEY_CHAT', 'KEY_SEARCH', 'KEY_CONNECT', 'KEY_FINANCE', 'KEY_SPORT', 'KEY_SHOP', 'KEY_ALTERASE', 'KEY_CANCEL', 'KEY_BRIGHTNESSDOWN', 'KEY_BRIGHTNESSUP', 'KEY_MEDIA', 'KEY_SWITCHVIDEOMODE', 'KEY_KBDILLUMTOGGLE', 'KEY_KBDILLUMDOWN', 'KEY_KBDILLUMUP', 'KEY_SEND', 'KEY_REPLY', 'KEY_FORWARDMAIL', 'KEY_SAVE', 'KEY_DOCUMENTS', 'KEY_BATTERY', 'KEY_BLUETOOTH', 'KEY_WLAN', 'KEY_UWB', 'KEY_UNKNOWN', 'KEY_VIDEO_NEXT', 'KEY_VIDEO_PREV', 'KEY_BRIGHTNESS_CYCLE', 'KEY_BRIGHTNESS_AUTO', 'KEY_BRIGHTNESS_ZERO', 'KEY_DISPLAY_OFF', 'KEY_WIMAX', 'KEY_WWAN', 'KEY_RFKILL', 'KEY_MICMUTE', 'BTN_0', 'BTN_MISC', 'BTN_1', 'BTN_2', 'BTN_3', 'BTN_4', 'BTN_5', 'BTN_6', 'BTN_7', 'BTN_8', 'BTN_9', 'BTN_LEFT', 'BTN_MOUSE', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_SIDE', 'BTN_EXTRA', 'BTN_FORWARD', 'BTN_BACK', 'BTN_TASK', 'BTN_JOYSTICK', 'BTN_TRIGGER', 'BTN_THUMB', 'BTN_THUMB2', 'BTN_TOP', 'BTN_TOP2', 'BTN_PINKIE', 'BTN_BASE', 'BTN_BASE2', 'BTN_BASE3', 'BTN_BASE4', 'BTN_BASE5', 'BTN_BASE6', 'BTN_DEAD', 'BTN_A', 'BTN_GAMEPAD', 'BTN_SOUTH', 'BTN_B', 'BTN_EAST', 'BTN_C', 'BTN_NORTH', 'BTN_X', 'BTN_WEST', 'BTN_Y', 'BTN_Z', 'BTN_TL', 'BTN_TR', 'BTN_TL2', 'BTN_TR2', 'BTN_SELECT', 'BTN_START', 'BTN_MODE', 'BTN_THUMBL', 'BTN_THUMBR', 'BTN_DIGI', 'BTN_TOOL_PEN', 'BTN_TOOL_RUBBER', 'BTN_TOOL_BRUSH', 'BTN_TOOL_PENCIL', 'BTN_TOOL_AIRBRUSH', 'BTN_TOOL_FINGER', 'BTN_TOOL_MOUSE', 'BTN_TOOL_LENS', 'BTN_TOOL_QUINTTAP', 'BTN_TOUCH', 'BTN_STYLUS', 'BTN_STYLUS2', 'BTN_TOOL_DOUBLETAP', 'BTN_TOOL_TRIPLETAP', 'BTN_TOOL_QUADTAP', 'BTN_GEAR_DOWN', 'BTN_WHEEL', 'BTN_GEAR_UP', 'KEY_OK', 'KEY_SELECT', 'KEY_GOTO', 'KEY_CLEAR', 'KEY_POWER2', 'KEY_OPTION', 'KEY_INFO', 'KEY_TIME', 'KEY_VENDOR', 'KEY_ARCHIVE', 'KEY_PROGRAM', 'KEY_CHANNEL', 'KEY_FAVORITES', 'KEY_EPG', 'KEY_PVR', 'KEY_MHP', 'KEY_LANGUAGE', 'KEY_TITLE', 'KEY_SUBTITLE', 'KEY_ANGLE', 'KEY_ZOOM', 'KEY_MODE', 'KEY_KEYBOARD', 'KEY_SCREEN', 'KEY_PC', 'KEY_TV', 'KEY_TV2', 'KEY_VCR', 'KEY_VCR2', 'KEY_SAT', 'KEY_SAT2', 'KEY_CD', 'KEY_TAPE', 'KEY_RADIO', 'KEY_TUNER', 'KEY_PLAYER', 'KEY_TEXT', 'KEY_DVD', 'KEY_AUX', 'KEY_MP3', 'KEY_AUDIO', 'KEY_VIDEO', 'KEY_DIRECTORY', 'KEY_LIST', 'KEY_MEMO', 'KEY_CALENDAR', 'KEY_RED', 'KEY_GREEN', 'KEY_YELLOW', 'KEY_BLUE', 'KEY_CHANNELUP', 'KEY_CHANNELDOWN', 'KEY_FIRST', 'KEY_LAST', 'KEY_AB', 'KEY_NEXT', 'KEY_RESTART', 'KEY_SLOW', 'KEY_SHUFFLE', 'KEY_BREAK', 'KEY_PREVIOUS', 'KEY_DIGITS', 'KEY_TEEN', 'KEY_TWEN', 'KEY_VIDEOPHONE', 'KEY_GAMES', 'KEY_ZOOMIN', 'KEY_ZOOMOUT', 'KEY_ZOOMRESET', 'KEY_WORDPROCESSOR', 'KEY_EDITOR', 'KEY_SPREADSHEET', 'KEY_GRAPHICSEDITOR', 'KEY_PRESENTATION', 'KEY_DATABASE', 'KEY_NEWS', 'KEY_VOICEMAIL', 'KEY_ADDRESSBOOK', 'KEY_MESSENGER', 'KEY_BRIGHTNESS_TOGGLE', 'KEY_DISPLAYTOGGLE', 'KEY_SPELLCHECK', 'KEY_LOGOFF', 'KEY_DOLLAR', 'KEY_EURO', 'KEY_FRAMEBACK', 'KEY_FRAMEFORWARD', 'KEY_CONTEXT_MENU', 'KEY_MEDIA_REPEAT', 'KEY_10CHANNELSUP', 'KEY_10CHANNELSDOWN', 'KEY_IMAGES', 'KEY_DEL_EOL', 'KEY_DEL_EOS', 'KEY_INS_LINE', 'KEY_DEL_LINE', 'KEY_FN', 'KEY_FN_ESC', 'KEY_FN_F1', 'KEY_FN_F2', 'KEY_FN_F3', 'KEY_FN_F4', 'KEY_FN_F5', 'KEY_FN_F6', 'KEY_FN_F7', 'KEY_FN_F8', 'KEY_FN_F9', 'KEY_FN_F10', 'KEY_FN_F11', 'KEY_FN_F12', 'KEY_FN_1', 'KEY_FN_2', 'KEY_FN_D', 'KEY_FN_E', 'KEY_FN_F', 'KEY_FN_S', 'KEY_FN_B', 'KEY_BRL_DOT1', 'KEY_BRL_DOT2', 'KEY_BRL_DOT3', 'KEY_BRL_DOT4', 'KEY_BRL_DOT5', 'KEY_BRL_DOT6', 'KEY_BRL_DOT7', 'KEY_BRL_DOT8', 'KEY_BRL_DOT9', 'KEY_BRL_DOT10', 'KEY_NUMERIC_0', 'KEY_NUMERIC_1', 'KEY_NUMERIC_2', 'KEY_NUMERIC_3', 'KEY_NUMERIC_4', 'KEY_NUMERIC_5', 'KEY_NUMERIC_6', 'KEY_NUMERIC_7', 'KEY_NUMERIC_8', 'KEY_NUMERIC_9', 'KEY_NUMERIC_STAR', 'KEY_NUMERIC_POUND', 'KEY_NUMERIC_A', 'KEY_NUMERIC_B', 'KEY_NUMERIC_C', 'KEY_NUMERIC_D', 'KEY_CAMERA_FOCUS', 'KEY_WPS_BUTTON', 'KEY_TOUCHPAD_TOGGLE', 'KEY_TOUCHPAD_ON', 'KEY_TOUCHPAD_OFF', 'KEY_CAMERA_ZOOMIN', 'KEY_CAMERA_ZOOMOUT', 'KEY_CAMERA_UP', 'KEY_CAMERA_DOWN', 'KEY_CAMERA_LEFT', 'KEY_CAMERA_RIGHT', 'KEY_ATTENDANT_ON', 'KEY_ATTENDANT_OFF', 'KEY_ATTENDANT_TOGGLE', 'KEY_LIGHTS_TOGGLE', 'BTN_DPAD_UP', 'BTN_DPAD_DOWN', 'BTN_DPAD_LEFT', 'BTN_DPAD_RIGHT', 'KEY_ALS_TOGGLE', 'KEY_BUTTONCONFIG', 'KEY_TASKMANAGER', 'KEY_JOURNAL', 'KEY_CONTROLPANEL', 'KEY_APPSELECT', 'KEY_SCREENSAVER', 'KEY_VOICECOMMAND', 'KEY_BRIGHTNESS_MIN', 'KEY_BRIGHTNESS_MAX', 'KEY_KBDINPUTASSIST_PREV', 'KEY_KBDINPUTASSIST_NEXT', 'KEY_KBDINPUTASSIST_PREVGROUP', 'KEY_KBDINPUTASSIST_NEXTGROUP', 'KEY_KBDINPUTASSIST_ACCEPT', 'KEY_KBDINPUTASSIST_CANCEL', 'KEY_RIGHT_UP', 'KEY_RIGHT_DOWN', 'KEY_LEFT_UP', 'KEY_LEFT_DOWN', 'KEY_ROOT_MENU', 'KEY_MEDIA_TOP_MENU', 'KEY_NUMERIC_11', 'KEY_NUMERIC_12', 'KEY_AUDIO_DESC', 'KEY_3D_MODE', 'KEY_NEXT_FAVORITE', 'KEY_STOP_RECORD', 'KEY_PAUSE_RECORD', 'KEY_VOD', 'KEY_UNMUTE', 'KEY_DATA', 'KEY_FASTREVERSE', 'KEY_SLOWREVERSE', 'BTN_TRIGGER_HAPPY', 'BTN_TRIGGER_HAPPY1', 'BTN_TRIGGER_HAPPY2', 'BTN_TRIGGER_HAPPY3', 'BTN_TRIGGER_HAPPY4', 'BTN_TRIGGER_HAPPY5', 'BTN_TRIGGER_HAPPY6', 'BTN_TRIGGER_HAPPY7', 'BTN_TRIGGER_HAPPY8', 'BTN_TRIGGER_HAPPY9', 'BTN_TRIGGER_HAPPY10', 'BTN_TRIGGER_HAPPY11', 'BTN_TRIGGER_HAPPY12', 'BTN_TRIGGER_HAPPY13', 'BTN_TRIGGER_HAPPY14', 'BTN_TRIGGER_HAPPY15', 'BTN_TRIGGER_HAPPY16', 'BTN_TRIGGER_HAPPY17', 'BTN_TRIGGER_HAPPY18', 'BTN_TRIGGER_HAPPY19', 'BTN_TRIGGER_HAPPY20', 'BTN_TRIGGER_HAPPY21', 'BTN_TRIGGER_HAPPY22', 'BTN_TRIGGER_HAPPY23', 'BTN_TRIGGER_HAPPY24', 'BTN_TRIGGER_HAPPY25', 'BTN_TRIGGER_HAPPY26', 'BTN_TRIGGER_HAPPY27', 'BTN_TRIGGER_HAPPY28', 'BTN_TRIGGER_HAPPY29', 'BTN_TRIGGER_HAPPY30', 'BTN_TRIGGER_HAPPY31', 'BTN_TRIGGER_HAPPY32', 'BTN_TRIGGER_HAPPY33', 'BTN_TRIGGER_HAPPY34', 'BTN_TRIGGER_HAPPY35', 'BTN_TRIGGER_HAPPY36', 'BTN_TRIGGER_HAPPY37', 'BTN_TRIGGER_HAPPY38', 'BTN_TRIGGER_HAPPY39', 'BTN_TRIGGER_HAPPY40', 'KEY_FENRIR', 'KEY_SCRIPT', 'KEY_ALT', 'KEY_CTRL', 'KEY_META', 'KEY_SHIFT']
36
55
66 import time
77 from core import debug
8 from core import inputEvent
98
109 class inputManager():
1110 def __init__(self):
1413 self.env = environment
1514 self.env['runtime']['settingsManager'].loadDriver(\
1615 self.env['runtime']['settingsManager'].getSetting('keyboard', 'driver'), 'inputDriver')
16 self.updateInputDevices()
1717 # init LEDs with current state
1818 self.env['input']['newNumLock'] = self.env['runtime']['inputDriver'].getLedState()
1919 self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
2121 self.env['input']['oldCapsLock'] = self.env['input']['newCapsLock']
2222 self.env['input']['newScrollLock'] = self.env['runtime']['inputDriver'].getLedState(2)
2323 self.env['input']['oldScrollLock'] = self.env['input']['newScrollLock']
24 self.grabDevices()
25
24 self.lastDeepestInput = []
25 self.lastInputTime = time.time()
2626 def shutdown(self):
27 self.env['runtime']['inputManager'].releaseDevices()
27 self.removeAllDevices()
2828 self.env['runtime']['settingsManager'].shutdownDriver('inputDriver')
2929
3030 def getInputEvent(self):
3939 self.env['input']['currInput'].remove(mEvent['EventName'])
4040 if len(self.env['input']['currInput']) > 1:
4141 self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
42 if len(self.env['input']['currInput']) == 0:
43 self.env['input']['prevDeepestInput'] = []
42 elif len(self.env['input']['currInput']) == 0:
4443 self.env['input']['shortcutRepeat'] = 1
4544 self.setLedState = self.handleLedStates(mEvent)
46 self.env['input']['lastInputTime'] = time.time()
45 self.lastInputTime = time.time()
4746 elif mEvent['EventState'] == 1:
4847 if not mEvent['EventName'] in self.env['input']['currInput']:
4948 self.env['input']['currInput'].append(mEvent['EventName'])
5049 if len(self.env['input']['currInput']) > 1:
5150 self.env['input']['currInput'] = sorted(self.env['input']['currInput'])
52 if len(self.env['input']['prevDeepestInput']) < len(self.env['input']['currInput']):
53 self.env['input']['prevDeepestInput'] = self.env['input']['currInput'].copy()
54 elif self.env['input']['prevDeepestInput'] == self.env['input']['currInput']:
55 if time.time() - self.env['input']['lastInputTime'] <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'):
51 if len(self.lastDeepestInput) < len(self.env['input']['currInput']):
52 self.setLastDeepestInput( self.env['input']['currInput'].copy())
53 elif self.lastDeepestInput == self.env['input']['currInput']:
54 if time.time() - self.lastInputTime <= self.env['runtime']['settingsManager'].getSettingAsFloat('keyboard','doubleTapTimeout'):
5655 self.env['input']['shortcutRepeat'] += 1
5756 else:
5857 self.env['input']['shortcutRepeat'] = 1
5958 self.setLedState = self.handleLedStates(mEvent)
60 self.env['input']['lastInputTime'] = time.time()
59 self.lastInputTime = time.time()
6160 elif mEvent['EventState'] == 2:
62 self.env['input']['lastInputTime'] = time.time()
61 self.lastInputTime = time.time()
6362 else:
6463 pass
6564 self.env['input']['oldNumLock'] = self.env['input']['newNumLock']
10099 return False
101100 return self.setLedState
102101
103 def grabDevices(self):
102 def grabAllDevices(self):
104103 if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
105 self.env['runtime']['inputDriver'].grabDevices()
106
107 def releaseDevices(self):
104 self.env['runtime']['inputDriver'].grabAllDevices()
105
106 def updateInputDevices(self):
108107 try:
109 self.env['runtime']['inputDriver'].releaseDevices()
108 self.env['runtime']['inputDriver'].updateInputDevices()
109 except:
110 pass
111
112 def removeAllDevices(self):
113 try:
114 self.env['runtime']['inputDriver'].removeAllDevices()
110115 except:
111116 pass
112117
138143 eventName = 'KEY_SCRIPT'
139144 return eventName
140145
141 def isConsumeInput(self):
142 return self.env['runtime']['commandManager'].isCommandQueued() and \
143 not self.env['input']['keyForeward']
144 #and
145 # not (self.env['input']['keyForeward'] or \
146 # self.env['runtime']['settingsManager'].getSettingAsBool(, 'keyboard', 'grabDevices'))
147
148146 def clearEventBuffer(self):
149147 self.env['runtime']['inputDriver'].clearEventBuffer()
150
148 def setLastDeepestInput(self, currentDeepestInput):
149 self.lastDeepestInput = currentDeepestInput
150 def clearLastDeepInput(self):
151 self.lastDeepestInput = []
152 def getLastInputTime(self):
153 return self.lastInputTime
154 def getLastDeepestInput(self):
155 return self.lastDeepestInput
151156 def writeEventBuffer(self):
152157 try:
153158 if self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
154159 self.env['runtime']['inputDriver'].writeEventBuffer()
155 time.sleep(0.008)
156160 self.clearEventBuffer()
157 if len(self.env['input']['currInput']) == 1:
158 if self.env['input']['currInput'][0] in ['KEY_UP','KEY_DOWN']:
159 time.sleep(0.08) # hack for tintin history because it needs more time
160161 except Exception as e:
161162 self.env['runtime']['debug'].writeDebugOut("Error while writeUInput",debug.debugLevel.ERROR)
162163 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
163164
164 def isFenrirKeyPressed(self):
165 return 'KEY_FENRIR' in self.env['input']['prevDeepestInput']
166
167 def isScriptKeyPressed(self):
168 return 'KEY_SCRIPT' in self.env['input']['prevDeepestInput']
169
170165 def noKeyPressed(self):
171166 return self.env['input']['currInput'] == []
172
173 def getPrevDeepestInput(self):
167 def isKeyPress(self):
168 return (self.env['input']['prevInput'] == []) and (self.env['input']['currInput'] != [])
169 def getPrevDeepestShortcut(self):
174170 shortcut = []
175171 shortcut.append(self.env['input']['shortcutRepeat'])
176 shortcut.append(self.env['input']['prevDeepestInput'])
172 shortcut.append(self.getLastDeepestInput())
177173 return str(shortcut)
178174
179175 def getPrevShortcut(self):
182178 shortcut.append(self.env['input']['prevInput'])
183179 return str(shortcut)
184180
185 def getCurrShortcut(self):
181 def getCurrShortcut(self, inputSequence = None):
186182 shortcut = []
187183 shortcut.append(self.env['input']['shortcutRepeat'])
188 shortcut.append(self.env['input']['currInput'])
184 if inputSequence:
185 shortcut.append(inputSequence)
186 else:
187 shortcut.append(self.env['input']['currInput'])
189188 if len(self.env['input']['prevInput']) < len(self.env['input']['currInput']):
190189 if self.env['input']['shortcutRepeat'] > 1 and not self.shortcutExists(str(shortcut)):
191190 shortcut = []
195194 self.env['runtime']['debug'].writeDebugOut("currShortcut " + str(shortcut) ,debug.debugLevel.INFO)
196195 return str(shortcut)
197196
197 def currKeyIsModifier(self):
198 if len(self.getLastDeepestInput()) != 1:
199 return False
200 return (self.env['input']['currInput'][0] =='KEY_FENRIR') or (self.env['input']['currInput'][0] == 'KEY_SCRIPT')
201
198202 def isFenrirKey(self, eventName):
199203 return eventName in self.env['input']['fenrirKey']
204
200205 def isScriptKey(self, eventName):
201206 return eventName in self.env['input']['scriptKey']
207
202208 def getCommandForShortcut(self, shortcut):
203209 if not self.shortcutExists(shortcut):
204210 return ''
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import time
7 from core import debug
8
9 outputData = {
10 'nextFlush': time.time(),
11 'messageText': '',
12 'messageOffset': None,
13 'cursorOffset': None,
14 }
44 # By Chrys, Storm Dragon, and contributers.
55
66 from core import debug
7 import string
7 from utils import line_utils
8 import string, time
89
910 class outputManager():
1011 def __init__(self):
2223 self.env['runtime']['settingsManager'].shutdownDriver('speechDriver')
2324 self.env['runtime']['settingsManager'].shutdownDriver('brailleDriver')
2425
25 def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False):
26 def presentText(self, text, interrupt=True, soundIcon = '', ignorePunctuation=False, announceCapital=False, flush=True):
2627 if text == '':
2728 return
2829 self.env['runtime']['debug'].writeDebugOut("presentText:\nsoundIcon:'"+soundIcon+"'\nText:\n" + text ,debug.debugLevel.INFO)
3738 toAnnounceCapital = False
3839
3940 self.speakText(text, interrupt, ignorePunctuation,toAnnounceCapital)
40 self.brailleText(text, interrupt)
41 if flush:
42 self.brailleText(text, flush)
4143
4244 def speakText(self, text, interrupt=True, ignorePunctuation=False, announceCapital=False):
4345 if not self.env['runtime']['settingsManager'].getSettingAsBool('speech', 'enabled'):
9799 self.env['runtime']['debug'].writeDebugOut("\"speak\" in outputManager.speakText ",debug.debugLevel.ERROR)
98100 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
99101
100 def brailleText(self, text, interrupt=True):
102 def brailleText(self, text='', flush=True):
101103 if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
102104 return
103105 if self.env['runtime']['brailleDriver'] == None:
104106 return
105 self.env['runtime']['brailleDriver'].writeText(text[:35])
106
107 if flush:
108 self.env['output']['nextFlush'] = time.time() + self.getFlushTime(text)
109 self.env['output']['messageOffset'] = {'x':0,'y':0}
110 self.env['output']['messageText'] = text
111 displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
112 self.env['runtime']['brailleDriver'].writeText('flush'+displayText)
113 else:
114 if self.env['output']['nextFlush'] < time.time():
115 if self.env['output']['messageText'] != '':
116 self.env['output']['messageText'] = ''
117 if self.env['output']['messageOffset'] != None:
118 self.env['output']['messageOffset'] = None
119 cursor = self.getBrailleCursor()
120 x, y, self.env['output']['brlText'] = \
121 line_utils.getCurrentLine(cursor['x'], cursor['y'], self.env['screen']['newContentText'])
122 displayText = self.getBrailleTextWithOffset(self.env['screen']['newContentText'], self.env['output']['cursorOffset'], cursor)
123 self.env['runtime']['brailleDriver'].writeText('notflush'+displayText)
124 else:
125 displayText = self.getBrailleTextWithOffset(self.env['output']['messageText'], self.env['output']['messageOffset'])
126 self.env['runtime']['brailleDriver'].writeText('flush'+displayText)
127
128 def getBrailleCursor(self):
129 if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'REVIEW':
130 return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
131 if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'MANUAL':
132 return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
133 if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'LAST':
134 return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
135 return self.env['runtime']['cursorManager'].getReviewOrTextCursor()
136
137 def getFixCursorCell(self):
138 size = self.env['runtime']['brailleDriver'].getDeviceSize()[0]
139 fixCell = self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'fixCursorOnCell')
140 if fixCell <= -1:
141 return size[0]
142 if fixCell >= size[0]:
143 return size[0]
144 return fixCell
145 def getActiveOffsetAndText(self):
146 if self.env['output']['messageOffset']:
147 return self.env['output']['messageOffset'], self.env['output']['messageText']
148 if not self.env['output']['cursorOffset']:
149 return self.getBrailleCursor(), self.env['screen']['newContentText']
150 return self.env['output']['cursorOffset'], self.env['screen']['newContentText']
151 def getHorizontalPanSize(self):
152 size = self.env['runtime']['brailleDriver'].getDeviceSize()
153 if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') <= 0:
154 return size[0]
155 if self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal') >= size[0]:
156 return size[0]
157 return self.env['runtime']['settingsManager'].getSettingAsInt('braille', 'panSizeHorizontal')
158 def getHorizontalPanLevel(self,offsetChange = 0):
159 panned = True
160 panSize = self.getHorizontalPanSize()
161 offset, text = self.getActiveOffsetAndText()
162 currline = text.split('\n')[offset['y']]
163 newOffsetStart = (int(offset['x'] / panSize) + offsetChange) * panSize
164 if newOffsetStart < 0:
165 newOffsetStart = 0
166 panned = False
167 if newOffsetStart >= len(text):
168 newOffsetStart = int((len(text) - panSize - 1) / panSize)
169 panned = False
170 return newOffsetStart, panned
171 def setPanLeft(self):
172 newPan, panned = self.getHorizontalPanLevel(-1)
173 if self.env['output']['messageOffset']:
174 self.env['output']['messageOffset'] = newPan.copy()
175 else:
176 self.env['output']['cursorOffset'] = newPan.copy()
177 return panned
178 def setPanRight(self):
179 newPan, panned = self.getHorizontalPanLevel(1)
180 if self.env['output']['messageOffset']:
181 self.env['output']['messageOffset'] = newPan.copy()
182 else:
183 self.env['output']['cursorOffset'] = newPan.copy()
184 return panned
185 def removePanning(self):
186 if self.env['output']['messageOffset']:
187 self.env['output']['messageOffset'] = None
188 else:
189 self.env['output']['cursorOffset'] = None
190 def getBrailleTextWithOffset(self, text, offset = None, cursor = None):
191 if text == '':
192 return ''
193 size = self.env['runtime']['brailleDriver'].getDeviceSize()
194 offsetText = text
195
196 if cursor and not offset:
197 if self.env['runtime']['settingsManager'].getSetting('braille', 'cursorFollowMode').upper() == 'FIXCELL':
198 #fix cell
199 cursorCell = self.getFixCursorCell()
200 offsetStart = cursor['x']
201 if offsetStart < size[0]:
202 if offsetStart <= cursorCell:
203 return offsetText[0: size[0]]
204
205 offsetStart -= cursorCell
206 if offsetStart >= len(offsetText):
207 offsetStart = len(offsetText) - 1
208 else:
209 # page and fallback
210 offsetStart = int(cursor['x'] / size[0]) * size[0]
211 else:
212 if not offset:
213 offset = {'x':0,'y':0}
214 offsetStart = offset['x']
215 if offsetStart >= len(offsetText):
216 offsetStart = len(offsetText) - size[0]
217
218 if offsetStart < 0:
219 offsetStart = 0
220 offsetEnd = offsetStart + size[0]
221 offsetText = offsetText[offsetStart: offsetEnd]
222 return offsetText
107223 def interruptOutput(self):
108224 self.env['runtime']['speechDriver'].cancel()
109225 self.env['runtime']['debug'].writeDebugOut("Interrupt speech",debug.debugLevel.INFO)
110
111
226
227 def clearFlushTime(self):
228 self.setFlushTime(0.0)
229
230 def setFlushTime(self,newTime):
231 self.env['output']['nextFlush'] = newTime
232
233 def getFlushTime(self,text=''):
234 if self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') < 0 or \
235 self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'NONE':
236 return 999999999999
237 if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'FIX':
238 return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout')
239 if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'CHAR':
240 return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len(text)
241 if self.env['runtime']['settingsManager'].getSetting('braille', 'flushMode').upper() == 'WORD':
242 wordsList = text.split(' ')
243 return self.env['runtime']['settingsManager'].getSettingAsFloat('braille', 'flushTimeout') * len( list( filter(None, wordsList) ) )
244
112245 def playSoundIcon(self, soundIcon = '', interrupt=True):
113246 if soundIcon == '':
114247 return False
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 from core.eventData import fenrirEventType
8 import time
9 from threading import Thread
10 from multiprocessing import Process
11
12 class processManager():
13 def __init__(self):
14 self._Processes = []
15 self._Threads = []
16 def initialize(self, environment):
17 self.env = environment
18 self.running = self.env['runtime']['eventManager'].getRunning()
19 self.addSimpleEventThread(fenrirEventType.HeartBeat, self.heartBeatTimer, multiprocess=True)
20 def shutdown(self):
21 self.terminateAllProcesses()
22
23 def terminateAllProcesses(self):
24 for proc in self._Processes:
25 try:
26 proc.terminate()
27 except Exception as e:
28 print(e)
29 def heartBeatTimer(self, active):
30 try:
31 time.sleep(0.5)
32 except:
33 pass
34 return time.time()
35 def addCustomEventThread(self, function, pargs = None, multiprocess = False, runOnce = False):
36 eventQueue = self.env['runtime']['eventManager'].getEventQueue()
37 if multiprocess:
38 t = Process(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce))
39 self._Processes.append(t)
40 else:# thread not implemented yet
41 t = Thread(target=self.customEventWorkerThread, args=(eventQueue, function, pargs, runOnce))
42 self._Threads.append(t)
43 t.start()
44
45 def addSimpleEventThread(self, event, function, pargs = None, multiprocess = False, runOnce = False):
46 if multiprocess:
47 t = Process(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce))
48 self._Processes.append(t)
49 else:
50 t = Thread(target=self.simpleEventWorkerThread, args=(event, function, pargs, runOnce))
51 self._Threads.append(t)
52 t.start()
53
54 def customEventWorkerThread(self, eventQueue, function, pargs = None, runOnce = False):
55 #if not isinstance(eventQueue, Queue):
56 # return
57 if not callable(function):
58 return
59 while self.running.value:
60 try:
61 if pargs:
62 function(self.running, eventQueue, pargs)
63 else:
64 function(self.running, eventQueue)
65 except Exception as e:
66 self.env['runtime']['debug'].writeDebugOut('processManager:customEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR)
67 if runOnce:
68 break
69
70 def simpleEventWorkerThread(self, event, function, pargs = None, runOnce = False):
71 if not isinstance(event, fenrirEventType):
72 return
73 if not callable(function):
74 return
75 while self.running.value:
76 Data = None
77 try:
78 if pargs:
79 Data = function(self.running, pargs)
80 else:
81 Data = function(self.running)
82 except Exception as e:
83 self.env['runtime']['debug'].writeDebugOut('processManager:simpleEventWorkerThread:function():' + str(e),debug.debugLevel.ERROR)
84 self.env['runtime']['eventManager'].putToEventQueue(event, Data)
85 if runOnce:
86 break
+0
-61
src/fenrir/core/punctuation.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import string
8
9 punctuation = {
10 'LEVELDICT':{
11 'none': '',
12 'some': '#-$~+*-/\\@',
13 'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;',
14 'all': string.punctuation + ' §',
15 },
16 'PUNCTDICT':{
17 ' ':'space',
18 '&':'and',
19 "'":"apostrophe",
20 '@':'at',
21 '\\':'backslash',
22 '|':'bar',
23 '!':'bang',
24 '^':'carrot',
25 ':':'colon',
26 ',':'comma',
27 '-':'dash',
28 '$':'dollar',
29 '.':'dot',
30 '>':'greater',
31 '`':'grave',
32 '#':'hash',
33 '{':'left brace',
34 '[':'left bracket',
35 '(':'left paren',
36 '<':'less',
37 '%':'percent',
38 '+':'plus',
39 '?':'question',
40 '"':'quote',
41 ')':'right paren',
42 '}':'right brace',
43 ']':'right bracket',
44 ';':'semicolon',
45 '/':'slash',
46 '*':'star',
47 '~':'tilde',
48 '_':'line',
49 '=':'equals',
50 },
51 'CUSTOMDICT':{
52 },
53 'EMOTICONDICT':{
54 ':)':'smiley',
55 ';)':'winking face',
56 'XD':'loool',
57 ':@':'angry face',
58 ':D':'lought'
59 },
60 }
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import string
8
9 punctuationData = {
10 'LEVELDICT':{
11 'none': '',
12 'some': '#-$~+*-/\\@',
13 'most': '.,:-$~ +*-/\\@!#%^&*()[]}{<>;',
14 'all': string.punctuation + ' §',
15 },
16 'PUNCTDICT':{
17 ' ':'space',
18 '&':'and',
19 "'":"apostrophe",
20 '@':'at',
21 '\\':'backslash',
22 '|':'bar',
23 '!':'bang',
24 '^':'carrot',
25 ':':'colon',
26 ',':'comma',
27 '-':'dash',
28 '$':'dollar',
29 '.':'dot',
30 '>':'greater',
31 '`':'grave',
32 '#':'hash',
33 '{':'left brace',
34 '[':'left bracket',
35 '(':'left paren',
36 '<':'less',
37 '%':'percent',
38 '+':'plus',
39 '?':'question',
40 '"':'quote',
41 ')':'right paren',
42 '}':'right brace',
43 ']':'right bracket',
44 ';':'semicolon',
45 '/':'slash',
46 '*':'star',
47 '~':'tilde',
48 '_':'line',
49 '=':'equals',
50 },
51 'CUSTOMDICT':{
52 },
53 'EMOTICONDICT':{
54 ':)':'smiley',
55 ';)':'winking face',
56 'XD':'loool',
57 ':@':'angry face',
58 ':D':'lought'
59 },
60 }
3131 pass
3232 return text.translate(currAllPunctNone)
3333
34 def useCustomDict(self, text, customDict):
34 def useCustomDict(self, text, customDict, seperator=''):
3535 resultText = str(text)
3636 if customDict:
3737 for key,item in customDict.items():
38 resultText = resultText.replace(str(key),str(item))
38 resultText = resultText.replace(str(key),seperator + str(item) + seperator)
3939 return resultText
4040
4141 def usePunctuationDict(self, text, punctuationDict, punctuation):
5858 resultText = text
5959 resultText = self.useCustomDict(resultText, self.env['punctuation']['CUSTOMDICT'])
6060 if self.env['runtime']['settingsManager'].getSettingAsBool('general', 'emoticons'):
61 resultText = self.useCustomDict(resultText, self.env['punctuation']['EMOTICONDICT'])
61 resultText = self.useCustomDict(resultText, self.env['punctuation']['EMOTICONDICT'], ' ')
6262 currPunctLevel = ''
6363 if not ignorePunctuation and self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower() in self.env['punctuation']['LEVELDICT']:
6464 currPunctLevel = self.env['punctuation']['LEVELDICT'][self.env['runtime']['settingsManager'].getSetting('general', 'punctuationLevel').lower()]
+0
-20
src/fenrir/core/runtime.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 runtime = {
9 'speechDriver': None,
10 'screenDriver': None,
11 'soundDriver': None,
12 'inputDriver': None,
13 'brailleDriver': None,
14 'inputManager': None,
15 'commandManager': None,
16 'screenManager': None,
17 'outputManager': None,
18 'debug':None,
19 }
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 runtimeData = {
9 'speechDriver': None,
10 'screenDriver': None,
11 'soundDriver': None,
12 'inputDriver': None,
13 'brailleDriver': None,
14 'inputManager': None,
15 'commandManager': None,
16 'screenManager': None,
17 'outputManager': None,
18 'debug':None,
19 }
1717 'oldCursor':{'x':0,'y':0},
1818 'oldContentBytes': b'',
1919 'oldContentText': '',
20 'oldContentAttrib': b'',
20 'oldContentAttrib': None,
2121 'oldApplication': '',
2222 'oldTTY':None,
2323 'newDelta': '',
2828 'newCursor':{'x':0,'y':0},
2929 'newContentBytes': b'',
3030 'newContentText': '',
31 'newContentAttrib': b'',
31 'newContentAttrib': None,
3232 'newTTY':'0',
3333 'newApplication': '',
34 'lastScreenUpdate': time.time()
34 'lastScreenUpdate': time.time(),
35 'autoIgnoreScreens':[],
3536 }
37 '''
38 screenData = {
39 'columns': 0,
40 'lines': 0,
41 'textDelta': '',
42 'negativeDelta': '',
43 'attribDelta': '',
44 'reviewCursor':None, #{'x':0,'y':0}
45 'attribCursor':None, #{'x':0,'y':0}
46 'textCursor':None, #{'x':0,'y':0}
47 'content': None, #{'x':0,'y':0}
48 'Text': '',
49 'Attrib': None,
50 'screen': None,
51 'application': '',
52 'timestamp': time.time(),
53 }
54 '''
88
99 class screenManager():
1010 def __init__(self):
11 self.autoIgnoreScreens = []
12
11 pass
1312 def initialize(self, environment):
1413 self.env = environment
1514 self.env['runtime']['settingsManager'].loadDriver(\
1615 self.env['runtime']['settingsManager'].getSetting('screen', 'driver'), 'screenDriver')
16 self.env['runtime']['screenDriver'].getCurrScreen()
1717 self.env['runtime']['screenDriver'].getSessionInformation()
1818
1919 def shutdown(self):
2020 self.env['runtime']['settingsManager'].shutdownDriver('screenDriver')
2121
2222 def update(self, trigger='onUpdate'):
23 self.env['runtime']['screenDriver'].getCurrScreen()
24 self.env['runtime']['screenDriver'].getSessionInformation()
25 self.env['screenData']['oldApplication'] = self.env['screenData']['newApplication']
26 if self.isScreenChange():
23 self.env['runtime']['screenDriver'].getCurrScreen()
24
25 if trigger == 'onScreenChange':
26 self.env['runtime']['screenDriver'].getSessionInformation()
27
28 self.env['screen']['oldApplication'] = self.env['screen']['newApplication']
29 if self.isScreenChange():
2730 self.changeBrailleScreen()
28 if not self.isSuspendingScreen(self.env['screenData']['newTTY']):
31 if not self.isSuspendingScreen(self.env['screen']['newTTY']):
2932 self.env['runtime']['screenDriver'].update(trigger)
30 if trigger == 'onUpdate' or self.isScreenChange() \
31 or len(self.env['screenData']['newDelta']) > 6:
32 self.env['runtime']['screenDriver'].getCurrApplication()
33 self.env['screenData']['lastScreenUpdate'] = time.time()
34
33 #if trigger == 'onUpdate' or self.isScreenChange() \
34 # or len(self.env['screen']['newDelta']) > 6:
35 # self.env['runtime']['screenDriver'].getCurrApplication()
36 self.env['screen']['lastScreenUpdate'] = time.time()
37 def formatAttributes(self, attribute, attributeFormatString = None):
38 if not attributeFormatString:
39 attributeFormatString = self.env['runtime']['settingsManager'].getSetting('general', 'attributeFormatString')
40 if not attributeFormatString:
41 return ''
42 if attributeFormatString == '':
43 return ''
44 attributeFormatString = attributeFormatString.replace('fenrirBGColor', self.env['runtime']['screenDriver'].getFenrirBGColor(attribute))
45 attributeFormatString = attributeFormatString.replace('fenrirFGColor', self.env['runtime']['screenDriver'].getFenrirFGColor(attribute))
46 attributeFormatString = attributeFormatString.replace('fenrirUnderline', self.env['runtime']['screenDriver'].getFenrirUnderline(attribute))
47 attributeFormatString = attributeFormatString.replace('fenrirBold', self.env['runtime']['screenDriver'].getFenrirBold(attribute))
48 attributeFormatString = attributeFormatString.replace('fenrirBlink', self.env['runtime']['screenDriver'].getFenrirBlink(attribute))
49 attributeFormatString = attributeFormatString.replace('fenrirFontSize', self.env['runtime']['screenDriver'].getFenrirFontSize(attribute))
50 attributeFormatString = attributeFormatString.replace('fenrirFont', self.env['runtime']['screenDriver'].getFenrirFont(attribute))
51 return attributeFormatString
3552 def isSuspendingScreen(self, screen = None):
3653 if screen == None:
37 screen = self.env['screenData']['newTTY']
54 screen = self.env['screen']['newTTY']
3855 ignoreScreens = []
3956 fixIgnoreScreens = self.env['runtime']['settingsManager'].getSetting('screen', 'suspendingScreen')
4057 if fixIgnoreScreens != '':
41 ignoreScreens.append(fixIgnoreScreens.split(','))
58 ignoreScreens.extend(fixIgnoreScreens.split(','))
4259 if self.env['runtime']['settingsManager'].getSettingAsBool('screen', 'autodetectSuspendingScreen'):
43 ignoreScreens.extend(self.env['screenData']['autoIgnoreScreens'])
60 ignoreScreens.extend(self.env['screen']['autoIgnoreScreens'])
61 self.env['runtime']['debug'].writeDebugOut('screenManager:isSuspendingScreen ' + str(ignoreScreens) + ' '+ str(self.env['screen']['newTTY']),debug.debugLevel.INFO)
4462 return (screen in ignoreScreens)
45
63
4664 def isScreenChange(self):
47 if not self.env['screenData']['oldTTY']:
65 if not self.env['screen']['oldTTY']:
4866 return False
49 return self.env['screenData']['newTTY'] != self.env['screenData']['oldTTY']
67 return self.env['screen']['newTTY'] != self.env['screen']['oldTTY']
5068 def isDelta(self):
51 return self.env['screenData']['newDelta'] != ''
69 return self.env['screen']['newDelta'] != ''
5270 def isNegativeDelta(self):
53 return self.env['screenData']['newNegativeDelta'] != ''
71 return self.env['screen']['newNegativeDelta'] != ''
5472 def getWindowAreaInText(self, text):
5573 if not self.env['runtime']['cursorManager'].isApplicationWindowSet():
5674 return text
6987 self.env['runtime']['debug'].writeDebugOut('screenManager:injectTextToScreen ' + str(e),debug.debugLevel.ERROR)
7088
7189 def changeBrailleScreen(self):
90 if not self.env['runtime']['settingsManager'].getSettingAsBool('braille', 'enabled'):
91 return
7292 if not self.env['runtime']['brailleDriver']:
7393 return
74 if self.env['screenData']['oldTTY']:
75 if not self.isSuspendingScreen(self.env['screenData']['oldTTY']):
94 if self.env['screen']['oldTTY']:
95 if not self.isSuspendingScreen(self.env['screen']['oldTTY']):
7696 try:
7797 self.env['runtime']['brailleDriver'].leveScreen()
7898 except Exception as e:
7999 self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:leveScreen ' + str(e),debug.debugLevel.ERROR)
80100 if not self.isSuspendingScreen():
81101 try:
82 self.env['runtime']['brailleDriver'].enterScreen(self.env['screenData']['newTTY'])
102 self.env['runtime']['brailleDriver'].enterScreen(self.env['screen']['newTTY'])
83103 except Exception as e:
84104 self.env['runtime']['debug'].writeDebugOut('screenManager:changeBrailleScreen:enterScreen ' + str(e),debug.debugLevel.ERROR)
+0
-93
src/fenrir/core/settings.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 settings = {
9 'sound': {
10 'enabled': True,
11 'driver': 'generic',
12 'theme': 'default',
13 'volume': 1.0,
14 'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile',
15 'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
16 },
17 'speech':{
18 'enabled': True,
19 'driver': 'speechd',
20 'rate': 0.75,
21 'pitch': 0.5,
22 'capitalPitch':0.8,
23 'volume': 1.0,
24 'module': 'espeak',
25 'voice': '',
26 'language': 'english-us',
27 'autoReadIncoming': True,
28 },
29 'braille':{
30 'enabled': False,
31 'driver':'brlapi',
32 'layout': 'en',
33 },
34 'screen':{
35 'driver': 'vcsa',
36 'encoding': 'cp850',
37 'screenUpdateDelay': 0.1,
38 'suspendingScreen': '',
39 'autodetectSuspendingScreen': False,
40 },
41 'general':{
42 'debugLevel': debug.debugLevel.DEACTIVE,
43 'punctuationProfile':'default',
44 'punctuationLevel': 'some',
45 'respectPunctuationPause':True,
46 'newLinePause':True,
47 'numberOfClipboards': 10,
48 'emoticons': True,
49 'fenrirKeys': 'KEY_KP0,KEY_META',
50 'scriptKeys': 'KEY_COMPOSE',
51 'timeFormat': '%I:%M%P',
52 'dateFormat': '%A, %B %d, %Y',
53 'autoSpellCheck': False,
54 'spellCheckLanguage': 'en_US',
55 'scriptPath':'/usr/share/fenrir/scripts',
56 },
57 'focus':{
58 'cursor': True,
59 'highlight': False,
60 },
61 'review':{
62 'lineBreak': True,
63 'endOfScreen': True,
64 },
65 'promote':{
66 'enabled': True,
67 'inactiveTimeoutSec': 120,
68 'list': '',
69 },
70 'time':{
71 'enabled': False,
72 'presentTime': True,
73 'presentDate': True,
74 'delaySec': 0,
75 'onMinutes': '00,30',
76 'announce': True,
77 'interrupt': False,
78 },
79 'keyboard':{
80 'driver': 'evdev',
81 'device': 'all',
82 'grabDevices': True,
83 'ignoreShortcuts': False,
84 'keyboardLayout': "desktop",
85 'charEcho': False,
86 'charDeleteEcho': True,
87 'wordEcho': True,
88 'interruptOnKeyPress': True,
89 'interruptOnKeyPressFilter': '',
90 'doubleTapTimeout': 0.2,
91 }
92 }
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 settingsData = {
9 'sound': {
10 'enabled': True,
11 'driver': 'genericDriver',
12 'theme': 'default',
13 'volume': 1.0,
14 'genericPlayFileCommand': 'play -q -v fenrirVolume fenrirSoundFile',
15 'genericFrequencyCommand': 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
16 },
17 'speech':{
18 'enabled': True,
19 'driver': 'speechdDriver',
20 'serverPath': '',
21 'rate': 0.75,
22 'pitch': 0.5,
23 'capitalPitch':0.8,
24 'volume': 1.0,
25 'module': 'espeak',
26 'voice': '',
27 'language': 'english-us',
28 'autoReadIncoming': True,
29 'genericSpeechCommand':'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"',
30 'fenrirMinVolume':0,
31 'fenrirMaxVolume':200,
32 'fenrirMinPitch':0,
33 'fenrirMaxPitch':99,
34 'fenrirMinRate':80,
35 'fenrirMaxRate':450,
36 },
37 'braille':{
38 'enabled': False,
39 'driver':'brlapiDriver',
40 'layout': 'en',
41 'flushMode': 'word', #NONE,FIX,CHAR,WORD
42 'flushTimeout': 3,
43 'cursorFocusMode':'page', # page,fixCell
44 'fixCursorOnCell': -1,
45 'cursorFollowMode': 'review', # none, review, last, text
46 'panSizeHorizontal': 0 # 0 = display size
47 },
48 'screen':{
49 'driver': 'vcsaDriver',
50 'encoding': 'cp850',
51 'screenUpdateDelay': 0.1,
52 'suspendingScreen': '',
53 'autodetectSuspendingScreen': False,
54 },
55 'general':{
56 'debugLevel': debug.debugLevel.DEACTIVE,
57 'debugMode': 'FILE',
58 'punctuationProfile':'default',
59 'punctuationLevel': 'some',
60 'respectPunctuationPause':True,
61 'newLinePause':True,
62 'numberOfClipboards': 10,
63 'emoticons': True,
64 'fenrirKeys': 'KEY_KP0,KEY_META',
65 'scriptKeys': 'KEY_COMPOSE',
66 'timeFormat': '%I:%M%P',
67 'dateFormat': '%A, %B %d, %Y',
68 'autoSpellCheck': False,
69 'spellCheckLanguage': 'en_US',
70 'scriptPath': '/usr/share/fenrir/scripts',
71 'commandPath': '/usr/share/fenrir/commands',
72 'attributeFormatString': 'Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize'
73 },
74 'focus':{
75 'cursor': True,
76 'highlight': False,
77 },
78 'review':{
79 'lineBreak': True,
80 'endOfScreen': True,
81 'leaveReviewOnCursorChange': True,
82 'leaveReviewOnScreenChange': True,
83 },
84 'promote':{
85 'enabled': True,
86 'inactiveTimeoutSec': 120,
87 'list': '',
88 },
89 'time':{
90 'enabled': False,
91 'presentTime': True,
92 'presentDate': True,
93 'delaySec': 0,
94 'onMinutes': '00,30',
95 'announce': True,
96 'interrupt': False,
97 },
98 'keyboard':{
99 'driver': 'evdev',
100 'device': 'all',
101 'grabDevices': True,
102 'ignoreShortcuts': False,
103 'keyboardLayout': "desktop",
104 'charEcho': False,
105 'charDeleteEcho': True,
106 'wordEcho': True,
107 'interruptOnKeyPress': True,
108 'interruptOnKeyPressFilter': '',
109 'doubleTapTimeout': 0.2,
110 }
111 }
33 # Fenrir TTY screen reader
44 # By Chrys, Storm Dragon, and contributers.
55
6 import importlib.util
7 import os
8 import __main__
6 import os, inspect
7 currentdir = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
8 fenrirPath = os.path.dirname(currentdir)
9
910 from configparser import ConfigParser
11 from core import debugManager
12 from core import processManager
13 from core import eventManager
1014 from core import inputManager
1115 from core import outputManager
1216 from core import commandManager
1418 from core import punctuationManager
1519 from core import cursorManager
1620 from core import applicationManager
21 from core import helpManager
1722 from core import environment
18 from core import inputEvent
19 from core.settings import settings
23 from core import inputData
24 from core.settingsData import settingsData
2025 from core import debug
26 from utils import module_utils
2127
2228 class settingsManager():
2329 def __init__(self):
24 self.settings = settings
30 self.settings = settingsData
31 self.settingArgDict = {}
2532 def initialize(self, environment):
2633 self.env = environment
2734 def shutdown(self):
2835 pass
29 def loadShortcuts(self, kbConfigPath=os.path.dirname(os.path.realpath(__main__.__file__)) + '/../../config/keyboard/desktop.conf'):
36 def loadShortcuts(self, kbConfigPath=fenrirPath + '/../../config/keyboard/desktop.conf'):
3037 kbConfig = open(kbConfigPath,"r")
3138 while(True):
3239 invalid = False
6673 self.env['runtime']['debug'].writeDebugOut("invalid shortcut (missing KEY_FENRIR): "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.ERROR)
6774 continue
6875 self.env['runtime']['debug'].writeDebugOut("Shortcut: "+ str(shortcut) + ' command:' +commandName ,debug.debugLevel.INFO, onAnyLevel=True)
69 self.env['bindings'][str(shortcut)] = commandName
76 self.env['bindings'][str(shortcut)] = commandName
7077 kbConfig.close()
78 # fix bindings
79 self.env['bindings'][str([1, ['KEY_F1', 'KEY_FENRIR']])] = 'TOGGLE_TUTORIAL_MODE'
7180
7281 def loadSoundIcons(self, soundIconPath):
7382 siConfig = open(soundIconPath + '/soundicons.conf',"r")
98107 self.env['runtime']['debug'].writeDebugOut("SoundIcon: " + soundIcon + '.' + soundIconFile, debug.debugLevel.INFO, onAnyLevel=True)
99108 siConfig.close()
100109 def isValidKey(self, key):
101 return key in inputEvent.keyNames
110 return key in inputData.keyNames
102111
103 def loadDicts(self, dictConfigPath=os.path.dirname(os.path.realpath(__main__.__file__)) + '/../../config/punctuation/default.conf'):
112 def loadDicts(self, dictConfigPath=fenrirPath + '/../../config/punctuation/default.conf'):
104113 dictConfig = open(dictConfigPath,"r")
105114 currDictName = ''
106115 while(True):
144153 def getSetting(self, section, setting):
145154 value = ''
146155 try:
156 value = self.settingArgDict[section.lower()][setting.lower()]
157 return value
158 except:
159 pass
160 try:
147161 value = self.env['settings'].get(section, setting)
148162 except:
149163 value = str(self.settings[section][setting])
152166 def getSettingAsInt(self, section, setting):
153167 value = 0
154168 try:
169 value = int(self.settingArgDict[section.lower()][setting.lower()])
170 return value
171 except Exception as e:
172 pass
173 try:
155174 value = self.env['settings'].getint(section, setting)
156175 except:
157176 value = self.settings[section][setting]
160179 def getSettingAsFloat(self, section, setting):
161180 value = 0.0
162181 try:
182 value = float(self.settingArgDict[section.lower()][setting.lower()])
183 return value
184 except Exception as e:
185 pass
186 try:
163187 value = self.env['settings'].getfloat(section, setting)
164188 except:
165189 value = self.settings[section][setting]
168192 def getSettingAsBool(self, section, setting):
169193 value = False
170194 try:
195 value = self.settingArgDict[section.lower()][setting.lower()].upper() in ['1','YES','JA','TRUE']
196 return value
197 except Exception as e:
198 pass
199 try:
171200 value = self.env['settings'].getboolean(section, setting)
172201 except:
173202 value = self.settings[section][setting]
177206 try:
178207 if self.env['runtime'][driverType] != None:
179208 self.env['runtime'][driverType].shutdown(self.env)
180 spec = importlib.util.spec_from_file_location(driverName, os.path.dirname(os.path.realpath(__main__.__file__)) + "/" + driverType + '/' + driverName + '.py')
181 driver_mod = importlib.util.module_from_spec(spec)
182 spec.loader.exec_module(driver_mod)
209 driver_mod = module_utils.importModule(driverName,
210 fenrirPath + "/" + driverType + '/' + driverName + '.py')
183211 self.env['runtime'][driverType] = driver_mod.driver()
184212 self.env['runtime'][driverType].initialize(self.env)
185 self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType +" OK",debug.debugLevel.INFO, onAnyLevel=True)
213 self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") OK",debug.debugLevel.INFO, onAnyLevel=True)
186214 except Exception as e:
187215 self.env['runtime'][driverType] = None
188 self.env['runtime']['debug'].writeDebugOut("Loading " + driverType + " Driver : "+ str(e), debug.debugLevel.ERROR)
216 self.env['runtime']['debug'].writeDebugOut('Loading Driver ' + driverType + ' (' + driverName +") FAILED:"+ str(e), debug.debugLevel.ERROR)
189217 def shutdownDriver(self, driverType):
190218 if self.env['runtime'][driverType] == None:
191219 return
204232 for key in keyList:
205233 if not key in self.env['input']['scriptKey']:
206234 self.env['input']['scriptKey'].append(key)
207
208 def initFenrirConfig(self, environment = environment.environment, settingsRoot = '/etc/fenrir/', settingsFile='settings.conf', soundRoot = '/usr/share/sounds/fenrir/'):
209 environment['runtime']['debug'] = debug.debug()
235 def setOptionArgDict(self, section, option, value):
236 section = section.lower()
237 option = option.lower()
238 try:
239 e = self.settingArgDict[section]
240 except KeyError:
241 self.settingArgDict[section] = {}
242 self.settingArgDict[section][option] = str(value)
243
244 def parseSettingArgs(self, settingArgs):
245 for optionElem in settingArgs.split(';'):
246 if len(optionElem.split('#',1)) != 2:
247 continue
248 if len(optionElem.split('#',1)[1].split('=',1)) != 2:
249 continue
250 section = str(optionElem.split('#',1)[0]).lower()
251 option = str(optionElem.split('#',1)[1].split('=',1)[0]).lower()
252 value = optionElem.split('#',1)[1].split('=',1)[1]
253 self.setOptionArgDict(section, option, value)
254
255 def initFenrirConfig(self, cliArgs, fenrirManager = None, environment = environment.environment):
256 settingsRoot = '/etc/fenrir/'
257 settingsFile = cliArgs.setting
258 soundRoot = '/usr/share/sounds/fenrir/'
259 environment['runtime']['debug'] = debugManager.debugManager()
210260 environment['runtime']['debug'].initialize(environment)
261 # get fenrir settings root
211262 if not os.path.exists(settingsRoot):
212 if os.path.exists(os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/'):
213 settingsRoot = os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/'
263 if os.path.exists(fenrirPath +'/../../config/'):
264 settingsRoot = fenrirPath +'/../../config/'
214265 else:
215266 return None
267 # get settings file
268 if not os.path.exists(settingsFile):
269 if os.path.exists(settingsRoot + '/settings/settings.conf'):
270 settingsFile = settingsRoot + '/settings/settings.conf'
271 else:
272 return None
273 # get sound themes root
216274 if not os.path.exists(soundRoot):
217 if os.path.exists(os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/sound/'):
218 soundRoot = os.path.dirname(os.path.realpath(__main__.__file__)) +'/../../config/sound/'
275 if os.path.exists(fenrirPath + '/../../config/sound/'):
276 soundRoot = fenrirPath + '/../../config/sound/'
219277
220278 environment['runtime']['settingsManager'] = self
221279 environment['runtime']['settingsManager'].initialize(environment)
222280
223 validConfig = environment['runtime']['settingsManager'].loadSettings(settingsRoot + '/settings/' + settingsFile)
281 validConfig = environment['runtime']['settingsManager'].loadSettings(settingsFile)
224282 if not validConfig:
225283 return None
226
284
285 if cliArgs.options != '':
286 self.parseSettingArgs(cliArgs.options)
287 if cliArgs.debug:
288 self.setOptionArgDict('general', 'debugLevel', 3)
289 if cliArgs.print:
290 self.setOptionArgDict('general', 'debugLevel', 3)
291 self.setOptionArgDict('general', 'debugMode', 'PRINT')
227292 self.setFenrirKeys(self.getSetting('general','fenrirKeys'))
228293 self.setScriptKeys(self.getSetting('general','scriptKeys'))
229
294
230295 if not os.path.exists(self.getSetting('keyboard','keyboardLayout')):
231296 if os.path.exists(settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout')):
232297 self.setSetting('keyboard', 'keyboardLayout', settingsRoot + 'keyboard/' + self.getSetting('keyboard','keyboardLayout'))
254319 environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile'))
255320 else:
256321 environment['runtime']['settingsManager'].loadDicts(self.getSetting('general','punctuationProfile'))
257
258 environment['runtime']['inputManager'] = inputManager.inputManager()
259 environment['runtime']['inputManager'].initialize(environment)
322
323 if fenrirManager:
324 environment['runtime']['fenrirManager'] = fenrirManager
325 environment['runtime']['eventManager'] = eventManager.eventManager()
326 environment['runtime']['eventManager'].initialize(environment)
327 environment['runtime']['processManager'] = processManager.processManager()
328 environment['runtime']['processManager'].initialize(environment)
260329 environment['runtime']['outputManager'] = outputManager.outputManager()
261330 environment['runtime']['outputManager'].initialize(environment)
262331 environment['runtime']['commandManager'] = commandManager.commandManager()
263332 environment['runtime']['commandManager'].initialize(environment)
333 environment['runtime']['inputManager'] = inputManager.inputManager()
334 environment['runtime']['inputManager'].initialize(environment)
264335 environment['runtime']['punctuationManager'] = punctuationManager.punctuationManager()
265336 environment['runtime']['punctuationManager'].initialize(environment)
266337 environment['runtime']['cursorManager'] = cursorManager.cursorManager()
267338 environment['runtime']['cursorManager'].initialize(environment)
268339 environment['runtime']['applicationManager'] = applicationManager.applicationManager()
269340 environment['runtime']['applicationManager'].initialize(environment)
270
341 environment['runtime']['helpManager'] = helpManager.helpManager()
342 environment['runtime']['helpManager'].initialize(environment)
271343 if environment['runtime']['screenManager'] == None:
272344 environment['runtime']['screenManager'] = screenManager.screenManager()
273345 environment['runtime']['screenManager'].initialize(environment)
274346
275347 environment['runtime']['debug'].writeDebugOut('\/-------environment-------\/',debug.debugLevel.INFO, onAnyLevel=True)
276 environment['runtime']['debug'].writeDebugOut(str(environment),debug.debugLevel.INFO, onAnyLevel=True)
277 environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/',debug.debugLevel.INFO, onAnyLevel=True)
278 environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections
279 ),debug.debugLevel.INFO, onAnyLevel=True)
348 environment['runtime']['debug'].writeDebugOut(str(environment), debug.debugLevel.INFO, onAnyLevel=True)
349 environment['runtime']['debug'].writeDebugOut('\/-------settings.conf-------\/', debug.debugLevel.INFO, onAnyLevel=True)
350 environment['runtime']['debug'].writeDebugOut(str(environment['settings']._sections) , debug.debugLevel.INFO, onAnyLevel=True)
351 environment['runtime']['debug'].writeDebugOut('\/-------self.settingArgDict-------\/',debug.debugLevel.INFO, onAnyLevel=True)
352 environment['runtime']['debug'].writeDebugOut(str( self.settingArgDict) ,debug.debugLevel.INFO, onAnyLevel=True)
280353 return environment
281354
33 # Fenrir TTY screen reader
44 # By Chrys, Storm Dragon, and contributers.
55
6 import os, sys
7 import __main__
6 import os, sys, inspect
7 fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
88
9 if not os.path.dirname(os.path.realpath(__main__.__file__)) in sys.path:
10 sys.path.append(os.path.dirname(os.path.realpath(__main__.__file__)))
9 if not fenrirPath in sys.path:
10 sys.path.append(fenrirPath)
1111
12 import fenrir
12 from core import fenrirManager
1313
1414 def main():
15 app = fenrir.fenrir()
15 app = fenrirManager.fenrirManager()
1616 app.proceed()
1717 del app
1818
33 # Fenrir TTY screen reader
44 # By Chrys, Storm Dragon, and contributers.
55
6 import os, sys
7 import __main__
6 import os, sys, inspect
7 fenrirPath = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))))
88
9 if not os.path.dirname(os.path.realpath(__main__.__file__)) in sys.path:
10 sys.path.append(os.path.dirname(os.path.realpath(__main__.__file__)))
9 if not fenrirPath in sys.path:
10 sys.path.append(fenrirPath)
1111
12 import fenrir
12 from core import fenrirManager
1313 from daemonize import Daemonize
1414
1515 pidFile = "/run/fenrir.pid"
1616
1717 def main():
18 app = fenrir.fenrir()
18 app = fenrirManager.fenrirManager()
1919 app.proceed()
2020 del app
2121
2222 if __name__ == "__main__":
2323 # for debug in foreground
24 #daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, foreground=True,chdir=os.path.dirname(os.path.realpath(__main__.__file__)))
25 daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, chdir=os.path.dirname(os.path.realpath(__main__.__file__)))
24 #daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, foreground=True,chdir=os.path.dirname(os.path.realpath(fenrirVersion.__file__)))
25 daemon = Daemonize(app="fenrir-daemon", pid=pidFile, action=main, chdir=fenrirPath)
2626 daemon.start()
2727
+0
-137
src/fenrir/fenrir.py less more
0 #!/bin/python3
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import os, sys, signal, time
7 import __main__
8
9 if not os.path.dirname(os.path.realpath(__main__.__file__)) in sys.path:
10 sys.path.append(os.path.dirname(os.path.realpath(__main__.__file__)))
11
12 from core import settingsManager
13 from core import debug
14
15 class fenrir():
16 def __init__(self):
17 try:
18 self.environment = settingsManager.settingsManager().initFenrirConfig()
19 if not self.environment:
20 raise RuntimeError('Cannot Initialize. Maybe the configfile is not available or not parseable')
21 except RuntimeError:
22 raise
23 self.environment['runtime']['outputManager'].presentText("Start Fenrir", soundIcon='ScreenReaderOn', interrupt=True)
24 signal.signal(signal.SIGINT, self.captureSignal)
25 signal.signal(signal.SIGTERM, self.captureSignal)
26 self.wasCommand = False
27
28 def proceed(self):
29 while(self.environment['generalInformation']['running']):
30 try:
31 self.handleProcess()
32 except Exception as e:
33 self.environment['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
34 self.shutdown()
35
36 def handleProcess(self):
37 #startTime = time.time()
38 eventReceived = self.environment['runtime']['inputManager'].getInputEvent()
39 if eventReceived:
40 self.prepareCommand()
41 if not (self.wasCommand or self.environment['generalInformation']['tutorialMode']) or self.environment['runtime']['screenManager'].isSuspendingScreen():
42 self.environment['runtime']['inputManager'].writeEventBuffer()
43 if self.environment['runtime']['inputManager'].noKeyPressed():
44 if self.wasCommand:
45 self.wasCommand = False
46 self.environment['runtime']['inputManager'].clearEventBuffer()
47 if self.environment['generalInformation']['tutorialMode']:
48 self.environment['runtime']['inputManager'].clearEventBuffer()
49 if self.environment['input']['keyForeward'] > 0:
50 self.environment['input']['keyForeward'] -=1
51 self.environment['runtime']['screenManager'].update('onInput')
52 self.environment['runtime']['commandManager'].executeDefaultTrigger('onInput')
53 else:
54 self.environment['runtime']['screenManager'].update('onUpdate')
55 if self.environment['runtime']['applicationManager'].isApplicationChange():
56 self.environment['runtime']['commandManager'].executeDefaultTrigger('onApplicationChange')
57 self.environment['runtime']['commandManager'].executeSwitchTrigger('onSwitchApplicationProfile', \
58 self.environment['runtime']['applicationManager'].getPrevApplication(), \
59 self.environment['runtime']['applicationManager'].getCurrentApplication())
60
61 if self.environment['runtime']['screenManager'].isScreenChange():
62 self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenChanged')
63 else:
64 self.environment['runtime']['commandManager'].executeDefaultTrigger('onScreenUpdate')
65
66 self.handleCommands()
67 #print(time.time()-startTime)
68
69 def prepareCommand(self):
70 if self.environment['runtime']['screenManager'].isSuspendingScreen():
71 self.wasCommand = False
72 return
73 if self.environment['runtime']['inputManager'].noKeyPressed():
74 return
75 if self.environment['input']['keyForeward'] > 0:
76 return
77 shortcut = self.environment['runtime']['inputManager'].getCurrShortcut()
78 command = self.environment['runtime']['inputManager'].getCommandForShortcut(shortcut)
79 if len(self.environment['input']['prevDeepestInput']) <= len(self.environment['input']['currInput']):
80 self.wasCommand = command != '' or self.environment['runtime']['inputManager'].isFenrirKeyPressed() or self.environment['runtime']['inputManager'].isScriptKeyPressed()
81 if command == '':
82 return
83
84 self.environment['runtime']['commandManager'].queueCommand(command)
85
86
87 def handleCommands(self):
88 if not self.environment['runtime']['commandManager'].isCommandQueued():
89 return
90 self.environment['runtime']['commandManager'].executeCommand( self.environment['commandInfo']['currCommand'], 'commands')
91
92 def shutdownRequest(self):
93 self.environment['generalInformation']['running'] = False
94
95 def captureSignal(self, siginit, frame):
96 self.shutdownRequest()
97
98 def shutdown(self):
99 if self.environment['runtime']['inputManager']:
100 self.environment['runtime']['inputManager'].shutdown()
101 del self.environment['runtime']['inputManager']
102 self.environment['runtime']['outputManager'].presentText("Quit Fenrir", soundIcon='ScreenReaderOff', interrupt=True)
103 time.sleep(0.9) # wait a little for sound
104
105 if self.environment['runtime']['screenManager']:
106 self.environment['runtime']['screenManager'].shutdown()
107 del self.environment['runtime']['screenManager']
108 if self.environment['runtime']['commandManager']:
109 self.environment['runtime']['commandManager'].shutdown()
110 del self.environment['runtime']['commandManager']
111 if self.environment['runtime']['outputManager']:
112 self.environment['runtime']['outputManager'].shutdown()
113 del self.environment['runtime']['outputManager']
114 if self.environment['runtime']['punctuationManager']:
115 self.environment['runtime']['punctuationManager'].shutdown()
116 del self.environment['runtime']['punctuationManager']
117 if self.environment['runtime']['cursorManager']:
118 self.environment['runtime']['cursorManager'].shutdown()
119 del self.environment['runtime']['cursorManager']
120 if self.environment['runtime']['applicationManager']:
121 self.environment['runtime']['applicationManager'].shutdown()
122 del self.environment['runtime']['applicationManager']
123
124 if self.environment['runtime']['debug']:
125 self.environment['runtime']['debug'].shutdown()
126 del self.environment['runtime']['debug']
127 time.sleep(0.2) # wait a little before splatter it :)
128 self.environment = None
129
130 def main():
131 app = fenrir()
132 app.proceed()
133 del app
134
135 if __name__ == "__main__":
136 main()
0 #!/usr/bin/env python3
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import os, sys
7 import __main__
8
9 version = 1.5
10 codename = 'gampert'
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import time
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 self._initialized = False
12
13 def initialize(self, environment):
14 self.env = environment
15
16 def shutdown(self):
17 pass
18
19 def getInputEvent(self):
20 time.sleep(0.05)
21 if not self._initialized:
22 return None
23
24 def writeEventBuffer(self):
25 if not self._initialized:
26 return
27
28 def clearEventBuffer(self):
29 if not self._initialized:
30 return
31 del self.env['input']['eventBuffer'][:]
32
33 def updateInputDevices(self, force = False, init = False):
34 if not self._initialized:
35 return
36
37 def getLedState(self, led = 0):
38 if not self._initialized:
39 return False
40 return False
41
42 def toggleLedState(self, led = 0):
43 if not self._initialized:
44 return None
45
46 def grabDevices(self):
47 if not self._initialized:
48 return None
49
50 def releaseDevices(self):
51 if not self._initialized:
52 return None
53
54 def __del__(self):
55 if not self._initialized:
56 return None
57 self.releaseDevices()
58
59
+0
-211
src/fenrir/inputDriver/evdev.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 _evdevAvailable = False
7 _evdevAvailableError = ''
8 try:
9 import evdev
10 from evdev import InputDevice, UInput
11 _evdevAvailable = True
12 except Exception as e:
13 _evdevAvailableError = str(e)
14
15 import time
16 from select import select
17 from core import inputEvent
18 from core import debug
19
20 class driver():
21 def __init__(self):
22 self.iDevices = {}
23 self.uDevices = {}
24 self.ledDevices = {}
25 self._initialized = False
26
27 def initialize(self, environment):
28 self.env = environment
29 global _evdevAvailable
30 self._initialized = _evdevAvailable
31 if not self._initialized:
32 global _evdevAvailableError
33 self.env['runtime']['debug'].writeDebugOut('InputDriver: ' + _evdevAvailableError,debug.debugLevel.ERROR)
34 return
35 self.getInputDevices()
36
37 def shutdown(self):
38 pass
39 def getInputEvent(self):
40 if not self._initialized:
41 time.sleep(0.005) # dont flood CPU
42 return None
43 if not self.iDevices:
44 return None
45 if self.iDevices == {}:
46 return None
47
48 event = None
49 r, w, x = select(self.iDevices, [], [], self.env['runtime']['settingsManager'].getSettingAsFloat('screen', 'screenUpdateDelay'))
50 if r != []:
51 for fd in r:
52 event = self.iDevices[fd].read_one()
53 foreward = False
54 while(event):
55 self.env['input']['eventBuffer'].append( [self.iDevices[fd], self.uDevices[fd], event])
56 if event.type == evdev.events.EV_KEY:
57 if event.code != 0:
58 currMapEvent = self.mapEvent(event)
59 if not currMapEvent:
60 foreward = True
61 event = self.iDevices[fd].read_one()
62 continue
63 if not isinstance(currMapEvent['EventName'], str):
64 foreward = True
65 event = self.iDevices[fd].read_one()
66 continue
67 if not foreward:
68 if currMapEvent['EventState'] in [0,1,2]:
69 return currMapEvent
70 else:
71 if not event.type in [0,1,4]:
72 foreward = True
73 event = self.iDevices[fd].read_one()
74 if foreward:
75 self.writeEventBuffer()
76 self.clearEventBuffer()
77 return None
78
79 def writeEventBuffer(self):
80 if not self._initialized:
81 return
82 for iDevice, uDevice, event in self.env['input']['eventBuffer']:
83 self.writeUInput(uDevice, event)
84
85 def clearEventBuffer(self):
86 if not self._initialized:
87 return
88 del self.env['input']['eventBuffer'][:]
89
90 def writeUInput(self, uDevice, event):
91 if not self._initialized:
92 return
93 uDevice.write_event(event)
94 uDevice.syn()
95 def getInputDevices(self):
96 if not self._initialized:
97 return
98 deviceList = evdev.list_devices()
99 readableDevices = []
100 for dev in deviceList:
101 try:
102 open(dev)
103 readableDevices.append(dev)
104 except Exception as e:
105 self.env['runtime']['debug'].writeDebugOut("Skip Inputdevice : " + dev +' ' + str(e),debug.debugLevel.ERROR)
106 self.iDevices = map(evdev.InputDevice, (readableDevices))
107 self.ledDevices = map(evdev.InputDevice, (readableDevices))
108 # 3 pos absolute
109 # 2 pos relative
110 # 17 LEDs
111 # 1 Keys
112 # we try to filter out mices and other stuff here
113 if self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() == 'ALL':
114 self.iDevices = {dev.fd: dev for dev in self.iDevices if 1 in dev.capabilities()}
115 self.ledDevices = {dev.fd: dev for dev in self.ledDevices if 1 in dev.capabilities() and 17 in dev.capabilities()}
116 elif self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper() == 'NOMICE':
117 self.iDevices = {dev.fd: dev for dev in self.iDevices if 1 in dev.capabilities() and not 3 in dev.capabilities() and not 2 in dev.capabilities()}
118 self.ledDevices = {dev.fd: dev for dev in self.ledDevices if 1 in dev.capabilities() and 17 in dev.capabilities() and not 3 in dev.capabilities() and not 2 in dev.capabilities()}
119 else:
120 self.iDevices = {dev.fd: dev for dev in self.iDevices if dev.name.upper() in self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper().split(',')}
121 self.ledDevices = {dev.fd: dev for dev in self.ledDevices if dev.name.upper() in self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper().split(',')}
122
123 def mapEvent(self, event):
124 if not self._initialized:
125 return None
126 if not event:
127 return None
128 mEvent = inputEvent.inputEvent
129 try:
130 mEvent['EventName'] = evdev.ecodes.keys[event.code]
131 mEvent['EventValue'] = event.code
132 mEvent['EventSec'] = event.sec
133 mEvent['EventUsec'] = event.usec
134 mEvent['EventState'] = event.value
135 return mEvent
136 except Exception as e:
137 return None
138
139 def getLedState(self, led = 0):
140 if not self._initialized:
141 return None
142 # 0 = Numlock
143 # 1 = Capslock
144 # 2 = Rollen
145 if self.ledDevices == None:
146 return False
147 if self.ledDevices == {}:
148 return False
149 for fd, dev in self.ledDevices.items():
150 return led in dev.leds()
151 return False
152 def toggleLedState(self, led = 0):
153 if not self._initialized:
154 return None
155 ledState = self.getLedState(led)
156 for i in self.ledDevices:
157 if ledState == 1:
158 self.ledDevices[i].set_led(led , 0)
159 else:
160 self.ledDevices[i].set_led(led , 1)
161 def grabDevices(self):
162 if not self._initialized:
163 return None
164 # leve the old code until the new one is better tested
165 # for fd in self.iDevices:
166 # dev = self.iDevices[fd]
167 # cap = dev.capabilities()
168 # del cap[0]
169 # self.uDevices[fd] = UInput(
170 # cap,
171 # dev.name,
172 # #dev.info.vendor,
173 # #dev.info.product,
174 # #dev.version,
175 # #dev.info.bustype,
176 # #'/dev/uinput'
177 # )
178 # dev.grab()
179 for fd in self.iDevices:
180 try:
181 self.uDevices[fd] = UInput.from_device(self.iDevices[fd].fn)
182 self.iDevices[fd].grab()
183 except Exception as e:
184 self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR)
185 def releaseDevices(self):
186 if not self._initialized:
187 return None
188 for fd in self.iDevices:
189 try:
190 self.iDevices[fd].ungrab()
191 except:
192 pass
193 try:
194 self.iDevices[fd].close()
195 except:
196 pass
197 try:
198 self.uDevices[fd].close()
199 except:
200 pass
201
202 self.iDevices.clear()
203 self.uDevices.clear()
204
205 def __del__(self):
206 if not self._initialized:
207 return None
208 self.releaseDevices()
209
210
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 _evdevAvailable = False
7 _udevAvailable = False
8 _evdevAvailableError = ''
9 _udevAvailableError = ''
10 try:
11 import evdev
12 from evdev import InputDevice, UInput
13 _evdevAvailable = True
14 except Exception as e:
15 _evdevAvailableError = str(e)
16
17 try:
18 import pyudev
19 _udevAvailable = True
20 except Exception as e:
21 _udevAvailableError = str(e)
22
23 import time
24 from select import select
25 import multiprocessing
26 from multiprocessing.sharedctypes import Value
27 from ctypes import c_bool
28
29 from core.eventData import fenrirEventType
30 from core import inputData
31 from core import debug
32
33
34 class driver():
35 def __init__(self):
36 self._manager = multiprocessing.Manager()
37 self.iDevices = {}
38 self.iDevicesFD = self._manager.list()
39 self.uDevices = {}
40 self.iDeviceNo = 0
41 self._initialized = False
42 self.watchDog = Value(c_bool, True)
43 def initialize(self, environment):
44 self.env = environment
45 global _evdevAvailable
46 global _udevAvailable
47 self._initialized = _evdevAvailable
48 if not self._initialized:
49 global _evdevAvailableError
50 self.env['runtime']['debug'].writeDebugOut('InputDriver: ' + _evdevAvailableError,debug.debugLevel.ERROR)
51 return
52 if _udevAvailable:
53 self.env['runtime']['processManager'].addCustomEventThread(self.plugInputDeviceWatchdogUdev)
54 else:
55 self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.PlugInputDevice, self.plugInputDeviceWatchdogTimer)
56 self.env['runtime']['processManager'].addSimpleEventThread(fenrirEventType.KeyboardInput, self.inputWatchdog, {'dev':self.iDevicesFD})
57 def plugInputDeviceWatchdogUdev(self,active , eventQueue):
58 context = pyudev.Context()
59 monitor = pyudev.Monitor.from_netlink(context)
60 monitor.filter_by(subsystem='input')
61 monitor.start()
62 while active.value:
63 devices = monitor.poll(2)
64 if devices:
65 while monitor.poll(0.5):
66 time.sleep(0.2)
67 eventQueue.put({"Type":fenrirEventType.PlugInputDevice,"Data":None})
68 return time.time()
69 def plugInputDeviceWatchdogTimer(self, active):
70 time.sleep(2.5)
71 return time.time()
72 def shutdown(self):
73 if not self._initialized:
74 return
75 def inputWatchdog(self,active , params):
76 try:
77 deviceFd = []
78 while self.watchDog.value == 0:
79 if active.value == 0:
80 return
81 r = []
82 while r == []:
83 if active.value == 0:
84 return
85 r, w, x = select(list(params['dev']), [], [], 0.3)
86 self.watchDog.value = 0
87 except:
88 pass
89 def getInputEvent(self):
90 if not self.hasIDevices():
91 self.watchDog.value = 1
92 return None
93 event = None
94 r, w, x = select(self.iDevices, [], [], 0.00001)
95 if r != []:
96 for fd in r:
97 try:
98 event = self.iDevices[fd].read_one()
99 except:
100 self.removeDevice(fd)
101 self.watchDog.value = 1
102 return None
103 foreward = False
104 while(event):
105 self.env['input']['eventBuffer'].append( [self.iDevices[fd], self.uDevices[fd], event])
106 if event.type == evdev.events.EV_KEY:
107 if event.code != 0:
108 currMapEvent = self.mapEvent(event)
109 if not currMapEvent:
110 foreward = True
111 event = self.iDevices[fd].read_one()
112 continue
113 if not isinstance(currMapEvent['EventName'], str):
114 foreward = True
115 event = self.iDevices[fd].read_one()
116 continue
117 if not foreward:
118 if currMapEvent['EventState'] in [0,1,2]:
119 self.watchDog.value = 1
120 return currMapEvent
121 else:
122 if not event.type in [0,1,4]:
123 foreward = True
124 event = self.iDevices[fd].read_one()
125 if foreward:
126 self.writeEventBuffer()
127 self.clearEventBuffer()
128 self.watchDog.value = 1
129 return None
130
131 def writeEventBuffer(self):
132 if not self._initialized:
133 return
134 for iDevice, uDevice, event in self.env['input']['eventBuffer']:
135 self.writeUInput(uDevice, event)
136
137 def clearEventBuffer(self):
138 if not self._initialized:
139 return
140 del self.env['input']['eventBuffer'][:]
141
142 def writeUInput(self, uDevice, event):
143 if not self._initialized:
144 return
145 uDevice.write_event(event)
146 uDevice.syn()
147 time.sleep(0.00001)
148
149 def updateInputDevices(self, force = False, init = False):
150 if init:
151 self.removeAllDevices()
152 deviceFileList = evdev.list_devices()
153 if not force and False:
154 if len(deviceFileList) == self.iDeviceNo:
155 return
156 mode = self.env['runtime']['settingsManager'].getSetting('keyboard', 'device').upper()
157 iDevicesFiles = []
158 for device in self.iDevices:
159 iDevicesFiles.append(self.iDevices[device].fn)
160 if len(iDevicesFiles) == len(deviceFileList):
161 return
162 eventType = evdev.events
163 for deviceFile in deviceFileList:
164 try:
165 if deviceFile in iDevicesFiles:
166 continue
167 try:
168 open(deviceFile)
169 except Exception as e:
170 self.env['runtime']['debug'].writeDebugOut("Not readable Inputdevice : " + deviceFile +' ' + str(e),debug.debugLevel.ERROR)
171 continue
172 # 3 pos absolute
173 # 2 pos relative
174 # 1 Keys
175 currDevice = evdev.InputDevice(deviceFile)
176 if currDevice.name.upper() in ['','SPEAKUP','PY-EVDEV-UINPUT']:
177 continue
178 if 'BRLTTY' in currDevice.name.upper():
179 continue
180 cap = currDevice.capabilities()
181 if mode in ['ALL','NOMICE']:
182 if eventType.EV_KEY in cap:
183 if 116 in cap[eventType.EV_KEY] and len(cap[eventType.EV_KEY]) < 10:
184 self.env['runtime']['debug'].writeDebugOut('Device Skipped (has 116):' + currDevice.name,debug.debugLevel.INFO)
185 continue
186 if len(cap[eventType.EV_KEY]) < 30:
187 self.env['runtime']['debug'].writeDebugOut('Device Skipped (< 30 keys):' + currDevice.name,debug.debugLevel.INFO)
188 continue
189 if mode == 'ALL':
190 self.iDevices[currDevice.fd] = currDevice
191 self.grabDevice(currDevice.fd)
192 self.env['runtime']['debug'].writeDebugOut('Device added (ALL):' + self.iDevices[currDevice.fd].name, debug.debugLevel.INFO)
193 elif mode == 'NOMICE':
194 if not ((eventType.EV_REL in cap) or (eventType.EV_ABS in cap)):
195 self.iDevices[currDevice.fd] = currDevice
196 self.grabDevice(currDevice.fd)
197 self.env['runtime']['debug'].writeDebugOut('Device added (NOMICE):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO)
198 else:
199 self.env['runtime']['debug'].writeDebugOut('Device Skipped (NOMICE):' + currDevice.name,debug.debugLevel.INFO)
200 elif currDevice.name.upper() in mode.split(','):
201 self.iDevices[currDevice.fd] = currDevice
202 self.grabDevice(currDevice.fd)
203 self.env['runtime']['debug'].writeDebugOut('Device added (Name):' + self.iDevices[currDevice.fd].name,debug.debugLevel.INFO)
204 except Exception as e:
205 print(e)
206 self.env['runtime']['debug'].writeDebugOut("Device Skipped (Exception): " + deviceFile +' ' + currDevice.name +' '+ str(e),debug.debugLevel.INFO)
207 self.iDeviceNo = len(evdev.list_devices())
208 self.updateMPiDevicesFD()
209
210 def updateMPiDevicesFD(self):
211 for fd in self.iDevices:
212 if not fd in self.iDevicesFD:
213 self.iDevicesFD.append(fd)
214 for fd in self.iDevicesFD:
215 if not fd in self.iDevices:
216 self.iDevicesFD.remove(fd)
217 def mapEvent(self, event):
218 if not self._initialized:
219 return None
220 if not event:
221 return None
222 mEvent = inputData.inputEvent
223 try:
224 mEvent['EventName'] = evdev.ecodes.keys[event.code]
225 mEvent['EventValue'] = event.code
226 mEvent['EventSec'] = event.sec
227 mEvent['EventUsec'] = event.usec
228 mEvent['EventState'] = event.value
229 return mEvent
230 except Exception as e:
231 return None
232
233 def getLedState(self, led = 0):
234 if not self.hasIDevices():
235 return False
236 # 0 = Numlock
237 # 1 = Capslock
238 # 2 = Rollen
239 for fd, dev in self.iDevices.items():
240 if led in dev.leds():
241 return True
242 return False
243 def toggleLedState(self, led = 0):
244 if not self.hasIDevices():
245 return False
246 ledState = self.getLedState(led)
247 for i in self.iDevices:
248 # 17 LEDs
249 if 17 in self.iDevices[i].capabilities():
250 if ledState == 1:
251 self.iDevices[i].set_led(led , 0)
252 else:
253 self.iDevices[i].set_led(led , 1)
254 def grabAllDevices(self):
255 if not self._initialized:
256 return
257 for fd in self.iDevices:
258 self.grabDevice(fd)
259
260 def grabDevice(self, fd):
261 if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'grabDevices'):
262 self.uDevices[fd] = None
263 return
264 try:
265 self.uDevices[fd] = UInput.from_device(self.iDevices[fd].fn)
266 except Exception as e:
267 try:
268 self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: compat fallback: ' + str(e),debug.debugLevel.WARNING)
269 dev = self.iDevices[fd]
270 cap = dev.capabilities()
271 del cap[0]
272 self.uDevices[fd] = UInput(
273 cap,
274 dev.name,
275 )
276 except Exception as e:
277 self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: init Uinput not possible: ' + str(e),debug.debugLevel.ERROR)
278 return
279 try:
280 self.iDevices[fd].grab()
281 except Exception as e:
282 self.env['runtime']['debug'].writeDebugOut('InputDriver evdev: grabing not possible: ' + str(e),debug.debugLevel.ERROR)
283
284 def removeDevice(self,fd):
285 self.clearEventBuffer()
286 try:
287 self.iDevices[fd].ungrab()
288 except:
289 pass
290 try:
291 self.iDevices[fd].close()
292 except:
293 pass
294 try:
295 self.uDevices[fd].close()
296 except:
297 pass
298 try:
299 del(self.iDevices[fd])
300 except:
301 pass
302 try:
303 del(self.uDevices[fd])
304 except:
305 pass
306 self.updateMPiDevicesFD()
307
308 def hasIDevices(self):
309 if not self._initialized:
310 return False
311 if not self.iDevices:
312 return False
313 if len(self.iDevices) == 0:
314 return False
315 return True
316
317 def removeAllDevices(self):
318 if not self.hasIDevices():
319 return
320 devices = self.iDevices.copy()
321 for fd in devices:
322 self.removeDevice(fd)
323 self.iDevices.clear()
324 self.uDevices.clear()
325 self.iDeviceNo = 0
326
327 def __del__(self):
328 if not self._initialized:
329 return
330
331
+0
-179
src/fenrir/screenDriver/vcsa.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 import difflib
7 import re
8 import subprocess
9 import fcntl
10 import termios
11 import time
12 import dbus
13 from core import debug
14 from utils import screen_utils
15
16 class driver():
17 def __init__(self):
18 self.vcsaDevicePath = '/dev/vcsa'
19 def initialize(self, environment):
20 self.env = environment
21 def shutdown(self):
22 pass
23 def getCurrScreen(self):
24 self.env['screenData']['oldTTY'] = self.env['screenData']['newTTY']
25 try:
26 currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r')
27 self.env['screenData']['newTTY'] = str(currScreenFile.read()[3:-1])
28 currScreenFile.close()
29 except Exception as e:
30 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
31 def injectTextToScreen(self, text, screen = None):
32 useScreen = "/dev/tty" + self.env['screenData']['newTTY']
33 if screen != None:
34 useScreen = screen
35 with open(useScreen, 'w') as fd:
36 for c in text:
37 fcntl.ioctl(fd, termios.TIOCSTI, c)
38
39 def getCurrApplication(self):
40 apps = []
41 try:
42 currScreen = self.env['screenData']['newTTY']
43 apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
44 except Exception as e:
45 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
46 return
47 try:
48 for i in apps:
49 i = i.upper()
50 i = i.split()
51 i[0] = i[0]
52 i[1] = i[1]
53 if '+' in i[2]:
54 if i[0] != '':
55 if not "GREP" == i[0] and \
56 not "SH" == i[0] and \
57 not "PS" == i[0]:
58 if "TTY"+currScreen in i[1]:
59 if self.env['screenData']['newApplication'] != i[0]:
60 self.env['screenData']['newApplication'] = i[0]
61 return
62 except Exception as e:
63 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
64 return
65
66 def getSessionInformation(self):
67 progname = 'org.freedesktop.login1'
68 objpath = '/org/freedesktop/login1'
69 intfname = 'org.freedesktop.login1.Manager'
70 methname = 'ListSessions'
71
72 bus = dbus.SystemBus()
73
74 obj = bus.get_object(progname, objpath)
75 inf = dbus.Interface(obj, intfname)
76 meth = inf.get_dbus_method(methname)
77
78 sessions = meth()
79 self.env['screenData']['autoIgnoreScreens'] = []
80 for session in sessions:
81 obj = bus.get_object(progname, session[4])
82 inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
83 sessionType = inf.Get('org.freedesktop.login1.Session', 'Type')
84 screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY'))
85 screen = screen[screen.upper().find('TTY') + 3:]
86 if sessionType.upper() == 'X11':
87 self.env['screenData']['autoIgnoreScreens'].append(screen)
88
89 def update(self, trigger='onUpdate'):
90 newContentBytes = b''
91 try:
92 # read screen
93 vcsa = open(self.vcsaDevicePath + self.env['screenData']['newTTY'],'rb',0)
94 newContentBytes = vcsa.read()
95 vcsa.close()
96 if len(newContentBytes) < 5:
97 return
98 except Exception as e:
99 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
100 return
101 screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
102 # set new "old" values
103 self.env['screenData']['oldContentBytes'] = self.env['screenData']['newContentBytes']
104 self.env['screenData']['oldContentText'] = self.env['screenData']['newContentText']
105 self.env['screenData']['oldContentAttrib'] = self.env['screenData']['newContentAttrib']
106 self.env['screenData']['oldCursor'] = self.env['screenData']['newCursor'].copy()
107 if self.env['screenData']['newCursorAttrib']:
108 self.env['screenData']['oldCursorAttrib'] = self.env['screenData']['newCursorAttrib'].copy()
109 self.env['screenData']['oldDelta'] = self.env['screenData']['newDelta']
110 self.env['screenData']['oldAttribDelta'] = self.env['screenData']['newAttribDelta']
111 self.env['screenData']['oldNegativeDelta'] = self.env['screenData']['newNegativeDelta']
112 self.env['screenData']['newContentBytes'] = newContentBytes
113 # get metadata like cursor or screensize
114 self.env['screenData']['lines'] = int( self.env['screenData']['newContentBytes'][0])
115 self.env['screenData']['columns'] = int( self.env['screenData']['newContentBytes'][1])
116 self.env['screenData']['newCursor']['x'] = int( self.env['screenData']['newContentBytes'][2])
117 self.env['screenData']['newCursor']['y'] = int( self.env['screenData']['newContentBytes'][3])
118 # analyze content
119 self.env['screenData']['newContentText'] = self.env['screenData']['newContentBytes'][4:][::2].decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
120 self.env['screenData']['newContentText'] = screen_utils.removeNonprintable(self.env['screenData']['newContentText'])
121 self.env['screenData']['newContentAttrib'] = self.env['screenData']['newContentBytes'][5:][::2]
122 self.env['screenData']['newContentText'] = screen_utils.insertNewlines(self.env['screenData']['newContentText'], self.env['screenData']['columns'])
123
124 if self.env['screenData']['newTTY'] != self.env['screenData']['oldTTY']:
125 self.env['screenData']['oldContentBytes'] = b''
126 self.env['screenData']['oldContentAttrib'] = b''
127 self.env['screenData']['oldContentText'] = ''
128 self.env['screenData']['oldCursor']['x'] = 0
129 self.env['screenData']['oldCursor']['y'] = 0
130 self.env['screenData']['oldDelta'] = ''
131 self.env['screenData']['oldAttribDelta'] = ''
132 self.env['screenData']['oldCursorAttrib'] = None
133 self.env['screenData']['newCursorAttrib'] = None
134 self.env['screenData']['oldNegativeDelta'] = ''
135 # initialize current deltas
136 self.env['screenData']['newNegativeDelta'] = ''
137 self.env['screenData']['newDelta'] = ''
138 self.env['screenData']['newAttribDelta'] = ''
139
140 # changes on the screen
141 oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['oldContentText']))
142 newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screenData']['newContentText']))
143 typing = False
144 if (self.env['screenData']['oldContentText'] != self.env['screenData']['newContentText']) and \
145 (self.env['screenData']['newContentText'] != '' ):
146 if oldScreenText == '' and\
147 newScreenText != '':
148 self.env['screenData']['newDelta'] = newScreenText
149 else:
150 cursorLineStart = self.env['screenData']['newCursor']['y'] * self.env['screenData']['columns'] + self.env['screenData']['newCursor']['y']
151 cursorLineEnd = cursorLineStart + self.env['screenData']['columns']
152 if self.env['screenData']['oldCursor']['x'] != self.env['screenData']['newCursor']['x'] and \
153 self.env['screenData']['oldCursor']['y'] == self.env['screenData']['newCursor']['y'] and \
154 self.env['screenData']['newContentText'][:cursorLineStart] == self.env['screenData']['oldContentText'][:cursorLineStart]:
155
156 oldScreenText = self.env['screenData']['oldContentText'][cursorLineStart:cursorLineEnd]
157 oldScreenText = re.sub(' +',' ',oldScreenText)
158 newScreenText = self.env['screenData']['newContentText'][cursorLineStart:cursorLineEnd]
159 newScreenText = re.sub(' +',' ',newScreenText)
160 diff = difflib.ndiff(oldScreenText, newScreenText)
161 typing = True
162 else:
163 diff = difflib.ndiff( oldScreenText.split('\n'),\
164 newScreenText.split('\n'))
165
166 diffList = list(diff)
167
168 if self.env['runtime']['settingsManager'].getSetting('general', 'newLinePause') and not typing:
169 self.env['screenData']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
170 else:
171 self.env['screenData']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
172 self.env['screenData']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
173
174 # track highlighted
175 if self.env['screenData']['oldContentAttrib'] != self.env['screenData']['newContentAttrib']:
176 if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
177 self.env['screenData']['newAttribDelta'], self.env['screenData']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screenData']['oldContentAttrib'], self.env['screenData']['newContentAttrib'], self.env['screenData']['newContentText'], self.env['screenData']['columns'])
178
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 #attrib:
6 #http://rampex.ihep.su/Linux/linux_howto/html/tutorials/mini/Colour-ls-6.html
7 #0 = black, 1 = blue, 2 = green, 3 = cyan, 4 = red, 5 = purple, 6 = brown/yellow, 7 = white.
8 #https://github.com/jwilk/vcsapeek/blob/master/linuxvt.py
9 #blink = 5 if attr & 1 else 0
10 #bold = 1 if attr & 16 else 0
11
12
13 import difflib
14 import re
15 import subprocess
16 import glob, os
17 import termios
18 import time
19 import select
20 import dbus
21 import fcntl
22 from array import array
23 import errno
24 import sys
25 from utils import screen_utils
26 from fcntl import ioctl
27 from struct import unpack_from, unpack, pack
28 from core import debug
29 from core.eventData import fenrirEventType
30
31
32 class driver():
33 def __init__(self):
34 self.vcsaDevicePath = '/dev/vcsa'
35 self.ListSessions = None
36 self.charmap = {}
37 self.bgColorNames = {0: _('black'), 1: _('blue'), 2: _('green'), 3: _('cyan'), 4: _('red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('white')}
38 self.fgColorNames = {0: _('Black'), 1: _('Blue'), 2: _('Green'), 3: _('Cyan'), 4: _('Red'), 5: _('Magenta'), 6: _('brown/yellow'), 7: _('Light gray'), 8: _('Dark gray'), 9: _('Light blue'), 10: ('Light green'), 11: _('Light cyan'), 12: _('Light red'), 13: _('Light magenta'), 14: _('Light yellow'), 15: _('White')}
39 self.hichar = None
40 def initialize(self, environment):
41 self.env = environment
42 self.env['runtime']['processManager'].addCustomEventThread(self.updateWatchdog)
43 def shutdown(self):
44 pass
45 def getCurrScreen(self):
46 self.env['screen']['oldTTY'] = self.env['screen']['newTTY']
47 try:
48 currScreenFile = open('/sys/devices/virtual/tty/tty0/active','r')
49 self.env['screen']['newTTY'] = str(currScreenFile.read()[3:-1])
50 currScreenFile.close()
51 except Exception as e:
52 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
53 def injectTextToScreen(self, text, screen = None):
54 useScreen = "/dev/tty" + self.env['screen']['newTTY']
55 if screen != None:
56 useScreen = screen
57 with open(useScreen, 'w') as fd:
58 for c in text:
59 fcntl.ioctl(fd, termios.TIOCSTI, c)
60
61 def getCurrApplication(self):
62 apps = []
63 try:
64 currScreen = self.env['screen']['newTTY']
65 apps = subprocess.Popen('ps -t tty' + currScreen + ' -o comm,tty,stat', shell=True, stdout=subprocess.PIPE).stdout.read().decode()[:-1].split('\n')
66 except Exception as e:
67 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
68 return
69 try:
70 for i in apps:
71 i = i.upper()
72 i = i.split()
73 i[0] = i[0]
74 i[1] = i[1]
75 if '+' in i[2]:
76 if i[0] != '':
77 if not "GREP" == i[0] and \
78 not "SH" == i[0] and \
79 not "PS" == i[0]:
80 if "TTY"+currScreen in i[1]:
81 if self.env['screen']['newApplication'] != i[0]:
82 self.env['screen']['newApplication'] = i[0]
83 return
84 except Exception as e:
85 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
86
87 def getSessionInformation(self):
88 try:
89 bus = dbus.SystemBus()
90 if not self.ListSessions:
91 obj = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1')
92 inf = dbus.Interface(obj, 'org.freedesktop.login1.Manager')
93 self.ListSessions = inf.get_dbus_method('ListSessions')
94 sessions = self.ListSessions()
95 self.env['screen']['autoIgnoreScreens'] = []
96 for session in sessions:
97 obj = bus.get_object('org.freedesktop.login1', session[4])
98 inf = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
99 sessionType = inf.Get('org.freedesktop.login1.Session', 'Type')
100 screen = str(inf.Get('org.freedesktop.login1.Session', 'VTNr'))
101 if screen == '':
102 screen = str(inf.Get('org.freedesktop.login1.Session', 'TTY'))
103 screen = screen[screen.upper().find('TTY') + 3:]
104 if screen == '':
105 self.env['runtime']['debug'].writeDebugOut('No TTY found for session:' + session[4],debug.debugLevel.ERROR)
106 return
107 if sessionType.upper() == 'X11':
108 self.env['screen']['autoIgnoreScreens'].append(screen)
109 if screen == self.env['screen']['newTTY'] :
110 if self.env['general']['currUser'] != session[2]:
111 self.env['general']['prevUser'] = self.env['general']['currUser']
112 self.env['general']['currUser'] = session[2]
113 except Exception as e:
114 self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)
115 self.env['screen']['autoIgnoreScreens'] = []
116 self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO)
117
118 def updateWatchdog(self,active , eventQueue):
119 try:
120 vcsa = {}
121 vcsaDevices = glob.glob('/dev/vcsa*')
122 for vcsaDev in vcsaDevices:
123 index = vcsaDev[9:]
124 vcsa[str(index)] = open(vcsaDev,'rb')
125
126 tty = open('/sys/devices/virtual/tty/tty0/active','r')
127 currScreen = str(tty.read()[3:-1])
128 oldScreen = currScreen
129 watchdog = select.epoll()
130 watchdog.register(vcsa[currScreen], select.POLLPRI | select.POLLERR)
131 watchdog.register(tty, select.POLLPRI | select.POLLERR)
132 while active.value == 1:
133 changes = watchdog.poll(2)
134 for change in changes:
135 fileno = change[0]
136 event = change[1]
137 if fileno == tty.fileno():
138 self.env['runtime']['debug'].writeDebugOut('ScreenChange',debug.debugLevel.INFO)
139 tty.seek(0)
140 currScreen = str(tty.read()[3:-1])
141 if currScreen != oldScreen:
142 try:
143 watchdog.unregister(vcsa[ oldScreen ])
144 except:
145 pass
146 try:
147 watchdog.register(vcsa[ currScreen ], select.POLLPRI | select.POLLERR)
148 except:
149 pass
150 oldScreen = currScreen
151 eventQueue.put({"Type":fenrirEventType.ScreenChanged,"Data":''})
152 try:
153 vcsa[currScreen].seek(0)
154 lastScreenContent = vcsa[currScreen].read()
155 except:
156 pass
157 else:
158 self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)
159 vcsa[currScreen].seek(0)
160 dirtyContent = vcsa[currScreen].read()
161 screenContent = b''
162 timeout = time.time()
163 while screenContent != dirtyContent:
164 screenContent = dirtyContent
165 if time.time() - timeout >= 0.4:
166 break
167 time.sleep(0.007)
168 vcsa[currScreen].seek(0)
169 dirtyContent = vcsa[currScreen].read()
170 eventQueue.put({"Type":fenrirEventType.ScreenUpdate,"Data":None})
171 except Exception as e:
172 self.env['runtime']['debug'].writeDebugOut('VCSA:updateWatchdog:' + str(e),debug.debugLevel.ERROR)
173
174 def updateCharMap(self, screen):
175 self.charmap = {}
176 try:
177 tty = open('/dev/tty' + screen, 'rb')
178 except Exception as e:
179 self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:' + str(e),debug.debugLevel.ERROR)
180 return
181 GIO_UNIMAP = 0x4B66
182 VT_GETHIFONTMASK = 0x560D
183 himask = array("H", (0,))
184 ioctl(tty, VT_GETHIFONTMASK, himask)
185 self.hichar, = unpack_from("@H", himask)
186 sz = 512
187 line = ''
188 while True:
189 try:
190 unipairs = array("H", [0]*(2*sz))
191 unimapdesc = array("B", pack("@HP", sz, unipairs.buffer_info()[0]))
192 ioctl(tty.fileno(), GIO_UNIMAP, unimapdesc)
193 break
194 except Exception as e:
195 self.env['runtime']['debug'].writeDebugOut('VCSA:updateCharMap:scaling up sz=' + str(sz) + ' ' + str(e),debug.debugLevel.WARNING)
196 sz *= 2
197 tty.close()
198 ncodes, = unpack_from("@H", unimapdesc)
199 utable = unpack_from("@%dH" % (2*ncodes), unipairs)
200 for u, b in zip(utable[::2], utable[1::2]):
201 if self.charmap.get(b) is None:
202 self.charmap[b] = chr(u)
203
204 def autoDecodeVCSA(self, allData, rows, cols):
205 allText = ''
206 allAttrib = []
207 i = 0
208 for y in range(rows):
209 lineText = ''
210 lineAttrib = []
211 for x in range(cols):
212 data = allData[i: i + 2]
213 i += 2
214 if data == b' \x07':
215 #attr = 7
216 #ink = 7
217 #paper = 0
218 #ch = ' '
219 lineAttrib.append((7,15,0,0,0,0)) # attribute, ink, paper, blink, bold, underline
220 lineText += ' '
221 continue
222 (sh,) = unpack("=H", data)
223 attr = (sh >> 8) & 0xFF
224 ch = sh & 0xFF
225 if self.hichar == 0x100:
226 attr >>= 1
227 ink = attr & 0x0F
228 paper = (attr>>4) & 0x0F
229 blink = 0
230 #if attr & 1:
231 # blink = 1
232 bold = 0
233 #if attr & 16:
234 # bold = 1
235 #if (ink != 7) or (paper != 0):
236 # print(ink,paper)
237 if sh & self.hichar:
238 ch |= 0x100
239 try:
240 lineText += self.charmap[ch]
241 except KeyError:
242 lineText += '?'
243 lineAttrib.append((attr,ink, paper,blink,bold,0)) # attribute, ink, paper, blink, bold, underline
244 allText += lineText + '\n'
245 allAttrib += lineAttrib
246 return str(allText), allAttrib
247 def getFenrirBGColor(self, attribute):
248 try:
249 return self.bgColorNames[attribute[2]]
250 except Exception as e:
251 print(e)
252 return ''
253 def getFenrirFGColor(self, attribute):
254 try:
255 return self.fgColorNames[attribute[1]]
256 except Exception as e:
257 print(e)
258 return ''
259 def getFenrirUnderline(self, attribute):
260 if attribute[5] == 1:
261 return _('underlined')
262 return ''
263 def getFenrirBold(self, attribute):
264 if attribute[4] == 1:
265 return _('bold')
266 return ''
267 def getFenrirBlink(self, attribute):
268 if attribute[3] == 1:
269 return _('blink')
270 return ''
271 def getFenrirFont(self, attribute):
272 return _('Default')
273 def getFenrirFontSize(self, attribute):
274 return _('Default')
275 def update(self, trigger='onUpdate'):
276 if trigger == 'onInput': # no need for an update on input for VCSA
277 return
278 newContentBytes = b''
279 try:
280 # read screen
281 vcsa = open(self.vcsaDevicePath + self.env['screen']['newTTY'],'rb',0)
282 newContentBytes = vcsa.read()
283 vcsa.close()
284 if len(newContentBytes) < 5:
285 return
286 except Exception as e:
287 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
288 return
289 # set new "old" values
290 self.env['screen']['oldContentBytes'] = self.env['screen']['newContentBytes']
291 self.env['screen']['oldContentText'] = self.env['screen']['newContentText']
292 self.env['screen']['oldContentAttrib'] = self.env['screen']['newContentAttrib']
293 self.env['screen']['oldCursor'] = self.env['screen']['newCursor'].copy()
294 if self.env['screen']['newCursorAttrib']:
295 self.env['screen']['oldCursorAttrib'] = self.env['screen']['newCursorAttrib'].copy()
296 self.env['screen']['oldDelta'] = self.env['screen']['newDelta']
297 self.env['screen']['oldAttribDelta'] = self.env['screen']['newAttribDelta']
298 self.env['screen']['oldNegativeDelta'] = self.env['screen']['newNegativeDelta']
299 self.env['screen']['newContentBytes'] = newContentBytes
300 # get metadata like cursor or screensize
301 self.env['screen']['lines'] = int( self.env['screen']['newContentBytes'][0])
302 self.env['screen']['columns'] = int( self.env['screen']['newContentBytes'][1])
303 self.env['screen']['newCursor']['x'] = int( self.env['screen']['newContentBytes'][2])
304 self.env['screen']['newCursor']['y'] = int( self.env['screen']['newContentBytes'][3])
305
306 # analyze content
307 self.updateCharMap(str(self.env['screen']['newTTY']))
308 self.env['screen']['newContentText'], \
309 self.env['screen']['newContentAttrib'] =\
310 self.autoDecodeVCSA(self.env['screen']['newContentBytes'][4:], self.env['screen']['lines'], self.env['screen']['columns'])
311
312 if self.env['screen']['newTTY'] != self.env['screen']['oldTTY']:
313 self.env['screen']['oldContentBytes'] = b''
314 self.env['screen']['oldContentAttrib'] = None
315 self.env['screen']['oldContentText'] = ''
316 self.env['screen']['oldCursor']['x'] = 0
317 self.env['screen']['oldCursor']['y'] = 0
318 self.env['screen']['oldDelta'] = ''
319 self.env['screen']['oldAttribDelta'] = ''
320 self.env['screen']['oldCursorAttrib'] = None
321 self.env['screen']['newCursorAttrib'] = None
322 self.env['screen']['oldNegativeDelta'] = ''
323 # initialize current deltas
324 self.env['screen']['newNegativeDelta'] = ''
325 self.env['screen']['newDelta'] = ''
326 self.env['screen']['newAttribDelta'] = ''
327
328 # changes on the screen
329 oldScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['oldContentText']))
330 newScreenText = re.sub(' +',' ',self.env['runtime']['screenManager'].getWindowAreaInText(self.env['screen']['newContentText']))
331 typing = False
332 if (self.env['screen']['oldContentText'] != self.env['screen']['newContentText']):
333 if self.env['screen']['newContentText'] != '' and self.env['screen']['oldContentText'] == '':
334 if oldScreenText == '' and\
335 newScreenText != '':
336 self.env['screen']['newDelta'] = newScreenText
337 else:
338 cursorLineStart = self.env['screen']['newCursor']['y'] * self.env['screen']['columns'] + self.env['screen']['newCursor']['y']
339 cursorLineEnd = cursorLineStart + self.env['screen']['columns']
340 if abs(self.env['screen']['oldCursor']['x'] - self.env['screen']['newCursor']['x']) == 1 and \
341 self.env['screen']['oldCursor']['y'] == self.env['screen']['newCursor']['y'] and \
342 self.env['screen']['newContentText'][:cursorLineStart] == self.env['screen']['oldContentText'][:cursorLineStart] and \
343 self.env['screen']['newContentText'][cursorLineEnd:] == self.env['screen']['oldContentText'][cursorLineEnd:]:
344 cursorLineStartOffset = cursorLineStart
345 cursorLineEndOffset = cursorLineEnd
346 #if cursorLineStart < cursorLineStart + self.env['screen']['newCursor']['x'] - 4:
347 # cursorLineStartOffset = cursorLineStart + self.env['screen']['newCursor']['x'] - 4
348 if cursorLineEnd > cursorLineStart + self.env['screen']['newCursor']['x'] + 3:
349 cursorLineEndOffset = cursorLineStart + self.env['screen']['newCursor']['x'] + 3
350 oldScreenText = self.env['screen']['oldContentText'][cursorLineStartOffset:cursorLineEndOffset]
351 oldScreenText = re.sub(' +',' ',oldScreenText)
352 newScreenText = self.env['screen']['newContentText'][cursorLineStartOffset:cursorLineEndOffset]
353 newScreenText = re.sub(' +',' ',newScreenText)
354 diff = difflib.ndiff(oldScreenText, newScreenText)
355 typing = True
356 else:
357 diff = difflib.ndiff( oldScreenText.split('\n'),\
358 newScreenText.split('\n'))
359
360 diffList = list(diff)
361
362 if self.env['runtime']['settingsManager'].getSetting('general', 'newLinePause') and not typing:
363 self.env['screen']['newDelta'] = '\n'.join(x[2:] for x in diffList if x[0] == '+')
364 else:
365 self.env['screen']['newDelta'] = ''.join(x[2:] for x in diffList if x[0] == '+')
366 self.env['screen']['newNegativeDelta'] = ''.join(x[2:] for x in diffList if x[0] == '-')
367
368 # track highlighted
369 if self.env['screen']['oldContentAttrib'] != self.env['screen']['newContentAttrib']:
370 if self.env['runtime']['settingsManager'].getSettingAsBool('focus', 'highlight'):
371 self.env['screen']['newAttribDelta'], self.env['screen']['newCursorAttrib'] = screen_utils.trackHighlights(self.env['screen']['oldContentAttrib'], self.env['screen']['newContentAttrib'], self.env['screen']['newContentText'], self.env['screen']['columns'])
372
+0
-38
src/fenrir/soundDriver/dummy.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class driver():
9 def __init__(self):
10 self.volume = None
11 self._initialized = False
12 def initialize(self, environment):
13 self.env = environment
14 def shutdown(self):
15 if not self._initialized:
16 return
17 self.cancel()
18 def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
19 if not self._initialized:
20 return
21 if interrupt:
22 self.cancel()
23 def playSoundFile(self, filePath, interrupt = True):
24 if not self._initialized:
25 return
26 if interrupt:
27 self.cancel()
28 def cancel(self):
29 if not self._initialized:
30 return
31 def setCallback(self, callback):
32 if not self._initialized:
33 return
34 def setVolume(self, volume):
35 if not self._initialized:
36 return
37 self.volume = volume
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7
8 class driver():
9 def __init__(self):
10 self.volume = None
11 self._initialized = False
12
13 def initialize(self, environment):
14 self.env = environment
15 self._initialized = True
16 print('SoundDummyDriver: Initialize')
17
18 def shutdown(self):
19 if not self._initialized:
20 return
21 self.cancel()
22 print('SoundDummyDriver: Shutdown')
23
24 def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
25 if not self._initialized:
26 return
27 if interrupt:
28 self.cancel()
29 print('SoundDummyDriver: playFrequence:' + ' freq:' + str(frequence) + ' duration:' + str(duration) + ' adjustVolume:' + str(adjustVolume) )
30 print('SoundDummyDriver: -----------------------------------')
31
32 def playSoundFile(self, filePath, interrupt = True):
33 if not self._initialized:
34 return
35 if interrupt:
36 self.cancel()
37 print('SoundDummyDriver: playSoundFile:' + str(filePath))
38 print('SoundDummyDriver: -----------------------------------')
39
40 def cancel(self):
41 if not self._initialized:
42 return
43 print('SoundDummyDriver: Cancel')
44
45 def setCallback(self, callback):
46 if not self._initialized:
47 return
48 print('SoundDummyDriver: setCallback')
49
50 def setVolume(self, volume):
51 if not self._initialized:
52 return
53 self.volume = volume
54 print('SoundDummyDriver: setVolume:' + str(self.volume))
+0
-66
src/fenrir/soundDriver/generic.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import subprocess
8
9 class driver():
10 def __init__(self):
11 self.proc = None
12 self.volume = 1.0
13 self.soundType = ''
14 self.soundFileCommand = ''
15 self.frequenceCommand = ''
16 self._initialized = False
17 def initialize(self, environment):
18 self.env = environment
19 self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand')
20 self.frequenceCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericFrequencyCommand')
21 if self.soundFileCommand == '':
22 self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile'
23 if self.frequenceCommand == '':
24 self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
25 self._initialized = True
26 def shutdown(self):
27 if not self._initialized:
28 return
29 self.cancel()
30 def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
31 if not self._initialized:
32 return
33 if interrupt:
34 self.cancel()
35 popenFrequenceCommand = self.frequenceCommand.replace('fenrirVolume', str(self.volume + adjustVolume ))
36 popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFreqDuration', str(duration))
37 popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFrequence', str(frequence))
38 self.proc = subprocess.Popen(popenFrequenceCommand, shell=True)
39 self.soundType = 'frequence'
40 def playSoundFile(self, filePath, interrupt = True):
41 if not self._initialized:
42 return
43 if interrupt:
44 self.cancel()
45 popenSoundFileCommand = self.soundFileCommand.replace('fenrirVolume', str(self.volume ))
46 popenSoundFileCommand = popenSoundFileCommand.replace('fenrirSoundFile', filePath)
47 self.proc = subprocess.Popen(popenSoundFileCommand, shell=True)
48 self.soundType = 'file'
49 def cancel(self):
50 if not self._initialized:
51 return
52 if self.soundType == '':
53 return
54 if self.soundType == 'file':
55 self.proc.kill()
56 if self.soundType == 'frequence':
57 self.proc.kill()
58 self.soundType = ''
59 def setCallback(self, callback):
60 if not self._initialized:
61 return
62 def setVolume(self, volume):
63 if not self._initialized:
64 return
65 self.volume = volume
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import subprocess
8
9 class driver():
10 def __init__(self):
11 self.proc = None
12 self.volume = 1.0
13 self.soundType = ''
14 self.soundFileCommand = ''
15 self.frequenceCommand = ''
16 self._initialized = False
17 def initialize(self, environment):
18 self.env = environment
19 self.soundFileCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericPlayFileCommand')
20 self.frequenceCommand = self.env['runtime']['settingsManager'].getSetting('sound', 'genericFrequencyCommand')
21 if self.soundFileCommand == '':
22 self.soundFileCommand = 'play -q -v fenrirVolume fenrirSoundFile'
23 if self.frequenceCommand == '':
24 self.frequenceCommand = 'play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence'
25 self._initialized = True
26 def shutdown(self):
27 if not self._initialized:
28 return
29 self.cancel()
30 def playFrequence(self, frequence = 1000, duration = 0.3, adjustVolume = 0):
31 if not self._initialized:
32 return
33 if interrupt:
34 self.cancel()
35 popenFrequenceCommand = self.frequenceCommand.replace('fenrirVolume', str(self.volume + adjustVolume ))
36 popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFreqDuration', str(duration))
37 popenFrequenceCommand = popenFrequenceCommand.replace('fenrirFrequence', str(frequence))
38 self.proc = subprocess.Popen(popenFrequenceCommand, shell=True)
39 self.soundType = 'frequence'
40 def playSoundFile(self, filePath, interrupt = True):
41 if not self._initialized:
42 return
43 if interrupt:
44 self.cancel()
45 popenSoundFileCommand = self.soundFileCommand.replace('fenrirVolume', str(self.volume ))
46 popenSoundFileCommand = popenSoundFileCommand.replace('fenrirSoundFile', filePath)
47 self.proc = subprocess.Popen(popenSoundFileCommand, shell=True)
48 self.soundType = 'file'
49 def cancel(self):
50 if not self._initialized:
51 return
52 if self.soundType == '':
53 return
54 if self.soundType == 'file':
55 self.proc.kill()
56 if self.soundType == 'frequence':
57 self.proc.kill()
58 self.soundType = ''
59 def setCallback(self, callback):
60 if not self._initialized:
61 return
62 def setVolume(self, volume):
63 if not self._initialized:
64 return
65 self.volume = volume
+0
-121
src/fenrir/soundDriver/gstreamer.py less more
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time, threading
8
9
10 _gstreamerAvailable = False
11 try:
12 import gi
13 from gi.repository import GLib
14 gi.require_version('Gst', '1.0')
15 from gi.repository import Gst
16 _gstreamerAvailable, args = Gst.init_check(None)
17 except Exception as e:
18 _gstreamerAvailable = False
19 _availableError = str(e)
20
21 class driver:
22 def __init__(self):
23 self._source = None
24 self._sink = None
25 self.volume = 1
26 self._initialized = False
27
28 def initialize(self, environment):
29 self.env = environment
30 global _gstreamerAvailable
31 self._initialized = _gstreamerAvailable
32 if not self._initialized:
33 global _availableError
34 self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)
35 return
36 self._player = Gst.ElementFactory.make('playbin', 'player')
37 bus = self._player.get_bus()
38 bus.add_signal_watch()
39 bus.connect("message", self._onPlayerMessage)
40
41 self._pipeline = Gst.Pipeline(name='fenrir-pipeline')
42 bus = self._pipeline.get_bus()
43 bus.add_signal_watch()
44 bus.connect("message", self._onPipelineMessage)
45
46 self._source = Gst.ElementFactory.make('audiotestsrc', 'src')
47 self._sink = Gst.ElementFactory.make('autoaudiosink', 'output')
48 self._pipeline.add(self._source)
49 self._pipeline.add(self._sink)
50 self._source.link(self._sink)
51 self.mainloop = GLib.MainLoop()
52 self.thread = threading.Thread(target=self.mainloop.run)
53 self.thread.start()
54
55 def shutdown(self):
56 if not self._initialized:
57 return
58 self.cancel()
59 self.mainloop.quit()
60
61 def _onPlayerMessage(self, bus, message):
62 if not self._initialized:
63 return
64 if message.type == Gst.MessageType.EOS:
65 self._player.set_state(Gst.State.NULL)
66 elif message.type == Gst.MessageType.ERROR:
67 self._player.set_state(Gst.State.NULL)
68 error, info = message.parse_error()
69 self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
70
71 def _onPipelineMessage(self, bus, message):
72 if not self._initialized:
73 return
74 if message.type == Gst.MessageType.EOS:
75 self._pipeline.set_state(Gst.State.NULL)
76 elif message.type == Gst.MessageType.ERROR:
77 self._pipeline.set_state(Gst.State.NULL)
78 error, info = message.parse_error()
79 self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
80
81 def _onTimeout(self, element):
82 if not self._initialized:
83 return
84 element.set_state(Gst.State.NULL)
85
86 def playSoundFile(self, fileName, interrupt=True):
87 if not self._initialized:
88 return
89 if interrupt:
90 self.cancel()
91 self._player.set_property('uri', 'file://%s' % fileName)
92 self._player.set_state(Gst.State.PLAYING)
93
94 def playFrequence(self, frequence, duration, adjustVolume, interrupt=True):
95 if not self._initialized:
96 return
97 if interrupt:
98 self.cancel()
99 self._source.set_property('volume', tone.volume)
100 self._source.set_property('freq', tone.frequency)
101 self._source.set_property('wave', tone.wave)
102 self._pipeline.set_state(Gst.State.PLAYING)
103 duration = int(1000 * tone.duration)
104 GLib.timeout_add(duration, self._onTimeout, self._pipeline)
105
106 def cancel(self, element=None):
107 if not self._initialized:
108 return
109 if element:
110 element.set_state(Gst.State.NULL)
111 return
112 self._player.set_state(Gst.State.NULL)
113 self._pipeline.set_state(Gst.State.NULL)
114 def setVolume(self, volume):
115 if not self._initialized:
116 return
117 self.volume = volume
118
119
120
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5
6 from core import debug
7 import time, threading
8
9
10 _gstreamerAvailable = False
11 try:
12 import gi
13 from gi.repository import GLib
14 gi.require_version('Gst', '1.0')
15 from gi.repository import Gst
16 _gstreamerAvailable, args = Gst.init_check(None)
17 except Exception as e:
18 _gstreamerAvailable = False
19 _availableError = str(e)
20
21 class driver:
22 def __init__(self):
23 self._source = None
24 self._sink = None
25 self.volume = 1
26 self._initialized = False
27
28 def initialize(self, environment):
29 self.env = environment
30 global _gstreamerAvailable
31 self._initialized = _gstreamerAvailable
32 if not self._initialized:
33 global _availableError
34 self.environment['runtime']['debug'].writeDebugOut('Gstreamer not available ' + _availableError,debug.debugLevel.ERROR)
35 return
36 self._player = Gst.ElementFactory.make('playbin', 'player')
37 bus = self._player.get_bus()
38 bus.add_signal_watch()
39 bus.connect("message", self._onPlayerMessage)
40
41 self._pipeline = Gst.Pipeline(name='fenrir-pipeline')
42 bus = self._pipeline.get_bus()
43 bus.add_signal_watch()
44 bus.connect("message", self._onPipelineMessage)
45
46 self._source = Gst.ElementFactory.make('audiotestsrc', 'src')
47 self._sink = Gst.ElementFactory.make('autoaudiosink', 'output')
48 self._pipeline.add(self._source)
49 self._pipeline.add(self._sink)
50 self._source.link(self._sink)
51 self.mainloop = GLib.MainLoop()
52 self.thread = threading.Thread(target=self.mainloop.run)
53 self.thread.start()
54
55 def shutdown(self):
56 if not self._initialized:
57 return
58 self.cancel()
59 self.mainloop.quit()
60
61 def _onPlayerMessage(self, bus, message):
62 if not self._initialized:
63 return
64 if message.type == Gst.MessageType.EOS:
65 self._player.set_state(Gst.State.NULL)
66 elif message.type == Gst.MessageType.ERROR:
67 self._player.set_state(Gst.State.NULL)
68 error, info = message.parse_error()
69 self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPlayerMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
70
71 def _onPipelineMessage(self, bus, message):
72 if not self._initialized:
73 return
74 if message.type == Gst.MessageType.EOS:
75 self._pipeline.set_state(Gst.State.NULL)
76 elif message.type == Gst.MessageType.ERROR:
77 self._pipeline.set_state(Gst.State.NULL)
78 error, info = message.parse_error()
79 self.env['runtime']['debug'].writeDebugOut('GSTREAMER: _onPipelineMessage'+ str(error) + str(info),debug.debugLevel.WARNING)
80
81 def _onTimeout(self, element):
82 if not self._initialized:
83 return
84 element.set_state(Gst.State.NULL)
85
86 def playSoundFile(self, fileName, interrupt=True):
87 if not self._initialized:
88 return
89 if interrupt:
90 self.cancel()
91 self._player.set_property('uri', 'file://%s' % fileName)
92 self._player.set_state(Gst.State.PLAYING)
93
94 def playFrequence(self, frequence, duration, adjustVolume, interrupt=True):
95 if not self._initialized:
96 return
97 if interrupt:
98 self.cancel()
99 self._source.set_property('volume', tone.volume)
100 self._source.set_property('freq', tone.frequency)
101 self._source.set_property('wave', tone.wave)
102 self._pipeline.set_state(Gst.State.PLAYING)
103 duration = int(1000 * tone.duration)
104 GLib.timeout_add(duration, self._onTimeout, self._pipeline)
105
106 def cancel(self, element=None):
107 if not self._initialized:
108 return
109 if element:
110 element.set_state(Gst.State.NULL)
111 return
112 self._player.set_state(Gst.State.NULL)
113 self._pipeline.set_state(Gst.State.NULL)
114 def setVolume(self, volume):
115 if not self._initialized:
116 return
117 self.volume = volume
118
119
120
+0
-67
src/fenrir/speechDriver/dummy.py less more
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # generic driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self._isInitialized = False
14 self.env = environment
15 def shutdown(self):
16 pass
17
18 def speak(self,text, queueable=True):
19 if not self._isInitialized:
20 return False
21 if not queueable:
22 self.cancel()
23 return True
24
25 def cancel(self):
26 if not self._isInitialized:
27 return False
28 return True
29
30 def setCallback(self, callback):
31 pass
32
33 def clear_buffer(self):
34 if not self._isInitialized:
35 return False
36 return True
37
38 def setVoice(self, voice):
39 if not self._isInitialized:
40 return False
41 return True
42
43 def setPitch(self, pitch):
44 if not self._isInitialized:
45 return False
46 return True
47
48 def setRate(self, rate):
49 if not self._isInitialized:
50 return False
51 return True
52
53 def setModule(self, module):
54 if not self._isInitialized:
55 return False
56 return True
57
58 def setLanguage(self, language):
59 if not self._isInitialized:
60 return False
61 return True
62
63 def setVolume(self, volume):
64 if not self._isInitialized:
65 return False
66 return True
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # generic driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 pass
12 def initialize(self, environment):
13 self._isInitialized = True
14 self.env = environment
15 print('SpeechDummyDriver: Iitialize')
16
17 def shutdown(self):
18 print('SpeechDummyDriver: Shutdown')
19
20 def speak(self,text, queueable=True):
21 if not self._isInitialized:
22 return
23 if not queueable:
24 self.cancel()
25 print('SpeechDummyDriver: Speak:'+text)
26 print('SpeechDummyDriver: -----------------------------------')
27
28 def cancel(self):
29 if not self._isInitialized:
30 return
31 print('SpeechDummyDriver: Cancel')
32
33 def setCallback(self, callback):
34 print('SpeechDummyDriver: setCallback')
35
36 def clear_buffer(self):
37 if not self._isInitialized:
38 return
39 print('SpeechDummyDriver: clear_buffer')
40
41 def setVoice(self, voice):
42 if not self._isInitialized:
43 return
44 print('SpeechDummyDriver: setVoice:' + str(voice))
45
46 def setPitch(self, pitch):
47 if not self._isInitialized:
48 return
49 print('SpeechDummyDriver: setPitch:' + str(pitch))
50
51 def setRate(self, rate):
52 if not self._isInitialized:
53 return
54 print('SpeechDummyDriver: setRate:' + str(rate))
55
56 def setModule(self, module):
57 if not self._isInitialized:
58 return
59 print('SpeechDummyDriver: setModule:' + str(module))
60
61 def setLanguage(self, language):
62 if not self._isInitialized:
63 return
64 print('SpeechDummyDriver: setLanguage:' + str(language))
65
66 def setVolume(self, volume):
67 if not self._isInitialized:
68 return
69 print('SpeechDummyDriver: setVolume:' + str(volume))
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # generic driver
6
7 from core import debug
8 from subprocess import Popen, PIPE
9 import pexpect
10 import sys
11 import time
12
13 class driver():
14 def __init__(self):
15 pass
16 def initialize(self, environment):
17 self._isInitialized = False
18 self.env = environment
19 try:
20 self.server = pexpect.spawnu('tclsh ' + self.env['runtime']['settingsManager'].getSetting('speech', 'serverPath'))
21 except Exception as e:
22 self.env['runtime']['debug'].writeDebugOut('speechDriver:initialize:' + str(e),debug.debugLevel.ERROR)
23 self._isInitialized = True
24
25 def shutdown(self):
26 if self.server:
27 try:
28 self.server.terminate()
29 except Exception as e:
30 self.env['runtime']['debug'].writeDebugOut('speechDriver:shutdown:self.server.terminate():' + str(e),debug.debugLevel.ERROR)
31
32 def speak(self,text, queueable=True):
33 if not self._isInitialized:
34 return
35 if not queueable:
36 self.cancel()
37 try:
38 cleanText = text.replace('}', '\}')
39 cleanText = cleanText.replace('{', '\{')
40 cleanText = cleanText.replace('*', '\*')
41 cleanText = cleanText.replace('"', '\"')
42 cleanText = cleanText.replace('\n', ' ')
43 cleanText = cleanText.replace('[', '\[')
44 #print(text.replace('"', '\\\"'))
45 self.server.sendline('tts_say ' + '"' + cleanText +'"')
46 except Exception as e:
47 self.env['runtime']['debug'].writeDebugOut('speechDriver:speak:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
48
49 def cancel(self):
50 if not self._isInitialized:
51 return
52 try:
53 self.server.sendline('s')
54 except Exception as e:
55 self.env['runtime']['debug'].writeDebugOut('speechDriver:cancel:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
56
57 def setCallback(self, callback):
58 pass
59
60 def clear_buffer(self):
61 if not self._isInitialized:
62 return
63
64 def setVoice(self, voice):
65 if not self._isInitialized:
66 return
67
68 def setPitch(self, pitch):
69 pass
70
71 def setRate(self, rate):
72 if not self._isInitialized:
73 return
74 try:
75 self.server.sendline('tts_set_speech_rate ' + str(int(rate * 400)) + '')
76 except Exception as e:
77 self.env['runtime']['debug'].writeDebugOut('speechDriver:setRate:self.server.sendline():' + str(e),debug.debugLevel.ERROR)
78
79 def setModule(self, module):
80 pass
81 def setLanguage(self, language):
82 if not self._isInitialized:
83 return
84 self.server.sendline('set_lang ' + language + '')
85 def setVolume(self, volume):
86 pass
+0
-81
src/fenrir/speechDriver/espeak.py less more
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # Espeak driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 self._es = None
12 self._isInitialized = False
13
14 def initialize(self, environment):
15 self.env = environment
16 try:
17 from espeak import espeak
18 self._es = espeak
19 self._isInitialized = True
20 except Exception as e:
21 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
22 self._initialized = False
23
24 def shutdown(self):
25 pass
26
27 def speak(self,text, interrupt=True):
28 if not self._isInitialized:
29 return False
30 if not interrupt:
31 self.cancel()
32 self._es.synth(text)
33 return True
34
35 def cancel(self):
36 if not self._isInitialized:
37 return False
38 self._es.cancel()
39 return True
40
41 def setCallback(self, callback):
42 pass
43
44 def clear_buffer(self):
45 if not self._isInitialized:
46 return False
47 return True
48
49 def setVoice(self, voice):
50 if not self._isInitialized:
51 return False
52 if voice =='':
53 return False
54 return self._es.set_voice(voice)
55
56 def setPitch(self, pitch):
57 if not self._isInitialized:
58 return False
59 return self._es.set_parameter(self._es.Parameter().Pitch, int(pitch * 99))
60
61 def setRate(self, rate):
62 if not self._isInitialized:
63 return False
64 return self._es.set_parameter(self._es.Parameter().Rate, int(rate * 500 + 100))
65
66 def setModule(self, module):
67 if not self._isInitialized:
68 return False
69
70 def setLanguage(self, language):
71 if not self._isInitialized:
72 return False
73 if language =='':
74 return False
75 return self._es.set_voice(language)
76
77 def setVolume(self, volume):
78 if not self._isInitialized:
79 return False
80 return self._es.set_parameter(self._es.Parameter().Volume, int(volume * 200))
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # Espeak driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 self._es = None
12 self._isInitialized = False
13
14 def initialize(self, environment):
15 self.env = environment
16 try:
17 from espeak import espeak
18 self._es = espeak
19 self._isInitialized = True
20 except Exception as e:
21 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
22 self._initialized = False
23
24 def shutdown(self):
25 pass
26
27 def speak(self,text, interrupt=True):
28 if not self._isInitialized:
29 return
30 if not interrupt:
31 self.cancel()
32 self._es.synth(text)
33
34 def cancel(self):
35 if not self._isInitialized:
36 return False
37 self._es.cancel()
38 return True
39
40 def setCallback(self, callback):
41 pass
42
43 def clear_buffer(self):
44 if not self._isInitialized:
45 return
46
47 def setVoice(self, voice):
48 if not self._isInitialized:
49 return
50 if voice =='':
51 return
52 return self._es.set_voice(voice)
53
54 def setPitch(self, pitch):
55 if not self._isInitialized:
56 return
57 return self._es.set_parameter(self._es.Parameter().Pitch, int(pitch * 99))
58
59 def setRate(self, rate):
60 if not self._isInitialized:
61 return
62 return self._es.set_parameter(self._es.Parameter().Rate, int(rate * 500 + 100))
63
64 def setModule(self, module):
65 if not self._isInitialized:
66 return
67
68 def setLanguage(self, language):
69 if not self._isInitialized:
70 return
71 if language =='':
72 return
73 return self._es.set_voice(language)
74
75 def setVolume(self, volume):
76 if not self._isInitialized:
77 return
78 return self._es.set_parameter(self._es.Parameter().Volume, int(volume * 200))
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # generic driver
6
7 from core import debug
8 from threading import Thread, Lock
9 from queue import Queue, Empty
10 from subprocess import Popen
11
12 class speakQueue(Queue):
13 def clear(self):
14 try:
15 while True:
16 self.get_nowait()
17 except Empty:
18 pass
19
20 class driver():
21 def __init__(self):
22 self.proc = None
23 self.speechThread = Thread(target=self.worker)
24 self.lock = Lock()
25 self.textQueue = speakQueue()
26 self.volume = ''
27 self.rate = ''
28 self.pitch = ''
29 self.module = ''
30 self.language = ''
31 self.voice = ''
32 def initialize(self, environment):
33 self.env = environment
34 self.minVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinVolume')
35 self.maxVolume = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxVolume')
36 self.minPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinPitch')
37 self.maxPitch = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxPitch')
38 self.minRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMinRate')
39 self.maxRate = self.env['runtime']['settingsManager'].getSettingAsInt('speech', 'fenrirMaxRate')
40
41 self.speechCommand = self.env['runtime']['settingsManager'].getSetting('speech', 'genericSpeechCommand')
42 if self.speechCommand == '':
43 self.speechCommand = 'espeak -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice "fenrirText"'
44 if False: #for debugging overwrite here
45 #self.speechCommand = 'spd-say --wait -r 100 -i 100 "fenrirText"'
46 self.speechCommand = 'flite -t "fenrirText"'
47
48 self._isInitialized = True
49 if self._isInitialized:
50 self.speechThread.start()
51 def shutdown(self):
52 if not self._isInitialized:
53 return
54 self.cancel()
55 self.textQueue.put(-1)
56
57 def speak(self,text, queueable=True):
58 if not self._isInitialized:
59 return
60 if not queueable:
61 self.cancel()
62 utterance = {
63 'text': text,
64 'volume': self.volume,
65 'rate': self.rate,
66 'pitch': self.pitch,
67 'module': self.module,
68 'language': self.language,
69 'voice': self.voice,
70 }
71 self.textQueue.put(utterance.copy())
72
73 def cancel(self):
74 if not self._isInitialized:
75 return
76 self.clear_buffer()
77 self.lock.acquire(True)
78 if self.proc:
79 try:
80 self.proc.terminate()
81 except Exception as e:
82 self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.terminate():' + str(e),debug.debugLevel.WARNING)
83 try:
84 self.proc.kill()
85 except Exception as e:
86 self.env['runtime']['debug'].writeDebugOut('speechDriver:Cancel:self.proc.kill():' + str(e),debug.debugLevel.WARNING)
87 self.proc = None
88 self.lock.release()
89 def setCallback(self, callback):
90 print('SpeechDummyDriver: setCallback')
91
92 def clear_buffer(self):
93 if not self._isInitialized:
94 return
95 self.textQueue.clear()
96
97 def setVoice(self, voice):
98 if not self._isInitialized:
99 return
100 self.voice = str(voice)
101
102 def setPitch(self, pitch):
103 if not self._isInitialized:
104 return
105 self.pitch = str(self.minPitch + pitch * (self.maxPitch - self.minPitch ))
106
107 def setRate(self, rate):
108 if not self._isInitialized:
109 return
110 self.rate = str(self.minRate + rate * (self.maxRate - self.minRate ))
111
112 def setModule(self, module):
113 if not self._isInitialized:
114 return
115 self.module = str(module)
116
117 def setLanguage(self, language):
118 if not self._isInitialized:
119 return
120 self.language = str(language)
121
122 def setVolume(self, volume):
123 if not self._isInitialized:
124 return
125 self.volume = str(self.minVolume + volume * (self.maxVolume - self.minVolume ))
126
127 def worker(self):
128 while True:
129 utterance = self.textQueue.get()
130
131 if isinstance(utterance, int):
132 if utterance == -1:
133 return
134 elif not isinstance(utterance, dict):
135 continue
136
137 for key in ['volume','module','language','voice','pitch','rate','text']:
138 if not key in utterance:
139 utterance[key] = ''
140 if not isinstance(utterance[key],str):
141 utterance[key] = ''
142 if key == 'text':
143 if utterance[key] == '':
144 continue
145
146 popenSpeechCommand = self.speechCommand
147 popenSpeechCommand = popenSpeechCommand.replace('fenrirVolume', str(utterance['volume'] ).replace('"',''))
148 popenSpeechCommand = popenSpeechCommand.replace('fenrirModule', str(utterance['module']).replace('"',''))
149 popenSpeechCommand = popenSpeechCommand.replace('fenrirLanguage', str(utterance['language']).replace('"',''))
150 popenSpeechCommand = popenSpeechCommand.replace('fenrirVoice', str(utterance['voice']).replace('"',''))
151 popenSpeechCommand = popenSpeechCommand.replace('fenrirPitch', str(utterance['pitch']).replace('"',''))
152 popenSpeechCommand = popenSpeechCommand.replace('fenrirRate', str(utterance['rate']).replace('"',''))
153 popenSpeechCommand = popenSpeechCommand.replace('fenrirText', str(utterance['text']).replace('"','').replace('\n',''))
154
155 try:
156 self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + popenSpeechCommand,debug.debugLevel.INFO)
157 self.lock.acquire(True)
158 self.proc = Popen(popenSpeechCommand, shell=True)
159 self.lock.release()
160 self.proc.wait()
161 except Exception as e:
162 self.env['runtime']['debug'].writeDebugOut('speechDriver:worker:' + str(e),debug.debugLevel.ERROR)
163
164 self.lock.acquire(True)
165 self.proc = None
166 self.lock.release()
167
+0
-109
src/fenrir/speechDriver/speechd.py less more
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # speech-dispatcher driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 self._sd = None
12 self._isInitialized = False
13 self._language = ''
14
15 def initialize(self, environment):
16 self.env = environment
17 try:
18 import speechd
19 self._sd = speechd.SSIPClient('fenrir')
20 self._punct = speechd.PunctuationMode()
21 self._isInitialized = True
22 except Exception as e:
23 self.env['runtime']['debug'].writeDebugOut(str(e),debug.debugLevel.ERROR)
24 self._initialized = False
25
26 def shutdown(self):
27 if not self._isInitialized:
28 return
29 self._isInitialized = False
30 self.cancel()
31 self._sd.close()
32 return
33
34 def speak(self,text, queueable=True):
35 if not self._isInitialized:
36 self.initialize(self.env)
37 if not self._isInitialized:
38 return False
39 if queueable == False: self.cancel()
40 try:
41 self._sd.set_synthesis_voice(self._language)
42 self._sd.set_punctuation(self._punct.NONE)
43 except Exception as e:
44 self._isInitialized = False
45 self._sd.speak(text)
46 return True
47
48 def cancel(self):
49 if not self._isInitialized:
50 return False
51 self._sd.cancel()
52 return True
53
54 def setCallback(self, callback):
55 pass
56
57 def clear_buffer(self):
58 if not self._isInitialized:
59 return False
60 return True
61
62 def setVoice(self, voice):
63 if not self._isInitialized:
64 return False
65 try:
66 if voice != '':
67 self._sd.set_voice(voice)
68 return True
69 except:
70 return False
71
72 def setPitch(self, pitch):
73 if not self._isInitialized:
74 return False
75 try:
76 self._sd.set_pitch(int(-100 + pitch * 200))
77 return True
78 except:
79 return False
80
81 def setRate(self, rate):
82 if not self._isInitialized:
83 return False
84 try:
85 self._sd.set_rate(int(-100 + rate * 200))
86 return True
87 except:
88 return False
89
90 def setModule(self, module):
91 if not self._isInitialized:
92 return False
93 try:
94 self._sd.set_output_module(module)
95 return True
96 except:
97 return False
98
99 def setLanguage(self, language):
100 if not self._isInitialized:
101 return False
102 self._language = language
103
104 def setVolume(self, volume):
105 if not self._isInitialized:
106 return False
107 self._sd.set_volume(int(-100 + volume * 200))
108
0 #!/usr/bin/python
1 # -*- coding: utf-8 -*-
2
3 # Fenrir TTY screen reader
4 # By Chrys, Storm Dragon, and contributers.
5 # speech-dispatcher driver
6
7 from core import debug
8
9 class driver():
10 def __init__(self):
11 self._sd = None
12 self._isInitialized = False
13 self._language = ''
14
15 def initialize(self, environment):
16 self.env = environment
17 try:
18 import speechd
19 self._sd = speechd.SSIPClient('fenrir')
20 self._punct = speechd.PunctuationMode()
21 self._isInitialized = True
22 except Exception as e:
23 self.env['runtime']['debug'].writeDebugOut('speechDriver initialize:' + str(e),debug.debugLevel.ERROR)
24 self._initialized = False
25
26 def shutdown(self):
27 if not self._isInitialized:
28 return
29 self.cancel()
30 try:
31 self._sd.close()
32 except:
33 pass
34 self._isInitialized = False
35
36 def speak(self,text, queueable=True):
37 if not queueable:
38 self.cancel()
39 if not self._isInitialized:
40 self.initialize(self.env)
41 if not self._isInitialized:
42 return
43 try:
44 self._sd.set_synthesis_voice(self._language)
45 self._sd.set_punctuation(self._punct.NONE)
46 self._sd.speak(text)
47 except Exception as e:
48 self.env['runtime']['debug'].writeDebugOut('speechDriver speak:' + str(e),debug.debugLevel.ERROR)
49 self._isInitialized = False
50
51 def cancel(self):
52 if not self._isInitialized:
53 return
54 try:
55 self._sd.cancel()
56 except Exception as e:
57 self.env['runtime']['debug'].writeDebugOut('speechDriver cancel:' + str(e),debug.debugLevel.ERROR)
58 self._isInitialized = False
59
60 def setCallback(self, callback):
61 pass
62
63 def clear_buffer(self):
64 if not self._isInitialized:
65 return
66
67 def setVoice(self, voice):
68 if not self._isInitialized:
69 return
70 try:
71 if voice != '':
72 self._sd.set_voice(voice)
73 except Exception as e:
74 self.env['runtime']['debug'].writeDebugOut('speechDriver setVoice:' + str(e),debug.debugLevel.ERROR)
75
76 def setPitch(self, pitch):
77 if not self._isInitialized:
78 return
79 try:
80 self._sd.set_pitch(int(-100 + pitch * 200))
81 except Exception as e:
82 self.env['runtime']['debug'].writeDebugOut('speechDriver setPitch:' + str(e),debug.debugLevel.ERROR)
83
84 def setRate(self, rate):
85 if not self._isInitialized:
86 return
87 try:
88 self._sd.set_rate(int(-100 + rate * 200))
89 except Exception as e:
90 self.env['runtime']['debug'].writeDebugOut('speechDriver setRate:' + str(e),debug.debugLevel.ERROR)
91
92 def setModule(self, module):
93 if not self._isInitialized:
94 return
95 try:
96 self._sd.set_output_module(module)
97 except Exception as e:
98 self.env['runtime']['debug'].writeDebugOut('speechDriver setModule:' + str(e),debug.debugLevel.ERROR)
99
100 def setLanguage(self, language):
101 if not self._isInitialized:
102 return
103 self._language = language
104
105 def setVolume(self, volume):
106 if not self._isInitialized:
107 return
108 try:
109 self._sd.set_volume(int(-100 + volume * 200))
110 except Exception as e:
111 self.env['runtime']['debug'].writeDebugOut('speechDriver setVolume:' + str(e),debug.debugLevel.ERROR)
0 #!/bin/python
1 # -*- coding: utf-8 -*-
2 # Fenrir TTY screen reader
3 # By Chrys, Storm Dragon, and contributers.
4 import sys
5 version = sys.version[:3] # we only need major.minor version.
6 if version in ["3.3","3.4"]:
7 from importlib.machinery import SourceFileLoader
8 else: # Python 3.5+, no support for python < 3.3.
9 import importlib.util
10
11 def importModule(moduleName, moduleLocation):
12 if version in ["3.3","3.4"]:
13 return SourceFileLoader(moduleName, moduleLocation).load_module()
14 else:
15 spec = importlib.util.spec_from_file_location(moduleName, moduleLocation)
16 driver_mod = importlib.util.module_from_spec(spec)
17 spec.loader.exec_module(driver_mod)
18 return driver_mod
66 from core import debug
77 from collections import Counter
88 import string
9
9 from select import select
10 from select import epoll
11 import select
12
1013 def removeNonprintable(text):
1114 # Get the difference of all ASCII characters from the set of printable characters
1215 nonprintable = set([chr(i) for i in range(128)]).difference(string.printable)
1619 def insertNewlines(string, every=64):
1720 return '\n'.join(string[i:i+every] for i in range(0, len(string), every))
1821
19 def splitEvery(string, every=64):
20 return list(string[i:i+every] for i in range(0, len(string), every))
22 def splitEvery(toSplit, every=64):
23 return list(toSplit[i:i+every] for i in range(0, len(toSplit), every))
24
25 def hasMoreRead(fd):
26 r, w, e = select([fd], [], [], 0)
27 return (fd in r)
28
29 def hasMorePollPri(fd):
30 p = epoll()
31 p.register(fd, select.POLLPRI | select.POLLERR)
32 r = p.poll(0)
33 return (fd in r)
2134
2235 def trackHighlights(oldAttr, newAttr, text, lenght):
2336 result = ''
2841 return result, currCursor
2942 if len(oldAttr) != len(newAttr):
3043 return result, currCursor
44
3145 old = splitEvery(oldAttr,lenght)
3246 new = splitEvery(newAttr,lenght)
3347 textLines = text.split('\n')
3448 background = []
35 if len(textLines) != len(new):
49
50 if len(textLines) - 1 != len(new):
3651 return result, currCursor
3752 try:
3853 bgStat = Counter(newAttr).most_common(3)
4257 if bgStat[1][1] > 40:
4358 background.append(bgStat[1][0])
4459 except Exception as e:
45 background.append(chr(7))
60 background.append((7,7,0,0,0,0))
4661 for line in range(len(new)):
4762 if old[line] != new[line]:
4863 for column in range(len(new[line])):
64 print(new[line][column])
4965 if old[line][column] != new[line][column]:
5066 if not new[line][column] in background:
5167 if not currCursor:
5571 result += textLines[line][column]
5672 result += ' '
5773 return result, currCursor
74
75 '''
76 t = 'hallo\nwelt!'
77 old = ((1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0))
78 new = ((0,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,1,1),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0),(1,1,0,0))
79
80 trackHighlights(old,new,t,5)
81 '''
00 #!/bin/bash
11
2 # This script configures pulse to work both in the graphical invironment and in the console with root apps.
2 # This script configures Pulse to work both in the graphical environment and in the console with root apps.
33
44 if [[ $(whoami) != "root" ]]; then
55 # Get the current user's XDG_HOME
1010 read -p "This will replace the current file located at $xdgPath/pulse/default.pa, press enter to continue or control+c to abort. " continue
1111 fi
1212 echo '.include /etc/pulse/default.pa
13 load-module module-switch-on-connect
1314 load-module module-native-protocol-unix auth-anonymous=1 socket=/tmp/pulse.sock' > $xdgPath/pulse/default.pa
1415 echo "If you have not yet done so, please run this script as root to write the client.conf file."
1516 else
6566
6667 # If there were no errors tell user to restart, else warn them errors happened.
6768 if [ $? -eq 0 ]; then
68 echo "Configuration created succeswsfully, restart pulse, or your system, for changes to take affect."
69 echo "Configuration created successfully, please restart Pulseaudio or your system, for changes to take affect."
6970 else
70 echo "Errors were encountered while writing the configuration. please correct them manually."
71 echo "Errors were encountered whilst writing the configuration, please correct them manually."
7172 fi
7273 exit 0
22 # Get user input args are return variable, question, options
33 get_input()
44 {
5 # Variable names are long, cause I want absolutely no name conflicts.
5 # Variable names are long, because we want absolutely no name conflicts.
66 local __get_input_input=$1
77 shift
88 local __get_input_question="$1"
4141 fi
4242
4343 if [ -f "$configFile" ]; then
44 read -p "This will replace your current settings. Press enter to continue or control+c to abort." continue
44 read -p "This will replace your current settings, press enter to continue or control+C to abort." continue
4545 fi
4646
4747 get_input sound "Enable sound?" -yes no
6868 # Sox is the default.
6969 driver=$soundDriver
7070
71 # Sound themes. This is the pack of sounds used for sound alerts.
71 # Sound themes. These are the pack of sounds used for sound alerts.
7272 # Sound packs may be located at /usr/share/sounds
7373 # For system wide availability, or ~/.local/share/fenrir/sounds
7474 # For the current user.
7979 volume=1.0
8080
8181 # shell commands for generic sound driver
82 # the folowing variable are substituded
82 # the folowing variables are substituted
8383 # fenrirVolume = the current volume setting
8484 # fenrirSoundFile = the soundfile for an soundicon
8585 # fenrirFrequence = the frequence to play
86 # fenrirDuration = the duration of the frequence
86 # fenrirDuration = the duration of the frequency
8787 # the following command is used for play a soundfile
8888 genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
89 #the following command is used for generating a frequence beep
89 #the following command is used for generating a frequency beep
9090 genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
9191
9292 [speech]
9797 driver=$speechDriver
9898
9999
100 # The rate selects how fast fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
100 # The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
101101 rate=0.45
102102
103103 # Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
108108 # Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
109109 volume=1.0
110110
111 # Module is used for speech-dispatcher, to select the speech module you want to use.
112 # Consult speech-dispatcher's configuration and help ti find out which modules are available.
113 # The default is espeak.
111 # Module is used for Speech-dispatcher, to select the speech module you want to use.
112 # Consult Speech-dispatcher's configuration and help to find out which modules are available.
113 # The default is Espeak.
114114 module=espeak
115115
116116 # Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak,
117 # or if using the espeak module in speech-dispatcher. To find out which voices are available, consult the documentation provided with your chosen synthesizer.
117 # or if using the espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
118118 voice=
119119
120 # Select the language you want fenrir to use.
120 # Select the language you want Fenrir to use.
121121 language=english-us
122122
123123 # Read new text as it happens?
124124 autoReadIncoming=True
125125
126126 [braille]
127 #braille is not implemented yet
127 #Braille is not implemented yet
128128 enabled=False
129129 driver=brlapi
130130 layout=en
131131
132132 [screen]
133133 driver=vcsa
134 encoding=cp850
135 screenUpdateDelay=0.05
136 suspendingScreen=
134 encoding=auto
137135 autodetectSuspendingScreen=True
138136
139137 [keyboard]
140138 driver=evdev
141139 # filter input devices NOMICE, ALL or a DEVICE NAME
142140 device=ALL
143 # gives fenrir exclusive access to the keyboard and let consume keystrokes.
141 # gives Fenrir exclusive access to the keyboard and lets it absorb keystrokes.
144142 grabDevices=True
145143 ignoreShortcuts=False
146144 # the current shortcut layout located in /etc/fenrir/keyboard
153151 wordEcho=$wordEcho
154152 # interrupt speech on any keypress
155153 interruptOnKeyPress=$enterupt
156 # you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
154 # you can filter the keys that the speech should interrupt (empty = all keys, otherwise the given keys)
157155 interruptOnKeyPressFilter=
158156 # timeout for double tap in sec
159157 doubleTapTimeout=0.2
160158
161159 [general]
162160 debugLevel=0
161 # debugMode sets where the debug output should send to:
162 # debugMode=File writes to /var/log/fenrir.log
163 # debugMode=Print just prints on the screen
164 debugMode=File
163165 punctuationProfile=default
164166 punctuationLevel=some
165167 respectPunctuationPause=True
166168 newLinePause=True
167169 numberOfClipboards=10
168170 emoticons=True
169 # define the current fenrir key
171 # define the current Fenrir key
170172 fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
171173 scriptKey=KEY_COMPOSE
172174 timeFormat=%H:%M:%P
0 # SOME DESCRIPTIVE TITLE.
1 # Copyright (C) YEAR ORGANIZATION
2 # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
3 #
4 msgid ""
5 msgstr ""
6 "Project-Id-Version: PACKAGE VERSION\n"
7 "POT-Creation-Date: 2017-02-26 22:19+UTC\n"
8 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
9 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
10 "Language-Team: LANGUAGE <LL@li.org>\n"
11 "MIME-Version: 1.0\n"
12 "Content-Type: text/plain; charset=UTF-8\n"
13 "Content-Transfer-Encoding: 8bit\n"
14 "Generated-By: pygettext.py 1.5\n"
15
16
17 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:27
18 msgid "adds the current word to the exceptions dictionary"
19 msgstr ""
20
21 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:34
22 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:34
23 #: ../src/fenrir/commands/commands/spell_check.py:29
24 #: ../src/fenrir/commands/commands/spell_check.py:36
25 msgid "pyenchant is not installed"
26 msgstr ""
27
28 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:49
29 msgid "{0} is already in dict"
30 msgstr ""
31
32 #: ../src/fenrir/commands/commands/add_word_to_spell_check.py:52
33 msgid "{0} added"
34 msgstr ""
35
36 #: ../src/fenrir/commands/commands/bookmark_1.py:19
37 #: ../src/fenrir/commands/commands/bookmark_10.py:19
38 #: ../src/fenrir/commands/commands/bookmark_2.py:19
39 #: ../src/fenrir/commands/commands/bookmark_3.py:19
40 #: ../src/fenrir/commands/commands/bookmark_4.py:19
41 #: ../src/fenrir/commands/commands/bookmark_5.py:19
42 #: ../src/fenrir/commands/commands/bookmark_6.py:19
43 #: ../src/fenrir/commands/commands/bookmark_7.py:19
44 #: ../src/fenrir/commands/commands/bookmark_8.py:19
45 #: ../src/fenrir/commands/commands/bookmark_9.py:19
46 msgid "read Bookmark {0}"
47 msgstr ""
48
49 #: ../src/fenrir/commands/commands/bookmark_1.py:24
50 #: ../src/fenrir/commands/commands/bookmark_10.py:24
51 #: ../src/fenrir/commands/commands/bookmark_2.py:24
52 #: ../src/fenrir/commands/commands/bookmark_3.py:24
53 #: ../src/fenrir/commands/commands/bookmark_4.py:24
54 #: ../src/fenrir/commands/commands/bookmark_5.py:24
55 #: ../src/fenrir/commands/commands/bookmark_6.py:24
56 #: ../src/fenrir/commands/commands/bookmark_7.py:24
57 #: ../src/fenrir/commands/commands/bookmark_8.py:24
58 #: ../src/fenrir/commands/commands/bookmark_9.py:24
59 msgid "Bookmark {0} not set"
60 msgstr ""
61
62 #: ../src/fenrir/commands/commands/bookmark_1.py:27
63 #: ../src/fenrir/commands/commands/bookmark_1.py:30
64 #: ../src/fenrir/commands/commands/bookmark_10.py:27
65 #: ../src/fenrir/commands/commands/bookmark_10.py:30
66 #: ../src/fenrir/commands/commands/bookmark_2.py:27
67 #: ../src/fenrir/commands/commands/bookmark_2.py:30
68 #: ../src/fenrir/commands/commands/bookmark_3.py:27
69 #: ../src/fenrir/commands/commands/bookmark_3.py:30
70 #: ../src/fenrir/commands/commands/bookmark_4.py:27
71 #: ../src/fenrir/commands/commands/bookmark_4.py:30
72 #: ../src/fenrir/commands/commands/bookmark_5.py:27
73 #: ../src/fenrir/commands/commands/bookmark_5.py:30
74 #: ../src/fenrir/commands/commands/bookmark_6.py:27
75 #: ../src/fenrir/commands/commands/bookmark_6.py:30
76 #: ../src/fenrir/commands/commands/bookmark_7.py:27
77 #: ../src/fenrir/commands/commands/bookmark_7.py:30
78 #: ../src/fenrir/commands/commands/bookmark_8.py:27
79 #: ../src/fenrir/commands/commands/bookmark_8.py:30
80 #: ../src/fenrir/commands/commands/bookmark_9.py:27
81 #: ../src/fenrir/commands/commands/bookmark_9.py:30
82 msgid "Bookmark for application {0} not set"
83 msgstr ""
84
85 #: ../src/fenrir/commands/commands/bookmark_1.py:43
86 #: ../src/fenrir/commands/commands/bookmark_10.py:43
87 #: ../src/fenrir/commands/commands/bookmark_2.py:43
88 #: ../src/fenrir/commands/commands/bookmark_3.py:43
89 #: ../src/fenrir/commands/commands/bookmark_4.py:43
90 #: ../src/fenrir/commands/commands/bookmark_5.py:43
91 #: ../src/fenrir/commands/commands/bookmark_6.py:43
92 #: ../src/fenrir/commands/commands/bookmark_7.py:43
93 #: ../src/fenrir/commands/commands/bookmark_8.py:43
94 #: ../src/fenrir/commands/commands/bookmark_9.py:43
95 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:27
96 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:30
97 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:27
98 #: ../src/fenrir/commands/commands/indent_curr_line.py:31
99 #: ../src/fenrir/commands/commands/marked_text.py:33
100 #: ../src/fenrir/commands/commands/present_first_line.py:25
101 #: ../src/fenrir/commands/commands/present_last_line.py:25
102 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:27
103 #: ../src/fenrir/commands/commands/review_curr_line.py:27
104 #: ../src/fenrir/commands/commands/review_curr_word.py:27
105 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:27
106 #: ../src/fenrir/commands/commands/review_line_begin.py:27
107 #: ../src/fenrir/commands/commands/review_next_line.py:29
108 #: ../src/fenrir/commands/commands/review_next_word.py:29
109 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:27
110 #: ../src/fenrir/commands/commands/review_prev_line.py:27
111 #: ../src/fenrir/commands/commands/review_prev_word.py:27
112 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:27
113 #: ../src/fenrir/commands/onInput/55000-present_line_if_cursor_change_vertical.py:38
114 #: ../src/fenrir/commands/onInput/72000-history.py:50
115 msgid "blank"
116 msgstr ""
117
118 #: ../src/fenrir/commands/commands/braille_flush.py:17
119 msgid "flush the braille device if a message is written on"
120 msgstr ""
121
122 #: ../src/fenrir/commands/commands/braille_pan_left.py:17
123 msgid "Move braille view to the left."
124 msgstr ""
125
126 #: ../src/fenrir/commands/commands/braille_pan_right.py:17
127 msgid "Move braille view to the right."
128 msgstr ""
129
130 #: ../src/fenrir/commands/commands/braille_return_to_cursor.py:17
131 msgid "Set the braille view back to cursor."
132 msgstr ""
133
134 #: ../src/fenrir/commands/commands/clear_bookmark_1.py:17
135 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:17
136 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:17
137 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:17
138 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:17
139 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:17
140 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:17
141 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:17
142 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:17
143 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:17
144 msgid "remove Bookmark {0}"
145 msgstr ""
146
147 #: ../src/fenrir/commands/commands/clear_bookmark_1.py:24
148 #: ../src/fenrir/commands/commands/clear_bookmark_10.py:24
149 #: ../src/fenrir/commands/commands/clear_bookmark_2.py:24
150 #: ../src/fenrir/commands/commands/clear_bookmark_3.py:24
151 #: ../src/fenrir/commands/commands/clear_bookmark_4.py:24
152 #: ../src/fenrir/commands/commands/clear_bookmark_5.py:24
153 #: ../src/fenrir/commands/commands/clear_bookmark_6.py:24
154 #: ../src/fenrir/commands/commands/clear_bookmark_7.py:24
155 #: ../src/fenrir/commands/commands/clear_bookmark_8.py:24
156 #: ../src/fenrir/commands/commands/clear_bookmark_9.py:24
157 msgid "Bookmark {0} removed for application {1}"
158 msgstr ""
159
160 #: ../src/fenrir/commands/commands/clear_clipboard.py:17
161 msgid "clears the currently selected clipboard"
162 msgstr ""
163
164 #: ../src/fenrir/commands/commands/clear_clipboard.py:22
165 msgid "clipboard cleared"
166 msgstr ""
167
168 #: ../src/fenrir/commands/commands/clear_window_application.py:17
169 msgid "Turn off window mode for application"
170 msgstr ""
171
172 #: ../src/fenrir/commands/commands/clear_window_application.py:22
173 msgid "Window Mode off for application {0}"
174 msgstr ""
175
176 #: ../src/fenrir/commands/commands/clear_window_application.py:24
177 msgid "Not in window Mode"
178 msgstr ""
179
180 #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:18
181 msgid "copies marked text to the currently selected clipboard"
182 msgstr ""
183
184 #: ../src/fenrir/commands/commands/copy_marked_to_clipboard.py:22
185 msgid "one or two marks needed"
186 msgstr ""
187
188 #: ../src/fenrir/commands/commands/curr_clipboard.py:17
189 msgid "speaks the contents of the currently selected clipboard"
190 msgstr ""
191
192 #: ../src/fenrir/commands/commands/curr_clipboard.py:21
193 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:29
194 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:32
195 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:35
196 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:38
197 #: ../src/fenrir/commands/commands/first_clipboard.py:21
198 #: ../src/fenrir/commands/commands/last_clipboard.py:21
199 #: ../src/fenrir/commands/commands/next_clipboard.py:21
200 #: ../src/fenrir/commands/commands/paste_clipboard.py:23
201 #: ../src/fenrir/commands/commands/paste_clipboard.py:26
202 #: ../src/fenrir/commands/commands/paste_clipboard.py:29
203 #: ../src/fenrir/commands/commands/paste_clipboard.py:32
204 #: ../src/fenrir/commands/commands/prev_clipboard.py:21
205 msgid "clipboard empty"
206 msgstr ""
207
208 #: ../src/fenrir/commands/commands/curr_screen.py:17
209 msgid "reads the contents of the current screen"
210 msgstr ""
211
212 #: ../src/fenrir/commands/commands/curr_screen.py:21
213 msgid "screen is empty"
214 msgstr ""
215
216 #: ../src/fenrir/commands/commands/curr_screen_after_cursor.py:18
217 msgid "reads from the cursor to the bottom of the screen"
218 msgstr ""
219
220 #: ../src/fenrir/commands/commands/curr_screen_before_cursor.py:18
221 msgid "Reads from the top of the screen to the cursor position"
222 msgstr ""
223
224 #: ../src/fenrir/commands/commands/cursor_column.py:17
225 msgid "presents the current column number for review cursor in review mode or the text cursor if not. Starts with 1"
226 msgstr ""
227
228 #: ../src/fenrir/commands/commands/cursor_lineno.py:17
229 msgid "presents the current line number for review cursor in review mode or the text cursor if not. Starts with 1"
230 msgstr ""
231
232 #: ../src/fenrir/commands/commands/cursor_position.py:17
233 msgid "displays the position of the review cursor"
234 msgstr ""
235
236 #: ../src/fenrir/commands/commands/cursor_position.py:23
237 msgid "line {0}, column {1}"
238 msgstr ""
239
240 #: ../src/fenrir/commands/commands/cursor_read_to_end_of_line.py:18
241 msgid "read to end of line, use review cursor if you are in review mode, otherwhise use text cursor"
242 msgstr ""
243
244 #: ../src/fenrir/commands/commands/date.py:18
245 msgid "presents the date"
246 msgstr ""
247
248 #: ../src/fenrir/commands/commands/dec_sound_volume.py:18
249 msgid "decrease sound volume"
250 msgstr ""
251
252 #: ../src/fenrir/commands/commands/dec_sound_volume.py:29
253 #: ../src/fenrir/commands/commands/inc_sound_volume.py:29
254 msgid "{0} percent sound volume"
255 msgstr ""
256
257 #: ../src/fenrir/commands/commands/dec_speech_pitch.py:18
258 msgid "decreases the pitch of the speech"
259 msgstr ""
260
261 #: ../src/fenrir/commands/commands/dec_speech_pitch.py:27
262 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:27
263 msgid "{0} percent speech pitch"
264 msgstr ""
265
266 #: ../src/fenrir/commands/commands/dec_speech_rate.py:18
267 msgid "decreases the rate of the speech"
268 msgstr ""
269
270 #: ../src/fenrir/commands/commands/dec_speech_rate.py:27
271 #: ../src/fenrir/commands/commands/inc_speech_rate.py:27
272 msgid "{0} percent speech rate"
273 msgstr ""
274
275 #: ../src/fenrir/commands/commands/dec_speech_volume.py:18
276 msgid "decreases the volume of the speech"
277 msgstr ""
278
279 #: ../src/fenrir/commands/commands/dec_speech_volume.py:27
280 #: ../src/fenrir/commands/commands/inc_speech_volume.py:27
281 msgid "{0} percent speech volume"
282 msgstr ""
283
284 #: ../src/fenrir/commands/commands/exit_review.py:17
285 msgid "exits review mode"
286 msgstr ""
287
288 #: ../src/fenrir/commands/commands/exit_review.py:21
289 msgid "Not in review mode"
290 msgstr ""
291
292 #: ../src/fenrir/commands/commands/exit_review.py:25
293 msgid "leave review mode"
294 msgstr ""
295
296 #: ../src/fenrir/commands/commands/export_clipboard_to_x.py:21
297 msgid "export the current fenrir clipboard to X clipboard"
298 msgstr ""
299
300 #: ../src/fenrir/commands/commands/first_clipboard.py:17
301 msgid "selects the first clipboard"
302 msgstr ""
303
304 #: ../src/fenrir/commands/commands/forward_keypress.py:17
305 msgid "sends the following keypress to the terminal"
306 msgstr ""
307
308 #: ../src/fenrir/commands/commands/forward_keypress.py:21
309 msgid "Forward next keypress"
310 msgstr ""
311
312 #: ../src/fenrir/commands/commands/inc_sound_volume.py:18
313 msgid "adjusts the volume for in coming sounds"
314 msgstr ""
315
316 #: ../src/fenrir/commands/commands/inc_speech_pitch.py:18
317 msgid "increases the pitch of the speech"
318 msgstr ""
319
320 #: ../src/fenrir/commands/commands/inc_speech_rate.py:18
321 msgid "increase the speech rate"
322 msgstr ""
323
324 #: ../src/fenrir/commands/commands/inc_speech_volume.py:18
325 msgid "increase the speech volume"
326 msgstr ""
327
328 #: ../src/fenrir/commands/commands/indent_curr_line.py:18
329 msgid "shows the indention level for the current line"
330 msgstr ""
331
332 #: ../src/fenrir/commands/commands/indent_curr_line.py:33
333 msgid "indent {0}"
334 msgstr ""
335
336 #: ../src/fenrir/commands/commands/last_clipboard.py:17
337 msgid "selects the last clipboard"
338 msgstr ""
339
340 #: ../src/fenrir/commands/commands/last_incoming.py:17
341 msgid "displays the last received text"
342 msgstr ""
343
344 #: ../src/fenrir/commands/commands/marked_text.py:18
345 msgid "speaks the currently selected text that will be copied to the clipboard"
346 msgstr ""
347
348 #: ../src/fenrir/commands/commands/marked_text.py:23
349 msgid "please set begin and endmark"
350 msgstr ""
351
352 #: ../src/fenrir/commands/commands/next_clipboard.py:17
353 msgid "selects the next clipboard"
354 msgstr ""
355
356 #: ../src/fenrir/commands/commands/next_clipboard.py:26
357 msgid "First clipboard "
358 msgstr ""
359
360 #: ../src/fenrir/commands/commands/paste_clipboard.py:18
361 msgid "pastes the text from the currently selected clipboard"
362 msgstr ""
363
364 #: ../src/fenrir/commands/commands/present_first_line.py:18
365 msgid "present first line"
366 msgstr ""
367
368 #: ../src/fenrir/commands/commands/present_last_line.py:18
369 #: ../src/fenrir/commands/commands/review_curr_line.py:18
370 msgid "current line"
371 msgstr ""
372
373 #: ../src/fenrir/commands/commands/prev_clipboard.py:17
374 msgid "selects the previous clipboard"
375 msgstr ""
376
377 #: ../src/fenrir/commands/commands/prev_clipboard.py:26
378 msgid "Last clipboard "
379 msgstr ""
380
381 #: ../src/fenrir/commands/commands/quit_fenrir.py:17
382 msgid "exits Fenrir"
383 msgstr ""
384
385 #: ../src/fenrir/commands/commands/remove_marks.py:17
386 msgid "removes marks from selected text"
387 msgstr ""
388
389 #: ../src/fenrir/commands/commands/remove_marks.py:21
390 msgid "Remove marks"
391 msgstr ""
392
393 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:27
394 msgid "removes the current word from the exceptions dictionary"
395 msgstr ""
396
397 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:50
398 msgid "{0} is already removed from dict"
399 msgstr ""
400
401 #: ../src/fenrir/commands/commands/remove_word_from_spell_check.py:53
402 msgid "{0} removed"
403 msgstr ""
404
405 #: ../src/fenrir/commands/commands/review_bottom.py:17
406 msgid "move review to bottom of screen"
407 msgstr ""
408
409 #: ../src/fenrir/commands/commands/review_bottom.py:21
410 msgid "Bottom"
411 msgstr ""
412
413 #: ../src/fenrir/commands/commands/review_curr_char.py:18
414 msgid "presents the current character."
415 msgstr ""
416
417 #: ../src/fenrir/commands/commands/review_curr_char_phonetic.py:18
418 msgid "set review and phonetically presents the current character"
419 msgstr ""
420
421 #: ../src/fenrir/commands/commands/review_curr_word.py:18
422 msgid "current word."
423 msgstr ""
424
425 #: ../src/fenrir/commands/commands/review_curr_word.py:32
426 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:36
427 #: ../src/fenrir/commands/commands/review_down.py:27
428 #: ../src/fenrir/commands/commands/review_next_char.py:28
429 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:30
430 #: ../src/fenrir/commands/commands/review_next_line.py:34
431 #: ../src/fenrir/commands/commands/review_next_word.py:34
432 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:36
433 #: ../src/fenrir/commands/commands/review_prev_char.py:31
434 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:30
435 #: ../src/fenrir/commands/commands/review_prev_line.py:32
436 #: ../src/fenrir/commands/commands/review_prev_word.py:32
437 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:36
438 #: ../src/fenrir/commands/commands/review_up.py:27
439 msgid "end of screen"
440 msgstr ""
441
442 #: ../src/fenrir/commands/commands/review_curr_word.py:35
443 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:39
444 #: ../src/fenrir/commands/commands/review_next_char.py:31
445 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:33
446 #: ../src/fenrir/commands/commands/review_next_word.py:37
447 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:39
448 #: ../src/fenrir/commands/commands/review_prev_char.py:34
449 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:33
450 #: ../src/fenrir/commands/commands/review_prev_word.py:35
451 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:39
452 #: ../src/fenrir/commands/commands/review_up.py:30
453 msgid "line break"
454 msgstr ""
455
456 #: ../src/fenrir/commands/commands/review_curr_word_phonetic.py:19
457 #: ../src/fenrir/commands/commands/review_next_word_phonetic.py:19
458 #: ../src/fenrir/commands/commands/review_prev_word_phonetic.py:19
459 msgid "phonetically spells the current word and set review to it"
460 msgstr ""
461
462 #: ../src/fenrir/commands/commands/review_down.py:18
463 msgid "set review cursor to char below the current char and present it."
464 msgstr ""
465
466 #: ../src/fenrir/commands/commands/review_line_begin.py:18
467 msgid "set review cursor to begin of current line and display the content"
468 msgstr ""
469
470 #: ../src/fenrir/commands/commands/review_line_begin.py:30
471 msgid "beginning of line"
472 msgstr ""
473
474 #: ../src/fenrir/commands/commands/review_line_end.py:18
475 #: ../src/fenrir/commands/commands/review_line_first_char.py:19
476 #: ../src/fenrir/commands/commands/review_line_last_char.py:18
477 msgid "set review cursor to end of current line and display the content"
478 msgstr ""
479
480 #: ../src/fenrir/commands/commands/review_line_end.py:27
481 msgid "end of line"
482 msgstr ""
483
484 #: ../src/fenrir/commands/commands/review_line_first_char.py:26
485 msgid "line is empty"
486 msgstr ""
487
488 #: ../src/fenrir/commands/commands/review_line_first_char.py:33
489 msgid "first char in line indent {0}"
490 msgstr ""
491
492 #: ../src/fenrir/commands/commands/review_line_last_char.py:27
493 msgid "last char in line"
494 msgstr ""
495
496 #: ../src/fenrir/commands/commands/review_next_char.py:18
497 msgid "moves review to the next character and presents it"
498 msgstr ""
499
500 #: ../src/fenrir/commands/commands/review_next_char_phonetic.py:18
501 msgid "phonetically presents the next character and set review to it"
502 msgstr ""
503
504 #: ../src/fenrir/commands/commands/review_next_line.py:18
505 msgid "moves review to the next line and presents it"
506 msgstr ""
507
508 #: ../src/fenrir/commands/commands/review_next_word.py:18
509 msgid "moves review to the next word and presents it"
510 msgstr ""
511
512 #: ../src/fenrir/commands/commands/review_prev_char.py:18
513 msgid "moves review to the previous character and presents it"
514 msgstr ""
515
516 #: ../src/fenrir/commands/commands/review_prev_char_phonetic.py:18
517 msgid "phonetically presents the previous character and set review to it"
518 msgstr ""
519
520 #: ../src/fenrir/commands/commands/review_prev_line.py:18
521 msgid "moves review to the previous line and presents it"
522 msgstr ""
523
524 #: ../src/fenrir/commands/commands/review_prev_word.py:18
525 msgid "moves review focus to the previous word and presents it"
526 msgstr ""
527
528 #: ../src/fenrir/commands/commands/review_top.py:18
529 msgid "move review to top of screen"
530 msgstr ""
531
532 #: ../src/fenrir/commands/commands/review_top.py:22
533 msgid "Top"
534 msgstr ""
535
536 #: ../src/fenrir/commands/commands/review_up.py:18
537 msgid "set review cursor to the char in the line below and present it"
538 msgstr ""
539
540 #: ../src/fenrir/commands/commands/set_bookmark_1.py:18
541 #: ../src/fenrir/commands/commands/set_bookmark_10.py:18
542 #: ../src/fenrir/commands/commands/set_bookmark_2.py:18
543 #: ../src/fenrir/commands/commands/set_bookmark_3.py:18
544 #: ../src/fenrir/commands/commands/set_bookmark_4.py:18
545 #: ../src/fenrir/commands/commands/set_bookmark_5.py:18
546 #: ../src/fenrir/commands/commands/set_bookmark_6.py:18
547 #: ../src/fenrir/commands/commands/set_bookmark_7.py:18
548 #: ../src/fenrir/commands/commands/set_bookmark_8.py:18
549 #: ../src/fenrir/commands/commands/set_bookmark_9.py:18
550 msgid "set Bookmark {0}"
551 msgstr ""
552
553 #: ../src/fenrir/commands/commands/set_bookmark_1.py:22
554 #: ../src/fenrir/commands/commands/set_bookmark_10.py:22
555 #: ../src/fenrir/commands/commands/set_bookmark_2.py:22
556 #: ../src/fenrir/commands/commands/set_bookmark_3.py:22
557 #: ../src/fenrir/commands/commands/set_bookmark_4.py:22
558 #: ../src/fenrir/commands/commands/set_bookmark_5.py:22
559 #: ../src/fenrir/commands/commands/set_bookmark_6.py:22
560 #: ../src/fenrir/commands/commands/set_bookmark_7.py:22
561 #: ../src/fenrir/commands/commands/set_bookmark_8.py:22
562 #: ../src/fenrir/commands/commands/set_bookmark_9.py:22
563 msgid "No Mark found"
564 msgstr ""
565
566 #: ../src/fenrir/commands/commands/set_bookmark_1.py:32
567 #: ../src/fenrir/commands/commands/set_bookmark_10.py:32
568 #: ../src/fenrir/commands/commands/set_bookmark_2.py:32
569 #: ../src/fenrir/commands/commands/set_bookmark_3.py:32
570 #: ../src/fenrir/commands/commands/set_bookmark_4.py:32
571 #: ../src/fenrir/commands/commands/set_bookmark_5.py:32
572 #: ../src/fenrir/commands/commands/set_bookmark_6.py:32
573 #: ../src/fenrir/commands/commands/set_bookmark_7.py:32
574 #: ../src/fenrir/commands/commands/set_bookmark_8.py:32
575 #: ../src/fenrir/commands/commands/set_bookmark_9.py:32
576 msgid "Bookmark {0} set for application {1}"
577 msgstr ""
578
579 #: ../src/fenrir/commands/commands/set_mark.py:17
580 msgid "places marks to select text to copy to the clipboard"
581 msgstr ""
582
583 #: ../src/fenrir/commands/commands/set_mark.py:21
584 msgid "no review cursor"
585 msgstr ""
586
587 #: ../src/fenrir/commands/commands/set_mark.py:26
588 #: ../src/fenrir/commands/commands/set_mark.py:28
589 msgid "set mark"
590 msgstr ""
591
592 #: ../src/fenrir/commands/commands/set_window_application.py:17
593 msgid "set Window Mode, needs 2 marks "
594 msgstr ""
595
596 #: ../src/fenrir/commands/commands/set_window_application.py:22
597 msgid "Window Mode on for application {0}"
598 msgstr ""
599
600 #: ../src/fenrir/commands/commands/set_window_application.py:25
601 msgid "Set window begin and end marks"
602 msgstr ""
603
604 #: ../src/fenrir/commands/commands/shut_up.py:17
605 msgid "interrupts the current presentation"
606 msgstr ""
607
608 #: ../src/fenrir/commands/commands/spell_check.py:26
609 msgid "checks the spelling of the current word"
610 msgstr ""
611
612 #: ../src/fenrir/commands/commands/spell_check.py:52
613 #: ../src/fenrir/commands/onInput/62000-spell_check.py:132
614 msgid "misspelled"
615 msgstr ""
616
617 #: ../src/fenrir/commands/commands/spell_check.py:54
618 msgid "correct"
619 msgstr ""
620
621 #: ../src/fenrir/commands/commands/subprocess.py:21
622 msgid "script: {0} fullpath: {1}"
623 msgstr ""
624
625 #: ../src/fenrir/commands/commands/subprocess.py:24
626 msgid "scriptfile does not exist"
627 msgstr ""
628
629 #: ../src/fenrir/commands/commands/subprocess.py:27
630 msgid "scriptfile is not a file"
631 msgstr ""
632
633 #: ../src/fenrir/commands/commands/subprocess.py:30
634 msgid "scriptfile is not executable"
635 msgstr ""
636
637 #: ../src/fenrir/commands/commands/temp_disable_speech.py:17
638 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:17
639 msgid "disables speech until next keypress"
640 msgstr ""
641
642 #: ../src/fenrir/commands/commands/temp_disable_speech.py:21
643 msgid "speech temporary disabled"
644 msgstr ""
645
646 #: ../src/fenrir/commands/commands/time.py:18
647 msgid "presents the time"
648 msgstr ""
649
650 #: ../src/fenrir/commands/commands/toggle_auto_read.py:16
651 msgid "enables or disables automatic reading of new text as it appears"
652 msgstr ""
653
654 #: ../src/fenrir/commands/commands/toggle_auto_read.py:21
655 msgid "autoread enabled"
656 msgstr ""
657
658 #: ../src/fenrir/commands/commands/toggle_auto_read.py:23
659 msgid "autoread disabled"
660 msgstr ""
661
662 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:17
663 msgid "enables or disables automatic spell checking"
664 msgstr ""
665
666 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:22
667 msgid "auto spellcheck enabled"
668 msgstr ""
669
670 #: ../src/fenrir/commands/commands/toggle_auto_spell_check.py:24
671 msgid "auto spellcheck disabled"
672 msgstr ""
673
674 #: ../src/fenrir/commands/commands/toggle_auto_time.py:16
675 msgid "enables or disables automatic reading of time after an period"
676 msgstr ""
677
678 #: ../src/fenrir/commands/commands/toggle_auto_time.py:21
679 msgid "autotime enabled"
680 msgstr ""
681
682 #: ../src/fenrir/commands/commands/toggle_auto_time.py:23
683 msgid "autotime disabled"
684 msgstr ""
685
686 #: ../src/fenrir/commands/commands/toggle_braille.py:17
687 msgid "enables and disables output in braille"
688 msgstr ""
689
690 #: ../src/fenrir/commands/commands/toggle_braille.py:21
691 msgid "braille disabled"
692 msgstr ""
693
694 #: ../src/fenrir/commands/commands/toggle_braille.py:24
695 msgid "braille enabled"
696 msgstr ""
697
698 #: ../src/fenrir/commands/commands/toggle_emoticons.py:16
699 msgid "enables or disables announcement of emoticons instead of chars"
700 msgstr ""
701
702 #: ../src/fenrir/commands/commands/toggle_emoticons.py:21
703 msgid "emoticons enabled"
704 msgstr ""
705
706 #: ../src/fenrir/commands/commands/toggle_emoticons.py:23
707 msgid "emoticons disabled"
708 msgstr ""
709
710 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:16
711 #: ../src/fenrir/commands/onInput/56000-highlight_tracking.py:16
712 msgid "enables or disables tracking of highlighted"
713 msgstr ""
714
715 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:24
716 msgid "highlight tracking"
717 msgstr ""
718
719 #: ../src/fenrir/commands/commands/toggle_highlight_tracking.py:26
720 msgid "cursor tracking"
721 msgstr ""
722
723 #: ../src/fenrir/commands/commands/toggle_output.py:17
724 msgid "toggles all output settings"
725 msgstr ""
726
727 #: ../src/fenrir/commands/commands/toggle_output.py:23
728 msgid "Fenrir muted"
729 msgstr ""
730
731 #: ../src/fenrir/commands/commands/toggle_output.py:31
732 msgid "Fenrir unmuted"
733 msgstr ""
734
735 #: ../src/fenrir/commands/commands/toggle_punctuation_level.py:23
736 msgid "No punctuation found."
737 msgstr ""
738
739 #: ../src/fenrir/commands/commands/toggle_sound.py:17
740 msgid "enables or disables sound"
741 msgstr ""
742
743 #: ../src/fenrir/commands/commands/toggle_sound.py:21
744 msgid "sound disabled"
745 msgstr ""
746
747 #: ../src/fenrir/commands/commands/toggle_sound.py:24
748 msgid "sound enabled"
749 msgstr ""
750
751 #: ../src/fenrir/commands/commands/toggle_speech.py:17
752 msgid "enables or disables speech"
753 msgstr ""
754
755 #: ../src/fenrir/commands/commands/toggle_speech.py:21
756 msgid "speech disabled"
757 msgstr ""
758
759 #: ../src/fenrir/commands/commands/toggle_speech.py:24
760 #: ../src/fenrir/commands/onInput/15000-enable_temp_speech.py:28
761 msgid "speech enabled"
762 msgstr ""
763
764 #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:18
765 msgid "You are leaving the tutorial mode. Press that shortcut again to enter the tutorial mode again."
766 msgstr ""
767
768 #: ../src/fenrir/commands/commands/toggle_tutorial_mode.py:21
769 msgid "you entered the tutorial mode. In that mode the commands are not executed. but you get a description of what the shortcut does. To leave the tutorial mode, press that shortcut again."
770 msgstr ""
771
772 #: ../src/fenrir/commands/onInput/80000-capslock.py:22
773 msgid "Capslock on"
774 msgstr ""
775
776 #: ../src/fenrir/commands/onInput/80000-capslock.py:24
777 msgid "Capslock off"
778 msgstr ""
779
780 #: ../src/fenrir/commands/onInput/80300-scrolllock.py:22
781 msgid "Scrolllock on"
782 msgstr ""
783
784 #: ../src/fenrir/commands/onInput/80300-scrolllock.py:24
785 msgid "Scrolllock off"
786 msgstr ""
787
788 #: ../src/fenrir/commands/onInput/80500-numlock.py:22
789 msgid "Numlock on"
790 msgstr ""
791
792 #: ../src/fenrir/commands/onInput/80500-numlock.py:24
793 msgid "Numlock off"
794 msgstr ""
795
796 #:
797 #: ../src/fenrir/commands/onScreenChanged/80000-screen_change_announcement.py:20
798 msgid "screen {0}"
799 msgstr ""
800
801 #: ../src/fenrir/commands/onScreenUpdate/76000-time.py:66
802 msgid "Autotime: {0}"
803 msgstr ""
804
805 #: ../src/fenrir/fenrir.py:24
806 msgid "Start Fenrir"
807 msgstr ""
808
809 #: ../src/fenrir/fenrir.py:99
810 msgid "Quit Fenrir"
811 msgstr ""
812
0 #!/usr/bin/env bash
1
2 pygettext3 -d fenrir ../src/fenrir/*.py ../src/fenrir/*/*.py ../src/fenrir/*/*/*.py
0 #!/bin/bash
1 #Basic uninstall script for Fenrir.
2 cat << EOF
3 Fenrir is going to remove.
4 All scripts and settings will be lost.
5 EOF
6
7 # ask
8 read -p "This will remove Fenrir and its settings from your system,, press ctrl+C to cancel, or enter to continue." continue
9
10 # do it
11 unlink /usr/bin/fenrir
12 unlink /usr/bin/fenrir-daemon
13 rm -rf /opt/fenrir
14 rm -rf /usr/share/fenrir
15 rm -rf /etc/fenrir
16 rm -rf /usr/share/sounds/fenrir
17 rm -f /usr/lib/systemd/system/fenrir.service
18
19 # success message
20 cat << EOF
21 Fenrir has been successfully removed from your system.
22 EOF