diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-16 23:28:05 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-16 23:29:28 +0300 |
| commit | 4a3302d19a2baa3a33e910e0088c24e780905b90 (patch) | |
| tree | dcaf76fae1c82102d933c9225b17ca7ac5d3a847 /vendor/libghostty-vt/include | |
| parent | 550e9f8cc085f428429f5cf2da0bb2dba897e8b8 (diff) | |
chore: update vendored libghostty-vt
refs #276
Diffstat (limited to 'vendor/libghostty-vt/include')
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty.h | 1 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt.h | 9 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/color.h | 432 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/color_scheme.h | 73 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h | 89 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/render.h | 66 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/sgr.h | 7 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/terminal.h | 351 | ||||
| -rw-r--r-- | vendor/libghostty-vt/include/ghostty/vt/unicode.h | 154 |
9 files changed, 1144 insertions, 38 deletions
diff --git a/vendor/libghostty-vt/include/ghostty.h b/vendor/libghostty-vt/include/ghostty.h index fbfe3ee2..72bbb57a 100644 --- a/vendor/libghostty-vt/include/ghostty.h +++ b/vendor/libghostty-vt/include/ghostty.h @@ -934,6 +934,7 @@ typedef enum { GHOSTTY_ACTION_CONFIG_CHANGE, GHOSTTY_ACTION_CLOSE_WINDOW, GHOSTTY_ACTION_RING_BELL, + GHOSTTY_ACTION_SELECTION_CHANGED, GHOSTTY_ACTION_UNDO, GHOSTTY_ACTION_REDO, GHOSTTY_ACTION_CHECK_FOR_UPDATES, diff --git a/vendor/libghostty-vt/include/ghostty/vt.h b/vendor/libghostty-vt/include/ghostty/vt.h index 94a85033..5606f169 100644 --- a/vendor/libghostty-vt/include/ghostty/vt.h +++ b/vendor/libghostty-vt/include/ghostty/vt.h @@ -34,6 +34,7 @@ * - @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 @@ -55,6 +56,7 @@ * - @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 * */ @@ -104,6 +106,11 @@ * 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. @@ -125,6 +132,7 @@ extern "C" { #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> @@ -145,6 +153,7 @@ extern "C" { #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 diff --git a/vendor/libghostty-vt/include/ghostty/vt/color.h b/vendor/libghostty-vt/include/ghostty/vt/color.h index 9dc21864..f5f7f9c4 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/color.h +++ b/vendor/libghostty-vt/include/ghostty/vt/color.h @@ -7,6 +7,114 @@ #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> @@ -17,7 +125,7 @@ extern "C" { /** * RGB color value. * - * @ingroup sgr + * @ingroup color */ typedef struct { uint8_t r; /**< Red component (0-255) */ @@ -28,49 +136,128 @@ typedef struct { /** * Palette color index (0-255). * - * @ingroup sgr + * @ingroup color */ typedef uint8_t GhosttyColorPaletteIndex; -/** @addtogroup sgr - * @{ +/** + * 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)) -/** Black color (0) @ingroup sgr */ +/** + * 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 sgr */ +/** Red color (1) @ingroup color */ #define GHOSTTY_COLOR_NAMED_RED 1 -/** Green color (2) @ingroup sgr */ +/** Green color (2) @ingroup color */ #define GHOSTTY_COLOR_NAMED_GREEN 2 -/** Yellow color (3) @ingroup sgr */ +/** Yellow color (3) @ingroup color */ #define GHOSTTY_COLOR_NAMED_YELLOW 3 -/** Blue color (4) @ingroup sgr */ +/** Blue color (4) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BLUE 4 -/** Magenta color (5) @ingroup sgr */ +/** Magenta color (5) @ingroup color */ #define GHOSTTY_COLOR_NAMED_MAGENTA 5 -/** Cyan color (6) @ingroup sgr */ +/** Cyan color (6) @ingroup color */ #define GHOSTTY_COLOR_NAMED_CYAN 6 -/** White color (7) @ingroup sgr */ +/** White color (7) @ingroup color */ #define GHOSTTY_COLOR_NAMED_WHITE 7 -/** Bright black color (8) @ingroup sgr */ +/** Bright black color (8) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_BLACK 8 -/** Bright red color (9) @ingroup sgr */ +/** Bright red color (9) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_RED 9 -/** Bright green color (10) @ingroup sgr */ +/** Bright green color (10) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_GREEN 10 -/** Bright yellow color (11) @ingroup sgr */ +/** Bright yellow color (11) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_YELLOW 11 -/** Bright blue color (12) @ingroup sgr */ +/** Bright blue color (12) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_BLUE 12 -/** Bright magenta color (13) @ingroup sgr */ +/** Bright magenta color (13) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_MAGENTA 13 -/** Bright cyan color (14) @ingroup sgr */ +/** Bright cyan color (14) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_CYAN 14 -/** Bright white color (15) @ingroup sgr */ +/** Bright white color (15) @ingroup color */ #define GHOSTTY_COLOR_NAMED_BRIGHT_WHITE 15 -/** @} */ - /** * Get the RGB color components. * @@ -78,20 +265,215 @@ typedef uint8_t GhosttyColorPaletteIndex; * from a GhosttyColorRgb value. Primarily useful in WebAssembly environments * where accessing struct fields directly is difficult. * - * @param color The RGB color value + * @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 sgr + * @ingroup color */ -GHOSTTY_API void ghostty_color_rgb_get(GhosttyColorRgb 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 */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/color_scheme.h b/vendor/libghostty-vt/include/ghostty/vt/color_scheme.h new file mode 100644 index 00000000..d028ec08 --- /dev/null +++ b/vendor/libghostty-vt/include/ghostty/vt/color_scheme.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 */ diff --git a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h index d5b50067..dda8b836 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h +++ b/vendor/libghostty-vt/include/ghostty/vt/kitty_graphics.h @@ -84,6 +84,28 @@ extern "C" { * - 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, @@ -119,6 +141,29 @@ typedef enum GHOSTTY_ENUM_TYPED { * 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; @@ -255,6 +300,12 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * 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 { @@ -269,6 +320,12 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * 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 { @@ -315,14 +372,17 @@ typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_KITTY_IMAGE_DATA_HEIGHT = 4, /** - * Pixel format of the image. + * 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. + * Compression of the image. Always + * GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE; compressed payloads are + * inflated before storage. * * Output type: GhosttyKittyImageCompression * */ @@ -332,25 +392,40 @@ typedef enum GHOSTTY_ENUM_TYPED { * 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. + * 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, /** - * Timestamp of the image's most recent transmission, in nanoseconds. - * The epoch is unspecified; only equality and ordering between values - * read from the same terminal are meaningful. + * 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_TRANSMIT_TIME_NS = 9, + GHOSTTY_KITTY_IMAGE_DATA_GENERATION = 9, GHOSTTY_KITTY_IMAGE_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyKittyGraphicsImageData; diff --git a/vendor/libghostty-vt/include/ghostty/vt/render.h b/vendor/libghostty-vt/include/ghostty/vt/render.h index c5b1d0d4..2e3f2f71 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/render.h +++ b/vendor/libghostty-vt/include/ghostty/vt/render.h @@ -39,6 +39,18 @@ extern "C" { * 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 @@ -331,6 +343,12 @@ GHOSTTY_API void ghostty_render_state_free(GhosttyRenderState state); * 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 @@ -343,6 +361,54 @@ 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 diff --git a/vendor/libghostty-vt/include/ghostty/vt/sgr.h b/vendor/libghostty-vt/include/ghostty/vt/sgr.h index 8eec11dc..757c5aed 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/sgr.h +++ b/vendor/libghostty-vt/include/ghostty/vt/sgr.h @@ -19,8 +19,11 @@ * 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 various color formats including 8-color, 16-color, 256-color, - * X11 named colors, and RGB in multiple formats. + * 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 * diff --git a/vendor/libghostty-vt/include/ghostty/vt/terminal.h b/vendor/libghostty-vt/include/ghostty/vt/terminal.h index ddfcb9c0..26ee0c0b 100644 --- a/vendor/libghostty-vt/include/ghostty/vt/terminal.h +++ b/vendor/libghostty-vt/include/ghostty/vt/terminal.h @@ -40,6 +40,17 @@ extern "C" { * @snippet c-vt-stream/src/main.c vt-stream-init * @snippet c-vt-stream/src/main.c vt-stream-write * + * ## Scrollback Compression + * + * Scrollback compression is caller-driven. The terminal exposes an opaque + * activity token so an embedding application can restart an idle timer only + * when compression-relevant state changes. Once idle, call incremental + * compression until it no longer reports pending work. libghostty-vt does not + * create a timer or background thread. + * + * @snippet c-vt-compression/src/main.c compression-activity + * @snippet c-vt-compression/src/main.c compression-idle-step + * * ## Effects * * By default, the terminal sequence processing with ghostty_terminal_vt_write() @@ -76,11 +87,13 @@ extern "C" { * | `GHOSTTY_TERMINAL_OPT_WRITE_PTY` | `GhosttyTerminalWritePtyFn` | Query responses written back to the pty | * | `GHOSTTY_TERMINAL_OPT_BELL` | `GhosttyTerminalBellFn` | BEL character (0x07) | * | `GHOSTTY_TERMINAL_OPT_TITLE_CHANGED` | `GhosttyTerminalTitleChangedFn` | Title change via OSC 0 / OSC 2 | + * | `GHOSTTY_TERMINAL_OPT_PWD_CHANGED` | `GhosttyTerminalPwdChangedFn` | Pwd change via OSC 7 / OSC 9 / OSC 1337 | * | `GHOSTTY_TERMINAL_OPT_ENQUIRY` | `GhosttyTerminalEnquiryFn` | ENQ character (0x05) | * | `GHOSTTY_TERMINAL_OPT_XTVERSION` | `GhosttyTerminalXtversionFn` | XTVERSION query (CSI > q) | * | `GHOSTTY_TERMINAL_OPT_SIZE` | `GhosttyTerminalSizeFn` | XTWINOPS size query (CSI 14/16/18 t) | * | `GHOSTTY_TERMINAL_OPT_COLOR_SCHEME` | `GhosttyTerminalColorSchemeFn` | Color scheme query (CSI ? 996 n) | * | `GHOSTTY_TERMINAL_OPT_DEVICE_ATTRIBUTES`| `GhosttyTerminalDeviceAttributesFn`| Device attributes query (CSI c / > c / = c)| + * | `GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE` | `GhosttyTerminalClipboardWriteFn` | Clipboard write via OSC 52 / OSC 1337 | * * ### Defining a write_pty callback * @snippet c-vt-effects/src/main.c effects-write-pty @@ -91,6 +104,9 @@ extern "C" { * ### Defining a title_changed callback * @snippet c-vt-effects/src/main.c effects-title-changed * + * ### Defining a clipboard_write callback + * @snippet c-vt-effects/src/main.c effects-clipboard-write + * * ### Registering effects and processing VT data * @snippet c-vt-effects/src/main.c effects-register * @@ -177,6 +193,37 @@ typedef struct { } GhosttyTerminalOptions; /** + * Amount of compression work to perform before returning. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Perform one bounded compression step suitable for idle scheduling. */ + GHOSTTY_TERMINAL_COMPRESSION_MODE_INCREMENTAL = 0, + + /** Synchronously inspect every currently eligible page. */ + GHOSTTY_TERMINAL_COMPRESSION_MODE_FULL = 1, + GHOSTTY_TERMINAL_COMPRESSION_MODE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyTerminalCompressionMode; + +/** + * Scheduling result from terminal compression. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Retained-mapping reclamation is unavailable on this target. */ + GHOSTTY_TERMINAL_COMPRESSION_RESULT_UNSUPPORTED = 0, + + /** More incremental compression work remains. */ + GHOSTTY_TERMINAL_COMPRESSION_RESULT_PENDING = 1, + + /** The pass has no continuation to schedule. */ + GHOSTTY_TERMINAL_COMPRESSION_RESULT_COMPLETE = 2, + GHOSTTY_TERMINAL_COMPRESSION_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyTerminalCompressionResult; + +/** * Scroll viewport behavior tag. * * @ingroup terminal @@ -190,6 +237,21 @@ typedef enum GHOSTTY_ENUM_TYPED { /** Scroll by a delta amount (up is negative). */ GHOSTTY_SCROLL_VIEWPORT_DELTA, + + /** + * Scroll to an absolute row offset from the top of the scrollable + * area. Row 0 is the top of the scrollback and the requested row + * becomes the first visible row of the viewport. The value is + * clamped so the viewport never scrolls beyond the top of the + * active area. If the terminal has no scrollback (e.g. the + * alternate screen is active), the viewport always remains on the + * active area. + * + * This is the same row space as the offset field of + * GhosttyTerminalScrollbar, so a scrollbar position obtained from + * GHOSTTY_TERMINAL_DATA_SCROLLBAR round-trips cleanly. + */ + GHOSTTY_SCROLL_VIEWPORT_ROW, GHOSTTY_SCROLL_VIEWPORT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalScrollViewportTag; @@ -202,6 +264,9 @@ typedef union { /** Scroll delta (only used with GHOSTTY_SCROLL_VIEWPORT_DELTA). Up is negative. */ intptr_t delta; + /** Absolute row offset (only used with GHOSTTY_SCROLL_VIEWPORT_ROW). */ + size_t row; + /** Padding for ABI compatibility. Do not use. */ uint64_t _padding[2]; } GhosttyTerminalScrollViewportValue; @@ -233,6 +298,26 @@ typedef enum GHOSTTY_ENUM_TYPED { } GhosttyTerminalScreen; /** + * Visual style of the terminal cursor. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** Bar cursor (DECSCUSR 5, 6). */ + GHOSTTY_TERMINAL_CURSOR_STYLE_BAR = 0, + + /** Block cursor (DECSCUSR 1, 2). */ + GHOSTTY_TERMINAL_CURSOR_STYLE_BLOCK = 1, + + /** Underline cursor (DECSCUSR 3, 4). */ + GHOSTTY_TERMINAL_CURSOR_STYLE_UNDERLINE = 2, + + /** Hollow block cursor. */ + GHOSTTY_TERMINAL_CURSOR_STYLE_BLOCK_HOLLOW = 3, + GHOSTTY_TERMINAL_CURSOR_STYLE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyTerminalCursorStyle; + +/** * Scrollbar state for the terminal viewport. * * Represents the scrollable area dimensions needed to render a scrollbar. @@ -264,6 +349,125 @@ typedef void (*GhosttyTerminalBellFn)(GhosttyTerminal terminal, void* userdata); /** + * Clipboard destination for a clipboard write. + * + * Protocol-specific destination identifiers are normalized to these values + * before the clipboard write callback is invoked. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** The standard system clipboard. */ + GHOSTTY_CLIPBOARD_LOCATION_STANDARD = 0, + + /** The selection clipboard. */ + GHOSTTY_CLIPBOARD_LOCATION_SELECTION = 1, + + /** The primary selection clipboard. */ + GHOSTTY_CLIPBOARD_LOCATION_PRIMARY = 2, + GHOSTTY_CLIPBOARD_LOCATION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyClipboardLocation; + +/** + * One MIME representation in a clipboard write. + * + * Both strings are borrowed and valid only for the duration of the callback. + * The data is binary-safe and has already been decoded from any protocol-level + * encoding. A zero-length data string is an explicit empty representation; it + * does not clear the clipboard. + * + * This struct has a frozen layout and will not gain fields in future versions. + * + * @ingroup terminal + */ +typedef struct { + /** MIME type of the representation. */ + GhosttyString mime; + + /** Decoded, binary-safe representation data. */ + GhosttyString data; +} GhosttyClipboardContent; + +/** + * A semantic, atomic clipboard write. + * + * This is a sized struct. The callback must only access fields present in the + * size reported by `size`. The request, contents array, MIME strings, and + * data strings are all borrowed and valid only for the callback duration. + * + * All entries in `contents` are representations of the same logical value + * and must be committed atomically. A `contents_len` of zero requests that + * the destination be cleared. This is distinct from a content entry whose data + * has zero length. + * + * @ingroup terminal + */ +typedef struct { + /** Size of this struct in bytes. */ + size_t size; + + /** Clipboard destination. */ + GhosttyClipboardLocation location; + + /** Borrowed array of MIME representations. */ + const GhosttyClipboardContent* contents; + + /** Number of entries in contents; zero means clear the destination. */ + size_t contents_len; +} GhosttyClipboardWrite; + +/** + * Result of a clipboard write callback. + * + * Protocols without write acknowledgements, including OSC 52 and iTerm2 + * OSC 1337 Copy, ignore this result. + * + * @ingroup terminal + */ +typedef enum GHOSTTY_ENUM_TYPED { + /** The clipboard write completed successfully. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_SUCCESS = 0, + + /** The clipboard write was denied by policy or the user. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_DENIED = 1, + + /** The destination or one or more representations are unsupported. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_UNSUPPORTED = 2, + + /** The clipboard is temporarily unavailable. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_BUSY = 3, + + /** One or more representations contain invalid data. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_INVALID_DATA = 4, + + /** The clipboard write failed due to an I/O error. */ + GHOSTTY_CLIPBOARD_WRITE_RESULT_IO_ERROR = 5, + GHOSTTY_CLIPBOARD_WRITE_RESULT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, +} GhosttyClipboardWriteResult; + +/** + * Callback function type for clipboard_write. + * + * Called synchronously for a complete logical clipboard write. Protocol + * details such as OSC 52 selectors, base64 encoding, multipart chunks, + * aliases, and terminators are normalized before this callback is invoked. + * OSC 52 and iTerm2 OSC 1337 Copy writes therefore use the same callback + * shape. OSC 52 clipboard read requests ("?") are always ignored and never + * forwarded to this callback. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * @param write Borrowed atomic clipboard write request + * @return The result of attempting the clipboard write + * + * @ingroup terminal + */ +typedef GhosttyClipboardWriteResult (*GhosttyTerminalClipboardWriteFn)( + GhosttyTerminal terminal, + void* userdata, + const GhosttyClipboardWrite* write); + +/** * Callback function type for color scheme queries (CSI ? 996 n). * * Called when the terminal receives a color scheme device status report @@ -353,6 +557,31 @@ typedef void (*GhosttyTerminalTitleChangedFn)(GhosttyTerminal terminal, void* userdata); /** + * Callback function type for pwd_changed. + * + * Called when the terminal pwd (current working directory) changes via + * escape sequences: OSC 7 (file:// URI), OSC 9 (ConEmu CurrentDir), or + * OSC 1337 CurrentDir (iTerm2). Use ghostty_terminal_get() with + * GHOSTTY_TERMINAL_DATA_PWD inside the callback to read the new value. + * + * The terminal stores whatever bytes the shell emitted, without parsing. + * That means for OSC 7 the value is the raw URI (typically file://...); + * for OSC 9/OSC 1337 it is typically a bare path. The embedder is + * responsible for decoding any URI scheme or host if it cares about them. + * + * The callback also fires when the shell clears the pwd (e.g. an empty + * OSC 7). In that case GHOSTTY_TERMINAL_DATA_PWD returns a zero-length + * string. + * + * @param terminal The terminal handle + * @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA + * + * @ingroup terminal + */ +typedef void (*GhosttyTerminalPwdChangedFn)(GhosttyTerminal terminal, + void* userdata); + +/** * Callback function type for write_pty. * * Called when the terminal needs to write data back to the pty, for @@ -608,6 +837,56 @@ typedef enum GHOSTTY_ENUM_TYPED { * Input type: GhosttySelection* */ GHOSTTY_TERMINAL_OPT_SELECTION = 21, + + /** + * Set the default cursor style used by DECSCUSR reset (CSI 0 q). + * + * A NULL value pointer resets to the built-in default block cursor. + * + * Input type: GhosttyTerminalCursorStyle* + */ + GHOSTTY_TERMINAL_OPT_DEFAULT_CURSOR_STYLE = 22, + + /** + * Set whether the default cursor should blink when reset by DECSCUSR + * (CSI 0 q). + * + * A NULL value pointer resets to the built-in default of not blinking. + * + * Input type: bool* + */ + GHOSTTY_TERMINAL_OPT_DEFAULT_CURSOR_BLINK = 23, + + /** + * Enable or disable Glyph Protocol APC handling. + * + * When disabled, Glyph Protocol APC sequences are ignored and no + * support/query/register/clear responses are emitted. Disabling also clears + * the terminal session's glyph glossary. A NULL value pointer is a no-op. + * + * Input type: bool* + */ + GHOSTTY_TERMINAL_OPT_GLYPH_PROTOCOL = 24, + + /** + * Callback invoked when the terminal pwd changes via escape + * sequences (OSC 7, OSC 9, or OSC 1337 CurrentDir). Set to NULL + * to ignore pwd change events. + * + * Input type: GhosttyTerminalPwdChangedFn + */ + GHOSTTY_TERMINAL_OPT_PWD_CHANGED = 25, + + /** + * Callback invoked when the running program performs a clipboard write. + * OSC 52 and iTerm2 OSC 1337 Copy writes are normalized to an atomic set + * of decoded MIME representations. Set to NULL to ignore clipboard writes. + * Clipboard read requests are always ignored; see + * GhosttyTerminalClipboardWriteFn. + * + * Input type: GhosttyTerminalClipboardWriteFn + */ + GHOSTTY_TERMINAL_OPT_CLIPBOARD_WRITE = 26, GHOSTTY_TERMINAL_OPT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyTerminalOption; @@ -682,9 +961,16 @@ typedef enum GHOSTTY_ENUM_TYPED { /** * Scrollbar state for the terminal viewport. * - * This may be expensive to calculate depending on where the viewport - * is (arbitrary pins are expensive). The caller should take care to only - * call this as needed and not too frequently. + * This is amortized O(1): the total is maintained incrementally as + * the terminal is modified and the viewport offset is cached. The + * first read after the viewport moves to an arbitrary position that + * isn't an absolute row (e.g. scrolling to a selection) may cost + * O(pages) to compute the offset, after which it is cached again. + * + * There is intentionally no change notification for scroll state. + * Callers building scrollbars should poll this once per frame or + * per write batch and diff the result to detect changes; this is + * what Ghostty's own renderer does. * * Output type: GhosttyTerminalScrollbar * */ @@ -1035,7 +1321,10 @@ GHOSTTY_API void ghostty_terminal_vt_write(GhosttyTerminal terminal, * Scrolls the terminal's viewport according to the given behavior. * When using GHOSTTY_SCROLL_VIEWPORT_DELTA, set the delta field in * the value union to specify the number of rows to scroll (negative - * for up, positive for down). For other behaviors, the value is ignored. + * for up, positive for down). When using GHOSTTY_SCROLL_VIEWPORT_ROW, + * set the row field to the absolute row offset from the top of the + * scrollable area (the same row space as the offset field of + * GhosttyTerminalScrollbar). For other behaviors, the value is ignored. * * @param terminal The terminal handle (may be NULL, in which case this is a no-op) * @param behavior The scroll behavior as a tagged union @@ -1046,6 +1335,60 @@ GHOSTTY_API void ghostty_terminal_scroll_viewport(GhosttyTerminal terminal, GhosttyTerminalScrollViewport behavior); /** + * Return the current compression activity token. + * + * The token is opaque and only equality comparisons are meaningful. An + * embedding application should cache it and restart its compression idle + * delay whenever the value changes. The value may wrap and changes in either + * direction have the same meaning. + * + * This function only observes terminal state. It does not perform or schedule + * compression. + * + * @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param[out] out_activity Receives the current activity token + * @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if an argument + * is NULL + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_compression_activity( + GhosttyTerminal terminal, + uint64_t* out_activity); + +/** + * Compress eligible terminal scrollback. + * + * Incremental mode performs bounded work suitable for an idle callback. A + * pending result means the application should invoke another step while the + * terminal remains idle. A complete result means no continuation is needed + * until ghostty_terminal_compression_activity() changes. Full mode performs + * one synchronous scan and can stall on large scrollback buffers. + * + * Compression is opportunistic. Complete means the pass has finished, not + * that every page was compressed: pages may be unprofitable or encounter an + * allocation or reclamation failure. Compression changes only the terminal's + * storage representation and never its logical contents or scrollback limit. + * Accessing compressed history restores it transparently. + * + * This function is not thread-safe with other operations on the same + * terminal. The caller must serialize it with writes, rendering, searches, + * and other terminal access. + * + * @param terminal The terminal handle (NULL returns GHOSTTY_INVALID_VALUE) + * @param mode The amount of compression work to perform + * @param[out] out_result Receives the compression scheduling result + * @return GHOSTTY_SUCCESS on success, or GHOSTTY_INVALID_VALUE if an argument + * or mode is invalid + * + * @ingroup terminal + */ +GHOSTTY_API GhosttyResult ghostty_terminal_compress( + GhosttyTerminal terminal, + GhosttyTerminalCompressionMode mode, + GhosttyTerminalCompressionResult* out_result); + +/** * Get the current value of a terminal mode. * * Returns the value of the mode identified by the given mode. diff --git a/vendor/libghostty-vt/include/ghostty/vt/unicode.h b/vendor/libghostty-vt/include/ghostty/vt/unicode.h new file mode 100644 index 00000000..e4d62c81 --- /dev/null +++ b/vendor/libghostty-vt/include/ghostty/vt/unicode.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 */ |
