| 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 | */ |
| 42 | typedef 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 | */ |
| 77 | typedef 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 | */ |
| 108 | GHOSTTY_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 | */ |
| 120 | GHOSTTY_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 | */ |
| 133 | GHOSTTY_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 | */ |
| 150 | GHOSTTY_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 | */ |
| 180 | GHOSTTY_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 | */ |
| 194 | GHOSTTY_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 | */ |
| 211 | GHOSTTY_API bool ghostty_osc_command_data(GhosttyOscCommand command, GhosttyOscCommandData data, void *out); |
| 212 | |
| 213 | /** @} */ |
| 214 | |
| 215 | #endif /* GHOSTTY_VT_OSC_H */ |