# EARS Kiosk Mode

Runs the EARS application fullscreen on tty3 at boot, with no desktop
environment around it. The normal Xubuntu desktop remains available on
tty7 for development and troubleshooting.

**Status: semi-permanent.** Nothing here replaces the Xubuntu desktop.
lightdm still runs, the default systemd target is unchanged, and GRUB is
untouched. Removing two files returns the machine to stock.

---

## Quick reference

| Action | How |
|---|---|
| Switch to kiosk | `Ctrl+Alt+F3` |
| Switch to desktop | `Ctrl+Alt+F7` |
| Exit kiosk to a shell | Press **Close** in the app |
| Start kiosk manually | `~/kiosk/kiosk-start.sh` (from a text console) |
| Disable kiosk at next boot | `rm ~/kiosk/enabled` |
| Re-enable | `touch ~/kiosk/enabled` |
| Live log | `tail -f ~/kiosk/logs/current.log` |
| Kill the app | `pkill -f program.exe` (relaunches automatically) |

---

## Layout

```
~/kiosk/
├── kiosk-start.sh        launches the X server on the current VT
├── kiosk-session.sh      the session: hardware setup, WM, app loop
├── display-setup.sh      symlink to the rotation/touch script
├── enabled               presence of this file enables boot autostart
├── README.md             this file
└── logs/
    ├── current.log       symlink to the newest session log
    ├── session-*.log     one per session, 20 kept
    └── startx.log        X server output (appended, never rotated)
```

Application: `/home/ears/Desktop/Kazi/v3/linux/program.exe`

---

## How it boots

```
power on
  → GRUB → systemd → graphical.target
      ├── lightdm on vt7          (normal Xubuntu, untouched)
      └── getty@tty3 autologin as `ears`
            → ~/.bash_profile sees tty3 + ~/kiosk/enabled
              → exec kiosk-start.sh
                → startx on vt3
                  → kiosk-session.sh
                    → display-setup.sh, matchbox, unclutter
                    → loop: mono program.exe
```

`kiosk-start.sh` calls `fgconsole` to find the VT it was launched from,
so it works whether started at boot on tty3 or by hand from any console.

### Exit codes

| Code | Meaning |
|---|---|
| 0 | Clean exit (Close button) — session ends, shell on tty3 |
| other | Crash — relaunched after 2s |
| 3 crashes in <20s each | Recovery console (xterm) opens with the log |

---

## Dependencies

```bash
sudo apt install --no-install-recommends \
     xinit matchbox-window-manager unclutter xterm x11-xserver-utils
```

Plus `mono-complete` for the application itself.

---

## Installation from scratch

### 1. Scripts

Place `kiosk-start.sh` and `kiosk-session.sh` in `~/kiosk/`, then:

```bash
chmod +x ~/kiosk/kiosk-start.sh ~/kiosk/kiosk-session.sh
mkdir -p ~/kiosk/logs
```

Confirm the app path at the top of `kiosk-session.sh`:

```bash
APP_DIR="/home/ears/Desktop/Kazi/v3/linux"
APP_CMD="mono program.exe"
```

No `$` before the path, no trailing slash.

### 2. Display and touch

The rotation script is shared with the Xubuntu session
(`~/.config/autostart/Rotate Display.desktop`). Symlink it:

```bash
ln -s /path/to/rotate-display.sh ~/kiosk/display-setup.sh
```

It handles: 90° right rotation, the matching touch coordinate matrix
for `SIS0457:00 0457:11ED`, and disabling blanking/DPMS.

### 3. Autologin on tty3

```bash
sudo systemctl edit getty@tty3
```

```ini
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin ears --noclear %I $TERM
```

```bash
sudo systemctl enable getty@tty3.service
```

### 4. Boot hook

