# ScriptCanvas Server (`canvas_server`)

`canvas_server` is a high-performance, lightweight GTK3/Cairo rendering engine written in Vala. It reads line-oriented drawing commands from standard input (`STDIN`) and renders them onto a double-buffered canvas window.

Designed for lightweight desktop setups (e.g., IceWM, Openbox, Puppy Linux), `canvas_server` can render transparent borderless overlays, pinned desktop gadgets, or real-time performance graphs driven directly by shell scripts.

---

## Features

- **STDIN Stream Protocol:** Simple command-based rendering engine (`color`, `line`, `rect`, `frect`, `plot`, `text`, `clear`, `flush`, `save_canvas_to_file`).
- **PNG File Export:** Export the live canvas surface directly to disk (`save_canvas_to_file filename.png`).
- **Transparency & Compositing:** Real RGBA alpha channel support with adjustable background opacity (`-t -a <opacity>`).
- **Desktop Pinning:** Embeds into lower desktop window manager layers using `-d` (`Gdk.WindowTypeHint.DOCK`).
- **Borderless Dragging:** Move borderless windows (`-b`) by clicking and dragging anywhere on the canvas with the left mouse button.
- **Flicker-Free Atomic Double Buffering:** Explicit buffer swap on `flush` ensures smooth rendering and persistent canvas memory across window state changes (raise, focus, move).

---

## Prerequisites

- `valac` (Vala Compiler)
- `libgtk-3-dev`
- `libcairo2-dev`
- An active X11 compositor (e.g., `picom`, `xcompmgr`) for RGBA window transparency.

---

## Compilation

Compile `canvas_server.vala` using `valac`:

```bash
valac --pkg gtk+-3.0 --pkg cairo --pkg gio-2.0 --pkg gio-unix-2.0 canvas_server.vala -o canvas_server
```

---

## Command Line Options

| Option | Short | Type | Default | Description |
| :--- | :---: | :---: | :---: | :--- |
| `--width` | `-w` | `int` | `800` | Canvas width in pixels |
| `--height` | `-h` | `int` | `600` | Canvas height in pixels |
| `--x-pos` | `-x` | `int` | `-1` | Window X position on screen |
| `--y-pos` | `-y` | `int` | `-1` | Window Y position on screen |
| `--transparent`| `-t` | flag | `false` | Enable RGBA visual transparency |
| `--alpha` | `-a` | `double`| `0.0` | Background opacity (`0.0` = transparent, `1.0` = solid) |
| `--bg-color` | `-c` | `string`| `#1e1e2e`| Background hex color |
| `--borderless` | `-b` | flag | `false` | Hide window decorations/titlebar |
| `--desktop` | `-d` | flag | `false` | Embed window in lower desktop layer |

---

## STDIN Drawing Commands

Commands are fed line-by-line via pipe (`|`). Lines starting with `#` or empty lines are ignored.

| Command | Arguments | Description | Example |
| :--- | :--- | :--- | :--- |
| `clear` | *(none)* | Clears canvas using background color/alpha | `clear` |
| `color` | `<hex_or_rgba>` | Sets active draw color (#RRGGBB, #RRGGBBAA, or `rgba(...)`) | `color #89b4fa` |
| `line` | `<x1> <y1> <x2> <y2>` | Draws a 1.5px line between two points | `line 10 50 100 50` |
| `rect` | `<x> <y> <w> <h>` | Draws a rectangle outline | `rect 50 50 200 100` |
| `frect` / `rectfill` | `<x> <y> <w> <h>` | Draws a filled rectangle | `frect 0 0 400 200` |
| `plot` | `<x> <y> <diameter>` | Draws a filled circle/dot | `plot 150 75 8` |
| `text` | `<x> <y> <size> <text>` | Draws bold text at `(x, y)` with given size | `text 12 28 14 CPU` |
| `flush` / `present` / `sync` | *(none)* | Swaps back buffer to front display surface | `flush` |
| `save_canvas_to_file` / `save` | `<filename.png>` | Saves current canvas to a PNG file | `save_canvas_to_file snapshot.png` |

---

## Best Practices for Client Scripts

1. **Atomic Grouping:** Wrap entire frames in Bash `{ ... }` blocks to send complete drawing frames in a single write pass and prevent buffer-induced flickering.
2. **Zero Process Forks:** Perform loop arithmetic using pure Bash integer calculations (`$(( ... ))`) instead of invoking `awk` or subshells in high-frequency loops.
3. **Terminal Console Output:** Direct diagnostic `echo` logs to `STDERR` (`>&2`) so stdout remains clean for piping drawing commands:
   ```bash
   echo "Log message" >&2
   ```
4. **Interactive Prompts:** When prompting for keypresses while piping to `canvas_server`, redirect stdin directly from the terminal device:
   ```bash
   read -r -p "Press [ENTER]..." < /dev/tty
   ```

---

## Usage Examples

### 1. Animated Demo with Screenshot Export (`demo.sh`)

```bash
#!/usr/bin/env bash

# Clear display
echo "clear"

# Draw red rectangle and blue line
echo "color #ff0055"
echo "rect 50 50 200 150"
echo "color #0088ff"
echo "line 50 50 250 200"
echo "flush"

# Animate green trail
echo "color #00aa44"
for i in $(seq 0 10 300); do
    echo "plot $((300 + i)) $((100 + i / 2)) 8"
    echo "flush"
    sleep 0.05
done

# Export final canvas state to PNG
echo "save_canvas_to_file screenshot.png"

# Keep window open until user presses ENTER
read -r -p "Press [ENTER] in terminal to exit..." < /dev/tty