1/**
2 * @file osc.h
3 *
4 * OSC (Operating System Command) sequence parser and command handling.
5 */
6
7#ifndef GHOSTTY_VT_OSC_H
8#define GHOSTTY_VT_OSC_H
9
10#include <stdbool.h>
11#include <stddef.h>
12#include <stdint.h>
13#include <ghostty/vt/types.h>
14#include <ghostty/vt/allocator.h>
15
16/** @defgroup osc OSC Parser
17 *
18 * OSC (Operating System Command) sequence parser and command handling.
19 *
20 * The parser operates in a streaming fashion, processing input byte-by-byte
21 * to handle OSC sequences that may arrive in fragments across multiple reads.
22 * This interface makes it easy to integrate into most environments and avoids
23 * over-allocating buffers.
24 *
25 * ## Basic Usage
26 *
27 * 1. Create a parser instance with ghostty_osc_new()
28 * 2. Feed bytes to the parser using ghostty_osc_next()
29 * 3. Finalize parsing with ghostty_osc_end() to get the command
30 * 4. Query command type and extract data using ghostty_osc_command_type()
31 * and ghostty_osc_command_data()
32 * 5. Free the parser with ghostty_osc_free() when done
33 *
34 * @{
35 */
36
37/**
38 * OSC command types.
39 *
40 * @ingroup osc
41 */
42typedef enum GHOSTTY_ENUM_TYPED {
43 GHOSTTY_OSC_COMMAND_INVALID = 0,
44 GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE = 1,
45 GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_ICON = 2,
46 GHOSTTY_OSC_COMMAND_SEMANTIC_PROMPT = 3,
47 GHOSTTY_OSC_COMMAND_CLIPBOARD_CONTENTS = 4,
48 GHOSTTY_OSC_COMMAND_REPORT_PWD = 5,
49 GHOSTTY_OSC_COMMAND_MOUSE_SHAPE = 6,
50 GHOSTTY_OSC_COMMAND_COLOR_OPERATION = 7,
51 GHOSTTY_OSC_COMMAND_KITTY_COLOR_PROTOCOL = 8,
52 GHOSTTY_OSC_COMMAND_SHOW_DESKTOP_NOTIFICATION = 9,
53 GHOSTTY_OSC_COMMAND_HYPERLINK_START = 10,
54 GHOSTTY_OSC_COMMAND_HYPERLINK_END = 11,
55 GHOSTTY_OSC_COMMAND_CONEMU_SLEEP = 12,
56 GHOSTTY_OSC_COMMAND_CONEMU_SHOW_MESSAGE_BOX = 13,
57 GHOSTTY_OSC_COMMAND_CONEMU_CHANGE_TAB_TITLE = 14,
58 GHOSTTY_OSC_COMMAND_CONEMU_PROGRESS_REPORT = 15,
59 GHOSTTY_OSC_COMMAND_CONEMU_WAIT_INPUT = 16,
60 GHOSTTY_OSC_COMMAND_CONEMU_GUIMACRO = 17,
61 GHOSTTY_OSC_COMMAND_CONEMU_RUN_PROCESS = 18,
62 GHOSTTY_OSC_COMMAND_CONEMU_OUTPUT_ENVIRONMENT_VARIABLE = 19,
63 GHOSTTY_OSC_COMMAND_CONEMU_XTERM_EMULATION = 20,
64 GHOSTTY_OSC_COMMAND_CONEMU_COMMENT = 21,
65 GHOSTTY_OSC_COMMAND_KITTY_TEXT_SIZING = 22,
66 GHOSTTY_OSC_COMMAND_TYPE_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
67} GhosttyOscCommandType;
68
69/**
70 * OSC command data types.
71 *
72 * These values specify what type of data to extract from an OSC command
73 * using `ghostty_osc_command_data`.
74 *
75 * @ingroup osc
76 */
77typedef enum GHOSTTY_ENUM_TYPED {
78 /** Invalid data type. Never results in any data extraction. */
79 GHOSTTY_OSC_DATA_INVALID = 0,
80
81 /**
82 * Window title string data.
83 *
84 * Valid for: GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE
85 *
86 * Output type: const char ** (pointer to null-terminated string)
87 *
88 * Lifetime: Valid until the next call to any ghostty_osc_* function with
89 * the same parser instance. Memory is owned by the parser.
90 */
91 GHOSTTY_OSC_DATA_CHANGE_WINDOW_TITLE_STR = 1,
92 GHOSTTY_OSC_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
93} GhosttyOscCommandData;
94
95/**
96 * Create a new OSC parser instance.
97 *
98 * Creates a new OSC (Operating System Command) parser using the provided
99 * allocator. The parser must be freed using ghostty_vt_osc_free() when
100 * no longer needed.
101 *
102 * @param allocator Pointer to the allocator to use for memory management, or NULL to use the default allocator
103 * @param parser Pointer to store the created parser handle
104 * @return GHOSTTY_SUCCESS on success, or an error code on failure
105 *
106 * @ingroup osc
107 */
108GHOSTTY_API GhosttyResult ghostty_osc_new(const GhosttyAllocator *allocator, GhosttyOscParser *parser);
109
110/**
111 * Free an OSC parser instance.
112 *
113 * Releases all resources associated with the OSC parser. After this call,
114 * the parser handle becomes invalid and must not be used.
115 *
116 * @param parser The parser handle to free (may be NULL)
117 *
118 * @ingroup osc
119 */
120GHOSTTY_API void ghostty_osc_free(GhosttyOscParser parser);
121
122/**
123 * Reset an OSC parser instance to its initial state.
124 *
125 * Resets the parser state, clearing any partially parsed OSC sequences
126 * and returning the parser to its initial state. This is useful for
127 * reusing a parser instance or recovering from parse errors.
128 *
129 * @param parser The parser handle to reset, must not be null.
130 *
131 * @ingroup osc
132 */
133GHOSTTY_API void ghostty_osc_reset(GhosttyOscParser parser);
134
135/**
136 * Parse the next byte in an OSC sequence.
137 *
138 * Processes a single byte as part of an OSC sequence. The parser maintains
139 * internal state to track the progress through the sequence. Call this
140 * function for each byte in the sequence data.
141 *
142 * When finished pumping the parser with bytes, call ghostty_osc_end
143 * to get the final result.
144 *
145 * @param parser The parser handle, must not be null.
146 * @param byte The next byte to parse
147 *
148 * @ingroup osc
149 */
150GHOSTTY_API void ghostty_osc_next(GhosttyOscParser parser, uint8_t byte);
151
152/**
153 * Finalize OSC parsing and retrieve the parsed command.
154 *
155 * Call this function after feeding all bytes of an OSC sequence to the parser
156 * using ghostty_osc_next() with the exception of the terminating character
157 * (ESC or ST). This function finalizes the parsing process and returns the
158 * parsed OSC command.
159 *
160 * The return value is never NULL. Invalid commands will return a command
161 * with type GHOSTTY_OSC_COMMAND_INVALID.
162 *
163 * The terminator parameter specifies the byte that terminated the OSC sequence
164 * (typically 0x07 for BEL or 0x5C for ST after ESC). This information is
165 * preserved in the parsed command so that responses can use the same terminator
166 * format for better compatibility with the calling program. For commands that
167 * do not require a response, this parameter is ignored and the resulting
168 * command will not retain the terminator information.
169 *
170 * The returned command handle is valid until the next call to any
171 * `ghostty_osc_*` function with the same parser instance with the exception
172 * of command introspection functions such as `ghostty_osc_command_type`.
173 *
174 * @param parser The parser handle, must not be null.
175 * @param terminator The terminating byte of the OSC sequence (0x07 for BEL, 0x5C for ST)
176 * @return Handle to the parsed OSC command
177 *
178 * @ingroup osc
179 */
180GHOSTTY_API GhosttyOscCommand ghostty_osc_end(GhosttyOscParser parser, uint8_t terminator);
181
182/**
183 * Get the type of an OSC command.
184 *
185 * Returns the type identifier for the given OSC command. This can be used
186 * to determine what kind of command was parsed and what data might be
187 * available from it.
188 *
189 * @param command The OSC command handle to query (may be NULL)
190 * @return The command type, or GHOSTTY_OSC_COMMAND_INVALID if command is NULL
191 *
192 * @ingroup osc
193 */
194GHOSTTY_API GhosttyOscCommandType ghostty_osc_command_type(GhosttyOscCommand command);
195
196/**
197 * Extract data from an OSC command.
198 *
199 * Extracts typed data from the given OSC command based on the specified
200 * data type. The output pointer must be of the appropriate type for the
201 * requested data kind. Valid command types, output types, and memory
202 * safety information are documented in the `GhosttyOscCommandData` enum.
203 *
204 * @param command The OSC command handle to query (may be NULL)
205 * @param data The type of data to extract
206 * @param out Pointer to store the extracted data (type depends on data parameter)
207 * @return true if data extraction was successful, false otherwise
208 *
209 * @ingroup osc
210 */
211GHOSTTY_API bool ghostty_osc_command_data(GhosttyOscCommand command, GhosttyOscCommandData data, void *out);
212
213/** @} */
214
215#endif /* GHOSTTY_VT_OSC_H */