# Fenrir User Manual

Fenrir is a modern command line screen reader written in Python 3. 
 
It has a modular structure, a flexible driver-based architecture, is highly configurable and easy to customize and extend.

**Current maintainer:** Storm Dragon  
**Previous developer:** Chrys

## Quick Start

1. **Installation**: See the [README.md](../README.md) for installation instructions
2. **First run**: `sudo fenrir` (or `sudo systemctl start fenrir` if installed)
3. **Tutorial mode**: Press `Fenrir + H` to learn all commands interactively
4. **Basic navigation**: Use numeric keypad for review (desktop layout)
5. **Stop speech**: Press `Ctrl` at any time
6. **Quit**: Press `Fenrir + Q`

## Key Concepts

### Fenrir Key
The Fenrir Key is used to invoke screen reader commands. By default:
- Insert
- Keypad Insert  
- Meta (Super/Windows key)

You can configure multiple Fenrir keys to suit your preference.

### Keyboard Layouts
- **Desktop Layout**: Uses numeric keypad (recommended for desktop users)
- **Laptop Layout**: Alternative bindings for keyboards without numeric keypad

### Review Mode
Navigate the screen without moving the text cursor. Essential for examining content without disrupting your workflow.

## Essential Commands

### Navigation (Desktop Layout)
- `Ctrl` - Stop speech (shut up)
- `Fenrir + H` - Tutorial mode
- `Fenrir + Q` - Quit Fenrir
- `Fenrir + Keypad 5` - Read current screen
- `Keypad 8` - Read current line  
- `Keypad 5` - Read current word
- `Keypad 2` - Read current character

### Review Commands
- `Keypad 7/9` - Previous/next line
- `Keypad 4/6` - Previous/next word
- `Keypad 1/3` - Previous/next character
- `Fenrir + Keypad dot` - Exit review mode

### Table Navigation
- `Fenrir + Keypad *` - Toggle table mode / highlight tracking
- `Keypad 4/6` - Previous/next column (in table mode)
- `Fenrir + Keypad 4/6` - First/last column (in table mode)
- `Fenrir + X` - Set column headers (in table mode)

### Information
- `Fenrir + T` - Announce time
- `Fenrir + T T` - Announce date
- `Keypad dot` - Cursor position

### Clipboard
- `Fenrir + X` - Set mark
- `Fenrir + C` - Copy marked text
- `Fenrir + V` - Paste clipboard
- `Fenrir + Shift + C` - Read current clipboard

### Settings (Runtime Changes)
- `Fenrir + F3` - Toggle sound
- `Fenrir + F4` - Toggle speech  
- `Fenrir + Up/Down` - Speech volume
- `Fenrir + Right/Left` - Speech rate
- `Fenrir + Ctrl + P` - Punctuation level

## Configuration

### Settings File
Main configuration: `/etc/fenrir/settings/settings.conf`

### Key Sections
- `[speech]` - Speech synthesis settings
- `[sound]` - Sound output and icons
- `[keyboard]` - Input and key bindings
- `[screen]` - Screen reading configuration
- `[general]` - General settings

### Common Settings
```ini
[speech]
enabled=True
driver=speechdDriver
rate=0.5
pitch=0.5
volume=1.0

[sound] 
enabled=True
driver=genericDriver
volume=0.7

[keyboard]
driver=evdevDriver
keyboard_layout=desktop

[screen]
driver=vcsaDriver
ignore_screen=

[remote]
enable=True
driver=unixDriver
enable_settings_remote=True
enable_command_remote=True
```

## Remote Control

Fenrir includes a powerful remote control system for automation and integration with external applications.

### Configuration
Enable remote control in settings:
```ini
[remote]
enable=True
driver=unixDriver              # or tcpDriver  
port=22447                     # for TCP driver
enable_settings_remote=True      # allow settings changes
enable_command_remote=True       # allow command execution
```

### Basic Usage with socat

#### Instance Discovery
```bash
# List registered Fenrir instances and their socket paths
echo "ls" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
```

In X terminal mode (`fenrir -x`), multiple Fenrir instances can run at the same
time. Each instance has a private socket at `/tmp/fenrirscreenreader-<pid>.sock`,
and one instance may also own the standard control socket. Use `ls` or
`command ls` on the standard socket to find the private socket for a specific
instance.

#### Speech Control
```bash
# Interrupt current speech
echo "command interrupt" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Speak custom text  
echo "command say Hello, this is a test" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Temporarily disable speech
echo "command tempdisablespeech" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
```

