libghostty als zweite Terminal-Engine integriert (Default ghostty, SwiftTerm Fallback)
- vendor/libghostty: vorgebaute macOS-libghostty.a (arm64) + Header + Build-Patches + README - Sources/CGhostty: C-Modul der libghostty-C-API - Sources/MiniTerm/Ghostty.swift: GhosttyApp + GhosttySurfaceView (Surface, Input, Größe, Fokus) - main.swift: Engine-Wahl per Info.plist MTEngine - Package.swift: CGhostty-Target + Link gegen libghostty + Frameworks - STATUS.md: Stand, Build-Weg (macOS-15-VM), offene Punkte
This commit is contained in:
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @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 key "Key Encoding" - Encode key events into terminal sequences
|
||||
* - @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 allocator "Memory Management" - Memory management and custom allocators
|
||||
* - @ref wasm "WebAssembly Utilities" - WebAssembly convenience functions
|
||||
*
|
||||
* @section examples_sec Examples
|
||||
*
|
||||
* Complete working examples:
|
||||
* - @ref c-vt/src/main.c - OSC parser example
|
||||
* - @ref c-vt-key-encode/src/main.c - Key encoding example
|
||||
* - @ref c-vt-paste/src/main.c - Paste safety check example
|
||||
* - @ref c-vt-sgr/src/main.c - SGR parser example
|
||||
*
|
||||
*/
|
||||
|
||||
/** @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-key-encode/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-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.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_H
|
||||
#define GHOSTTY_VT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <ghostty/vt/result.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/osc.h>
|
||||
#include <ghostty/vt/sgr.h>
|
||||
#include <ghostty/vt/key.h>
|
||||
#include <ghostty/vt/paste.h>
|
||||
#include <ghostty/vt/wasm.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_H */
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @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>
|
||||
|
||||
/** @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
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_ALLOCATOR_H */
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file color.h
|
||||
*
|
||||
* Color types and utilities.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_COLOR_H
|
||||
#define GHOSTTY_VT_COLOR_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RGB color value.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
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 sgr
|
||||
*/
|
||||
typedef uint8_t GhosttyColorPaletteIndex;
|
||||
|
||||
/** @addtogroup sgr
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Black color (0) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BLACK 0
|
||||
/** Red color (1) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_RED 1
|
||||
/** Green color (2) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_GREEN 2
|
||||
/** Yellow color (3) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_YELLOW 3
|
||||
/** Blue color (4) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BLUE 4
|
||||
/** Magenta color (5) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_MAGENTA 5
|
||||
/** Cyan color (6) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_CYAN 6
|
||||
/** White color (7) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_WHITE 7
|
||||
/** Bright black color (8) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_BLACK 8
|
||||
/** Bright red color (9) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_RED 9
|
||||
/** Bright green color (10) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_GREEN 10
|
||||
/** Bright yellow color (11) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_YELLOW 11
|
||||
/** Bright blue color (12) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_BLUE 12
|
||||
/** Bright magenta color (13) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_MAGENTA 13
|
||||
/** Bright cyan color (14) @ingroup sgr */
|
||||
#define GHOSTTY_COLOR_NAMED_BRIGHT_CYAN 14
|
||||
/** Bright white color (15) @ingroup sgr */
|
||||
#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 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
|
||||
*/
|
||||
void ghostty_color_rgb_get(GhosttyColorRgb color,
|
||||
uint8_t* r,
|
||||
uint8_t* g,
|
||||
uint8_t* b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_COLOR_H */
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @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().
|
||||
* 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
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @code{.c}
|
||||
* #include <assert.h>
|
||||
* #include <stdio.h>
|
||||
* #include <ghostty/vt.h>
|
||||
*
|
||||
* int main() {
|
||||
* // Create encoder
|
||||
* GhosttyKeyEncoder encoder;
|
||||
* GhosttyResult result = ghostty_key_encoder_new(NULL, &encoder);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
*
|
||||
* // Enable Kitty keyboard protocol with all features
|
||||
* ghostty_key_encoder_setopt(encoder, GHOSTTY_KEY_ENCODER_OPT_KITTY_FLAGS,
|
||||
* &(uint8_t){GHOSTTY_KITTY_KEY_ALL});
|
||||
*
|
||||
* // Create and configure key event for Ctrl+C press
|
||||
* GhosttyKeyEvent event;
|
||||
* result = ghostty_key_event_new(NULL, &event);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
* ghostty_key_event_set_action(event, GHOSTTY_KEY_ACTION_PRESS);
|
||||
* ghostty_key_event_set_key(event, GHOSTTY_KEY_C);
|
||||
* ghostty_key_event_set_mods(event, GHOSTTY_MODS_CTRL);
|
||||
*
|
||||
* // Encode the key event
|
||||
* char buf[128];
|
||||
* size_t written = 0;
|
||||
* result = ghostty_key_encoder_encode(encoder, event, buf, sizeof(buf), &written);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
*
|
||||
* // Use the encoded sequence (e.g., write to terminal)
|
||||
* fwrite(buf, 1, written, stdout);
|
||||
*
|
||||
* // Cleanup
|
||||
* ghostty_key_event_free(event);
|
||||
* ghostty_key_encoder_free(encoder);
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* For a complete working example, see example/c-vt-key-encode in the
|
||||
* repository.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ghostty/vt/key/event.h>
|
||||
#include <ghostty/vt/key/encoder.h>
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_KEY_H */
|
||||
+221
@@ -0,0 +1,221 @@
|
||||
/**
|
||||
* @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/result.h>
|
||||
#include <ghostty/vt/allocator.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 GhosttyKeyEncoder *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 {
|
||||
/** 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,
|
||||
} 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 {
|
||||
/** 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,
|
||||
} 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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).
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
void ghostty_key_encoder_setopt(GhosttyKeyEncoder encoder, GhosttyKeyEncoderOption option, const void *value);
|
||||
|
||||
/**
|
||||
* 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_MEMORY
|
||||
* 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_MEMORY 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_MEMORY)
|
||||
* size_t required = 0;
|
||||
* GhosttyResult result = ghostty_key_encoder_encode(encoder, event, NULL, 0, &required);
|
||||
* assert(result == GHOSTTY_OUT_OF_MEMORY);
|
||||
*
|
||||
* // 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_MEMORY) {
|
||||
* // 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
|
||||
*/
|
||||
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 */
|
||||
+474
@@ -0,0 +1,474 @@
|
||||
/**
|
||||
* @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/result.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 GhosttyKeyEvent *GhosttyKeyEvent;
|
||||
|
||||
/**
|
||||
* Keyboard input event types.
|
||||
*
|
||||
* @ingroup key
|
||||
*/
|
||||
typedef enum {
|
||||
/** 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,
|
||||
} 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_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,
|
||||
} 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool ghostty_key_event_get_composing(GhosttyKeyEvent event);
|
||||
|
||||
/**
|
||||
* Set the UTF-8 text generated by the key event.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
uint32_t ghostty_key_event_get_unshifted_codepoint(GhosttyKeyEvent event);
|
||||
|
||||
#endif /* GHOSTTY_VT_KEY_EVENT_H */
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @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/result.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
|
||||
/**
|
||||
* 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 GhosttyOscParser *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 GhosttyOscCommand *GhosttyOscCommand;
|
||||
|
||||
/** @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_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,
|
||||
} 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 {
|
||||
/** 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,
|
||||
} 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
bool ghostty_osc_command_data(GhosttyOscCommand command, GhosttyOscCommandData data, void *out);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_OSC_H */
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @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 paste data safety.
|
||||
*
|
||||
* ## Basic Usage
|
||||
*
|
||||
* Use ghostty_paste_is_safe() to check if paste data contains potentially
|
||||
* dangerous sequences before sending it to the terminal.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* @code{.c}
|
||||
* #include <stdio.h>
|
||||
* #include <string.h>
|
||||
* #include <ghostty/vt.h>
|
||||
*
|
||||
* int main() {
|
||||
* const char* safe_data = "hello world";
|
||||
* const char* unsafe_data = "rm -rf /\n";
|
||||
*
|
||||
* if (ghostty_paste_is_safe(safe_data, strlen(safe_data))) {
|
||||
* printf("Safe to paste\n");
|
||||
* }
|
||||
*
|
||||
* if (!ghostty_paste_is_safe(unsafe_data, strlen(unsafe_data))) {
|
||||
* printf("Unsafe! Contains newline\n");
|
||||
* }
|
||||
*
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.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
|
||||
*/
|
||||
bool ghostty_paste_is_safe(const char* data, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_PASTE_H */
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* @file result.h
|
||||
*
|
||||
* Result codes for libghostty-vt operations.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_RESULT_H
|
||||
#define GHOSTTY_VT_RESULT_H
|
||||
|
||||
/**
|
||||
* Result codes for libghostty-vt operations.
|
||||
*/
|
||||
typedef enum {
|
||||
/** 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,
|
||||
} GhosttyResult;
|
||||
|
||||
#endif /* GHOSTTY_VT_RESULT_H */
|
||||
+393
@@ -0,0 +1,393 @@
|
||||
/**
|
||||
* @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 various color formats including 8-color, 16-color, 256-color,
|
||||
* X11 named colors, and RGB in multiple formats.
|
||||
*
|
||||
* ## 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
|
||||
*
|
||||
* @code{.c}
|
||||
* #include <assert.h>
|
||||
* #include <stdio.h>
|
||||
* #include <ghostty/vt.h>
|
||||
*
|
||||
* int main() {
|
||||
* // Create parser
|
||||
* GhosttySgrParser parser;
|
||||
* GhosttyResult result = ghostty_sgr_new(NULL, &parser);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
*
|
||||
* // Parse "bold, red foreground" sequence: ESC[1;31m
|
||||
* uint16_t params[] = {1, 31};
|
||||
* result = ghostty_sgr_set_params(parser, params, NULL, 2);
|
||||
* assert(result == GHOSTTY_SUCCESS);
|
||||
*
|
||||
* // Iterate through attributes
|
||||
* GhosttySgrAttribute attr;
|
||||
* while (ghostty_sgr_next(parser, &attr)) {
|
||||
* switch (attr.tag) {
|
||||
* case GHOSTTY_SGR_ATTR_BOLD:
|
||||
* printf("Bold enabled\n");
|
||||
* break;
|
||||
* case GHOSTTY_SGR_ATTR_FG_8:
|
||||
* printf("Foreground color: %d\n", attr.value.fg_8);
|
||||
* break;
|
||||
* default:
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* // Cleanup
|
||||
* ghostty_sgr_free(parser);
|
||||
* return 0;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/result.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* 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 GhosttySgrParser* GhosttySgrParser;
|
||||
|
||||
/**
|
||||
* 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_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,
|
||||
} GhosttySgrAttributeTag;
|
||||
|
||||
/**
|
||||
* Underline style types.
|
||||
*
|
||||
* @ingroup sgr
|
||||
*/
|
||||
typedef enum {
|
||||
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,
|
||||
} 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
void ghostty_wasm_free_sgr_attribute(GhosttySgrAttribute* attr);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* GHOSTTY_VT_SGR_H */
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/**
|
||||
* @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>
|
||||
|
||||
/** @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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
void ghostty_wasm_free_usize(size_t *ptr);
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* __wasm__ */
|
||||
|
||||
#endif /* GHOSTTY_VT_WASM_H */
|
||||
Reference in New Issue
Block a user