Append to `~/.bash_profile` (or `~/.profile` if that's the one bash reads):

```bash
# --- kiosk autostart on tty3 only ---
if [[ -z $DISPLAY && $(tty) == /dev/tty3 && -f $HOME/kiosk/enabled ]]; then
    sleep 3                      # let lightdm claim vt7 first
    exec "$HOME/kiosk/kiosk-start.sh"
fi
```

### 5. Enable and reboot

```bash
touch ~/kiosk/enabled
sudo reboot
```

---

## Troubleshooting

Always start here:

```bash
tail -60 ~/kiosk/logs/current.log     # app + session errors
tail -40 ~/kiosk/logs/startx.log      # X server failed to start
grep -E '\(EE\)' ~/.local/share/xorg/Xorg.1.log
```

| Symptom | Cause / fix |
|---|---|
| `Only console users are allowed to run the X server` | Launched from a terminal inside Xfce. Use `Ctrl+Alt+F3` and run from the text console. |
| `Cannot open virtual console N (Permission denied)` | Asking for a VT you don't own. `kiosk-start.sh` uses `fgconsole` to avoid this — check it wasn't edited to a hardcoded `vt8`. |
| `Server is already active for display 1` | Stale lock: `sudo rm -f /tmp/.X1-lock /tmp/.X11-unix/X1` |
| `cd: $/home/... No such file` | Stray `$` in `APP_DIR`. Path must be literal. |
| Black screen, then "session ended" | X started, session script exited. Read `current.log`. |
| App runs but not fullscreen | `matchbox-window-manager` missing. |
| Rotation right, touch wrong | `display-setup.sh` not executable, or `xinput` device name changed. Check with `xinput list --name-only`. |
| Boot lands on vt7 not vt3 | lightdm won the race. Increase `sleep 3` to `sleep 6`. |
| No sound | See below. |

`xf86EnableIO: failed to enable I/O ports` in the Xorg log is normal and
can be ignored — rootless X doesn't need legacy port access.

### Getting a shell inside the kiosk

Add temporarily to `kiosk-session.sh`, before the `while true` loop:

```bash
xterm -fa Monospace -fs 14 -geometry 100x30 &
```

### Audio

The kiosk session does not start an audio server; on the desktop that's
done by Xfce's autostart. Check from inside the kiosk:

```bash
pactl info                    # "Connection refused" = no server
aplay /usr/share/sounds/alsa/Front_Center.wav
```

If a server is needed, add to `kiosk-session.sh` before `matchbox`:

```bash
if command -v pipewire >/dev/null && ! pactl info &>/dev/null; then
    pipewire & pipewire-pulse & wireplumber &
    sleep 2
elif command -v pulseaudio >/dev/null && ! pactl info &>/dev/null; then
    pulseaudio --start
    sleep 2
fi
```

**Test with the Xfce session logged out**, not merely switched away.
Both sessions run as `ears`, so an audio server started by the desktop
will serve the kiosk too — giving a false pass that breaks later when
lightdm is removed.

---

## Updating the application

Replace files in `/home/ears/Desktop/Kazi/v3/linux/`, then from a shell:

```bash
pkill -f program.exe
```

The session loop treats this as a crash and relaunches within 2 seconds
with the new build. No reboot needed.

---

## Removal

Temporary (next boot only):

```bash
rm ~/kiosk/enabled
```

Complete:

```bash
sudo systemctl disable getty@tty3.service
sudo rm -rf /etc/systemd/system/getty@tty3.service.d/
# remove the kiosk block from ~/.bash_profile
rm -rf ~/kiosk
```

Nothing else was modified. lightdm, the default target, GRUB, and
`~/.config/xfce4/` are all untouched.

---

## Known limitations

- Both lightdm and the kiosk X server run simultaneously — roughly 200MB
  of RAM that will be freed when lightdm is eventually dropped.
- No lockdown yet: VT switching, GRUB editing, and USB boot are all open.
- No in-app power control; shutdown is done from the desktop or a shell.
- `startx.log` grows without bound; truncate occasionally.

---

## Next steps toward a permanent kiosk

In this order, testing each before moving on:

1. `systemctl set-default multi-user.target`, disable lightdm
2. Move autologin from tty3 to tty1
3. In-app power menu (sleep/shutdown/restart) with a polkit rule
4. Developer unlock: PIN pad, `exit 42` → Xfce session
5. Lockdown: GRUB password, `DontVTSwitch`, mask tty4–6, BIOS password
6. Move the app out of `Desktop/` to `/opt/ears/`

Keep a transcript (`script -a ~/kiosk/setup-transcript.txt`) through each
stage — it becomes the provisioning script for the remaining tablets.