#### Settings Control
```bash
# Enable highlight tracking
echo "setting set focus#highlight=True" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Change speech parameters
echo "setting set speech#rate=0.8" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
echo "setting set speech#pitch=0.6" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
echo "setting set speech#volume=0.9" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Change punctuation level (none/some/most/all)
echo "setting set general#punctuation_level=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
echo "setting set speech#module=espeak-ng" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Multiple settings at once
echo "setting set speech#rate=0.8;sound#volume=0.7;general#punctuation_level=most" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Reset all settings
echo "setting reset" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Save settings
echo "setting save" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
echo "setting saveas /tmp/my-settings.conf" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
```

#### Clipboard Operations
```bash
# Add text to clipboard
echo "command clipboard Text to copy" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock

# Export clipboard to file
echo "command exportclipboard" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
```

#### Application Control
```bash
# Quit Fenrir
echo "command quitapplication" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
```

### Command Reference

**Speech Commands:**
- `command say <text>` - Speak text
- `command interrupt` - Stop speech
- `command tempdisablespeech` - Disable until next key
- `ls` / `list` / `command ls` / `command list` - List registered Fenrir instances

**Settings Commands:**
- `setting set <section>#<key>=<value>` - Change setting
- `setting reset` - Reset to defaults  
- `setting save` - Save current settings

**Other Commands:**
- `command clipboard <text>` - Add to clipboard
- `command exportclipboard` - Export clipboard to file
- `command window <x1> <y1> <x2> <y2>` - Define window
- `command resetwindow` - Reset window
- `command vmenu <menu_path>` - Set virtual menu
- `command resetvmenu` - Reset virtual menu

**Key Settings You Can Change:**
- Punctuation level: `setting set general#punctuation_level=all`
- Speech parameters: `setting set speech#rate=0.8;speech#pitch=0.6`
- Voice selection: `setting set speech#voice=en-us+f3`
- Character echo: `setting set keyboard#char_echo_mode=1`
- Screen ignore: `setting set screen#ignore_screen=1,2,3`

### Scripting Integration

#### Bash Helper Function
```bash
fenrir_say() {
    echo "command say $1" | socat - UNIX-CLIENT:/tmp/fenrirscreenreader-deamon.sock
}

# Usage
fenrir_say "Build completed"
```

#### Python Integration
```python
import socket
import os

def send_fenrir_command(command):
    socket_path = "/tmp/fenrirscreenreader-deamon.sock"
    if os.path.exists(socket_path):
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        try:
            sock.connect(socket_path)
            sock.send(command.encode('utf-8'))
        finally:
            sock.close()

send_fenrir_command("command say Process complete")
```

## Advanced Features

### Table Navigation Mode

Fenrir includes advanced table navigation capabilities for working with tabular data in terminal applications, CSV files, and formatted text output.

#### Entering Table Mode
1. Press `Fenrir + Keypad *` (desktop) or `Fenrir + Y` (laptop)
2. Cycle through: Highlight tracking → Cursor tracking → Table mode
3. Listen for "table mode enabled" announcement

#### Table Navigation Commands
- **Column navigation**: `Keypad 4/6` - Move between columns
- **Row boundaries**: `Fenrir + Keypad 4/6` - Jump to first/last column
- **Cell characters**: `Fenrir + Keypad 1/3` - First/last character in cell
- **Set headers**: `Fenrir + X` - Mark current line as column headers

#### Table Features
- **Automatic detection**: Supports CSV, pipe-separated, space-aligned columns
- **Column headers**: Set and announce headers for better context
- **Boundary feedback**: Audio cues when reaching row boundaries
- **Cell-by-cell navigation**: Precise positioning within tables

### Progress Bar Monitoring

Fenrir automatically detects and provides audio feedback for progress indicators.

