mirror of
https://github.com/aphrody-labs/opentui.git
synced 2026-10-13 21:08:53 +00:00
Keep controls in editor text and render them as safe, visible notation. This lets the cursor, selection, wrapping, and offsets handle controls consistently without sending them to the terminal. Strip terminal escape sequences from pasted text so pasted controls cannot change terminal state. Alternative to #1632 and aligned with how vim does it. We accidentally in pre 0.6 and explicit in 0.6.x rejects edit text that contains a C0 control other than tab, carriage return, and line feed, DEL, or a C1 control: `setText()`, `insertText()`, `replaceText()`, Textarea `initialValue`, and `Input.value` throw `NativeError` with `InvalidArgument`. The reason is that the editor places its cursor by display cell, and a control took no cells, so the cursor could neither move past it nor delete it. In 0.5.14, which accepted controls, the cursor in `"a\fb"` could not reach column 0, Backspace stopped at `"a\f"`, and rendering `"A\x07B\x1bC\fD"` wrote raw BEL and ESC bytes to the terminal while `C` and `D` vanished. This is an alternative to #1632, which drops these characters. Instead, editors keep them and show them the way Vim and Neovim do. Measured with Neovim 0.12.5 and Vim 9.2, both show `a^Lb^@c^[d<85>e^?f`: a C0 control or DEL as caret notation in 2 cells, and a C1 control as hex in 4 cells. The cursor stops on each one, `x` deletes one, and writing the file back gives identical bytes. Editors now do the same. A per-buffer `ControlDisplay` setting is passed with the tab width to the native width functions, so cursor movement, deletion, wrapping, selection, history, and drawing share one rule: - C0 controls other than tab, LF, and CR, and DEL, show as `^@`..`^_` and `^?` in 2 cells. C1 controls show as `<80>`..`<9f>` in 4 cells. Tab, LF, and CR keep their current behavior. - Cells still never hold a raw control: drawing writes the notation's printable glyphs. - Each control is its own grapheme, so it no longer joins the next character, and a soft wrap never splits its notation. - `getText()`, undo and redo, and selection copy return the original bytes. - Read-only text keeps hiding controls with zero width, so `TextRenderable`, the console, and other displayed text do not change. Only `EditBuffer` and its placeholder use notation. Text input changes with it: - Paste keeps controls, as Vim does, and still removes escape sequences. The stripper is now one shared implementation, so Bun and Node give the same result, and core no longer depends on `strip-ansi`. A lone ESC and a truncated sequence are removed, so a paste never inserts ESC. Key sequences with a control stay ignored, so Escape does not insert `^[`. - `Input` puts its cursor at the native end of the value instead of the string length. - Extmarks convert display offsets through native `offsetToPosition` instead of JavaScript string widths, and Right stops at the native end of the buffer before a virtual extmark. `deleteLine` adjusts extmarks by native line offsets. - `EditBuffer.measureText(text)` and `ot_edit_buffer_measure_text` return the display offset at the end of a text as the buffer would lay it out, without storing it. JavaScript width functions give a control and a tab no cells, so an app that computes editor offsets in JavaScript needs this: in `"\f@fi"` the `@` is at offset 2, not 0. Along the way, these bugs that already exist in are fixed: - A standalone zero-width cluster (zero-width space, word joiner, BOM) blocked Left and Backspace in the Unicode width methods. - After `"日\u{fffd}"`, Backspace deleted the wide character. In the no_zwj method, one emoji step had the wrong size. - U+FFFD inside a joining sequence, such as `"क्\u{FFFD}\u{301}ष"`, made layout and cursor movement disagree: Right got stuck, and Backspace deleted the wrong cells. - An extmark ending at a line end after a tab lost its last cell. Right could step into a virtual extmark after CJK text. `deleteLine` moved extmarks by UTF-16 indexes. `Input` placed its cursor in the middle after CJK text. Backspace no longer measures the whole chunk for each step. The native "backspace 500 chars" benchmark takes 0.21 ms instead of 25.3 ms on v0.6.0; other benchmarks match v0.6.0 within noise. Most of the diff passes the new setting to the width functions: of the added lines, most only add `.hidden`, `.notation`, or `control_display`, and others of them in existing tests. Net source is +86 lines and net tests +95. Not included: a distinct style for the notation (like Vim's SpecialKey), a literal-insert key, `^M` for a lone CR, controls as word boundaries, and clipping wide units cell by cell at the left edge of a horizontally scrolled view. Fixes #1642
316 lines
19 KiB
TypeScript
316 lines
19 KiB
TypeScript
export interface PointerPolicy {
|
|
ffi: "buffer" | "ptr"
|
|
nullable: "never" | "empty" | "optional"
|
|
retention:
|
|
| "call"
|
|
| "until-measure-replaced-unset-or-node-context-destroyed"
|
|
| "until-observer-replaced-unset-or-context-destroyed"
|
|
source: "view" | "native-address" | "view-or-native-address" | "callback"
|
|
result?: { nullable: "on-error"; release: "ot_context_destroy" }
|
|
}
|
|
|
|
export type PointerPolicies = Record<string, Partial<Record<number | "returns", PointerPolicy>>>
|
|
|
|
export type AddressFields = Record<
|
|
string,
|
|
Record<string, { type: string; nullable: boolean; lifetime: string; release: string; element: string }>
|
|
>
|
|
|
|
const context = { ffi: "ptr", nullable: "never", retention: "call", source: "native-address" } as const
|
|
const buffer = { ffi: "buffer", nullable: "never", retention: "call", source: "view" } as const
|
|
const optional = { ffi: "ptr", nullable: "optional", retention: "call", source: "view" } as const
|
|
const empty = { ffi: "ptr", nullable: "empty", retention: "call", source: "view" } as const
|
|
const pixels = { ffi: "ptr", nullable: "empty", retention: "call", source: "view-or-native-address" } as const
|
|
const measure = {
|
|
ffi: "ptr",
|
|
nullable: "optional",
|
|
source: "callback",
|
|
retention: "until-measure-replaced-unset-or-node-context-destroyed",
|
|
} as const
|
|
const observer = {
|
|
ffi: "ptr",
|
|
nullable: "optional",
|
|
source: "callback",
|
|
retention: "until-observer-replaced-unset-or-context-destroyed",
|
|
} as const
|
|
|
|
// This is host policy, not a second C signature table. Each pointer position is
|
|
// explicit; scalar widths, pointer types, symbols and records come from Translate-C.
|
|
// `nullable` describes values passed by this binding. Several C spans also accept
|
|
// NULL at zero length, but their existing TS callers always pass a view (`buffer`).
|
|
// `retention` describes borrowing the pointer itself, not copying/retaining handles.
|
|
// Changes to C ownership comments require review here: C pointer types cannot prove lifetimes.
|
|
export const nativePointerPolicies = {
|
|
ot_output_write_callback: {
|
|
0: { ...optional, source: "native-address" },
|
|
1: { ...context, source: "native-address" },
|
|
},
|
|
ot_context_create: { 0: buffer, 1: { ...buffer, result: { nullable: "on-error", release: "ot_context_destroy" } } },
|
|
ot_context_destroy: { 0: context },
|
|
ot_context_get_last_error: { 0: context, 1: buffer },
|
|
ot_context_drain_diagnostics: { 0: context, 1: empty, 3: buffer },
|
|
ot_context_get_link_url: { 0: context, 2: buffer, 4: buffer },
|
|
ot_unicode_create: { 0: context, 1: empty, 4: buffer },
|
|
ot_unicode_destroy: { 0: context, 1: buffer },
|
|
ot_unicode_get: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_buffer_draw_unicode: { 0: context, 1: buffer, 2: optional, 3: buffer, 7: buffer, 8: buffer },
|
|
ot_embedded_terminal_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_embedded_terminal_destroy: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_write: { 0: context, 1: buffer, 2: empty },
|
|
ot_embedded_terminal_resize: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_command: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_set_selection: { 0: context, 1: buffer },
|
|
ot_embedded_terminal_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_embedded_terminal_compose: { 0: context, 1: buffer, 2: buffer, 3: optional },
|
|
ot_embedded_terminal_cursor_get: { 0: context, 1: buffer, 2: buffer },
|
|
ot_embedded_terminal_encode_key: { 0: context, 1: buffer, 2: buffer, 3: empty, 5: empty, 7: empty, 9: buffer },
|
|
ot_embedded_terminal_encode_mouse: { 0: context, 1: buffer, 2: buffer, 3: buffer, 5: buffer },
|
|
ot_embedded_terminal_encode_paste: { 0: context, 1: buffer, 2: empty, 4: empty, 6: buffer },
|
|
ot_embedded_terminal_encode_focus: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_embedded_terminal_drain_responses: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_image_destroy: { 0: context, 1: buffer },
|
|
ot_image_inspect: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_decode: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_create_pixels: { 0: context, 1: buffer, 8: buffer },
|
|
ot_image_update_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_clone: { 0: context, 1: context, 2: buffer, 3: buffer },
|
|
ot_image_retain: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_resize: { 0: context, 1: buffer, 5: buffer },
|
|
ot_image_extract: { 0: context, 1: buffer, 6: buffer },
|
|
ot_image_extend: { 0: context, 1: buffer, 6: buffer, 7: buffer },
|
|
ot_image_transform: { 0: context, 1: buffer, 3: buffer },
|
|
ot_image_composite: { 0: context, 1: buffer, 2: buffer, 7: buffer },
|
|
ot_image_copy_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_copy_png: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_image_take_pixels: { 0: context, 1: buffer, 2: buffer },
|
|
ot_image_pixels_release: { 0: context, 1: buffer },
|
|
ot_scene_set_image: { 0: context, 1: buffer, 2: optional, 5: optional },
|
|
ot_buffer_draw_image: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: buffer, 5: buffer },
|
|
ot_session_set_image_resolution: { 0: context, 1: buffer },
|
|
ot_session_set_kitty_image_transport: { 0: context, 1: buffer },
|
|
ot_session_get_kitty_image_transport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_poll_kitty_image_transport: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_cancel_kitty_image_transport: { 0: context, 1: buffer },
|
|
ot_session_process_kitty_image_reply: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_session_start_kitty_file_probe: { 0: context, 1: buffer },
|
|
ot_text_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_text_buffer_view_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_destroy: { 0: context, 1: buffer },
|
|
ot_text_buffer_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_text_buffer_append: { 0: context, 1: buffer, 2: empty },
|
|
ot_text_buffer_clear: { 0: context, 1: buffer },
|
|
ot_text_buffer_set_styled_text: { 0: context, 1: buffer, 2: empty, 4: empty, 6: empty },
|
|
ot_text_buffer_replace_styled_batch: { 0: context, 1: buffer, 3: buffer, 5: buffer, 7: buffer, 9: buffer },
|
|
ot_text_buffer_set_syntax_style: { 0: context, 1: buffer, 2: optional },
|
|
ot_text_buffer_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_text_buffer_get_range: { 0: context, 1: buffer, 4: empty, 6: buffer },
|
|
ot_text_buffer_set_defaults: { 0: context, 1: buffer, 3: buffer },
|
|
ot_text_buffer_set_tab_width: { 0: context, 1: buffer },
|
|
ot_text_buffer_highlight: { 0: context, 1: buffer, 4: optional },
|
|
ot_text_buffer_get_highlights: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_text_buffer_view_set_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_command: { 0: context, 1: buffer },
|
|
ot_text_buffer_view_set_tab_color: { 0: context, 1: buffer, 2: optional },
|
|
ot_text_buffer_view_select: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_text_buffer_view_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_text_buffer_view_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_text_buffer_view_get_lines: { 0: context, 1: buffer, 4: empty, 6: buffer },
|
|
ot_text_buffer_view_measure: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_set_text_view: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_text_view_paint: { 0: context, 1: buffer },
|
|
ot_buffer_draw_text_view: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_buffer_draw_editor_view: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_buffer_draw_scene_text: { 0: context, 1: buffer, 2: optional, 3: buffer },
|
|
ot_edit_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_editor_view_create: { 0: context, 1: buffer, 4: buffer },
|
|
ot_editor_view_destroy: { 0: context, 1: buffer },
|
|
ot_syntax_style_create: { 0: context, 1: buffer },
|
|
ot_syntax_style_destroy: { 0: context, 1: buffer },
|
|
ot_edit_buffer_set_syntax_style: { 0: context, 1: buffer, 2: optional },
|
|
ot_edit_buffer_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_edit_buffer_insert_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_edit_buffer_delete_range: { 0: context, 1: buffer },
|
|
ot_edit_buffer_set_cursor: { 0: context, 1: buffer },
|
|
ot_edit_buffer_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_edit_buffer_get_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_set_tab_width: { 0: context, 1: buffer },
|
|
ot_edit_buffer_command: { 0: context, 1: buffer },
|
|
ot_edit_buffer_history: { 0: context, 1: buffer, 3: buffer, 5: buffer },
|
|
ot_edit_buffer_get_position: { 0: context, 1: buffer, 5: buffer },
|
|
ot_edit_buffer_get_range: { 0: context, 1: buffer, 7: empty, 9: buffer },
|
|
ot_edit_buffer_measure_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_edit_buffer_set_defaults: { 0: context, 1: buffer, 3: buffer },
|
|
ot_syntax_style_register: { 0: context, 1: buffer, 2: empty, 4: buffer, 5: buffer },
|
|
ot_syntax_style_resolve: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_syntax_style_get_count: { 0: context, 1: buffer, 2: buffer },
|
|
ot_edit_buffer_highlight: { 0: context, 1: buffer, 4: optional },
|
|
ot_edit_buffer_get_highlights: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_editor_view_set_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_get_viewport: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_set_scroll_margin: { 0: context, 1: buffer },
|
|
ot_editor_view_command: { 0: context, 1: buffer },
|
|
ot_editor_view_replace_selection: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_editor_view_set_tab_color: { 0: context, 1: buffer, 2: optional },
|
|
ot_editor_view_select: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_editor_view_get_info: { 0: context, 1: buffer, 3: buffer },
|
|
ot_editor_view_get_selection: { 0: context, 1: buffer, 2: buffer },
|
|
ot_editor_view_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_editor_view_get_position: { 0: context, 1: buffer, 3: buffer },
|
|
ot_editor_view_get_lines: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_editor_view_measure: { 0: context, 1: buffer, 4: buffer },
|
|
ot_editor_view_set_placeholder: { 0: context, 1: buffer, 2: empty, 4: empty },
|
|
ot_context_set_edit_event_callback: { 0: context, 1: observer },
|
|
ot_buffer_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_buffer_destroy: { 0: context, 1: buffer },
|
|
ot_buffer_resize: { 0: context, 1: buffer },
|
|
ot_buffer_draw: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: optional, 5: buffer, 7: buffer },
|
|
ot_buffer_stack: { 0: context, 1: buffer, 2: optional, 8: buffer, 9: buffer },
|
|
ot_buffer_draw_grid: { 0: context, 1: buffer, 2: optional, 3: buffer, 4: buffer, 6: buffer },
|
|
ot_buffer_draw_packed: { 0: context, 1: buffer, 2: optional, 3: pixels },
|
|
ot_buffer_draw_supersample: { 0: context, 1: buffer, 2: optional, 3: pixels },
|
|
ot_buffer_draw_grayscale: { 0: context, 1: buffer, 2: optional, 3: buffer, 9: optional, 10: optional },
|
|
ot_buffer_color_matrix: { 0: context, 1: buffer, 2: optional, 3: buffer, 5: optional, 7: buffer },
|
|
ot_buffer_acquire_lease: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_create: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_attach_renderer: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_attach_renderer_with_env: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_session_render: { 0: context, 1: buffer, 3: buffer },
|
|
ot_scene_frame_copy_buffer: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_measure_layout: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_render_split: { 0: context, 1: buffer, 2: optional, 3: empty, 7: buffer },
|
|
ot_session_split_control: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_session_set_screen: { 0: context, 1: buffer, 5: buffer },
|
|
ot_session_sync_detached: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_resize_renderer: { 0: context, 1: buffer },
|
|
ot_session_draw_buffer: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_set_debug_overlay: { 0: context, 1: buffer },
|
|
ot_session_update_stats: { 0: context, 1: buffer },
|
|
ot_session_update_memory_stats: { 0: context, 1: buffer },
|
|
ot_session_dump_hit_grid: { 0: context, 1: buffer },
|
|
ot_session_get_renderer_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_acquire_buffer_lease: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_get_link_id: { 0: context, 1: buffer, 4: buffer },
|
|
ot_buffer_lease_validate: { 0: context, 1: buffer },
|
|
ot_buffer_lease_release: { 0: context, 1: buffer },
|
|
ot_buffer_lease_get_real_char_size: { 0: context, 1: buffer, 3: buffer },
|
|
ot_buffer_lease_write_resolved_chars: { 0: context, 1: buffer, 2: empty, 5: empty, 7: buffer },
|
|
ot_session_setup_terminal: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_suspend: { 0: context, 1: buffer },
|
|
ot_session_resume: { 0: context, 1: buffer },
|
|
ot_session_get_terminal_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_pump: { 0: context, 1: buffer, 4: buffer },
|
|
ot_session_pump_exit: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_control: { 0: context, 1: buffer, 2: buffer, 3: empty },
|
|
ot_session_clipboard: { 0: context, 1: buffer, 3: buffer, 5: buffer },
|
|
ot_session_notification: { 0: context, 1: buffer, 2: buffer, 4: empty, 6: buffer },
|
|
ot_session_set_palette_state: { 0: context, 1: buffer, 2: buffer, 4: buffer, 5: buffer },
|
|
ot_session_get_capabilities: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_get_write_limit: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_write: { 0: context, 1: buffer, 2: empty },
|
|
ot_session_read_output: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_session_drain_output: {
|
|
0: context,
|
|
1: buffer,
|
|
3: buffer,
|
|
4: { ...optional, source: "view-or-native-address" },
|
|
5: { ffi: "ptr", nullable: "never", retention: "call", source: "callback" },
|
|
},
|
|
ot_session_drain_stdout: { 0: context, 1: buffer, 3: buffer },
|
|
ot_session_complete_output: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_close: { 0: context, 1: buffer },
|
|
ot_session_cancel: { 0: context, 1: buffer },
|
|
ot_session_get_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_session_destroy: { 0: context, 1: buffer },
|
|
ot_clipboard_service_create: { 0: context, 3: empty },
|
|
ot_clipboard_service_begin_shutdown: { 0: context },
|
|
ot_clipboard_service_poll_shutdown: { 0: context },
|
|
ot_clipboard_service_destroy: { 0: context },
|
|
ot_clipboard_service_drain: { 0: context },
|
|
ot_clipboard_read_operation_start: { 0: context, 1: buffer, 8: buffer },
|
|
ot_clipboard_write_operation_start: { 0: context, 1: buffer, 5: buffer },
|
|
ot_clipboard_clear_operation_start: { 0: context, 3: buffer },
|
|
ot_clipboard_operation_poll: { 0: context, 1: buffer },
|
|
ot_clipboard_operation_cancel: { 0: context, 1: buffer },
|
|
ot_clipboard_operation_result_mime_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_mime_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_data_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_data_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_error_code: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_diagnostic_length: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_result_diagnostic_copy: { 0: context, 1: buffer, 2: buffer },
|
|
ot_clipboard_operation_destroy: { 0: context, 1: buffer },
|
|
ot_scene_create_node: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_destroy_node: { 0: context, 1: buffer },
|
|
ot_scene_move_node: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_viewport: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_focus: { 0: context, 1: buffer },
|
|
ot_scene_set_style: { 0: context, 1: buffer },
|
|
ot_scene_flush: { 0: context, 1: empty, 3: buffer },
|
|
ot_scene_set_measure: { 0: context, 1: buffer, 2: measure },
|
|
ot_scene_has_measure: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_mark_dirty: { 0: context, 1: buffer },
|
|
ot_scene_get_style: { 0: context, 1: buffer, 5: buffer },
|
|
ot_scene_set_paint: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_surface: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_box_details: { 0: context, 1: buffer, 2: buffer, 3: empty, 5: empty },
|
|
ot_scene_set_slider: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_slider_thumb: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_arrow: { 0: context, 1: buffer, 2: buffer, 3: optional },
|
|
ot_scene_set_editor_view: { 0: context, 1: buffer, 2: optional },
|
|
ot_scene_set_editor_options: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_text: { 0: context, 1: buffer, 2: empty },
|
|
ot_scene_set_styled_text: { 0: context, 1: buffer, 2: empty, 4: empty, 6: empty },
|
|
ot_scene_set_text_options: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_set_text_selection: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_get_text_selection: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_selected_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_scene_get_text: { 0: context, 1: buffer, 2: empty, 4: buffer },
|
|
ot_scene_get_text_info: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_text_lines: { 0: context, 1: buffer, 3: empty, 5: buffer },
|
|
ot_scene_get_layout: { 0: context, 1: buffer, 3: buffer },
|
|
ot_scene_paint: { 0: context, 1: buffer, 2: buffer, 5: buffer },
|
|
ot_scene_set_hooks: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_frame_step_with_geometry: {
|
|
0: context,
|
|
1: buffer,
|
|
2: optional,
|
|
3: buffer,
|
|
5: optional,
|
|
7: buffer,
|
|
8: buffer,
|
|
},
|
|
ot_scene_frame_get_paint_slots: { 0: context, 1: buffer, 2: buffer, 3: buffer, 5: buffer },
|
|
ot_scene_frame_acquire_buffer_lease: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_scene_frame_draw_buffer: { 0: context, 1: buffer, 2: buffer, 3: buffer },
|
|
ot_scene_frame_commit: { 0: context, 1: buffer, 2: buffer, 4: buffer },
|
|
ot_scene_frame_cancel: { 0: context, 1: buffer },
|
|
ot_scene_hit_test: { 0: context, 1: buffer, 4: buffer },
|
|
ot_scene_get_stats: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_get_cursor_state: { 0: context, 1: buffer, 2: buffer },
|
|
ot_scene_measure_callback: { 7: { ffi: "ptr", nullable: "never", retention: "call", source: "native-address" } },
|
|
} satisfies PointerPolicies
|
|
|
|
// The header intentionally transports these native addresses as fixed-width u64.
|
|
// Their storage is borrowed until lease release; record copying never retains it.
|
|
export const nativeAddressFields = {
|
|
ot_image_pixels: {
|
|
pixels: { type: "u64", nullable: false, lifetime: "lease", release: "ot_image_pixels_release", element: "u8" },
|
|
},
|
|
ot_buffer_lease_snapshot: {
|
|
char_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u32" },
|
|
fg_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u16" },
|
|
bg_ptr: { type: "u64", nullable: false, lifetime: "lease", release: "ot_buffer_lease_release", element: "u16" },
|
|
attributes_ptr: {
|
|
type: "u64",
|
|
nullable: false,
|
|
lifetime: "lease",
|
|
release: "ot_buffer_lease_release",
|
|
element: "u32",
|
|
},
|
|
},
|
|
} as const satisfies AddressFields
|