Add a ghostty_alloc function that pairs with the existing
ghostty_free, giving embedders a symmetric malloc/free-style
API for buffer allocation through the libghostty allocator
interface. Returns NULL on allocation failure.
On Windows, Zig's built-in libc and MSVC's CRT maintain separate
heaps, so calling free() on memory allocated by the library causes
undefined behavior. Add ghostty_free() that frees through the same
allocator that performed the allocation, making it safe on all
platforms.
Update format_alloc docs and all examples to use ghostty_free()
instead of free().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fixes#11705
Add bg_color and fg_color options to GhosttyRenderStateRowCellsData that
resolve the final RGB color for a cell, flattening the multiple possible
sources. For background, this handles content-tag bg_color_rgb,
content-tag bg_color_palette (looked up in the palette), and the style
bg_color. For foreground, this resolves palette indices through the
palette; bold color handling is not applied and is left to the caller.
Both return GHOSTTY_INVALID_VALUE when no explicit color is set, in
which case the caller should fall back to whatever default color it
wants (e.g. the terminal background/foreground).
Fixes#11705
Add bg_color and fg_color options to GhosttyRenderStateRowCellsData
that resolve the final RGB color for a cell, flattening the multiple
possible sources. For background, this handles content-tag bg_color_rgb,
content-tag bg_color_palette (looked up in the palette), and the
style bg_color. For foreground, this resolves palette indices through
the palette; bold color handling is not applied and is left to the
caller.
Both return GHOSTTY_INVALID_VALUE when no explicit color is set, in
which case the caller should fall back to whatever default color it
wants (e.g. the terminal background/foreground).
#11706
Add a new GHOSTTY_TERMINAL_DATA_MOUSE_TRACKING option to the
ghostty_terminal_get API. This returns true if any mouse tracking
mode is active (X10, normal, button, or any-event), replacing the
need for consumers to loop over four separate mode queries.
Add GHOSTTY_BUILD_INFO_OPTIMIZE to query the Zig optimization mode
(debug, release safe/small/fast) the library was compiled with. This
reads directly from builtin.mode at comptime so it requires no build
system plumbing.
Add a new C API function ghostty_build_info() that exposes compile-time
build options to library consumers. This allows callers to query whether
SIMD, Kitty graphics protocol, and tmux control mode support were
enabled at build time.
Add two new CellData variants to extract background color values
directly from cells. color_palette (10) returns the palette index
as a GhosttyColorPaletteIndex and color_rgb (11) returns the RGB
components as a GhosttyColorRgb. Both reuse the existing color
types from color.h rather than introducing new ones.
These are only valid when the cell content_tag is
bg_color_palette or bg_color_rgb respectively; querying them
with a mismatched tag reads from the wrong union member.
The GRAPHEMES_BUF data kind previously required a double pointer
(pointer to a uint32_t*) because the OutType was [*]u32, making the
typed out parameter *[*]u32. Change OutType to u32 so that callers
pass a plain uint32_t* buffer directly, which is the natural C
calling convention. The implementation casts the out pointer to
[*]u32 internally to write into the buffer.
The STYLE data kind read directly from the render state style array
without checking whether the cell actually had non-default styling.
The style data is undefined for unstyled cells, so this caused a
panic on a corrupt enum value when the caller read the style of an
unstyled cell. Now check cell.hasStyling() first and return the
default style for unstyled cells.
Expand the c-vt-render example to exercise dirty tracking, color
retrieval, cursor state, row/cell iteration with style resolution,
and dirty state reset. Break the example into six doxygen snippet
regions and reference them from render.h.
Expose the cursor fields from RenderState.Cursor through the C API
via new GhosttyRenderStateData enum values. This adds getters for
visual style, visibility, blink state, password input detection,
and viewport position (x, y, wide tail).
A new GhosttyRenderStateCursorVisualStyle enum maps the Zig
cursor.Style values (bar, block, underline, block_hollow) to
stable C integer constants. Viewport position getters return
GHOSTTY_INVALID_VALUE when the cursor is not visible within
the viewport.
Add individual color data kinds to GhosttyRenderStateData so callers
can query background, foreground, cursor color, cursor-color presence,
and the full 256-color palette through ghostty_render_state_get()
without using the sized-struct colors API.
COLOR_CURSOR returns GHOSTTY_INVALID_VALUE when no explicit cursor
color is set; callers can check COLOR_CURSOR_HAS_VALUE first.
Add next, select, and get functions to the render state row cells
API, mirroring the row iterator pattern. row_cells_next advances to
the next cell sequentially, row_cells_select jumps to a specific
column index with bounds validation, and row_cells_get queries data
for the current cell position.
The get function supports querying raw cell values (GhosttyCell),
resolved styles (GhosttyStyle), grapheme codepoint counts, and
writing grapheme codepoints into a caller-provided buffer.
Also add Cell.C and Cell.cval() to page.zig, matching the existing
Row.C/Row.cval() pattern, so the render state can convert cells to
the C ABI type without a raw bitCast.
Change row_iterator_new to only allocate with undefined fields,
matching the pattern used by row_cells_new. The iterator is now
populated via the render state get API with a new .row_iterator
data kind, which slices the row data and resets y to null.
This separates the lifetime of the opaque handle from the render
state it iterates, letting callers allocate once and re-populate
from different states without reallocating.
Add a new opaque RowCells type that wraps per-row cell data
(raw cells, graphemes, styles) for the C API. The caller
allocates a RowCells handle via row_cells_new, then populates
it by passing it to row_get with the new .cells data kind.
This queries the current row from the iterator and slices the
underlying MultiArrayList into the RowCellsWrapper fields.
The new type and functions are wired through main.zig,
lib_vt.zig, and the render.h C header.
Replace ghostty_render_state_row_dirty_get and
ghostty_render_state_row_dirty_set with generic
ghostty_render_state_row_get and ghostty_render_state_row_set
functions using enum-dispatched data/option kinds.
Replace the individual ghostty_render_state_size_get,
ghostty_render_state_dirty_get, and ghostty_render_state_dirty_set
functions with generic ghostty_render_state_get and
ghostty_render_state_set functions that use enum-dispatched data
kinds and option kinds, following the same InType/OutType pattern
used by the terminal and mouse encoder C APIs.
Add a C ABI row-iterator handle for render state with
ghostty_render_state_row_iterator_new and
ghostty_render_state_row_iterator_free, and wire them through
src/terminal/c/main.zig, src/lib_vt.zig, and
include/ghostty/vt/render.h. The header now documents only the
currently exported iterator API.
Add a C-facing GhosttyRenderStateColors sized struct and a
ghostty_render_state_colors_get accessor so renderers can read
background, foreground, cursor color state, and palette data directly
from the render state.
Add ghostty_render_state_size_get() to return cols and rows from the
current render state using out pointers. The C wrapper validates null
inputs, the symbol is wired through the C API export layers, and tests
cover success and invalid-value paths.
Switch RenderState.Dirty to lib.Enum so it uses C-compatible enum
backing when building the C ABI target. Add GhosttyRenderStateDirty and
new ghostty_render_state_dirty_get/set declarations to the render header,
then wire both functions through src/terminal/c/main.zig and the lib_vt
export table.
Introduce the first public C render-state surface for libghostty-vt.
Before this change, the render-state path was only available in Zig,
so C embedders had no direct way to create and update that cache.
Add an opaque GhosttyRenderState type with new, update, and free
entry points, then wire those symbols through the C API bridge and
library exports. Keep the surface intentionally minimal for now so
ownership and update behavior are established before adding read
accessors.
Add a c-vt-grid-ref example that demonstrates the terminal and grid
reference APIs end-to-end. The example creates a small 10x3 terminal,
writes text with mixed styles via VT sequences, then iterates over
every cell in the active area using ghostty_terminal_grid_ref. For
each cell it extracts the codepoint, and for each row it inspects
the wrap flag and the style bold attribute.
The grid_ref.h defgroup gains a @snippet reference to the new example,
and vt.h gets the corresponding @example entry and @ref listing.
Add ghostty_grid_ref_style and ghostty_grid_ref_graphemes to the grid
ref C API, allowing callers to extract the full style and grapheme
cluster directly from a grid reference without manually resolving
the page internals.
Add a new C API function ghostty_terminal_cell that retrieves the
opaque cell and row values at a given point in the terminal grid.
The point is a tagged union supporting active, viewport, screen, and
history coordinate systems.
Add opaque GhosttyCell (uint64_t) and GhosttyRow (uint64_t) types that
bitcast to the internal packed Cell and Row structs from page.zig. Each
type has a corresponding data enum and getter function following the
same pattern as ghostty_terminal_get.
ghostty_cell_get supports extracting codepoint, content tag, wide
property, has_text, has_styling, style_id, has_hyperlink, protected,
and semantic_content. ghostty_row_get supports wrap, wrap_continuation,
grapheme, styled, hyperlink, semantic_prompt, kitty_virtual_placeholder,
and dirty.
The cell and row types and functions live in a new screen.h header,
separate from terminal.h, with terminal.h including screen.h for
convenience.
Add cursor_style to TerminalData, returning the current SGR style
of the cursor (the style applied to newly printed characters) as a
GhosttyStyle.
Refactor the C style conversion helpers: replace the standalone
convertStyle and convertColor functions with fromStyle and fromColor
initializers on the Style and Color extern structs respectively.
Expose the terminal Style struct to the C API as GhosttyStyle, a
sized struct with foreground, background, and underline colors
(as tagged unions) plus boolean text decoration flags.
Add ghostty_style_default() to obtain the default style and
ghostty_style_is_default() to check whether a style has all
default values. Wire both through c/style.zig, main.zig, and
lib_vt.zig with the corresponding header in vt/style.h.
Add a typed data query API to the terminal C interface, following
the same OutType pattern used by the OSC command data API. The new
ghostty_terminal_get function takes a GhosttyTerminalData tag and
an output pointer, returning GhosttyResult.
Currently exposes cols, rows, cursor x/y position, and cursor
pending wrap state. The GhosttyTerminalData enum is placed with the
other types in the header (before functions) per the ordering
convention.
Extract inline @code blocks from vt headers (size_report.h, modes.h,
sgr.h, paste.h, mouse.h, key.h) into standalone buildable examples
under example/. Each header now uses Doxygen @snippet tags to include
code from the example source files, keeping documentation in sync
with code that is verified to compile and run.
New example projects: c-vt-size-report and c-vt-modes. Existing
examples (c-vt-sgr, c-vt-paste, c-vt-mouse-encode, c-vt-key-encode)
gain snippet markers so their code can be referenced from the headers.
Conceptual snippets in key.h, mouse.h, and key/encoder.h that show
terminal-state usage patterns remain inline since they cannot be
compiled standalone.
Extract the inline code example from focus.h into a standalone
buildable example at example/c-vt-encode-focus. The header now
uses a Doxygen @snippet tag to include the code from the example
source file, so the documentation stays in sync with code that
is verified to compile and run.
Add ghostty_size_report_encode() to libghostty-vt, following the
same pattern as focus encoding: a single stateless function that
writes a terminal size report escape sequence into a caller-provided
buffer.
The size_report.zig Style enum and Size struct now use lib.Enum and
lib.Struct so the types are automatically C-compatible when building
with c_abi, eliminating the need for duplicate type definitions in
the C wrapper. The C wrapper in c/size_report.zig re-exports these
types directly and provides the callconv(.c) encode entry point.
Supports mode 2048 in-band reports and XTWINOPS responses (CSI 14 t,
CSI 16 t, CSI 18 t).
Add ghostty_mode_report_encode() which encodes a DECRPM response
sequence into a caller-provided buffer. The function takes a mode
tag, a report state integer, an output buffer, and writes the
appropriate CSI sequence (with ? prefix for DEC private modes).
The Zig-side ReportState is a non-exhaustive c_int enum that uses
std.meta.intToEnum for safe conversion to the internal type,
returning GHOSTTY_INVALID_VALUE on overflow. The C header exposes
a GhosttyModeReportState enum with named constants for the five
standard DECRPM state values.
Add modes.h with GhosttyModeTag (uint16_t) matching the Zig ModeTag
packed struct layout, along with inline helpers for constructing and
inspecting mode tags. Provide GHOSTTY_MODE_* macros for all 39
built-in modes (4 ANSI, 35 DEC), parenthesized for safety.
Add ghostty_terminal_mode_get and ghostty_terminal_mode_set to
terminal.h, both returning GhosttyResult so that null terminals
and unknown mode tags return GHOSTTY_INVALID_VALUE. The get function
writes its result through a bool out-parameter.
Add a note in the Zig mode entries reminding developers to update
modes.h when adding new modes.
Add modes.h with GhosttyModeTag, a uint16_t typedef matching the
Zig ModeTag packed struct layout (bits 0-14 for the mode value,
bit 15 for the ANSI flag). Three inline helper functions provide
construction and inspection: ghostty_mode_tag_new,
ghostty_mode_tag_value, and ghostty_mode_tag_ansi.
Add focus event encoding (CSI I / CSI O) to the libghostty-vt public
API, following the same patterns as key and mouse encoding.
The focus Event enum uses lib.Enum for C ABI compatibility. The C API
provides ghostty_focus_encode() which writes into a caller-provided
buffer and returns GHOSTTY_OUT_OF_SPACE with the required size when
the buffer is too small.
Also update key and mouse encoders to return GHOSTTY_OUT_OF_SPACE
instead of GHOSTTY_OUT_OF_MEMORY for buffer-too-small errors,
reserving OUT_OF_MEMORY for actual allocation failures. Update all
corresponding header documentation.
Add a new c-vt-mouse-encode example that demonstrates how to use the
mouse encoder C API. The example creates a mouse encoder configured
with SGR format and normal tracking mode, sets up terminal geometry
for pixel-to-cell coordinate mapping, and encodes a left button press
event into a terminal escape sequence.
Mirrors the structure of the existing c-vt-key-encode example. Also
adds the corresponding @example doxygen reference in vt.h.
Expose the internal mouse encoding functionality through the C API,
following the same pattern as the existing key encoding API. This
allows external consumers of libvt to encode mouse events into
terminal escape sequences (X10, UTF-8, SGR, URxvt, SGR-Pixels).
The API is split into two opaque handle types: GhosttyMouseEvent
for building normalized mouse events (action, button, modifiers,
position) and GhosttyMouseEncoder for converting those events into
escape sequences. The encoder is configured via a setopt interface
supporting tracking mode, output format, renderer geometry, button
state, and optional motion deduplication by last cell.
Encoder state can also be bulk-configured from a terminal handle
via ghostty_mouse_encoder_setopt_from_terminal. Failed encodes due
to insufficient buffer space report the required size without
mutating deduplication state.
Expose the key encoder Options.fromTerminal function to the C API as
ghostty_key_encoder_setopt_from_terminal. This lets C callers sync all
terminal-derived encoding options (cursor key application mode, keypad
mode, alt escape prefix, modifyOtherKeys, and Kitty flags) in a single
call instead of setting each option individually.
Add an example showing how to use the ghostty-vt terminal and
formatter APIs from C. The example creates a terminal, writes
VT-encoded content with cursor movement and styling sequences,
then formats the screen contents as plain text using the formatter
API.
Rename the existing format function to format_buf to clarify that it
writes into a caller-provided buffer. Add a new format_alloc variant
that allocates the output buffer internally using the provided
allocator (or the default if NULL). The caller receives the allocated
pointer and length and is responsible for freeing it.
This is useful for consumers that do not know the required buffer size
ahead of time and want to avoid the two-pass query-then-format pattern
needed with format_buf.
Add a size field as the first member of formatter option structs
(TerminalOptions, TerminalOptions.Extra, ScreenOptions.Extra) for ABI
compatibility. This allows adding new fields without breaking callers
compiled against older versions of the struct.
Introduce include/ghostty/vt/types.h as the foundational header
containing GhosttyResult and the GHOSTTY_INIT_SIZED macro for
zero-initializing sized structs. Remove the separate result.h header,
moving its contents into types.h.