diff --git a/include/ghostty/vt/build_info.h b/include/ghostty/vt/build_info.h index d0aedfdc1..8573556f7 100644 --- a/include/ghostty/vt/build_info.h +++ b/include/ghostty/vt/build_info.h @@ -35,7 +35,7 @@ extern "C" { /** * Build optimization mode. */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_OPTIMIZE_DEBUG = 0, GHOSTTY_OPTIMIZE_RELEASE_SAFE = 1, GHOSTTY_OPTIMIZE_RELEASE_SMALL = 2, @@ -48,7 +48,7 @@ typedef enum { * * Each variant documents the expected output pointer type. */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid data type. Never results in any data extraction. */ GHOSTTY_BUILD_INFO_INVALID = 0, diff --git a/include/ghostty/vt/device.h b/include/ghostty/vt/device.h index 3b6ba3d7c..0a1567280 100644 --- a/include/ghostty/vt/device.h +++ b/include/ghostty/vt/device.h @@ -71,7 +71,7 @@ extern "C" { * * @ingroup terminal */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_COLOR_SCHEME_LIGHT = 0, GHOSTTY_COLOR_SCHEME_DARK = 1, GHOSTTY_COLOR_SCHEME_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, diff --git a/include/ghostty/vt/focus.h b/include/ghostty/vt/focus.h index 2f4954965..b9940f792 100644 --- a/include/ghostty/vt/focus.h +++ b/include/ghostty/vt/focus.h @@ -35,7 +35,7 @@ extern "C" { /** * Focus event types for focus reporting mode (mode 1004). */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Terminal window gained focus */ GHOSTTY_FOCUS_GAINED = 0, /** Terminal window lost focus */ diff --git a/include/ghostty/vt/formatter.h b/include/ghostty/vt/formatter.h index f0fc1447d..358e95f66 100644 --- a/include/ghostty/vt/formatter.h +++ b/include/ghostty/vt/formatter.h @@ -37,7 +37,7 @@ extern "C" { * * @ingroup formatter */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Plain text (no escape sequences). */ GHOSTTY_FORMATTER_FORMAT_PLAIN, diff --git a/include/ghostty/vt/key/encoder.h b/include/ghostty/vt/key/encoder.h index 5d1200741..dc9e27e7e 100644 --- a/include/ghostty/vt/key/encoder.h +++ b/include/ghostty/vt/key/encoder.h @@ -64,7 +64,7 @@ typedef uint8_t GhosttyKittyKeyFlags; * * @ingroup key */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Option key is not treated as alt */ GHOSTTY_OPTION_AS_ALT_FALSE = 0, /** Option key is treated as alt */ @@ -84,7 +84,7 @@ typedef enum { * * @ingroup key */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Terminal DEC mode 1: cursor key application mode (value: bool) */ GHOSTTY_KEY_ENCODER_OPT_CURSOR_KEY_APPLICATION = 0, diff --git a/include/ghostty/vt/key/event.h b/include/ghostty/vt/key/event.h index 39f23d7e4..eba433c6a 100644 --- a/include/ghostty/vt/key/event.h +++ b/include/ghostty/vt/key/event.h @@ -28,7 +28,7 @@ typedef struct GhosttyKeyEventImpl *GhosttyKeyEvent; * * @ingroup key */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Key was released */ GHOSTTY_KEY_ACTION_RELEASE = 0, /** Key was pressed */ @@ -104,7 +104,7 @@ typedef uint16_t GhosttyMods; * * @ingroup key */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_KEY_UNIDENTIFIED = 0, // Writing System Keys (W3C § 3.1.1) diff --git a/include/ghostty/vt/kitty_graphics.h b/include/ghostty/vt/kitty_graphics.h index b9ea64eb3..04d1daf27 100644 --- a/include/ghostty/vt/kitty_graphics.h +++ b/include/ghostty/vt/kitty_graphics.h @@ -107,7 +107,7 @@ extern "C" { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_KITTY_GRAPHICS_DATA_INVALID = 0, @@ -127,7 +127,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_KITTY_GRAPHICS_PLACEMENT_DATA_INVALID = 0, @@ -228,7 +228,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_KITTY_PLACEMENT_LAYER_ALL = 0, GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_BG = 1, GHOSTTY_KITTY_PLACEMENT_LAYER_BELOW_TEXT = 2, @@ -241,7 +241,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** * Set the z-layer filter for the iterator. * @@ -256,7 +256,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_KITTY_IMAGE_FORMAT_RGB = 0, GHOSTTY_KITTY_IMAGE_FORMAT_RGBA = 1, GHOSTTY_KITTY_IMAGE_FORMAT_PNG = 2, @@ -270,7 +270,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_KITTY_IMAGE_COMPRESSION_NONE = 0, GHOSTTY_KITTY_IMAGE_COMPRESSION_ZLIB_DEFLATE = 1, GHOSTTY_KITTY_IMAGE_COMPRESSION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, @@ -281,7 +281,7 @@ typedef enum { * * @ingroup kitty_graphics */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_KITTY_IMAGE_DATA_INVALID = 0, diff --git a/include/ghostty/vt/modes.h b/include/ghostty/vt/modes.h index f8fa7c009..db95a1a7d 100644 --- a/include/ghostty/vt/modes.h +++ b/include/ghostty/vt/modes.h @@ -146,7 +146,7 @@ static inline bool ghostty_mode_ansi(GhosttyMode mode) { * These correspond to the Ps2 parameter in a DECRPM response * sequence (CSI ? Ps1 ; Ps2 $ y). */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Mode is not recognized */ GHOSTTY_MODE_REPORT_NOT_RECOGNIZED = 0, /** Mode is set (enabled) */ diff --git a/include/ghostty/vt/mouse/encoder.h b/include/ghostty/vt/mouse/encoder.h index a82dda089..d84d863c8 100644 --- a/include/ghostty/vt/mouse/encoder.h +++ b/include/ghostty/vt/mouse/encoder.h @@ -30,7 +30,7 @@ typedef struct GhosttyMouseEncoderImpl *GhosttyMouseEncoder; * * @ingroup mouse */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Mouse reporting disabled. */ GHOSTTY_MOUSE_TRACKING_NONE = 0, @@ -53,7 +53,7 @@ typedef enum { * * @ingroup mouse */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_MOUSE_FORMAT_X10 = 0, GHOSTTY_MOUSE_FORMAT_UTF8 = 1, GHOSTTY_MOUSE_FORMAT_SGR = 2, @@ -107,7 +107,7 @@ typedef struct { * * @ingroup mouse */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Mouse tracking mode (value: GhosttyMouseTrackingMode). */ GHOSTTY_MOUSE_ENCODER_OPT_EVENT = 0, diff --git a/include/ghostty/vt/mouse/event.h b/include/ghostty/vt/mouse/event.h index ac71881f2..a24b0c079 100644 --- a/include/ghostty/vt/mouse/event.h +++ b/include/ghostty/vt/mouse/event.h @@ -27,7 +27,7 @@ typedef struct GhosttyMouseEventImpl *GhosttyMouseEvent; * * @ingroup mouse */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Mouse button was pressed. */ GHOSTTY_MOUSE_ACTION_PRESS = 0, @@ -44,7 +44,7 @@ typedef enum { * * @ingroup mouse */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_MOUSE_BUTTON_UNKNOWN = 0, GHOSTTY_MOUSE_BUTTON_LEFT = 1, GHOSTTY_MOUSE_BUTTON_RIGHT = 2, diff --git a/include/ghostty/vt/osc.h b/include/ghostty/vt/osc.h index 43d137061..9409ebc73 100644 --- a/include/ghostty/vt/osc.h +++ b/include/ghostty/vt/osc.h @@ -39,7 +39,7 @@ * * @ingroup osc */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_OSC_COMMAND_INVALID = 0, GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_TITLE = 1, GHOSTTY_OSC_COMMAND_CHANGE_WINDOW_ICON = 2, @@ -74,7 +74,7 @@ typedef enum { * * @ingroup osc */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid data type. Never results in any data extraction. */ GHOSTTY_OSC_DATA_INVALID = 0, diff --git a/include/ghostty/vt/point.h b/include/ghostty/vt/point.h index c1ade0f96..8b717f494 100644 --- a/include/ghostty/vt/point.h +++ b/include/ghostty/vt/point.h @@ -42,7 +42,7 @@ typedef struct { * * @ingroup point */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Active area where the cursor can move. */ GHOSTTY_POINT_TAG_ACTIVE = 0, diff --git a/include/ghostty/vt/render.h b/include/ghostty/vt/render.h index 759c9354c..3c2ea619e 100644 --- a/include/ghostty/vt/render.h +++ b/include/ghostty/vt/render.h @@ -86,7 +86,7 @@ extern "C" { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Not dirty at all; rendering can be skipped. */ GHOSTTY_RENDER_STATE_DIRTY_FALSE = 0, @@ -103,7 +103,7 @@ typedef enum { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Bar cursor (DECSCUSR 5, 6). */ GHOSTTY_RENDER_STATE_CURSOR_VISUAL_STYLE_BAR = 0, @@ -123,7 +123,7 @@ typedef enum { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_RENDER_STATE_DATA_INVALID = 0, @@ -195,7 +195,7 @@ typedef enum { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Set dirty state (GhosttyRenderStateDirty). */ GHOSTTY_RENDER_STATE_OPTION_DIRTY = 0, GHOSTTY_RENDER_STATE_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, @@ -206,7 +206,7 @@ typedef enum { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_RENDER_STATE_ROW_DATA_INVALID = 0, @@ -229,7 +229,7 @@ typedef enum { * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Set dirty state for the current row (bool). */ GHOSTTY_RENDER_STATE_ROW_OPTION_DIRTY = 0, GHOSTTY_RENDER_STATE_ROW_OPTION_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, @@ -481,7 +481,7 @@ GHOSTTY_API GhosttyResult ghostty_render_state_row_cells_new( * * @ingroup render */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid / sentinel value. */ GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_INVALID = 0, diff --git a/include/ghostty/vt/screen.h b/include/ghostty/vt/screen.h index 13bb8e43b..a8f73abad 100644 --- a/include/ghostty/vt/screen.h +++ b/include/ghostty/vt/screen.h @@ -57,7 +57,7 @@ typedef uint64_t GhosttyRow; * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** A single codepoint (may be zero for empty). */ GHOSTTY_CELL_CONTENT_CODEPOINT = 0, @@ -79,7 +79,7 @@ typedef enum { * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Not a wide character, cell width 1. */ GHOSTTY_CELL_WIDE_NARROW = 0, @@ -102,7 +102,7 @@ typedef enum { * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Regular output content, such as command output. */ GHOSTTY_CELL_SEMANTIC_OUTPUT = 0, @@ -122,7 +122,7 @@ typedef enum { * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid data type. Never results in any data extraction. */ GHOSTTY_CELL_DATA_INVALID = 0, @@ -215,7 +215,7 @@ typedef enum { * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** No prompt cells in this row. */ GHOSTTY_ROW_SEMANTIC_NONE = 0, @@ -235,7 +235,7 @@ typedef enum { * * @ingroup screen */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid data type. Never results in any data extraction. */ GHOSTTY_ROW_DATA_INVALID = 0, diff --git a/include/ghostty/vt/sgr.h b/include/ghostty/vt/sgr.h index 00849283d..8eec11dc9 100644 --- a/include/ghostty/vt/sgr.h +++ b/include/ghostty/vt/sgr.h @@ -55,7 +55,7 @@ extern "C" { * * @ingroup sgr */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_SGR_ATTR_UNSET = 0, GHOSTTY_SGR_ATTR_UNKNOWN = 1, GHOSTTY_SGR_ATTR_BOLD = 2, @@ -95,7 +95,7 @@ typedef enum { * * @ingroup sgr */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_SGR_UNDERLINE_NONE = 0, GHOSTTY_SGR_UNDERLINE_SINGLE = 1, GHOSTTY_SGR_UNDERLINE_DOUBLE = 2, diff --git a/include/ghostty/vt/size_report.h b/include/ghostty/vt/size_report.h index d65fa95f6..da33e5e55 100644 --- a/include/ghostty/vt/size_report.h +++ b/include/ghostty/vt/size_report.h @@ -40,7 +40,7 @@ extern "C" { * * Determines the output format for the terminal size report. */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** In-band size report (mode 2048): ESC [ 48 ; rows ; cols ; height ; width t */ GHOSTTY_SIZE_REPORT_MODE_2048 = 0, /** XTWINOPS text area size in pixels: ESC [ 4 ; height ; width t */ diff --git a/include/ghostty/vt/style.h b/include/ghostty/vt/style.h index ea1750395..b6bf860eb 100644 --- a/include/ghostty/vt/style.h +++ b/include/ghostty/vt/style.h @@ -46,7 +46,7 @@ typedef uint16_t GhosttyStyleId; * * @ingroup style */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { GHOSTTY_STYLE_COLOR_NONE = 0, GHOSTTY_STYLE_COLOR_PALETTE = 1, GHOSTTY_STYLE_COLOR_RGB = 2, diff --git a/include/ghostty/vt/sys.h b/include/ghostty/vt/sys.h index 56e60b237..e3d6e2cc7 100644 --- a/include/ghostty/vt/sys.h +++ b/include/ghostty/vt/sys.h @@ -88,7 +88,7 @@ typedef bool (*GhosttySysDecodePngFn)( /** * System option identifiers for ghostty_sys_set(). */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** * Set the userdata pointer passed to all sys callbacks. * diff --git a/include/ghostty/vt/terminal.h b/include/ghostty/vt/terminal.h index c57ba27b5..637bebbfb 100644 --- a/include/ghostty/vt/terminal.h +++ b/include/ghostty/vt/terminal.h @@ -180,7 +180,7 @@ typedef struct { * * @ingroup terminal */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Scroll to the top of the scrollback. */ GHOSTTY_SCROLL_VIEWPORT_TOP, @@ -222,7 +222,7 @@ typedef struct { * * @ingroup terminal */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** The primary (normal) screen. */ GHOSTTY_TERMINAL_SCREEN_PRIMARY = 0, @@ -396,7 +396,7 @@ typedef GhosttyString (*GhosttyTerminalXtversionFn)(GhosttyTerminal terminal, * * @ingroup terminal */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** * Opaque userdata pointer passed to all callbacks. * @@ -584,7 +584,7 @@ typedef enum { * * @ingroup terminal */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Invalid data type. Never results in any data extraction. */ GHOSTTY_TERMINAL_DATA_INVALID = 0, diff --git a/include/ghostty/vt/types.h b/include/ghostty/vt/types.h index 70ac11d57..e0be0b77d 100644 --- a/include/ghostty/vt/types.h +++ b/include/ghostty/vt/types.h @@ -34,29 +34,44 @@ #endif /** - * Sentinel value for enum definitions to force max int width sizing. + * Enum int-sizing helpers. * - * Pre-C23, the C standard allows compilers to choose any integer type - * that can represent all enum values (C11 §6.7.2.2), so small enums - * could be backed by char or short. Adding this value as the last - * entry in every enum forces the compiler to use at an `int` - * type, ensuring ABI stability across compilers and platforms. + * The Zig side backs all C enums with c_int, so the C declarations + * must use int as their underlying type to maintain ABI compatibility. * - * We use INT_MAX rather than a fixed constant like 0xFFFFFFFF because - * enum constants must have type int (which is signed). Values above - * INT_MAX overflow signed int and are a constraint violation in - * standard C; compilers that accept them interpret them as negative - * values via two's complement, which can collide with legitimate - * negative enum values. Using INT_MAX also ensures the enum matches - * the target's int size, which is important because the Zig side - * backs these enums with c_int for ABI compatibility. + * C23 (detected via __STDC_VERSION__ >= 202311L) supports explicit + * enum underlying types with `enum : int { ... }`. For pre-C23 + * compilers, which are free to choose any type that can represent + * all values (C11 §6.7.2.2), we add an INT_MAX sentinel as the last + * entry to force the compiler to use int. + * + * INT_MAX is used rather than a fixed constant like 0xFFFFFFFF + * because enum constants must have type int (which is signed). + * Values above INT_MAX overflow signed int and are a constraint + * violation in standard C; compilers that accept them interpret them + * as negative values via two's complement, which can collide with + * legitimate negative enum values. + * + * Usage: + * @code + * typedef enum GHOSTTY_ENUM_TYPED { + * FOO_A = 0, + * FOO_B = 1, + * FOO_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE, + * } Foo; + * @endcode */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +#define GHOSTTY_ENUM_TYPED : int +#else +#define GHOSTTY_ENUM_TYPED +#endif #define GHOSTTY_ENUM_MAX_VALUE INT_MAX /** * Result codes for libghostty-vt operations. */ -typedef enum { +typedef enum GHOSTTY_ENUM_TYPED { /** Operation completed successfully */ GHOSTTY_SUCCESS = 0, /** Operation failed due to failed allocation */