Merge branch 'master' into storm
This commit is contained in:
commit
a7b28af947
70
README.md
70
README.md
@ -1,19 +1,26 @@
|
|||||||
# Fenrir
|
# Fenrir
|
||||||
|
|
||||||
A modern, modular, flexible and fast console screenreader.
|
A modern, modular, flexible and fast console screenreader.
|
||||||
It should run on any operating system. If you want to help, or write drivers to make it work on other systems, just let me know.
|
It should run on any operating system. If you want to help, or write drivers to make it work on other systems, just let me know.
|
||||||
This software is licensed under the LGPL v3.
|
This software is licensed under the LGPL v3.
|
||||||
|
|
||||||
|
|
||||||
# OS Requirements
|
# OS Requirements
|
||||||
|
|
||||||
- Linux (ptyDriver, vcsaDriver, evdevDriver)
|
- Linux (ptyDriver, vcsaDriver, evdevDriver)
|
||||||
- macOS (ptyDriver)
|
- macOS (ptyDriver)
|
||||||
- BSD (ptyDriver)
|
- BSD (ptyDriver)
|
||||||
- Windows (ptyDriver)
|
- Windows (ptyDriver)
|
||||||
|
|
||||||
|
|
||||||
# Core Requirements
|
# Core Requirements
|
||||||
|
|
||||||
- python3 >= 3.3
|
- python3 >= 3.3
|
||||||
- screen, input, speech, sound or braille drivers dependencies see "Features, Drivers, Extras".
|
- screen, input, speech, sound or braille drivers dependencies see "Features, Drivers, Extras".
|
||||||
|
|
||||||
|
|
||||||
# Features, Drivers, Extras, Dependencies
|
# Features, Drivers, Extras, Dependencies
|
||||||
|
|
||||||
# Input Drivers:
|
# Input Drivers:
|
||||||
1. "evdevDriver" input driver for linux evdev
|
1. "evdevDriver" input driver for linux evdev
|
||||||
- python-evdev >=0.6.3 (This is commonly referred to as python3-evdev by your distribution)
|
- python-evdev >=0.6.3 (This is commonly referred to as python3-evdev by your distribution)
|
||||||
@ -25,7 +32,9 @@ This software is licensed under the LGPL v3.
|
|||||||
2. "ptyDriver" terminal emulation input driver
|
2. "ptyDriver" terminal emulation input driver
|
||||||
- python-pyte
|
- python-pyte
|
||||||
|
|
||||||
|
|
||||||
# Screen Drivers:
|
# Screen Drivers:
|
||||||
|
|
||||||
1. "vcsaDriver" screen driver for linux VCSA devices
|
1. "vcsaDriver" screen driver for linux VCSA devices
|
||||||
- python-dbus
|
- python-dbus
|
||||||
- Read permission to the following files and services:
|
- Read permission to the following files and services:
|
||||||
@ -36,7 +45,9 @@ This software is licensed under the LGPL v3.
|
|||||||
2. "ptyDriver" terminal emulation driver
|
2. "ptyDriver" terminal emulation driver
|
||||||
- python-pyte
|
- python-pyte
|
||||||
|
|
||||||
|
|
||||||
# Speech Drivers:
|
# Speech Drivers:
|
||||||
|
|
||||||
1. "genericDriver" (default) speech driver for sound as subprocess:
|
1. "genericDriver" (default) speech driver for sound as subprocess:
|
||||||
- espeak or espeak-ng
|
- espeak or espeak-ng
|
||||||
2. "espeakDriver" speech driver for Espeak or Espeak-NG:
|
2. "espeakDriver" speech driver for Espeak or Espeak-NG:
|
||||||
@ -47,19 +58,25 @@ This software is licensed under the LGPL v3.
|
|||||||
4. "emacspeakDriver" speech driver for emacspeak
|
4. "emacspeakDriver" speech driver for emacspeak
|
||||||
- emacspeak
|
- emacspeak
|
||||||
|
|
||||||
|
|
||||||
# Braille Drivers:
|
# Braille Drivers:
|
||||||
|
|
||||||
1. "BrlttyDriver" braille driver (WIP):
|
1. "BrlttyDriver" braille driver (WIP):
|
||||||
- brltty (configured and running)
|
- brltty (configured and running)
|
||||||
- python-brlapi
|
- python-brlapi
|
||||||
|
|
||||||
|
|
||||||
# Sound Drivers:
|
# Sound Drivers:
|
||||||
|
|
||||||
1. "genericDriver" (default) sound driver for sound as subprocess:
|
1. "genericDriver" (default) sound driver for sound as subprocess:
|
||||||
- Sox
|
- Sox
|
||||||
2. "gstreamerDriver" sound driver for gstreamer
|
2. "gstreamerDriver" sound driver for gstreamer
|
||||||
- gstreamer >=1.0
|
- gstreamer >=1.0
|
||||||
- GLib
|
- GLib
|
||||||
|
|
||||||
|
|
||||||
# Extras:
|
# Extras:
|
||||||
|
|
||||||
1. spellchecker
|
1. spellchecker
|
||||||
- python-pyenchant
|
- python-pyenchant
|
||||||
- aspell-YourLanguageCode (example aspell-en for us English)
|
- aspell-YourLanguageCode (example aspell-en for us English)
|
||||||
@ -68,18 +85,29 @@ This software is licensed under the LGPL v3.
|
|||||||
3. Modify system volume:
|
3. Modify system volume:
|
||||||
- pyalsaaudio (needs libasound2's headers).
|
- pyalsaaudio (needs libasound2's headers).
|
||||||
|
|
||||||
|
|
||||||
# installation
|
# installation
|
||||||
- Archlinux: PKGBUILD in AUR
|
|
||||||
|
If there is a package for your distrobution of choice, please let us know so we can add it here.
|
||||||
|
|
||||||
|
- Archlinux: PKGBUILD in AUR (fenrir-git recommended)
|
||||||
- PIP: sudo pip install fenrir-screenreader
|
- PIP: sudo pip install fenrir-screenreader
|
||||||
- Manual:
|
- Manual:
|
||||||
- install "espeak" and "sox" with your package manager
|
- install "espeak" and "sox" with your package manager
|
||||||
- sudo pip install -r requirements.txt
|
- sudo pip install -r requirements.txt
|
||||||
- run install.sh and uninstall.sh as root
|
- run install.sh or uninstall.sh as root
|
||||||
- you also can just run it from Git without installing:
|
- you also can just run it from Git without installing:
|
||||||
You can just run the following as root:
|
You can just run the following as root:
|
||||||
if you are in Fenrir Git rootfolder:
|
if you are in Fenrir Git rootfolder:
|
||||||
cd src/fenrir/
|
|
||||||
sudo ./fenrir
|
cd src/fenrir/
|
||||||
|
sudo ./fenrir
|
||||||
|
|
||||||
|
Same thing, but use the daemon so the terminal is not blocked:
|
||||||
|
|
||||||
|
cd src/fenrir/
|
||||||
|
sudo ./fenrir-daemon
|
||||||
|
|
||||||
Settings "settings.conf" is located in the "config" directory or after installation in /etc/fenrir/settings.
|
Settings "settings.conf" is located in the "config" directory or after installation in /etc/fenrir/settings.
|
||||||
Take care to use drivers from the config matching your installed drivers.
|
Take care to use drivers from the config matching your installed drivers.
|
||||||
By default it uses:
|
By default it uses:
|
||||||
@ -87,21 +115,37 @@ By default it uses:
|
|||||||
- speech driver: genericDriver (via espeak or espeak-ng, could configured in settings.conf)
|
- speech driver: genericDriver (via espeak or espeak-ng, could configured in settings.conf)
|
||||||
- braille driver: brlttyDriver (WIP)
|
- braille driver: brlttyDriver (WIP)
|
||||||
- input driver: evdevDriver
|
- input driver: evdevDriver
|
||||||
|
|
||||||
|
|
||||||
# Configure pulseaudio
|
# Configure pulseaudio
|
||||||
Pulseaudio by default does only play sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
|
|
||||||
for this fenrir provides a script to configure pulseaudio to stream the sound played as root to your local user. Last is playing the sound then. This is not a issue of fenrir but this is how pulseaudio works.
|
|
||||||
|
|
||||||
just run the configuration scipt twice (once as user, once as root).
|
Pulseaudio by default only plays sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
|
||||||
|
for this fenrir provides a script to configure pulseaudio to stream the sound played as root to your local user. This is not a issue of fenrir but this is how pulseaudio works.
|
||||||
|
|
||||||
Run:
|
just run the configuration script twice (once as user, once as root):
|
||||||
configure_pulse.sh
|
|
||||||
sudo configure_pulse.sh
|
|
||||||
|
|
||||||
The script could also be found at /tools/ in git
|
/usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||||
|
sudo /usr/share/fenrirscreenreader/tools/configure_pulse.sh
|
||||||
|
|
||||||
|
The script is also located in the tools directory in git
|
||||||
|
|
||||||
|
|
||||||
|
# Configure pipewire
|
||||||
|
|
||||||
|
Pipewire by default only plays sound for the user its currently running for. As fenrir is running as root, your local user does not hear the sound and speech produced by fenrir.
|
||||||
|
for this fenrir provides a script to configure pipewire to stream the sound played as root to your local user. This is not a issue of fenrir but this is how pipewire works.
|
||||||
|
|
||||||
|
just run the configuration script twice (once as user, once as root):
|
||||||
|
|
||||||
|
/usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||||
|
sudo /usr/share/fenrirscreenreader/tools/configure_pipewire.sh
|
||||||
|
|
||||||
|
The script is also located in the tools directory in git
|
||||||
|
|
||||||
# localization
|
# localization
|
||||||
copy fenrir.mo translations file from fenrir/locale/your_language/LC_MESSAGES/fenrir.mo to /usr/share/locale/your_language/LC_MESSAGES/fenrir.mo
|
copy fenrir.mo translations file from fenrir/locale/your_language/LC_MESSAGES/fenrir.mo to /usr/share/locale/your_language/LC_MESSAGES/fenrir.mo
|
||||||
|
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
You can see all information on the Wiki:
|
|
||||||
https://wiki.linux-a11y.org/doku.php?id=fenrir_user_manual
|
Here is the [Fenrir Wiki](https://github.com/chrys87/fenrir/wiki). It is currently being updated, so keep checking back. Feel free to help with documentation.
|
||||||
|
@ -32,12 +32,15 @@ KEY_FENRIR,KEY_KP5=curr_screen
|
|||||||
KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
|
KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
|
||||||
KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
|
KEY_FENRIR,KEY_KP2=curr_screen_after_cursor
|
||||||
#=cursor_read_to_end_of_line
|
#=cursor_read_to_end_of_line
|
||||||
|
#=review_screen_last_char
|
||||||
|
#=review_screen_first_char
|
||||||
#=cursor_column
|
#=cursor_column
|
||||||
#=cursor_lineno
|
#=cursor_lineno
|
||||||
#=braille_flush
|
#=braille_flush
|
||||||
#=braille_return_to_cursor
|
#=braille_return_to_cursor
|
||||||
#=braille_pan_left
|
#=braille_pan_left
|
||||||
#=braille_pan_right
|
#=braille_pan_right
|
||||||
|
#=cursor_read_line_to_cursor
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
|
KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
|
KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
|
||||||
KEY_FENRIR,KEY_1=bookmark_1
|
KEY_FENRIR,KEY_1=bookmark_1
|
||||||
|
@ -6,7 +6,7 @@ KEY_FENRIR,KEY_I=review_curr_line
|
|||||||
KEY_FENRIR,KEY_U=review_prev_line
|
KEY_FENRIR,KEY_U=review_prev_line
|
||||||
KEY_FENRIR,KEY_O=review_next_line
|
KEY_FENRIR,KEY_O=review_next_line
|
||||||
KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin
|
KEY_FENRIR,KEY_SHIFT,KEY_J=review_line_begin
|
||||||
KEY_FENRIR,KEY_SHFIT,KEY_L=review_line_end
|
KEY_FENRIR,KEY_SHIFT,KEY_L=review_line_end
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
|
KEY_FENRIR,KEY_CTRL,KEY_J=review_line_first_char
|
||||||
KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
|
KEY_FENRIR,KEY_CTRL,KEY_L=review_line_last_char
|
||||||
KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
|
KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
|
||||||
@ -83,6 +83,7 @@ KEY_FENRIR,KEY_ENTER=toggle_auto_read
|
|||||||
KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
|
KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
|
||||||
KEY_FENRIR,KEY_Y=toggle_highlight_tracking
|
KEY_FENRIR,KEY_Y=toggle_highlight_tracking
|
||||||
#=toggle_barrier
|
#=toggle_barrier
|
||||||
|
#=cursor_read_line_to_cursor
|
||||||
KEY_FENRIR,KEY_Q=quit_fenrir
|
KEY_FENRIR,KEY_Q=quit_fenrir
|
||||||
KEY_FENRIR,KEY_T=time
|
KEY_FENRIR,KEY_T=time
|
||||||
2,KEY_FENRIR,KEY_T=date
|
2,KEY_FENRIR,KEY_T=date
|
||||||
|
218
config/keyboard/speakup.conf
Normal file
218
config/keyboard/speakup.conf
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
# Fenrir comment: copy of speakup DefaultKeyAssignments converted to fenrir syntax
|
||||||
|
# Fenrir comment: https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/drivers/staging/speakup/DefaultKeyAssignments
|
||||||
|
# Fenrir comment: The insert or shift key named below is the fenrir key
|
||||||
|
|
||||||
|
# This file is intended to give you an overview of the default keys used
|
||||||
|
# by speakup for it's review functions. You may change them to be
|
||||||
|
# anything you want but that will take some familiarity with key
|
||||||
|
# mapping.
|
||||||
|
|
||||||
|
# We have remapped the insert or zero key on the keypad to act as a
|
||||||
|
# shift key. Well, actually as an altgr key. So in the following list
|
||||||
|
# InsKeyPad-period means hold down the insert key like a shift key and
|
||||||
|
# hit the keypad period.
|
||||||
|
|
||||||
|
# KeyPad-8 Say current Line
|
||||||
|
KEY_KP8=review_curr_line
|
||||||
|
|
||||||
|
# InsKeyPad-8 say from top of screen to reading cursor.
|
||||||
|
KEY_FENRIR,KEY_KP8=curr_screen_before_cursor
|
||||||
|
|
||||||
|
# KeyPad-7 Say Previous Line (UP one line)
|
||||||
|
KEY_KP7=review_prev_line
|
||||||
|
|
||||||
|
# KeyPad-9 Say Next Line (down one line)
|
||||||
|
KEY_KP9=review_next_line
|
||||||
|
|
||||||
|
# KeyPad-5 Say Current Word
|
||||||
|
KEY_KP5=review_curr_word
|
||||||
|
|
||||||
|
# InsKeyPad-5 Spell Current Word
|
||||||
|
KEY_FENRIR,KEY_KP5=review_curr_word_phonetic
|
||||||
|
|
||||||
|
# KeyPad-4 Say Previous Word (left one word)
|
||||||
|
KEY_KP4=review_prev_word
|
||||||
|
|
||||||
|
# InsKeyPad-4 say from left edge of line to reading cursor.
|
||||||
|
KEY_FENRIR,KEY_KP4=cursor_read_line_to_cursor
|
||||||
|
|
||||||
|
# KeyPad-6 Say Next Word (right one word)
|
||||||
|
KEY_KP6=review_next_word
|
||||||
|
|
||||||
|
# InsKeyPad-6 Say from reading cursor to right edge of line.
|
||||||
|
KEY_FENRIR,KEY_KP6=cursor_read_to_end_of_line
|
||||||
|
|
||||||
|
# KeyPad-2 Say Current Letter
|
||||||
|
KEY_KP2=review_curr_char
|
||||||
|
|
||||||
|
# InsKeyPad-2 say current letter phonetically
|
||||||
|
KEY_FENRIR,KEY_KP2=review_curr_char_phonetic
|
||||||
|
|
||||||
|
# KeyPad-1 Say Previous Character (left one letter)
|
||||||
|
KEY_KP1=review_prev_char
|
||||||
|
|
||||||
|
# KeyPad-3 Say Next Character (right one letter)
|
||||||
|
KEY_KP3=review_next_char
|
||||||
|
|
||||||
|
# KeyPad-plus Say Entire Screen
|
||||||
|
KEY_KPPLUS=curr_screen
|
||||||
|
|
||||||
|
# InsKeyPad-plus Say from reading cursor line to bottom of screen.
|
||||||
|
KEY_FENRIR,KEY_KPPLUS=curr_screen_after_cursor
|
||||||
|
|
||||||
|
# KeyPad-Minus Park reading cursor (toggle)
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
# InsKeyPad-minus Say character hex and decimal value.
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
# KeyPad-period Say Position (current line, position and console)
|
||||||
|
KEY_KPDOT=cursor_position
|
||||||
|
|
||||||
|
# InsKeyPad-period say colour attributes of current position.
|
||||||
|
KEY_FENRIR,KEY_KPDOT=attribute_cursor
|
||||||
|
|
||||||
|
# InsKeyPad-9 Move reading cursor to top of screen (insert pgup)
|
||||||
|
KEY_FENRIR,KEY_KP9=review_bottom
|
||||||
|
|
||||||
|
# InsKeyPad-3 Move reading cursor to bottom of screen (insert pgdn)
|
||||||
|
KEY_FENRIR,KEY_KP3=review_top
|
||||||
|
|
||||||
|
# InsKeyPad-7 Move reading cursor to left edge of screen (insert home)
|
||||||
|
KEY_FENRIR,KEY_KP7=review_screen_first_char
|
||||||
|
|
||||||
|
# InsKeyPad-1 Move reading cursor to right edge of screen (insert end)
|
||||||
|
KEY_FENRIR,KEY_KP1=review_screen_last_char
|
||||||
|
|
||||||
|
# ControlKeyPad-1 Move reading cursor to last character on current line.
|
||||||
|
KEY_CTRL,KEY_KP1=review_line_end
|
||||||
|
|
||||||
|
# KeyPad-Enter Shut Up (until another key is hit) and sync reading cursor
|
||||||
|
KEY_KPENTER=temp_disable_speech
|
||||||
|
|
||||||
|
# InsKeyPad-Enter Shut Up (until toggled back on).
|
||||||
|
KEY_FENRIR,KEY_KPENTER=toggle_speech
|
||||||
|
|
||||||
|
# InsKeyPad-star n<x|y> go to line (y) or column (x). Where 'n' is any
|
||||||
|
# allowed value for the row or column for your current screen.
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
# KeyPad-/ Mark and Cut screen region.
|
||||||
|
KEY_KPSLASH=copy_marked_to_clipboard
|
||||||
|
|
||||||
|
# InsKeyPad-/ Paste screen region into any console.
|
||||||
|
KEY_FENRIR,KEY_KPSLASH=paste_clipboard
|
||||||
|
|
||||||
|
|
||||||
|
# Hitting any key while speakup is outputting speech will quiet the
|
||||||
|
# synth until it has caught up with what is being printed on the
|
||||||
|
# console.
|
||||||
|
|
||||||
|
# following by other fenrir commands
|
||||||
|
KEY_FENRIR,KEY_H=toggle_tutorial_mode
|
||||||
|
KEY_CTRL=shut_up
|
||||||
|
|
||||||
|
|
||||||
|
KEY_FENRIR,KEY_KP4=review_line_begin
|
||||||
|
#=review_line_end
|
||||||
|
#=review_line_first_char
|
||||||
|
#=review_line_last_char
|
||||||
|
KEY_FENRIR,KEY_ALT,KEY_1=present_first_line
|
||||||
|
KEY_FENRIR,KEY_ALT,KEY_2=present_last_line
|
||||||
|
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_KP4=review_prev_word_phonetic
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_KP6=review_next_word_phonetic
|
||||||
|
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_KP1=review_prev_char_phonetic
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_KP3=review_next_char_phonetic
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_KP8=review_up
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_KP2=review_down
|
||||||
|
#=exit_review
|
||||||
|
KEY_FENRIR,KEY_I=indent_curr_line
|
||||||
|
KEY_KPPLUS=curr_screen
|
||||||
|
#=cursor_column
|
||||||
|
#=cursor_lineno
|
||||||
|
#=braille_flush
|
||||||
|
#=braille_return_to_cursor
|
||||||
|
#=braille_pan_left
|
||||||
|
#=braille_pan_right
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_1=clear_bookmark_1
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_1=set_bookmark_1
|
||||||
|
KEY_FENRIR,KEY_1=bookmark_1
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_2=clear_bookmark_2
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_2=set_bookmark_2
|
||||||
|
KEY_FENRIR,KEY_2=bookmark_2
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_3=clear_bookmark_3
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_3=set_bookmark_3
|
||||||
|
KEY_FENRIR,KEY_3=bookmark_3
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_4=clear_bookmark_4
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_4=set_bookmark_4
|
||||||
|
KEY_FENRIR,KEY_4=bookmark_4
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_5=clear_bookmark_5
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_5=set_bookmark_5
|
||||||
|
KEY_FENRIR,KEY_5=bookmark_5
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_6=clear_bookmark_6
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_6=set_bookmark_6
|
||||||
|
KEY_FENRIR,KEY_6=bookmark_6
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_7=clear_bookmark_7
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_7=set_bookmark_7
|
||||||
|
KEY_FENRIR,KEY_7=bookmark_7
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_8=clear_bookmark_8
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_8=set_bookmark_8
|
||||||
|
KEY_FENRIR,KEY_8=bookmark_8
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_9=clear_bookmark_9
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_9=set_bookmark_9
|
||||||
|
KEY_FENRIR,KEY_9=bookmark_9
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_0=clear_bookmark_10
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_0=set_bookmark_10
|
||||||
|
KEY_FENRIR,KEY_0=bookmark_10
|
||||||
|
KEY_FENRIR,KEY_KPSLASH=set_window_application
|
||||||
|
2,KEY_FENRIR,KEY_KPSLASH=clear_window_application
|
||||||
|
#=last_incoming
|
||||||
|
KEY_FENRIR,KEY_F2=toggle_braille
|
||||||
|
KEY_FENRIR,KEY_F3=toggle_sound
|
||||||
|
|
||||||
|
KEY_FENRIR,KEY_F9=toggle_punctuation_level
|
||||||
|
KEY_FENRIR,KEY_RIGHTBRACE=toggle_auto_spell_check
|
||||||
|
KEY_FENRIR,KEY_BACKSLASH=toggle_output
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_E=toggle_emoticons
|
||||||
|
key_FENRIR,KEY_KPENTER=toggle_auto_read
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_T=toggle_auto_time
|
||||||
|
KEY_FENRIR,KEY_KPASTERISK=toggle_highlight_tracking
|
||||||
|
KEY_FENRIR,KEY_KPMINUS=toggle_barrier
|
||||||
|
KEY_FENRIR,KEY_Q=quit_fenrir
|
||||||
|
KEY_FENRIR,KEY_T=time
|
||||||
|
2,KEY_FENRIR,KEY_T=date
|
||||||
|
KEY_KPSLASH=toggle_auto_indent
|
||||||
|
#=toggle_has_attribute
|
||||||
|
KEY_FENRIR,KEY_S=spell_check
|
||||||
|
2,KEY_FENRIR,KEY_S=add_word_to_spell_check
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_S=remove_word_from_spell_check
|
||||||
|
KEY_FENRIR,KEY_BACKSPACE=forward_keypress
|
||||||
|
KEY_FENRIR,KEY_ALT,KEY_UP=inc_sound_volume
|
||||||
|
KEY_FENRIR,KEY_ALT,KEY_DOWN=dec_sound_volume
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_C=clear_clipboard
|
||||||
|
KEY_FENRIR,KEY_HOME=first_clipboard
|
||||||
|
KEY_FENRIR,KEY_END=last_clipboard
|
||||||
|
KEY_FENRIR,KEY_PAGEUP=prev_clipboard
|
||||||
|
KEY_FENRIR,KEY_PAGEDOWN=next_clipboard
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_C=curr_clipboard
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_C=copy_last_echo_to_clipboard
|
||||||
|
KEY_FENRIR,KEY_F5=import_clipboard_from_file
|
||||||
|
KEY_FENRIR,KEY_F6=export_clipboard_to_file
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_SHIFT,KEY_X=remove_marks
|
||||||
|
KEY_FENRIR,KEY_X=set_mark
|
||||||
|
KEY_FENRIR,KEY_SHIFT,KEY_X=marked_text
|
||||||
|
KEY_FENRIR,KEY_F10=toggle_vmenu_mode
|
||||||
|
KEY_FENRIR,KEY_SPACE=current_quick_menu_entry
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_SPACE=current_quick_menu_value
|
||||||
|
KEY_FENRIR,KEY_RIGHT=next_quick_menu_entry
|
||||||
|
KEY_FENRIR,KEY_UP=next_quick_menu_value
|
||||||
|
KEY_FENRIR,KEY_LEFT=prev_quick_menu_entry
|
||||||
|
KEY_FENRIR,KEY_DOWN=prev_quick_menu_value
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_S=save_settings
|
||||||
|
# linux specific
|
||||||
|
KEY_FENRIR,KEY_F7=import_clipboard_from_x
|
||||||
|
KEY_FENRIR,KEY_F8=export_clipboard_to_x
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_UP=inc_alsa_volume
|
||||||
|
KEY_FENRIR,KEY_CTRL,KEY_DOWN=dec_alsa_volume
|
78
config/punctuation/rhvoice-en.conf
Normal file
78
config/punctuation/rhvoice-en.conf
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
# how to use this file?
|
||||||
|
# the # on the beginning of the line is a comment
|
||||||
|
# the different sections are seperated by [<name>Dict] <name> is the section name. Dict is a keyword
|
||||||
|
# the entrys are seperated with :===: in words colon tripple equal colon ( to not collide with substitutions)
|
||||||
|
[levelDict]
|
||||||
|
none:===:
|
||||||
|
some:===:-$~+*-/\@
|
||||||
|
most:===:.,:-$~+*-/\@!#%^&*()[]}{<>;
|
||||||
|
all:===:!"#$%& \'()*+,-./:;<=>?@[\\]^_`{|}~
|
||||||
|
|
||||||
|
[punctDict]
|
||||||
|
:===:space
|
||||||
|
&:===:and
|
||||||
|
':===:apostrophe
|
||||||
|
@:===:at
|
||||||
|
\:===:backslash
|
||||||
|
|:===:bar
|
||||||
|
!:===:bang
|
||||||
|
^:===:carrot
|
||||||
|
::===:colon
|
||||||
|
,:===:comma
|
||||||
|
-:===:dash
|
||||||
|
$:===:dollar
|
||||||
|
.:===:dot
|
||||||
|
>:===:greater
|
||||||
|
`:===:grave
|
||||||
|
#:===:hash
|
||||||
|
{:===:left brace
|
||||||
|
[:===:left bracket
|
||||||
|
(:===:left paren
|
||||||
|
<:===:less
|
||||||
|
%:===:percent
|
||||||
|
+:===:plus
|
||||||
|
?:===:question?
|
||||||
|
":===:quote
|
||||||
|
):===:right paren
|
||||||
|
}:===:right brace
|
||||||
|
]:===:right bracket
|
||||||
|
;:===:semicolon
|
||||||
|
/:===:slash
|
||||||
|
*:===:star
|
||||||
|
~:===:tilde
|
||||||
|
_:===:line
|
||||||
|
=:===:equals
|
||||||
|
|
||||||
|
[customDict]
|
||||||
|
regex;(?i)certificates:===:certiffikets
|
||||||
|
regex;(?i)certificate:===:certifficate
|
||||||
|
regex;(?i)lowblow:===:LowBlow
|
||||||
|
regex;(?i)nginx:===:EngineX
|
||||||
|
regex;(?i)shit:===:shitt
|
||||||
|
regex;(?i)slither:===:slitther
|
||||||
|
|
||||||
|
[emoticonDict]
|
||||||
|
# This dictionary uses regexp when prefixed with "regex;", so be sure to escape anything that would be parsed by regexp, e.g. *, ., ^, $, etc.
|
||||||
|
regex;[\s*|'|"][\s*|'|"]<{-.-}>:===:Raves
|
||||||
|
regex;[\s*|'|"][\s*|'|"]8-\):===:smile with sunglasses
|
||||||
|
regex;[\s*|'|"][\s*|'|"]:-/:===:confused
|
||||||
|
regex;[\s*|'|"][\s*|'|"]-\.-:===:bugged
|
||||||
|
regex;[\s*|'|"][\s*|'|"]>\.<:===:laughing
|
||||||
|
regex;[\s*|'|"][\s*|'|"]8-X:===:skull
|
||||||
|
regex;[\s*|'|"][\s*|'|"]>:\):===:evil smile
|
||||||
|
regex;[\s*|'|"][\s*|'|"]>:-\):===:evil smile
|
||||||
|
regex;[\s*|'|"][\s*|'|"]\\o/:===:Hurray
|
||||||
|
regex;[\s*|'|"][\s*|'|"]:/:===:confused
|
||||||
|
regex;[\s*|'|"]:D[\s*|'|"]:===:laugh
|
||||||
|
regex;[\s*|'|"];\)[\s*|'|"]:===:wink
|
||||||
|
regex;[\s*|'|"]XD[\s*|'|"]:===:LOL
|
||||||
|
regex;[\s*|'|"]:-\)[\s*|'|"]:===:smile
|
||||||
|
regex;[\s*|'|"]:\)[\s*|'|"]:===:smile
|
||||||
|
regex;[\s*|'|"]->[\s*|'|"]:===:arrow right
|
||||||
|
# example for arrow left
|
||||||
|
#(?:[ |^])(<-)(?:[ ,.!?$]):===:arrow left
|
||||||
|
# or
|
||||||
|
#([ |^])<-([ ,.!?$]):===:arrow left\2
|
||||||
|
regex;[\s*|'|"]<-[\s*|'|"]:===:arrow left
|
||||||
|
regex;[\s+|'|"][O|o][O|o][\s+|'|"]:===:WTF?
|
||||||
|
regex;[\s*|'|"]\^\^[\s*|'|"]:===:enjoy smile
|
@ -134,7 +134,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=True
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
## echo deleted chars
|
## echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
265
config/settings/settings-chime.conf
Normal file
265
config/settings/settings-chime.conf
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
[sound]
|
||||||
|
# Turn sound on or off:
|
||||||
|
enabled=True
|
||||||
|
|
||||||
|
# Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
|
||||||
|
# Sox is the default.
|
||||||
|
#driver=gstreamerDriver
|
||||||
|
driver=genericDriver
|
||||||
|
|
||||||
|
# Sound themes. These are the pack of sounds used for sound alerts.
|
||||||
|
# Sound packs may be located at /usr/share/sounds
|
||||||
|
# For system wide availability, or ~/.local/share/fenrirscreenreader/sounds
|
||||||
|
# For the current user.
|
||||||
|
theme=default
|
||||||
|
|
||||||
|
# Sound volume controls how loud the sounds for your selected soundpack are.
|
||||||
|
# 0 is quietest, 1.0 is loudest.
|
||||||
|
volume=1.0
|
||||||
|
|
||||||
|
# shell commands for generic sound driver
|
||||||
|
# the folowing variable are substituted
|
||||||
|
# fenrirVolume = the current volume setting
|
||||||
|
# fenrirSoundFile = the soundfile for an soundicon
|
||||||
|
# fenrirFrequence = the frequency to play
|
||||||
|
# fenrirDuration = the duration of the frequency
|
||||||
|
# the following command is used to play a soundfile
|
||||||
|
genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
|
||||||
|
#the following command is used to generate a frequency beep
|
||||||
|
genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
|
||||||
|
|
||||||
|
[speech]
|
||||||
|
# Turn speech on or off:
|
||||||
|
enabled=True
|
||||||
|
|
||||||
|
# Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
|
||||||
|
# chrys: comment out genericDriver, uncomment speechdDriver
|
||||||
|
driver=speechdDriver
|
||||||
|
#driver=espeakDriver
|
||||||
|
#driver=genericDriver
|
||||||
|
|
||||||
|
# server path for emacspeak
|
||||||
|
serverPath=/home/chrys/Projekte/emacspeak/servers/espeak
|
||||||
|
|
||||||
|
# The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
|
||||||
|
rate=0.65
|
||||||
|
|
||||||
|
# Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
|
||||||
|
pitch=0.5
|
||||||
|
# Pitch for capital letters
|
||||||
|
capitalPitch=0.9
|
||||||
|
|
||||||
|
# Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
|
||||||
|
volume=1.0
|
||||||
|
|
||||||
|
# Module is used for Speech-dispatcher, to select the speech module you want to use.
|
||||||
|
# Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available.
|
||||||
|
# The default is specified in speechd.conf.
|
||||||
|
# chrys: uncomment module, set it to voxin (default espeak-ng)
|
||||||
|
module=voxin
|
||||||
|
|
||||||
|
# Voice selects the voice you want to use, for example, en-GB-scotland will use the Scotish English voice in Espeak,
|
||||||
|
# To find out which voices are available, consult the documentation provided with your selected synthesizer.
|
||||||
|
# This also sets the voice used in the generic driver.
|
||||||
|
# You can add a variant by adding +name onto the end.
|
||||||
|
# chrys: set voice (default was en-us)
|
||||||
|
voice=allison-embedded-high
|
||||||
|
|
||||||
|
# Select the language you want Fenrir to use.
|
||||||
|
# chrys: uncomment language and set language to en-US (default was en)
|
||||||
|
language=en
|
||||||
|
|
||||||
|
# Read new text as it happens?
|
||||||
|
autoReadIncoming=True
|
||||||
|
|
||||||
|
# genericSpeechCommand is the command that is executed for talking
|
||||||
|
# the following variables are replaced with values
|
||||||
|
# fenrirText = is the text that should be spoken
|
||||||
|
# fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this
|
||||||
|
# fenrirLanguage = the language
|
||||||
|
# fenrirVoice = is the current voice that should be used. Set the voice variable above.
|
||||||
|
# the current volume, pitch and rate is calculated like this
|
||||||
|
# value = min + settingValue * (min - max )
|
||||||
|
# fenrirVolume = is replaced with the current volume
|
||||||
|
# fenrirPitch = is replaced with the current pitch
|
||||||
|
# fenrirRate = is replaced with the current speed (speech rate)
|
||||||
|
genericSpeechCommand=espeak-ng -a fenrirVolume -s fenrirRate -p fenrirPitch -v fenrirVoice -- "fenrirText"
|
||||||
|
|
||||||
|
# those are the min and max values of the TTS system that is used in genericSpeechCommand
|
||||||
|
fenrirMinVolume=0
|
||||||
|
fenrirMaxVolume=200
|
||||||
|
fenrirMinPitch=0
|
||||||
|
fenrirMaxPitch=99
|
||||||
|
fenrirMinRate=80
|
||||||
|
fenrirMaxRate=450
|
||||||
|
|
||||||
|
[braille]
|
||||||
|
enabled=False
|
||||||
|
driver=dummyDriver
|
||||||
|
layout=en
|
||||||
|
# to what should the flush timeout relate to
|
||||||
|
# word = flush after (number of words to display) * seconds
|
||||||
|
# char = flush after (number of chars to display) * seconds
|
||||||
|
# fix = flush after X seconds
|
||||||
|
# none = no automatic flush (manual via shortcut)
|
||||||
|
flushMode=word
|
||||||
|
# seconds to flush or
|
||||||
|
# -1 = no automatic flush (manual via shortcut)
|
||||||
|
flushTimeout=3
|
||||||
|
# how should the cursor be focused?
|
||||||
|
# page = if cursor cross the border move to next page and start at beginn
|
||||||
|
# fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
|
||||||
|
cursorFocusMode=page
|
||||||
|
# define the cell on the Braille device where fenrir should scroll and keep the cursor
|
||||||
|
# 0 = first cell on device
|
||||||
|
# -1 = last cell on device
|
||||||
|
# >0 = fix cell number
|
||||||
|
fixCursorOnCell=-1
|
||||||
|
#How should the braille follow the focus
|
||||||
|
# none = no automatic toggle command used
|
||||||
|
# review = priority to review
|
||||||
|
# last = follow last used cursor
|
||||||
|
cursorFollowMode=review
|
||||||
|
# number of cells in panning (horizontal)
|
||||||
|
# 0 = display size, >0 number of cells
|
||||||
|
panSizeHorizontal=0
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
driver=vcsaDriver
|
||||||
|
encoding=auto
|
||||||
|
screenUpdateDelay=0.05
|
||||||
|
suspendingScreen=
|
||||||
|
autodetectSuspendingScreen=True
|
||||||
|
|
||||||
|
[keyboard]
|
||||||
|
driver=evdevDriver
|
||||||
|
# filter input devices NOMICE, ALL or a DEVICE NAME
|
||||||
|
device=ALL
|
||||||
|
# gives Fenrir exclusive access to the keyboard and lets it control keystrokes.
|
||||||
|
grabDevices=True
|
||||||
|
ignoreShortcuts=False
|
||||||
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
|
keyboardLayout=desktop
|
||||||
|
# echo chars while typing.
|
||||||
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
|
# echo deleted chars
|
||||||
|
charDeleteEcho=True
|
||||||
|
# echo word after pressing space
|
||||||
|
wordEcho=False
|
||||||
|
# interrupt speech on any keypress
|
||||||
|
interruptOnKeyPress=True
|
||||||
|
# you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
|
||||||
|
interruptOnKeyPressFilter=
|
||||||
|
# timeout for double tap in sec
|
||||||
|
doubleTapTimeout=0.2
|
||||||
|
|
||||||
|
[general]
|
||||||
|
debugLevel=0
|
||||||
|
# debugMode sets where the debug output should send to:
|
||||||
|
# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
|
||||||
|
# debugMode=Print just prints on the screen
|
||||||
|
debugMode=File
|
||||||
|
debugFile=
|
||||||
|
punctuationProfile=default
|
||||||
|
punctuationLevel=some
|
||||||
|
respectPunctuationPause=True
|
||||||
|
newLinePause=True
|
||||||
|
numberOfClipboards=10
|
||||||
|
# used path for "export_clipboard_to_file"
|
||||||
|
# $user is replaced by username
|
||||||
|
#clipboardExportPath=/home/$user/fenrirClipboard
|
||||||
|
clipboardExportPath=/tmp/fenrirClipboard
|
||||||
|
emoticons=True
|
||||||
|
# define the current Fenrir key
|
||||||
|
fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
|
||||||
|
scriptKeys=KEY_COMPOSE
|
||||||
|
timeFormat=%H:%M:%P
|
||||||
|
dateFormat=%A, %B %d, %Y
|
||||||
|
autoSpellCheck=True
|
||||||
|
spellCheckLanguage=en_US
|
||||||
|
# path for your scripts "scriptKeys" functionality
|
||||||
|
scriptPath=/usr/share/fenrirscreenreader/scripts
|
||||||
|
# overload commands, and create new one without changing Fenrir default
|
||||||
|
commandPath=
|
||||||
|
#fenrirBGColor = the backgroundcolor
|
||||||
|
#fenrirFGColor = the foregroundcolor
|
||||||
|
#fenrirUnderline = speak the underline attribute
|
||||||
|
#fenrirBold = speak the bold attribute
|
||||||
|
#fenrirBlink = speak the blink attribute
|
||||||
|
#fenrirFont = the font
|
||||||
|
#fenrirFontSize = the fontsize
|
||||||
|
attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
|
||||||
|
# present indentation
|
||||||
|
autoPresentIndent=False
|
||||||
|
# speak is only invoked on changeing ident level, sound always
|
||||||
|
# 0 = sound and speak
|
||||||
|
# 1 = sound only
|
||||||
|
# 2 = speak only
|
||||||
|
autoPresentIndentMode=1
|
||||||
|
# play a sound when attributes are changeing
|
||||||
|
hasAttributes=True
|
||||||
|
# shell for PTY emulatiun (empty = default shell)
|
||||||
|
shell=
|
||||||
|
|
||||||
|
[focus]
|
||||||
|
#follow the text cursor
|
||||||
|
cursor=True
|
||||||
|
#follow highlighted text changes
|
||||||
|
highlight=False
|
||||||
|
|
||||||
|
[remote]
|
||||||
|
enable=True
|
||||||
|
# driver
|
||||||
|
# unixDriver = unix sockets
|
||||||
|
# tcpDriver = tcp (localhost only)
|
||||||
|
driver=unixDriver
|
||||||
|
# tcp port
|
||||||
|
port=22447
|
||||||
|
# socket filepath
|
||||||
|
socketFile=
|
||||||
|
# allow settings to overwrite
|
||||||
|
enableSettingsRemote=True
|
||||||
|
# allow commands to be executed
|
||||||
|
enableCommandRemote=True
|
||||||
|
|
||||||
|
[barrier]
|
||||||
|
enabled=True
|
||||||
|
leftBarriers=│└┌─
|
||||||
|
rightBarriers=│┘┐─
|
||||||
|
|
||||||
|
[review]
|
||||||
|
lineBreak=True
|
||||||
|
endOfScreen=True
|
||||||
|
# leave the review when pressing a key
|
||||||
|
leaveReviewOnCursorChange=True
|
||||||
|
# leave the review when changing the screen
|
||||||
|
leaveReviewOnScreenChange=True
|
||||||
|
|
||||||
|
[promote]
|
||||||
|
enabled=True
|
||||||
|
inactiveTimeoutSec=120
|
||||||
|
list=
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
vmenuPath=
|
||||||
|
quickMenu=speech#rate;speech#pitch;speech#volume
|
||||||
|
|
||||||
|
[time]
|
||||||
|
# automatic time anouncement
|
||||||
|
enabled=False
|
||||||
|
# present time
|
||||||
|
presentTime=True
|
||||||
|
# present date (on change)
|
||||||
|
presentDate=True
|
||||||
|
# present time after a given period of seconds
|
||||||
|
delaySec=0
|
||||||
|
# present time after to given minutes example every 15 minutes: 00,15,30,45
|
||||||
|
# if delaySec is >0 onMinutes is ignored
|
||||||
|
onMinutes=00,30
|
||||||
|
# announce via soundicon (not interrupting)
|
||||||
|
announce=True
|
||||||
|
# interrupt current speech for time announcement
|
||||||
|
interrupt=False
|
@ -136,7 +136,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
# echo deleted chars
|
# echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
@ -136,7 +136,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
# echo deleted chars
|
# echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
@ -137,7 +137,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=1
|
||||||
# echo deleted chars
|
# echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
261
config/settings/settings.conf.dectalk
Normal file
261
config/settings/settings.conf.dectalk
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
[sound]
|
||||||
|
# Turn sound on or off:
|
||||||
|
enabled=True
|
||||||
|
|
||||||
|
# Select the driver used to play sounds, choices are genericDriver and gstreamerDriver.
|
||||||
|
# Sox is the default.
|
||||||
|
#driver=gstreamerDriver
|
||||||
|
driver=genericDriver
|
||||||
|
|
||||||
|
# Sound themes. These are the pack of sounds used for sound alerts.
|
||||||
|
# Sound packs may be located at /usr/share/sounds
|
||||||
|
# For system wide availability, or ~/.local/share/fenrirscreenreader/sounds
|
||||||
|
# For the current user.
|
||||||
|
theme=default
|
||||||
|
|
||||||
|
# Sound volume controls how loud the sounds for your selected soundpack are.
|
||||||
|
# 0 is quietest, 1.0 is loudest.
|
||||||
|
volume=1.0
|
||||||
|
|
||||||
|
# shell commands for generic sound driver
|
||||||
|
# the folowing variable are substituted
|
||||||
|
# fenrirVolume = the current volume setting
|
||||||
|
# fenrirSoundFile = the soundfile for an soundicon
|
||||||
|
# fenrirFrequence = the frequency to play
|
||||||
|
# fenrirDuration = the duration of the frequency
|
||||||
|
# the following command is used to play a soundfile
|
||||||
|
genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
|
||||||
|
#the following command is used to generate a frequency beep
|
||||||
|
genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
|
||||||
|
|
||||||
|
[speech]
|
||||||
|
# Turn speech on or off:
|
||||||
|
enabled=True
|
||||||
|
|
||||||
|
# Select speech driver, options are speechdDriver (default), genericDriver or espeakDriver:
|
||||||
|
#driver=speechdDriver
|
||||||
|
#driver=espeakDriver
|
||||||
|
driver=genericDriver
|
||||||
|
|
||||||
|
# server path for emacspeak
|
||||||
|
serverPath=/home/chrys/Projekte/emacspeak/servers/espeak
|
||||||
|
|
||||||
|
# The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
|
||||||
|
rate=0.2
|
||||||
|
|
||||||
|
# Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
|
||||||
|
pitch=0.5
|
||||||
|
# Pitch for capital letters
|
||||||
|
capitalPitch=0.9
|
||||||
|
|
||||||
|
# Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
|
||||||
|
volume=1.0
|
||||||
|
|
||||||
|
# Module is used for Speech-dispatcher, to select the speech module you want to use.
|
||||||
|
# Consult Speech-dispatcher's configuration and help Fenrir find out which modules are available.
|
||||||
|
# The default is specified in speechd.conf.
|
||||||
|
#module=espeak-ng
|
||||||
|
|
||||||
|
# Voice selects the voice you want to use, for example, en-GB-scotland will use the Scotish English voice in Espeak,
|
||||||
|
# To find out which voices are available, consult the documentation provided with your selected synthesizer.
|
||||||
|
# This also sets the voice used in the generic driver.
|
||||||
|
# You can add a variant by adding +name onto the end.
|
||||||
|
voice=0
|
||||||
|
|
||||||
|
# Select the language you want Fenrir to use.
|
||||||
|
#language=en
|
||||||
|
|
||||||
|
# Read new text as it happens?
|
||||||
|
autoReadIncoming=True
|
||||||
|
|
||||||
|
# genericSpeechCommand is the command that is executed for talking
|
||||||
|
# the following variables are replaced with values
|
||||||
|
# fenrirText = is the text that should be spoken
|
||||||
|
# fenrirModule = may be the speech module like used in speech-dispatcher, not every TTY need this
|
||||||
|
# fenrirLanguage = the language
|
||||||
|
# fenrirVoice = is the current voice that should be used. Set the voice variable above.
|
||||||
|
# the current volume, pitch and rate is calculated like this
|
||||||
|
# value = min + settingValue * (min - max )
|
||||||
|
# fenrirVolume = is replaced with the current volume
|
||||||
|
# fenrirPitch = is replaced with the current pitch
|
||||||
|
# fenrirRate = is replaced with the current speed (speech rate)
|
||||||
|
genericSpeechCommand=/opt/dectalk/say -v fenrirVolume -r fenrirRate -s fenrirVoice -a "fenrirText"
|
||||||
|
|
||||||
|
# those are the min and max values of the TTS system that is used in genericSpeechCommand
|
||||||
|
fenrirMinVolume=0
|
||||||
|
fenrirMaxVolume=100
|
||||||
|
fenrirMinPitch=0
|
||||||
|
fenrirMaxPitch=99
|
||||||
|
fenrirMinRate=75
|
||||||
|
fenrirMaxRate=600
|
||||||
|
|
||||||
|
[braille]
|
||||||
|
enabled=False
|
||||||
|
driver=dummyDriver
|
||||||
|
layout=en
|
||||||
|
# to what should the flush timeout relate to
|
||||||
|
# word = flush after (number of words to display) * seconds
|
||||||
|
# char = flush after (number of chars to display) * seconds
|
||||||
|
# fix = flush after X seconds
|
||||||
|
# none = no automatic flush (manual via shortcut)
|
||||||
|
flushMode=word
|
||||||
|
# seconds to flush or
|
||||||
|
# -1 = no automatic flush (manual via shortcut)
|
||||||
|
flushTimeout=3
|
||||||
|
# how should the cursor be focused?
|
||||||
|
# page = if cursor cross the border move to next page and start at beginn
|
||||||
|
# fixCell = ajust the cursor on an special cell where it is always placed. the display scroll here more smooth.
|
||||||
|
cursorFocusMode=page
|
||||||
|
# define the cell on the Braille device where fenrir should scroll and keep the cursor
|
||||||
|
# 0 = first cell on device
|
||||||
|
# -1 = last cell on device
|
||||||
|
# >0 = fix cell number
|
||||||
|
fixCursorOnCell=-1
|
||||||
|
#How should the braille follow the focus
|
||||||
|
# none = no automatic toggle command used
|
||||||
|
# review = priority to review
|
||||||
|
# last = follow last used cursor
|
||||||
|
cursorFollowMode=review
|
||||||
|
# number of cells in panning (horizontal)
|
||||||
|
# 0 = display size, >0 number of cells
|
||||||
|
panSizeHorizontal=0
|
||||||
|
|
||||||
|
[screen]
|
||||||
|
driver=vcsaDriver
|
||||||
|
encoding=auto
|
||||||
|
screenUpdateDelay=0.05
|
||||||
|
suspendingScreen=
|
||||||
|
autodetectSuspendingScreen=True
|
||||||
|
|
||||||
|
[keyboard]
|
||||||
|
driver=evdevDriver
|
||||||
|
# filter input devices NOMICE, ALL or a DEVICE NAME
|
||||||
|
device=ALL
|
||||||
|
# gives Fenrir exclusive access to the keyboard and lets it control keystrokes.
|
||||||
|
grabDevices=True
|
||||||
|
ignoreShortcuts=False
|
||||||
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
|
keyboardLayout=desktop
|
||||||
|
# echo chars while typing.
|
||||||
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=1
|
||||||
|
# echo deleted chars
|
||||||
|
charDeleteEcho=True
|
||||||
|
# echo word after pressing space
|
||||||
|
wordEcho=False
|
||||||
|
# interrupt speech on any keypress
|
||||||
|
interruptOnKeyPress=True
|
||||||
|
# you can filter the keys on that the speech should interrupt (empty = all keys, otherwhise the given keys)
|
||||||
|
interruptOnKeyPressFilter=
|
||||||
|
# timeout for double tap in sec
|
||||||
|
doubleTapTimeout=0.2
|
||||||
|
|
||||||
|
[general]
|
||||||
|
debugLevel=0
|
||||||
|
# debugMode sets where the debug output should send to:
|
||||||
|
# debugMode=File writes to debugFile (Default:/tmp/fenrir-PID.log)
|
||||||
|
# debugMode=Print just prints on the screen
|
||||||
|
debugMode=File
|
||||||
|
debugFile=
|
||||||
|
punctuationProfile=default
|
||||||
|
punctuationLevel=some
|
||||||
|
respectPunctuationPause=True
|
||||||
|
newLinePause=True
|
||||||
|
numberOfClipboards=10
|
||||||
|
# used path for "export_clipboard_to_file"
|
||||||
|
# $user is replaced by username
|
||||||
|
#clipboardExportPath=/home/$user/fenrirClipboard
|
||||||
|
clipboardExportPath=/tmp/fenrirClipboard
|
||||||
|
emoticons=True
|
||||||
|
# define the current Fenrir key
|
||||||
|
fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
|
||||||
|
scriptKeys=KEY_COMPOSE
|
||||||
|
timeFormat=%H:%M:%P
|
||||||
|
dateFormat=%A, %B %d, %Y
|
||||||
|
autoSpellCheck=True
|
||||||
|
spellCheckLanguage=en_US
|
||||||
|
# path for your scripts "scriptKeys" functionality
|
||||||
|
scriptPath=/usr/share/fenrirscreenreader/scripts
|
||||||
|
# overload commands, and create new one without changing Fenrir default
|
||||||
|
commandPath=
|
||||||
|
#fenrirBGColor = the backgroundcolor
|
||||||
|
#fenrirFGColor = the foregroundcolor
|
||||||
|
#fenrirUnderline = speak the underline attribute
|
||||||
|
#fenrirBold = speak the bold attribute
|
||||||
|
#fenrirBlink = speak the blink attribute
|
||||||
|
#fenrirFont = the font
|
||||||
|
#fenrirFontSize = the fontsize
|
||||||
|
attributeFormatString=Background fenrirBGColor,Foreground fenrirFGColor,fenrirUnderline,fenrirBold,fenrirBlink, Font fenrirFont,Fontsize fenrirFontSize
|
||||||
|
# present indentation
|
||||||
|
autoPresentIndent=False
|
||||||
|
# speak is only invoked on changeing ident level, sound always
|
||||||
|
# 0 = sound and speak
|
||||||
|
# 1 = sound only
|
||||||
|
# 2 = speak only
|
||||||
|
autoPresentIndentMode=1
|
||||||
|
# play a sound when attributes are changeing
|
||||||
|
hasAttributes=True
|
||||||
|
# shell for PTY emulatiun (empty = default shell)
|
||||||
|
shell=
|
||||||
|
|
||||||
|
[focus]
|
||||||
|
#follow the text cursor
|
||||||
|
cursor=True
|
||||||
|
#follow highlighted text changes
|
||||||
|
highlight=False
|
||||||
|
|
||||||
|
[remote]
|
||||||
|
enable=True
|
||||||
|
# driver
|
||||||
|
# unixDriver = unix sockets
|
||||||
|
# tcpDriver = tcp (localhost only)
|
||||||
|
driver=unixDriver
|
||||||
|
# tcp port
|
||||||
|
port=22447
|
||||||
|
# socket filepath
|
||||||
|
socketFile=
|
||||||
|
# allow settings to overwrite
|
||||||
|
enableSettingsRemote=True
|
||||||
|
# allow commands to be executed
|
||||||
|
enableCommandRemote=True
|
||||||
|
|
||||||
|
[barrier]
|
||||||
|
enabled=True
|
||||||
|
leftBarriers=│└┌─
|
||||||
|
rightBarriers=│┘┐─
|
||||||
|
|
||||||
|
[review]
|
||||||
|
lineBreak=True
|
||||||
|
endOfScreen=True
|
||||||
|
# leave the review when pressing a key
|
||||||
|
leaveReviewOnCursorChange=True
|
||||||
|
# leave the review when changing the screen
|
||||||
|
leaveReviewOnScreenChange=True
|
||||||
|
|
||||||
|
[promote]
|
||||||
|
enabled=True
|
||||||
|
inactiveTimeoutSec=120
|
||||||
|
list=
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
vmenuPath=
|
||||||
|
quickMenu=speech#rate;speech#pitch;speech#volume
|
||||||
|
|
||||||
|
[time]
|
||||||
|
# automatic time anouncement
|
||||||
|
enabled=False
|
||||||
|
# present time
|
||||||
|
presentTime=True
|
||||||
|
# present date (on change)
|
||||||
|
presentDate=True
|
||||||
|
# present time after a given period of seconds
|
||||||
|
delaySec=0
|
||||||
|
# present time after to given minutes example every 15 minutes: 00,15,30,45
|
||||||
|
# if delaySec is >0 onMinutes is ignored
|
||||||
|
onMinutes=00,30
|
||||||
|
# announce via soundicon (not interrupting)
|
||||||
|
announce=True
|
||||||
|
# interrupt current speech for time announcement
|
||||||
|
interrupt=False
|
@ -137,7 +137,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
# echo deleted chars
|
# echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
@ -88,7 +88,10 @@ device=ALL
|
|||||||
grabDevices=True
|
grabDevices=True
|
||||||
ignoreShortcuts=False
|
ignoreShortcuts=False
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
wordEcho=False
|
wordEcho=False
|
||||||
interruptOnKeyPress=True
|
interruptOnKeyPress=True
|
||||||
|
@ -136,7 +136,10 @@ ignoreShortcuts=False
|
|||||||
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
# the current shortcut layout located in /etc/fenrirscreenreader/keyboard
|
||||||
keyboardLayout=desktop
|
keyboardLayout=desktop
|
||||||
# echo chars while typing.
|
# echo chars while typing.
|
||||||
charEcho=False
|
# 0 = None
|
||||||
|
# 1 = always
|
||||||
|
# 2 = only while capslock
|
||||||
|
charEchoMode=2
|
||||||
# echo deleted chars
|
# echo deleted chars
|
||||||
charDeleteEcho=True
|
charDeleteEcho=True
|
||||||
# echo word after pressing space
|
# echo word after pressing space
|
||||||
|
456
docu/fenrir.1
456
docu/fenrir.1
File diff suppressed because it is too large
Load Diff
11
play zone/pasteClipboardDemo.py
Executable file
11
play zone/pasteClipboardDemo.py
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
import termios
|
||||||
|
import fcntl
|
||||||
|
|
||||||
|
def injectTextToScreen(text):
|
||||||
|
useScreen = "/dev/tty5"
|
||||||
|
with open(useScreen, 'w') as fd:
|
||||||
|
for c in text:
|
||||||
|
fcntl.ioctl(fd, termios.TIOCSTI, c)
|
||||||
|
|
||||||
|
injectTextToScreen('this is a test that works')
|
2
setup.py
2
setup.py
@ -1,4 +1,4 @@
|
|||||||
#!/bin/python
|
#!/usr/bin/env python3
|
||||||
#https://python-packaging.readthedocs.io/en/latest/minimal.html
|
#https://python-packaging.readthedocs.io/en/latest/minimal.html
|
||||||
import os, glob, sys
|
import os, glob, sys
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
|
|
||||||
|
from fenrirscreenreader.core import debug
|
||||||
|
from fenrirscreenreader.utils import line_utils
|
||||||
|
|
||||||
|
class command():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def initialize(self, environment):
|
||||||
|
self.env = environment
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
def getDescription(self):
|
||||||
|
return _('read line to cursor pos, use review cursor if you are in review mode, otherwhise use text cursor')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
||||||
|
|
||||||
|
x, y, currLine = \
|
||||||
|
line_utils.getCurrentLine(cursorPos['x'], cursorPos['y'], self.env['screen']['newContentText'])
|
||||||
|
|
||||||
|
if currLine.isspace():
|
||||||
|
self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
|
||||||
|
else:
|
||||||
|
self.env['runtime']['outputManager'].presentText(currLine[:cursorPos['x']], interrupt=True)
|
||||||
|
self.env['runtime']['outputManager'].announceActiveCursor()
|
||||||
|
def setCallback(self, callback):
|
||||||
|
pass
|
||||||
|
|
@ -26,7 +26,7 @@ class command():
|
|||||||
if currLine.isspace():
|
if currLine.isspace():
|
||||||
self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
|
self.env['runtime']['outputManager'].presentText(_("blank"), soundIcon='EmptyLine', interrupt=True)
|
||||||
else:
|
else:
|
||||||
self.env['runtime']['outputManager'].presentText(currLine[cursorPos['x']], interrupt=True)
|
self.env['runtime']['outputManager'].presentText(currLine[cursorPos['x']:], interrupt=True)
|
||||||
self.env['runtime']['outputManager'].announceActiveCursor()
|
self.env['runtime']['outputManager'].announceActiveCursor()
|
||||||
def setCallback(self, callback):
|
def setCallback(self, callback):
|
||||||
pass
|
pass
|
||||||
|
@ -20,30 +20,37 @@ class command():
|
|||||||
return _('Export current fenrir clipboard to X or GUI clipboard')
|
return _('Export current fenrir clipboard to X or GUI clipboard')
|
||||||
def run(self):
|
def run(self):
|
||||||
_thread.start_new_thread(self._threadRun , ())
|
_thread.start_new_thread(self._threadRun , ())
|
||||||
|
|
||||||
def _threadRun(self):
|
def _threadRun(self):
|
||||||
try:
|
try:
|
||||||
if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'):
|
if self.env['runtime']['memoryManager'].isIndexListEmpty('clipboardHistory'):
|
||||||
self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
|
self.env['runtime']['outputManager'].presentText(_('clipboard empty'), interrupt=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory')
|
clipboard = self.env['runtime']['memoryManager'].getIndexListElement('clipboardHistory')
|
||||||
|
user = self.env['general']['currUser']
|
||||||
|
|
||||||
for display in range(10):
|
for display in range(10):
|
||||||
p = Popen('su ' + self.env['general']['currUser'] + ' -c "cat << \\\"EOF\\\" | xclip -d :' + str(display) + ' -selection clipboard\n' + clipboard + '\nEOF\n"', stdout=PIPE, stderr=PIPE, shell=True)
|
p = Popen(
|
||||||
stdout, stderr = p.communicate()
|
['su', user, '-c', f"xclip -d :{display} -selection clipboard"],
|
||||||
|
stdin=PIPE, stdout=PIPE, stderr=PIPE, preexec_fn=os.setpgrp
|
||||||
|
)
|
||||||
|
stdout, stderr = p.communicate(input=clipboard.encode('utf-8'))
|
||||||
|
|
||||||
self.env['runtime']['outputManager'].interruptOutput()
|
self.env['runtime']['outputManager'].interruptOutput()
|
||||||
#screenEncoding = self.env['runtime']['settingsManager'].getSetting('screen', 'encoding')
|
|
||||||
stderr = stderr.decode('utf-8')
|
stderr = stderr.decode('utf-8')
|
||||||
stdout = stdout.decode('utf-8')
|
stdout = stdout.decode('utf-8')
|
||||||
if (stderr == ''):
|
|
||||||
|
if stderr == '':
|
||||||
break
|
break
|
||||||
#stderr = stderr.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
|
|
||||||
#stdout = stdout.decode(screenEncoding, "replace").encode('utf-8').decode('utf-8')
|
|
||||||
if stderr != '':
|
if stderr != '':
|
||||||
self.env['runtime']['outputManager'].presentText(stderr , soundIcon='', interrupt=False)
|
self.env['runtime']['outputManager'].presentText(stderr, soundIcon='', interrupt=False)
|
||||||
else:
|
else:
|
||||||
self.env['runtime']['outputManager'].presentText('exported to the X session.', interrupt=True)
|
self.env['runtime']['outputManager'].presentText('exported to the X session.', interrupt=True)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.env['runtime']['outputManager'].presentText(e , soundIcon='', interrupt=False)
|
self.env['runtime']['outputManager'].presentText(str(e), soundIcon='', interrupt=False)
|
||||||
|
|
||||||
def setCallback(self, callback):
|
def setCallback(self, callback):
|
||||||
pass
|
pass
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
|
|
||||||
|
from fenrirscreenreader.core import debug
|
||||||
|
from fenrirscreenreader.utils import char_utils
|
||||||
|
|
||||||
|
class command():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def initialize(self, environment):
|
||||||
|
self.env = environment
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
def getDescription(self):
|
||||||
|
return _('Move Review to the first character on the screen (left top)')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
||||||
|
self.env['runtime']['cursorManager'].setReviewCursorPosition(0 ,0)
|
||||||
|
self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \
|
||||||
|
char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
|
||||||
|
|
||||||
|
self.env['runtime']['outputManager'].presentText(lastChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
|
||||||
|
self.env['runtime']['outputManager'].presentText(_("first character in screen"), interrupt=False)
|
||||||
|
|
||||||
|
def setCallback(self, callback):
|
||||||
|
pass
|
@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Fenrir TTY screen reader
|
||||||
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
|
|
||||||
|
from fenrirscreenreader.core import debug
|
||||||
|
from fenrirscreenreader.utils import char_utils
|
||||||
|
|
||||||
|
class command():
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
def initialize(self, environment):
|
||||||
|
self.env = environment
|
||||||
|
def shutdown(self):
|
||||||
|
pass
|
||||||
|
def getDescription(self):
|
||||||
|
return _('Move Review to the last character on the screen (right bottom)')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
cursorPos = self.env['runtime']['cursorManager'].getReviewOrTextCursor()
|
||||||
|
self.env['runtime']['cursorManager'].setReviewCursorPosition(self.env['screen']['columns']-1 ,self.env['screen']['lines']-1)
|
||||||
|
self.env['screen']['newCursorReview']['x'], self.env['screen']['newCursorReview']['y'], lastChar = \
|
||||||
|
char_utils.getLastCharInLine(self.env['screen']['newCursorReview']['y'], self.env['screen']['newContentText'])
|
||||||
|
|
||||||
|
self.env['runtime']['outputManager'].presentText(lastChar ,interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
|
||||||
|
self.env['runtime']['outputManager'].presentText(_("last character in screen"), interrupt=False)
|
||||||
|
|
||||||
|
def setCallback(self, callback):
|
||||||
|
pass
|
@ -18,8 +18,14 @@ class command():
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# enabled?
|
# enabled?
|
||||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('keyboard', 'charEcho'):
|
active = self.env['runtime']['settingsManager'].getSettingAsInt('keyboard', 'charEchoMode')
|
||||||
|
# 0 = off
|
||||||
|
if active == 0:
|
||||||
return
|
return
|
||||||
|
# 2 = caps only
|
||||||
|
if active == 2:
|
||||||
|
if not self.env['input']['newCapsLock']:
|
||||||
|
return
|
||||||
# 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)
|
# 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)
|
||||||
xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
|
xMove = abs(self.env['screen']['newCursor']['x'] - self.env['screen']['oldCursor']['x'])
|
||||||
if xMove > 3:
|
if xMove > 3:
|
||||||
@ -42,6 +48,7 @@ class command():
|
|||||||
currDelta.strip() != '':
|
currDelta.strip() != '':
|
||||||
currDelta = currDelta.strip()
|
currDelta = currDelta.strip()
|
||||||
self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
|
self.env['runtime']['outputManager'].presentText(currDelta, interrupt=True, ignorePunctuation=True, announceCapital=True, flush=False)
|
||||||
|
print(currDelta)
|
||||||
|
|
||||||
def setCallback(self, callback):
|
def setCallback(self, callback):
|
||||||
pass
|
pass
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#!/bin/python
|
#!/bin/python
|
||||||
import time
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Fenrir TTY screen reader
|
# Fenrir TTY screen reader
|
||||||
@ -12,47 +11,57 @@ import datetime
|
|||||||
class command():
|
class command():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def initialize(self, environment):
|
def initialize(self, environment):
|
||||||
self.env = environment
|
self.env = environment
|
||||||
self.lastTime = datetime.datetime.now()
|
self.lastTime = datetime.datetime.now()
|
||||||
self.lastDateString = ''
|
self.lastDateString = ''
|
||||||
self.lastTimeString = ''
|
self.lastTimeString = ''
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def getDescription(self):
|
def getDescription(self):
|
||||||
return 'No Description found'
|
return 'No Description found'
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'):
|
if not self.env['runtime']['settingsManager'].getSettingAsBool('time', 'enabled'):
|
||||||
return
|
return
|
||||||
|
|
||||||
onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes')
|
onMinutes = self.env['runtime']['settingsManager'].getSetting('time', 'onMinutes')
|
||||||
delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec')
|
delaySec = self.env['runtime']['settingsManager'].getSettingAsInt('time', 'delaySec')
|
||||||
|
|
||||||
# no need
|
# no need
|
||||||
if onMinutes == '' and delaySec <= 0:
|
if onMinutes == '' and delaySec <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
onMinutes = onMinutes.split(',')
|
onMinutes = onMinutes.split(',')
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
|
|
||||||
# ignore onMinutes if there is a delaySec
|
# ignore onMinutes if there is a delaySec
|
||||||
if delaySec > 0:
|
if delaySec > 0:
|
||||||
if int((now-self.lastTime).total_seconds()) < delaySec:
|
if int((now - self.lastTime).total_seconds()) < delaySec:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
# shoul announce?
|
# should announce?
|
||||||
if not str(now.minute).zfill(2) in onMinutes:
|
if not str(now.minute).zfill(2) in onMinutes:
|
||||||
return
|
return
|
||||||
# already announced?
|
# already announced?
|
||||||
if now.hour == self.lastTime.hour:
|
if now.hour == self.lastTime.hour:
|
||||||
if now.minute == self.lastTime.minute:
|
if now.minute == self.lastTime.minute:
|
||||||
return
|
return
|
||||||
|
|
||||||
dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
|
dateFormat = self.env['runtime']['settingsManager'].getSetting('general', 'dateFormat')
|
||||||
dateString = datetime.datetime.strftime(now, dateFormat)
|
dateString = datetime.datetime.strftime(now, dateFormat)
|
||||||
|
|
||||||
presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \
|
presentDate = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentDate') and \
|
||||||
self.lastDateString != dateString
|
self.lastDateString != dateString
|
||||||
presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime')
|
presentTime = self.env['runtime']['settingsManager'].getSettingAsBool('time', 'presentTime')
|
||||||
|
|
||||||
# no changed value to announce
|
# no changed value to announce
|
||||||
if not (presentDate or presentTime):
|
if not (presentDate or presentTime):
|
||||||
return
|
return
|
||||||
|
|
||||||
timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat')
|
timeFormat = self.env['runtime']['settingsManager'].getSetting('general', 'timeFormat')
|
||||||
timeString = datetime.datetime.strftime(now, timeFormat)
|
timeString = datetime.datetime.strftime(now, timeFormat)
|
||||||
|
|
||||||
@ -64,11 +73,13 @@ class command():
|
|||||||
if presentTime:
|
if presentTime:
|
||||||
# present the time
|
# present the time
|
||||||
self.env['runtime']['outputManager'].presentText(_("It's {0}").format(timeString.replace(':00', " O'clock ").lstrip('0')), soundIcon='', interrupt=False)
|
self.env['runtime']['outputManager'].presentText(_("It's {0}").format(timeString.replace(':00', " O'clock ").lstrip('0')), soundIcon='', interrupt=False)
|
||||||
# and date if changes
|
# Check if it's 12:00 AM
|
||||||
if presentDate:
|
if now.hour == 0 and now.minute == 0:
|
||||||
self.env['runtime']['outputManager'].presentText(dateString , soundIcon='', interrupt=False)
|
# present the date
|
||||||
self.lastDateString = dateString
|
self.env['runtime']['outputManager'].presentText(dateString, soundIcon='', interrupt=False)
|
||||||
|
|
||||||
self.lastTime = datetime.datetime.now()
|
self.lastTime = datetime.datetime.now()
|
||||||
self.lastTimeString = timeString
|
self.lastTimeString = timeString
|
||||||
|
|
||||||
def setCallback(self, callback):
|
def setCallback(self, callback):
|
||||||
pass
|
pass
|
||||||
|
@ -85,7 +85,9 @@ class fenrirManager():
|
|||||||
if self.environment['runtime']['inputManager'].noKeyPressed():
|
if self.environment['runtime']['inputManager'].noKeyPressed():
|
||||||
self.modifierInput = False
|
self.modifierInput = False
|
||||||
self.singleKeyCommand = False
|
self.singleKeyCommand = False
|
||||||
|
self.environment['runtime']['inputManager'].writeEventBuffer()
|
||||||
self.environment['runtime']['inputManager'].handleDeviceGrab()
|
self.environment['runtime']['inputManager'].handleDeviceGrab()
|
||||||
|
|
||||||
if self.environment['input']['keyForeward'] > 0:
|
if self.environment['input']['keyForeward'] > 0:
|
||||||
self.environment['input']['keyForeward'] -=1
|
self.environment['input']['keyForeward'] -=1
|
||||||
self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
|
self.environment['runtime']['commandManager'].executeDefaultTrigger('onKeyInput')
|
||||||
|
@ -139,6 +139,8 @@ class inputManager():
|
|||||||
self.env['input']['prevInput'] = []
|
self.env['input']['prevInput'] = []
|
||||||
|
|
||||||
def handleLedStates(self, mEvent):
|
def handleLedStates(self, mEvent):
|
||||||
|
if self.currKeyIsModifier():
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
if mEvent['EventName'] == 'KEY_NUMLOCK':
|
if mEvent['EventName'] == 'KEY_NUMLOCK':
|
||||||
self.env['runtime']['inputDriver'].toggleLedState()
|
self.env['runtime']['inputDriver'].toggleLedState()
|
||||||
|
@ -124,7 +124,7 @@ settingsData = {
|
|||||||
'grabDevices': True,
|
'grabDevices': True,
|
||||||
'ignoreShortcuts': False,
|
'ignoreShortcuts': False,
|
||||||
'keyboardLayout': "desktop",
|
'keyboardLayout': "desktop",
|
||||||
'charEcho': False,
|
'charEchoMode': 2, # while capslock
|
||||||
'charDeleteEcho': True,
|
'charDeleteEcho': True,
|
||||||
'wordEcho': True,
|
'wordEcho': True,
|
||||||
'interruptOnKeyPress': True,
|
'interruptOnKeyPress': True,
|
||||||
|
@ -34,6 +34,11 @@ class driver(screenDriver):
|
|||||||
self.bgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'white'}
|
self.bgColorValues = {0: 'black', 1: 'blue', 2: 'green', 3: 'cyan', 4: 'red', 5: 'magenta', 6: 'brown/yellow', 7: 'white'}
|
||||||
self.fgColorValues = {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'}
|
self.fgColorValues = {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'}
|
||||||
self.hichar = None
|
self.hichar = None
|
||||||
|
try:
|
||||||
|
# set workaround for paste clipboard -> injectTextToScreen
|
||||||
|
os.system('sysctl dev.tty.legacy_tiocsti=1')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
def initialize(self, environment):
|
def initialize(self, environment):
|
||||||
self.env = environment
|
self.env = environment
|
||||||
self.env['runtime']['attributeManager'].appendDefaultAttributes([
|
self.env['runtime']['attributeManager'].appendDefaultAttributes([
|
||||||
@ -95,8 +100,23 @@ class driver(screenDriver):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)
|
self.env['runtime']['debug'].writeDebugOut('getSessionInformation: Maybe no LoginD:' + str(e),debug.debugLevel.ERROR)
|
||||||
#self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO)
|
#self.env['runtime']['debug'].writeDebugOut('getSessionInformation:' + str(self.env['screen']['autoIgnoreScreens']) + ' ' + str(self.env['general']) ,debug.debugLevel.INFO)
|
||||||
|
def readFile(self, file):
|
||||||
def updateWatchdog(self,active , eventQueue):
|
d = b''
|
||||||
|
file.seek(0)
|
||||||
|
try:
|
||||||
|
d = file.read()
|
||||||
|
except:
|
||||||
|
file.seek(0)
|
||||||
|
while True:
|
||||||
|
# Read from file
|
||||||
|
try:
|
||||||
|
d += file.readline(1)
|
||||||
|
if not d:
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
break
|
||||||
|
return d
|
||||||
|
def updateWatchdog(self, active , eventQueue):
|
||||||
try:
|
try:
|
||||||
useVCSU = os.access('/dev/vcsu', os.R_OK)
|
useVCSU = os.access('/dev/vcsu', os.R_OK)
|
||||||
vcsa = {}
|
vcsa = {}
|
||||||
@ -111,7 +131,7 @@ class driver(screenDriver):
|
|||||||
index = str(vcsaDev[9:])
|
index = str(vcsaDev[9:])
|
||||||
vcsa[index] = open(vcsaDev,'rb')
|
vcsa[index] = open(vcsaDev,'rb')
|
||||||
if index == currScreen:
|
if index == currScreen:
|
||||||
lastScreenContent = vcsa[index].read()
|
lastScreenContent = self.readFile(vcsa[index])
|
||||||
if useVCSU:
|
if useVCSU:
|
||||||
vcsuDevices = glob.glob('/dev/vcsu*')
|
vcsuDevices = glob.glob('/dev/vcsu*')
|
||||||
for vcsuDev in vcsuDevices:
|
for vcsuDev in vcsuDevices:
|
||||||
@ -143,13 +163,13 @@ class driver(screenDriver):
|
|||||||
oldScreen = currScreen
|
oldScreen = currScreen
|
||||||
try:
|
try:
|
||||||
vcsa[currScreen].seek(0)
|
vcsa[currScreen].seek(0)
|
||||||
lastScreenContent = vcsa[currScreen].read()
|
lastScreenContent = self.readFile(vcsa[currScreen])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
vcsuContent = None
|
vcsuContent = None
|
||||||
if useVCSU:
|
if useVCSU:
|
||||||
vcsu[currScreen].seek(0)
|
vcsu[currScreen].seek(0)
|
||||||
vcsuContent = vcsu[currScreen].read()
|
vcsuContent = self.readFile(vcsu[currScreen])
|
||||||
eventQueue.put({"Type":fenrirEventType.ScreenChanged,
|
eventQueue.put({"Type":fenrirEventType.ScreenChanged,
|
||||||
"Data":self.createScreenEventData(currScreen, lastScreenContent, vcsuContent)
|
"Data":self.createScreenEventData(currScreen, lastScreenContent, vcsuContent)
|
||||||
})
|
})
|
||||||
@ -157,7 +177,7 @@ class driver(screenDriver):
|
|||||||
self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)
|
self.env['runtime']['debug'].writeDebugOut('ScreenUpdate',debug.debugLevel.INFO)
|
||||||
vcsa[currScreen].seek(0)
|
vcsa[currScreen].seek(0)
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
dirtyContent = vcsa[currScreen].read()
|
dirtyContent = self.readFile(vcsa[currScreen])
|
||||||
screenContent = dirtyContent
|
screenContent = dirtyContent
|
||||||
vcsuContent = None
|
vcsuContent = None
|
||||||
timeout = time.time()
|
timeout = time.time()
|
||||||
@ -183,7 +203,7 @@ class driver(screenDriver):
|
|||||||
#if not vcsa[currScreen] in r:
|
#if not vcsa[currScreen] in r:
|
||||||
# break
|
# break
|
||||||
vcsa[currScreen].seek(0)
|
vcsa[currScreen].seek(0)
|
||||||
dirtyContent = vcsa[currScreen].read()
|
dirtyContent = self.readFile(vcsa[currScreen])
|
||||||
if screenContent == dirtyContent:
|
if screenContent == dirtyContent:
|
||||||
break
|
break
|
||||||
if time.time() - timeout >= 0.1:
|
if time.time() - timeout >= 0.1:
|
||||||
@ -191,7 +211,7 @@ class driver(screenDriver):
|
|||||||
break
|
break
|
||||||
if useVCSU:
|
if useVCSU:
|
||||||
vcsu[currScreen].seek(0)
|
vcsu[currScreen].seek(0)
|
||||||
vcsuContent = vcsu[currScreen].read()
|
vcsuContent = self.readFile(vcsu[currScreen])
|
||||||
lastScreenContent = screenContent
|
lastScreenContent = screenContent
|
||||||
eventQueue.put({"Type":fenrirEventType.ScreenUpdate,
|
eventQueue.put({"Type":fenrirEventType.ScreenUpdate,
|
||||||
"Data":self.createScreenEventData(currScreen, screenContent, vcsuContent)
|
"Data":self.createScreenEventData(currScreen, screenContent, vcsuContent)
|
||||||
|
275
tools/configure_pipewire.sh
Executable file
275
tools/configure_pipewire.sh
Executable file
@ -0,0 +1,275 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script configures pipewire to work both in the graphical environment and in the console with root apps.
|
||||||
|
|
||||||
|
if [[ $(whoami) != "root" ]]; then
|
||||||
|
# Get the current user's XDG_HOME
|
||||||
|
xdgPath="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
|
mkdir -p "$xdgPath/pipewire"
|
||||||
|
mkdir -p "$xdgPath/wireplumber/main.lua.d"
|
||||||
|
mkdir -p "$xdgPath/wireplumber/bluetooth.lua.d"
|
||||||
|
|
||||||
|
#create the file that tells the pipewire-pulse server to use a second socket located at /tmp/pulse.sock
|
||||||
|
# Warn user if we are going to overwrite an existing pipewire-pulse.conf
|
||||||
|
if [ -f "$xdgPath/pipewire/pipewire-pulse.conf" ]; then
|
||||||
|
read -p "This will replace the current file located at $xdgPath/pipewire/pipewire-pulse.conf, press enter to continue or control+c to abort. " continue
|
||||||
|
fi
|
||||||
|
cat << "EOF" > "$xdgPath/pipewire/pipewire-pulse.conf"
|
||||||
|
# PulseAudio config file for PipeWire version "0.3.49" #
|
||||||
|
#
|
||||||
|
# Copy and edit this file in /etc/pipewire for system-wide changes
|
||||||
|
# or in ~/.config/pipewire for local changes.
|
||||||
|
#
|
||||||
|
# It is also possible to place a file with an updated section in
|
||||||
|
# /etc/pipewire/pipewire-pulse.conf.d/ for system-wide changes or in
|
||||||
|
# ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes.
|
||||||
|
#
|
||||||
|
|
||||||
|
context.properties = {
|
||||||
|
## Configure properties in the system.
|
||||||
|
#mem.warn-mlock = false
|
||||||
|
#mem.allow-mlock = true
|
||||||
|
#mem.mlock-all = false
|
||||||
|
#log.level = 2
|
||||||
|
|
||||||
|
#default.clock.quantum-limit = 8192
|
||||||
|
}
|
||||||
|
|
||||||
|
context.spa-libs = {
|
||||||
|
audio.convert.* = audioconvert/libspa-audioconvert
|
||||||
|
support.* = support/libspa-support
|
||||||
|
}
|
||||||
|
|
||||||
|
context.modules = [
|
||||||
|
{ name = libpipewire-module-rt
|
||||||
|
args = {
|
||||||
|
nice.level = -11
|
||||||
|
#rt.prio = 88
|
||||||
|
#rt.time.soft = -1
|
||||||
|
#rt.time.hard = -1
|
||||||
|
}
|
||||||
|
flags = [ ifexists nofail ]
|
||||||
|
}
|
||||||
|
{ name = libpipewire-module-protocol-native }
|
||||||
|
{ name = libpipewire-module-client-node }
|
||||||
|
{ name = libpipewire-module-adapter }
|
||||||
|
{ name = libpipewire-module-metadata }
|
||||||
|
|
||||||
|
{ name = libpipewire-module-protocol-pulse
|
||||||
|
args = {
|
||||||
|
# contents of pulse.properties can also be placed here
|
||||||
|
# to have config per server.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Extra modules can be loaded here. Setup in default.pa can be moved here
|
||||||
|
context.exec = [
|
||||||
|
{ path = "pactl" args = "load-module module-always-sink" }
|
||||||
|
{ path = "pactl" args = "load-module module-switch-on-connect" }
|
||||||
|
#{ path = "/usr/bin/sh" args = "~/.config/pipewire/default.pw" }
|
||||||
|
]
|
||||||
|
|
||||||
|
stream.properties = {
|
||||||
|
#node.latency = 1024/48000
|
||||||
|
#node.autoconnect = true
|
||||||
|
#resample.quality = 4
|
||||||
|
#channelmix.normalize = false
|
||||||
|
#channelmix.mix-lfe = false
|
||||||
|
#channelmix.upmix = true
|
||||||
|
#channelmix.upmix-method = simple # none, psd
|
||||||
|
#channelmix.lfe-cutoff = 120
|
||||||
|
#channelmix.fc-cutoff = 6000
|
||||||
|
#channelmix.rear-delay = 12.0
|
||||||
|
#channelmix.stereo-widen = 0.1
|
||||||
|
#channelmix.hilbert-taps = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pulse.properties = {
|
||||||
|
# the addresses this server listens on
|
||||||
|
server.address = [
|
||||||
|
"unix:native"
|
||||||
|
"unix:/tmp/pulse.sock" # absolute paths may be used
|
||||||
|
#"tcp:4713" # IPv4 and IPv6 on all addresses
|
||||||
|
#"tcp:[::]:9999" # IPv6 on all addresses
|
||||||
|
#"tcp:127.0.0.1:8888" # IPv4 on a single address
|
||||||
|
#
|
||||||
|
#{ address = "tcp:4713" # address
|
||||||
|
# max-clients = 64 # maximum number of clients
|
||||||
|
# listen-backlog = 32 # backlog in the server listen queue
|
||||||
|
# client.access = "restricted" # permissions for clients
|
||||||
|
#}
|
||||||
|
]
|
||||||
|
#pulse.min.req = 256/48000 # 5ms
|
||||||
|
#pulse.default.req = 960/48000 # 20 milliseconds
|
||||||
|
#pulse.min.frag = 256/48000 # 5ms
|
||||||
|
#pulse.default.frag = 96000/48000 # 2 seconds
|
||||||
|
#pulse.default.tlength = 96000/48000 # 2 seconds
|
||||||
|
#pulse.min.quantum = 256/48000 # 5ms
|
||||||
|
#pulse.default.format = F32
|
||||||
|
#pulse.default.position = [ FL FR ]
|
||||||
|
# These overrides are only applied when running in a vm.
|
||||||
|
vm.overrides = {
|
||||||
|
pulse.min.quantum = 1024/48000 # 22ms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# client/stream specific properties
|
||||||
|
pulse.rules = [
|
||||||
|
{
|
||||||
|
matches = [
|
||||||
|
{
|
||||||
|
# all keys must match the value. ~ starts regex.
|
||||||
|
#client.name = "Firefox"
|
||||||
|
#application.process.binary = "teams"
|
||||||
|
#application.name = "~speech-dispatcher.*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
actions = {
|
||||||
|
update-props = {
|
||||||
|
#node.latency = 512/48000
|
||||||
|
}
|
||||||
|
# Possible quirks:"
|
||||||
|
# force-s16-info forces sink and source info as S16 format
|
||||||
|
# remove-capture-dont-move removes the capture DONT_MOVE flag
|
||||||
|
#quirks = [ ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# skype does not want to use devices that don't have an S16 sample format.
|
||||||
|
matches = [
|
||||||
|
{ application.process.binary = "teams" }
|
||||||
|
{ application.process.binary = "skypeforlinux" }
|
||||||
|
]
|
||||||
|
actions = { quirks = [ force-s16-info ] }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# firefox marks the capture streams as don't move and then they
|
||||||
|
# can't be moved with pavucontrol or other tools.
|
||||||
|
matches = [ { application.process.binary = "firefox" } ]
|
||||||
|
actions = { quirks = [ remove-capture-dont-move ] }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
# speech dispatcher asks for too small latency and then underruns.
|
||||||
|
matches = [ { application.name = "~speech-dispatcher*" } ]
|
||||||
|
actions = {
|
||||||
|
update-props = {
|
||||||
|
pulse.min.req = 1024/48000 # 21ms
|
||||||
|
pulse.min.quantum = 1024/48000 # 21ms
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
#Creates the file that tells pipewire not to suspend any sinks for all devices. This makes sure audio doesn't die after switching to the console.
|
||||||
|
# Warn user if we are going to overwrite an existing 50-do-not-suspend.lua
|
||||||
|
if [ -f "$xdgPath/wireplumber/main.lua.d/50-do-not-suspend.lua" ]; then
|
||||||
|
read -p "This will replace the current file located at $xdgPath/wireplumber/main.lua.d/50-do-not-suspend.lua, press enter to continue or control+c to abort. " continue
|
||||||
|
fi
|
||||||
|
echo 'alsa_monitor.rules = {
|
||||||
|
{
|
||||||
|
matches = {
|
||||||
|
{
|
||||||
|
{ "device.name", "matches", "alsa_card.*" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apply_properties = {
|
||||||
|
["api.alsa.use-acp"] = true,
|
||||||
|
["api.acp.auto-profile"] = false,
|
||||||
|
["api.acp.auto-port"] = false,
|
||||||
|
["session.suspend-timeout-seconds"] = 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
matches = {
|
||||||
|
{
|
||||||
|
{ "node.name", "matches", "alsa_input.*" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ "node.name", "matches", "alsa_output.*" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apply_properties = {
|
||||||
|
["session.suspend-timeout-seconds"] = 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}' > $xdgPath/wireplumber/main.lua.d/50-do-not-suspend.lua
|
||||||
|
|
||||||
|
#Creates the file that disables the logind module for wireplumber which causes bluetooth to disconnect when switching tty
|
||||||
|
# Warn user if we are going to overwrite an existing 30-bluez-monitor.lua
|
||||||
|
if [ -f "$xdgPath/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua" ]; then
|
||||||
|
read -p "This will replace the current file located at $xdgPath/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua, press enter to continue or control+c to abort. " continue
|
||||||
|
fi
|
||||||
|
echo 'bluez_monitor = {}
|
||||||
|
bluez_monitor.properties = {}
|
||||||
|
bluez_monitor.rules = {}
|
||||||
|
|
||||||
|
function bluez_monitor.enable()
|
||||||
|
load_monitor("bluez", {
|
||||||
|
properties = bluez_monitor.properties,
|
||||||
|
rules = bluez_monitor.rules,
|
||||||
|
})
|
||||||
|
|
||||||
|
end' > $xdgPath/wireplumber/bluetooth.lua.d/30-bluez-monitor.lua
|
||||||
|
|
||||||
|
echo "Please ensure that your user is added to the audio group."
|
||||||
|
echo "If you have not yet done so, please run this script as root to write the client.conf file."
|
||||||
|
else
|
||||||
|
# This section does the root part:
|
||||||
|
xdgPath="/root/.config"
|
||||||
|
mkdir -p "$xdgPath/pulse"
|
||||||
|
|
||||||
|
# Warn user if we are going to overwrite an existing default.pa
|
||||||
|
if [ -f "$xdgPath/pulse/default.pa" ]; then
|
||||||
|
read -p "This will replace the current file located at $xdgPath/pulse/default.pa, press enter to continue or control+c to abort. " continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat << EOF > "$xdgPath/pulse/client.conf"
|
||||||
|
# This file is part of PulseAudio.
|
||||||
|
#
|
||||||
|
# PulseAudio is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# PulseAudio is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
## Configuration file for PulseAudio clients. See pulse-client.conf(5) for
|
||||||
|
## more information. Default values are commented out. Use either ; or # for
|
||||||
|
## commenting.
|
||||||
|
|
||||||
|
; default-sink =
|
||||||
|
; default-source =
|
||||||
|
default-server = unix:/tmp/pulse.sock
|
||||||
|
; default-dbus-server =
|
||||||
|
|
||||||
|
autospawn = no
|
||||||
|
; autospawn = yes
|
||||||
|
; daemon-binary = /usr/bin/pulseaudio
|
||||||
|
; extra-arguments = --log-target=syslog
|
||||||
|
|
||||||
|
; cookie-file =
|
||||||
|
|
||||||
|
; enable-shm = yes
|
||||||
|
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
|
||||||
|
|
||||||
|
; auto-connect-localhost = no
|
||||||
|
; auto-connect-display = no
|
||||||
|
EOF
|
||||||
|
echo "If you have not yet done so, run this script as your normal user to write the user configs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If there were no errors tell user to restart, else warn them errors happened.
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "Configuration created successfully, please restart both Pipewire-pulseaudio and Wireplumber or your system, for changes to take affect."
|
||||||
|
else
|
||||||
|
echo "Errors were encountered whilst writing the configuration, please correct them manually."
|
||||||
|
fi
|
||||||
|
exit 0
|
@ -5,6 +5,7 @@
|
|||||||
if [[ $(whoami) != "root" ]]; then
|
if [[ $(whoami) != "root" ]]; then
|
||||||
# Get the current user's XDG_HOME
|
# Get the current user's XDG_HOME
|
||||||
xdgPath="${XDG_CONFIG_HOME:-$HOME/.config}"
|
xdgPath="${XDG_CONFIG_HOME:-$HOME/.config}"
|
||||||
|
mkdir -p "$xdgPath/pulse"
|
||||||
|
|
||||||
# Warn user if we are going to overwrite an existing default.pa
|
# Warn user if we are going to overwrite an existing default.pa
|
||||||
if [ -f "$xdgPath/pulse/default.pa" ]; then
|
if [ -f "$xdgPath/pulse/default.pa" ]; then
|
||||||
|
250
tools/fenrir-conf
Normal file → Executable file
250
tools/fenrir-conf
Normal file → Executable file
@ -1,216 +1,66 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# Get user input args are return variable, question, options
|
# Fenrir TTY screen reader
|
||||||
get_input()
|
# By Chrys, Storm Dragon, and contributers.
|
||||||
{
|
|
||||||
# Variable names are long, because we want absolutely no name conflicts.
|
|
||||||
local __get_input_input=$1
|
|
||||||
shift
|
|
||||||
local __get_input_question="$1"
|
|
||||||
shift
|
|
||||||
local __get_input_answer=""
|
|
||||||
local __get_input_i=""
|
|
||||||
local __get_input_continue=false
|
|
||||||
for __get_input_i in $@; do
|
|
||||||
if [ "${__get_input_i:0:1}" = "-" ]; then
|
|
||||||
local __get_input_default="${__get_input_i:1}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
while [ $__get_input_continue = false ]; do
|
|
||||||
echo -n "$__get_input_question (${@/#-/}) "
|
|
||||||
if [ -n "$__get_input_default" ]; then
|
|
||||||
read -e -i "$__get_input_default" __get_input_answer
|
|
||||||
else
|
|
||||||
read -e __get_input_answer
|
|
||||||
fi
|
|
||||||
for __get_input_i in $@; do
|
|
||||||
if [ "$__get_input_answer" = "${__get_input_i/#-/}" ]; then
|
|
||||||
__get_input_continue=true
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
__get_input_answer="${__get_input_answer//no/False}"
|
|
||||||
__get_input_answer="${__get_input_answer//yes/True}"
|
|
||||||
eval $__get_input_input="'$__get_input_answer'"
|
|
||||||
}
|
|
||||||
configFile="/etc/fenrirscreenreader/settings/settings.conf"
|
|
||||||
|
|
||||||
if [ "$(whoami)" != "root" ]; then
|
import os
|
||||||
echo "Please run $0 as root."
|
import configparser
|
||||||
exit 1
|
import dialog
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$configFile" ]; then
|
# Make sure dialog is accessible
|
||||||
read -p "This will replace your current settings, press enter to continue or control+C to abort." continue
|
os.environ['DIALOGOPTS'] = '--no-lines --visit-items'
|
||||||
fi
|
# Initialize the dialog
|
||||||
|
tui = dialog.Dialog(dialog="dialog")
|
||||||
|
|
||||||
get_input sound "Enable sound?" -yes no
|
# Define the path to the settings file
|
||||||
if [ "$sound" = "true" ]; then
|
settings_file = '/etc/fenrirscreenreader/settings/settings.conf'
|
||||||
get_input soundDriver "Select sound driver:" -generic gstreamer
|
|
||||||
else
|
|
||||||
soundDriver="generic"
|
|
||||||
fi
|
|
||||||
get_input speech "Enable speech?" -yes no
|
|
||||||
if [ "$speech" = "true" ]; then
|
|
||||||
get_input speechDriver "Select speech driver:" espeak -speechd
|
|
||||||
else
|
|
||||||
speechDriver="speechd"
|
|
||||||
fi
|
|
||||||
get_input charEcho "enable character echo?" -yes no
|
|
||||||
get_input wordEcho "enable word echo?" yes -no
|
|
||||||
|
|
||||||
cat << EOF > "$configFile"
|
# Check write permissions for the settings file
|
||||||
[sound]
|
if not os.access(settings_file, os.W_OK):
|
||||||
# Turn sound on or off:
|
tui.msgbox("Error: Insufficient permissions to modify the settings file. Please run as root or with sudo.")
|
||||||
enabled=$sound
|
exit()
|
||||||
|
|
||||||
# Select the driver used to play sounds, choices are generic and gstreamer.
|
while True:
|
||||||
# Sox is the default.
|
# Load the settings file
|
||||||
driver=$soundDriver
|
config = configparser.ConfigParser()
|
||||||
|
config.read(settings_file)
|
||||||
|
|
||||||
# Sound themes. These are the pack of sounds used for sound alerts.
|
# Get a list of sections in the settings file
|
||||||
# Sound packs may be located at /usr/share/sounds
|
sections = config.sections()
|
||||||
# For system wide availability, or ~/.local/share/fenrir/sounds
|
|
||||||
# For the current user.
|
|
||||||
theme=default
|
|
||||||
|
|
||||||
# Sound volume controls how loud the sounds for your chosen soundpack are.
|
# Select a section.
|
||||||
# 0 is quietest, 1.0 is loudest.
|
code, section = tui.menu("Select a section:", choices=[(s, "") for s in sections] + [("Exit", " ")])
|
||||||
volume=1.0
|
|
||||||
|
|
||||||
# shell commands for generic sound driver
|
# Exit if the "Exit" option is chosen
|
||||||
# the folowing variables are substituted
|
if section == "Exit":
|
||||||
# fenrirVolume = the current volume setting
|
break
|
||||||
# fenrirSoundFile = the soundfile for an soundicon
|
|
||||||
# fenrirFrequence = the frequence to play
|
|
||||||
# fenrirDuration = the duration of the frequency
|
|
||||||
# the following command is used for play a soundfile
|
|
||||||
genericPlayFileCommand=play -q -v fenrirVolume fenrirSoundFile
|
|
||||||
#the following command is used for generating a frequency beep
|
|
||||||
genericFrequencyCommand=play -q -v fenrirVolume -n -c1 synth fenrirDuration sine fenrirFrequence
|
|
||||||
|
|
||||||
[speech]
|
while True:
|
||||||
# Turn speech on or off:
|
# Get the options in the selected section
|
||||||
enabled=$speech
|
options = config.options(section)
|
||||||
|
|
||||||
# Select speech driver, options are speechd (default) or espeak:
|
# Select a value to edit using dialog
|
||||||
driver=$speechDriver
|
code, option = tui.menu(f"Select a value to edit in '{section}':", choices=[(o, "") for o in options] + [("Go Back", " ")])
|
||||||
|
|
||||||
|
# Go back to the section menu if the "Go Back" option is chosen
|
||||||
|
if option == "Go Back":
|
||||||
|
break
|
||||||
|
|
||||||
# The rate selects how fast Fenrir will speak. Options range from 0, slowest, to 1.0, fastest.
|
# If something is selected, prompt for a new value.
|
||||||
rate=0.45
|
if code == tui.OK:
|
||||||
|
value = config.get(section, option)
|
||||||
|
code, new_value = tui.inputbox(f"Enter a new value for '{option}':", init=value)
|
||||||
|
|
||||||
# Pitch controls the pitch of the voice, select from 0, lowest, to 1.0, highest.
|
# If a new setting is provided, update the configuration
|
||||||
pitch=0.5
|
if code == tui.OK:
|
||||||
# Pitch for capital letters
|
config.set(section, option, new_value)
|
||||||
capitalPitch=0.9
|
|
||||||
|
|
||||||
# Volume controls the loudness of the voice, select from 0, quietest, to 1.0, loudest.
|
# Save changes.
|
||||||
volume=1.0
|
with open(settings_file, 'w') as configfile:
|
||||||
|
config.write(configfile)
|
||||||
|
|
||||||
# Module is used for Speech-dispatcher, to select the speech module you want to use.
|
tui.msgbox("Fenrir settings saved.")
|
||||||
# Consult Speech-dispatcher's configuration and help to find out which modules are available.
|
else:
|
||||||
# The default is Espeak.
|
tui.msgbox("Changes discarded. Your Fenrir configuration has not been modified.")
|
||||||
module=espeak
|
else:
|
||||||
|
tui.msgbox("Canceled.")
|
||||||
# Voice selects the varient you want to use, for example, f5 will use the female voice #5 in espeak,
|
|
||||||
# or if using the espeak module in Speech-dispatcher. To find out which voices are available, consult the documentation provided with your selected synthesizer.
|
|
||||||
voice=
|
|
||||||
|
|
||||||
# Select the language you want Fenrir to use.
|
|
||||||
language=english-us
|
|
||||||
|
|
||||||
# Read new text as it happens?
|
|
||||||
autoReadIncoming=True
|
|
||||||
|
|
||||||
[braille]
|
|
||||||
#Braille is not implemented yet
|
|
||||||
enabled=False
|
|
||||||
driver=brlapi
|
|
||||||
layout=en
|
|
||||||
|
|
||||||
[screen]
|
|
||||||
driver=vcsa
|
|
||||||
encoding=auto
|
|
||||||
autodetectSuspendingScreen=True
|
|
||||||
|
|
||||||
[keyboard]
|
|
||||||
driver=evdev
|
|
||||||
# filter input devices NOMICE, ALL or a DEVICE NAME
|
|
||||||
device=ALL
|
|
||||||
# gives Fenrir exclusive access to the keyboard and lets it absorb keystrokes.
|
|
||||||
grabDevices=True
|
|
||||||
ignoreShortcuts=False
|
|
||||||
# the current shortcut layout located in /etc/fenrir/keyboard
|
|
||||||
keyboardLayout=$keyboard
|
|
||||||
# echo chars while typing.
|
|
||||||
charEcho=$charEcho
|
|
||||||
# echo deleted chars
|
|
||||||
charDeleteEcho=True
|
|
||||||
# echo word after pressing space
|
|
||||||
wordEcho=$wordEcho
|
|
||||||
# interrupt speech on any keypress
|
|
||||||
interruptOnKeyPress=$enterupt
|
|
||||||
# you can filter the keys that the speech should interrupt (empty = all keys, otherwise the given keys)
|
|
||||||
interruptOnKeyPressFilter=
|
|
||||||
# timeout for double tap in sec
|
|
||||||
doubleTapTimeout=0.2
|
|
||||||
|
|
||||||
[general]
|
|
||||||
debugLevel=0
|
|
||||||
# debugMode sets where the debug output should send to:
|
|
||||||
# debugMode=File writes to /var/log/fenrir.log
|
|
||||||
# debugMode=Print just prints on the screen
|
|
||||||
debugMode=File
|
|
||||||
punctuationProfile=default
|
|
||||||
punctuationLevel=some
|
|
||||||
respectPunctuationPause=True
|
|
||||||
newLinePause=True
|
|
||||||
numberOfClipboards=10
|
|
||||||
emoticons=True
|
|
||||||
# define the current Fenrir key
|
|
||||||
fenrirKeys=KEY_KP0,KEY_META,KEY_INSERT
|
|
||||||
scriptKey=KEY_COMPOSE
|
|
||||||
timeFormat=%H:%M:%P
|
|
||||||
dateFormat=%A, %B %d, %Y
|
|
||||||
autoSpellCheck=True
|
|
||||||
spellCheckLanguage=en_US
|
|
||||||
scriptPath=/usr/share/fenrirscreenreader/scripts
|
|
||||||
|
|
||||||
[focus]
|
|
||||||
#follow the text cursor
|
|
||||||
cursor=True
|
|
||||||
#follow highlighted text changes
|
|
||||||
highlight=False
|
|
||||||
|
|
||||||
[review]
|
|
||||||
lineBreak=True
|
|
||||||
endOfScreen=True
|
|
||||||
|
|
||||||
[promote]
|
|
||||||
enabled=True
|
|
||||||
inactiveTimeoutSec=120
|
|
||||||
list=
|
|
||||||
|
|
||||||
[time]
|
|
||||||
# automatic time anouncement
|
|
||||||
enabled=False
|
|
||||||
# present time
|
|
||||||
presentTime=True
|
|
||||||
# present date (on change)
|
|
||||||
presentDate=True
|
|
||||||
# present time after a given period of seconds
|
|
||||||
delaySec=0
|
|
||||||
# present time after to given minutes example every 15 minutes: 00,15,30,45
|
|
||||||
# if delaySec is >0 onMinutes is ignored
|
|
||||||
onMinutes=00,30
|
|
||||||
# announce via soundicon (not interrupting)
|
|
||||||
announce=True
|
|
||||||
# interrupt current speech for time announcement
|
|
||||||
interrupt=False
|
|
||||||
EOF
|
|
||||||
|
|
||||||
echo "Settings saved to $configFile."
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
@ -6,8 +6,54 @@ if [[ "$(whoami)" != "root" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
write_pulse() {
|
# This script checks for, and creates if needed, the fenrirscreenreader user.
|
||||||
sudo -u fenrirscreenreader cat << EOF > "/var/fenrirscreenreader/.config/pulse/client.conf"
|
|
||||||
|
# Find out which group to use for uinput
|
||||||
|
uinput="$(stat -c '%G' /dev/uinput | grep -v root)"
|
||||||
|
if ! [[ "$uinput" =~ ^[a-zA-Z]+$ ]]; then
|
||||||
|
groupadd -r uinput
|
||||||
|
chown root:uinput /dev/uinput
|
||||||
|
fi
|
||||||
|
|
||||||
|
# find out which group to use for /dev/input.
|
||||||
|
input="$(stat -c '%G' /dev/input/* | grep -v root | head -1)"
|
||||||
|
if ! [[ "$input" =~ ^[a-zA-Z]+$ ]]; then
|
||||||
|
# Create the input group
|
||||||
|
groupadd --system input
|
||||||
|
echo 'KERNEL=="event*", NAME="input/%k", MODE="660", GROUP="input"' >> /etc/udev/rules.d/99-input.rules
|
||||||
|
input="input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# find out which group to use for /dev/tty.
|
||||||
|
tty="$(stat -c '%G' /dev/tty | grep -v root)"
|
||||||
|
if ! [[ "$tty" =~ ^[a-zA-Z]+$ ]]; then
|
||||||
|
# Create the tty group
|
||||||
|
groupadd --system tty
|
||||||
|
echo 'KERNEL=="event*", NAME="tty/%k", MODE="660", GROUP="tty"' >> /etc/udev/rules.d/99-tty.rules
|
||||||
|
tty="tty"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add fenrirscreenreader
|
||||||
|
id fenrirscreenreader &> /dev/null ||
|
||||||
|
useradd -m -d /var/fenrirscreenreader -r -G $input,$tty,$uinput -s /bin/nologin -U fenrirscreenreader
|
||||||
|
|
||||||
|
#configure directory structure.
|
||||||
|
mkdir -p /var/log/fenrirscreenreader /etc/fenrirscreenreader
|
||||||
|
|
||||||
|
# Set directory ownership
|
||||||
|
chown -R fenrirscreenreader:fenrirscreenreader /var/log/fenrirscreenreader
|
||||||
|
chmod -R 755 /var/log/fenrirscreenreader
|
||||||
|
chown -R root:fenrirscreenreader /etc/fenrirscreenreader
|
||||||
|
|
||||||
|
# Fix permissions on tty#s
|
||||||
|
for i in /dev/tty[0-9]* ; do
|
||||||
|
chmod 660 "$i"
|
||||||
|
done
|
||||||
|
|
||||||
|
sudo -Hu fenrirscreenreader mkdir /var/fenrirscreenreader/.config/pulse
|
||||||
|
|
||||||
|
# Set up sound
|
||||||
|
cat << EOF > /var/fenrirscreenreader/.config/pulse/client.conf
|
||||||
# This file is part of PulseAudio.
|
# This file is part of PulseAudio.
|
||||||
#
|
#
|
||||||
# PulseAudio is free software; you can redistribute it and/or modify
|
# PulseAudio is free software; you can redistribute it and/or modify
|
||||||
@ -45,54 +91,6 @@ autospawn = no
|
|||||||
; auto-connect-localhost = no
|
; auto-connect-localhost = no
|
||||||
; auto-connect-display = no
|
; auto-connect-display = no
|
||||||
EOF
|
EOF
|
||||||
}
|
|
||||||
|
|
||||||
# This script checks for, and creates if needed, the fenrirscreenreader user.
|
|
||||||
|
|
||||||
# Find out which group to use for uinput
|
|
||||||
uinput="$(stat -c '%G' /dev/uinput | grep -v root)"
|
|
||||||
if ! [[ "$uinput" =~ ^[a-zA-Z]+$ ]]; then
|
|
||||||
groupadd -r uinput
|
|
||||||
chown root:uinput /dev/uinput
|
|
||||||
fi
|
|
||||||
|
|
||||||
# find out which group to use for /dev/input.
|
|
||||||
input="$(stat -c '%G' /dev/input/* | grep -v root | head -1)"
|
|
||||||
if ! [[ "$input" =~ ^[a-zA-Z]+$ ]]; then
|
|
||||||
# Create the input group
|
|
||||||
groupadd --system input
|
|
||||||
echo 'KERNEL=="event*", NAME="input/%k", MODE="660", GROUP="input"' >> /etc/udev/rules.d/99-input.rules
|
|
||||||
input="input"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# find out which group to use for /dev/tty.
|
|
||||||
tty="$(stat -c '%G' /dev/tty | grep -v root)"
|
|
||||||
if ! [[ "$tty" =~ ^[a-zA-Z]+$ ]]; then
|
|
||||||
# Create the tty group
|
|
||||||
groupadd --system tty
|
|
||||||
echo 'KERNEL=="event*", NAME="tty/%k", MODE="660", GROUP="tty"' >> /etc/udev/rules.d/99-tty.rules
|
|
||||||
tty="tty"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add fenrirscreenreader
|
|
||||||
id fenrirscreenreader &> /dev/null || {
|
|
||||||
useradd -m -d /var/fenrirscreenreader -r -G $input,$tty,$uinput -s /bin/nologin -U fenrirscreenreader;
|
|
||||||
sleep 1;
|
|
||||||
sudo -u fenrirscreenreader mkdir -p /var/fenrirscreenreader/.config/pulse;
|
|
||||||
write_pulse;
|
|
||||||
}
|
|
||||||
|
|
||||||
#configure directory structure.
|
|
||||||
mkdir -p /var/log/fenrirscreenreader /etc/fenrirscreenreader
|
|
||||||
|
|
||||||
# Set directory ownership
|
|
||||||
chown -R fenrirscreenreader:fenrirscreenreader /var/log/fenrirscreenreader
|
|
||||||
chmod -R 755 /var/log/fenrirscreenreader
|
|
||||||
chown -R root:fenrirscreenreader /etc/fenrirscreenreader
|
|
||||||
|
|
||||||
# Fix permissions on tty#s
|
|
||||||
for i in /dev/tty[0-9]* ; do
|
|
||||||
chmod 660 "$i"
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
Loading…
Reference in New Issue
Block a user