#### Progress Detection
- **Percentage**: 45%, 67.5%, 100%
- **Fractions**: 15/100, 3 of 10, Step 7/15
- **Progress bars**: [####    ], [====>   ]
- **Activity indicators**: Loading..., Processing...

#### Audio Feedback
- **Progress tones**: Ascending 400Hz-1200Hz frequency range
- **Activity beeps**: 800Hz tone every 2 seconds
- **Non-intrusive**: Doesn't interrupt speech or other audio

#### Usage
- **Enable**: Use `progress_bar_monitor` command (assign key binding)
- **Automatic**: Works with downloads, compilations, installations
- **Remote control**: Enable via socket commands

### Spell Checking
- `Fenrir + S` - Spell check current word
- `Fenrir + S S` - Add word to dictionary
- `Fenrir + Shift + S` - Remove word from dictionary

### Bookmarks (1-10)
- `Fenrir + Shift + [1-0]` - Set bookmark
- `Fenrir + [1-0]` - Go to bookmark
- `Fenrir + Ctrl + [1-0]` - Clear bookmark

### Multiple Clipboards
- `Fenrir + Home/End` - First/last clipboard
- `Fenrir + PageUp/PageDown` - Previous/next clipboard

### Window Mode
1. Set marks to define window area
2. `Fenrir + Keypad /` - Set window
3. `Fenrir + Keypad / /` - Clear window

## Drivers

### Speech Drivers
- **speechdDriver** - Speech-dispatcher (recommended)
- **genericDriver** - Command-line TTS (espeak, etc.)

### Sound Drivers  
- **genericDriver** - Sox-based (default)
- **gstreamerDriver** - GStreamer-based

### Input Drivers
- **evdevDriver** - Linux evdev (recommended for Linux)
- **x11Driver** - X11 terminal-scoped input for `fenrir -x`

### Screen Drivers
- **vcsaDriver** - Linux VCSA devices (TTY)
- **ptyDriver** - Terminal emulation

### Remote Drivers
- **unixDriver** - Unix socket remote control (recommended)
- **tcpDriver** - TCP socket remote control (localhost only)

## Command Line Options

```
fenrir [OPTIONS]
```

- `-h, --help` - Show help
- `-v, --version` - Show version
- `-f, --foreground` - Run in foreground
- `-s, --setting FILE` - Custom settings file
- `-o, --options SECTION#SETTING=VALUE;..` - Override settings
- `-d, --debug` - Enable debug mode
- `-p, --print` - Print debug to screen
- `-x, --x11` - PTY + X11 keyboard input scoped to the terminal window
- `--x11-window-id WINDOWID` - X11 window id to use for `--x11` terminal mode
- `-F, --force-all-screens` - Ignore ignoreScreen setting
- `-i, -I, --ignore-screen SCREEN` - Ignore specific screen(s), can be used multiple times

### X11 Terminal Mode

Use `fenrir -x` to run Fenrir in an X11 terminal as a normal user:

```bash
fenrir -x
```

This mode uses PTY screen monitoring and X11 keyboard input. It is intended for GUI terminals such as xterm and VTE-based terminals, while keeping Fenrir key handling scoped to that terminal window. Desktop screen readers keep their global bindings outside the focused terminal.

Fenrir normally detects the target terminal from `WINDOWID` or the active X11 window. If needed, pass a window id explicitly:

```bash
fenrir -x --x11-window-id 0x123456
```

X11 terminal mode uses the same keyboard layout files as TTY Fenrir. Supported Fenrir keys include numpad Insert/`KEY_KP0`, CapsLock/`KEY_CAPSLOCK`, Insert/`KEY_INSERT`, and Super/Windows/`KEY_META`. Compose script keys are exposed as `KEY_COMPOSE`.

This mode requires `python-xlib`.

For a dedicated PTY/terminal screen reader, see TDSR: https://github.com/tspivey/tdsr

## Troubleshooting

### No Speech
1. Test speech-dispatcher: `sudo spd-say "hello"`
2. Check driver setting in configuration
3. Verify speech-dispatcher is running

### No Sound
1. Run audio configuration script: `configure_pulse.sh` or `configure_pipewire.sh`
2. Check sound driver setting
3. Verify sox installation

### No Input Response
1. Check permissions: `/dev/input/*` and `/dev/uinput`
2. Verify evdev driver setting
3. Run as root for testing

### Debug Mode
```bash
sudo fenrir -f -d
# Debug output goes to /var/log/fenrir.log
```

## Getting Help

- **Tutorial Mode**: `Fenrir + H` (interactive help)
- **Wiki**: https://git.stormux.org/storm/fenrir/wiki
- **Email**: stormux+subscribe@groups.io
- **IRC**: irc.stormux.org #stormux

## See Also

- [README.md](../README.md) - Installation and basic setup
- [diff_review_mode.md](./diff_review_mode.md) - Diff review workflow and key bindings
- [settings.conf](../config/settings/settings.conf) - Configuration reference
- `man fenrir` - Manual page
