/** * @file modes.h * * Terminal mode utilities - pack and unpack ANSI/DEC mode identifiers. */ #ifndef GHOSTTY_VT_MODES_H #define GHOSTTY_VT_MODES_H /** @defgroup modes Mode Utilities * * Utilities for working with terminal modes. A mode is a compact * 16-bit representation of a terminal mode identifier that encodes both * the numeric mode value (up to 15 bits) and whether the mode is an ANSI * mode or a DEC private mode (?-prefixed). * * The packed layout (least-significant bit first) is: * - Bits 0–14: mode value (u15) * - Bit 15: ANSI flag (0 = DEC private mode, 1 = ANSI mode) * * ## Example * * @snippet c-vt-modes/src/main.c modes-pack-unpack * * ## DECRPM Report Encoding * * Use ghostty_mode_report_encode() to encode a DECRPM response into a * caller-provided buffer: * * @snippet c-vt-modes/src/main.c modes-decrpm * * @{ */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /** @name ANSI Modes * Modes for standard ANSI modes. * @{ */ #define GHOSTTY_MODE_KAM (ghostty_mode_new(2, true)) /**< Keyboard action (disable keyboard) */ #define GHOSTTY_MODE_INSERT (ghostty_mode_new(4, true)) /**< Insert mode */ #define GHOSTTY_MODE_SRM (ghostty_mode_new(12, true)) /**< Send/receive mode */ #define GHOSTTY_MODE_LINEFEED (ghostty_mode_new(20, true)) /**< Linefeed/new line mode */ /** @} */ /** @name DEC Private Modes * Modes for DEC private modes (?-prefixed). * @{ */ #define GHOSTTY_MODE_DECCKM (ghostty_mode_new(1, false)) /**< Cursor keys */ #define GHOSTTY_MODE_132_COLUMN (ghostty_mode_new(3, false)) /**< 132/80 column mode */ #define GHOSTTY_MODE_SLOW_SCROLL (ghostty_mode_new(4, false)) /**< Slow scroll */ #define GHOSTTY_MODE_REVERSE_COLORS (ghostty_mode_new(5, false)) /**< Reverse video */ #define GHOSTTY_MODE_ORIGIN (ghostty_mode_new(6, false)) /**< Origin mode */ #define GHOSTTY_MODE_WRAPAROUND (ghostty_mode_new(7, false)) /**< Auto-wrap mode */ #define GHOSTTY_MODE_AUTOREPEAT (ghostty_mode_new(8, false)) /**< Auto-repeat keys */ #define GHOSTTY_MODE_X10_MOUSE (ghostty_mode_new(9, false)) /**< X10 mouse reporting */ #define GHOSTTY_MODE_CURSOR_BLINKING (ghostty_mode_new(12, false)) /**< Cursor blink */ #define GHOSTTY_MODE_CURSOR_VISIBLE (ghostty_mode_new(25, false)) /**< Cursor visible (DECTCEM) */ #define GHOSTTY_MODE_ENABLE_MODE_3 (ghostty_mode_new(40, false)) /**< Allow 132 column mode */ #define GHOSTTY_MODE_REVERSE_WRAP (ghostty_mode_new(45, false)) /**< Reverse wrap */ #define GHOSTTY_MODE_ALT_SCREEN_LEGACY (ghostty_mode_new(47, false)) /**< Alternate screen (legacy) */ #define GHOSTTY_MODE_KEYPAD_KEYS (ghostty_mode_new(66, false)) /**< Application keypad */ #define GHOSTTY_MODE_BACKARROW_KEY_MODE (ghostty_mode_new(67, false)) /**< Backarrow key mode (DECBKM) */ #define GHOSTTY_MODE_LEFT_RIGHT_MARGIN (ghostty_mode_new(69, false)) /**< Left/right margin mode */ #define GHOSTTY_MODE_NORMAL_MOUSE (ghostty_mode_new(1000, false)) /**< Normal mouse tracking */ #define GHOSTTY_MODE_BUTTON_MOUSE (ghostty_mode_new(1002, false)) /**< Button-event mouse tracking */ #define GHOSTTY_MODE_ANY_MOUSE (ghostty_mode_new(1003, false)) /**< Any-event mouse tracking */ #define GHOSTTY_MODE_FOCUS_EVENT (ghostty_mode_new(1004, false)) /**< Focus in/out events */ #define GHOSTTY_MODE_UTF8_MOUSE (ghostty_mode_new(1005, false)) /**< UTF-8 mouse format */ #define GHOSTTY_MODE_SGR_MOUSE (ghostty_mode_new(1006, false)) /**< SGR mouse format */ #define GHOSTTY_MODE_ALT_SCROLL (ghostty_mode_new(1007, false)) /**< Alternate scroll mode */ #define GHOSTTY_MODE_URXVT_MOUSE (ghostty_mode_new(1015, false)) /**< URxvt mouse format */ #define GHOSTTY_MODE_SGR_PIXELS_MOUSE (ghostty_mode_new(1016, false)) /**< SGR-Pixels mouse format */ #define GHOSTTY_MODE_NUMLOCK_KEYPAD (ghostty_mode_new(1035, false)) /**< Ignore keypad with NumLock */ #define GHOSTTY_MODE_ALT_ESC_PREFIX (ghostty_mode_new(1036, false)) /**< Alt key sends ESC prefix */ #define GHOSTTY_MODE_ALT_SENDS_ESC (ghostty_mode_new(1039, false)) /**< Alt sends escape */ #define GHOSTTY_MODE_REVERSE_WRAP_EXT (ghostty_mode_new(1045, false)) /**< Extended reverse wrap */ #define GHOSTTY_MODE_ALT_SCREEN (ghostty_mode_new(1047, false)) /**< Alternate screen */ #define GHOSTTY_MODE_SAVE_CURSOR (ghostty_mode_new(1048, false)) /**< Save cursor (DECSC) */ #define GHOSTTY_MODE_ALT_SCREEN_SAVE (ghostty_mode_new(1049, false)) /**< Alt screen + save cursor + clear */ #define GHOSTTY_MODE_BRACKETED_PASTE (ghostty_mode_new(2004, false)) /**< Bracketed paste mode */ #define GHOSTTY_MODE_SYNC_OUTPUT (ghostty_mode_new(2026, false)) /**< Synchronized output */ #define GHOSTTY_MODE_GRAPHEME_CLUSTER (ghostty_mode_new(2027, false)) /**< Grapheme cluster mode */ #define GHOSTTY_MODE_COLOR_SCHEME_REPORT (ghostty_mode_new(2031, false)) /**< Report color scheme */ #define GHOSTTY_MODE_IN_BAND_RESIZE (ghostty_mode_new(2048, false)) /**< In-band size reports */ /** @} */ /** * A packed 16-bit terminal mode. * * Encodes a mode value (bits 0–14) and an ANSI flag (bit 15) into a * single 16-bit integer. Use the inline helper functions to construct * and inspect modes rather than manipulating bits directly. */ typedef uint16_t GhosttyMode; /** * Create a mode from a mode value and ANSI flag. * * @param value The numeric mode value (0–32767) * @param ansi true for an ANSI mode, false for a DEC private mode * @return The packed mode * * @ingroup modes */ static inline GhosttyMode ghostty_mode_new(uint16_t value, bool ansi) { return (GhosttyMode)((value & 0x7FFF) | ((uint16_t)ansi << 15)); } /** * Extract the numeric mode value from a mode. * * @param mode The mode * @return The mode value (0–32767) * * @ingroup modes */ static inline uint16_t ghostty_mode_value(GhosttyMode mode) { return mode & 0x7FFF; } /** * Check whether a mode represents an ANSI mode. * * @param mode The mode * @return true if this is an ANSI mode, false if it is a DEC private mode * * @ingroup modes */ static inline bool ghostty_mode_ansi(GhosttyMode mode) { return (mode >> 15) != 0; } /** * DECRPM report state values. * * These correspond to the Ps2 parameter in a DECRPM response * sequence (CSI ? Ps1 ; Ps2 $ y). */ typedef enum GHOSTTY_ENUM_TYPED { /** Mode is not recognized */ GHOSTTY_MODE_REPORT_NOT_RECOGNIZED = 0, /** Mode is set (enabled) */ GHOSTTY_MODE_REPORT_SET = 1, /** Mode is reset (disabled) */ GHOSTTY_MODE_REPORT_RESET = 2, /** Mode is permanently set */ GHOSTTY_MODE_REPORT_PERMANENTLY_SET = 3, /** Mode is permanently reset */ GHOSTTY_MODE_REPORT_PERMANENTLY_RESET = 4, GHOSTTY_MODE_REPORT_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, } GhosttyModeReportState; /** * Encode a DECRPM (DEC Private Mode Report) response sequence. * * Writes a mode report escape sequence into the provided buffer. * The generated sequence has the form: * - DEC private mode: CSI ? Ps1 ; Ps2 $ y * - ANSI mode: CSI Ps1 ; Ps2 $ y * * If the buffer is too small, the function returns GHOSTTY_OUT_OF_SPACE * and writes the required buffer size to @p out_written. The caller can * then retry with a sufficiently sized buffer. * * @param mode The mode identifying the mode to report on * @param state The report state for this mode * @param buf Output buffer to write the encoded sequence into (may be NULL) * @param buf_len Size of the output buffer in bytes * @param[out] out_written On success, the number of bytes written. On * GHOSTTY_OUT_OF_SPACE, the required buffer size. * @return GHOSTTY_SUCCESS on success, GHOSTTY_OUT_OF_SPACE if the buffer * is too small */ GHOSTTY_API GhosttyResult ghostty_mode_report_encode( GhosttyMode mode, GhosttyModeReportState state, char* buf, size_t buf_len, size_t* out_written); #ifdef __cplusplus } #endif /** @} */ #endif /* GHOSTTY_VT_MODES_H */