chore: import upstream snapshot with attribution
Test / build-libghostty-vt (x86_64-windows-gnu) (push) Has been cancelled
Test / build-libghostty-vt-macos (aarch64-ios) (push) Has been cancelled
Test / build-libghostty-vt-macos (aarch64-macos) (push) Has been cancelled
Test / build-libghostty-vt-macos (x86_64-macos) (push) Has been cancelled
Test / build-nix (namespace-profile-ghostty-md-arm64) (push) Has been cancelled
Test / build-dist (push) Has been cancelled
Test / GTK x11=true wayland=true (push) Has been cancelled
Test / Build -Dsimd=false (push) Has been cancelled
Test / Build -Dsimd=true (push) Has been cancelled
Test / Build -Dsentry=false (push) Has been cancelled
Test / Build -Dsentry=true (push) Has been cancelled
Test / zig-fmt (push) Has been cancelled
Test / GitHub Actions Pins (push) Has been cancelled
Test / prettier (push) Has been cancelled
Test / swiftlint (push) Has been cancelled
Test / alejandra (push) Has been cancelled
Test / typos (push) Has been cancelled
Nix / Required Checks: Nix (push) Has been cancelled
Nix / check-zig-cache-hash (push) Has been cancelled
Test / skip (push) Has been cancelled
Test / Required Checks: Test (push) Has been cancelled
Test / build-bench (push) Has been cancelled
Test / list-examples (push) Has been cancelled
Test / Example ${{ matrix.dir }} (Windows) (push) Has been cancelled
Test / build-cmake (push) Has been cancelled
Test / test-lib-vt-pkgconfig (push) Has been cancelled
Test / build-flatpak (push) Has been cancelled
Test / build-snap (push) Has been cancelled
Test / build-libghostty-vt (aarch64-linux) (push) Has been cancelled
Test / build-libghostty-vt (aarch64-macos) (push) Has been cancelled
Test / build-libghostty-vt (wasm32-freestanding) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-linux) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-linux-musl) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-macos) (push) Has been cancelled
Test / build-libghostty-vt-android (aarch64-linux-android) (push) Has been cancelled
Test / build-libghostty-vt-android (arm-linux-androideabi) (push) Has been cancelled
Test / build-libghostty-vt-android (x86_64-linux-android) (push) Has been cancelled
Test / build-libghostty-vt-windows (push) Has been cancelled
Test / build-libghostty-windows-gnu (push) Has been cancelled
Test / build-linux (namespace-profile-ghostty-md) (push) Has been cancelled
Test / build-linux (namespace-profile-ghostty-md-arm64) (push) Has been cancelled
Test / build-linux-libghostty (push) Has been cancelled
Test / build-nix (namespace-profile-ghostty-md) (push) Has been cancelled
Test / build-dist-lib-vt (push) Has been cancelled
Test / trigger-snap (push) Has been cancelled
Test / trigger-flatpak (push) Has been cancelled
Test / build-macos (push) Has been cancelled
Test / build-macos-freetype (push) Has been cancelled
Test / test (push) Has been cancelled
Test / test-lib-vt (push) Has been cancelled
Test / GTK x11=false wayland=false (push) Has been cancelled
Test / GTK x11=true wayland=false (push) Has been cancelled
Test / GTK x11=false wayland=true (push) Has been cancelled
Test / test-macos (push) Has been cancelled
Test / test-windows (push) Has been cancelled
Test / Build -Di18n=false (push) Has been cancelled
Test / Build -Di18n=true (push) Has been cancelled
Test / Build test/fuzz-libghostty (push) Has been cancelled
Test / shellcheck (push) Has been cancelled
Test / translations (push) Has been cancelled
Test / blueprint-compiler (push) Has been cancelled
Test / Test pkg/wuffs (push) Has been cancelled
Test / Test build on Debian 13 (push) Has been cancelled
Test / valgrind (push) Has been cancelled
Test / Example ${{ matrix.dir }} (push) Has been cancelled
Test / build-libghostty-vt (x86_64-windows-gnu) (push) Has been cancelled
Test / build-libghostty-vt-macos (aarch64-ios) (push) Has been cancelled
Test / build-libghostty-vt-macos (aarch64-macos) (push) Has been cancelled
Test / build-libghostty-vt-macos (x86_64-macos) (push) Has been cancelled
Test / build-nix (namespace-profile-ghostty-md-arm64) (push) Has been cancelled
Test / build-dist (push) Has been cancelled
Test / GTK x11=true wayland=true (push) Has been cancelled
Test / Build -Dsimd=false (push) Has been cancelled
Test / Build -Dsimd=true (push) Has been cancelled
Test / Build -Dsentry=false (push) Has been cancelled
Test / Build -Dsentry=true (push) Has been cancelled
Test / zig-fmt (push) Has been cancelled
Test / GitHub Actions Pins (push) Has been cancelled
Test / prettier (push) Has been cancelled
Test / swiftlint (push) Has been cancelled
Test / alejandra (push) Has been cancelled
Test / typos (push) Has been cancelled
Nix / Required Checks: Nix (push) Has been cancelled
Nix / check-zig-cache-hash (push) Has been cancelled
Test / skip (push) Has been cancelled
Test / Required Checks: Test (push) Has been cancelled
Test / build-bench (push) Has been cancelled
Test / list-examples (push) Has been cancelled
Test / Example ${{ matrix.dir }} (Windows) (push) Has been cancelled
Test / build-cmake (push) Has been cancelled
Test / test-lib-vt-pkgconfig (push) Has been cancelled
Test / build-flatpak (push) Has been cancelled
Test / build-snap (push) Has been cancelled
Test / build-libghostty-vt (aarch64-linux) (push) Has been cancelled
Test / build-libghostty-vt (aarch64-macos) (push) Has been cancelled
Test / build-libghostty-vt (wasm32-freestanding) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-linux) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-linux-musl) (push) Has been cancelled
Test / build-libghostty-vt (x86_64-macos) (push) Has been cancelled
Test / build-libghostty-vt-android (aarch64-linux-android) (push) Has been cancelled
Test / build-libghostty-vt-android (arm-linux-androideabi) (push) Has been cancelled
Test / build-libghostty-vt-android (x86_64-linux-android) (push) Has been cancelled
Test / build-libghostty-vt-windows (push) Has been cancelled
Test / build-libghostty-windows-gnu (push) Has been cancelled
Test / build-linux (namespace-profile-ghostty-md) (push) Has been cancelled
Test / build-linux (namespace-profile-ghostty-md-arm64) (push) Has been cancelled
Test / build-linux-libghostty (push) Has been cancelled
Test / build-nix (namespace-profile-ghostty-md) (push) Has been cancelled
Test / build-dist-lib-vt (push) Has been cancelled
Test / trigger-snap (push) Has been cancelled
Test / trigger-flatpak (push) Has been cancelled
Test / build-macos (push) Has been cancelled
Test / build-macos-freetype (push) Has been cancelled
Test / test (push) Has been cancelled
Test / test-lib-vt (push) Has been cancelled
Test / GTK x11=false wayland=false (push) Has been cancelled
Test / GTK x11=true wayland=false (push) Has been cancelled
Test / GTK x11=false wayland=true (push) Has been cancelled
Test / test-macos (push) Has been cancelled
Test / test-windows (push) Has been cancelled
Test / Build -Di18n=false (push) Has been cancelled
Test / Build -Di18n=true (push) Has been cancelled
Test / Build test/fuzz-libghostty (push) Has been cancelled
Test / shellcheck (push) Has been cancelled
Test / translations (push) Has been cancelled
Test / blueprint-compiler (push) Has been cancelled
Test / Test pkg/wuffs (push) Has been cancelled
Test / Test build on Debian 13 (push) Has been cancelled
Test / valgrind (push) Has been cancelled
Test / Example ${{ matrix.dir }} (push) Has been cancelled
This commit is contained in:
+1209
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @file vt.h
|
||||
*
|
||||
* libghostty-vt - Virtual terminal emulator library
|
||||
*
|
||||
* This library provides functionality for parsing and handling terminal
|
||||
* escape sequences as well as maintaining terminal state such as styles,
|
||||
* cursor position, screen, scrollback, and more.
|
||||
*
|
||||
* WARNING: This is an incomplete, work-in-progress API. It is not yet
|
||||
* stable and is definitely going to change.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @mainpage libghostty-vt - Virtual Terminal Emulator Library
|
||||
*
|
||||
* libghostty-vt is a C library which implements a modern terminal emulator,
|
||||
* extracted from the [Ghostty](https://ghostty.org) terminal emulator.
|
||||
*
|
||||
* libghostty-vt contains the logic for handling the core parts of a terminal
|
||||
* emulator: parsing terminal escape sequences, maintaining terminal state,
|
||||
* encoding input events, etc. It can handle scrollback, line wrapping,
|
||||
* reflow on resize, and more.
|
||||
*
|
||||
* @warning This library is currently in development and the API is not yet stable.
|
||||
* Breaking changes are expected in future versions. Use with caution in production code.
|
||||
*
|
||||
* @section groups_sec API Reference
|
||||
*
|
||||
* The API is organized into the following groups:
|
||||
* - @ref terminal "Terminal" - Complete terminal emulator state and rendering
|
||||
* - @ref render "Render State" - Incremental render state updates for custom renderers
|
||||
* - @ref formatter "Formatter" - Format terminal content as plain text, VT sequences, or HTML
|
||||
* - @ref osc "OSC Parser" - Parse OSC (Operating System Command) sequences
|
||||
* - @ref sgr "SGR Parser" - Parse SGR (Select Graphic Rendition) sequences
|
||||
* - @ref paste "Paste Utilities" - Validate paste data safety
|
||||
* - @ref unicode "Unicode Utilities" - Codepoint properties for text layout
|
||||
* - @ref build_info "Build Info" - Query compile-time build configuration
|
||||
* - @ref allocator "Memory Management" - Memory management and custom allocators
|
||||
* - @ref wasm "WebAssembly Utilities" - WebAssembly convenience functions
|
||||
*
|
||||
* Encoding related APIs:
|
||||
* - @ref focus "Focus Encoding" - Encode focus in/out events into terminal sequences
|
||||
* - @ref key "Key Encoding" - Encode key events into terminal sequences
|
||||
* - @ref mouse "Mouse Encoding" - Encode mouse events into terminal sequences
|
||||
*
|
||||
* @section examples_sec Examples
|
||||
*
|
||||
* Complete working examples:
|
||||
* - @ref c-vt-build-info/src/main.c - Build info query example
|
||||
* - @ref c-vt/src/main.c - OSC parser example
|
||||
* - @ref c-vt-encode-key/src/main.c - Key encoding example
|
||||
* - @ref c-vt-encode-mouse/src/main.c - Mouse encoding example
|
||||
* - @ref c-vt-paste/src/main.c - Paste safety check example
|
||||
* - @ref c-vt-sgr/src/main.c - SGR parser example
|
||||
* - @ref c-vt-formatter/src/main.c - Terminal formatter example
|
||||
* - @ref c-vt-grid-traverse/src/main.c - Grid traversal example using grid refs
|
||||
* - @ref c-vt-grid-ref-tracked/src/main.c - Tracked grid ref example
|
||||
* - @ref c-vt-compression/src/main.c - Idle scrollback compression example
|
||||
*
|
||||
*/
|
||||
|
||||
/** @example c-vt-build-info/src/main.c
|
||||
* This example demonstrates how to query compile-time build configuration
|
||||
* such as SIMD support, Kitty graphics, and tmux control mode availability.
|
||||
*/
|
||||
|
||||
/** @example c-vt/src/main.c
|
||||
* This example demonstrates how to use the OSC parser to parse an OSC sequence,
|
||||
* extract command information, and retrieve command-specific data like window titles.
|
||||
*/
|
||||
|
||||
/** @example c-vt-encode-key/src/main.c
|
||||
* This example demonstrates how to use the key encoder to convert key events
|
||||
* into terminal escape sequences using the Kitty keyboard protocol.
|
||||
*/
|
||||
|
||||
/** @example c-vt-encode-mouse/src/main.c
|
||||
* This example demonstrates how to use the mouse encoder to convert mouse events
|
||||
* into terminal escape sequences using the SGR mouse format.
|
||||
*/
|
||||
|
||||
/** @example c-vt-paste/src/main.c
|
||||
* This example demonstrates how to use the paste utilities to check if
|
||||
* paste data is safe before sending it to the terminal.
|
||||
*/
|
||||
|
||||
/** @example c-vt-sgr/src/main.c
|
||||
* This example demonstrates how to use the SGR parser to parse terminal
|
||||
* styling sequences and extract text attributes like colors and underline styles.
|
||||
*/
|
||||
|
||||
/** @example c-vt-formatter/src/main.c
|
||||
* This example demonstrates how to use the terminal and formatter APIs to
|
||||
* create a terminal, write VT-encoded content into it, and format the screen
|
||||
* contents as plain text.
|
||||
*/
|
||||
|
||||
/** @example c-vt-grid-traverse/src/main.c
|
||||
* This example demonstrates how to traverse the entire terminal grid using
|
||||
* grid refs to inspect cell codepoints, row wrap state, and cell styles.
|
||||
*/
|
||||
|
||||
/** @example c-vt-grid-ref-tracked/src/main.c
|
||||
* This example demonstrates how to track a grid ref as the terminal scrolls,
|
||||
* detect when it loses its value, and move it to a new point.
|
||||
*/
|
||||
|
||||
/** @example c-vt-compression/src/main.c
|
||||
* This example demonstrates how to schedule incremental scrollback compression
|
||||
* after compression-relevant terminal activity becomes idle.
|
||||
*/
|
||||
|
||||
/** @example c-vt-selection-gesture/src/main.c
|
||||
* This example demonstrates how to use synthetic selection gesture events to
|
||||
* derive drag and deep-press selection snapshots.
|
||||
*/
|
||||
|
||||
/** @example c-vt-kitty-graphics/src/main.c
|
||||
* This example demonstrates how to use the system interface to install a
|
||||
* PNG decoder callback and send a Kitty Graphics Protocol image.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_H
|
||||
#define GHOSTTY_VT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/build_info.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/color_scheme.h>
|
||||
#include <ghostty/vt/device.h>
|
||||
#include <ghostty/vt/focus.h>
|
||||
#include <ghostty/vt/formatter.h>
|
||||
#include <ghostty/vt/render.h>
|
||||
#include <ghostty/vt/terminal.h>
|
||||
#include <ghostty/vt/grid_ref.h>
|
||||
#include <ghostty/vt/grid_ref_tracked.h>
|
||||
#include <ghostty/vt/osc.h>
|
||||
#include <ghostty/vt/sgr.h>
|
||||
#include <ghostty/vt/style.h>
|
||||
#include <ghostty/vt/sys.h>
|
||||
#include <ghostty/vt/key.h>
|
||||
#include <ghostty/vt/kitty_graphics.h>
|
||||
#include <ghostty/vt/modes.h>
|
||||
#include <ghostty/vt/mouse.h>
|
||||
#include <ghostty/vt/paste.h>
|
||||
#include <ghostty/vt/point.h>
|
||||
#include <ghostty/vt/screen.h>
|
||||
#include <ghostty/vt/selection.h>
|
||||
#include <ghostty/vt/size_report.h>
|
||||
#include <ghostty/vt/unicode.h>
|
||||
#include <ghostty/vt/wasm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_H */
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* @file allocator.h
|
||||
*
|
||||
* Memory management interface for libghostty-vt.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_ALLOCATOR_H
|
||||
#define GHOSTTY_VT_ALLOCATOR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
/** @defgroup allocator Memory Management
|
||||
*
|
||||
* libghostty-vt does require memory allocation for various operations,
|
||||
* but is resilient to allocation failures and will gracefully handle
|
||||
* out-of-memory situations by returning error codes.
|
||||
*
|
||||
* The exact memory management semantics are documented in the relevant
|
||||
* functions and data structures.
|
||||
*
|
||||
* libghostty-vt uses explicit memory allocation via an allocator
|
||||
* interface provided by GhosttyAllocator. The interface is based on the
|
||||
* [Zig](https://ziglang.org) allocator interface, since this has been
|
||||
* shown to be a flexible and powerful interface in practice and enables
|
||||
* a wide variety of allocation strategies.
|
||||
*
|
||||
* **For the common case, you can pass NULL as the allocator for any
|
||||
* function that accepts one,** and libghostty will use a default allocator.
|
||||
* The default allocator will be libc malloc/free if libc is linked.
|
||||
* Otherwise, a custom allocator is used (currently Zig's SMP allocator)
|
||||
* that doesn't require any external dependencies.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* For simple use cases, you can ignore this interface entirely by passing NULL
|
||||
* as the allocator parameter to functions that accept one. This will use the
|
||||
* default allocator (typically libc malloc/free, if libc is linked, but
|
||||
* we provide our own default allocator if libc isn't linked).
|
||||
*
|
||||
* To use a custom allocator:
|
||||
* 1. Implement the GhosttyAllocatorVtable function pointers
|
||||
* 2. Create a GhosttyAllocator struct with your vtable and context
|
||||
* 3. Pass the allocator to functions that accept one
|
||||
*
|
||||
* ## Alloc/Free Helpers
|
||||
*
|
||||
* ghostty_alloc() and ghostty_free() provide a simple malloc/free-style
|
||||
* interface for allocating and freeing byte buffers through the library's
|
||||
* allocator. These are useful when:
|
||||
*
|
||||
* - You need to allocate a buffer to pass into a libghostty-vt function
|
||||
* (e.g. preparing input data for ghostty_terminal_vt_write()).
|
||||
* - You need to free a buffer returned by a libghostty-vt function
|
||||
* (e.g. the output of ghostty_formatter_format_alloc()).
|
||||
* - You are on a platform where the library's internal allocator differs
|
||||
* from the consumer's C runtime (e.g. Windows, where Zig's libc and
|
||||
* MSVC's CRT maintain separate heaps), so calling the standard C
|
||||
* free() on library-allocated memory would be undefined behavior.
|
||||
*
|
||||
* Always use the same allocator (or NULL) for both the allocation and
|
||||
* the corresponding free.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Function table for custom memory allocator operations.
|
||||
*
|
||||
* This vtable defines the interface for a custom memory allocator. All
|
||||
* function pointers must be valid and non-NULL.
|
||||
*
|
||||
* @ingroup allocator
|
||||
*
|
||||
* If you're not going to use a custom allocator, you can ignore all of
|
||||
* this. All functions that take an allocator pointer allow NULL to use a
|
||||
* default allocator.
|
||||
*
|
||||
* The interface is based on the Zig allocator interface. I'll say up front
|
||||
* that it is easy to look at this interface and think "wow, this is really
|
||||
* overcomplicated". The reason for this complexity is well thought out by
|
||||
* the Zig folks, and it enables a diverse set of allocation strategies
|
||||
* as shown by the Zig ecosystem. As a consolation, please note that many
|
||||
* of the arguments are only needed for advanced use cases and can be
|
||||
* safely ignored in simple implementations. For example, if you look at
|
||||
* the Zig implementation of the libc allocator in `lib/std/heap.zig`
|
||||
* (search for CAllocator), you'll see it is very simple.
|
||||
*
|
||||
* We chose to align with the Zig allocator interface because:
|
||||
*
|
||||
* 1. It is a proven interface that serves a wide variety of use cases
|
||||
* in the real world via the Zig ecosystem. It's shown to work.
|
||||
*
|
||||
* 2. Our core implementation itself is Zig, and this lets us very
|
||||
* cheaply and easily convert between C and Zig allocators.
|
||||
*
|
||||
* NOTE(mitchellh): In the future, we can have default implementations of
|
||||
* resize/remap and allow those to be null.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* Return a pointer to `len` bytes with specified `alignment`, or return
|
||||
* `NULL` indicating the allocation failed.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param len Number of bytes to allocate
|
||||
* @param alignment Required alignment for the allocation. Guaranteed to
|
||||
* be a power of two between 1 and 16 inclusive.
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return Pointer to allocated memory, or NULL if allocation failed
|
||||
*/
|
||||
void* (*alloc)(void *ctx, size_t len, uint8_t alignment, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Attempt to expand or shrink memory in place.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* `new_len` must be greater than zero.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to resize
|
||||
* @param memory_len Current size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param new_len New requested size
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return true if resize was successful in-place, false if relocation would be required
|
||||
*/
|
||||
bool (*resize)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, size_t new_len, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Attempt to expand or shrink memory, allowing relocation.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* A non-`NULL` return value indicates the resize was successful. The
|
||||
* allocation may have same address, or may have been relocated. In either
|
||||
* case, the allocation now has size of `new_len`. A `NULL` return value
|
||||
* indicates that the resize would be equivalent to allocating new memory,
|
||||
* copying the bytes from the old memory, and then freeing the old memory.
|
||||
* In such case, it is more efficient for the caller to perform the copy.
|
||||
*
|
||||
* `new_len` must be greater than zero.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to remap
|
||||
* @param memory_len Current size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param new_len New requested size
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
* @return Pointer to resized memory (may be relocated), or NULL if manual copy is needed
|
||||
*/
|
||||
void* (*remap)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, size_t new_len, uintptr_t ret_addr);
|
||||
|
||||
/**
|
||||
* Free and invalidate a region of memory.
|
||||
*
|
||||
* `memory_len` must equal the length requested from the most recent
|
||||
* successful call to `alloc`, `resize`, or `remap`. `alignment` must
|
||||
* equal the same value that was passed as the `alignment` parameter to
|
||||
* the original `alloc` call.
|
||||
*
|
||||
* @param ctx The allocator context
|
||||
* @param memory Pointer to the memory block to free
|
||||
* @param memory_len Size of the memory block
|
||||
* @param alignment Alignment (must match original allocation)
|
||||
* @param ret_addr First return address of the allocation call stack (0 if not provided)
|
||||
*/
|
||||
void (*free)(void *ctx, void *memory, size_t memory_len, uint8_t alignment, uintptr_t ret_addr);
|
||||
} GhosttyAllocatorVtable;
|
||||
|
||||
/**
|
||||
* Custom memory allocator.
|
||||
*
|
||||
* For functions that take an allocator pointer, a NULL pointer indicates
|
||||
* that the default allocator should be used. The default allocator will
|
||||
* be libc malloc/free if we're linking to libc. If libc isn't linked,
|
||||
* a custom allocator is used (currently Zig's SMP allocator).
|
||||
*
|
||||
* @ingroup allocator
|
||||
*
|
||||
* Usage example:
|
||||
* @code
|
||||
* GhosttyAllocator allocator = {
|
||||
* .vtable = &my_allocator_vtable,
|
||||
* .ctx = my_allocator_state
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct GhosttyAllocator {
|
||||
/**
|
||||
* Opaque context pointer passed to all vtable functions.
|
||||
* This allows the allocator implementation to maintain state
|
||||
* or reference external resources needed for memory management.
|
||||
*/
|
||||
void *ctx;
|
||||
|
||||
/**
|
||||
* Pointer to the allocator's vtable containing function pointers
|
||||
* for memory operations (alloc, resize, remap, free).
|
||||
*/
|
||||
const GhosttyAllocatorVtable *vtable;
|
||||
} GhosttyAllocator;
|
||||
|
||||
/**
|
||||
* Allocate a buffer of `len` bytes.
|
||||
*
|
||||
* Uses the provided allocator, or the default allocator if NULL is passed.
|
||||
* The returned buffer must be freed with ghostty_free() using the same
|
||||
* allocator.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use, or NULL for the default
|
||||
* @param len Number of bytes to allocate
|
||||
* @return Pointer to the allocated buffer, or NULL if allocation failed
|
||||
*
|
||||
* @ingroup allocator
|
||||
*/
|
||||
GHOSTTY_API uint8_t* ghostty_alloc(const GhosttyAllocator* allocator, size_t len);
|
||||
|
||||
/**
|
||||
* Free memory that was allocated by a libghostty-vt function.
|
||||
*
|
||||
* Use this to free buffers returned by functions such as
|
||||
* ghostty_formatter_format_alloc(). Pass the same allocator that was
|
||||
* used for the allocation, or NULL if the default allocator was used.
|
||||
*
|
||||
* On platforms where the library's internal allocator differs from the
|
||||
* consumer's C runtime (e.g. Windows, where Zig's libc and MSVC's CRT
|
||||
* maintain separate heaps), calling the standard C free() on memory
|
||||
* allocated by the library causes undefined behavior. This function
|
||||
* guarantees the correct allocator is used regardless of platform.
|
||||
*
|
||||
* It is safe to pass a NULL pointer; the call is a no-op in that case.
|
||||
*
|
||||
* @param allocator Pointer to the allocator that was used to allocate the
|
||||
* memory, or NULL if the default allocator was used
|
||||
* @param ptr Pointer to the memory to free (may be NULL)
|
||||
* @param len Length of the allocation in bytes (must match the original
|
||||
* allocation size)
|
||||
*
|
||||
* @ingroup allocator
|
||||
*/
|
||||
GHOSTTY_API void ghostty_free(const GhosttyAllocator* allocator, uint8_t* ptr, size_t len);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_ALLOCATOR_H */
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* @file build_info.h
|
||||
*
|
||||
* Build info - query compile-time build configuration of libghostty-vt.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_BUILD_INFO_H
|
||||
#define GHOSTTY_VT_BUILD_INFO_H
|
||||
|
||||
/** @defgroup build_info Build Info
|
||||
*
|
||||
* Query compile-time build configuration of libghostty-vt.
|
||||
*
|
||||
* These values reflect the options the library was built with and are
|
||||
* constant for the lifetime of the process.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_build_info() to query individual build options:
|
||||
*
|
||||
* @snippet c-vt-build-info/src/main.c build-info-query
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Build optimization mode.
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_OPTIMIZE_DEBUG = 0,
|
||||
GHOSTTY_OPTIMIZE_RELEASE_SAFE = 1,
|
||||
GHOSTTY_OPTIMIZE_RELEASE_SMALL = 2,
|
||||
GHOSTTY_OPTIMIZE_RELEASE_FAST = 3,
|
||||
GHOSTTY_OPTIMIZE_MODE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyOptimizeMode;
|
||||
|
||||
/**
|
||||
* Build info data types that can be queried.
|
||||
*
|
||||
* Each variant documents the expected output pointer type.
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid data type. Never results in any data extraction. */
|
||||
GHOSTTY_BUILD_INFO_INVALID = 0,
|
||||
|
||||
/**
|
||||
* Whether SIMD-accelerated code paths are enabled.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_SIMD = 1,
|
||||
|
||||
/**
|
||||
* Whether Kitty graphics protocol support is available.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_KITTY_GRAPHICS = 2,
|
||||
|
||||
/**
|
||||
* Whether tmux control mode support is available.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_TMUX_CONTROL_MODE = 3,
|
||||
|
||||
/**
|
||||
* The optimization mode the library was built with.
|
||||
*
|
||||
* Output type: GhosttyOptimizeMode *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_OPTIMIZE = 4,
|
||||
|
||||
/**
|
||||
* The full version string (e.g. "1.2.3" or "1.2.3-dev+abcdef").
|
||||
*
|
||||
* Output type: GhosttyString *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_STRING = 5,
|
||||
|
||||
/**
|
||||
* The major version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_MAJOR = 6,
|
||||
|
||||
/**
|
||||
* The minor version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_MINOR = 7,
|
||||
|
||||
/**
|
||||
* The patch version number.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_PATCH = 8,
|
||||
|
||||
/**
|
||||
* The pre metadata string (e.g. "alpha", "beta", "dev"). Has zero length if
|
||||
* no pre metadata is present.
|
||||
*
|
||||
* Output type: GhosttyString *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_PRE = 9,
|
||||
|
||||
/**
|
||||
* The build metadata string (e.g. commit hash). Has zero length if
|
||||
* no build metadata is present.
|
||||
*
|
||||
* Output type: GhosttyString *
|
||||
*/
|
||||
GHOSTTY_BUILD_INFO_VERSION_BUILD = 10,
|
||||
GHOSTTY_BUILD_INFO_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyBuildInfo;
|
||||
|
||||
/**
|
||||
* Query a compile-time build configuration value.
|
||||
*
|
||||
* The caller must pass a pointer to the correct output type for the
|
||||
* requested data (see GhosttyBuildInfo variants for types).
|
||||
*
|
||||
* @param data The build info field to query
|
||||
* @param out Pointer to store the result (type depends on data parameter)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
|
||||
* data type is invalid
|
||||
*
|
||||
* @ingroup build_info
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_build_info(GhosttyBuildInfo data, void *out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_BUILD_INFO_H */
|
||||
@@ -0,0 +1,479 @@
|
||||
/**
|
||||
* @file color.h
|
||||
*
|
||||
* Color types and utilities.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_COLOR_H
|
||||
#define GHOSTTY_VT_COLOR_H
|
||||
|
||||
/** @defgroup color Color Utilities
|
||||
*
|
||||
* Color parsing, palette generation, color math, and X11 color name
|
||||
* utilities shared by libghostty-vt.
|
||||
*
|
||||
* These APIs expose Ghostty's color semantics directly to embedders. Use
|
||||
* them when an application needs to parse the same color strings as Ghostty
|
||||
* config and theme files, generate the same 256-color palette used by the
|
||||
* terminal, list supported X11 color names, or make UI decisions from
|
||||
* luminance and contrast values.
|
||||
*
|
||||
* ## Parsing Colors
|
||||
*
|
||||
* ghostty_color_parse() accepts the flexible syntax used by Ghostty for
|
||||
* terminal colors:
|
||||
*
|
||||
* - X11 color names, matched ASCII case-insensitively.
|
||||
* - 3- or 6-digit hex colors, with or without a leading `#`.
|
||||
* - 9- or 12-digit hex colors, with a leading `#`.
|
||||
* - XParseColor-style `rgb:<red>/<green>/<blue>` values.
|
||||
* - XParseColor-style `rgbi:<red>/<green>/<blue>` values.
|
||||
*
|
||||
* Leading and trailing spaces and tabs are ignored. Use
|
||||
* ghostty_color_parse_x11() when only X11 names should be accepted.
|
||||
*
|
||||
* @code{.c}
|
||||
* GhosttyColorRgb color;
|
||||
*
|
||||
* if (ghostty_color_parse(
|
||||
* "ForestGreen",
|
||||
* sizeof("ForestGreen") - 1,
|
||||
* &color) != GHOSTTY_SUCCESS) {
|
||||
* // Handle invalid color input.
|
||||
* }
|
||||
*
|
||||
* ghostty_color_parse("#abc", sizeof("#abc") - 1, &color);
|
||||
* ghostty_color_parse("rgb:12/34/56", sizeof("rgb:12/34/56") - 1, &color);
|
||||
* @endcode
|
||||
*
|
||||
* ## Palette Entries
|
||||
*
|
||||
* ghostty_color_parse_palette_entry() parses a single Ghostty palette
|
||||
* override in `INDEX=COLOR` form. The index may be decimal or use a `0x`,
|
||||
* `0o`, or `0b` prefix. The color side uses ghostty_color_parse().
|
||||
*
|
||||
* @code{.c}
|
||||
* GhosttyColorRgb palette[256];
|
||||
* ghostty_color_palette_default(palette);
|
||||
*
|
||||
* uint8_t index;
|
||||
* GhosttyColorRgb rgb;
|
||||
*
|
||||
* if (ghostty_color_parse_palette_entry(
|
||||
* "0x10=#282c34",
|
||||
* sizeof("0x10=#282c34") - 1,
|
||||
* &index,
|
||||
* &rgb) == GHOSTTY_SUCCESS) {
|
||||
* palette[index] = rgb;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* ## Palette Generation
|
||||
*
|
||||
* ghostty_color_palette_generate() derives the 216-color cube and grayscale
|
||||
* ramp from a base palette, background, and foreground. Set bits in
|
||||
* GhosttyColorPaletteMask preserve specific indices from the base palette.
|
||||
* The output may alias the base input.
|
||||
*
|
||||
* @code{.c}
|
||||
* GhosttyColorRgb palette[256];
|
||||
* ghostty_color_palette_default(palette);
|
||||
*
|
||||
* GhosttyColorPaletteMask skip = {0};
|
||||
* GHOSTTY_COLOR_PALETTE_MASK_SET(&skip, 16);
|
||||
*
|
||||
* GhosttyColorRgb background = {40, 44, 52};
|
||||
* GhosttyColorRgb foreground = {220, 223, 228};
|
||||
*
|
||||
* ghostty_color_palette_generate(
|
||||
* palette,
|
||||
* &skip,
|
||||
* &background,
|
||||
* &foreground,
|
||||
* true,
|
||||
* palette);
|
||||
* @endcode
|
||||
*
|
||||
* ## X11 Color Names
|
||||
*
|
||||
* The X11 name table is static program-lifetime memory. Entries are in
|
||||
* rgb.txt order and are terminated by an entry with `name == NULL`.
|
||||
* ghostty_color_x11_name_count() returns the number of non-terminator
|
||||
* entries.
|
||||
*
|
||||
* @code{.c}
|
||||
* const GhosttyColorX11Entry* names = ghostty_color_x11_names();
|
||||
* size_t count = ghostty_color_x11_name_count();
|
||||
*
|
||||
* for (size_t i = 0; i < count; i++) {
|
||||
* // names[i].name and names[i].color are valid here.
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RGB color value.
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t r; /**< Red component (0-255) */
|
||||
uint8_t g; /**< Green component (0-255) */
|
||||
uint8_t b; /**< Blue component (0-255) */
|
||||
} GhosttyColorRgb;
|
||||
|
||||
/**
|
||||
* Palette color index (0-255).
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
typedef uint8_t GhosttyColorPaletteIndex;
|
||||
|
||||
/**
|
||||
* A 256-bit mask of palette indices.
|
||||
*
|
||||
* Index i is set iff `(bits[i >> 6] >> (i & 63)) & 1` is 1.
|
||||
* The mask is typically initialized to zero and then populated with
|
||||
* GHOSTTY_COLOR_PALETTE_MASK_SET().
|
||||
*
|
||||
* @code{.c}
|
||||
* GhosttyColorPaletteMask mask = {0};
|
||||
* GHOSTTY_COLOR_PALETTE_MASK_SET(&mask, 20);
|
||||
* if (GHOSTTY_COLOR_PALETTE_MASK_IS_SET(&mask, 20)) {
|
||||
* // Index 20 will be preserved.
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
typedef struct {
|
||||
uint64_t bits[4];
|
||||
} GhosttyColorPaletteMask;
|
||||
|
||||
/**
|
||||
* An entry in Ghostty's X11 color name table.
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
typedef struct {
|
||||
/** Null-terminated color name. NULL marks the end of the table. */
|
||||
const char* name;
|
||||
/** The RGB value of the color. */
|
||||
GhosttyColorRgb color;
|
||||
} GhosttyColorX11Entry;
|
||||
|
||||
/**
|
||||
* Return the storage word for a palette mask index.
|
||||
*
|
||||
* @param index The palette index (0-255)
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
#define GHOSTTY_COLOR_PALETTE_MASK_WORD(index) ((index) >> 6)
|
||||
|
||||
/**
|
||||
* Return the storage bit for a palette mask index.
|
||||
*
|
||||
* @param index The palette index (0-255)
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
#define GHOSTTY_COLOR_PALETTE_MASK_BIT(index) (UINT64_C(1) << ((index) & 63))
|
||||
|
||||
/**
|
||||
* Set a palette mask index.
|
||||
*
|
||||
* @param mask Pointer to a GhosttyColorPaletteMask
|
||||
* @param index The palette index (0-255)
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
#define GHOSTTY_COLOR_PALETTE_MASK_SET(mask, index) \
|
||||
((mask)->bits[GHOSTTY_COLOR_PALETTE_MASK_WORD(index)] |= GHOSTTY_COLOR_PALETTE_MASK_BIT(index))
|
||||
|
||||
/**
|
||||
* Clear a palette mask index.
|
||||
*
|
||||
* @param mask Pointer to a GhosttyColorPaletteMask
|
||||
* @param index The palette index (0-255)
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
#define GHOSTTY_COLOR_PALETTE_MASK_UNSET(mask, index) \
|
||||
((mask)->bits[GHOSTTY_COLOR_PALETTE_MASK_WORD(index)] &= ~GHOSTTY_COLOR_PALETTE_MASK_BIT(index))
|
||||
|
||||
/**
|
||||
* Test whether a palette mask index is set.
|
||||
*
|
||||
* @param mask Pointer to a GhosttyColorPaletteMask
|
||||
* @param index The palette index (0-255)
|
||||
* @return true if the palette index is set, false otherwise
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
#define GHOSTTY_COLOR_PALETTE_MASK_IS_SET(mask, index) \
|
||||
(((mask)->bits[GHOSTTY_COLOR_PALETTE_MASK_WORD(index)] & GHOSTTY_COLOR_PALETTE_MASK_BIT(index)) != 0)
|
||||
|
||||
/** Black color (0) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BLACK 0
|
||||
/** Red color (1) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_RED 1
|
||||
/** Green color (2) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_GREEN 2
|
||||
/** Yellow color (3) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_YELLOW 3
|
||||
/** Blue color (4) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BLUE 4
|
||||
/** Magenta color (5) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_MAGENTA 5
|
||||
/** Cyan color (6) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_CYAN 6
|
||||
/** White color (7) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_WHITE 7
|
||||
/** Bright black color (8) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_BLACK 8
|
||||
/** Bright red color (9) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_RED 9
|
||||
/** Bright green color (10) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_GREEN 10
|
||||
/** Bright yellow color (11) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_YELLOW 11
|
||||
/** Bright blue color (12) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_BLUE 12
|
||||
/** Bright magenta color (13) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_MAGENTA 13
|
||||
/** Bright cyan color (14) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_CYAN 14
|
||||
/** Bright white color (15) @ingroup color */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_WHITE 15
|
||||
|
||||
/**
|
||||
* Get the RGB color components.
|
||||
*
|
||||
* This function extracts the individual red, green, and blue components
|
||||
* from a GhosttyColorRgb value. Primarily useful in WebAssembly environments
|
||||
* where accessing struct fields directly is difficult.
|
||||
*
|
||||
* @param color Pointer to the RGB color value
|
||||
* @param r Pointer to store the red component (0-255)
|
||||
* @param g Pointer to store the green component (0-255)
|
||||
* @param b Pointer to store the blue component (0-255)
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API void ghostty_color_rgb_get(const GhosttyColorRgb* color,
|
||||
uint8_t* r,
|
||||
uint8_t* g,
|
||||
uint8_t* b);
|
||||
|
||||
/**
|
||||
* Parse an X11 color name.
|
||||
*
|
||||
* The color name is resolved from Ghostty's embedded rgb.txt table.
|
||||
* Leading and trailing spaces and tabs are trimmed, and matching is
|
||||
* ASCII case-insensitive. Hex values are not accepted by this function.
|
||||
*
|
||||
* @param name The color name bytes (must not be NULL)
|
||||
* @param len The length of @p name in bytes
|
||||
* @param[out] out The parsed RGB color
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if no color
|
||||
* matches or @p name is NULL
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_color_parse_x11(
|
||||
const char* name,
|
||||
size_t len,
|
||||
GhosttyColorRgb* out);
|
||||
|
||||
/**
|
||||
* Parse a flexible Ghostty color value.
|
||||
*
|
||||
* Accepts Ghostty's terminal color syntax: X11 color names, hex colors
|
||||
* in 3-, 6-, 9-, or 12-digit form (the leading # is optional for 3- and
|
||||
* 6-digit values), and rgb:<red>/<green>/<blue> or
|
||||
* rgbi:<red>/<green>/<blue> specifications. Leading and trailing spaces
|
||||
* and tabs are trimmed.
|
||||
*
|
||||
* @param value The color value bytes (must not be NULL)
|
||||
* @param len The length of @p value in bytes
|
||||
* @param[out] out The parsed RGB color
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if parsing
|
||||
* fails or @p value is NULL
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_color_parse(
|
||||
const char* value,
|
||||
size_t len,
|
||||
GhosttyColorRgb* out);
|
||||
|
||||
/**
|
||||
* Parse a Ghostty palette entry.
|
||||
*
|
||||
* Accepts Ghostty palette config syntax: N=COLOR. N is a palette index
|
||||
* from 0 to 255 in decimal or in 0x, 0o, or 0b-prefixed form. Spaces and
|
||||
* tabs around N and COLOR are ignored. COLOR accepts the same syntax as
|
||||
* ghostty_color_parse().
|
||||
*
|
||||
* @param value The palette entry bytes (must not be NULL)
|
||||
* @param len The length of @p value in bytes
|
||||
* @param[out] out_index The parsed palette index
|
||||
* @param[out] out_rgb The parsed RGB color
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE on any
|
||||
* failure, including index overflow
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_color_parse_palette_entry(
|
||||
const char* value,
|
||||
size_t len,
|
||||
uint8_t* out_index,
|
||||
GhosttyColorRgb* out_rgb);
|
||||
|
||||
/**
|
||||
* Get Ghostty's built-in default 256-color palette.
|
||||
*
|
||||
* Writes exactly 256 entries: Ghostty's base16 defaults, the xterm
|
||||
* 6x6x6 color cube, and the grayscale ramp.
|
||||
*
|
||||
* @param[out] out The output palette, an array of exactly 256
|
||||
* GhosttyColorRgb values
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API void ghostty_color_palette_default(GhosttyColorRgb* out);
|
||||
|
||||
/**
|
||||
* Generate a 256-color palette from base colors.
|
||||
*
|
||||
* The base palette supplies indices 0-15, which are always preserved.
|
||||
* If @p base is NULL, Ghostty's default palette is used. If @p skip is
|
||||
* NULL, no extra indices are skipped. Set bits in @p skip preserve those
|
||||
* indices from @p base. The 216-color cube at indices 16-231 is generated
|
||||
* with trilinear CIELAB interpolation, and the grayscale ramp at indices
|
||||
* 232-255 is interpolated from the background to the foreground.
|
||||
*
|
||||
* For light themes, @p harmonious controls whether the generated palette
|
||||
* keeps the background-to-foreground orientation. When false, Ghostty
|
||||
* swaps the light background and dark foreground so the cube and ramp run
|
||||
* dark-to-light. The output palette may be the same pointer as @p base.
|
||||
*
|
||||
* @param base The base palette, an array of exactly 256 GhosttyColorRgb
|
||||
* values, or NULL to use Ghostty's default palette
|
||||
* @param skip The palette indices to preserve from @p base, or NULL for
|
||||
* an empty mask
|
||||
* @param bg The terminal background color (must not be NULL)
|
||||
* @param fg The terminal foreground color (must not be NULL)
|
||||
* @param harmonious Whether light themes keep background-to-foreground
|
||||
* orientation
|
||||
* @param[out] out The output palette, an array of exactly 256
|
||||
* GhosttyColorRgb values
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API void ghostty_color_palette_generate(
|
||||
const GhosttyColorRgb* base,
|
||||
const GhosttyColorPaletteMask* skip,
|
||||
const GhosttyColorRgb* bg,
|
||||
const GhosttyColorRgb* fg,
|
||||
bool harmonious,
|
||||
GhosttyColorRgb* out);
|
||||
|
||||
/**
|
||||
* Calculate W3C relative luminance for an RGB color.
|
||||
*
|
||||
* Returns a normalized value from 0.0 for black to 1.0 for white.
|
||||
* See https://www.w3.org/TR/WCAG20/#relativeluminancedef.
|
||||
*
|
||||
* @param color The RGB color (must not be NULL)
|
||||
* @return Relative luminance in the range 0.0 to 1.0
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API double ghostty_color_luminance(const GhosttyColorRgb* color);
|
||||
|
||||
/**
|
||||
* Calculate perceived luminance for an RGB color.
|
||||
*
|
||||
* Returns a normalized value from 0.0 for black to 1.0 for white.
|
||||
* Ghostty treats a background color as light when this exceeds 0.5.
|
||||
* This is not the metric used internally by
|
||||
* ghostty_color_palette_generate(), which uses CIELAB lightness.
|
||||
*
|
||||
* @param color The RGB color (must not be NULL)
|
||||
* @return Perceived luminance in the range 0.0 to 1.0
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API double ghostty_color_perceived_luminance(const GhosttyColorRgb* color);
|
||||
|
||||
/**
|
||||
* Calculate the WCAG contrast ratio between two RGB colors.
|
||||
*
|
||||
* The contrast ratio is symmetric and ranges from 1.0 for identical
|
||||
* colors to 21.0 for black and white.
|
||||
*
|
||||
* @param a The first RGB color (must not be NULL)
|
||||
* @param b The second RGB color (must not be NULL)
|
||||
* @return WCAG contrast ratio in the range 1.0 to 21.0
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API double ghostty_color_contrast(const GhosttyColorRgb* a,
|
||||
const GhosttyColorRgb* b);
|
||||
|
||||
/**
|
||||
* Get Ghostty's X11 color name table.
|
||||
*
|
||||
* The returned pointer references static memory valid for the program
|
||||
* lifetime and is never NULL. Entries are in rgb.txt order and are
|
||||
* terminated by an entry with name == NULL. Aliases are separate entries,
|
||||
* such as "medium spring green" and "MediumSpringGreen". Names are the
|
||||
* exact supported spellings from rgb.txt; ghostty_color_parse_x11() also
|
||||
* matches them case-insensitively.
|
||||
*
|
||||
* @code{.c}
|
||||
* for (const GhosttyColorX11Entry* e = ghostty_color_x11_names();
|
||||
* e->name != NULL;
|
||||
* e++) {
|
||||
* // e->name and e->color are valid here.
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @return Pointer to the first X11 color entry
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API const GhosttyColorX11Entry* ghostty_color_x11_names(void);
|
||||
|
||||
/**
|
||||
* Get the number of X11 color name entries.
|
||||
*
|
||||
* The returned count excludes the NULL terminator and is provided so
|
||||
* bindings can preallocate storage before reading ghostty_color_x11_names().
|
||||
*
|
||||
* @return Number of X11 color name entries
|
||||
*
|
||||
* @ingroup color
|
||||
*/
|
||||
GHOSTTY_API size_t ghostty_color_x11_name_count(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_COLOR_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file color_scheme.h
|
||||
*
|
||||
* Color scheme report encoding - encode terminal color scheme reports into
|
||||
* escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_COLOR_SCHEME_H
|
||||
#define GHOSTTY_VT_COLOR_SCHEME_H
|
||||
|
||||
/** @defgroup color_scheme Color Scheme Report Encoding
|
||||
*
|
||||
* Utilities for encoding color scheme reports into terminal escape
|
||||
* sequences for color scheme reporting mode (mode 2031).
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_color_scheme_report_encode() to encode a color scheme report
|
||||
* into a caller-provided buffer. If the buffer is too small, the function
|
||||
* returns GHOSTTY_OUT_OF_SPACE and sets the required size in the output
|
||||
* parameter.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-color-scheme/src/main.c color-scheme-report-encode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Encode a color scheme report into an escape sequence.
|
||||
*
|
||||
* Encodes a color scheme report into the provided buffer. Dark color schemes
|
||||
* emit ESC [ ? 997 ; 1 n, and light color schemes emit ESC [ ? 997 ; 2 n.
|
||||
* The encoded bytes are identical to the terminal's internal CSI ? 996 n
|
||||
* query response.
|
||||
*
|
||||
* Hosts should gate unsolicited sends on GHOSTTY_MODE_COLOR_SCHEME_REPORT
|
||||
* (mode 2031) being set, which can be checked via the mode getters.
|
||||
*
|
||||
* If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE
|
||||
* and writes the required buffer size to @p out_written. The caller can
|
||||
* then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param scheme The color scheme to encode
|
||||
* @param buf Output buffer to write the encoded sequence into (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_written On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer
|
||||
* is too small
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_color_scheme_report_encode(
|
||||
GhosttyColorScheme scheme,
|
||||
char* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_COLOR_SCHEME_H */
|
||||
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* @file device.h
|
||||
*
|
||||
* Device types used by the terminal for device status and device attribute
|
||||
* queries.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_DEVICE_H
|
||||
#define GHOSTTY_VT_DEVICE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* DA1 conformance levels (Pp parameter). */
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT100 1
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT101 1
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT102 6
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT125 12
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT131 7
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT132 4
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT220 62
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT240 62
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT320 63
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT340 63
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT420 64
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT510 65
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT520 65
|
||||
#define GHOSTTY_DA_CONFORMANCE_VT525 65
|
||||
#define GHOSTTY_DA_CONFORMANCE_LEVEL_2 62
|
||||
#define GHOSTTY_DA_CONFORMANCE_LEVEL_3 63
|
||||
#define GHOSTTY_DA_CONFORMANCE_LEVEL_4 64
|
||||
#define GHOSTTY_DA_CONFORMANCE_LEVEL_5 65
|
||||
|
||||
/* DA1 feature codes (Ps parameters). */
|
||||
#define GHOSTTY_DA_FEATURE_COLUMNS_132 1
|
||||
#define GHOSTTY_DA_FEATURE_PRINTER 2
|
||||
#define GHOSTTY_DA_FEATURE_REGIS 3
|
||||
#define GHOSTTY_DA_FEATURE_SIXEL 4
|
||||
#define GHOSTTY_DA_FEATURE_SELECTIVE_ERASE 6
|
||||
#define GHOSTTY_DA_FEATURE_USER_DEFINED_KEYS 8
|
||||
#define GHOSTTY_DA_FEATURE_NATIONAL_REPLACEMENT 9
|
||||
#define GHOSTTY_DA_FEATURE_TECHNICAL_CHARACTERS 15
|
||||
#define GHOSTTY_DA_FEATURE_LOCATOR 16
|
||||
#define GHOSTTY_DA_FEATURE_TERMINAL_STATE 17
|
||||
#define GHOSTTY_DA_FEATURE_WINDOWING 18
|
||||
#define GHOSTTY_DA_FEATURE_HORIZONTAL_SCROLLING 21
|
||||
#define GHOSTTY_DA_FEATURE_ANSI_COLOR 22
|
||||
#define GHOSTTY_DA_FEATURE_RECTANGULAR_EDITING 28
|
||||
#define GHOSTTY_DA_FEATURE_ANSI_TEXT_LOCATOR 29
|
||||
#define GHOSTTY_DA_FEATURE_CLIPBOARD 52
|
||||
|
||||
/* DA2 device type identifiers (Pp parameter). */
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT100 0
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT220 1
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT240 2
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT330 18
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT340 19
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT320 24
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT382 32
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT420 41
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT510 61
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT520 64
|
||||
#define GHOSTTY_DA_DEVICE_TYPE_VT525 65
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Color scheme reported in response to a CSI ? 996 n query.
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_COLOR_SCHEME_LIGHT = 0,
|
||||
GHOSTTY_COLOR_SCHEME_DARK = 1,
|
||||
GHOSTTY_COLOR_SCHEME_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyColorScheme;
|
||||
|
||||
/**
|
||||
* Primary device attributes (DA1) response data.
|
||||
*
|
||||
* Returned as part of GhosttyDeviceAttributes in response to a CSI c query.
|
||||
* The conformance_level is the Pp parameter and features contains the Ps
|
||||
* feature codes.
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef struct {
|
||||
/** Conformance level (Pp parameter). E.g. 62 for VT220. */
|
||||
uint16_t conformance_level;
|
||||
|
||||
/** DA1 feature codes. Only the first num_features entries are valid. */
|
||||
uint16_t features[64];
|
||||
|
||||
/** Number of valid entries in the features array. */
|
||||
size_t num_features;
|
||||
} GhosttyDeviceAttributesPrimary;
|
||||
|
||||
/**
|
||||
* Secondary device attributes (DA2) response data.
|
||||
*
|
||||
* Returned as part of GhosttyDeviceAttributes in response to a CSI > c query.
|
||||
* Response format: CSI > Pp ; Pv ; Pc c
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef struct {
|
||||
/** Terminal type identifier (Pp). E.g. 1 for VT220. */
|
||||
uint16_t device_type;
|
||||
|
||||
/** Firmware/patch version number (Pv). */
|
||||
uint16_t firmware_version;
|
||||
|
||||
/** ROM cartridge registration number (Pc). Always 0 for emulators. */
|
||||
uint16_t rom_cartridge;
|
||||
} GhosttyDeviceAttributesSecondary;
|
||||
|
||||
/**
|
||||
* Tertiary device attributes (DA3) response data.
|
||||
*
|
||||
* Returned as part of GhosttyDeviceAttributes in response to a CSI = c query.
|
||||
* Response format: DCS ! | D...D ST (DECRPTUI).
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef struct {
|
||||
/** Unit ID encoded as 8 uppercase hex digits in the response. */
|
||||
uint32_t unit_id;
|
||||
} GhosttyDeviceAttributesTertiary;
|
||||
|
||||
/**
|
||||
* Device attributes response data for all three DA levels.
|
||||
*
|
||||
* Filled by the device_attributes callback in response to CSI c,
|
||||
* CSI > c, or CSI = c queries. The terminal uses whichever sub-struct
|
||||
* matches the request type.
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef struct {
|
||||
GhosttyDeviceAttributesPrimary primary;
|
||||
GhosttyDeviceAttributesSecondary secondary;
|
||||
GhosttyDeviceAttributesTertiary tertiary;
|
||||
} GhosttyDeviceAttributes;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_DEVICE_H */
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file focus.h
|
||||
*
|
||||
* Focus encoding - encode focus in/out events into terminal escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_FOCUS_H
|
||||
#define GHOSTTY_VT_FOCUS_H
|
||||
|
||||
/** @defgroup focus Focus Encoding
|
||||
*
|
||||
* Utilities for encoding focus gained/lost events into terminal escape
|
||||
* sequences (CSI I / CSI O) for focus reporting mode (mode 1004).
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_focus_encode() to encode a focus event into a caller-provided
|
||||
* buffer. If the buffer is too small, the function returns
|
||||
* GHOSTTY_OUT_OF_SPACE and sets the required size in the output parameter.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-encode-focus/src/main.c focus-encode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Focus event types for focus reporting mode (mode 1004).
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Terminal window gained focus */
|
||||
GHOSTTY_FOCUS_GAINED = 0,
|
||||
/** Terminal window lost focus */
|
||||
GHOSTTY_FOCUS_LOST = 1,
|
||||
GHOSTTY_FOCUS_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyFocusEvent;
|
||||
|
||||
/**
|
||||
* Encode a focus event into a terminal escape sequence.
|
||||
*
|
||||
* Encodes a focus gained (CSI I) or focus lost (CSI O) report into the
|
||||
* provided buffer.
|
||||
*
|
||||
* If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE
|
||||
* and writes the required buffer size to @p out_written. The caller can
|
||||
* then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param event The focus event to encode
|
||||
* @param buf Output buffer to write the encoded sequence into (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_written On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer
|
||||
* is too small
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_focus_encode(
|
||||
GhosttyFocusEvent event,
|
||||
char* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_FOCUS_H */
|
||||
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* @file formatter.h
|
||||
*
|
||||
* Format terminal content as plain text, VT sequences, or HTML.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_FORMATTER_H
|
||||
#define GHOSTTY_VT_FORMATTER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/selection.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/terminal.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup formatter Formatter
|
||||
*
|
||||
* Format terminal content as plain text, VT sequences, or HTML.
|
||||
*
|
||||
* A formatter captures a reference to a terminal and formatting options.
|
||||
* It can be used repeatedly to produce output that reflects the current
|
||||
* terminal state at the time of each format call.
|
||||
*
|
||||
* The terminal must outlive the formatter.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Extra screen state to include in styled output.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterScreenExtra). */
|
||||
size_t size;
|
||||
|
||||
/** Emit cursor position using CUP (CSI H). */
|
||||
bool cursor;
|
||||
|
||||
/** Emit current SGR style state based on the cursor's active style_id. */
|
||||
bool style;
|
||||
|
||||
/** Emit current hyperlink state using OSC 8 sequences. */
|
||||
bool hyperlink;
|
||||
|
||||
/** Emit character protection mode using DECSCA. */
|
||||
bool protection;
|
||||
|
||||
/** Emit Kitty keyboard protocol state using CSI > u and CSI = sequences. */
|
||||
bool kitty_keyboard;
|
||||
|
||||
/** Emit character set designations and invocations. */
|
||||
bool charsets;
|
||||
} GhosttyFormatterScreenExtra;
|
||||
|
||||
/**
|
||||
* Extra terminal state to include in styled output.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterTerminalExtra). */
|
||||
size_t size;
|
||||
|
||||
/** Emit the palette using OSC 4 sequences. */
|
||||
bool palette;
|
||||
|
||||
/** Emit terminal modes that differ from their defaults using CSI h/l. */
|
||||
bool modes;
|
||||
|
||||
/** Emit scrolling region state using DECSTBM and DECSLRM sequences. */
|
||||
bool scrolling_region;
|
||||
|
||||
/** Emit tabstop positions by clearing all tabs and setting each one. */
|
||||
bool tabstops;
|
||||
|
||||
/** Emit the present working directory using OSC 7. */
|
||||
bool pwd;
|
||||
|
||||
/** Emit keyboard modes such as ModifyOtherKeys. */
|
||||
bool keyboard;
|
||||
|
||||
/** Screen-level extras. */
|
||||
GhosttyFormatterScreenExtra screen;
|
||||
} GhosttyFormatterTerminalExtra;
|
||||
|
||||
/**
|
||||
* Options for creating a terminal formatter.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyFormatterTerminalOptions). */
|
||||
size_t size;
|
||||
|
||||
/** Output format to emit. */
|
||||
GhosttyFormatterFormat emit;
|
||||
|
||||
/** Whether to unwrap soft-wrapped lines. */
|
||||
bool unwrap;
|
||||
|
||||
/** Whether to trim trailing whitespace on non-blank lines. */
|
||||
bool trim;
|
||||
|
||||
/** Extra terminal state to include in styled output. */
|
||||
GhosttyFormatterTerminalExtra extra;
|
||||
|
||||
/** Optional selection to restrict output to a range.
|
||||
* If NULL, the entire screen is formatted. */
|
||||
const GhosttySelection *selection;
|
||||
} GhosttyFormatterTerminalOptions;
|
||||
|
||||
/**
|
||||
* Create a formatter for a terminal's active screen.
|
||||
*
|
||||
* The terminal must outlive the formatter. The formatter stores a borrowed
|
||||
* reference to the terminal and reads its current state on each format call.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param formatter Pointer to store the created formatter handle
|
||||
* @param terminal The terminal to format (must not be NULL)
|
||||
* @param options Formatting options
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_formatter_terminal_new(
|
||||
const GhosttyAllocator* allocator,
|
||||
GhosttyFormatter* formatter,
|
||||
GhosttyTerminal terminal,
|
||||
GhosttyFormatterTerminalOptions options);
|
||||
|
||||
/**
|
||||
* Run the formatter and produce output into the caller-provided buffer.
|
||||
*
|
||||
* Each call formats the current terminal state. Pass NULL for buf to
|
||||
* query the required buffer size without writing any output; in that case
|
||||
* out_written receives the required size and the return value is
|
||||
* GHOSTTY_OUT_OF_SPACE.
|
||||
*
|
||||
* If the buffer is too small, returns GHOSTTY_OUT_OF_SPACE and sets
|
||||
* out_written to the required size. The caller can then retry with a
|
||||
* larger buffer.
|
||||
*
|
||||
* @param formatter The formatter handle (must not be NULL)
|
||||
* @param buf Pointer to the output buffer, or NULL to query size
|
||||
* @param buf_len Length of the output buffer in bytes
|
||||
* @param out_written Pointer to receive the number of bytes written,
|
||||
* or the required size on failure
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_formatter_format_buf(GhosttyFormatter formatter,
|
||||
uint8_t* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Run the formatter and return an allocated buffer with the output.
|
||||
*
|
||||
* Each call formats the current terminal state. The buffer is allocated
|
||||
* using the provided allocator (or the default allocator if NULL).
|
||||
* The caller is responsible for freeing the returned buffer with
|
||||
* ghostty_free(), passing the same allocator (or NULL for the default)
|
||||
* that was used for the allocation.
|
||||
*
|
||||
* @param formatter The formatter handle (must not be NULL)
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param out_ptr Pointer to receive the allocated buffer
|
||||
* @param out_len Pointer to receive the length of the output in bytes
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
|
||||
* failure
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_formatter_format_alloc(GhosttyFormatter formatter,
|
||||
const GhosttyAllocator* allocator,
|
||||
uint8_t** out_ptr,
|
||||
size_t* out_len);
|
||||
|
||||
/**
|
||||
* Free a formatter instance.
|
||||
*
|
||||
* Releases all resources associated with the formatter. After this call,
|
||||
* the formatter handle becomes invalid.
|
||||
*
|
||||
* @param formatter The formatter handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
GHOSTTY_API void ghostty_formatter_free(GhosttyFormatter formatter);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_FORMATTER_H */
|
||||
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @file grid_ref.h
|
||||
*
|
||||
* Terminal grid reference type for referencing a resolved position in the
|
||||
* terminal grid.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_GRID_REF_H
|
||||
#define GHOSTTY_VT_GRID_REF_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/screen.h>
|
||||
#include <ghostty/vt/style.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup grid_ref Grid Reference
|
||||
*
|
||||
* A grid reference is a reference to a specific cell position in the
|
||||
* terminal. Obtain a grid reference from `ghostty_terminal_grid_ref`
|
||||
* for untracked or `ghostty_terminal_grid_ref_track` for tracked. Untracked
|
||||
* vs tracked is explained next.
|
||||
*
|
||||
* Important: The grid reference APIs are not meant to be used as the core of a render
|
||||
* loop. They are not built to sustain the framerates needed for rendering large
|
||||
* screens. Use the render state API for that.
|
||||
*
|
||||
* ## Untracked vs Tracked References
|
||||
*
|
||||
* ### Untracked Reference
|
||||
*
|
||||
* An untracked grid reference is a value type that snapshots a specific
|
||||
* cell. It is only valid until the next update to the terminal instance.
|
||||
* There is no guarantee that it will remain valid after any operation,
|
||||
* even if a seemingly unrelated part of the grid is changed. These are meant
|
||||
* to be read and have their values cached immediately after obtaining it.
|
||||
*
|
||||
* An untracked grid reference has a performance cost in its initial lookup,
|
||||
* but doesn't affect the ongoing performance of the terminal in any way,
|
||||
* since it is a one-time snapshot.
|
||||
*
|
||||
* ### Tracked Reference
|
||||
*
|
||||
* A tracked grid reference follows its cell across normal screen operations.
|
||||
* For example scrolling, scrollback pruning, resize/reflow, and other
|
||||
* terminal mutations update the tracked reference automatically.
|
||||
*
|
||||
* A tracked reference can still lose its original semantic location. This can
|
||||
* happen when the underlying grid is reset, pruned, or otherwise discarded in a
|
||||
* way that cannot be mapped to a meaningful new cell. In that state,
|
||||
* ghostty_tracked_grid_ref_has_value() returns false and
|
||||
* ghostty_tracked_grid_ref_snapshot() / ghostty_tracked_grid_ref_point() return
|
||||
* GHOSTTY_NO_VALUE. The handle remains valid, and callers may move it to a new
|
||||
* point with ghostty_tracked_grid_ref_set().
|
||||
*
|
||||
* To read cell data from a tracked reference, first snapshot it with
|
||||
* ghostty_tracked_grid_ref_snapshot(). The returned `GhosttyGridRef` is again
|
||||
* an untracked reference and follows the same short lifetime rules as any other
|
||||
* untracked grid reference.
|
||||
*
|
||||
* A tracked reference belongs to the terminal screen/page-list that was active
|
||||
* when it was created or last set. Converting it to a point uses that owning
|
||||
* screen/page-list, even if the terminal has since switched between primary and
|
||||
* alternate screens. Calling ghostty_tracked_grid_ref_set() resolves the new
|
||||
* point against the terminal's currently active screen/page-list and may move
|
||||
* the tracked reference between screens.
|
||||
*
|
||||
* Tracked references are owned by the caller and must be freed with
|
||||
* ghostty_tracked_grid_ref_free(). If the terminal that created a tracked
|
||||
* reference is freed first, the handle remains valid only for tracked-grid-ref
|
||||
* APIs: it reports no value and can still be freed.
|
||||
*
|
||||
* Each tracked reference adds bookkeeping to terminal mutations. Use them
|
||||
* sparingly for long-lived anchors such as selections, search state, marks,
|
||||
* or application-side bookmarks.
|
||||
*
|
||||
* ## Lifetime
|
||||
*
|
||||
* An untracked reference is a snapshot. It doesn't need to be freed.
|
||||
* The safety of accessing the value is documented explicitly above: it
|
||||
* is only safe to access any data until the next terminal mutating
|
||||
* operation (including free).
|
||||
*
|
||||
* A tracked reference is allocated and must be freed when it is no
|
||||
* longer needed. A tracked reference may outlive the terminal that created it;
|
||||
* after terminal free, it reports no value and can still be freed.
|
||||
*
|
||||
* ## Examples
|
||||
*
|
||||
* @snippet c-vt-grid-traverse/src/main.c grid-ref-traverse
|
||||
* @snippet c-vt-grid-ref-tracked/src/main.c grid-ref-tracked
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* A resolved reference to a terminal cell position.
|
||||
*
|
||||
* This is a sized struct. Use GHOSTTY_INIT_SIZED() to initialize it.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
typedef struct {
|
||||
size_t size;
|
||||
void *node;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} GhosttyGridRef;
|
||||
|
||||
/**
|
||||
* Get the cell from a grid reference.
|
||||
*
|
||||
* @param ref Pointer to the grid reference
|
||||
* @param[out] out_cell On success, set to the cell at the ref's position (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's
|
||||
* node is NULL
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_grid_ref_cell(const GhosttyGridRef *ref,
|
||||
GhosttyCell *out_cell);
|
||||
|
||||
/**
|
||||
* Get the row from a grid reference.
|
||||
*
|
||||
* @param ref Pointer to the grid reference
|
||||
* @param[out] out_row On success, set to the row at the ref's position (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's
|
||||
* node is NULL
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_grid_ref_row(const GhosttyGridRef *ref,
|
||||
GhosttyRow *out_row);
|
||||
|
||||
/**
|
||||
* Get the grapheme cluster codepoints for the cell at the grid reference's
|
||||
* position.
|
||||
*
|
||||
* Writes the full grapheme cluster (the cell's primary codepoint followed by
|
||||
* any combining codepoints) into the provided buffer. If the cell has no text,
|
||||
* out_len is set to 0 and GHOSTTY_SUCCESS is returned.
|
||||
*
|
||||
* If the buffer is too small (or NULL), the function returns
|
||||
* GHOSTTY_OUT_OF_SPACE and writes the required number of codepoints to
|
||||
* out_len. The caller can then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param ref Pointer to the grid reference
|
||||
* @param buf Output buffer of uint32_t codepoints (may be NULL)
|
||||
* @param buf_len Number of uint32_t elements in the buffer
|
||||
* @param[out] out_len On success, the number of codepoints written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size in codepoints.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's
|
||||
* node is NULL, GHOSTTY_OUT_OF_SPACE if the buffer is too small
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_grid_ref_graphemes(const GhosttyGridRef *ref,
|
||||
uint32_t *buf,
|
||||
size_t buf_len,
|
||||
size_t *out_len);
|
||||
|
||||
/**
|
||||
* Get the hyperlink URI for the cell at the grid reference's position.
|
||||
*
|
||||
* Writes the URI bytes into the provided buffer. If the cell has no
|
||||
* hyperlink, out_len is set to 0 and GHOSTTY_SUCCESS is returned.
|
||||
*
|
||||
* If the buffer is too small (or NULL), the function returns
|
||||
* GHOSTTY_OUT_OF_SPACE and writes the required number of bytes to
|
||||
* out_len. The caller can then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param ref Pointer to the grid reference
|
||||
* @param buf Output buffer for the URI bytes (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_len On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size in bytes.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's
|
||||
* node is NULL, GHOSTTY_OUT_OF_SPACE if the buffer is too small
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_grid_ref_hyperlink_uri(
|
||||
const GhosttyGridRef *ref,
|
||||
uint8_t *buf,
|
||||
size_t buf_len,
|
||||
size_t *out_len);
|
||||
|
||||
/**
|
||||
* Get the style of the cell at the grid reference's position.
|
||||
*
|
||||
* @param ref Pointer to the grid reference
|
||||
* @param[out] out_style On success, set to the cell's style (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the ref's
|
||||
* node is NULL
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_grid_ref_style(const GhosttyGridRef *ref,
|
||||
GhosttyStyle *out_style);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_GRID_REF_H */
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* @file grid_ref_tracked.h
|
||||
*
|
||||
* Tracked terminal grid references.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_GRID_REF_TRACKED_H
|
||||
#define GHOSTTY_VT_GRID_REF_TRACKED_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/grid_ref.h>
|
||||
#include <ghostty/vt/point.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Tracked grid references are owned grid references that move with the
|
||||
* terminal. See @ref grid_ref for the full overview of tracked and untracked
|
||||
* grid reference behavior.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
|
||||
/**
|
||||
* Free a tracked grid reference.
|
||||
*
|
||||
* Passing NULL is allowed and has no effect. A tracked reference may be freed
|
||||
* after the terminal that created it is freed.
|
||||
*
|
||||
* @param ref Tracked grid reference to free.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API void ghostty_tracked_grid_ref_free(GhosttyTrackedGridRef ref);
|
||||
|
||||
/**
|
||||
* Return whether a tracked grid reference currently has a meaningful value.
|
||||
*
|
||||
* If the terminal that created the tracked reference has been freed, this
|
||||
* returns false.
|
||||
*
|
||||
* @param ref Tracked grid reference.
|
||||
* @return true if the reference currently has a meaningful value.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_tracked_grid_ref_has_value(
|
||||
GhosttyTrackedGridRef ref);
|
||||
|
||||
/**
|
||||
* Convert a tracked grid reference to a point in the requested coordinate
|
||||
* space.
|
||||
*
|
||||
* This is the tracked equivalent of ghostty_terminal_point_from_grid_ref().
|
||||
* Unlike snapshotting, this does not expose an intermediate untracked
|
||||
* GhosttyGridRef.
|
||||
*
|
||||
* A tracked reference is resolved against the terminal screen/page-list that
|
||||
* currently owns the reference. If the terminal has switched between primary
|
||||
* and alternate screens since the reference was created or last set, this may
|
||||
* be different from the terminal's currently active screen.
|
||||
*
|
||||
* If the tracked reference no longer has a meaningful value, this returns
|
||||
* GHOSTTY_NO_VALUE. GHOSTTY_NO_VALUE is also returned when the reference cannot
|
||||
* be represented in the requested coordinate space, including after the
|
||||
* terminal that created the tracked reference has been freed.
|
||||
*
|
||||
* @param ref Tracked grid reference.
|
||||
* @param tag Coordinate space to convert into.
|
||||
* @param[out] out_point On success, receives the coordinate. May be NULL.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref is invalid,
|
||||
* or GHOSTTY_NO_VALUE if there is no representable value.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_point(
|
||||
GhosttyTrackedGridRef ref,
|
||||
GhosttyPointTag tag,
|
||||
GhosttyPointCoordinate *out_point);
|
||||
|
||||
/**
|
||||
* Move an existing tracked grid reference to a new terminal point.
|
||||
*
|
||||
* On success, the tracked reference begins tracking the new point and any prior
|
||||
* "no value" state is cleared. On GHOSTTY_OUT_OF_MEMORY, the original tracked
|
||||
* reference is left unchanged.
|
||||
*
|
||||
* The terminal must be the same terminal that created the tracked reference.
|
||||
* The point is resolved against the terminal screen/page-list that is active at
|
||||
* the time this function is called. If the terminal has switched between
|
||||
* primary and alternate screens, this may move the tracked reference from one
|
||||
* screen/page-list to the other.
|
||||
*
|
||||
* @param ref Tracked grid reference.
|
||||
* @param terminal Terminal instance that owns the reference.
|
||||
* @param point New point to track.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref, terminal,
|
||||
* or point is invalid, or GHOSTTY_OUT_OF_MEMORY if allocation fails.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_set(
|
||||
GhosttyTrackedGridRef ref,
|
||||
GhosttyTerminal terminal,
|
||||
GhosttyPoint point);
|
||||
|
||||
/**
|
||||
* Snapshot a tracked grid reference into a regular GhosttyGridRef.
|
||||
*
|
||||
* The returned GhosttyGridRef is an untracked snapshot and has the same
|
||||
* lifetime rules as ghostty_terminal_grid_ref(): it is only valid until the
|
||||
* next terminal update. Snapshot immediately before calling
|
||||
* ghostty_grid_ref_cell(), ghostty_grid_ref_row(),
|
||||
* ghostty_grid_ref_graphemes(), ghostty_grid_ref_hyperlink_uri(), or
|
||||
* ghostty_grid_ref_style().
|
||||
*
|
||||
* If the tracked reference no longer has a meaningful value, this returns
|
||||
* GHOSTTY_NO_VALUE. This includes references whose owning terminal has been
|
||||
* freed.
|
||||
*
|
||||
* @param ref Tracked grid reference.
|
||||
* @param[out] out_ref On success, receives an untracked snapshot. May be NULL.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if ref is invalid,
|
||||
* or GHOSTTY_NO_VALUE if the tracked location was discarded.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_tracked_grid_ref_snapshot(
|
||||
GhosttyTrackedGridRef ref,
|
||||
GhosttyGridRef *out_ref);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_GRID_REF_TRACKED_H */
|
||||
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @file key.h
|
||||
*
|
||||
* Key encoding module - encode key events into terminal escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_KEY_H
|
||||
#define GHOSTTY_VT_KEY_H
|
||||
|
||||
/** @defgroup key Key Encoding
|
||||
*
|
||||
* Utilities for encoding key events into terminal escape sequences,
|
||||
* supporting both legacy encoding as well as Kitty Keyboard Protocol.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* 1. Create an encoder instance with ghostty_key_encoder_new()
|
||||
* 2. Configure encoder options with ghostty_key_encoder_setopt()
|
||||
* or ghostty_key_encoder_setopt_from_terminal() if you have a
|
||||
* GhosttyTerminal.
|
||||
* 3. For each key event:
|
||||
* - Create a key event with ghostty_key_event_new()
|
||||
* - Set event properties (action, key, modifiers, etc.)
|
||||
* - Encode with ghostty_key_encoder_encode()
|
||||
* - Free the event with ghostty_key_event_free()
|
||||
* - Note: You can also reuse the same key event multiple times by
|
||||
* changing its properties.
|
||||
* 4. Free the encoder with ghostty_key_encoder_free() when done
|
||||
*
|
||||
* For a complete working example, see example/c-vt-encode-key in the
|
||||
* repository.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-encode-key/src/main.c key-encode
|
||||
*
|
||||
* ## Example: Encoding with Terminal State
|
||||
*
|
||||
* When you have a GhosttyTerminal, you can sync its modes (cursor key
|
||||
* application, Kitty flags, etc.) into the encoder automatically:
|
||||
*
|
||||
* @code{.c}
|
||||
* // Create a terminal and feed it some VT data that changes modes
|
||||
* GhosttyTerminal terminal;
|
||||
* ghostty_terminal_new(NULL, &terminal,
|
||||
* (GhosttyTerminalOptions){.cols = 80, .rows = 24, .max_scrollback = 0});
|
||||
*
|
||||
* // Application might write data that enables Kitty keyboard protocol, etc.
|
||||
* ghostty_terminal_vt_write(terminal, vt_data, vt_len);
|
||||
*
|
||||
* // Create an encoder and sync its options from the terminal
|
||||
* GhosttyKeyEncoder encoder;
|
||||
* ghostty_key_encoder_new(NULL, &encoder);
|
||||
* ghostty_key_encoder_setopt_from_terminal(encoder, terminal);
|
||||
*
|
||||
* // Encode a key event using the terminal-derived options
|
||||
* char buf[128];
|
||||
* size_t written = 0;
|
||||
* ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written);
|
||||
*
|
||||
* ghostty_key_encoder_free(encoder);
|
||||
* ghostty_terminal_free(terminal);
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ghostty/vt/key/event.h>
|
||||
#include <ghostty/vt/key/encoder.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_KEY_H */
|
||||
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* @file encoder.h
|
||||
*
|
||||
* Key event encoding to terminal escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_KEY_ENCODER_H
|
||||
#define GHOSTTY_VT_KEY_ENCODER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/terminal.h>
|
||||
#include <ghostty/vt/key/event.h>
|
||||
|
||||
/**
|
||||
* Opaque handle to a key encoder instance.
|
||||
*
|
||||
* This handle represents a key encoder that converts key events into terminal
|
||||
* escape sequences.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef struct GhosttyKeyEncoderImpl *GhosttyKeyEncoder;
|
||||
|
||||
/**
|
||||
* Kitty keyboard protocol flags.
|
||||
*
|
||||
* Bitflags representing the various modes of the Kitty keyboard protocol.
|
||||
* These can be combined using bitwise OR operations. Valid values all
|
||||
* start with `GHOSTTY_KITTY_KEY_`.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef uint8_t GhosttyKittyKeyFlags;
|
||||
|
||||
/** Kitty keyboard protocol disabled (all flags off) */
|
||||
#define GHOSTTY_KITTY_KEY_DISABLED 0
|
||||
|
||||
/** Disambiguate escape codes */
|
||||
#define GHOSTTY_KITTY_KEY_DISAMBIGUATE (1 << 0)
|
||||
|
||||
/** Report key press and release events */
|
||||
#define GHOSTTY_KITTY_KEY_REPORT_EVENTS (1 << 1)
|
||||
|
||||
/** Report alternate key codes */
|
||||
#define GHOSTTY_KITTY_KEY_REPORT_ALTERNATES (1 << 2)
|
||||
|
||||
/** Report all key events including those normally handled by the terminal */
|
||||
#define GHOSTTY_KITTY_KEY_REPORT_ALL (1 << 3)
|
||||
|
||||
/** Report associated text with key events */
|
||||
#define GHOSTTY_KITTY_KEY_REPORT_ASSOCIATED (1 << 4)
|
||||
|
||||
/** All Kitty keyboard protocol flags enabled */
|
||||
#define GHOSTTY_KITTY_KEY_ALL (GHOSTTY_KITTY_KEY_DISAMBIGUATE | GHOSTTY_KITTY_KEY_REPORT_EVENTS | GHOSTTY_KITTY_KEY_REPORT_ALTERNATES | GHOSTTY_KITTY_KEY_REPORT_ALL | GHOSTTY_KITTY_KEY_REPORT_ASSOCIATED)
|
||||
|
||||
/**
|
||||
* macOS option key behavior.
|
||||
*
|
||||
* Determines whether the "option" key on macOS is treated as "alt" or not.
|
||||
* See the Ghostty `macos-option-as-alt` configuration option for more details.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Option key is not treated as alt */
|
||||
GHOSTTY_OPTION_AS_ALT_FALSE = 0,
|
||||
/** Option key is treated as alt */
|
||||
GHOSTTY_OPTION_AS_ALT_TRUE = 1,
|
||||
/** Only left option key is treated as alt */
|
||||
GHOSTTY_OPTION_AS_ALT_LEFT = 2,
|
||||
/** Only right option key is treated as alt */
|
||||
GHOSTTY_OPTION_AS_ALT_RIGHT = 3,
|
||||
GHOSTTY_OPTION_AS_ALT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyOptionAsAlt;
|
||||
|
||||
/**
|
||||
* Key encoder option identifiers.
|
||||
*
|
||||
* These values are used with ghostty_key_encoder_setopt() to configure
|
||||
* the behavior of the key encoder.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Terminal DEC mode 1: cursor key application mode (value: bool) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_CURSOR_KEY_APPLICATION = 0,
|
||||
|
||||
/** Terminal DEC mode 66: keypad key application mode (value: bool) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_KEYPAD_KEY_APPLICATION = 1,
|
||||
|
||||
/** Terminal DEC mode 1035: ignore keypad with numlock (value: bool) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_IGNORE_KEYPAD_WITH_NUMLOCK = 2,
|
||||
|
||||
/** Terminal DEC mode 1036: alt sends escape prefix (value: bool) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_ALT_ESC_PREFIX = 3,
|
||||
|
||||
/** xterm modifyOtherKeys mode 2 (value: bool) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_MODIFY_OTHER_KEYS_STATE_2 = 4,
|
||||
|
||||
/** Kitty keyboard protocol flags (value: GhosttyKittyKeyFlags bitmask) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS = 5,
|
||||
|
||||
/** macOS option-as-alt setting (value: GhosttyOptionAsAlt) */
|
||||
GHOSTTY_KEY_ENCODER_OPT_MACOS_OPTION_AS_ALT = 6,
|
||||
|
||||
/** Backarrow key mode (value: bool)
|
||||
* See https://vt100.net/dec/ek-vt3xx-tp-002.pdf page 170
|
||||
* If `false` (the default), `backspace` emits 0x7f
|
||||
* If `true`, `backspace` emits 0x08
|
||||
*/
|
||||
GHOSTTY_KEY_ENCODER_OPT_BACKARROW_KEY_MODE = 7,
|
||||
|
||||
GHOSTTY_KEY_ENCODER_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKeyEncoderOption;
|
||||
|
||||
/**
|
||||
* Create a new key encoder instance.
|
||||
*
|
||||
* Creates a new key encoder with default options. The encoder can be configured
|
||||
* using ghostty_key_encoder_setopt() and must be freed using
|
||||
* ghostty_key_encoder_free() when no longer needed.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator
|
||||
* @param encoder Pointer to store the created encoder handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_key_encoder_new(const GhosttyAllocator *allocator, GhosttyKeyEncoder *encoder);
|
||||
|
||||
/**
|
||||
* Free a key encoder instance.
|
||||
*
|
||||
* Releases all resources associated with the key encoder. After this call,
|
||||
* the encoder handle becomes invalid and must not be used.
|
||||
*
|
||||
* @param encoder The encoder handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_encoder_free(GhosttyKeyEncoder encoder);
|
||||
|
||||
/**
|
||||
* Set an option on the key encoder.
|
||||
*
|
||||
* Configures the behavior of the key encoder. Options control various aspects
|
||||
* of encoding such as terminal modes (cursor key application mode, keypad mode),
|
||||
* protocol selection (Kitty keyboard protocol flags), and platform-specific
|
||||
* behaviors (macOS option-as-alt).
|
||||
*
|
||||
* If you are using a terminal instance, you can set the key encoding
|
||||
* options based on the active terminal state (e.g. legacy vs Kitty mode
|
||||
* and associated flags) with ghostty_key_encoder_setopt_from_terminal().
|
||||
*
|
||||
* A null pointer value does nothing. It does not reset the value to the
|
||||
* default. The setopt call will do nothing.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param option The option to set
|
||||
* @param value Pointer to the value to set (type depends on the option)
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_encoder_setopt(GhosttyKeyEncoder encoder, GhosttyKeyEncoderOption option, const void *value);
|
||||
|
||||
/**
|
||||
* Set encoder options from a terminal's current state.
|
||||
*
|
||||
* Reads the terminal's current modes and flags and applies them to the
|
||||
* encoder's options. This sets cursor key application mode, keypad mode,
|
||||
* alt escape prefix, modifyOtherKeys state, and Kitty keyboard protocol
|
||||
* flags from the terminal state.
|
||||
*
|
||||
* Note that the `macos_option_as_alt` option cannot be determined from
|
||||
* terminal state and is reset to `GHOSTTY_OPTION_AS_ALT_FALSE` by this
|
||||
* call. Use ghostty_key_encoder_setopt() to set it afterward if needed.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param terminal The terminal handle, must not be NULL
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_encoder_setopt_from_terminal(GhosttyKeyEncoder encoder, GhosttyTerminal terminal);
|
||||
|
||||
/**
|
||||
* Encode a key event into a terminal escape sequence.
|
||||
*
|
||||
* Converts a key event into the appropriate terminal escape sequence based on
|
||||
* the encoder's current options. The sequence is written to the provided buffer.
|
||||
*
|
||||
* Not all key events produce output. For example, unmodified modifier keys
|
||||
* typically don't generate escape sequences. Check the out_len parameter to
|
||||
* determine if any data was written.
|
||||
*
|
||||
* If the output buffer is too small, this function returns GHOSTTY_OUT_OF_SPACE
|
||||
* and out_len will contain the required buffer size. The caller can then
|
||||
* allocate a larger buffer and call the function again.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param event The key event to encode, must not be NULL
|
||||
* @param out_buf Buffer to write the encoded sequence to
|
||||
* @param out_buf_size Size of the output buffer in bytes
|
||||
* @param out_len Pointer to store the number of bytes written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if buffer too small, or other error code
|
||||
*
|
||||
* ## Example: Calculate required buffer size
|
||||
*
|
||||
* @code{.c}
|
||||
* // Query the required size with a NULL buffer (always returns OUT_OF_SPACE)
|
||||
* size_t required = 0;
|
||||
* GhosttyResult result = ghostty_key_encoder_encode(encoder, event, NULL, 0, &required);
|
||||
* assert(result == GHOSTTY_OUT_OF_SPACE);
|
||||
*
|
||||
* // Allocate buffer of required size
|
||||
* char *buf = malloc(required);
|
||||
*
|
||||
* // Encode with properly sized buffer
|
||||
* size_t written = 0;
|
||||
* result = ghostty_key_encoder_encode(encoder, event, buf, required, &written);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
*
|
||||
* // Use the encoded sequence...
|
||||
*
|
||||
* free(buf);
|
||||
* @endcode
|
||||
*
|
||||
* ## Example: Direct encoding with static buffer
|
||||
*
|
||||
* @code{.c}
|
||||
* // Most escape sequences are short, so a static buffer often suffices
|
||||
* char buf[128];
|
||||
* size_t written = 0;
|
||||
* GhosttyResult result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written);
|
||||
*
|
||||
* if (result == GHOSTTY_SUCCESS) {
|
||||
* // Write the encoded sequence to the terminal
|
||||
* write(pty_fd, buf, written);
|
||||
* } else if (result == GHOSTTY_OUT_OF_SPACE) {
|
||||
* // Buffer too small, written contains required size
|
||||
* char *dynamic_buf = malloc(written);
|
||||
* result = ghostty_key_encoder_encode(encoder, event, dynamic_buf, written, &written);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
* write(pty_fd, dynamic_buf, written);
|
||||
* free(dynamic_buf);
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_key_encoder_encode(GhosttyKeyEncoder encoder, GhosttyKeyEvent event, char *out_buf, size_t out_buf_size, size_t *out_len);
|
||||
|
||||
#endif /* GHOSTTY_VT_KEY_ENCODER_H */
|
||||
@@ -0,0 +1,482 @@
|
||||
/**
|
||||
* @file event.h
|
||||
*
|
||||
* Key event representation and manipulation.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_KEY_EVENT_H
|
||||
#define GHOSTTY_VT_KEY_EVENT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
|
||||
/**
|
||||
* Opaque handle to a key event.
|
||||
*
|
||||
* This handle represents a keyboard input event containing information about
|
||||
* the physical key pressed, modifiers, and generated text.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef struct GhosttyKeyEventImpl *GhosttyKeyEvent;
|
||||
|
||||
/**
|
||||
* Keyboard input event types.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Key was released */
|
||||
GHOSTTY_KEY_ACTION_RELEASE = 0,
|
||||
/** Key was pressed */
|
||||
GHOSTTY_KEY_ACTION_PRESS = 1,
|
||||
/** Key is being repeated (held down) */
|
||||
GHOSTTY_KEY_ACTION_REPEAT = 2,
|
||||
GHOSTTY_KEY_ACTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKeyAction;
|
||||
|
||||
/**
|
||||
* Keyboard modifier keys bitmask.
|
||||
*
|
||||
* A bitmask representing all keyboard modifiers. This tracks which modifier keys
|
||||
* are pressed and, where supported by the platform, which side (left or right)
|
||||
* of each modifier is active.
|
||||
*
|
||||
* Use the GHOSTTY_MODS_* constants to test and set individual modifiers.
|
||||
*
|
||||
* Modifier side bits are only meaningful when the corresponding modifier bit is set.
|
||||
* Not all platforms support distinguishing between left and right modifier
|
||||
* keys and Ghostty is built to expect that some platforms may not provide this
|
||||
* information.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef uint16_t GhosttyMods;
|
||||
|
||||
/** Shift key is pressed */
|
||||
#define GHOSTTY_MODS_SHIFT (1 << 0)
|
||||
/** Control key is pressed */
|
||||
#define GHOSTTY_MODS_CTRL (1 << 1)
|
||||
/** Alt/Option key is pressed */
|
||||
#define GHOSTTY_MODS_ALT (1 << 2)
|
||||
/** Super/Command/Windows key is pressed */
|
||||
#define GHOSTTY_MODS_SUPER (1 << 3)
|
||||
/** Caps Lock is active */
|
||||
#define GHOSTTY_MODS_CAPS_LOCK (1 << 4)
|
||||
/** Num Lock is active */
|
||||
#define GHOSTTY_MODS_NUM_LOCK (1 << 5)
|
||||
|
||||
/**
|
||||
* Right shift is pressed (0 = left, 1 = right).
|
||||
* Only meaningful when GHOSTTY_MODS_SHIFT is set.
|
||||
*/
|
||||
#define GHOSTTY_MODS_SHIFT_SIDE (1 << 6)
|
||||
/**
|
||||
* Right ctrl is pressed (0 = left, 1 = right).
|
||||
* Only meaningful when GHOSTTY_MODS_CTRL is set.
|
||||
*/
|
||||
#define GHOSTTY_MODS_CTRL_SIDE (1 << 7)
|
||||
/**
|
||||
* Right alt is pressed (0 = left, 1 = right).
|
||||
* Only meaningful when GHOSTTY_MODS_ALT is set.
|
||||
*/
|
||||
#define GHOSTTY_MODS_ALT_SIDE (1 << 8)
|
||||
/**
|
||||
* Right super is pressed (0 = left, 1 = right).
|
||||
* Only meaningful when GHOSTTY_MODS_SUPER is set.
|
||||
*/
|
||||
#define GHOSTTY_MODS_SUPER_SIDE (1 << 9)
|
||||
|
||||
/**
|
||||
* Physical key codes.
|
||||
*
|
||||
* The set of key codes that Ghostty is aware of. These represent physical keys
|
||||
* on the keyboard and are layout-independent. For example, the "a" key on a US
|
||||
* keyboard is the same as the "ф" key on a Russian keyboard, but both will
|
||||
* report the same key_a value.
|
||||
*
|
||||
* Layout-dependent strings are provided separately as UTF-8 text and are produced
|
||||
* by the platform. These values are based on the W3C UI Events KeyboardEvent code
|
||||
* standard. See: https://www.w3.org/TR/uievents-code
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_KEY_UNIDENTIFIED = 0,
|
||||
|
||||
// Writing System Keys (W3C § 3.1.1)
|
||||
GHOSTTY_KEY_BACKQUOTE,
|
||||
GHOSTTY_KEY_BACKSLASH,
|
||||
GHOSTTY_KEY_BRACKET_LEFT,
|
||||
GHOSTTY_KEY_BRACKET_RIGHT,
|
||||
GHOSTTY_KEY_COMMA,
|
||||
GHOSTTY_KEY_DIGIT_0,
|
||||
GHOSTTY_KEY_DIGIT_1,
|
||||
GHOSTTY_KEY_DIGIT_2,
|
||||
GHOSTTY_KEY_DIGIT_3,
|
||||
GHOSTTY_KEY_DIGIT_4,
|
||||
GHOSTTY_KEY_DIGIT_5,
|
||||
GHOSTTY_KEY_DIGIT_6,
|
||||
GHOSTTY_KEY_DIGIT_7,
|
||||
GHOSTTY_KEY_DIGIT_8,
|
||||
GHOSTTY_KEY_DIGIT_9,
|
||||
GHOSTTY_KEY_EQUAL,
|
||||
GHOSTTY_KEY_INTL_BACKSLASH,
|
||||
GHOSTTY_KEY_INTL_RO,
|
||||
GHOSTTY_KEY_INTL_YEN,
|
||||
GHOSTTY_KEY_A,
|
||||
GHOSTTY_KEY_B,
|
||||
GHOSTTY_KEY_C,
|
||||
GHOSTTY_KEY_D,
|
||||
GHOSTTY_KEY_E,
|
||||
GHOSTTY_KEY_F,
|
||||
GHOSTTY_KEY_G,
|
||||
GHOSTTY_KEY_H,
|
||||
GHOSTTY_KEY_I,
|
||||
GHOSTTY_KEY_J,
|
||||
GHOSTTY_KEY_K,
|
||||
GHOSTTY_KEY_L,
|
||||
GHOSTTY_KEY_M,
|
||||
GHOSTTY_KEY_N,
|
||||
GHOSTTY_KEY_O,
|
||||
GHOSTTY_KEY_P,
|
||||
GHOSTTY_KEY_Q,
|
||||
GHOSTTY_KEY_R,
|
||||
GHOSTTY_KEY_S,
|
||||
GHOSTTY_KEY_T,
|
||||
GHOSTTY_KEY_U,
|
||||
GHOSTTY_KEY_V,
|
||||
GHOSTTY_KEY_W,
|
||||
GHOSTTY_KEY_X,
|
||||
GHOSTTY_KEY_Y,
|
||||
GHOSTTY_KEY_Z,
|
||||
GHOSTTY_KEY_MINUS,
|
||||
GHOSTTY_KEY_PERIOD,
|
||||
GHOSTTY_KEY_QUOTE,
|
||||
GHOSTTY_KEY_SEMICOLON,
|
||||
GHOSTTY_KEY_SLASH,
|
||||
|
||||
// Functional Keys (W3C § 3.1.2)
|
||||
GHOSTTY_KEY_ALT_LEFT,
|
||||
GHOSTTY_KEY_ALT_RIGHT,
|
||||
GHOSTTY_KEY_BACKSPACE,
|
||||
GHOSTTY_KEY_CAPS_LOCK,
|
||||
GHOSTTY_KEY_CONTEXT_MENU,
|
||||
GHOSTTY_KEY_CONTROL_LEFT,
|
||||
GHOSTTY_KEY_CONTROL_RIGHT,
|
||||
GHOSTTY_KEY_ENTER,
|
||||
GHOSTTY_KEY_META_LEFT,
|
||||
GHOSTTY_KEY_META_RIGHT,
|
||||
GHOSTTY_KEY_SHIFT_LEFT,
|
||||
GHOSTTY_KEY_SHIFT_RIGHT,
|
||||
GHOSTTY_KEY_SPACE,
|
||||
GHOSTTY_KEY_TAB,
|
||||
GHOSTTY_KEY_CONVERT,
|
||||
GHOSTTY_KEY_KANA_MODE,
|
||||
GHOSTTY_KEY_NON_CONVERT,
|
||||
|
||||
// Control Pad Section (W3C § 3.2)
|
||||
GHOSTTY_KEY_DELETE,
|
||||
GHOSTTY_KEY_END,
|
||||
GHOSTTY_KEY_HELP,
|
||||
GHOSTTY_KEY_HOME,
|
||||
GHOSTTY_KEY_INSERT,
|
||||
GHOSTTY_KEY_PAGE_DOWN,
|
||||
GHOSTTY_KEY_PAGE_UP,
|
||||
|
||||
// Arrow Pad Section (W3C § 3.3)
|
||||
GHOSTTY_KEY_ARROW_DOWN,
|
||||
GHOSTTY_KEY_ARROW_LEFT,
|
||||
GHOSTTY_KEY_ARROW_RIGHT,
|
||||
GHOSTTY_KEY_ARROW_UP,
|
||||
|
||||
// Numpad Section (W3C § 3.4)
|
||||
GHOSTTY_KEY_NUM_LOCK,
|
||||
GHOSTTY_KEY_NUMPAD_0,
|
||||
GHOSTTY_KEY_NUMPAD_1,
|
||||
GHOSTTY_KEY_NUMPAD_2,
|
||||
GHOSTTY_KEY_NUMPAD_3,
|
||||
GHOSTTY_KEY_NUMPAD_4,
|
||||
GHOSTTY_KEY_NUMPAD_5,
|
||||
GHOSTTY_KEY_NUMPAD_6,
|
||||
GHOSTTY_KEY_NUMPAD_7,
|
||||
GHOSTTY_KEY_NUMPAD_8,
|
||||
GHOSTTY_KEY_NUMPAD_9,
|
||||
GHOSTTY_KEY_NUMPAD_ADD,
|
||||
GHOSTTY_KEY_NUMPAD_BACKSPACE,
|
||||
GHOSTTY_KEY_NUMPAD_CLEAR,
|
||||
GHOSTTY_KEY_NUMPAD_CLEAR_ENTRY,
|
||||
GHOSTTY_KEY_NUMPAD_COMMA,
|
||||
GHOSTTY_KEY_NUMPAD_DECIMAL,
|
||||
GHOSTTY_KEY_NUMPAD_DIVIDE,
|
||||
GHOSTTY_KEY_NUMPAD_ENTER,
|
||||
GHOSTTY_KEY_NUMPAD_EQUAL,
|
||||
GHOSTTY_KEY_NUMPAD_MEMORY_ADD,
|
||||
GHOSTTY_KEY_NUMPAD_MEMORY_CLEAR,
|
||||
GHOSTTY_KEY_NUMPAD_MEMORY_RECALL,
|
||||
GHOSTTY_KEY_NUMPAD_MEMORY_STORE,
|
||||
GHOSTTY_KEY_NUMPAD_MEMORY_SUBTRACT,
|
||||
GHOSTTY_KEY_NUMPAD_MULTIPLY,
|
||||
GHOSTTY_KEY_NUMPAD_PAREN_LEFT,
|
||||
GHOSTTY_KEY_NUMPAD_PAREN_RIGHT,
|
||||
GHOSTTY_KEY_NUMPAD_SUBTRACT,
|
||||
GHOSTTY_KEY_NUMPAD_SEPARATOR,
|
||||
GHOSTTY_KEY_NUMPAD_UP,
|
||||
GHOSTTY_KEY_NUMPAD_DOWN,
|
||||
GHOSTTY_KEY_NUMPAD_RIGHT,
|
||||
GHOSTTY_KEY_NUMPAD_LEFT,
|
||||
GHOSTTY_KEY_NUMPAD_BEGIN,
|
||||
GHOSTTY_KEY_NUMPAD_HOME,
|
||||
GHOSTTY_KEY_NUMPAD_END,
|
||||
GHOSTTY_KEY_NUMPAD_INSERT,
|
||||
GHOSTTY_KEY_NUMPAD_DELETE,
|
||||
GHOSTTY_KEY_NUMPAD_PAGE_UP,
|
||||
GHOSTTY_KEY_NUMPAD_PAGE_DOWN,
|
||||
|
||||
// Function Section (W3C § 3.5)
|
||||
GHOSTTY_KEY_ESCAPE,
|
||||
GHOSTTY_KEY_F1,
|
||||
GHOSTTY_KEY_F2,
|
||||
GHOSTTY_KEY_F3,
|
||||
GHOSTTY_KEY_F4,
|
||||
GHOSTTY_KEY_F5,
|
||||
GHOSTTY_KEY_F6,
|
||||
GHOSTTY_KEY_F7,
|
||||
GHOSTTY_KEY_F8,
|
||||
GHOSTTY_KEY_F9,
|
||||
GHOSTTY_KEY_F10,
|
||||
GHOSTTY_KEY_F11,
|
||||
GHOSTTY_KEY_F12,
|
||||
GHOSTTY_KEY_F13,
|
||||
GHOSTTY_KEY_F14,
|
||||
GHOSTTY_KEY_F15,
|
||||
GHOSTTY_KEY_F16,
|
||||
GHOSTTY_KEY_F17,
|
||||
GHOSTTY_KEY_F18,
|
||||
GHOSTTY_KEY_F19,
|
||||
GHOSTTY_KEY_F20,
|
||||
GHOSTTY_KEY_F21,
|
||||
GHOSTTY_KEY_F22,
|
||||
GHOSTTY_KEY_F23,
|
||||
GHOSTTY_KEY_F24,
|
||||
GHOSTTY_KEY_F25,
|
||||
GHOSTTY_KEY_FN,
|
||||
GHOSTTY_KEY_FN_LOCK,
|
||||
GHOSTTY_KEY_PRINT_SCREEN,
|
||||
GHOSTTY_KEY_SCROLL_LOCK,
|
||||
GHOSTTY_KEY_PAUSE,
|
||||
|
||||
// Media Keys (W3C § 3.6)
|
||||
GHOSTTY_KEY_BROWSER_BACK,
|
||||
GHOSTTY_KEY_BROWSER_FAVORITES,
|
||||
GHOSTTY_KEY_BROWSER_FORWARD,
|
||||
GHOSTTY_KEY_BROWSER_HOME,
|
||||
GHOSTTY_KEY_BROWSER_REFRESH,
|
||||
GHOSTTY_KEY_BROWSER_SEARCH,
|
||||
GHOSTTY_KEY_BROWSER_STOP,
|
||||
GHOSTTY_KEY_EJECT,
|
||||
GHOSTTY_KEY_LAUNCH_APP_1,
|
||||
GHOSTTY_KEY_LAUNCH_APP_2,
|
||||
GHOSTTY_KEY_LAUNCH_MAIL,
|
||||
GHOSTTY_KEY_MEDIA_PLAY_PAUSE,
|
||||
GHOSTTY_KEY_MEDIA_SELECT,
|
||||
GHOSTTY_KEY_MEDIA_STOP,
|
||||
GHOSTTY_KEY_MEDIA_TRACK_NEXT,
|
||||
GHOSTTY_KEY_MEDIA_TRACK_PREVIOUS,
|
||||
GHOSTTY_KEY_POWER,
|
||||
GHOSTTY_KEY_SLEEP,
|
||||
GHOSTTY_KEY_AUDIO_VOLUME_DOWN,
|
||||
GHOSTTY_KEY_AUDIO_VOLUME_MUTE,
|
||||
GHOSTTY_KEY_AUDIO_VOLUME_UP,
|
||||
GHOSTTY_KEY_WAKE_UP,
|
||||
|
||||
// Legacy, Non-standard, and Special Keys (W3C § 3.7)
|
||||
GHOSTTY_KEY_COPY,
|
||||
GHOSTTY_KEY_CUT,
|
||||
GHOSTTY_KEY_PASTE,
|
||||
GHOSTTY_KEY_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKey;
|
||||
|
||||
/**
|
||||
* Create a new key event instance.
|
||||
*
|
||||
* Creates a new key event with default values. The event must be freed using
|
||||
* ghostty_key_event_free() when no longer needed.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator
|
||||
* @param event Pointer to store the created key event handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_key_event_new(const GhosttyAllocator *allocator, GhosttyKeyEvent *event);
|
||||
|
||||
/**
|
||||
* Free a key event instance.
|
||||
*
|
||||
* Releases all resources associated with the key event. After this call,
|
||||
* the event handle becomes invalid and must not be used.
|
||||
*
|
||||
* @param event The key event handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_free(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the key action (press, release, repeat).
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param action The action to set
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_action(GhosttyKeyEvent event, GhosttyKeyAction action);
|
||||
|
||||
/**
|
||||
* Get the key action (press, release, repeat).
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return The key action
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyKeyAction ghostty_key_event_get_action(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the physical key code.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param key The physical key code to set
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_key(GhosttyKeyEvent event, GhosttyKey key);
|
||||
|
||||
/**
|
||||
* Get the physical key code.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return The physical key code
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyKey ghostty_key_event_get_key(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the modifier keys bitmask.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param mods The modifier keys bitmask to set
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_mods(GhosttyKeyEvent event, GhosttyMods mods);
|
||||
|
||||
/**
|
||||
* Get the modifier keys bitmask.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return The modifier keys bitmask
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyMods ghostty_key_event_get_mods(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the consumed modifiers bitmask.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param consumed_mods The consumed modifiers bitmask to set
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_consumed_mods(GhosttyKeyEvent event, GhosttyMods consumed_mods);
|
||||
|
||||
/**
|
||||
* Get the consumed modifiers bitmask.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return The consumed modifiers bitmask
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API GhosttyMods ghostty_key_event_get_consumed_mods(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set whether the key event is part of a composition sequence.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param composing Whether the key event is part of a composition sequence
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_composing(GhosttyKeyEvent event, bool composing);
|
||||
|
||||
/**
|
||||
* Get whether the key event is part of a composition sequence.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return Whether the key event is part of a composition sequence
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_key_event_get_composing(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the UTF-8 text generated by the key for the current keyboard layout.
|
||||
*
|
||||
* Must contain the unmodified character before any Ctrl/Meta transformations.
|
||||
* The encoder derives modifier sequences from the logical key and mods
|
||||
* bitmask, not from this text. Do not pass C0 control characters
|
||||
* (U+0000-U+001F, U+007F) or platform function key codes (e.g. macOS PUA
|
||||
* U+F700-U+F8FF); pass NULL instead and let the encoder use the logical key.
|
||||
*
|
||||
* The key event does NOT take ownership of the text pointer. The caller
|
||||
* must ensure the string remains valid for the lifetime needed by the event.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param utf8 The UTF-8 text to set (or NULL for empty)
|
||||
* @param len Length of the UTF-8 text in bytes
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_utf8(GhosttyKeyEvent event, const char *utf8, size_t len);
|
||||
|
||||
/**
|
||||
* Get the UTF-8 text generated by the key event.
|
||||
*
|
||||
* The returned pointer is valid until the event is freed or the UTF-8 text is modified.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param len Pointer to store the length of the UTF-8 text in bytes (may be NULL)
|
||||
* @return The UTF-8 text (or NULL for empty)
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API const char *ghostty_key_event_get_utf8(GhosttyKeyEvent event, size_t *len);
|
||||
|
||||
/**
|
||||
* Set the unshifted Unicode codepoint.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @param codepoint The unshifted Unicode codepoint to set
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API void ghostty_key_event_set_unshifted_codepoint(GhosttyKeyEvent event, uint32_t codepoint);
|
||||
|
||||
/**
|
||||
* Get the unshifted Unicode codepoint.
|
||||
*
|
||||
* @param event The key event handle, must not be NULL
|
||||
* @return The unshifted Unicode codepoint
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
GHOSTTY_API uint32_t ghostty_key_event_get_unshifted_codepoint(GhosttyKeyEvent event);
|
||||
|
||||
#endif /* GHOSTTY_VT_KEY_EVENT_H */
|
||||
@@ -0,0 +1,859 @@
|
||||
/**
|
||||
* @file kitty_graphics.h
|
||||
*
|
||||
* Kitty graphics protocol
|
||||
*
|
||||
* See @ref kitty_graphics for a full usage guide.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_KITTY_GRAPHICS_H
|
||||
#define GHOSTTY_VT_KITTY_GRAPHICS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/selection.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup kitty_graphics Kitty Graphics
|
||||
*
|
||||
* API for inspecting images and placements stored via the
|
||||
* [Kitty graphics protocol](https://sw.kovidgoyal.net/kitty/graphics-protocol/).
|
||||
*
|
||||
* The central object is @ref GhosttyKittyGraphics, an opaque handle to
|
||||
* the image storage associated with a terminal's active screen. From it
|
||||
* you can iterate over placements and look up individual images.
|
||||
*
|
||||
* ## Obtaining a KittyGraphics Handle
|
||||
*
|
||||
* A @ref GhosttyKittyGraphics handle is obtained from a terminal via
|
||||
* ghostty_terminal_get() with @ref GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS.
|
||||
* The handle is borrowed from the terminal and remains valid until the
|
||||
* next mutating terminal call (e.g. ghostty_terminal_vt_write() or
|
||||
* ghostty_terminal_reset()).
|
||||
*
|
||||
* Before images can be stored, Kitty graphics must be enabled on the
|
||||
* terminal by setting a non-zero storage limit with
|
||||
* @ref GHOSTTY_TERMINAL_OPT_KITTY_IMAGE_STORAGE_LIMIT, and a PNG
|
||||
* decoder callback must be installed via ghostty_sys_set() with
|
||||
* @ref GHOSTTY_SYS_OPT_DECODE_PNG.
|
||||
*
|
||||
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-decode-png
|
||||
*
|
||||
* ## Iterating Placements
|
||||
*
|
||||
* Placements are inspected through a @ref GhosttyKittyGraphicsPlacementIterator.
|
||||
* The typical workflow is:
|
||||
*
|
||||
* 1. Create an iterator with ghostty_kitty_graphics_placement_iterator_new().
|
||||
* 2. Populate it from the storage with ghostty_kitty_graphics_get() using
|
||||
* @ref GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR.
|
||||
* 3. Optionally filter by z-layer with
|
||||
* ghostty_kitty_graphics_placement_iterator_set().
|
||||
* 4. Advance with ghostty_kitty_graphics_placement_next() and read
|
||||
* per-placement data with ghostty_kitty_graphics_placement_get().
|
||||
* 5. For each placement, look up its image with
|
||||
* ghostty_kitty_graphics_image() to access pixel data and dimensions.
|
||||
* 6. Free the iterator with ghostty_kitty_graphics_placement_iterator_free().
|
||||
*
|
||||
* ## Looking Up Images
|
||||
*
|
||||
* Given an image ID (obtained from a placement via
|
||||
* @ref GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID), call
|
||||
* ghostty_kitty_graphics_image() to get a @ref GhosttyKittyGraphicsImage
|
||||
* handle. From this handle, ghostty_kitty_graphics_image_get() provides
|
||||
* the image dimensions, pixel format, compression, and a borrowed pointer
|
||||
* to the raw pixel data.
|
||||
*
|
||||
* ## Rendering Helpers
|
||||
*
|
||||
* Several functions assist with rendering a placement:
|
||||
*
|
||||
* - ghostty_kitty_graphics_placement_pixel_size() — rendered pixel
|
||||
* dimensions accounting for source rect and aspect ratio.
|
||||
* - ghostty_kitty_graphics_placement_grid_size() — number of grid
|
||||
* columns and rows the placement occupies.
|
||||
* - ghostty_kitty_graphics_placement_viewport_pos() — viewport-relative
|
||||
* grid position (may be negative for partially scrolled placements).
|
||||
* - ghostty_kitty_graphics_placement_source_rect() — resolved source
|
||||
* rectangle in pixels, clamped to image bounds.
|
||||
* - ghostty_kitty_graphics_placement_rect() — bounding rectangle as a
|
||||
* @ref GhosttySelection.
|
||||
*
|
||||
* ## Change Detection
|
||||
*
|
||||
* Generation stamps allow renderers to cheaply detect whether Kitty
|
||||
* graphics state changed between frames:
|
||||
*
|
||||
* - @ref GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION is a storage-wide stamp
|
||||
* updated on any transmit, placement, or delete. If unchanged, the
|
||||
* placement set and all image data are identical and both placement
|
||||
* snapshots and per-image staleness checks can be skipped. Placement
|
||||
* geometry can still change independently (scrolling moves
|
||||
* placements), so ghostty_kitty_graphics_placement_render_info()
|
||||
* should still be recomputed on dirty frames.
|
||||
* - @ref GHOSTTY_KITTY_IMAGE_DATA_GENERATION is a per-image stamp
|
||||
* changed on every add/replace of that image ID. Texture caches
|
||||
* should treat a cached texture as stale when this differs from the
|
||||
* cached value; dimension/length heuristics cannot detect a
|
||||
* same-sized retransmission.
|
||||
*
|
||||
* Stamps are unique and monotonically increasing process-wide, so
|
||||
* caches keyed on a generation value never alias across screens
|
||||
* (main/alternate), resets, or terminals.
|
||||
*
|
||||
* ## Lifetime and Thread Safety
|
||||
*
|
||||
* All handles borrowed from the terminal (GhosttyKittyGraphics,
|
||||
* GhosttyKittyGraphicsImage) are invalidated by any mutating terminal
|
||||
* call. The placement iterator is independently owned and must be freed
|
||||
* by the caller, but the data it yields is only valid while the
|
||||
* underlying terminal is not mutated.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* The following example creates a terminal, sends a Kitty graphics
|
||||
* image, then iterates placements and prints image metadata:
|
||||
*
|
||||
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-main
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_kitty_graphics_get().
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_KITTY_GRAPHICS_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* Populate a pre-allocated placement iterator with placement data from
|
||||
* the storage. Iterator data is only valid as long as the underlying
|
||||
* terminal is not mutated.
|
||||
*
|
||||
* Output type: GhosttyKittyGraphicsPlacementIterator *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR = 1,
|
||||
|
||||
/**
|
||||
* Generation stamp of the last content mutation to this storage:
|
||||
* any image transmit/replace, placement add, or delete. Zero means
|
||||
* the storage has never been mutated (and is therefore empty).
|
||||
*
|
||||
* If the generation is unchanged since a previous query, the set of
|
||||
* placements and all image data are identical, so placement iteration
|
||||
* and image staleness checks can be skipped entirely. Note that
|
||||
* placement *geometry* may still have changed (scrolling and resizing
|
||||
* move placements without changing the storage contents), so rendering
|
||||
* geometry such as ghostty_kitty_graphics_placement_render_info()
|
||||
* must still be recomputed for frames marked dirty.
|
||||
*
|
||||
* Stamps are unique and monotonically increasing process-wide: a
|
||||
* value observed from any storage never recurs for different content,
|
||||
* even across screen switches (main vs. alternate screen have
|
||||
* independent storages) or terminal resets. It is therefore safe to
|
||||
* key caches on this value alone.
|
||||
*
|
||||
* Output type: uint64_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION = 2,
|
||||
GHOSTTY_KITTY_GRAPHICS_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyGraphicsData;
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_kitty_graphics_placement_get().
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* The image ID this placement belongs to.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IMAGE_ID = 1,
|
||||
|
||||
/**
|
||||
* The placement ID.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_PLACEMENT_ID = 2,
|
||||
|
||||
/**
|
||||
* Whether this is a virtual placement (unicode placeholder).
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_IS_VIRTUAL = 3,
|
||||
|
||||
/**
|
||||
* Pixel offset from the left edge of the cell.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_X_OFFSET = 4,
|
||||
|
||||
/**
|
||||
* Pixel offset from the top edge of the cell.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Y_OFFSET = 5,
|
||||
|
||||
/**
|
||||
* Source rectangle x origin in pixels.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_X = 6,
|
||||
|
||||
/**
|
||||
* Source rectangle y origin in pixels.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_Y = 7,
|
||||
|
||||
/**
|
||||
* Source rectangle width in pixels (0 = full image width).
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_WIDTH = 8,
|
||||
|
||||
/**
|
||||
* Source rectangle height in pixels (0 = full image height).
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_SOURCE_HEIGHT = 9,
|
||||
|
||||
/**
|
||||
* Number of columns this placement occupies.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_COLUMNS = 10,
|
||||
|
||||
/**
|
||||
* Number of rows this placement occupies.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_ROWS = 11,
|
||||
|
||||
/**
|
||||
* Z-index for this placement.
|
||||
*
|
||||
* Output type: int32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_Z = 12,
|
||||
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyGraphicsPlacementData;
|
||||
|
||||
/**
|
||||
* Z-layer classification for kitty graphics placements.
|
||||
*
|
||||
* Based on the kitty protocol z-index conventions:
|
||||
* - BELOW_BG: z < INT32_MIN/2 (drawn below cell background)
|
||||
* - BELOW_TEXT: INT32_MIN/2 <= z < 0 (above background, below text)
|
||||
* - ABOVE_TEXT: z >= 0 (above text)
|
||||
* - ALL: no filtering (current behavior)
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_KITTY_PLACEMENT_LAYER_ALL = 0,
|
||||
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1,
|
||||
GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2,
|
||||
GHOSTTY_KITTY_PLACEMENT_LAYER_ABOVE_TEXT = 3,
|
||||
GHOSTTY_KITTY_PLACEMENT_LAYER_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyPlacementLayer;
|
||||
|
||||
/**
|
||||
* Settable options for ghostty_kitty_graphics_placement_iterator_set().
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/**
|
||||
* Set the z-layer filter for the iterator.
|
||||
*
|
||||
* Input type: GhosttyKittyPlacementLayer *
|
||||
*/
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER = 0,
|
||||
GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyGraphicsPlacementIteratorOption;
|
||||
|
||||
/**
|
||||
* Pixel format of a Kitty graphics image.
|
||||
*
|
||||
* Note that stored images are always fully decoded:
|
||||
* GHOSTTY_KITTY_IMAGE_FORMAT_PNG is never returned by
|
||||
* ghostty_kitty_graphics_image_get() because PNG payloads are decoded
|
||||
* to GHOSTTY_KITTY_IMAGE_FORMAT_RGBA before storage. The PNG value
|
||||
* exists only for protocol-level completeness.
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_RGB = 0,
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_RGBA = 1,
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2,
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_GRAY_ALPHA = 3,
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_GRAY = 4,
|
||||
GHOSTTY_KITTY_IMAGE_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyImageFormat;
|
||||
|
||||
/**
|
||||
* Compression of a Kitty graphics image.
|
||||
*
|
||||
* Note that stored images are always decompressed:
|
||||
* GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE payloads are inflated
|
||||
* before storage, so ghostty_kitty_graphics_image_get() always reports
|
||||
* GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE. Consumers never need to
|
||||
* inflate image data themselves.
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0,
|
||||
GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1,
|
||||
GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyImageCompression;
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_kitty_graphics_image_get().
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_KITTY_IMAGE_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* The image ID.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_ID = 1,
|
||||
|
||||
/**
|
||||
* The image number.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_NUMBER = 2,
|
||||
|
||||
/**
|
||||
* Image width in pixels.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_WIDTH = 3,
|
||||
|
||||
/**
|
||||
* Image height in pixels.
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_HEIGHT = 4,
|
||||
|
||||
/**
|
||||
* Pixel format of the image. Never GHOSTTY_KITTY_IMAGE_FORMAT_PNG;
|
||||
* PNG payloads are decoded to RGBA before storage.
|
||||
*
|
||||
* Output type: GhosttyKittyImageFormat *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_FORMAT = 5,
|
||||
|
||||
/**
|
||||
* Compression of the image. Always
|
||||
* GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE; compressed payloads are
|
||||
* inflated before storage.
|
||||
*
|
||||
* Output type: GhosttyKittyImageCompression *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_COMPRESSION = 6,
|
||||
|
||||
/**
|
||||
* Borrowed pointer to the raw pixel data. Valid as long as the
|
||||
* underlying terminal is not mutated.
|
||||
*
|
||||
* The data is always fully decoded, uncompressed pixels in the
|
||||
* format reported by GHOSTTY_KITTY_IMAGE_DATA_FORMAT: zlib payloads
|
||||
* are inflated and PNG payloads are decoded to RGBA at transmission
|
||||
* time, before the image is stored. Consumers can upload this
|
||||
* directly to the GPU without any decode step.
|
||||
*
|
||||
* Output type: const uint8_t **
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_DATA_PTR = 7,
|
||||
|
||||
/**
|
||||
* Length of the raw pixel data in bytes. Always equal to
|
||||
* width * height * bytes-per-pixel for the reported format.
|
||||
*
|
||||
* Output type: size_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_DATA_LEN = 8,
|
||||
|
||||
/**
|
||||
* Generation stamp assigned when this image was added to (or
|
||||
* replaced in) the storage. A changed generation for a given image
|
||||
* ID means the pixel contents may have changed even when the
|
||||
* dimensions, format, and data length are identical (e.g. a
|
||||
* retransmission of the same image ID), so texture caches must key
|
||||
* staleness on this value rather than on size heuristics.
|
||||
*
|
||||
* Stamps are unique and monotonically increasing process-wide and
|
||||
* are drawn from the same sequence as
|
||||
* GHOSTTY_KITTY_GRAPHICS_DATA_GENERATION. Never zero for a stored
|
||||
* image, so zero can be used as an "empty" sentinel by callers.
|
||||
*
|
||||
* Output type: uint64_t *
|
||||
*/
|
||||
GHOSTTY_KITTY_IMAGE_DATA_GENERATION = 9,
|
||||
|
||||
GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyKittyGraphicsImageData;
|
||||
|
||||
/**
|
||||
* Combined rendering geometry for a placement in a single sized struct.
|
||||
*
|
||||
* Combines the results of ghostty_kitty_graphics_placement_pixel_size(),
|
||||
* ghostty_kitty_graphics_placement_grid_size(),
|
||||
* ghostty_kitty_graphics_placement_viewport_pos(), and
|
||||
* ghostty_kitty_graphics_placement_source_rect() into one call. This is
|
||||
* an optimization over calling those four functions individually,
|
||||
* particularly useful in environments with high per-call overhead such
|
||||
* as FFI or Cgo.
|
||||
*
|
||||
* This struct uses the sized-struct ABI pattern. Initialize with
|
||||
* GHOSTTY_INIT_SIZED(GhosttyKittyGraphicsPlacementRenderInfo) before calling
|
||||
* ghostty_kitty_graphics_placement_render_info().
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyKittyGraphicsPlacementRenderInfo). */
|
||||
size_t size;
|
||||
/** Rendered width in pixels. */
|
||||
uint32_t pixel_width;
|
||||
/** Rendered height in pixels. */
|
||||
uint32_t pixel_height;
|
||||
/** Number of grid columns the placement occupies. */
|
||||
uint32_t grid_cols;
|
||||
/** Number of grid rows the placement occupies. */
|
||||
uint32_t grid_rows;
|
||||
/** Viewport-relative column (may be negative for partially visible placements). */
|
||||
int32_t viewport_col;
|
||||
/** Viewport-relative row (may be negative for partially visible placements). */
|
||||
int32_t viewport_row;
|
||||
/** False when the placement is fully off-screen or virtual. */
|
||||
bool viewport_visible;
|
||||
/** Resolved source rectangle x origin in pixels. */
|
||||
uint32_t source_x;
|
||||
/** Resolved source rectangle y origin in pixels. */
|
||||
uint32_t source_y;
|
||||
/** Resolved source rectangle width in pixels. */
|
||||
uint32_t source_width;
|
||||
/** Resolved source rectangle height in pixels. */
|
||||
uint32_t source_height;
|
||||
} GhosttyKittyGraphicsPlacementRenderInfo;
|
||||
|
||||
/**
|
||||
* Get data from a kitty graphics storage instance.
|
||||
*
|
||||
* The output pointer must be of the appropriate type for the requested
|
||||
* data kind.
|
||||
*
|
||||
* Returns GHOSTTY_NO_VALUE when Kitty graphics are disabled at build time.
|
||||
*
|
||||
* @param graphics The kitty graphics handle
|
||||
* @param data The type of data to extract
|
||||
* @param[out] out Pointer to store the extracted data
|
||||
* @return GHOSTTY_SUCCESS on success
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_get(
|
||||
GhosttyKittyGraphics graphics,
|
||||
GhosttyKittyGraphicsData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Look up a Kitty graphics image by its image ID.
|
||||
*
|
||||
* Returns NULL if no image with the given ID exists or if Kitty graphics
|
||||
* are disabled at build time.
|
||||
*
|
||||
* @param graphics The kitty graphics handle
|
||||
* @param image_id The image ID to look up
|
||||
* @return An opaque image handle, or NULL if not found
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyKittyGraphicsImage ghostty_kitty_graphics_image(
|
||||
GhosttyKittyGraphics graphics,
|
||||
uint32_t image_id);
|
||||
|
||||
/**
|
||||
* Get data from a Kitty graphics image.
|
||||
*
|
||||
* The output pointer must be of the appropriate type for the requested
|
||||
* data kind.
|
||||
*
|
||||
* @param image The image handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param data The data kind to query
|
||||
* @param[out] out Pointer to receive the queried value
|
||||
* @return GHOSTTY_SUCCESS on success
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get(
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyKittyGraphicsImageData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from a Kitty graphics image in a single call.
|
||||
*
|
||||
* This is an optimization over calling ghostty_kitty_graphics_image_get()
|
||||
* repeatedly, particularly useful in environments with high per-call
|
||||
* overhead such as FFI or Cgo.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
* The type of each values[i] pointer must match the output type
|
||||
* documented for keys[i].
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param image The image handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_image_get_multi(
|
||||
GhosttyKittyGraphicsImage image,
|
||||
size_t count,
|
||||
const GhosttyKittyGraphicsImageData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Create a new placement iterator instance.
|
||||
*
|
||||
* All fields except the allocator are left undefined until populated
|
||||
* via ghostty_kitty_graphics_get() with
|
||||
* GHOSTTY_KITTY_GRAPHICS_DATA_PLACEMENT_ITERATOR.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param[out] out_iterator On success, receives the created iterator handle
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
|
||||
* failure
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_new(
|
||||
const GhosttyAllocator* allocator,
|
||||
GhosttyKittyGraphicsPlacementIterator* out_iterator);
|
||||
|
||||
/**
|
||||
* Free a placement iterator.
|
||||
*
|
||||
* @param iterator The iterator handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API void ghostty_kitty_graphics_placement_iterator_free(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator);
|
||||
|
||||
/**
|
||||
* Set an option on a placement iterator.
|
||||
*
|
||||
* Use GHOSTTY_KITTY_GRAPHICS_PLACEMENT_ITERATOR_OPTION_LAYER with a
|
||||
* GhosttyKittyPlacementLayer value to filter placements by z-layer.
|
||||
* The filter is applied during iteration: ghostty_kitty_graphics_placement_next()
|
||||
* will skip placements that do not match the configured layer.
|
||||
*
|
||||
* The default layer is GHOSTTY_KITTY_PLACEMENT_LAYER_ALL (no filtering).
|
||||
*
|
||||
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param option The option to set
|
||||
* @param value Pointer to the value (type depends on option; NULL returns
|
||||
* GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_iterator_set(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsPlacementIteratorOption option,
|
||||
const void* value);
|
||||
|
||||
/**
|
||||
* Advance the placement iterator to the next placement.
|
||||
*
|
||||
* If a layer filter has been set via
|
||||
* ghostty_kitty_graphics_placement_iterator_set(), only placements
|
||||
* matching that layer are returned.
|
||||
*
|
||||
* @param iterator The iterator handle (may be NULL)
|
||||
* @return true if advanced to the next placement, false if at the end
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_kitty_graphics_placement_next(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator);
|
||||
|
||||
/**
|
||||
* Get data from the current placement in a placement iterator.
|
||||
*
|
||||
* Call ghostty_kitty_graphics_placement_next() at least once before
|
||||
* calling this function.
|
||||
*
|
||||
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param data The data kind to query
|
||||
* @param[out] out Pointer to receive the queried value
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
|
||||
* iterator is NULL or not positioned on a placement
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsPlacementData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from the current placement in a single call.
|
||||
*
|
||||
* This is an optimization over calling ghostty_kitty_graphics_placement_get()
|
||||
* repeatedly, particularly useful in environments with high per-call
|
||||
* overhead such as FFI or Cgo.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
* The type of each values[i] pointer must match the output type
|
||||
* documented for keys[i].
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_get_multi(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
size_t count,
|
||||
const GhosttyKittyGraphicsPlacementData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Compute the grid rectangle occupied by the current placement.
|
||||
*
|
||||
* Uses the placement's pin, the image dimensions, and the terminal's
|
||||
* cell/pixel geometry to calculate the bounding rectangle. Virtual
|
||||
* placements (unicode placeholders) return GHOSTTY_NO_VALUE.
|
||||
*
|
||||
* @param terminal The terminal handle
|
||||
* @param image The image handle for this placement's image
|
||||
* @param iterator The placement iterator positioned on a placement
|
||||
* @param[out] out_selection On success, receives the bounding rectangle
|
||||
* as a selection with rectangle=true
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
|
||||
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE for
|
||||
* virtual placements or when Kitty graphics are disabled
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_rect(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyTerminal terminal,
|
||||
GhosttySelection* out_selection);
|
||||
|
||||
/**
|
||||
* Compute the rendered pixel size of the current placement.
|
||||
*
|
||||
* Takes into account the placement's source rectangle, specified
|
||||
* columns/rows, and aspect ratio to calculate the final rendered
|
||||
* pixel dimensions.
|
||||
*
|
||||
* @param iterator The placement iterator positioned on a placement
|
||||
* @param image The image handle for this placement's image
|
||||
* @param terminal The terminal handle
|
||||
* @param[out] out_width On success, receives the width in pixels
|
||||
* @param[out] out_height On success, receives the height in pixels
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
|
||||
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when
|
||||
* Kitty graphics are disabled
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_pixel_size(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyTerminal terminal,
|
||||
uint32_t* out_width,
|
||||
uint32_t* out_height);
|
||||
|
||||
/**
|
||||
* Compute the grid cell size of the current placement.
|
||||
*
|
||||
* Returns the number of columns and rows that the placement occupies
|
||||
* in the terminal grid. If the placement specifies explicit columns
|
||||
* and rows, those are returned directly; otherwise they are calculated
|
||||
* from the pixel size and cell dimensions.
|
||||
*
|
||||
* @param iterator The placement iterator positioned on a placement
|
||||
* @param image The image handle for this placement's image
|
||||
* @param terminal The terminal handle
|
||||
* @param[out] out_cols On success, receives the number of columns
|
||||
* @param[out] out_rows On success, receives the number of rows
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any handle
|
||||
* is NULL or the iterator is not positioned, GHOSTTY_NO_VALUE when
|
||||
* Kitty graphics are disabled
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_grid_size(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyTerminal terminal,
|
||||
uint32_t* out_cols,
|
||||
uint32_t* out_rows);
|
||||
|
||||
/**
|
||||
* Get the viewport-relative grid position of the current placement.
|
||||
*
|
||||
* Converts the placement's internal pin to viewport-relative column and
|
||||
* row coordinates. The returned coordinates represent the top-left
|
||||
* corner of the placement in the viewport's grid coordinate space.
|
||||
*
|
||||
* The row value can be negative when the placement's origin has
|
||||
* scrolled above the top of the viewport. For example, a 4-row
|
||||
* image that has scrolled up by 2 rows returns row=-2, meaning
|
||||
* its top 2 rows are above the visible area but its bottom 2 rows
|
||||
* are still on screen. Embedders should use these coordinates
|
||||
* directly when computing the destination rectangle for rendering;
|
||||
* the embedder is responsible for clipping the portion of the image
|
||||
* that falls outside the viewport.
|
||||
*
|
||||
* Returns GHOSTTY_SUCCESS for any placement that is at least
|
||||
* partially visible in the viewport. Returns GHOSTTY_NO_VALUE when
|
||||
* the placement is completely outside the viewport (its bottom edge
|
||||
* is above the viewport or its top edge is at or below the last
|
||||
* viewport row), or when the placement is a virtual (unicode
|
||||
* placeholder) placement.
|
||||
*
|
||||
* @param iterator The placement iterator positioned on a placement
|
||||
* @param image The image handle for this placement's image
|
||||
* @param terminal The terminal handle
|
||||
* @param[out] out_col On success, receives the viewport-relative column
|
||||
* @param[out] out_row On success, receives the viewport-relative row
|
||||
* (may be negative for partially visible placements)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_NO_VALUE if fully
|
||||
* off-screen or virtual, GHOSTTY_INVALID_VALUE if any handle
|
||||
* is NULL or the iterator is not positioned
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_viewport_pos(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyTerminal terminal,
|
||||
int32_t* out_col,
|
||||
int32_t* out_row);
|
||||
|
||||
/**
|
||||
* Get the resolved source rectangle for the current placement.
|
||||
*
|
||||
* Applies kitty protocol semantics: a width or height of 0 in the
|
||||
* placement means "use the full image dimension", and the resulting
|
||||
* rectangle is clamped to the actual image bounds. The returned
|
||||
* values are in pixels and are ready to use for texture sampling.
|
||||
*
|
||||
* @param iterator The placement iterator positioned on a placement
|
||||
* @param image The image handle for this placement's image
|
||||
* @param[out] out_x Source rect x origin in pixels
|
||||
* @param[out] out_y Source rect y origin in pixels
|
||||
* @param[out] out_width Source rect width in pixels
|
||||
* @param[out] out_height Source rect height in pixels
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if any
|
||||
* handle is NULL or the iterator is not positioned
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_source_rect(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
uint32_t* out_x,
|
||||
uint32_t* out_y,
|
||||
uint32_t* out_width,
|
||||
uint32_t* out_height);
|
||||
|
||||
/**
|
||||
* Get all rendering geometry for a placement in a single call.
|
||||
*
|
||||
* Combines pixel size, grid size, viewport position, and source
|
||||
* rectangle into one struct. Initialize with
|
||||
* GHOSTTY_INIT_SIZED(GhosttyKittyGraphicsPlacementRenderInfo).
|
||||
*
|
||||
* When viewport_visible is false, the placement is fully off-screen
|
||||
* or is a virtual placement; viewport_col and viewport_row may
|
||||
* contain meaningless values in that case.
|
||||
*
|
||||
* @param iterator The iterator positioned on a placement
|
||||
* @param image The image handle for this placement's image
|
||||
* @param terminal The terminal handle
|
||||
* @param[out] out_info Pointer to receive the rendering geometry
|
||||
* @return GHOSTTY_SUCCESS on success
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_kitty_graphics_placement_render_info(
|
||||
GhosttyKittyGraphicsPlacementIterator iterator,
|
||||
GhosttyKittyGraphicsImage image,
|
||||
GhosttyTerminal terminal,
|
||||
GhosttyKittyGraphicsPlacementRenderInfo* out_info);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_KITTY_GRAPHICS_H */
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @file modes.h
|
||||
*
|
||||
* Terminal mode utilities - pack and unpack ANSI/DEC mode identifiers.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_MODES_H
|
||||
#define GHOSTTY_VT_MODES_H
|
||||
|
||||
/** @defgroup modes Mode Utilities
|
||||
*
|
||||
* Utilities for working with terminal modes. A mode is a compact
|
||||
* 16-bit representation of a terminal mode identifier that encodes both
|
||||
* the numeric mode value (up to 15 bits) and whether the mode is an ANSI
|
||||
* mode or a DEC private mode (?-prefixed).
|
||||
*
|
||||
* The packed layout (least-significant bit first) is:
|
||||
* - Bits 0–14: mode value (u15)
|
||||
* - Bit 15: ANSI flag (0 = DEC private mode, 1 = ANSI mode)
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-modes/src/main.c modes-pack-unpack
|
||||
*
|
||||
* ## DECRPM Report Encoding
|
||||
*
|
||||
* Use ghostty_mode_report_encode() to encode a DECRPM response into a
|
||||
* caller-provided buffer:
|
||||
*
|
||||
* @snippet c-vt-modes/src/main.c modes-decrpm
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @name ANSI Modes
|
||||
* Modes for standard ANSI modes.
|
||||
* @{
|
||||
*/
|
||||
#define GHOSTTY_MODE_KAM (ghostty_mode_new(2, true)) /**< Keyboard action (disable keyboard) */
|
||||
#define GHOSTTY_MODE_INSERT (ghostty_mode_new(4, true)) /**< Insert mode */
|
||||
#define GHOSTTY_MODE_SRM (ghostty_mode_new(12, true)) /**< Send/receive mode */
|
||||
#define GHOSTTY_MODE_LINEFEED (ghostty_mode_new(20, true)) /**< Linefeed/new line mode */
|
||||
/** @} */
|
||||
|
||||
/** @name DEC Private Modes
|
||||
* Modes for DEC private modes (?-prefixed).
|
||||
* @{
|
||||
*/
|
||||
#define GHOSTTY_MODE_DECCKM (ghostty_mode_new(1, false)) /**< Cursor keys */
|
||||
#define GHOSTTY_MODE_132_COLUMN (ghostty_mode_new(3, false)) /**< 132/80 column mode */
|
||||
#define GHOSTTY_MODE_SLOW_SCROLL (ghostty_mode_new(4, false)) /**< Slow scroll */
|
||||
#define GHOSTTY_MODE_REVERSE_COLORS (ghostty_mode_new(5, false)) /**< Reverse video */
|
||||
#define GHOSTTY_MODE_ORIGIN (ghostty_mode_new(6, false)) /**< Origin mode */
|
||||
#define GHOSTTY_MODE_WRAPAROUND (ghostty_mode_new(7, false)) /**< Auto-wrap mode */
|
||||
#define GHOSTTY_MODE_AUTOREPEAT (ghostty_mode_new(8, false)) /**< Auto-repeat keys */
|
||||
#define GHOSTTY_MODE_X10_MOUSE (ghostty_mode_new(9, false)) /**< X10 mouse reporting */
|
||||
#define GHOSTTY_MODE_CURSOR_BLINKING (ghostty_mode_new(12, false)) /**< Cursor blink */
|
||||
#define GHOSTTY_MODE_CURSOR_VISIBLE (ghostty_mode_new(25, false)) /**< Cursor visible (DECTCEM) */
|
||||
#define GHOSTTY_MODE_ENABLE_MODE_3 (ghostty_mode_new(40, false)) /**< Allow 132 column mode */
|
||||
#define GHOSTTY_MODE_REVERSE_WRAP (ghostty_mode_new(45, false)) /**< Reverse wrap */
|
||||
#define GHOSTTY_MODE_ALT_SCREEN_LEGACY (ghostty_mode_new(47, false)) /**< Alternate screen (legacy) */
|
||||
#define GHOSTTY_MODE_KEYPAD_KEYS (ghostty_mode_new(66, false)) /**< Application keypad */
|
||||
#define GHOSTTY_MODE_BACKARROW_KEY_MODE (ghostty_mode_new(67, false)) /**< Backarrow key mode (DECBKM) */
|
||||
#define GHOSTTY_MODE_LEFT_RIGHT_MARGIN (ghostty_mode_new(69, false)) /**< Left/right margin mode */
|
||||
#define GHOSTTY_MODE_NORMAL_MOUSE (ghostty_mode_new(1000, false)) /**< Normal mouse tracking */
|
||||
#define GHOSTTY_MODE_BUTTON_MOUSE (ghostty_mode_new(1002, false)) /**< Button-event mouse tracking */
|
||||
#define GHOSTTY_MODE_ANY_MOUSE (ghostty_mode_new(1003, false)) /**< Any-event mouse tracking */
|
||||
#define GHOSTTY_MODE_FOCUS_EVENT (ghostty_mode_new(1004, false)) /**< Focus in/out events */
|
||||
#define GHOSTTY_MODE_UTF8_MOUSE (ghostty_mode_new(1005, false)) /**< UTF-8 mouse format */
|
||||
#define GHOSTTY_MODE_SGR_MOUSE (ghostty_mode_new(1006, false)) /**< SGR mouse format */
|
||||
#define GHOSTTY_MODE_ALT_SCROLL (ghostty_mode_new(1007, false)) /**< Alternate scroll mode */
|
||||
#define GHOSTTY_MODE_URXVT_MOUSE (ghostty_mode_new(1015, false)) /**< URxvt mouse format */
|
||||
#define GHOSTTY_MODE_SGR_PIXELS_MOUSE (ghostty_mode_new(1016, false)) /**< SGR-Pixels mouse format */
|
||||
#define GHOSTTY_MODE_NUMLOCK_KEYPAD (ghostty_mode_new(1035, false)) /**< Ignore keypad with NumLock */
|
||||
#define GHOSTTY_MODE_ALT_ESC_PREFIX (ghostty_mode_new(1036, false)) /**< Alt key sends ESC prefix */
|
||||
#define GHOSTTY_MODE_ALT_SENDS_ESC (ghostty_mode_new(1039, false)) /**< Alt sends escape */
|
||||
#define GHOSTTY_MODE_REVERSE_WRAP_EXT (ghostty_mode_new(1045, false)) /**< Extended reverse wrap */
|
||||
#define GHOSTTY_MODE_ALT_SCREEN (ghostty_mode_new(1047, false)) /**< Alternate screen */
|
||||
#define GHOSTTY_MODE_SAVE_CURSOR (ghostty_mode_new(1048, false)) /**< Save cursor (DECSC) */
|
||||
#define GHOSTTY_MODE_ALT_SCREEN_SAVE (ghostty_mode_new(1049, false)) /**< Alt screen + save cursor + clear */
|
||||
#define GHOSTTY_MODE_BRACKETED_PASTE (ghostty_mode_new(2004, false)) /**< Bracketed paste mode */
|
||||
#define GHOSTTY_MODE_SYNC_OUTPUT (ghostty_mode_new(2026, false)) /**< Synchronized output */
|
||||
#define GHOSTTY_MODE_GRAPHEME_CLUSTER (ghostty_mode_new(2027, false)) /**< Grapheme cluster mode */
|
||||
#define GHOSTTY_MODE_COLOR_SCHEME_REPORT (ghostty_mode_new(2031, false)) /**< Report color scheme */
|
||||
#define GHOSTTY_MODE_IN_BAND_RESIZE (ghostty_mode_new(2048, false)) /**< In-band size reports */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* A packed 16-bit terminal mode.
|
||||
*
|
||||
* Encodes a mode value (bits 0–14) and an ANSI flag (bit 15) into a
|
||||
* single 16-bit integer. Use the inline helper functions to construct
|
||||
* and inspect modes rather than manipulating bits directly.
|
||||
*/
|
||||
typedef uint16_t GhosttyMode;
|
||||
|
||||
/**
|
||||
* Create a mode from a mode value and ANSI flag.
|
||||
*
|
||||
* @param value The numeric mode value (0–32767)
|
||||
* @param ansi true for an ANSI mode, false for a DEC private mode
|
||||
* @return The packed mode
|
||||
*
|
||||
* @ingroup modes
|
||||
*/
|
||||
static inline GhosttyMode ghostty_mode_new(uint16_t value, bool ansi) {
|
||||
return (GhosttyMode)((value & 0x7FFF) | ((uint16_t)ansi << 15));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the numeric mode value from a mode.
|
||||
*
|
||||
* @param mode The mode
|
||||
* @return The mode value (0–32767)
|
||||
*
|
||||
* @ingroup modes
|
||||
*/
|
||||
static inline uint16_t ghostty_mode_value(GhosttyMode mode) {
|
||||
return mode & 0x7FFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a mode represents an ANSI mode.
|
||||
*
|
||||
* @param mode The mode
|
||||
* @return true if this is an ANSI mode, false if it is a DEC private mode
|
||||
*
|
||||
* @ingroup modes
|
||||
*/
|
||||
static inline bool ghostty_mode_ansi(GhosttyMode mode) {
|
||||
return (mode >> 15) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DECRPM report state values.
|
||||
*
|
||||
* These correspond to the Ps2 parameter in a DECRPM response
|
||||
* sequence (CSI ? Ps1 ; Ps2 $ y).
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Mode is not recognized */
|
||||
GHOSTTY_MODE_REPORT_NOT_RECOGNIZED = 0,
|
||||
/** Mode is set (enabled) */
|
||||
GHOSTTY_MODE_REPORT_SET = 1,
|
||||
/** Mode is reset (disabled) */
|
||||
GHOSTTY_MODE_REPORT_RESET = 2,
|
||||
/** Mode is permanently set */
|
||||
GHOSTTY_MODE_REPORT_PERMANENTLY_SET = 3,
|
||||
/** Mode is permanently reset */
|
||||
GHOSTTY_MODE_REPORT_PERMANENTLY_RESET = 4,
|
||||
GHOSTTY_MODE_REPORT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyModeReportState;
|
||||
|
||||
/**
|
||||
* Encode a DECRPM (DEC Private Mode Report) response sequence.
|
||||
*
|
||||
* Writes a mode report escape sequence into the provided buffer.
|
||||
* The generated sequence has the form:
|
||||
* - DEC private mode: CSI ? Ps1 ; Ps2 $ y
|
||||
* - ANSI mode: CSI Ps1 ; Ps2 $ y
|
||||
*
|
||||
* If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE
|
||||
* and writes the required buffer size to @p out_written. The caller can
|
||||
* then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param mode The mode identifying the mode to report on
|
||||
* @param state The report state for this mode
|
||||
* @param buf Output buffer to write the encoded sequence into (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_written On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer
|
||||
* is too small
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_mode_report_encode(
|
||||
GhosttyMode mode,
|
||||
GhosttyModeReportState state,
|
||||
char* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_MODES_H */
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @file mouse.h
|
||||
*
|
||||
* Mouse encoding module - encode mouse events into terminal escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_MOUSE_H
|
||||
#define GHOSTTY_VT_MOUSE_H
|
||||
|
||||
/** @defgroup mouse Mouse Encoding
|
||||
*
|
||||
* Utilities for encoding mouse events into terminal escape sequences,
|
||||
* supporting X10, UTF-8, SGR, URxvt, and SGR-Pixels mouse protocols.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* 1. Create an encoder instance with ghostty_mouse_encoder_new().
|
||||
* 2. Configure encoder options with ghostty_mouse_encoder_setopt() or
|
||||
* ghostty_mouse_encoder_setopt_from_terminal().
|
||||
* 3. For each mouse event:
|
||||
* - Create a mouse event with ghostty_mouse_event_new().
|
||||
* - Set event properties (action, button, modifiers, position).
|
||||
* - Encode with ghostty_mouse_encoder_encode().
|
||||
* - Free the event with ghostty_mouse_event_free() or reuse it.
|
||||
* 4. Free the encoder with ghostty_mouse_encoder_free() when done.
|
||||
*
|
||||
* For a complete working example, see example/c-vt-encode-mouse in the
|
||||
* repository.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-encode-mouse/src/main.c mouse-encode
|
||||
*
|
||||
* ## Example: Encoding with Terminal State
|
||||
*
|
||||
* When you have a GhosttyTerminal, you can sync its tracking mode and
|
||||
* output format into the encoder automatically:
|
||||
*
|
||||
* @code{.c}
|
||||
* // Create a terminal and feed it some VT data that enables mouse tracking
|
||||
* GhosttyTerminal terminal;
|
||||
* ghostty_terminal_new(NULL, &terminal,
|
||||
* (GhosttyTerminalOptions){.cols = 80, .rows = 24, .max_scrollback = 0});
|
||||
*
|
||||
* // Application might write data that enables mouse reporting, etc.
|
||||
* ghostty_terminal_vt_write(terminal, vt_data, vt_len);
|
||||
*
|
||||
* // Create an encoder and sync its options from the terminal
|
||||
* GhosttyMouseEncoder encoder;
|
||||
* ghostty_mouse_encoder_new(NULL, &encoder);
|
||||
* ghostty_mouse_encoder_setopt_from_terminal(encoder, terminal);
|
||||
*
|
||||
* // Encode a mouse event using the terminal-derived options
|
||||
* char buf[128];
|
||||
* size_t written = 0;
|
||||
* ghostty_mouse_encoder_encode(encoder, event, buf, sizeof(buf), &written);
|
||||
*
|
||||
* ghostty_mouse_encoder_free(encoder);
|
||||
* ghostty_terminal_free(terminal);
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ghostty/vt/mouse/event.h>
|
||||
#include <ghostty/vt/mouse/encoder.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_MOUSE_H */
|
||||
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* @file encoder.h
|
||||
*
|
||||
* Mouse event encoding to terminal escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_MOUSE_ENCODER_H
|
||||
#define GHOSTTY_VT_MOUSE_ENCODER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/mouse/event.h>
|
||||
#include <ghostty/vt/terminal.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
/**
|
||||
* Opaque handle to a mouse encoder instance.
|
||||
*
|
||||
* This handle represents a mouse encoder that converts normalized
|
||||
* mouse events into terminal escape sequences.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef struct GhosttyMouseEncoderImpl *GhosttyMouseEncoder;
|
||||
|
||||
/**
|
||||
* Mouse tracking mode.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Mouse reporting disabled. */
|
||||
GHOSTTY_MOUSE_TRACKING_NONE = 0,
|
||||
|
||||
/** X10 mouse mode. */
|
||||
GHOSTTY_MOUSE_TRACKING_X10 = 1,
|
||||
|
||||
/** Normal mouse mode (button press/release only). */
|
||||
GHOSTTY_MOUSE_TRACKING_NORMAL = 2,
|
||||
|
||||
/** Button-event tracking mode. */
|
||||
GHOSTTY_MOUSE_TRACKING_BUTTON = 3,
|
||||
|
||||
/** Any-event tracking mode. */
|
||||
GHOSTTY_MOUSE_TRACKING_ANY = 4,
|
||||
GHOSTTY_MOUSE_TRACKING_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyMouseTrackingMode;
|
||||
|
||||
/**
|
||||
* Mouse output format.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_MOUSE_FORMAT_X10 = 0,
|
||||
GHOSTTY_MOUSE_FORMAT_UTF8 = 1,
|
||||
GHOSTTY_MOUSE_FORMAT_SGR = 2,
|
||||
GHOSTTY_MOUSE_FORMAT_URXVT = 3,
|
||||
GHOSTTY_MOUSE_FORMAT_SGR_PIXELS = 4,
|
||||
GHOSTTY_MOUSE_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyMouseFormat;
|
||||
|
||||
/**
|
||||
* Mouse encoder size and geometry context.
|
||||
*
|
||||
* This describes the rendered terminal geometry used to convert
|
||||
* surface-space positions into encoded coordinates.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyMouseEncoderSize). */
|
||||
size_t size;
|
||||
|
||||
/** Full screen width in pixels. */
|
||||
uint32_t screen_width;
|
||||
|
||||
/** Full screen height in pixels. */
|
||||
uint32_t screen_height;
|
||||
|
||||
/** Cell width in pixels. Must be non-zero. */
|
||||
uint32_t cell_width;
|
||||
|
||||
/** Cell height in pixels. Must be non-zero. */
|
||||
uint32_t cell_height;
|
||||
|
||||
/** Top padding in pixels. */
|
||||
uint32_t padding_top;
|
||||
|
||||
/** Bottom padding in pixels. */
|
||||
uint32_t padding_bottom;
|
||||
|
||||
/** Right padding in pixels. */
|
||||
uint32_t padding_right;
|
||||
|
||||
/** Left padding in pixels. */
|
||||
uint32_t padding_left;
|
||||
} GhosttyMouseEncoderSize;
|
||||
|
||||
/**
|
||||
* Mouse encoder option identifiers.
|
||||
*
|
||||
* These values are used with ghostty_mouse_encoder_setopt() to configure
|
||||
* the behavior of the mouse encoder.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Mouse tracking mode (value: GhosttyMouseTrackingMode). */
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_EVENT = 0,
|
||||
|
||||
/** Mouse output format (value: GhosttyMouseFormat). */
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_FORMAT = 1,
|
||||
|
||||
/** Renderer size context (value: GhosttyMouseEncoderSize). */
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_SIZE = 2,
|
||||
|
||||
/** Whether any mouse button is currently pressed (value: bool). */
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_ANY_BUTTON_PRESSED = 3,
|
||||
|
||||
/** Whether to enable motion deduplication by last cell (value: bool). */
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_TRACK_LAST_CELL = 4,
|
||||
GHOSTTY_MOUSE_ENCODER_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyMouseEncoderOption;
|
||||
|
||||
/**
|
||||
* Create a new mouse encoder instance.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param encoder Pointer to store the created encoder handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_mouse_encoder_new(const GhosttyAllocator *allocator,
|
||||
GhosttyMouseEncoder *encoder);
|
||||
|
||||
/**
|
||||
* Free a mouse encoder instance.
|
||||
*
|
||||
* @param encoder The encoder handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_encoder_free(GhosttyMouseEncoder encoder);
|
||||
|
||||
/**
|
||||
* Set an option on the mouse encoder.
|
||||
*
|
||||
* A null pointer value does nothing. It does not reset to defaults.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param option The option to set
|
||||
* @param value Pointer to option value (type depends on option)
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_encoder_setopt(GhosttyMouseEncoder encoder,
|
||||
GhosttyMouseEncoderOption option,
|
||||
const void *value);
|
||||
|
||||
/**
|
||||
* Set encoder options from a terminal's current state.
|
||||
*
|
||||
* This sets tracking mode and output format from terminal state.
|
||||
* It does not modify size or any-button state.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param terminal The terminal handle, must not be NULL
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_encoder_setopt_from_terminal(GhosttyMouseEncoder encoder,
|
||||
GhosttyTerminal terminal);
|
||||
|
||||
/**
|
||||
* Reset internal encoder state.
|
||||
*
|
||||
* This clears motion deduplication state (last tracked cell).
|
||||
*
|
||||
* @param encoder The encoder handle (may be NULL)
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_encoder_reset(GhosttyMouseEncoder encoder);
|
||||
|
||||
/**
|
||||
* Encode a mouse event into a terminal escape sequence.
|
||||
*
|
||||
* Not all mouse events produce output. In such cases this returns
|
||||
* GHOSTTY_SUCCESS with out_len set to 0.
|
||||
*
|
||||
* If the output buffer is too small, this returns GHOSTTY_OUT_OF_SPACE
|
||||
* and out_len contains the required size.
|
||||
*
|
||||
* @param encoder The encoder handle, must not be NULL
|
||||
* @param event The mouse event to encode, must not be NULL
|
||||
* @param out_buf Buffer to write encoded bytes to, or NULL to query required size
|
||||
* @param out_buf_size Size of out_buf in bytes
|
||||
* @param out_len Pointer to store bytes written (or required bytes on failure)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if buffer is too small,
|
||||
* or another error code
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_mouse_encoder_encode(GhosttyMouseEncoder encoder,
|
||||
GhosttyMouseEvent event,
|
||||
char *out_buf,
|
||||
size_t out_buf_size,
|
||||
size_t *out_len);
|
||||
|
||||
#endif /* GHOSTTY_VT_MOUSE_ENCODER_H */
|
||||
@@ -0,0 +1,195 @@
|
||||
/**
|
||||
* @file event.h
|
||||
*
|
||||
* Mouse event representation and manipulation.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_MOUSE_EVENT_H
|
||||
#define GHOSTTY_VT_MOUSE_EVENT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/key/event.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
/**
|
||||
* Opaque handle to a mouse event.
|
||||
*
|
||||
* This handle represents a normalized mouse input event containing
|
||||
* action, button, modifiers, and surface-space position.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef struct GhosttyMouseEventImpl *GhosttyMouseEvent;
|
||||
|
||||
/**
|
||||
* Mouse event action type.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Mouse button was pressed. */
|
||||
GHOSTTY_MOUSE_ACTION_PRESS = 0,
|
||||
|
||||
/** Mouse button was released. */
|
||||
GHOSTTY_MOUSE_ACTION_RELEASE = 1,
|
||||
|
||||
/** Mouse moved. */
|
||||
GHOSTTY_MOUSE_ACTION_MOTION = 2,
|
||||
GHOSTTY_MOUSE_ACTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyMouseAction;
|
||||
|
||||
/**
|
||||
* Mouse button identity.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_MOUSE_BUTTON_UNKNOWN = 0,
|
||||
GHOSTTY_MOUSE_BUTTON_LEFT = 1,
|
||||
GHOSTTY_MOUSE_BUTTON_RIGHT = 2,
|
||||
GHOSTTY_MOUSE_BUTTON_MIDDLE = 3,
|
||||
GHOSTTY_MOUSE_BUTTON_FOUR = 4,
|
||||
GHOSTTY_MOUSE_BUTTON_FIVE = 5,
|
||||
GHOSTTY_MOUSE_BUTTON_SIX = 6,
|
||||
GHOSTTY_MOUSE_BUTTON_SEVEN = 7,
|
||||
GHOSTTY_MOUSE_BUTTON_EIGHT = 8,
|
||||
GHOSTTY_MOUSE_BUTTON_NINE = 9,
|
||||
GHOSTTY_MOUSE_BUTTON_TEN = 10,
|
||||
GHOSTTY_MOUSE_BUTTON_ELEVEN = 11,
|
||||
GHOSTTY_MOUSE_BUTTON_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyMouseButton;
|
||||
|
||||
/**
|
||||
* Mouse position in surface-space pixels.
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
typedef struct {
|
||||
float x;
|
||||
float y;
|
||||
} GhosttyMousePosition;
|
||||
|
||||
/**
|
||||
* Create a new mouse event instance.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param event Pointer to store the created event handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_mouse_event_new(const GhosttyAllocator *allocator,
|
||||
GhosttyMouseEvent *event);
|
||||
|
||||
/**
|
||||
* Free a mouse event instance.
|
||||
*
|
||||
* @param event The mouse event handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_free(GhosttyMouseEvent event);
|
||||
|
||||
/**
|
||||
* Set the event action.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @param action The action to set
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_set_action(GhosttyMouseEvent event,
|
||||
GhosttyMouseAction action);
|
||||
|
||||
/**
|
||||
* Get the event action.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @return The event action
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyMouseAction ghostty_mouse_event_get_action(GhosttyMouseEvent event);
|
||||
|
||||
/**
|
||||
* Set the event button.
|
||||
*
|
||||
* This sets a concrete button identity for the event.
|
||||
* To represent "no button" (for motion events), use
|
||||
* ghostty_mouse_event_clear_button().
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @param button The button to set
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_set_button(GhosttyMouseEvent event,
|
||||
GhosttyMouseButton button);
|
||||
|
||||
/**
|
||||
* Clear the event button.
|
||||
*
|
||||
* This sets the event button to "none".
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_clear_button(GhosttyMouseEvent event);
|
||||
|
||||
/**
|
||||
* Get the event button.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @param out_button Output pointer for the button value (may be NULL)
|
||||
* @return true if a button is set, false if no button is set
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_mouse_event_get_button(GhosttyMouseEvent event,
|
||||
GhosttyMouseButton *out_button);
|
||||
|
||||
/**
|
||||
* Set keyboard modifiers held during the event.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @param mods Modifier bitmask
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_set_mods(GhosttyMouseEvent event,
|
||||
GhosttyMods mods);
|
||||
|
||||
/**
|
||||
* Get keyboard modifiers held during the event.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @return Modifier bitmask
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyMods ghostty_mouse_event_get_mods(GhosttyMouseEvent event);
|
||||
|
||||
/**
|
||||
* Set the event position in surface-space pixels.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @param position The position to set
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API void ghostty_mouse_event_set_position(GhosttyMouseEvent event,
|
||||
GhosttyMousePosition position);
|
||||
|
||||
/**
|
||||
* Get the event position in surface-space pixels.
|
||||
*
|
||||
* @param event The event handle, must not be NULL
|
||||
* @return The current event position
|
||||
*
|
||||
* @ingroup mouse
|
||||
*/
|
||||
GHOSTTY_API GhosttyMousePosition ghostty_mouse_event_get_position(GhosttyMouseEvent event);
|
||||
|
||||
#endif /* GHOSTTY_VT_MOUSE_EVENT_H */
|
||||
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* @file osc.h
|
||||
*
|
||||
* OSC (Operating System Command) sequence parser and command handling.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_OSC_H
|
||||
#define GHOSTTY_VT_OSC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
|
||||
/** @defgroup osc OSC Parser
|
||||
*
|
||||
* OSC (Operating System Command) sequence parser and command handling.
|
||||
*
|
||||
* The parser operates in a streaming fashion, processing input byte-by-byte
|
||||
* to handle OSC sequences that may arrive in fragments across multiple reads.
|
||||
* This interface makes it easy to integrate into most environments and avoids
|
||||
* over-allocating buffers.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* 1. Create a parser instance with ghostty_osc_new()
|
||||
* 2. Feed bytes to the parser using ghostty_osc_next()
|
||||
* 3. Finalize parsing with ghostty_osc_end() to get the command
|
||||
* 4. Query command type and extract data using ghostty_osc_command_type()
|
||||
* and ghostty_osc_command_data()
|
||||
* 5. Free the parser with ghostty_osc_free() when done
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* OSC command types.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_OSC_COMMAND_INVALID = 0,
|
||||
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE = 1,
|
||||
GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_ICON = 2,
|
||||
GHOSTTY_OSC_COMMAND_SEMANTIC_PROMPT = 3,
|
||||
GHOSTTY_OSC_COMMAND_CLIPBOARD_CONTENTS = 4,
|
||||
GHOSTTY_OSC_COMMAND_REPORT_PWD = 5,
|
||||
GHOSTTY_OSC_COMMAND_MOUSE_SHAPE = 6,
|
||||
GHOSTTY_OSC_COMMAND_COLOR_OPERATION = 7,
|
||||
GHOSTTY_OSC_COMMAND_KITTY_COLOR_PROTOCOL = 8,
|
||||
GHOSTTY_OSC_COMMAND_SHOW_DESKTOP_NOTIFICATION = 9,
|
||||
GHOSTTY_OSC_COMMAND_HYPERLINK_START = 10,
|
||||
GHOSTTY_OSC_COMMAND_HYPERLINK_END = 11,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_SLEEP = 12,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_SHOW_MESSAGE_BOX = 13,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_CHANGE_TAB_TITLE = 14,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_PROGRESS_REPORT = 15,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_WAIT_INPUT = 16,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_GUIMACRO = 17,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_RUN_PROCESS = 18,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_OUTPUT_ENVIRONMENT_VARIABLE = 19,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_XTERM_EMULATION = 20,
|
||||
GHOSTTY_OSC_COMMAND_CONEMU_COMMENT = 21,
|
||||
GHOSTTY_OSC_COMMAND_KITTY_TEXT_SIZING = 22,
|
||||
GHOSTTY_OSC_COMMAND_TYPE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyOscCommandType;
|
||||
|
||||
/**
|
||||
* OSC command data types.
|
||||
*
|
||||
* These values specify what type of data to extract from an OSC command
|
||||
* using `ghostty_osc_command_data`.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid data type. Never results in any data extraction. */
|
||||
GHOSTTY_OSC_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* Window title string data.
|
||||
*
|
||||
* Valid for: GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE
|
||||
*
|
||||
* Output type: const char ** (pointer to null-terminated string)
|
||||
*
|
||||
* Lifetime: Valid until the next call to any ghostty_osc_* function with
|
||||
* the same parser instance. Memory is owned by the parser.
|
||||
*/
|
||||
GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR = 1,
|
||||
GHOSTTY_OSC_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyOscCommandData;
|
||||
|
||||
/**
|
||||
* Create a new OSC parser instance.
|
||||
*
|
||||
* Creates a new OSC (Operating System Command) parser using the provided
|
||||
* allocator. The parser must be freed using ghostty_vt_osc_free() when
|
||||
* no longer needed.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator
|
||||
* @param parser Pointer to store the created parser handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_osc_new(const GhosttyAllocator *allocator, GhosttyOscParser *parser);
|
||||
|
||||
/**
|
||||
* Free an OSC parser instance.
|
||||
*
|
||||
* Releases all resources associated with the OSC parser. After this call,
|
||||
* the parser handle becomes invalid and must not be used.
|
||||
*
|
||||
* @param parser The parser handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API void ghostty_osc_free(GhosttyOscParser parser);
|
||||
|
||||
/**
|
||||
* Reset an OSC parser instance to its initial state.
|
||||
*
|
||||
* Resets the parser state, clearing any partially parsed OSC sequences
|
||||
* and returning the parser to its initial state. This is useful for
|
||||
* reusing a parser instance or recovering from parse errors.
|
||||
*
|
||||
* @param parser The parser handle to reset, must not be null.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API void ghostty_osc_reset(GhosttyOscParser parser);
|
||||
|
||||
/**
|
||||
* Parse the next byte in an OSC sequence.
|
||||
*
|
||||
* Processes a single byte as part of an OSC sequence. The parser maintains
|
||||
* internal state to track the progress through the sequence. Call this
|
||||
* function for each byte in the sequence data.
|
||||
*
|
||||
* When finished pumping the parser with bytes, call ghostty_osc_end
|
||||
* to get the final result.
|
||||
*
|
||||
* @param parser The parser handle, must not be null.
|
||||
* @param byte The next byte to parse
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API void ghostty_osc_next(GhosttyOscParser parser, uint8_t byte);
|
||||
|
||||
/**
|
||||
* Finalize OSC parsing and retrieve the parsed command.
|
||||
*
|
||||
* Call this function after feeding all bytes of an OSC sequence to the parser
|
||||
* using ghostty_osc_next() with the exception of the terminating character
|
||||
* (ESC or ST). This function finalizes the parsing process and returns the
|
||||
* parsed OSC command.
|
||||
*
|
||||
* The return value is never NULL. Invalid commands will return a command
|
||||
* with type GHOSTTY_OSC_COMMAND_INVALID.
|
||||
*
|
||||
* The terminator parameter specifies the byte that terminated the OSC sequence
|
||||
* (typically 0x07 for BEL or 0x5C for ST after ESC). This information is
|
||||
* preserved in the parsed command so that responses can use the same terminator
|
||||
* format for better compatibility with the calling program. For commands that
|
||||
* do not require a response, this parameter is ignored and the resulting
|
||||
* command will not retain the terminator information.
|
||||
*
|
||||
* The returned command handle is valid until the next call to any
|
||||
* `ghostty_osc_*` function with the same parser instance with the exception
|
||||
* of command introspection functions such as `ghostty_osc_command_type`.
|
||||
*
|
||||
* @param parser The parser handle, must not be null.
|
||||
* @param terminator The terminating byte of the OSC sequence (0x07 for BEL, 0x5C for ST)
|
||||
* @return Handle to the parsed OSC command
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API GhosttyOscCommand ghostty_osc_end(GhosttyOscParser parser, uint8_t terminator);
|
||||
|
||||
/**
|
||||
* Get the type of an OSC command.
|
||||
*
|
||||
* Returns the type identifier for the given OSC command. This can be used
|
||||
* to determine what kind of command was parsed and what data might be
|
||||
* available from it.
|
||||
*
|
||||
* @param command The OSC command handle to query (may be NULL)
|
||||
* @return The command type, or GHOSTTY_OSC_COMMAND_INVALID if command is NULL
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API GhosttyOscCommandType ghostty_osc_command_type(GhosttyOscCommand command);
|
||||
|
||||
/**
|
||||
* Extract data from an OSC command.
|
||||
*
|
||||
* Extracts typed data from the given OSC command based on the specified
|
||||
* data type. The output pointer must be of the appropriate type for the
|
||||
* requested data kind. Valid command types, output types, and memory
|
||||
* safety information are documented in the `GhosttyOscCommandData` enum.
|
||||
*
|
||||
* @param command The OSC command handle to query (may be NULL)
|
||||
* @param data The type of data to extract
|
||||
* @param out Pointer to store the extracted data (type depends on data parameter)
|
||||
* @return true if data extraction was successful, false otherwise
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_osc_command_data(GhosttyOscCommand command, GhosttyOscCommandData data, void *out);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_OSC_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file paste.h
|
||||
*
|
||||
* Paste utilities - validate and encode paste data for terminal input.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_PASTE_H
|
||||
#define GHOSTTY_VT_PASTE_H
|
||||
|
||||
/** @defgroup paste Paste Utilities
|
||||
*
|
||||
* Utilities for validating and encoding paste data for terminal input.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_paste_is_safe() to check if paste data contains potentially
|
||||
* dangerous sequences before sending it to the terminal.
|
||||
*
|
||||
* Use ghostty_paste_encode() to encode paste data for writing to the pty,
|
||||
* including bracketed paste wrapping and unsafe byte stripping.
|
||||
*
|
||||
* ## Examples
|
||||
*
|
||||
* ### Safety Check
|
||||
*
|
||||
* @snippet c-vt-paste/src/main.c paste-safety
|
||||
*
|
||||
* ### Encoding
|
||||
*
|
||||
* @snippet c-vt-paste/src/main.c paste-encode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check if paste data is safe to paste into the terminal.
|
||||
*
|
||||
* Data is considered unsafe if it contains:
|
||||
* - Newlines (`\n`) which can inject commands
|
||||
* - The bracketed paste end sequence (`\x1b[201~`) which can be used
|
||||
* to exit bracketed paste mode and inject commands
|
||||
*
|
||||
* This check is conservative and considers data unsafe regardless of
|
||||
* current terminal state.
|
||||
*
|
||||
* @param data The paste data to check (must not be NULL)
|
||||
* @param len The length of the data in bytes
|
||||
* @return true if the data is safe to paste, false otherwise
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_paste_is_safe(const char* data, size_t len);
|
||||
|
||||
/**
|
||||
* Encode paste data for writing to the terminal pty.
|
||||
*
|
||||
* This function prepares paste data for terminal input by:
|
||||
* - Stripping unsafe control bytes (NUL, ESC, DEL, etc.) by replacing
|
||||
* them with spaces
|
||||
* - Wrapping the data in bracketed paste sequences if @p bracketed is true
|
||||
* - Replacing newlines with carriage returns if @p bracketed is false
|
||||
*
|
||||
* The input @p data buffer is modified in place during encoding. The
|
||||
* encoded result (potentially with bracketed paste prefix/suffix) is
|
||||
* written to the output buffer.
|
||||
*
|
||||
* If the output buffer is too small, the function returns
|
||||
* GHOSTTY_OUT_OF_SPACE and sets the required size in @p out_written.
|
||||
* The caller can then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param data The paste data to encode (modified in place, may be NULL)
|
||||
* @param data_len The length of the input data in bytes
|
||||
* @param bracketed Whether bracketed paste mode is active
|
||||
* @param buf Output buffer to write the encoded result into (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_written On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer
|
||||
* is too small
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_paste_encode(
|
||||
char* data,
|
||||
size_t data_len,
|
||||
bool bracketed,
|
||||
char* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_PASTE_H */
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @file point.h
|
||||
*
|
||||
* Terminal point types for referencing locations in the terminal grid.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_POINT_H
|
||||
#define GHOSTTY_VT_POINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup point Point
|
||||
*
|
||||
* Types for referencing x/y positions in the terminal grid under
|
||||
* different coordinate systems (active area, viewport, full screen,
|
||||
* scrollback history).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* A coordinate in the terminal grid.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef struct {
|
||||
/** Column (0-indexed). */
|
||||
uint16_t x;
|
||||
|
||||
/** Row (0-indexed). May exceed page size for screen/history tags. */
|
||||
uint32_t y;
|
||||
} GhosttyPointCoordinate;
|
||||
|
||||
/**
|
||||
* Point reference tag.
|
||||
*
|
||||
* Determines which coordinate system a point uses.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Active area where the cursor can move. */
|
||||
GHOSTTY_POINT_TAG_ACTIVE = 0,
|
||||
|
||||
/** Visible viewport (changes when scrolled). */
|
||||
GHOSTTY_POINT_TAG_VIEWPORT = 1,
|
||||
|
||||
/** Full screen including scrollback. */
|
||||
GHOSTTY_POINT_TAG_SCREEN = 2,
|
||||
|
||||
/** Scrollback history only (before active area). */
|
||||
GHOSTTY_POINT_TAG_HISTORY = 3,
|
||||
GHOSTTY_POINT_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyPointTag;
|
||||
|
||||
/**
|
||||
* Point value union.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef union {
|
||||
/** Coordinate (used for all tag variants). */
|
||||
GhosttyPointCoordinate coordinate;
|
||||
|
||||
/** Padding for ABI compatibility. Do not use. */
|
||||
uint64_t _padding[2];
|
||||
} GhosttyPointValue;
|
||||
|
||||
/**
|
||||
* Tagged union for a point in the terminal grid.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef struct {
|
||||
GhosttyPointTag tag;
|
||||
GhosttyPointValue value;
|
||||
} GhosttyPoint;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_POINT_H */
|
||||
@@ -0,0 +1,795 @@
|
||||
/**
|
||||
* @file render.h
|
||||
*
|
||||
* Render state for creating high performance renderers.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_RENDER_H
|
||||
#define GHOSTTY_VT_RENDER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/terminal.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup render Render State
|
||||
*
|
||||
* Represents the state required to render a visible screen (a viewport)
|
||||
* of a terminal instance. This is stateful and optimized for repeated
|
||||
* updates from a single terminal instance and only updating dirty regions
|
||||
* of the screen.
|
||||
*
|
||||
* The key design principle of this API is that it only needs read/write
|
||||
* access to the terminal instance during the update call. This allows
|
||||
* the render state to minimally impact terminal IO performance and also
|
||||
* allows the renderer to be safely multi-threaded (as long as a lock is
|
||||
* held during the update call to ensure exclusive access to the terminal
|
||||
* instance).
|
||||
*
|
||||
* The basic usage of this API is:
|
||||
*
|
||||
* 1. Create an empty render state
|
||||
* 2. Update it from a terminal instance whenever you need.
|
||||
* 3. Read from the render state to get the data needed to draw your frame.
|
||||
*
|
||||
* ## Two-Phase Updates
|
||||
*
|
||||
* For callers that synchronize terminal access (e.g. a renderer thread
|
||||
* sharing a lock with an IO thread), the update can be split into two
|
||||
* phases to minimize the time the terminal must be held exclusively:
|
||||
* ghostty_render_state_begin_update requires terminal access, while
|
||||
* ghostty_render_state_end_update completes any deferred work using only
|
||||
* memory owned by the render state. A typical renderer would lock, begin
|
||||
* the update, unlock, and then end the update while the IO thread is free
|
||||
* to continue modifying the terminal. ghostty_render_state_update is a
|
||||
* convenience that performs both phases in one call.
|
||||
*
|
||||
* ## Dirty Tracking
|
||||
*
|
||||
* Dirty tracking is a key feature of the render state that allows renderers
|
||||
* to efficiently determine what parts of the screen have changed and only
|
||||
* redraw changed regions.
|
||||
*
|
||||
* The render state API keeps track of dirty state at two independent layers:
|
||||
* a global dirty state that indicates whether the entire frame is clean,
|
||||
* partially dirty, or fully dirty, and a per-row dirty state that allows
|
||||
* tracking which rows in a partially dirty frame have changed.
|
||||
*
|
||||
* The user of the render state API is expected to unset both of these.
|
||||
* The `update` call does not unset dirty state, it only updates it.
|
||||
*
|
||||
* An extremely important detail: setting one dirty state doesn't unset
|
||||
* the other. For example, setting the global dirty state to false does not
|
||||
* reset the row-level dirty flags. So, the caller of the render state API must
|
||||
* be careful to manage both layers of dirty state correctly.
|
||||
*
|
||||
* ## Examples
|
||||
*
|
||||
* ### Creating and updating render state
|
||||
* @snippet c-vt-render/src/main.c render-state-update
|
||||
*
|
||||
* ### Checking dirty state
|
||||
* @snippet c-vt-render/src/main.c render-dirty-check
|
||||
*
|
||||
* ### Reading colors
|
||||
* @snippet c-vt-render/src/main.c render-colors
|
||||
*
|
||||
* ### Reading cursor state
|
||||
* @snippet c-vt-render/src/main.c render-cursor
|
||||
*
|
||||
* ### Iterating rows and cells
|
||||
* @snippet c-vt-render/src/main.c render-row-iterate
|
||||
*
|
||||
* ### Resetting dirty state after rendering
|
||||
* @snippet c-vt-render/src/main.c render-dirty-reset
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dirty state of a render state after update.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Not dirty at all; rendering can be skipped. */
|
||||
GHOSTTY_RENDER_STATE_DIRTY_FALSE = 0,
|
||||
|
||||
/** Some rows changed; renderer can redraw incrementally. */
|
||||
GHOSTTY_RENDER_STATE_DIRTY_PARTIAL = 1,
|
||||
|
||||
/** Global state changed; renderer should redraw everything. */
|
||||
GHOSTTY_RENDER_STATE_DIRTY_FULL = 2,
|
||||
GHOSTTY_RENDER_STATE_DIRTY_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateDirty;
|
||||
|
||||
/**
|
||||
* Visual style of the cursor.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Bar cursor (DECSCUSR 5, 6). */
|
||||
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BAR = 0,
|
||||
|
||||
/** Block cursor (DECSCUSR 1, 2). */
|
||||
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BLOCK = 1,
|
||||
|
||||
/** Underline cursor (DECSCUSR 3, 4). */
|
||||
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_UNDERLINE = 2,
|
||||
|
||||
/** Hollow block cursor. */
|
||||
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BLOCK_HOLLOW = 3,
|
||||
GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateCursorVisualStyle;
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_render_state_get().
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_RENDER_STATE_DATA_INVALID = 0,
|
||||
|
||||
/** Viewport width in cells (uint16_t). */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLS = 1,
|
||||
|
||||
/** Viewport height in cells (uint16_t). */
|
||||
GHOSTTY_RENDER_STATE_DATA_ROWS = 2,
|
||||
|
||||
/** Current dirty state (GhosttyRenderStateDirty). */
|
||||
GHOSTTY_RENDER_STATE_DATA_DIRTY = 3,
|
||||
|
||||
/** Populate a pre-allocated GhosttyRenderStateRowIterator with row data
|
||||
* from the render state (GhosttyRenderStateRowIterator). Row data is
|
||||
* only valid as long as the underlying render state is not updated.
|
||||
* It is unsafe to use row data after updating the render state.
|
||||
* */
|
||||
GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR = 4,
|
||||
|
||||
/** Default/current background color (GhosttyColorRgb). */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLOR_BACKGROUND = 5,
|
||||
|
||||
/** Default/current foreground color (GhosttyColorRgb). */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLOR_FOREGROUND = 6,
|
||||
|
||||
/** Cursor color when explicitly set by terminal state (GhosttyColorRgb).
|
||||
* Returns GHOSTTY_INVALID_VALUE if no explicit cursor color is set;
|
||||
* use COLOR_CURSOR_HAS_VALUE to check first. */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLOR_CURSOR = 7,
|
||||
|
||||
/** Whether an explicit cursor color is set (bool). */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLOR_CURSOR_HAS_VALUE = 8,
|
||||
|
||||
/** The active 256-color palette (GhosttyColorRgb[256]). */
|
||||
GHOSTTY_RENDER_STATE_DATA_COLOR_PALETTE = 9,
|
||||
|
||||
/** The visual style of the cursor (GhosttyRenderStateCursorVisualStyle). */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VISUAL_STYLE = 10,
|
||||
|
||||
/** Whether the cursor is visible based on terminal modes (bool). */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VISIBLE = 11,
|
||||
|
||||
/** Whether the cursor should blink based on terminal modes (bool). */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_BLINKING = 12,
|
||||
|
||||
/** Whether the cursor is at a password input field (bool). */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_PASSWORD_INPUT = 13,
|
||||
|
||||
/** Whether the cursor is visible within the viewport (bool).
|
||||
* If false, the cursor viewport position values are undefined. */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_HAS_VALUE = 14,
|
||||
|
||||
/** Cursor viewport x position in cells (uint16_t).
|
||||
* Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_X = 15,
|
||||
|
||||
/** Cursor viewport y position in cells (uint16_t).
|
||||
* Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_Y = 16,
|
||||
|
||||
/** Whether the cursor is on the tail of a wide character (bool).
|
||||
* Only valid when CURSOR_VIEWPORT_HAS_VALUE is true. */
|
||||
GHOSTTY_RENDER_STATE_DATA_CURSOR_VIEWPORT_WIDE_TAIL = 17,
|
||||
GHOSTTY_RENDER_STATE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateData;
|
||||
|
||||
/**
|
||||
* Settable options for ghostty_render_state_set().
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Set dirty state (GhosttyRenderStateDirty). */
|
||||
GHOSTTY_RENDER_STATE_OPTION_DIRTY = 0,
|
||||
GHOSTTY_RENDER_STATE_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateOption;
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_render_state_row_get().
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_INVALID = 0,
|
||||
|
||||
/** Whether the current row is dirty (bool). */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_DIRTY = 1,
|
||||
|
||||
/** The raw row value (GhosttyRow). */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_RAW = 2,
|
||||
|
||||
/** Populate a pre-allocated GhosttyRenderStateRowCells with cell data for
|
||||
* the current row (GhosttyRenderStateRowCells). Cell data is only
|
||||
* valid as long as the underlying render state is not updated.
|
||||
* It is unsafe to use cell data after updating the render state. */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_CELLS = 3,
|
||||
|
||||
/** Row-local selected cell range (GhosttyRenderStateRowSelection). */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION = 4,
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateRowData;
|
||||
|
||||
/**
|
||||
* Settable options for ghostty_render_state_row_set().
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Set dirty state for the current row (bool). */
|
||||
GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY = 0,
|
||||
GHOSTTY_RENDER_STATE_ROW_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateRowOption;
|
||||
|
||||
/**
|
||||
* Row-local selection range.
|
||||
*
|
||||
* This struct uses the sized-struct ABI pattern. Initialize with
|
||||
* GHOSTTY_INIT_SIZED(GhosttyRenderStateRowSelection) before querying
|
||||
* GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION.
|
||||
*
|
||||
* Querying GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION returns GHOSTTY_NO_VALUE
|
||||
* if the current row does not intersect the current selection.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyRenderStateRowSelection). */
|
||||
size_t size;
|
||||
|
||||
/** Start column of the row-local selection range, inclusive. */
|
||||
uint16_t start_x;
|
||||
|
||||
/** End column of the row-local selection range, inclusive. */
|
||||
uint16_t end_x;
|
||||
} GhosttyRenderStateRowSelection;
|
||||
|
||||
/**
|
||||
* Render-state color information.
|
||||
*
|
||||
* This struct uses the sized-struct ABI pattern. Initialize with
|
||||
* GHOSTTY_INIT_SIZED(GhosttyRenderStateColors) before calling
|
||||
* ghostty_render_state_colors_get().
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* GhosttyRenderStateColors colors = GHOSTTY_INIT_SIZED(GhosttyRenderStateColors);
|
||||
* GhosttyResult result = ghostty_render_state_colors_get(state, &colors);
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef struct {
|
||||
/** Size of this struct in bytes. Must be set to sizeof(GhosttyRenderStateColors). */
|
||||
size_t size;
|
||||
|
||||
/** The default/current background color for the render state. */
|
||||
GhosttyColorRgb background;
|
||||
|
||||
/** The default/current foreground color for the render state. */
|
||||
GhosttyColorRgb foreground;
|
||||
|
||||
/** The cursor color when explicitly set by terminal state. */
|
||||
GhosttyColorRgb cursor;
|
||||
|
||||
/**
|
||||
* True when cursor contains a valid explicit cursor color value.
|
||||
* If this is false, the cursor color should be ignored; it will
|
||||
* contain undefined data.
|
||||
* */
|
||||
bool cursor_has_value;
|
||||
|
||||
/** The active 256-color palette for this render state. */
|
||||
GhosttyColorRgb palette[256];
|
||||
} GhosttyRenderStateColors;
|
||||
|
||||
/**
|
||||
* Create a new render state instance.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param state Pointer to store the created render state handle
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
|
||||
* failure
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_new(const GhosttyAllocator* allocator,
|
||||
GhosttyRenderState* state);
|
||||
|
||||
/**
|
||||
* Free a render state instance.
|
||||
*
|
||||
* Releases all resources associated with the render state. After this call,
|
||||
* the render state handle becomes invalid.
|
||||
*
|
||||
* @param state The render state handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API void ghostty_render_state_free(GhosttyRenderState state);
|
||||
|
||||
/**
|
||||
* Update a render state instance from a terminal.
|
||||
*
|
||||
* This consumes terminal/screen dirty state in the same way as the internal
|
||||
* render state update path.
|
||||
*
|
||||
* This is a convenience function that performs a full update in one call,
|
||||
* equivalent to ghostty_render_state_begin_update immediately followed by
|
||||
* ghostty_render_state_end_update. Callers that hold a lock over the
|
||||
* terminal state should prefer calling the two phases directly so that the
|
||||
* lock is only held for the begin phase.
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param terminal The terminal handle to read from (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or
|
||||
* `terminal` is NULL, GHOSTTY_OUT_OF_MEMORY if updating the state requires
|
||||
* allocation and that allocation fails
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_update(GhosttyRenderState state,
|
||||
GhosttyTerminal terminal);
|
||||
|
||||
/**
|
||||
* Begin an update of a render state instance from a terminal.
|
||||
*
|
||||
* Every begin must be completed with a ghostty_render_state_end_update call
|
||||
* before the render state is read.
|
||||
*
|
||||
* This two-phase structure exists for callers that synchronize access to the
|
||||
* terminal state (e.g. with a lock shared with an IO thread): only this
|
||||
* function requires terminal access, so a caller can hold its lock for this
|
||||
* call only and then call ghostty_render_state_end_update after releasing
|
||||
* it. The end phase exclusively reads and writes memory owned by the render
|
||||
* state, so it is safe to call while the terminal is being modified.
|
||||
*
|
||||
* Work that doesn't require terminal access may be deferred to the end phase
|
||||
* to keep this call (and therefore lock hold time) as short as possible.
|
||||
* Callers must treat the render state as incomplete until
|
||||
* ghostty_render_state_end_update is called.
|
||||
*
|
||||
* This consumes terminal/screen dirty state in the same way as the internal
|
||||
* render state update path.
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param terminal The terminal handle to read from (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or
|
||||
* `terminal` is NULL, GHOSTTY_OUT_OF_MEMORY if updating the state requires
|
||||
* allocation and that allocation fails
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_begin_update(GhosttyRenderState state,
|
||||
GhosttyTerminal terminal);
|
||||
|
||||
/**
|
||||
* Complete a prior ghostty_render_state_begin_update call by performing any
|
||||
* deferred work.
|
||||
*
|
||||
* This only reads and writes memory owned by the render state, so it is safe
|
||||
* to call while the terminal is being modified (no terminal synchronization
|
||||
* is required). Calling this without a prior begin is a safe no-op.
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is
|
||||
* NULL
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_end_update(GhosttyRenderState state);
|
||||
|
||||
/**
|
||||
* Get a value from a render state.
|
||||
*
|
||||
* The `out` pointer must point to a value of the type corresponding to the
|
||||
* requested data kind (see GhosttyRenderStateData).
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param data The data kind to query
|
||||
* @param[out] out Pointer to receive the queried value
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` is
|
||||
* NULL or `data` is not a recognized enum value
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_get(GhosttyRenderState state,
|
||||
GhosttyRenderStateData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from a render state in a single call.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_get_multi(
|
||||
GhosttyRenderState state,
|
||||
size_t count,
|
||||
const GhosttyRenderStateData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Set an option on a render state.
|
||||
*
|
||||
* The `value` pointer must point to a value of the type corresponding to the
|
||||
* requested option kind (see GhosttyRenderStateOption).
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param option The option to set
|
||||
* @param[in] value Pointer to the value to set (NULL returns
|
||||
* GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or
|
||||
* `value` is NULL
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_set(GhosttyRenderState state,
|
||||
GhosttyRenderStateOption option,
|
||||
const void* value);
|
||||
|
||||
/**
|
||||
* Get the current color information from a render state.
|
||||
*
|
||||
* This writes as many fields as fit in the caller-provided sized struct.
|
||||
* `out_colors->size` must be set by the caller (typically via
|
||||
* GHOSTTY_INIT_SIZED(GhosttyRenderStateColors)).
|
||||
*
|
||||
* @param state The render state handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param[out] out_colors Sized output struct to receive render-state colors
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `state` or
|
||||
* `out_colors` is NULL, or if `out_colors->size` is smaller than
|
||||
* `sizeof(size_t)`
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_colors_get(GhosttyRenderState state,
|
||||
GhosttyRenderStateColors* out_colors);
|
||||
|
||||
/**
|
||||
* Create a new row iterator instance.
|
||||
*
|
||||
* All fields except the allocator are left undefined until populated
|
||||
* via ghostty_render_state_get() with
|
||||
* GHOSTTY_RENDER_STATE_DATA_ROW_ITERATOR.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param[out] out_iterator On success, receives the created iterator handle
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
|
||||
* failure
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_iterator_new(
|
||||
const GhosttyAllocator* allocator,
|
||||
GhosttyRenderStateRowIterator* out_iterator);
|
||||
|
||||
/**
|
||||
* Free a render-state row iterator.
|
||||
*
|
||||
* @param iterator The iterator handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API void ghostty_render_state_row_iterator_free(GhosttyRenderStateRowIterator iterator);
|
||||
|
||||
/**
|
||||
* Move a render-state row iterator to the next row.
|
||||
*
|
||||
* Returns true if the iterator moved successfully and row data is
|
||||
* available to read at the new position.
|
||||
*
|
||||
* @param iterator The iterator handle to advance (may be NULL)
|
||||
* @return true if advanced to the next row, false if `iterator` is
|
||||
* NULL or if the iterator has reached the end
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_render_state_row_iterator_next(GhosttyRenderStateRowIterator iterator);
|
||||
|
||||
/**
|
||||
* Get a value from the current row in a render-state row iterator.
|
||||
*
|
||||
* The `out` pointer must point to a value of the type corresponding to the
|
||||
* requested data kind (see GhosttyRenderStateRowData).
|
||||
* Call ghostty_render_state_row_iterator_next() at least once before
|
||||
* calling this function.
|
||||
*
|
||||
* @param iterator The iterator handle to query (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param data The data kind to query
|
||||
* @param[out] out Pointer to receive the queried value
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if
|
||||
* `iterator` is NULL or the iterator is not positioned on a row
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_get(
|
||||
GhosttyRenderStateRowIterator iterator,
|
||||
GhosttyRenderStateRowData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from the current row in a single call.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param iterator The iterator handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_get_multi(
|
||||
GhosttyRenderStateRowIterator iterator,
|
||||
size_t count,
|
||||
const GhosttyRenderStateRowData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Set an option on the current row in a render-state row iterator.
|
||||
*
|
||||
* The `value` pointer must point to a value of the type corresponding to the
|
||||
* requested option kind (see GhosttyRenderStateRowOption).
|
||||
* Call ghostty_render_state_row_iterator_next() at least once before
|
||||
* calling this function.
|
||||
*
|
||||
* @param iterator The iterator handle to update (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param option The option to set
|
||||
* @param[in] value Pointer to the value to set (NULL returns
|
||||
* GHOSTTY_INVALID_VALUE)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if
|
||||
* `iterator` is NULL or the iterator is not positioned on a row
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_set(
|
||||
GhosttyRenderStateRowIterator iterator,
|
||||
GhosttyRenderStateRowOption option,
|
||||
const void* value);
|
||||
|
||||
/**
|
||||
* Create a new row cells instance.
|
||||
*
|
||||
* All fields except the allocator are left undefined until populated
|
||||
* via ghostty_render_state_row_get() with
|
||||
* GHOSTTY_RENDER_STATE_ROW_DATA_CELLS.
|
||||
*
|
||||
* You can reuse this value repeatedly with ghostty_render_state_row_get() to
|
||||
* avoid allocating a new cells container for every row.
|
||||
*
|
||||
* @param allocator Pointer to allocator, or NULL to use the default allocator
|
||||
* @param[out] out_cells On success, receives the created row cells handle
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_MEMORY on allocation
|
||||
* failure
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_new(
|
||||
const GhosttyAllocator* allocator,
|
||||
GhosttyRenderStateRowCells* out_cells);
|
||||
|
||||
/**
|
||||
* Queryable data kinds for ghostty_render_state_row_cells_get().
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid / sentinel value. */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_INVALID = 0,
|
||||
|
||||
/** The raw cell value (GhosttyCell). */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW = 1,
|
||||
|
||||
/** The style for the current cell (GhosttyStyle). */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_STYLE = 2,
|
||||
|
||||
/** The total number of grapheme codepoints including the base codepoint
|
||||
* (uint32_t). Returns 0 if the cell has no text. */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_LEN = 3,
|
||||
|
||||
/** Write grapheme codepoints into a caller-provided buffer (uint32_t*).
|
||||
* The buffer must be at least graphemes_len elements. The base codepoint
|
||||
* is written first, followed by any extra codepoints. */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_BUF = 4,
|
||||
|
||||
/** The resolved background color of the cell (GhosttyColorRgb).
|
||||
* Flattens the three possible sources: content-tag bg_color_rgb,
|
||||
* content-tag bg_color_palette (looked up in the palette), or the
|
||||
* style's bg_color. Returns GHOSTTY_INVALID_VALUE if the cell has
|
||||
* no background color, in which case the caller should use whatever
|
||||
* default background color it wants (e.g. the terminal background). */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_BG_COLOR = 5,
|
||||
|
||||
/** The resolved foreground color of the cell (GhosttyColorRgb).
|
||||
* Resolves palette indices through the palette. Bold color handling
|
||||
* is not applied; the caller should handle bold styling separately.
|
||||
* Returns GHOSTTY_INVALID_VALUE if the cell has no explicit foreground
|
||||
* color, in which case the caller should use whatever default foreground
|
||||
* color it wants (e.g. the terminal foreground). */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_FG_COLOR = 6,
|
||||
|
||||
/** Whether the cell is contained within the current selection (bool).
|
||||
* This returns true when the cell's column is within the current row's
|
||||
* row-local selection range, and false otherwise. Rendering policy for
|
||||
* selected cells (colors, inversion, etc.) is left to the caller.
|
||||
*
|
||||
* Renderers that can draw cells in spans may be more efficient querying
|
||||
* GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION once per row and applying that
|
||||
* range directly, avoiding one C API call per cell for selection state. */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_SELECTED = 7,
|
||||
|
||||
/** Whether the cell has any explicit styling (bool).
|
||||
* This is equivalent to querying the raw cell's
|
||||
* GHOSTTY_CELL_DATA_HAS_STYLING value, but avoids materializing the raw
|
||||
* GhosttyCell for renderers that only need to know whether fetching the
|
||||
* full style is necessary. */
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_HAS_STYLING = 8,
|
||||
|
||||
/**
|
||||
* Encode the current cell's full grapheme cluster as UTF-8 into a
|
||||
* caller-provided buffer (GhosttyBuffer).
|
||||
*
|
||||
* The base codepoint is encoded first, followed by any extra grapheme
|
||||
* codepoints. Returns GHOSTTY_SUCCESS with len=0 when the cell has no text.
|
||||
*
|
||||
* If ptr is NULL or cap is too small for a non-empty cell, returns
|
||||
* GHOSTTY_OUT_OF_SPACE without writing any bytes and sets len to the required
|
||||
* buffer size in bytes.
|
||||
*/
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_GRAPHEMES_UTF8 = 9,
|
||||
GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateRowCellsData;
|
||||
|
||||
/**
|
||||
* Move a render-state row cells iterator to the next cell.
|
||||
*
|
||||
* Returns true if the iterator moved successfully and cell data is
|
||||
* available to read at the new position.
|
||||
*
|
||||
* @param cells The row cells handle to advance (may be NULL)
|
||||
* @return true if advanced to the next cell, false if `cells` is
|
||||
* NULL or if the iterator has reached the end
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_render_state_row_cells_next(GhosttyRenderStateRowCells cells);
|
||||
|
||||
/**
|
||||
* Move a render-state row cells iterator to a specific column.
|
||||
*
|
||||
* Positions the iterator at the given x (column) index so that
|
||||
* subsequent reads return data for that cell.
|
||||
*
|
||||
* @param cells The row cells handle to reposition (NULL returns
|
||||
* GHOSTTY_INVALID_VALUE)
|
||||
* @param x The zero-based column index to select
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if `cells`
|
||||
* is NULL or `x` is out of range
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_select(
|
||||
GhosttyRenderStateRowCells cells, uint16_t x);
|
||||
|
||||
/**
|
||||
* Get a value from the current cell in a render-state row cells iterator.
|
||||
*
|
||||
* The `out` pointer must point to a value of the type corresponding to the
|
||||
* requested data kind (see GhosttyRenderStateRowCellsData).
|
||||
* Call ghostty_render_state_row_cells_next() or
|
||||
* ghostty_render_state_row_cells_select() at least once before
|
||||
* calling this function.
|
||||
*
|
||||
* @param cells The row cells handle to query (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param data The data kind to query
|
||||
* @param[out] out Pointer to receive the queried value
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if
|
||||
* `cells` is NULL or the iterator is not positioned on a cell
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_get(
|
||||
GhosttyRenderStateRowCells cells,
|
||||
GhosttyRenderStateRowCellsData data,
|
||||
void* out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from the current cell in a single call.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param cells The row cells handle (NULL returns GHOSTTY_INVALID_VALUE)
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_get_multi(
|
||||
GhosttyRenderStateRowCells cells,
|
||||
size_t count,
|
||||
const GhosttyRenderStateRowCellsData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Free a row cells instance.
|
||||
*
|
||||
* @param cells The row cells handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
GHOSTTY_API void ghostty_render_state_row_cells_free(GhosttyRenderStateRowCells cells);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_RENDER_H */
|
||||
@@ -0,0 +1,400 @@
|
||||
/**
|
||||
* @file screen.h
|
||||
*
|
||||
* Terminal screen cell and row types.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_SCREEN_H
|
||||
#define GHOSTTY_VT_SCREEN_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup screen Screen
|
||||
*
|
||||
* Terminal screen cell and row types.
|
||||
*
|
||||
* These types represent the contents of a terminal screen. A GhosttyCell
|
||||
* is a single grid cell and a GhosttyRow is a single row. Both are opaque
|
||||
* values whose fields are accessed via ghostty_cell_get() and
|
||||
* ghostty_row_get() respectively.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Opaque cell value.
|
||||
*
|
||||
* Represents a single terminal cell. The internal layout is opaque and
|
||||
* must be queried via ghostty_cell_get(). Obtain cell values from
|
||||
* terminal query APIs.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef uint64_t GhosttyCell;
|
||||
|
||||
/**
|
||||
* Opaque row value.
|
||||
*
|
||||
* Represents a single terminal row. The internal layout is opaque and
|
||||
* must be queried via ghostty_row_get(). Obtain row values from
|
||||
* terminal query APIs.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef uint64_t GhosttyRow;
|
||||
|
||||
/**
|
||||
* Cell content tag.
|
||||
*
|
||||
* Describes what kind of content a cell holds.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** A single codepoint (may be zero for empty). */
|
||||
GHOSTTY_CELL_CONTENT_CODEPOINT = 0,
|
||||
|
||||
/** A codepoint that is part of a multi-codepoint grapheme cluster. */
|
||||
GHOSTTY_CELL_CONTENT_CODEPOINT_GRAPHEME = 1,
|
||||
|
||||
/** No text; background color from palette. */
|
||||
GHOSTTY_CELL_CONTENT_BG_COLOR_PALETTE = 2,
|
||||
|
||||
/** No text; background color as RGB. */
|
||||
GHOSTTY_CELL_CONTENT_BG_COLOR_RGB = 3,
|
||||
GHOSTTY_CELL_CONTENT_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyCellContentTag;
|
||||
|
||||
/**
|
||||
* Cell wide property.
|
||||
*
|
||||
* Describes the width behavior of a cell.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Not a wide character, cell width 1. */
|
||||
GHOSTTY_CELL_WIDE_NARROW = 0,
|
||||
|
||||
/** Wide character, cell width 2. */
|
||||
GHOSTTY_CELL_WIDE_WIDE = 1,
|
||||
|
||||
/** Spacer after wide character. Do not render. */
|
||||
GHOSTTY_CELL_WIDE_SPACER_TAIL = 2,
|
||||
|
||||
/** Spacer at end of soft-wrapped line for a wide character. */
|
||||
GHOSTTY_CELL_WIDE_SPACER_HEAD = 3,
|
||||
GHOSTTY_CELL_WIDE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyCellWide;
|
||||
|
||||
/**
|
||||
* Semantic content type of a cell.
|
||||
*
|
||||
* Set by semantic prompt sequences (OSC 133) to distinguish between
|
||||
* command output, user input, and shell prompt text.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Regular output content, such as command output. */
|
||||
GHOSTTY_CELL_SEMANTIC_OUTPUT = 0,
|
||||
|
||||
/** Content that is part of user input. */
|
||||
GHOSTTY_CELL_SEMANTIC_INPUT = 1,
|
||||
|
||||
/** Content that is part of a shell prompt. */
|
||||
GHOSTTY_CELL_SEMANTIC_PROMPT = 2,
|
||||
GHOSTTY_CELL_SEMANTIC_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyCellSemanticContent;
|
||||
|
||||
/**
|
||||
* Cell data types.
|
||||
*
|
||||
* These values specify what type of data to extract from a cell
|
||||
* using `ghostty_cell_get`.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid data type. Never results in any data extraction. */
|
||||
GHOSTTY_CELL_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* The codepoint of the cell (0 if empty or bg-color-only).
|
||||
*
|
||||
* Output type: uint32_t *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_CODEPOINT = 1,
|
||||
|
||||
/**
|
||||
* The content tag describing what kind of content is in the cell.
|
||||
*
|
||||
* Output type: GhosttyCellContentTag *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_CONTENT_TAG = 2,
|
||||
|
||||
/**
|
||||
* The wide property of the cell.
|
||||
*
|
||||
* Output type: GhosttyCellWide *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_WIDE = 3,
|
||||
|
||||
/**
|
||||
* Whether the cell has text to render.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_HAS_TEXT = 4,
|
||||
|
||||
/**
|
||||
* Whether the cell has non-default styling.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_HAS_STYLING = 5,
|
||||
|
||||
/**
|
||||
* The style ID for the cell (for use with style lookups).
|
||||
*
|
||||
* Output type: uint16_t *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_STYLE_ID = 6,
|
||||
|
||||
/**
|
||||
* Whether the cell has a hyperlink.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_HAS_HYPERLINK = 7,
|
||||
|
||||
/**
|
||||
* Whether the cell is protected.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_PROTECTED = 8,
|
||||
|
||||
/**
|
||||
* The semantic content type of the cell (from OSC 133).
|
||||
*
|
||||
* Output type: GhosttyCellSemanticContent *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_SEMANTIC_CONTENT = 9,
|
||||
|
||||
/**
|
||||
* The palette index for the cell's background color.
|
||||
* Only valid when content_tag is GHOSTTY_CELL_CONTENT_BG_COLOR_PALETTE.
|
||||
*
|
||||
* Output type: GhosttyColorPaletteIndex *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_COLOR_PALETTE = 10,
|
||||
|
||||
/**
|
||||
* The RGB value for the cell's background color.
|
||||
* Only valid when content_tag is GHOSTTY_CELL_CONTENT_BG_COLOR_RGB.
|
||||
*
|
||||
* Output type: GhosttyColorRgb *
|
||||
*/
|
||||
GHOSTTY_CELL_DATA_COLOR_RGB = 11,
|
||||
GHOSTTY_CELL_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyCellData;
|
||||
|
||||
/**
|
||||
* Row semantic prompt state.
|
||||
*
|
||||
* Indicates whether any cells in a row are part of a shell prompt,
|
||||
* as reported by OSC 133 sequences.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** No prompt cells in this row. */
|
||||
GHOSTTY_ROW_SEMANTIC_NONE = 0,
|
||||
|
||||
/** Prompt cells exist and this is a primary prompt line. */
|
||||
GHOSTTY_ROW_SEMANTIC_PROMPT = 1,
|
||||
|
||||
/** Prompt cells exist and this is a continuation line. */
|
||||
GHOSTTY_ROW_SEMANTIC_PROMPT_CONTINUATION = 2,
|
||||
GHOSTTY_ROW_SEMANTIC_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRowSemanticPrompt;
|
||||
|
||||
/**
|
||||
* Row data types.
|
||||
*
|
||||
* These values specify what type of data to extract from a row
|
||||
* using `ghostty_row_get`.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Invalid data type. Never results in any data extraction. */
|
||||
GHOSTTY_ROW_DATA_INVALID = 0,
|
||||
|
||||
/**
|
||||
* Whether this row is soft-wrapped.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_WRAP = 1,
|
||||
|
||||
/**
|
||||
* Whether this row is a continuation of a soft-wrapped row.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_WRAP_CONTINUATION = 2,
|
||||
|
||||
/**
|
||||
* Whether any cells in this row have grapheme clusters.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_GRAPHEME = 3,
|
||||
|
||||
/**
|
||||
* Whether any cells in this row have styling (may have false positives).
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_STYLED = 4,
|
||||
|
||||
/**
|
||||
* Whether any cells in this row have hyperlinks (may have false positives).
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_HYPERLINK = 5,
|
||||
|
||||
/**
|
||||
* The semantic prompt state of this row.
|
||||
*
|
||||
* Output type: GhosttyRowSemanticPrompt *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_SEMANTIC_PROMPT = 6,
|
||||
|
||||
/**
|
||||
* Whether this row contains a Kitty virtual placeholder.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_KITTY_VIRTUAL_PLACEHOLDER = 7,
|
||||
|
||||
/**
|
||||
* Whether this row is dirty and requires a redraw.
|
||||
*
|
||||
* Output type: bool *
|
||||
*/
|
||||
GHOSTTY_ROW_DATA_DIRTY = 8,
|
||||
GHOSTTY_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRowData;
|
||||
|
||||
/**
|
||||
* Get data from a cell.
|
||||
*
|
||||
* Extracts typed data from the given cell based on the specified
|
||||
* data type. The output pointer must be of the appropriate type for the
|
||||
* requested data kind. Valid data types and output types are documented
|
||||
* in the `GhosttyCellData` enum.
|
||||
*
|
||||
* @param cell The cell value
|
||||
* @param data The type of data to extract
|
||||
* @param out Pointer to store the extracted data (type depends on data parameter)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
|
||||
* data type is invalid
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_cell_get(GhosttyCell cell,
|
||||
GhosttyCellData data,
|
||||
void *out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from a cell in a single call.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param cell The cell value
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_cell_get_multi(GhosttyCell cell,
|
||||
size_t count,
|
||||
const GhosttyCellData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/**
|
||||
* Get data from a row.
|
||||
*
|
||||
* Extracts typed data from the given row based on the specified
|
||||
* data type. The output pointer must be of the appropriate type for the
|
||||
* requested data kind. Valid data types and output types are documented
|
||||
* in the `GhosttyRowData` enum.
|
||||
*
|
||||
* @param row The row value
|
||||
* @param data The type of data to extract
|
||||
* @param out Pointer to store the extracted data (type depends on data parameter)
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
|
||||
* data type is invalid
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_row_get(GhosttyRow row,
|
||||
GhosttyRowData data,
|
||||
void *out);
|
||||
|
||||
/**
|
||||
* Get multiple data fields from a row in a single call.
|
||||
*
|
||||
* Each element in the keys array specifies a data kind, and the
|
||||
* corresponding element in the values array receives the result.
|
||||
*
|
||||
* Processing stops at the first error; on success out_written
|
||||
* is set to count, on error it is set to the index of the
|
||||
* failing key (i.e. the number of values successfully written).
|
||||
*
|
||||
* @param row The row value
|
||||
* @param count Number of key/value pairs
|
||||
* @param keys Array of data kinds to query
|
||||
* @param values Array of output pointers (types must match each key's
|
||||
* documented output type)
|
||||
* @param[out] out_written On return, receives the number of values
|
||||
* successfully written (may be NULL)
|
||||
* @return GHOSTTY_SUCCESS if all queries succeed
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_row_get_multi(GhosttyRow row,
|
||||
size_t count,
|
||||
const GhosttyRowData* keys,
|
||||
void** values,
|
||||
size_t* out_written);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_SCREEN_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,353 @@
|
||||
/**
|
||||
* @file sgr.h
|
||||
*
|
||||
* SGR (Select Graphic Rendition) attribute parsing and handling.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_SGR_H
|
||||
#define GHOSTTY_VT_SGR_H
|
||||
|
||||
/** @defgroup sgr SGR Parser
|
||||
*
|
||||
* SGR (Select Graphic Rendition) attribute parser.
|
||||
*
|
||||
* SGR sequences are the syntax used to set styling attributes such as
|
||||
* bold, italic, underline, and colors for text in terminal emulators.
|
||||
* For example, you may be familiar with sequences like `ESC[1;31m`. The
|
||||
* `1;31` is the SGR attribute list.
|
||||
*
|
||||
* The parser processes SGR parameters from CSI sequences (e.g., `ESC[1;31m`)
|
||||
* and returns individual text attributes like bold, italic, colors, etc.
|
||||
* It supports both semicolon (`;`) and colon (`:`) separators, possibly mixed,
|
||||
* and handles SGR color attributes including 8-color, 16-color, 256-color,
|
||||
* direct RGB, underline color, and reset forms. Color values are returned
|
||||
* using the shared @ref color types; applications that need to parse Ghostty
|
||||
* config/theme color strings, generate palettes, inspect X11 color names, or
|
||||
* calculate luminance and contrast should use the @ref color APIs directly.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* 1. Create a parser instance with ghostty_sgr_new()
|
||||
* 2. Set SGR parameters with ghostty_sgr_set_params()
|
||||
* 3. Iterate through attributes using ghostty_sgr_next()
|
||||
* 4. Free the parser with ghostty_sgr_free() when done
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-sgr/src/main.c sgr-basic
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SGR attribute tags.
|
||||
*
|
||||
* These values identify the type of an SGR attribute in a tagged union.
|
||||
* Use the tag to determine which field in the attribute value union to access.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_SGR_ATTR_UNSET = 0,
|
||||
GHOSTTY_SGR_ATTR_UNKNOWN = 1,
|
||||
GHOSTTY_SGR_ATTR_BOLD = 2,
|
||||
GHOSTTY_SGR_ATTR_RESET_BOLD = 3,
|
||||
GHOSTTY_SGR_ATTR_ITALIC = 4,
|
||||
GHOSTTY_SGR_ATTR_RESET_ITALIC = 5,
|
||||
GHOSTTY_SGR_ATTR_FAINT = 6,
|
||||
GHOSTTY_SGR_ATTR_UNDERLINE = 7,
|
||||
GHOSTTY_SGR_ATTR_UNDERLINE_COLOR = 8,
|
||||
GHOSTTY_SGR_ATTR_UNDERLINE_COLOR_256 = 9,
|
||||
GHOSTTY_SGR_ATTR_RESET_UNDERLINE_COLOR = 10,
|
||||
GHOSTTY_SGR_ATTR_OVERLINE = 11,
|
||||
GHOSTTY_SGR_ATTR_RESET_OVERLINE = 12,
|
||||
GHOSTTY_SGR_ATTR_BLINK = 13,
|
||||
GHOSTTY_SGR_ATTR_RESET_BLINK = 14,
|
||||
GHOSTTY_SGR_ATTR_INVERSE = 15,
|
||||
GHOSTTY_SGR_ATTR_RESET_INVERSE = 16,
|
||||
GHOSTTY_SGR_ATTR_INVISIBLE = 17,
|
||||
GHOSTTY_SGR_ATTR_RESET_INVISIBLE = 18,
|
||||
GHOSTTY_SGR_ATTR_STRIKETHROUGH = 19,
|
||||
GHOSTTY_SGR_ATTR_RESET_STRIKETHROUGH = 20,
|
||||
GHOSTTY_SGR_ATTR_DIRECT_COLOR_FG = 21,
|
||||
GHOSTTY_SGR_ATTR_DIRECT_COLOR_BG = 22,
|
||||
GHOSTTY_SGR_ATTR_BG_8 = 23,
|
||||
GHOSTTY_SGR_ATTR_FG_8 = 24,
|
||||
GHOSTTY_SGR_ATTR_RESET_FG = 25,
|
||||
GHOSTTY_SGR_ATTR_RESET_BG = 26,
|
||||
GHOSTTY_SGR_ATTR_BRIGHT_BG_8 = 27,
|
||||
GHOSTTY_SGR_ATTR_BRIGHT_FG_8 = 28,
|
||||
GHOSTTY_SGR_ATTR_BG_256 = 29,
|
||||
GHOSTTY_SGR_ATTR_FG_256 = 30,
|
||||
GHOSTTY_SGR_ATTR_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttySgrAttributeTag;
|
||||
|
||||
/**
|
||||
* Underline style types.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_SGR_UNDERLINE_NONE = 0,
|
||||
GHOSTTY_SGR_UNDERLINE_SINGLE = 1,
|
||||
GHOSTTY_SGR_UNDERLINE_DOUBLE = 2,
|
||||
GHOSTTY_SGR_UNDERLINE_CURLY = 3,
|
||||
GHOSTTY_SGR_UNDERLINE_DOTTED = 4,
|
||||
GHOSTTY_SGR_UNDERLINE_DASHED = 5,
|
||||
GHOSTTY_SGR_UNDERLINE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttySgrUnderline;
|
||||
|
||||
/**
|
||||
* Unknown SGR attribute data.
|
||||
*
|
||||
* Contains the full parameter list and the partial list where parsing
|
||||
* encountered an unknown or invalid sequence.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef struct {
|
||||
const uint16_t* full_ptr;
|
||||
size_t full_len;
|
||||
const uint16_t* partial_ptr;
|
||||
size_t partial_len;
|
||||
} GhosttySgrUnknown;
|
||||
|
||||
/**
|
||||
* SGR attribute value union.
|
||||
*
|
||||
* This union contains all possible attribute values. Use the tag field
|
||||
* to determine which union member is active. Attributes without associated
|
||||
* data (like bold, italic) don't use the union value.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef union {
|
||||
GhosttySgrUnknown unknown;
|
||||
GhosttySgrUnderline underline;
|
||||
GhosttyColorRgb underline_color;
|
||||
GhosttyColorPaletteIndex underline_color_256;
|
||||
GhosttyColorRgb direct_color_fg;
|
||||
GhosttyColorRgb direct_color_bg;
|
||||
GhosttyColorPaletteIndex bg_8;
|
||||
GhosttyColorPaletteIndex fg_8;
|
||||
GhosttyColorPaletteIndex bright_bg_8;
|
||||
GhosttyColorPaletteIndex bright_fg_8;
|
||||
GhosttyColorPaletteIndex bg_256;
|
||||
GhosttyColorPaletteIndex fg_256;
|
||||
uint64_t _padding[8];
|
||||
} GhosttySgrAttributeValue;
|
||||
|
||||
/**
|
||||
* SGR attribute (tagged union).
|
||||
*
|
||||
* A complete SGR attribute with both its type tag and associated value.
|
||||
* Always check the tag field to determine which value union member is valid.
|
||||
*
|
||||
* Attributes without associated data (e.g., GHOSTTY_SGR_ATTR_BOLD) can be
|
||||
* identified by tag alone; the value union is not used for these and
|
||||
* the memory in the value field is undefined.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef struct {
|
||||
GhosttySgrAttributeTag tag;
|
||||
GhosttySgrAttributeValue value;
|
||||
} GhosttySgrAttribute;
|
||||
|
||||
/**
|
||||
* Create a new SGR parser instance.
|
||||
*
|
||||
* Creates a new SGR (Select Graphic Rendition) parser using the provided
|
||||
* allocator. The parser must be freed using ghostty_sgr_free() when
|
||||
* no longer needed.
|
||||
*
|
||||
* @param allocator Pointer to the allocator to use for memory management, or
|
||||
* NULL to use the default allocator
|
||||
* @param parser Pointer to store the created parser handle
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_sgr_new(const GhosttyAllocator* allocator,
|
||||
GhosttySgrParser* parser);
|
||||
|
||||
/**
|
||||
* Free an SGR parser instance.
|
||||
*
|
||||
* Releases all resources associated with the SGR parser. After this call,
|
||||
* the parser handle becomes invalid and must not be used. This includes
|
||||
* any attributes previously returned by ghostty_sgr_next().
|
||||
*
|
||||
* @param parser The parser handle to free (may be NULL)
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API void ghostty_sgr_free(GhosttySgrParser parser);
|
||||
|
||||
/**
|
||||
* Reset an SGR parser instance to the beginning of the parameter list.
|
||||
*
|
||||
* Resets the parser's iteration state without clearing the parameters.
|
||||
* After calling this, ghostty_sgr_next() will start from the beginning
|
||||
* of the parameter list again.
|
||||
*
|
||||
* @param parser The parser handle to reset, must not be NULL
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API void ghostty_sgr_reset(GhosttySgrParser parser);
|
||||
|
||||
/**
|
||||
* Set SGR parameters for parsing.
|
||||
*
|
||||
* Sets the SGR parameter list to parse. Parameters are the numeric values
|
||||
* from a CSI SGR sequence (e.g., for `ESC[1;31m`, params would be {1, 31}).
|
||||
*
|
||||
* The separators array optionally specifies the separator type for each
|
||||
* parameter position. Each byte should be either ';' for semicolon or ':'
|
||||
* for colon. This is needed for certain color formats that use colon
|
||||
* separators (e.g., `ESC[4:3m` for curly underline). Any invalid separator
|
||||
* values are treated as semicolons. The separators array must have the same
|
||||
* length as the params array, if it is not NULL.
|
||||
*
|
||||
* If separators is NULL, all parameters are assumed to be semicolon-separated.
|
||||
*
|
||||
* This function makes an internal copy of the parameter and separator data,
|
||||
* so the caller can safely free or modify the input arrays after this call.
|
||||
*
|
||||
* After calling this function, the parser is automatically reset and ready
|
||||
* to iterate from the beginning.
|
||||
*
|
||||
* @param parser The parser handle, must not be NULL
|
||||
* @param params Array of SGR parameter values
|
||||
* @param separators Optional array of separator characters (';' or ':'), or
|
||||
* NULL
|
||||
* @param len Number of parameters (and separators if provided)
|
||||
* @return GHOSTTY_SUCCESS on success, or an error code on failure
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_sgr_set_params(GhosttySgrParser parser,
|
||||
const uint16_t* params,
|
||||
const char* separators,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* Get the next SGR attribute.
|
||||
*
|
||||
* Parses and returns the next attribute from the parameter list.
|
||||
* Call this function repeatedly until it returns false to process
|
||||
* all attributes in the sequence.
|
||||
*
|
||||
* @param parser The parser handle, must not be NULL
|
||||
* @param attr Pointer to store the next attribute
|
||||
* @return true if an attribute was returned, false if no more attributes
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_sgr_next(GhosttySgrParser parser, GhosttySgrAttribute* attr);
|
||||
|
||||
/**
|
||||
* Get the full parameter list from an unknown SGR attribute.
|
||||
*
|
||||
* This function retrieves the full parameter list that was provided to the
|
||||
* parser when an unknown attribute was encountered. Primarily useful in
|
||||
* WebAssembly environments where accessing struct fields directly is difficult.
|
||||
*
|
||||
* @param unknown The unknown attribute data
|
||||
* @param ptr Pointer to store the pointer to the parameter array (may be NULL)
|
||||
* @return The length of the full parameter array
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API size_t ghostty_sgr_unknown_full(GhosttySgrUnknown unknown,
|
||||
const uint16_t** ptr);
|
||||
|
||||
/**
|
||||
* Get the partial parameter list from an unknown SGR attribute.
|
||||
*
|
||||
* This function retrieves the partial parameter list where parsing stopped
|
||||
* when an unknown attribute was encountered. Primarily useful in WebAssembly
|
||||
* environments where accessing struct fields directly is difficult.
|
||||
*
|
||||
* @param unknown The unknown attribute data
|
||||
* @param ptr Pointer to store the pointer to the parameter array (may be NULL)
|
||||
* @return The length of the partial parameter array
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API size_t ghostty_sgr_unknown_partial(GhosttySgrUnknown unknown,
|
||||
const uint16_t** ptr);
|
||||
|
||||
/**
|
||||
* Get the tag from an SGR attribute.
|
||||
*
|
||||
* This function extracts the tag that identifies which type of attribute
|
||||
* this is. Primarily useful in WebAssembly environments where accessing
|
||||
* struct fields directly is difficult.
|
||||
*
|
||||
* @param attr The SGR attribute
|
||||
* @return The attribute tag
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API GhosttySgrAttributeTag ghostty_sgr_attribute_tag(GhosttySgrAttribute attr);
|
||||
|
||||
/**
|
||||
* Get the value from an SGR attribute.
|
||||
*
|
||||
* This function returns a pointer to the value union from an SGR attribute. Use
|
||||
* the tag to determine which field of the union is valid. Primarily useful in
|
||||
* WebAssembly environments where accessing struct fields directly is difficult.
|
||||
*
|
||||
* @param attr Pointer to the SGR attribute
|
||||
* @return Pointer to the attribute value union
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
GHOSTTY_API GhosttySgrAttributeValue* ghostty_sgr_attribute_value(
|
||||
GhosttySgrAttribute* attr);
|
||||
|
||||
#ifdef __wasm__
|
||||
/**
|
||||
* Allocate memory for an SGR attribute (WebAssembly only).
|
||||
*
|
||||
* This is a convenience function for WebAssembly environments to allocate
|
||||
* memory for an SGR attribute structure that can be passed to ghostty_sgr_next.
|
||||
*
|
||||
* @return Pointer to the allocated attribute structure
|
||||
*
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API GhosttySgrAttribute* ghostty_wasm_alloc_sgr_attribute(void);
|
||||
|
||||
/**
|
||||
* Free memory for an SGR attribute (WebAssembly only).
|
||||
*
|
||||
* Frees memory allocated by ghostty_wasm_alloc_sgr_attribute.
|
||||
*
|
||||
* @param attr Pointer to the attribute structure to free
|
||||
*
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_sgr_attribute(GhosttySgrAttribute* attr);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_SGR_H */
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file size_report.h
|
||||
*
|
||||
* Size report encoding - encode terminal size reports into escape sequences.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_SIZE_REPORT_H
|
||||
#define GHOSTTY_VT_SIZE_REPORT_H
|
||||
|
||||
/** @defgroup size_report Size Report Encoding
|
||||
*
|
||||
* Utilities for encoding terminal size reports into escape sequences,
|
||||
* supporting in-band size reports (mode 2048) and XTWINOPS responses
|
||||
* (CSI 14 t, CSI 16 t, CSI 18 t).
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_size_report_encode() to encode a size report into a
|
||||
* caller-provided buffer. If the buffer is too small, the function
|
||||
* returns GHOSTTY_OUT_OF_SPACE and sets the required size in the
|
||||
* output parameter.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @snippet c-vt-size-report/src/main.c size-report-encode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Size report style.
|
||||
*
|
||||
* Determines the output format for the terminal size report.
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** In-band size report (mode 2048): ESC [ 48 ; rows ; cols ; height ; width t */
|
||||
GHOSTTY_SIZE_REPORT_MODE_2048 = 0,
|
||||
/** XTWINOPS text area size in pixels: ESC [ 4 ; height ; width t */
|
||||
GHOSTTY_SIZE_REPORT_CSI_14_T = 1,
|
||||
/** XTWINOPS cell size in pixels: ESC [ 6 ; height ; width t */
|
||||
GHOSTTY_SIZE_REPORT_CSI_16_T = 2,
|
||||
/** XTWINOPS text area size in characters: ESC [ 8 ; rows ; cols t */
|
||||
GHOSTTY_SIZE_REPORT_CSI_18_T = 3,
|
||||
GHOSTTY_SIZE_REPORT_STYLE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttySizeReportStyle;
|
||||
|
||||
/**
|
||||
* Terminal size information for encoding size reports.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Terminal row count in cells. */
|
||||
uint16_t rows;
|
||||
/** Terminal column count in cells. */
|
||||
uint16_t columns;
|
||||
/** Width of a single terminal cell in pixels. */
|
||||
uint32_t cell_width;
|
||||
/** Height of a single terminal cell in pixels. */
|
||||
uint32_t cell_height;
|
||||
} GhosttySizeReportSize;
|
||||
|
||||
/**
|
||||
* Encode a terminal size report into an escape sequence.
|
||||
*
|
||||
* Encodes a size report in the format specified by @p style into the
|
||||
* provided buffer.
|
||||
*
|
||||
* If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE
|
||||
* and writes the required buffer size to @p out_written. The caller can
|
||||
* then retry with a sufficiently sized buffer.
|
||||
*
|
||||
* @param style The size report format to encode
|
||||
* @param size Terminal size information
|
||||
* @param buf Output buffer to write the encoded sequence into (may be NULL)
|
||||
* @param buf_len Size of the output buffer in bytes
|
||||
* @param[out] out_written On success, the number of bytes written. On
|
||||
* GHOSTTY_OUT_OF_SPACE, the required buffer size.
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer
|
||||
* is too small
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_size_report_encode(
|
||||
GhosttySizeReportStyle style,
|
||||
GhosttySizeReportSize size,
|
||||
char* buf,
|
||||
size_t buf_len,
|
||||
size_t* out_written);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_SIZE_REPORT_H */
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* @file style.h
|
||||
*
|
||||
* Terminal cell style types.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_STYLE_H
|
||||
#define GHOSTTY_VT_STYLE_H
|
||||
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup style Style
|
||||
*
|
||||
* Terminal cell style attributes.
|
||||
*
|
||||
* A style describes the visual attributes of a terminal cell, including
|
||||
* foreground, background, and underline colors, as well as flags for
|
||||
* bold, italic, underline, and other text decorations.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Style identifier type.
|
||||
*
|
||||
* Used to look up the full style from a grid reference.
|
||||
* Obtain this from a cell via GHOSTTY_CELL_DATA_STYLE_ID.
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
typedef uint16_t GhosttyStyleId;
|
||||
|
||||
/**
|
||||
* Style color tags.
|
||||
*
|
||||
* These values identify the type of color in a style color.
|
||||
* Use the tag to determine which field in the color value union to access.
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_STYLE_COLOR_NONE = 0,
|
||||
GHOSTTY_STYLE_COLOR_PALETTE = 1,
|
||||
GHOSTTY_STYLE_COLOR_RGB = 2,
|
||||
GHOSTTY_STYLE_COLOR_TAG_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyStyleColorTag;
|
||||
|
||||
/**
|
||||
* Style color value union.
|
||||
*
|
||||
* Use the tag to determine which field is active.
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
typedef union {
|
||||
GhosttyColorPaletteIndex palette;
|
||||
GhosttyColorRgb rgb;
|
||||
uint64_t _padding;
|
||||
} GhosttyStyleColorValue;
|
||||
|
||||
/**
|
||||
* Style color (tagged union).
|
||||
*
|
||||
* A color used in a style attribute. Can be unset (none), a palette
|
||||
* index, or a direct RGB value.
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
typedef struct {
|
||||
GhosttyStyleColorTag tag;
|
||||
GhosttyStyleColorValue value;
|
||||
} GhosttyStyleColor;
|
||||
|
||||
/**
|
||||
* Terminal cell style.
|
||||
*
|
||||
* Describes the complete visual style for a terminal cell, including
|
||||
* foreground, background, and underline colors, as well as text
|
||||
* decoration flags. The underline field uses the same values as
|
||||
* GhosttySgrUnderline.
|
||||
*
|
||||
* This is a sized struct. Use GHOSTTY_INIT_SIZED() to initialize it.
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
typedef struct {
|
||||
size_t size;
|
||||
GhosttyStyleColor fg_color;
|
||||
GhosttyStyleColor bg_color;
|
||||
GhosttyStyleColor underline_color;
|
||||
bool bold;
|
||||
bool italic;
|
||||
bool faint;
|
||||
bool blink;
|
||||
bool inverse;
|
||||
bool invisible;
|
||||
bool strikethrough;
|
||||
bool overline;
|
||||
int underline; /**< One of GHOSTTY_SGR_UNDERLINE_* values */
|
||||
} GhosttyStyle;
|
||||
|
||||
/**
|
||||
* Get the default style.
|
||||
*
|
||||
* Initializes the style to the default values (no colors, no flags).
|
||||
*
|
||||
* @param style Pointer to the style to initialize
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
GHOSTTY_API void ghostty_style_default(GhosttyStyle* style);
|
||||
|
||||
/**
|
||||
* Check if a style is the default style.
|
||||
*
|
||||
* Returns true if all colors are unset and all flags are off.
|
||||
*
|
||||
* @param style Pointer to the style to check
|
||||
* @return true if the style is the default style
|
||||
*
|
||||
* @ingroup style
|
||||
*/
|
||||
GHOSTTY_API bool ghostty_style_is_default(const GhosttyStyle* style);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_STYLE_H */
|
||||
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* @file sys.h
|
||||
*
|
||||
* System interface - runtime-swappable implementations for external dependencies.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_SYS_H
|
||||
#define GHOSTTY_VT_SYS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
|
||||
/** @defgroup sys System Interface
|
||||
*
|
||||
* Runtime-swappable function pointers for operations that depend on
|
||||
* external implementations (e.g. image decoding).
|
||||
*
|
||||
* These are process-global settings that must be configured at startup
|
||||
* before any terminal functionality that depends on them is used.
|
||||
* Setting these enables various optional features of the terminal. For
|
||||
* example, setting a PNG decoder enables PNG image support in the Kitty
|
||||
* Graphics Protocol.
|
||||
*
|
||||
* Use ghostty_sys_set() with a `GhosttySysOption` to install or clear
|
||||
* an implementation. Passing NULL as the value clears the implementation
|
||||
* and disables the corresponding feature.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ### Defining a PNG decode callback
|
||||
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-decode-png
|
||||
*
|
||||
* ### Installing the callback and sending a PNG image
|
||||
* @snippet c-vt-kitty-graphics/src/main.c kitty-graphics-main
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Result of decoding an image.
|
||||
*
|
||||
* The `data` buffer must be allocated through the allocator provided to
|
||||
* the decode callback. The library takes ownership and will free it
|
||||
* with the same allocator.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Image width in pixels. */
|
||||
uint32_t width;
|
||||
|
||||
/** Image height in pixels. */
|
||||
uint32_t height;
|
||||
|
||||
/** Pointer to the decoded RGBA pixel data. */
|
||||
uint8_t* data;
|
||||
|
||||
/** Length of the pixel data in bytes. */
|
||||
size_t data_len;
|
||||
} GhosttySysImage;
|
||||
|
||||
/**
|
||||
* Log severity levels for the log callback.
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
GHOSTTY_SYS_LOG_LEVEL_ERROR = 0,
|
||||
GHOSTTY_SYS_LOG_LEVEL_WARNING = 1,
|
||||
GHOSTTY_SYS_LOG_LEVEL_INFO = 2,
|
||||
GHOSTTY_SYS_LOG_LEVEL_DEBUG = 3,
|
||||
GHOSTTY_SYS_LOG_LEVEL_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttySysLogLevel;
|
||||
|
||||
/**
|
||||
* Callback type for logging.
|
||||
*
|
||||
* When installed, internal library log messages are delivered through
|
||||
* this callback instead of being discarded. The embedder is responsible
|
||||
* for formatting and routing log output.
|
||||
*
|
||||
* @p scope is the log scope name as UTF-8 bytes (e.g. "osc", "kitty").
|
||||
* When the log is unscoped (default scope), @p scope_len is 0.
|
||||
*
|
||||
* All pointer arguments are only valid for the duration of the callback.
|
||||
* The callback must be safe to call from any thread.
|
||||
*
|
||||
* @param userdata The userdata pointer set via GHOSTTY_SYS_OPT_USERDATA
|
||||
* @param level The severity level of the log message
|
||||
* @param scope Pointer to the scope name bytes
|
||||
* @param scope_len Length of the scope name in bytes
|
||||
* @param message Pointer to the log message bytes
|
||||
* @param message_len Length of the log message in bytes
|
||||
*/
|
||||
typedef void (*GhosttySysLogFn)(
|
||||
void* userdata,
|
||||
GhosttySysLogLevel level,
|
||||
const uint8_t* scope,
|
||||
size_t scope_len,
|
||||
const uint8_t* message,
|
||||
size_t message_len);
|
||||
|
||||
/**
|
||||
* Callback type for PNG decoding.
|
||||
*
|
||||
* Decodes raw PNG data into RGBA pixels. The output pixel data must be
|
||||
* allocated through the provided allocator. The library takes ownership
|
||||
* of the buffer and will free it with the same allocator.
|
||||
*
|
||||
* @param userdata The userdata pointer set via GHOSTTY_SYS_OPT_USERDATA
|
||||
* @param allocator The allocator to use for the output pixel buffer
|
||||
* @param data Pointer to the raw PNG data
|
||||
* @param data_len Length of the raw PNG data in bytes
|
||||
* @param[out] out On success, filled with the decoded image
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
typedef bool (*GhosttySysDecodePngFn)(
|
||||
void* userdata,
|
||||
const GhosttyAllocator* allocator,
|
||||
const uint8_t* data,
|
||||
size_t data_len,
|
||||
GhosttySysImage* out);
|
||||
|
||||
/**
|
||||
* System option identifiers for ghostty_sys_set().
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/**
|
||||
* Set the userdata pointer passed to all sys callbacks.
|
||||
*
|
||||
* Input type: void* (or NULL)
|
||||
*/
|
||||
GHOSTTY_SYS_OPT_USERDATA = 0,
|
||||
|
||||
/**
|
||||
* Set the PNG decode function.
|
||||
*
|
||||
* When set, the terminal can accept PNG images via the Kitty
|
||||
* Graphics Protocol. When cleared (NULL value), PNG decoding is
|
||||
* unsupported and PNG image data will be rejected.
|
||||
*
|
||||
* Input type: GhosttySysDecodePngFn (function pointer, or NULL)
|
||||
*/
|
||||
GHOSTTY_SYS_OPT_DECODE_PNG = 1,
|
||||
|
||||
/**
|
||||
* Set the log callback.
|
||||
*
|
||||
* When set, internal library log messages are delivered to this
|
||||
* callback. When cleared (NULL value), log messages are silently
|
||||
* discarded.
|
||||
*
|
||||
* Use ghostty_sys_log_stderr as a convenience callback that
|
||||
* writes formatted messages to stderr.
|
||||
*
|
||||
* Which log levels are emitted depends on the build mode of the
|
||||
* library and is not configurable at runtime. Debug builds emit
|
||||
* all levels (debug and above). Release builds emit info and
|
||||
* above; debug-level messages are compiled out entirely and will
|
||||
* never reach the callback.
|
||||
*
|
||||
* Input type: GhosttySysLogFn (function pointer, or NULL)
|
||||
*/
|
||||
GHOSTTY_SYS_OPT_LOG = 2,
|
||||
GHOSTTY_SYS_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttySysOption;
|
||||
|
||||
/**
|
||||
* Set a system-level option.
|
||||
*
|
||||
* Configures a process-global implementation function. These should be
|
||||
* set once at startup before using any terminal functionality that
|
||||
* depends on them.
|
||||
*
|
||||
* @param option The option to set
|
||||
* @param value Pointer to the value (type depends on the option),
|
||||
* or NULL to clear it
|
||||
* @return GHOSTTY_SUCCESS on success, GHOSTTY_INVALID_VALUE if the
|
||||
* option is not recognized
|
||||
*/
|
||||
GHOSTTY_API GhosttyResult ghostty_sys_set(GhosttySysOption option,
|
||||
const void* value);
|
||||
|
||||
/**
|
||||
* Built-in log callback that writes to stderr.
|
||||
*
|
||||
* Formats each message as "[level](scope): message\n".
|
||||
* Can be passed directly to ghostty_sys_set():
|
||||
*
|
||||
* @code
|
||||
* ghostty_sys_set(GHOSTTY_SYS_OPT_LOG, &ghostty_sys_log_stderr);
|
||||
* @endcode
|
||||
*/
|
||||
GHOSTTY_API void ghostty_sys_log_stderr(void* userdata,
|
||||
GhosttySysLogLevel level,
|
||||
const uint8_t* scope,
|
||||
size_t scope_len,
|
||||
const uint8_t* message,
|
||||
size_t message_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_SYS_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,335 @@
|
||||
/**
|
||||
* @file types.h
|
||||
*
|
||||
* Common types, macros, and utilities for libghostty-vt.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_TYPES_H
|
||||
#define GHOSTTY_VT_TYPES_H
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Symbol visibility for shared library builds. On Windows, functions
|
||||
// are exported from the DLL when building and imported when consuming.
|
||||
// On other platforms with GCC/Clang, functions are marked with default
|
||||
// visibility so they remain accessible when the library is built with
|
||||
// -fvisibility=hidden. For static library builds, define GHOSTTY_STATIC
|
||||
// before including this header to make this a no-op.
|
||||
#ifndef GHOSTTY_API
|
||||
#if defined(GHOSTTY_STATIC)
|
||||
#define GHOSTTY_API
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
#ifdef GHOSTTY_BUILD_SHARED
|
||||
#define GHOSTTY_API __declspec(dllexport)
|
||||
#else
|
||||
#define GHOSTTY_API __declspec(dllimport)
|
||||
#endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
#define GHOSTTY_API __attribute__((visibility("default")))
|
||||
#else
|
||||
#define GHOSTTY_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Enum int-sizing helpers.
|
||||
*
|
||||
* The Zig side backs all C enums with c_int, so the C declarations
|
||||
* must use int as their underlying type to maintain ABI compatibility.
|
||||
*
|
||||
* C23 (detected via __STDC_VERSION__ >= 202311L) supports explicit
|
||||
* enum underlying types with `enum : int { ... }`. For pre-C23
|
||||
* compilers, which are free to choose any type that can represent
|
||||
* all values (C11 §6.7.2.2), we add an INT_MAX sentinel as the last
|
||||
* entry to force the compiler to use int.
|
||||
*
|
||||
* INT_MAX is used rather than a fixed constant like 0xFFFFFFFF
|
||||
* because enum constants must have type int (which is signed).
|
||||
* Values above INT_MAX overflow signed int and are a constraint
|
||||
* violation in standard C; compilers that accept them interpret them
|
||||
* as negative values via two's complement, which can collide with
|
||||
* legitimate negative enum values.
|
||||
*
|
||||
* Usage:
|
||||
* @code
|
||||
* typedef enum GHOSTTY_ENUM_TYPED {
|
||||
* FOO_A = 0,
|
||||
* FOO_B = 1,
|
||||
* FOO_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
* } Foo;
|
||||
* @endcode
|
||||
*/
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
|
||||
#define GHOSTTY_ENUM_TYPED : int
|
||||
#else
|
||||
#define GHOSTTY_ENUM_TYPED
|
||||
#endif
|
||||
#define GHOSTTY_ENUM_MAX_VALUE INT_MAX
|
||||
|
||||
/**
|
||||
* Result codes for libghostty-vt operations.
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Operation completed successfully */
|
||||
GHOSTTY_SUCCESS = 0,
|
||||
/** Operation failed due to failed allocation */
|
||||
GHOSTTY_OUT_OF_MEMORY = -1,
|
||||
/** Operation failed due to invalid value */
|
||||
GHOSTTY_INVALID_VALUE = -2,
|
||||
/** Operation failed because the provided buffer was too small */
|
||||
GHOSTTY_OUT_OF_SPACE = -3,
|
||||
/** The requested value has no value */
|
||||
GHOSTTY_NO_VALUE = -4,
|
||||
GHOSTTY_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyResult;
|
||||
|
||||
/* ---- Opaque handles ---- */
|
||||
|
||||
/**
|
||||
* Opaque handle to a terminal instance.
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef struct GhosttyTerminalImpl* GhosttyTerminal;
|
||||
|
||||
/**
|
||||
* Opaque handle to a tracked grid reference.
|
||||
*
|
||||
* A tracked grid reference is owned by the caller and must be freed with
|
||||
* ghostty_tracked_grid_ref_free(). If the terminal that created it is freed
|
||||
* first, the handle remains valid only for tracked-grid-ref APIs: it reports no
|
||||
* value and can still be freed.
|
||||
*
|
||||
* @ingroup grid_ref
|
||||
*/
|
||||
typedef struct GhosttyTrackedGridRefImpl* GhosttyTrackedGridRef;
|
||||
|
||||
/**
|
||||
* Opaque handle to a Kitty graphics image storage.
|
||||
*
|
||||
* Obtained via ghostty_terminal_get() with
|
||||
* GHOSTTY_TERMINAL_DATA_KITTY_GRAPHICS. The pointer is borrowed from
|
||||
* the terminal and remains valid until the next mutating terminal call
|
||||
* (e.g. ghostty_terminal_vt_write() or ghostty_terminal_reset()).
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef struct GhosttyKittyGraphicsImpl* GhosttyKittyGraphics;
|
||||
|
||||
/**
|
||||
* Opaque handle to a Kitty graphics image.
|
||||
*
|
||||
* Obtained via ghostty_kitty_graphics_image() with an image ID. The
|
||||
* pointer is borrowed from the storage and remains valid until the next
|
||||
* mutating terminal call.
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef const struct GhosttyKittyGraphicsImageImpl* GhosttyKittyGraphicsImage;
|
||||
|
||||
/**
|
||||
* Opaque handle to a Kitty graphics placement iterator.
|
||||
*
|
||||
* @ingroup kitty_graphics
|
||||
*/
|
||||
typedef struct GhosttyKittyGraphicsPlacementIteratorImpl* GhosttyKittyGraphicsPlacementIterator;
|
||||
|
||||
/**
|
||||
* Opaque handle to a render state instance.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef struct GhosttyRenderStateImpl* GhosttyRenderState;
|
||||
|
||||
/**
|
||||
* Opaque handle to a render-state row iterator.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef struct GhosttyRenderStateRowIteratorImpl* GhosttyRenderStateRowIterator;
|
||||
|
||||
/**
|
||||
* Opaque handle to render-state row cells.
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
typedef struct GhosttyRenderStateRowCellsImpl* GhosttyRenderStateRowCells;
|
||||
|
||||
/**
|
||||
* Opaque handle to an SGR parser instance.
|
||||
*
|
||||
* This handle represents an SGR (Select Graphic Rendition) parser that can
|
||||
* be used to parse SGR sequences and extract individual text attributes.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef struct GhosttySgrParserImpl* GhosttySgrParser;
|
||||
|
||||
/**
|
||||
* Opaque handle to a formatter instance.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef struct GhosttyFormatterImpl* GhosttyFormatter;
|
||||
|
||||
/**
|
||||
* Opaque handle to an OSC parser instance.
|
||||
*
|
||||
* This handle represents an OSC (Operating System Command) parser that can
|
||||
* be used to parse the contents of OSC sequences.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef struct GhosttyOscParserImpl* GhosttyOscParser;
|
||||
|
||||
/**
|
||||
* Opaque handle to a single OSC command.
|
||||
*
|
||||
* This handle represents a parsed OSC (Operating System Command) command.
|
||||
* The command can be queried for its type and associated data.
|
||||
*
|
||||
* @ingroup osc
|
||||
*/
|
||||
typedef struct GhosttyOscCommandImpl* GhosttyOscCommand;
|
||||
|
||||
/* ---- Common value types ---- */
|
||||
|
||||
/**
|
||||
* Terminal content output format.
|
||||
*
|
||||
* @ingroup formatter
|
||||
*/
|
||||
typedef enum GHOSTTY_ENUM_TYPED {
|
||||
/** Plain text (no escape sequences). */
|
||||
GHOSTTY_FORMATTER_FORMAT_PLAIN,
|
||||
|
||||
/** VT sequences preserving colors, styles, URLs, etc. */
|
||||
GHOSTTY_FORMATTER_FORMAT_VT,
|
||||
|
||||
/** HTML with inline styles. */
|
||||
GHOSTTY_FORMATTER_FORMAT_HTML,
|
||||
GHOSTTY_FORMATTER_FORMAT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyFormatterFormat;
|
||||
|
||||
/**
|
||||
* A borrowed byte string (pointer + length).
|
||||
*
|
||||
* The memory is not owned by this struct. The pointer is only valid
|
||||
* for the lifetime documented by the API that produces or consumes it.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to the string bytes. */
|
||||
const uint8_t* ptr;
|
||||
|
||||
/** Length of the string in bytes. */
|
||||
size_t len;
|
||||
} GhosttyString;
|
||||
|
||||
/**
|
||||
* A caller-provided byte buffer.
|
||||
*
|
||||
* APIs that write to this type use `len` for the number of bytes written on
|
||||
* GHOSTTY_SUCCESS and the required byte capacity on GHOSTTY_OUT_OF_SPACE.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Destination buffer for bytes. May be NULL when cap is 0 to query required size. */
|
||||
uint8_t* ptr;
|
||||
|
||||
/** Capacity of ptr in bytes. */
|
||||
size_t cap;
|
||||
|
||||
/** Bytes written on success, or required byte capacity on GHOSTTY_OUT_OF_SPACE. */
|
||||
size_t len;
|
||||
} GhosttyBuffer;
|
||||
|
||||
/**
|
||||
* A surface-space position in pixels.
|
||||
*
|
||||
* This is not a terminal grid coordinate. It represents an x/y position in the
|
||||
* rendered surface coordinate space, with (0, 0) at the top-left of the
|
||||
* surface.
|
||||
*/
|
||||
typedef struct {
|
||||
/** X position in surface pixels. */
|
||||
double x;
|
||||
|
||||
/** Y position in surface pixels. */
|
||||
double y;
|
||||
} GhosttySurfacePosition;
|
||||
|
||||
/**
|
||||
* A borrowed list of Unicode scalar values.
|
||||
*
|
||||
* Values are encoded as uint32_t scalar values. The memory is not owned by this
|
||||
* struct. The pointer is only valid for the lifetime documented by the API that
|
||||
* consumes or produces it.
|
||||
*
|
||||
* APIs may document special handling for NULL + len 0, such as “use defaults”.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to Unicode scalar values. */
|
||||
const uint32_t* ptr;
|
||||
|
||||
/** Number of entries in ptr. */
|
||||
size_t len;
|
||||
} GhosttyCodepoints;
|
||||
|
||||
/**
|
||||
* Initialize a sized struct to zero and set its size field.
|
||||
*
|
||||
* Sized structs use a `size` field as the first member for ABI
|
||||
* compatibility. This macro zero-initializes the struct and sets the
|
||||
* size field to `sizeof(type)`, which allows the library to detect
|
||||
* which version of the struct the caller was compiled against.
|
||||
*
|
||||
* @param type The struct type to initialize
|
||||
* @return A zero-initialized struct with the size field set
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* GhosttyFormatterTerminalOptions opts = GHOSTTY_INIT_SIZED(GhosttyFormatterTerminalOptions);
|
||||
* opts.emit = GHOSTTY_FORMATTER_FORMAT_PLAIN;
|
||||
* opts.trim = true;
|
||||
* @endcode
|
||||
*/
|
||||
#define GHOSTTY_INIT_SIZED(type) \
|
||||
((type){ .size = sizeof(type) })
|
||||
|
||||
/**
|
||||
* Return a pointer to a null-terminated JSON string describing the
|
||||
* layout of every C API struct for the current target.
|
||||
*
|
||||
* This is primarily useful for language bindings that can't easily
|
||||
* set C struct fields and need to do so via byte offsets. For example,
|
||||
* WebAssembly modules can't share struct definitions with the host.
|
||||
*
|
||||
* Example (abbreviated):
|
||||
* @code{.json}
|
||||
* {
|
||||
* "GhosttyMouseEncoderSize": {
|
||||
* "size": 40,
|
||||
* "align": 8,
|
||||
* "fields": {
|
||||
* "size": { "offset": 0, "size": 8, "type": "u64" },
|
||||
* "screen_width": { "offset": 8, "size": 4, "type": "u32" },
|
||||
* "screen_height": { "offset": 12, "size": 4, "type": "u32" },
|
||||
* "cell_width": { "offset": 16, "size": 4, "type": "u32" },
|
||||
* "cell_height": { "offset": 20, "size": 4, "type": "u32" },
|
||||
* "padding_top": { "offset": 24, "size": 4, "type": "u32" },
|
||||
* "padding_bottom": { "offset": 28, "size": 4, "type": "u32" },
|
||||
* "padding_right": { "offset": 32, "size": 4, "type": "u32" },
|
||||
* "padding_left": { "offset": 36, "size": 4, "type": "u32" }
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* The returned pointer is valid for the lifetime of the process.
|
||||
*
|
||||
* @return Pointer to the null-terminated JSON string.
|
||||
*/
|
||||
GHOSTTY_API const char *ghostty_type_json(void);
|
||||
|
||||
#endif /* GHOSTTY_VT_TYPES_H */
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @file unicode.h
|
||||
*
|
||||
* Unicode utilities - codepoint properties matching the terminal's
|
||||
* text layout semantics.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_UNICODE_H
|
||||
#define GHOSTTY_VT_UNICODE_H
|
||||
|
||||
/** @defgroup unicode Unicode Utilities
|
||||
*
|
||||
* Unicode codepoint properties matching the terminal's text layout
|
||||
* semantics.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_unicode_codepoint_width() to determine how many terminal
|
||||
* grid cells a codepoint occupies, using the exact same width table the
|
||||
* terminal itself uses when laying out printed text. Use
|
||||
* ghostty_unicode_grapheme_width() to segment and measure full grapheme
|
||||
* clusters with the same rules the terminal uses when mode 2027 is
|
||||
* enabled. These functions are useful for predicting column layout of
|
||||
* text that has not yet been written to the terminal, such as IME
|
||||
* preedit (composition) overlays.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Returns the terminal display width of a Unicode codepoint in
|
||||
* terminal grid cells: 0, 1, or 2.
|
||||
*
|
||||
* This is the same width table the terminal itself uses when laying
|
||||
* out printed text, so callers can predict column layout (e.g. IME
|
||||
* preedit overlays) that exactly matches what the terminal will do
|
||||
* when the text is actually written to it.
|
||||
*
|
||||
* Semantics:
|
||||
* - Returns 0 for zero-width codepoints: C0/C1 control characters,
|
||||
* nonspacing and enclosing combining marks, default-ignorable
|
||||
* codepoints (ZWJ, ZWNJ, variation selectors, etc.), and
|
||||
* surrogate codepoints.
|
||||
* - Returns 2 for wide codepoints: East Asian Wide/Fullwidth
|
||||
* (including emoji with default emoji presentation) and regional
|
||||
* indicators. Width is clamped to 2 (e.g. the three-em dash).
|
||||
* - Returns 1 for everything else, including invalid codepoints
|
||||
* beyond U+10FFFF (this function is total; it never fails).
|
||||
*
|
||||
* This operates on a single codepoint only and therefore cannot account
|
||||
* for grapheme-cluster-level width rules (VS16 emoji presentation,
|
||||
* combining sequences, etc.). For cluster-accurate widths, use
|
||||
* ghostty_unicode_grapheme_width(). Summing per-codepoint widths is only
|
||||
* correct when mode 2027 (grapheme clustering) is disabled.
|
||||
*
|
||||
* This function is pure, allocates nothing, and is thread-safe.
|
||||
*
|
||||
* @param cp The Unicode codepoint to measure
|
||||
* @return Display width in cells: 0, 1, or 2
|
||||
*/
|
||||
GHOSTTY_API uint8_t ghostty_unicode_codepoint_width(uint32_t cp);
|
||||
|
||||
/**
|
||||
* Measures the terminal display width of the first grapheme cluster in a
|
||||
* sequence of Unicode codepoints.
|
||||
*
|
||||
* This uses the exact same grapheme segmentation and cluster width rules
|
||||
* the terminal itself uses when printing text with grapheme clustering
|
||||
* enabled (mode 2027), so callers can predict column layout (e.g. IME
|
||||
* preedit overlays) that exactly matches what the terminal will do when
|
||||
* the text is actually written to it. Unlike
|
||||
* ghostty_unicode_codepoint_width(), this accounts for cluster-level
|
||||
* rules: emoji variation selectors, ZWJ sequences, combining marks, and
|
||||
* skin tone modifiers.
|
||||
*
|
||||
* Reads codepoints from cps until the terminal would consider the
|
||||
* grapheme cluster complete, stores the cluster's total width in cells
|
||||
* (0, 1, or 2) into width (which may be NULL if only segmentation is
|
||||
* desired), and returns the number of codepoints consumed. Returns 0 if
|
||||
* and only if len is 0; otherwise consumes at least one codepoint. Measure
|
||||
* a whole string by calling in a loop:
|
||||
*
|
||||
* @code
|
||||
* size_t total = 0;
|
||||
* for (size_t i = 0; i < len;) {
|
||||
* uint8_t width;
|
||||
* i += ghostty_unicode_grapheme_width(cps + i, len - i, &width);
|
||||
* total += width;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* This is not a streaming API. The provided sequence must contain a
|
||||
* complete first grapheme cluster, or the logical end of the string. If
|
||||
* input arrives in chunks, keep buffering while this function consumes all
|
||||
* available codepoints (return value == len) and the stream may still
|
||||
* continue; a later codepoint could still extend the cluster and change
|
||||
* its width.
|
||||
*
|
||||
* Width semantics, matching the terminal with mode 2027 enabled:
|
||||
* - The cluster starts at the width of its first codepoint, as returned by
|
||||
* ghostty_unicode_codepoint_width().
|
||||
* - VS16 (U+FE0F) forces the cluster wide (2) and VS15 (U+FE0E) forces it
|
||||
* narrow (1), but only when the immediately preceding codepoint in the
|
||||
* cluster is a valid emoji variation sequence base (per Unicode
|
||||
* emoji-variation-sequences.txt). Invalid variation selectors are
|
||||
* ignored entirely.
|
||||
* - Any other continuation codepoint that contributes to grapheme width
|
||||
* forces the cluster wide (2). Note this means cluster width is NOT the
|
||||
* maximum of per-codepoint widths: some continuation marks have narrow
|
||||
* codepoint width yet still widen the cluster.
|
||||
*
|
||||
* Mode dependence: this models mode 2027 (grapheme clustering) enabled,
|
||||
* which is Ghostty's recommended configuration. When mode 2027 is
|
||||
* disabled, clusters never combine and variation selectors never change
|
||||
* width; predict layout in that case by summing
|
||||
* ghostty_unicode_codepoint_width() over each codepoint instead.
|
||||
*
|
||||
* Edge cases:
|
||||
* - Codepoints beyond U+10FFFF consume one codepoint, have width 1, and
|
||||
* are always cluster boundaries. This function is total; it never fails.
|
||||
* - Control characters (C0/C1, CR, LF) are never printed through the
|
||||
* terminal's text path; passing them here returns an unspecified (but
|
||||
* stable and bounded) result.
|
||||
* - A cluster whose first codepoint is zero-width (e.g. a lone combining
|
||||
* mark) is malformed at a cell start; the terminal may attach it to
|
||||
* earlier screen content. This function reports the fold result for the
|
||||
* sequence in isolation (typically 0).
|
||||
*
|
||||
* This function is pure, allocates nothing, and is thread-safe.
|
||||
*
|
||||
* @param cps Pointer to codepoints (may be NULL only when len is 0)
|
||||
* @param len Number of codepoints available
|
||||
* @param width Out: cluster display width in cells (0-2); may be NULL
|
||||
* @return Number of codepoints in the first grapheme cluster
|
||||
*/
|
||||
GHOSTTY_API size_t ghostty_unicode_grapheme_width(const uint32_t *cps,
|
||||
size_t len,
|
||||
uint8_t *width);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_UNICODE_H */
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* @file wasm.h
|
||||
*
|
||||
* WebAssembly utility functions for libghostty-vt.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_WASM_H
|
||||
#define GHOSTTY_VT_WASM_H
|
||||
|
||||
#ifdef __wasm__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
|
||||
/** @defgroup wasm WebAssembly Utilities
|
||||
*
|
||||
* Convenience functions for allocating various types in WebAssembly builds.
|
||||
* **These are only available the libghostty-vt wasm module.**
|
||||
*
|
||||
* Ghostty relies on pointers to various types for ABI compatibility, and
|
||||
* creating those pointers in Wasm can be tedious. These functions provide
|
||||
* a purely additive set of utilities that simplify memory management in
|
||||
* Wasm environments without changing the core C library API.
|
||||
*
|
||||
* @note These functions always use the default allocator. If you need
|
||||
* custom allocation strategies, you should allocate types manually using
|
||||
* your custom allocator. This is a very rare use case in the WebAssembly
|
||||
* world so these are optimized for simplicity.
|
||||
*
|
||||
* ## Example Usage
|
||||
*
|
||||
* Here's a simple example of using the Wasm utilities with the key encoder:
|
||||
*
|
||||
* @code
|
||||
* const { exports } = wasmInstance;
|
||||
* const view = new DataView(wasmMemory.buffer);
|
||||
*
|
||||
* // Create key encoder
|
||||
* const encoderPtr = exports.ghostty_wasm_alloc_opaque();
|
||||
* exports.ghostty_key_encoder_new(null, encoderPtr);
|
||||
* const encoder = view.getUint32(encoder, true);
|
||||
*
|
||||
* // Configure encoder with Kitty protocol flags
|
||||
* const flagsPtr = exports.ghostty_wasm_alloc_u8();
|
||||
* view.setUint8(flagsPtr, 0x1F);
|
||||
* exports.ghostty_key_encoder_setopt(encoder, 5, flagsPtr);
|
||||
*
|
||||
* // Allocate output buffer and size pointer
|
||||
* const bufferSize = 32;
|
||||
* const bufPtr = exports.ghostty_wasm_alloc_u8_array(bufferSize);
|
||||
* const writtenPtr = exports.ghostty_wasm_alloc_usize();
|
||||
*
|
||||
* // Encode the key event
|
||||
* exports.ghostty_key_encoder_encode(
|
||||
* encoder, eventPtr, bufPtr, bufferSize, writtenPtr
|
||||
* );
|
||||
*
|
||||
* // Read encoded output
|
||||
* const bytesWritten = view.getUint32(writtenPtr, true);
|
||||
* const encoded = new Uint8Array(wasmMemory.buffer, bufPtr, bytesWritten);
|
||||
* @endcode
|
||||
*
|
||||
* @remark The code above is pretty ugly! This is the lowest level interface
|
||||
* to the libghostty-vt Wasm module. In practice, this should be wrapped
|
||||
* in a higher-level API that abstracts away all this.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate an opaque pointer. This can be used for any opaque pointer
|
||||
* types such as GhosttyKeyEncoder, GhosttyKeyEvent, etc.
|
||||
*
|
||||
* @return Pointer to allocated opaque pointer, or NULL if allocation failed
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void** ghostty_wasm_alloc_opaque(void);
|
||||
|
||||
/**
|
||||
* Free an opaque pointer allocated by ghostty_wasm_alloc_opaque().
|
||||
*
|
||||
* @param ptr Pointer to free, or NULL (NULL is safely ignored)
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_opaque(void **ptr);
|
||||
|
||||
/**
|
||||
* Allocate an array of uint8_t values.
|
||||
*
|
||||
* @param len Number of uint8_t elements to allocate
|
||||
* @return Pointer to allocated array, or NULL if allocation failed
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API uint8_t* ghostty_wasm_alloc_u8_array(size_t len);
|
||||
|
||||
/**
|
||||
* Free an array allocated by ghostty_wasm_alloc_u8_array().
|
||||
*
|
||||
* @param ptr Pointer to the array to free, or NULL (NULL is safely ignored)
|
||||
* @param len Length of the array (must match the length passed to alloc)
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_u8_array(uint8_t *ptr, size_t len);
|
||||
|
||||
/**
|
||||
* Allocate an array of uint16_t values.
|
||||
*
|
||||
* @param len Number of uint16_t elements to allocate
|
||||
* @return Pointer to allocated array, or NULL if allocation failed
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API uint16_t* ghostty_wasm_alloc_u16_array(size_t len);
|
||||
|
||||
/**
|
||||
* Free an array allocated by ghostty_wasm_alloc_u16_array().
|
||||
*
|
||||
* @param ptr Pointer to the array to free, or NULL (NULL is safely ignored)
|
||||
* @param len Length of the array (must match the length passed to alloc)
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_u16_array(uint16_t *ptr, size_t len);
|
||||
|
||||
/**
|
||||
* Allocate a single uint8_t value.
|
||||
*
|
||||
* @return Pointer to allocated uint8_t, or NULL if allocation failed
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API uint8_t* ghostty_wasm_alloc_u8(void);
|
||||
|
||||
/**
|
||||
* Free a uint8_t allocated by ghostty_wasm_alloc_u8().
|
||||
*
|
||||
* @param ptr Pointer to free, or NULL (NULL is safely ignored)
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_u8(uint8_t *ptr);
|
||||
|
||||
/**
|
||||
* Allocate a single size_t value.
|
||||
*
|
||||
* @return Pointer to allocated size_t, or NULL if allocation failed
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API size_t* ghostty_wasm_alloc_usize(void);
|
||||
|
||||
/**
|
||||
* Free a size_t allocated by ghostty_wasm_alloc_usize().
|
||||
*
|
||||
* @param ptr Pointer to free, or NULL (NULL is safely ignored)
|
||||
* @ingroup wasm
|
||||
*/
|
||||
GHOSTTY_API void ghostty_wasm_free_usize(size_t *ptr);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __wasm__ */
|
||||
|
||||
#endif /* GHOSTTY_VT_WASM_H */
|
||||
@@ -0,0 +1,7 @@
|
||||
// This makes Ghostty available to the XCode build for the macOS app.
|
||||
// We append "Kit" to it not to be cute, but because targets have to have
|
||||
// unique names and we use Ghostty for other things.
|
||||
module GhosttyKit {
|
||||
umbrella header "ghostty.h"
|
||||
export *
|
||||
}
|
||||
Reference in New Issue
Block a user