Updated documentation. Attempted to track down a bug that causes disable speech sound to play with no interaction.?

This commit is contained in:
Storm Dragon
2025-06-06 17:56:02 -04:00
parent bd151c7cec
commit 8d50003730
11 changed files with 1897 additions and 4394 deletions

View File

@ -1,4 +1,389 @@
1. Basic
2. Commands
3. Useful API
# Fenrir Development Guide
This document provides information for developers who want to contribute to Fenrir or understand its architecture.
## Project Structure
Fenrir follows a modular, driver-based architecture:
```
src/fenrirscreenreader/
├── core/ # Core system modules
│ ├── fenrirManager.py # Main application manager
│ ├── screenManager.py # Screen handling
│ ├── inputManager.py # Input handling
│ ├── outputManager.py # Speech/sound output
│ ├── commandManager.py # Command system
│ └── settingsManager.py # Configuration management
├── commands/ # Command implementations
│ ├── commands/ # User-invoked commands
│ ├── onCursorChange/ # Cursor movement hooks
│ ├── onScreenUpdate/ # Screen update hooks
│ ├── onKeyInput/ # Key input hooks
│ └── help/ # Tutorial system
├── drivers/ # Driver implementations
│ ├── inputDriver/ # Input drivers (evdev, pty, atspi)
│ ├── screenDriver/ # Screen drivers (vcsa, pty)
│ ├── speechDriver/ # Speech drivers (speechd, generic)
│ └── soundDriver/ # Sound drivers (generic, gstreamer)
└── utils/ # Utility modules
```
## Core Architecture
### Driver System
Fenrir uses a pluggable driver architecture:
1. **Input Drivers**: Capture keyboard input
- evdevDriver: Linux evdev (recommended)
- ptyDriver: Terminal emulation
- atspiDriver: AT-SPI for desktop
2. **Screen Drivers**: Read screen content
- vcsaDriver: Linux VCSA devices
- ptyDriver: Terminal emulation
3. **Speech Drivers**: Text-to-speech output
- speechdDriver: Speech-dispatcher
- genericDriver: Command-line TTS
4. **Sound Drivers**: Audio output
- genericDriver: Sox-based
- gstreamerDriver: GStreamer
5. **Remote Drivers**: Remote control interfaces
- unixDriver: Unix socket control
- tcpDriver: TCP socket control
### Command System
Commands are Python modules that implement specific functionality:
```python
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return _('Command description')
def run(self):
# Command implementation
pass
```
### Event Hooks
Fenrir supports various event hooks:
- **onCursorChange**: Triggered when cursor moves
- **onScreenUpdate**: Triggered on screen content changes
- **onKeyInput**: Triggered on key presses
- **onByteInput**: Triggered on byte-level input
- **onScreenChanged**: Triggered when switching screens
## Development Setup
### Requirements
- Python 3.6+
- python3-evdev
- python3-pyudev
- speech-dispatcher
- sox
### Getting Started
```bash
# Clone repository
git clone https://git.stormux.org/storm/fenrir.git
cd fenrir
# Install dependencies
sudo pip3 install -r requirements.txt
# Run from source
cd src/
sudo ./fenrir -f -d
```
### Testing
```bash
# Run in debug mode
sudo ./fenrir -f -d -p
# Debug output goes to:
# - Console (with -p flag)
# - /var/log/fenrir.log
```
## Creating Commands
### Basic Command
Create a file in `src/fenrirscreenreader/commands/commands/`:
```python
from fenrirscreenreader.core import debug
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return _('My custom command')
def run(self):
# Get current text
text = self.env['screen']['newContentText']
# Speak something
self.env['runtime']['outputManager'].presentText('Hello World')
# Play sound
self.env['runtime']['outputManager'].playSoundIcon('Accept')
```
### Key Bindings
Add key bindings in keyboard layout files:
`config/keyboard/desktop.conf` or `config/keyboard/laptop.conf`
```ini
[KEY_CTRL]#[KEY_ALT]#[KEY_H]=my_command
```
### Event Hooks
Create event handlers in appropriate directories:
```python
# onCursorChange/my_hook.py
class command():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
def getDescription(self):
return _('My cursor change handler')
def run(self):
if self.env['runtime']['cursorManager'].isCursorHorizontalMove():
# Handle horizontal cursor movement
pass
```
## Creating Drivers
### Driver Template
```python
class driver():
def __init__(self):
pass
def initialize(self, environment):
self.env = environment
def shutdown(self):
pass
# Driver-specific methods...
```
### Input Driver
Implement these methods:
- `getInputEvent()`: Return input events
- `writeEventBuffer()`: Handle output events
- `grabDevices()`: Take exclusive control
- `releaseDevices()`: Release control
### Screen Driver
Implement these methods:
- `getCurrScreen()`: Get current screen content
- `getSessionInformation()`: Get session info
### Speech Driver
Implement these methods:
- `speak()`: Speak text
- `cancel()`: Stop speech
- `setCallback()`: Set callback functions
### Remote Driver
Implement these methods:
- `initialize()`: Setup socket/connection
- `watchDog()`: Listen for incoming commands
- `shutdown()`: Clean up connections
#### Remote Driver Example
```python
class driver(remoteDriver):
def initialize(self, environment):
self.env = environment
# Start watchdog thread
self.env['runtime']['processManager'].addCustomEventThread(
self.watchDog, multiprocess=True
)
def watchDog(self, active, eventQueue):
# Listen for connections and process commands
while active.value:
# Accept connections
# Parse incoming data
# Send to event queue
eventQueue.put({
"Type": fenrirEventType.RemoteIncomming,
"Data": command_text
})
```
## Configuration
### Settings System
Settings are hierarchical:
1. Command-line options (`-o`)
2. Configuration file
3. Hard-coded defaults
### Adding Settings
1. Add default value to `core/settingsData.py`
2. Access via `self.env['runtime']['settingsManager'].getSetting(section, key)`
## Debugging
### Debug Levels
- 0: DEACTIVE
- 1: ERROR
- 2: WARNING
- 3: INFO
### Debug Output
```python
self.env['runtime']['debug'].writeDebugOut(
'Debug message',
debug.debugLevel.INFO
)
```
### Testing Commands
```bash
# Test specific functionality
sudo fenrir -f -d -o "general#debugLevel=3"
# Test with custom config
sudo fenrir -f -s /path/to/test.conf
```
## Contributing
### Code Style
- Follow PEP 8
- Use descriptive variable names
- Add docstrings for complex functions
- Handle exceptions gracefully
### Testing
- Test with different drivers
- Test keyboard layouts
- Test on different terminals
- Verify accessibility features
### Submitting Changes
1. Fork the repository
2. Create feature branch
3. Make changes with clear commit messages
4. Test thoroughly
5. Submit pull request
## API Reference
### Environment Structure
The `environment` dict contains all runtime data:
```python
environment = {
'runtime': {
'settingsManager': settingsManager,
'commandManager': commandManager,
'screenManager': screenManager,
'inputManager': inputManager,
'outputManager': outputManager,
'debug': debugManager,
# ... other managers
},
'screen': {
'newContentText': '',
'oldContentText': '',
'newCursor': {'x': 0, 'y': 0},
'oldCursor': {'x': 0, 'y': 0},
# ... screen data
},
'general': {
'prevCommand': '',
'currCommand': '',
# ... general data
}
}
```
### Common Operations
#### Speaking Text
```python
self.env['runtime']['outputManager'].presentText('Hello')
```
#### Playing Sounds
```python
self.env['runtime']['outputManager'].playSoundIcon('Accept')
```
#### Getting Settings
```python
rate = self.env['runtime']['settingsManager'].getSetting('speech', 'rate')
```
#### Cursor Information
```python
x = self.env['screen']['newCursor']['x']
y = self.env['screen']['newCursor']['y']
```
#### Screen Content
```python
text = self.env['screen']['newContentText']
lines = text.split('\n')
current_line = lines[self.env['screen']['newCursor']['y']]
```
## Maintenance
### Release Process
1. Update version in `fenrirVersion.py`
2. Update changelog
3. Test on multiple systems
4. Tag release
5. Update documentation
### Compatibility
- Maintain Python 3.6+ compatibility
- Test on multiple Linux distributions
- Ensure driver compatibility
- Check dependencies
## Resources
- **Repository**: https://git.stormux.org/storm/fenrir
- **Wiki**: https://git.stormux.org/storm/fenrir/wiki
- **Issues**: Use repository issue tracker
- **Community**: IRC irc.stormux.org #stormux
- **Email**: stormux+subscribe@groups.io

