mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-18 21:40:29 +00:00
terminal: convert Point to lib.Enum/lib.TaggedUnion with C header
This commit is contained in:
88
include/ghostty/vt/point.h
Normal file
88
include/ghostty/vt/point.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @file point.h
|
||||
*
|
||||
* Terminal point types for referencing locations in the terminal grid.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_POINT_H
|
||||
#define GHOSTTY_VT_POINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @defgroup point Point
|
||||
*
|
||||
* Types for referencing x/y positions in the terminal grid under
|
||||
* different coordinate systems (active area, viewport, full screen,
|
||||
* scrollback history).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* A coordinate in the terminal grid.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef struct {
|
||||
/** Column (0-indexed). */
|
||||
uint16_t x;
|
||||
|
||||
/** Row (0-indexed). May exceed page size for screen/history tags. */
|
||||
uint32_t y;
|
||||
} GhosttyPointCoordinate;
|
||||
|
||||
/**
|
||||
* Point reference tag.
|
||||
*
|
||||
* Determines which coordinate system a point uses.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef enum {
|
||||
/** Active area where the cursor can move. */
|
||||
GHOSTTY_POINT_TAG_ACTIVE = 0,
|
||||
|
||||
/** Visible viewport (changes when scrolled). */
|
||||
GHOSTTY_POINT_TAG_VIEWPORT = 1,
|
||||
|
||||
/** Full screen including scrollback. */
|
||||
GHOSTTY_POINT_TAG_SCREEN = 2,
|
||||
|
||||
/** Scrollback history only (before active area). */
|
||||
GHOSTTY_POINT_TAG_HISTORY = 3,
|
||||
} GhosttyPointTag;
|
||||
|
||||
/**
|
||||
* Point value union.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef union {
|
||||
/** Coordinate (used for all tag variants). */
|
||||
GhosttyPointCoordinate coordinate;
|
||||
|
||||
/** Padding for ABI compatibility. Do not use. */
|
||||
uint64_t _padding[2];
|
||||
} GhosttyPointValue;
|
||||
|
||||
/**
|
||||
* Tagged union for a point in the terminal grid.
|
||||
*
|
||||
* @ingroup point
|
||||
*/
|
||||
typedef struct {
|
||||
GhosttyPointTag tag;
|
||||
GhosttyPointValue value;
|
||||
} GhosttyPoint;
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_POINT_H */
|
||||
@@ -1,52 +1,56 @@
|
||||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const build_options = @import("terminal_options");
|
||||
const lib = @import("../lib/main.zig");
|
||||
const size = @import("size.zig");
|
||||
|
||||
const lib_target: lib.Target = if (build_options.c_abi) .c else .zig;
|
||||
|
||||
/// The possible reference locations for a point. When someone says "(42, 80)"
|
||||
/// in the context of a terminal, that could mean multiple things: it is in the
|
||||
/// current visible viewport? the current active area of the screen where the
|
||||
/// cursor is? the entire scrollback history? etc.
|
||||
///
|
||||
/// This tag is used to differentiate those cases.
|
||||
pub const Tag = enum {
|
||||
/// Top-left is part of the active area where a running program can
|
||||
/// jump the cursor and make changes. The active area is the "editable"
|
||||
/// part of the screen.
|
||||
///
|
||||
/// The bottom-right of the active tag differs from all other tags
|
||||
/// because it includes the full height (rows) of the screen, including
|
||||
/// rows that may not be written yet. This is required because the active
|
||||
/// area is fully "addressable" by the running program (see below) whereas
|
||||
/// the other tags are used primarily for reading/modifying past-written
|
||||
/// data so they can't address unwritten rows.
|
||||
///
|
||||
/// Note for those less familiar with terminal functionality: there
|
||||
/// are escape sequences to move the cursor to any position on
|
||||
/// the screen, but it is limited to the size of the viewport and
|
||||
/// the bottommost part of the screen. Terminal programs can't --
|
||||
/// with sequences at the time of writing this comment -- modify
|
||||
/// anything in the scrollback, visible viewport (if it differs
|
||||
/// from the active area), etc.
|
||||
active,
|
||||
pub const Tag = lib.Enum(lib_target, &.{
|
||||
// Top-left is part of the active area where a running program can
|
||||
// jump the cursor and make changes. The active area is the "editable"
|
||||
// part of the screen.
|
||||
//
|
||||
// The bottom-right of the active tag differs from all other tags
|
||||
// because it includes the full height (rows) of the screen, including
|
||||
// rows that may not be written yet. This is required because the active
|
||||
// area is fully "addressable" by the running program (see below) whereas
|
||||
// the other tags are used primarily for reading/modifying past-written
|
||||
// data so they can't address unwritten rows.
|
||||
//
|
||||
// Note for those less familiar with terminal functionality: there
|
||||
// are escape sequences to move the cursor to any position on
|
||||
// the screen, but it is limited to the size of the viewport and
|
||||
// the bottommost part of the screen. Terminal programs can't --
|
||||
// with sequences at the time of writing this comment -- modify
|
||||
// anything in the scrollback, visible viewport (if it differs
|
||||
// from the active area), etc.
|
||||
"active",
|
||||
|
||||
/// Top-left is the visible viewport. This means that if the user
|
||||
/// has scrolled in any direction, top-left changes. The bottom-right
|
||||
/// is the last written row from the top-left.
|
||||
viewport,
|
||||
// Top-left is the visible viewport. This means that if the user
|
||||
// has scrolled in any direction, top-left changes. The bottom-right
|
||||
// is the last written row from the top-left.
|
||||
"viewport",
|
||||
|
||||
/// Top-left is the furthest back in the scrollback history
|
||||
/// supported by the screen and the bottom-right is the bottom-right
|
||||
/// of the last written row. Note this last point is important: the
|
||||
/// bottom right is NOT necessarily the same as "active" because
|
||||
/// "active" always allows referencing the full rows tall of the
|
||||
/// screen whereas "screen" only contains written rows.
|
||||
screen,
|
||||
// Top-left is the furthest back in the scrollback history
|
||||
// supported by the screen and the bottom-right is the bottom-right
|
||||
// of the last written row. Note this last point is important: the
|
||||
// bottom right is NOT necessarily the same as "active" because
|
||||
// "active" always allows referencing the full rows tall of the
|
||||
// screen whereas "screen" only contains written rows.
|
||||
"screen",
|
||||
|
||||
/// The top-left is the same as "screen" but the bottom-right is
|
||||
/// the line just before the top of "active". This contains only
|
||||
/// the scrollback history.
|
||||
history,
|
||||
};
|
||||
// The top-left is the same as "screen" but the bottom-right is
|
||||
// the line just before the top of "active". This contains only
|
||||
// the scrollback history.
|
||||
"history",
|
||||
});
|
||||
|
||||
/// An x/y point in the terminal for some definition of location (tag).
|
||||
pub const Point = union(Tag) {
|
||||
@@ -64,6 +68,17 @@ pub const Point = union(Tag) {
|
||||
=> |v| v,
|
||||
};
|
||||
}
|
||||
|
||||
const c_union = lib.TaggedUnion(
|
||||
lib_target,
|
||||
@This(),
|
||||
// Padding: largest variant is Coordinate (u16 + u32 = 6 bytes).
|
||||
// Use [2]u64 (16 bytes) for future expansion.
|
||||
[2]u64,
|
||||
);
|
||||
pub const C = c_union.C;
|
||||
pub const CValue = c_union.CValue;
|
||||
pub const cval = c_union.cval;
|
||||
};
|
||||
|
||||
pub const Coordinate = extern struct {
|
||||
|
||||
Reference in New Issue
Block a user