Commit Graph

5 Commits

Author SHA1 Message Date
63aa9a400f feat: Send Key dropdown for browser-intercepted keys
Some checks failed
CI / fmt (push) Failing after 40s
Publish / frontend (push) Successful in 44s
CI / check (push) Successful in 1m21s
CI / clippy (push) Successful in 1m45s
Publish / backend (push) Successful in 2m51s
Adds a "Send Key" dropdown menu to the console toolbar for keys that
browsers intercept before JavaScript can capture them (Print Screen,
Scroll Lock, Pause/Break). Also includes Escape, Tab, Caps Lock,
Num Lock, and Ctrl+Alt+Del.

Each menu item sends a press+release scancode pair directly over the
WebSocket, bypassing browser key capture entirely. This enables
activating downstream KVM switch menus (e.g., Avocent OSCAR via
Print Screen) from the blekin interface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 11:32:10 +03:00
ea18d97aa6 feat: KVM port management — configuration, switching, and navigation shell
Some checks failed
CI / fmt (push) Failing after 43s
Publish / frontend (push) Successful in 44s
CI / check (push) Successful in 1m20s
CI / clippy (push) Successful in 1m41s
Publish / backend (push) Successful in 2m49s
Backend (crates/ericrfb-proxy):
- Session cookie now persisted in AppState for device API calls
- New kvm.rs with three REST endpoints:
  GET /api/kvm/ports — scrapes kvm.asp, returns port config as JSON
  PUT /api/kvm/ports — saves port names, hotkeys, visibility, count
  POST /api/kvm/switch — switches active KVM port via home2.asp
- HTML scraping extracts form values from predictable firmware HTML

Frontend (crates/ericrfb-frontend):
- New shell.ts: sidebar navigation with page routing pattern
  (Console, Ports — extensible for Virtual Media, Users, etc.)
- Console refactored into pages/console.ts with mount/unmount lifecycle
  - Port switcher dropdown in toolbar (fetches port list, switches on change)
  - WebSocket auto-reconnects after port switch
- New pages/ports.ts: editable port configuration table
  - Port count, key pause duration, per-port name/hotkey/show-in-console
  - Save, reload, and per-port switch buttons
  - Active port highlighted
- Dark theme sidebar with active state indicators

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 11:18:36 +03:00
75a51def79 fix: correct keyboard scancode mapping from KeyTranslator.java
All checks were successful
CI / fmt (push) Successful in 39s
Publish / frontend (push) Successful in 45s
CI / check (push) Successful in 1m22s
CI / clippy (push) Successful in 1m38s
Publish / backend (push) Successful in 2m48s
The mapping was built assuming keynr followed physical keyboard order
with Escape=0. In reality, KeyTranslator.java maps Java VK_* codes to
keynr values with a different layout:

- keynr 0 = Backquote (not Escape)
- keynr 59 = Escape
- keynr 27 = Enter (not 40)
- keynr 40 = Backslash (not 42)

This caused the number row and QWERTY row to be off by 1 (Escape
was inserted at position 0, pushing everything). The home row
(CapsLock=28, A=29...L=37) happened to align by coincidence, which
is why 'g'(33) worked but 'r'(should be 18, was 19=T) didn't.

Also fixes: F1-F12 off by 1, PrintScreen/ScrollLock/Pause off by 1,
numpad operator keys swapped with numpad 7/8/9.

Corrected both Rust (input.rs) and TypeScript (input.ts) mappings
to match the authoritative KeyTranslator.java VK→keynr table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 10:42:02 +03:00
c31508f138 feat: phase 10 — reconnection, encoding 10, disconnect button
All checks were successful
Publish / frontend (push) Successful in 42s
CI / fmt (push) Successful in 44s
CI / check (push) Successful in 1m43s
CI / clippy (push) Successful in 1m43s
Publish / backend (push) Successful in 2m47s
Frontend reconnection:
- WebSocket auto-reconnects with exponential backoff (1s → 30s)
- Re-authenticates with OmniView to get fresh APPLET_ID on reconnect
- Credentials stored in sessionStorage for automatic re-login
- Status bar shows connection state and reconnect countdown
- Disconnect button returns to login screen

Encoding 10 (Raw with tile interleave):
- codec/raw_tile.rs: decodes encoding 10 per ByteColorRFBRenderer.for()
- Flag byte bit 0 selects plain raw vs 16x16 tile-interleaved data
- Deinterleave handles edge tiles smaller than 16x16
- Wired into session dispatch
- 2 unit tests

39 tests passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 09:21:21 +03:00
8692c0e46a feat: phase 8 — Vite/TS canvas-based KVM console frontend
All checks were successful
CI / fmt (push) Successful in 28s
CI / check (push) Successful in 1m31s
CI / clippy (push) Successful in 1m29s
crates/ericrfb-frontend — vanilla TypeScript + Vite:

login.ts:
- Login form POSTs to /api/login, receives applet_id
- Error display, auto-transitions to console view on success

console.ts:
- Canvas-based renderer sized to framebuffer dimensions
- WebSocket binary protocol decoder: TAG_BLIT → putImageData,
  TAG_RESIZE → canvas resize
- Keyboard capture: keydown/keyup → JS code → e-RIC scancode → WS
- Mouse capture: move/click/wheel → scaled coords + button mask → WS
- Right-click and context menu suppressed for pass-through

input.ts:
- Full 104-key JS KeyboardEvent.code → scancode mapping table

protocol.ts:
- Binary message builders matching proxy WS protocol tags

Toolbar: Ctrl+Alt+Del button, Fullscreen toggle.
Dark theme, pixelated canvas rendering, cursor hidden over console.

Vite config proxies /api to localhost:3000 for dev mode.
Build outputs to ../../dist for proxy static serving.

Builds to 5.8KB JS + 1.4KB CSS gzipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-06 15:19:53 +03:00