File diff suppressed because it is too large Load Diff

View File

@ -1202,6 +1202,44 @@ link:#Settings[Settings]
=== Commandline Arguments
Fenrir supports several command-line options:
....
fenrir [OPTIONS]
....
==== Available Options
`+-h, --help+`::
Show help message and exit.
`+-v, --version+`::
Show version information and exit.
`+-f, --foreground+`::
Run Fenrir in the foreground instead of as a daemon.
`+-s, --setting SETTING-FILE+`::
Path to a custom settings file.
`+-o, --options SECTION#SETTING=VALUE;..+`::
Override settings file options (see below for details).
`+-d, --debug+`::
Enable debug mode. Debug information will be logged.
`+-p, --print+`::
Print debug messages to screen in addition to logging them.
`+-e, --emulated-pty+`::
Use PTY emulation with escape sequences for input. This enables usage in desktop/X11/Wayland environments and terminal emulators.
`+-E, --emulated-evdev+`::
Use PTY emulation with evdev for input (single instance mode).
`+-F, --force-all-screens+`::
Force Fenrir to respond on all screens, ignoring the ignoreScreen setting. This temporarily overrides screen filtering for the current session.
==== Set settings options
You can specify options that overwrite the setting.conf. This is done
@ -1224,9 +1262,154 @@ or change the debug level to verbose
fenrir -o "general#debugLevel=3"
....
Example using force all screens option:
....
fenrir -F
....
You can find the available sections and variables here #Settings See
Syntax link:#settings.conf syntax[#settings.conf syntax]
=== Remote Control
Fenrir includes a powerful remote control system that allows external applications and scripts to control Fenrir through Unix sockets or TCP connections.
==== Configuration
Enable remote control in settings.conf:
....
[remote]
enable=True
driver=unixDriver
enableSettingsRemote=True
enableCommandRemote=True
....
==== Using socat with Unix Sockets
The `+socat+` command provides the easiest way to send commands to Fenrir:
===== Basic Speech Control
....
# Interrupt current speech
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Speak custom text
echo "command say Hello, this is a test message" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Temporarily disable speech (until next keystroke)
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
....
===== Settings Control
....
# Enable highlight tracking mode
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Change speech rate
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Change punctuation level (none/some/most/all)
echo "setting set general#punctuationLevel=all" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Voice and TTS control
echo "setting set speech#voice=en-us+f3" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Multiple settings at once
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuationLevel=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Reset all settings to defaults
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
....
===== Clipboard Operations
....
# Place text into clipboard
echo "command clipboard This text will be copied to clipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
# Export clipboard to file
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
....
===== Application Control
....
# Quit Fenrir
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
....
==== Command Reference
===== Available Commands
*Speech Commands:*
* `+command say <text>+` - Speak the specified text
* `+command interrupt+` - Stop current speech
* `+command tempdisablespeech+` - Disable speech until next key press
*Clipboard Commands:*
* `+command clipboard <text>+` - Add text to clipboard
* `+command exportclipboard+` - Export clipboard to file
*Window Commands:*
* `+command window <x1> <y1> <x2> <y2>+` - Define window area
* `+command resetwindow+` - Reset to full screen
*VMenu Commands:*
* `+command vmenu <menu_path>+` - Set virtual menu context
* `+command resetvmenu+` - Reset virtual menu
*Application Commands:*
* `+command quitapplication+` - Quit Fenrir
===== Available Settings
*Settings Commands:*
* `+setting set <section>#<key>=<value>+` - Set configuration value
* `+setting reset+` - Reset all settings to defaults
* `+setting save [path]+` - Save current settings
*Key Settings You Can Control:*
*Speech Settings:*
* `+speech#enabled=True/False+` - Enable/disable speech
* `+speech#rate=0.1-1.0+` - Speech rate (speed)
* `+speech#pitch=0.1-1.0+` - Speech pitch (tone)
* `+speech#volume=0.1-1.0+` - Speech volume
* `+speech#voice=voice_name+` - Voice selection (e.g., "en-us+f3")
* `+speech#module=module_name+` - TTS module (e.g., "espeak-ng")
*General Settings:*
* `+general#punctuationLevel=none/some/most/all+` - Punctuation verbosity
* `+general#autoSpellCheck=True/False+` - Automatic spell checking
* `+general#emoticons=True/False+` - Enable emoticon replacement
*Sound Settings:*
* `+sound#enabled=True/False+` - Enable/disable sound
* `+sound#volume=0.1-1.0+` - Sound volume
*Focus Settings:*
* `+focus#cursor=True/False+` - Follow text cursor
* `+focus#highlight=True/False+` - Follow text highlighting
*Keyboard Settings:*
* `+keyboard#charEchoMode=0-2+` - Character echo (0=none, 1=always, 2=capslock only)
* `+keyboard#wordEcho=True/False+` - Echo complete words
*Screen Settings:*
* `+screen#ignoreScreen=1,2,3+` - TTY screens to ignore
==== settings.conf syntax
the syntax of the link:#Settings[settings.conf] is quite simple and

File diff suppressed because it is too large Load Diff