Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol lib raxol terminal commands csi_handlers device.ex
Raw

lib/raxol/terminal/commands/csi_handlers/device.ex

defmodule Raxol.Terminal.Commands.CSIHandlers.Device do
@moduledoc """
Handlers for device-related CSI commands.
"""
alias Raxol.Terminal.Emulator
def handle_command(emulator, params, intermediates_buffer, byte) do
case byte do
# Device Attributes
?c -> handle_da(emulator, params, intermediates_buffer)
# Device Status Report
?n -> handle_dsr(emulator, params)
# Save Cursor
?s -> handle_decsc(emulator, params)
# Restore Cursor
?u -> handle_decrc(emulator, params)
# Window Manipulation
?t -> handle_xtwinops(emulator, params)
_ -> {:ok, emulator}
end
end
@doc """
Handle Device Attributes (DA) command.
Responds with terminal capabilities.
"""
def handle_da(emulator, _params, intermediates_buffer) do
case intermediates_buffer do
"?" ->
# Respond with VT100 capabilities
# ESC [ ? 1 ; 2 c
# 1 = VT100
# 2 = Advanced Video Option
{:ok, emulator}
_ ->
# Public DA - respond with standard capabilities
Emulator.write_to_output(emulator, ~c"\e[?62;1;6;9;15;22;29c")
{:ok, emulator}
end
end
@doc """
Handle Device Status Report (DSR) command.
Responds with cursor position or device status.
"""
def handle_dsr(emulator, params) do
case params do
[5] ->
# Report device status
# ESC [ 0 n (ready, no malfunctions)
Emulator.write_to_output(emulator, "\e[0n")
{:ok, emulator}
[6] ->
# Report cursor position
# ESC [ row ; col R
{x, y} = Emulator.get_cursor_position(emulator)
Emulator.write_to_output(emulator, "\e[#{y + 1};#{x + 1}R")
{:ok, emulator}
_ ->
{:ok, emulator}
end
end
@doc """
Handle Save Cursor (DECSC) command.
Saves cursor position and attributes.
"""
def handle_decsc(emulator, _params) do
saved_cursor = %{
position: Emulator.get_cursor_position(emulator),
style: emulator.style,
attributes: emulator.cursor.attributes
}
{:ok, %{emulator | saved_cursor: saved_cursor}}
end
@doc """
Handle Restore Cursor (DECRC) command.
Restores cursor position and attributes.
"""
def handle_decrc(emulator, _params) do
case emulator.saved_cursor do
nil ->
{:ok, emulator}
saved ->
emulator =
Emulator.move_cursor_to(
emulator,
saved.position,
emulator.width,
emulator.height
)
{:ok,
%{
emulator
| style: saved.style,
cursor: %{emulator.cursor | attributes: saved.attributes}
}}
end
end
@doc """
Handle Window Manipulation (XTWINOPS) command.
Handles window size and state changes.
"""
def handle_xtwinops(emulator, params) do
case params do
[3, _x, _y] ->
# Report window size
# ESC [ 3 ; height ; width t
Emulator.write_to_output(
emulator,
"\e[3;#{emulator.window.x};#{emulator.window.y}t"
)
{:ok, emulator}
[4, height, width] ->
# Resize window
Emulator.resize(emulator, width, height)
{:ok, emulator}
[5, 0] ->
# Report window state
# ESC [ 5 ; 0 t (normal)
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[5;#{state}t")
{:ok, emulator}
[5, 1] ->
# Report window state
# ESC [ 5 ; 1 t (iconified)
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[5;#{state}t")
{:ok, emulator}
[5, 2] ->
# Report window state
# ESC [ 5 ; 2 t (maximized)
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[5;#{state}t")
{:ok, emulator}
[9, 0] ->
# Restore window
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[9;#{state}t")
{:ok, emulator}
[9, 1] ->
# Maximize window
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[9;#{state}t")
{:ok, %{emulator | window: %{emulator.window | maximized: true}}}
[10] ->
# Unmaximize window
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[10;#{state}t")
{:ok, %{emulator | window: %{emulator.window | maximized: false}}}
[11] ->
# Report window state
state = if emulator.window.maximized, do: 1, else: 0
Emulator.write_to_output(emulator, "\e[11;#{state}t")
[13] ->
# Report window position
Emulator.write_to_output(
emulator,
"\e[13;#{emulator.window.x};#{emulator.window.y}t"
)
[14] ->
# Report window size in pixels
Emulator.write_to_output(
emulator,
"\e[14;#{emulator.window.height};#{emulator.window.width}t"
)
[15] ->
# Report screen size in pixels
Emulator.write_to_output(
emulator,
"\e[15;#{emulator.window.height};#{emulator.window.width}t"
)
[16] ->
# Report character cell size in pixels
Emulator.write_to_output(
emulator,
"\e[16;#{emulator.window.cell_height};#{emulator.window.cell_width}t"
)
[18] ->
# Report screen size in characters
Emulator.write_to_output(
emulator,
"\e[18;#{emulator.height};#{emulator.width}t"
)
[19] ->
# Report screen size in characters
Emulator.write_to_output(
emulator,
"\e[19;#{emulator.height};#{emulator.width}t"
)
[20] ->
# Report icon label
Emulator.write_to_output(emulator, "\e[20;#{emulator.window.title}t")
[21] ->
# Report window title
Emulator.write_to_output(emulator, "\e[21;#{emulator.window.title}t")
_ ->
{:ok, emulator}
end
end
end