mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-18 21:40:29 +00:00
vt: expose color_scheme effect callback
Change device_status.ColorScheme from a plain Zig enum to lib.Enum so it uses c_int backing when targeting the C ABI. Add a color_scheme callback to the C terminal effects, following the bool + out-pointer pattern used by the size callback. The trampoline converts between the C calling convention and the internal stream handler color_scheme effect, returning null when no callback is set. Add device_status.h header with GhosttyColorScheme enum and wire it through terminal.h as GHOSTTY_TERMINAL_OPT_COLOR_SCHEME (= 7) with GhosttyTerminalColorSchemeFn.
This commit is contained in:
@@ -109,6 +109,7 @@ extern "C" {
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/build_info.h>
|
||||
#include <ghostty/vt/color.h>
|
||||
#include <ghostty/vt/device_status.h>
|
||||
#include <ghostty/vt/focus.h>
|
||||
#include <ghostty/vt/formatter.h>
|
||||
#include <ghostty/vt/render.h>
|
||||
|
||||
28
include/ghostty/vt/device_status.h
Normal file
28
include/ghostty/vt/device_status.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @file device_status.h
|
||||
*
|
||||
* Device status types used by the terminal.
|
||||
*/
|
||||
|
||||
#ifndef GHOSTTY_VT_DEVICE_STATUS_H
|
||||
#define GHOSTTY_VT_DEVICE_STATUS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Color scheme reported in response to a CSI ? 996 n query.
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef enum {
|
||||
GHOSTTY_COLOR_SCHEME_LIGHT = 0,
|
||||
GHOSTTY_COLOR_SCHEME_DARK = 1,
|
||||
} GhosttyColorScheme;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GHOSTTY_VT_DEVICE_STATUS_H */
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdint.h>
|
||||
#include <ghostty/vt/types.h>
|
||||
#include <ghostty/vt/allocator.h>
|
||||
#include <ghostty/vt/device_status.h>
|
||||
#include <ghostty/vt/modes.h>
|
||||
#include <ghostty/vt/size_report.h>
|
||||
#include <ghostty/vt/grid_ref.h>
|
||||
@@ -217,6 +218,24 @@ typedef GhosttyString (*GhosttyTerminalXtversionFn)(GhosttyTerminal terminal,
|
||||
typedef void (*GhosttyTerminalTitleChangedFn)(GhosttyTerminal terminal,
|
||||
void* userdata);
|
||||
|
||||
/**
|
||||
* Callback function type for color scheme queries (CSI ? 996 n).
|
||||
*
|
||||
* Called when the terminal receives a color scheme device status report
|
||||
* query. Return true and fill *out_scheme with the current color scheme,
|
||||
* or return false to silently ignore the query.
|
||||
*
|
||||
* @param terminal The terminal handle
|
||||
* @param userdata The userdata pointer set via GHOSTTY_TERMINAL_OPT_USERDATA
|
||||
* @param[out] out_scheme Pointer to store the current color scheme
|
||||
* @return true if the color scheme was filled, false to ignore the query
|
||||
*
|
||||
* @ingroup terminal
|
||||
*/
|
||||
typedef bool (*GhosttyTerminalColorSchemeFn)(GhosttyTerminal terminal,
|
||||
void* userdata,
|
||||
GhosttyColorScheme* out_scheme);
|
||||
|
||||
/**
|
||||
* Callback function type for size queries (XTWINOPS).
|
||||
*
|
||||
@@ -300,6 +319,16 @@ typedef enum {
|
||||
* Input type: GhosttyTerminalSizeFn*
|
||||
*/
|
||||
GHOSTTY_TERMINAL_OPT_SIZE = 6,
|
||||
|
||||
/**
|
||||
* Callback invoked in response to a color scheme device status
|
||||
* report query (CSI ? 996 n). Return true and fill the out pointer
|
||||
* to report the current scheme, or return false to silently ignore.
|
||||
* Set to NULL to ignore color scheme queries.
|
||||
*
|
||||
* Input type: GhosttyTerminalColorSchemeFn*
|
||||
*/
|
||||
GHOSTTY_TERMINAL_OPT_COLOR_SCHEME = 7,
|
||||
} GhosttyTerminalOption;
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ const kitty = @import("../kitty/key.zig");
|
||||
const modes = @import("../modes.zig");
|
||||
const point = @import("../point.zig");
|
||||
const size = @import("../size.zig");
|
||||
const device_status = @import("../device_status.zig");
|
||||
const size_report = @import("../size_report.zig");
|
||||
const cell_c = @import("cell.zig");
|
||||
const row_c = @import("row.zig");
|
||||
@@ -38,6 +39,7 @@ const Effects = struct {
|
||||
userdata: ?*anyopaque = null,
|
||||
write_pty: ?WritePtyFn = null,
|
||||
bell: ?BellFn = null,
|
||||
color_scheme: ?ColorSchemeFn = null,
|
||||
enquiry: ?EnquiryFn = null,
|
||||
xtversion: ?XtversionFn = null,
|
||||
title_changed: ?TitleChangedFn = null,
|
||||
@@ -49,6 +51,11 @@ const Effects = struct {
|
||||
/// C function pointer type for the bell callback.
|
||||
pub const BellFn = *const fn (Terminal, ?*anyopaque) callconv(.c) void;
|
||||
|
||||
/// C function pointer type for the color_scheme callback.
|
||||
/// Returns true and fills out_scheme if a color scheme is available,
|
||||
/// or returns false to silently ignore the query.
|
||||
pub const ColorSchemeFn = *const fn (Terminal, ?*anyopaque, *device_status.ColorScheme) callconv(.c) bool;
|
||||
|
||||
/// C function pointer type for the enquiry callback.
|
||||
/// Returns the response bytes. The memory must remain valid
|
||||
/// until the callback returns.
|
||||
@@ -82,6 +89,15 @@ const Effects = struct {
|
||||
func(@ptrCast(wrapper), wrapper.effects.userdata);
|
||||
}
|
||||
|
||||
fn colorSchemeTrampoline(handler: *Handler) ?device_status.ColorScheme {
|
||||
const stream_ptr: *Stream = @fieldParentPtr("handler", handler);
|
||||
const wrapper: *TerminalWrapper = @fieldParentPtr("stream", stream_ptr);
|
||||
const func = wrapper.effects.color_scheme orelse return null;
|
||||
var scheme: device_status.ColorScheme = undefined;
|
||||
if (func(@ptrCast(wrapper), wrapper.effects.userdata, &scheme)) return scheme;
|
||||
return null;
|
||||
}
|
||||
|
||||
fn enquiryTrampoline(handler: *Handler) []const u8 {
|
||||
const stream_ptr: *Stream = @fieldParentPtr("handler", handler);
|
||||
const wrapper: *TerminalWrapper = @fieldParentPtr("stream", stream_ptr);
|
||||
@@ -176,6 +192,7 @@ fn new_(
|
||||
var handler: Stream.Handler = t.vtHandler();
|
||||
handler.effects.write_pty = &Effects.writePtyTrampoline;
|
||||
handler.effects.bell = &Effects.bellTrampoline;
|
||||
handler.effects.color_scheme = &Effects.colorSchemeTrampoline;
|
||||
handler.effects.enquiry = &Effects.enquiryTrampoline;
|
||||
handler.effects.xtversion = &Effects.xtversionTrampoline;
|
||||
handler.effects.title_changed = &Effects.titleChangedTrampoline;
|
||||
@@ -207,6 +224,7 @@ pub const Option = enum(c_int) {
|
||||
xtversion = 4,
|
||||
title_changed = 5,
|
||||
size_cb = 6,
|
||||
color_scheme = 7,
|
||||
|
||||
/// Input type expected for setting the option.
|
||||
pub fn InType(comptime self: Option) type {
|
||||
@@ -214,6 +232,7 @@ pub const Option = enum(c_int) {
|
||||
.userdata => ?*anyopaque,
|
||||
.write_pty => ?Effects.WritePtyFn,
|
||||
.bell => ?Effects.BellFn,
|
||||
.color_scheme => ?Effects.ColorSchemeFn,
|
||||
.enquiry => ?Effects.EnquiryFn,
|
||||
.xtversion => ?Effects.XtversionFn,
|
||||
.title_changed => ?Effects.TitleChangedFn,
|
||||
@@ -253,6 +272,7 @@ fn setTyped(
|
||||
.userdata => wrapper.effects.userdata = if (value) |v| v.* else null,
|
||||
.write_pty => wrapper.effects.write_pty = if (value) |v| v.* else null,
|
||||
.bell => wrapper.effects.bell = if (value) |v| v.* else null,
|
||||
.color_scheme => wrapper.effects.color_scheme = if (value) |v| v.* else null,
|
||||
.enquiry => wrapper.effects.enquiry = if (value) |v| v.* else null,
|
||||
.xtversion => wrapper.effects.xtversion = if (value) |v| v.* else null,
|
||||
.title_changed => wrapper.effects.title_changed = if (value) |v| v.* else null,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
const std = @import("std");
|
||||
const build_options = @import("terminal_options");
|
||||
const lib = @import("../lib/main.zig");
|
||||
const lib_target: lib.Target = if (build_options.c_abi) .c else .zig;
|
||||
|
||||
/// The color scheme reported in response to a CSI ? 996 n query.
|
||||
pub const ColorScheme = enum {
|
||||
light,
|
||||
dark,
|
||||
};
|
||||
pub const ColorScheme = lib.Enum(lib_target, &.{
|
||||
"light",
|
||||
"dark",
|
||||
});
|
||||
|
||||
/// An enum(u16) of the available device status requests.
|
||||
pub const Request = dsr_enum: {
|
||||
|
||||
Reference in New Issue
Block a user