# Terminal

type termpaint_terminal

The terminal object represents a connected terminal. This can be seen as the root object in termpaint.

The actual connection with the terminal is left to the application. It can be connected to both a operating system terminal as well as to network protocols with suitable glue.

The terminal always needs an bi-directional connection for the terminal object to work.

See Integration for how write a custom integrate of termpaint into an application.

See Addon termpaintx for a simple premade integration suitable for simple applications using a synchronous usage style or which work with a very simple event loop design.

Terminals have different capabilities and thus a auto detection step is recommended before using the terminal in the application.

Input and other events from the terminal are passed to the application using callback functions. The primary callback is the event callback which is called for keyboard input, mouse events and clipboard paste events. Use `termpaint_terminal_set_event_cb()` to setup your event callback. This callback is required.

Output is done by placing text on the primary surface of the terminal. This surface can be obtained by `termpaint_terminal_get_surface()`. After all text is in place, call `termpaint_terminal_flush()` to output the contents of the surface to the terminal. If no full repaint is requested this will only send differences since the last flush to the terminal.

## Setup

The terminal object works better with terminal specific setup which can enabled by doing a terminal auto-detection before calling `termpaint_terminal_setup_fullscreen()`. The terminal auto-detection can be started using `termpaint_terminal_auto_detect()`. This will initiate bidirectional communication to the terminal. The application can proceed with the setup when the detection is finished.

For applications preferring synchronous integration the application should call `termpaint_terminal_auto_detect_state()` after each additional input from the terminal. If this function returns `termpaint_auto_detect_done` the detection is finished.

For applications preferring asynchronous integration the application needs to wait for an event of type `TERMPAINT_EV_AUTO_DETECT_FINISHED` before proceeding with terminal setup.

In either case the application needs to set an event callback before starting auto-detection.

Applications should call either `termpaint_terminal_setup_fullscreen()` or `termpaint_terminal_setup_inline()` after terminal detection to setup the terminal for the chosen mode.

In fullscreen mode the application claims and repaints the full terminal screen. If the terminal supports alternative screen mode, the terminal contents is not erased by the application and reappears after the application quits.

In inline mode the application instead claims a stripe with limited height for display. This stripe starts at the line where the cursor is located. If the requested number of lines in not available the terminal will be scrolled to make the necessary space available. (Requesting a stripe higher than the terminal height is invalid and will lead to display corruption) When the application terminates in inline mode the cursor is reset to the top line of the stripe and the output stripe is erased.

For clean shutdown the application needs to restore both terminal configuration as well as the kernel level terminal setup back to it’s previous values. The first part should be done by calling `termpaint_terminal_free_with_restore()`. The second part should be done by using operating system specific calls to save the kernel settings before changing those and then restoring them after restoring the terminal setup.

## Common functions

These functions are commonly used when a initialized terminal object has been acquired.

See Safety for general rules for calling functions in termpaint.

void termpaint_terminal_free_with_restore(termpaint_terminal *term)

  Frees the terminal object `term` and restores the attached terminal to its base state.

  This function calls the integrations free callback.

void termpaint_terminal_free_with_restore_and_persistent(termpaint_terminal *term, termpaint_surface *surface)

  Frees the terminal object `term` and restores the attached terminal to its base state. The contents of the surface `surface` is left visible on the terminal. The cursor is placed after the contents of `surface`.

  If `surface` is NULL, this function is the same as `termpaint_terminal_free_with_restore()`.

  This function calls the integrations free callback.

void termpaint_terminal_free(termpaint_terminal *term)

  Frees the terminal object `term` without restoring the attached terminal to it’s base state. This will leave the terminal in a state that other applications or the shell will not be prepared to handle in most cases.

  Prefer to use `termpaint_terminal_free_with_restore()`.

  This function calls the integrations free callback.

void termpaint_terminal_set_event_cb(termpaint_terminal *term, void (*cb)(void *user_data, termpaint_event *event), void *user_data)

  The application must use this function to set an event callback. See Events for details about events produced by terminal input.

  This is mostly a wrapper for using `termpaint_input_set_event_cb()` with a terminal object. Termpaint interprets certain events before passing them on to the application. Also, while running terminal auto detection, events are not passed to the given callback. Some events like `TERMPAINT_EV_AUTO_DETECT_FINISHED` are actually produced by termpaint and not by termpaint_input.

termpaint_surface *termpaint_terminal_get_surface(termpaint_terminal *term)

  Returns the primary surface of the terminal object `term`. This surface is linked to the terminal and can be output using `termpaint_terminal_flush()`.

  This object is owned by the terminal object, don’t free the returned value.

void termpaint_terminal_flush(termpaint_terminal *term, bool full_repaint)

  Output the current state of the primary surface of the terminal object to the attached terminal.

  If `full_repaint` is false it uses incremental drawing to reduce bandwidth use. Else it does a full redraw that can repair the contents of the terminal in case another application interfered with uncoordinated output to the same underlying terminal.

void termpaint_terminal_set_cursor_position(termpaint_terminal *term, int x, int y)

  Sets the text cursor position for the terminal object `term`. The cursor is moved to this position the next time `termpaint_terminal_flush()` is called.

void termpaint_terminal_set_cursor_visible(termpaint_terminal *term, bool visible)

  Sets the visibility of the text cursor for the terminal object `term`. The cursor is shown/hidden the next time `termpaint_terminal_flush()` is called.

void termpaint_terminal_set_cursor_style(termpaint_terminal *term, int style, bool blink)

  Sets the cursor shape / style of the terminal object `term` to the style specified in `style`. If `blink` is true, the cursor will blink.

  The following styles are available:

  > TERMPAINT_CURSOR_STYLE_TERM_DEFAULT

  >   This is the terminal default style. This is terminal implementation and configuration defined.

  > TERMPAINT_CURSOR_STYLE_BLOCK

  >   Display the cursor as a block that covers an entire character.

  > TERMPAINT_CURSOR_STYLE_UNDERLINE

  >   Display the cursor as a underline under the character.

  > TERMPAINT_CURSOR_STYLE_BAR

  >   Display the cursor as a vertical bar between characters.

void termpaint_terminal_set_title(termpaint_terminal *term, const char *title, int mode)

  Set the title of the terminal to the string `title`. `mode` specifies how to handle terminals where it is not certain that the original title can be restored when exiting the application.

  > TERMPAINT_TITLE_MODE_ENSURE_RESTORE

  >   Only set the title if it is certain that the original title can be restored when the application restores the terminal.

  >   This is the recommended mode.

  > TERMPAINT_TITLE_MODE_PREFER_RESTORE

  >   Set the title on all terminals that support setting a title without restricting to terminals that are known to be able to restore the title when the application restores the terminal.

void termpaint_terminal_set_icon_title(termpaint_terminal *term, const char *title, int mode)

  This function is like `termpaint_terminal_set_title()` but does not set the primary title but an alternative title called the icon title. Interpretation of this title differs by terminal.

void termpaint_terminal_set_color(termpaint_terminal *term, int color_slot, int r, int b, int g)

  Set special global (not per cell) terminal colors.

  `color_slot` can be one of:

  > TERMPAINT_COLOR_SLOT_BACKGROUND

  >   This is the color used for cells without an explicitly set background. This color is used e.g. for cells using the `TERMPAINT_DEFAULT_COLOR` as background.

  > TERMPAINT_COLOR_SLOT_FOREGRUND

  >   This is the color used for cells without an explicitly set foreground. This color is used e.g. for cells using the `TERMPAINT_DEFAULT_COLOR` as foreground.

  > TERMPAINT_COLOR_SLOT_CURSOR

  >   Set the color of the cursor in the terminal.

void termpaint_terminal_reset_color(termpaint_terminal *term, int color_slot)

  Reset color choices made using `termpaint_terminal_set_color()`. When `color_slot` is `TERMPAINT_COLOR_SLOT_CURSOR` the cursor color is reset to the default.

void termpaint_terminal_set_inline(termpaint_terminal *terminal, _Bool enabled)

  Switch between inline and fullscreen mode.

  If `enabled` is true switch to inline mode. Otherwise switch to fullscreen mode.

  A call to this function must be followed by reestablishing the primary surface size and contents and by a call to `termpaint_terminal_flush()` to finalize the switch to the new mode.

  Note: As primary surface resizing requirements differ between inline and fullscreen mode, check if your integration has an API for switching that needs to be called in addition or instead of this function. For example when using termpaintx `termpaintx_full_integration_set_inline()` needs to be called instead of this function.

void termpaint_terminal_request_tagged_paste(termpaint_terminal *term, _Bool enabled)

  Request the terminal to send the needed information so `TERMPAINT_EV_PASTE` events can be generated.

void termpaint_terminal_set_mouse_mode(termpaint_terminal *term, int mouse_mode)

  Request the terminal to enable mouse handling by the application. Depending on the setting `TERMPAINT_EV_MOUSE` events will be generated for:

  > TERMPAINT_MOUSE_MODE_OFF

  >   No events.

  >   Terminal native select and copy features will be available to the user.

  > TERMPAINT_MOUSE_MODE_CLICKS

  >   Only report mouse down and up events (clicks).

  >   Terminal native select and copy features will not be available to the user. Some terminals allow overriding this mouse mode using shift temporarily.

  > TERMPAINT_MOUSE_MODE_DRAG

  >   Report mouse down and up events as well as movement when at least one mouse button is held down.

  >   Terminal native select and copy features will not be available to the user. Some terminals allow overriding this mouse mode using shift temporarily.

  > TERMPAINT_MOUSE_MODE_MOVEMENT

  >   Report mouse movement and down and up events independent of mouse button state.

  >   Terminal native select and copy features will not be available to the user. Some terminals allow overriding this mouse mode using shift temporarily.

void termpaint_terminal_request_focus_change_reports(termpaint_terminal *term, _Bool enabled)

  Request focus change events from the terminal. If supported by the terminal these events will be reported as Misc events of type `termpaint_input_focus_in()` and `termpaint_input_focus_out()`.

_Bool termpaint_terminal_should_use_truecolor(termpaint_terminal *terminal)

  After auto detection, returns true if termpaint does not translate rgb color colors to indexed colors.

  To force passing rgb colors to the terminal, one of the the capabilities `TERMPAINT_CAPABILITY_TRUECOLOR_MAYBE_SUPPORTED` or `TERMPAINT_CAPABILITY_TRUECOLOR_SUPPORTED` must be set.

void termpaint_terminal_bell(termpaint_terminal *term)

  Send the BEL character to the terminal. Most terminals trigger a visual or audio reaction to the BEL character.

## Functions for setup and auto-detection

These functions are used to get a initialized terminal object and are somewhat dependent on the integration used.

For the integration from the termpaintx addon a convenience function encapsulating the setup is available as `termpaintx_full_integration_setup_terminal_fullscreen()` that can be used instead.

See Safety for general rules for calling functions in termpaint.

termpaint_terminal *termpaint_terminal_new(termpaint_integration *integration)

  Create a new terminal object.

  See Integration for details on the callbacks needed in `integration`.

  The application has to free this with `termpaint_terminal_free_with_restore()` or `termpaint_terminal_free()`

  If the integration’s free callback frees the integration this takes ownership of the integration.

bool termpaint_terminal_auto_detect(termpaint_terminal *terminal)

  Starts terminal type auto-detection. The event callback has to be set before calling this function.

  Return false, if the auto-detection could not be started.

enum termpaint_auto_detect_state_enum
  enumerator termpaint_auto_detect_none

    Terminal type auto-detection was not run yet.

  enumerator termpaint_auto_detect_running

    Terminal type auto-detection is currently running.

  enumerator termpaint_auto_detect_done

    Terminal type auto-detection was run and has finished.

enum termpaint_auto_detect_state_enum termpaint_terminal_auto_detect_state(const termpaint_terminal *terminal)

  Get the state of a possibly running terminal type auto-detection.

_Bool termpaint_terminal_might_be_supported(const termpaint_terminal *terminal)

  After auto detection, returns true if the terminal might be supported. If it returns false the terminal is likely missing essential features for proper support.

void termpaint_terminal_setup_fullscreen(termpaint_terminal *terminal, int width, int height, const char *options)

  Setup the terminal connected to the terminal object `term` to fullscreen mode. Assume terminal size is `width` columns by `height` lines.

  `options` specifies an space delimited list of additional settings:

  > `-altscreen`

  >   Do not activate the alternative screen of the terminal. Previous contents of the screen is not restored after terminating the application.

  > `+kbdsig`

  >   Do not activate any modes of the terminal that might conflict with processing of keyboard signals in the kernel tty layer. Use this when passing `+kdbsigint`, `+kdbsigquit` or `+kdbsigtstp` to `termpaintx_full_integration()` or when using an custom integration that enabled the equivalent kernel terminal layer processing.

  >   Affected key combinations are usually ctrl-c, ctrl-z and, ctrl-\

void termpaint_terminal_setup_inline(termpaint_terminal *terminal, int width, int height, const char *options)

  Setup the terminal connected to the terminal object `term` to inline mode. Assume terminal size is `width` columns. And the initially used height is `height` lines.

  `options` specifies an space delimited list of additional settings:

  > `+kbdsig`

  >   Do not activate any modes of the terminal that might conflict with processing of keyboard signals in the kernel tty layer. Use this when passing `+kdbsigint`, `+kdbsigquit` or `+kdbsigtstp` to `termpaintx_full_integration()` or when using an custom integration that enabled the equivalent kernel terminal layer processing.

  >   Affected key combinations are usually ctrl-c, ctrl-z and, ctrl-\

  In inline mode termpaint does not paint the full screen, but it only paints a vertical stripe starting at the previous cursor position of a given height. This allows integration of the output into the “transcript” of commands in a command line environment. For example implementing entering of interactive commands.

  Inline mode never uses the alternative screen of the terminal itself. But when switching from inline mode to fullscreen mode, alternative screen mode is always used when available.

void termpaint_terminal_auto_detect_apply_input_quirks(termpaint_terminal *terminal, _Bool backspace_is_x08)

  Setup input handling based on the auto detection result and `backspace_is_x08`.

  Needs to be called after auto detection is finished.

  Pass `backspace_is_x08` as true if the terminal uses 0x08 (ASCII BS) for the backspace key.

  On *nix platforms this information can be obtained from the `termios` structure by `original_termios.c_cc[VERASE] == 0x08`. For ssh connections the VERASE value is transmitted as part of the pseudo terminal request in the encoded terminal modes.

## Special purpose functions

These functions have specialized use. They are not needed in many applications.

See Safety for general rules for calling functions in termpaint.

void termpaint_terminal_pause(termpaint_terminal *term)

  Temporarily restore the terminal state. This should be called before running external applications. To return to rendering by termpaint call `termpaint_terminal_unpause()`.

  After calling this function the application still needs to restore the kernel tty layer settings to the state needed to run external applications.

void termpaint_terminal_pause_and_persistent(termpaint_terminal *term, termpaint_surface *surface)

  Temporarily restore the terminal state. This should be called before running external applications.

  The contents of the surface `surface` is left visible on the terminal. The cursor is placed after the contents of `surface`.

  If `surface` is NULL, this function is the same as `termpaint_terminal_pause_and_persistent()`.

  To return to rendering by termpaint call `termpaint_terminal_unpause()`.

  After calling this function the application still needs to restore the kernel tty layer settings to the state needed to run external applications.

void termpaint_terminal_unpause(termpaint_terminal *term)

  This function activates termpaint mode again after it was previously temporarily restored to the normal state.

  Before calling this function the application needs to restore the kernel tty layer settings to the state needed by termpaint (or to the state before calling pause).

void termpaint_terminal_set_raw_input_filter_cb(termpaint_terminal *term, bool (*cb)(void *user_data, const char *data, unsigned length, bool overflow), void *user_data)

  This function allows settings a callback that is called with raw sequences before interpretation. The application can inspect the sequences in this callback. If the callback returns true the sequence is not interpreted further.

  This is mostly a wrapper for using `termpaint_input_set_raw_filter_cb()` with a terminal object. But events while running terminal auto detection are not passed to the given callback.

void termpaint_terminal_handle_paste(termpaint_terminal *term, _Bool enabled)

  This is a wrapper for using `termpaint_input_handle_paste()` with a terminal object.

  Explicit paste handling is an switchable terminal feature, see `termpaint_terminal_request_tagged_paste()` for enabling it.

const char *termpaint_terminal_self_reported_name_and_version(const termpaint_terminal *terminal)

  Returns a pointer to a string with the result of the terminal’s self reported name and version. Only some terminals support this. For other terminals NULL will be returned.

  This value is only available after successful terminal auto-detection. The returned pointer is valid until the terminal object is freed or terminal auto detection is triggered again.

void termpaint_terminal_auto_detect_result_text(const termpaint_terminal *terminal, char *buffer, int buffer_length)

  Fills `buffer` with null terminated string with debugging details about the detected terminal type. The buffer pointed to by `buffer` needs to be at least `buffer_length` bytes long.

void termpaint_terminal_activate_input_quirk(termpaint_terminal *term, int quirk)

  This is a wrapper for using `termpaint_input_activate_quirk()` with a terminal object.

  Quirks matching the auto detected terminal are already activated by `termpaint_terminal_auto_detect_apply_input_quirks()`.

  Calling this function explicitly should be rarely needed.

const char *termpaint_terminal_peek_input_buffer(const termpaint_terminal *term)

  This function in conjunction with `termpaint_terminal_peek_input_buffer_length()` allows an application to observe input data that is buffered by not yet processed. If called after `termpaint_terminal_add_input_data()` returned, this will contain data in partial or ambiguous sequences not yet processed.

  This is a wrapper for using `termpaint_input_peek_buffer()` with a terminal object.

int termpaint_terminal_peek_input_buffer_length(const termpaint_terminal *term)

  Returns the length of the valid data for `termpaint_terminal_peek_input_buffer()`.

  This is a wrapper for using `termpaint_input_peek_buffer_length()` with a terminal object.

void termpaint_terminal_set_log_mask(termpaint_terminal *term, unsigned mask)

  Set the mask of what besides errors is reported to the integration’s logging callback.

  All logging messages are for debugging only and might change between releases.

  `mask` is a bit combination of

  TERMPAINT_LOG_AUTO_DETECT_TRACE

    Log details of the auto detection state machine

  TERMPAINT_LOG_TRACE_RAW_INPUT

    Log raw input bytes from the terminal.

_Bool termpaint_terminal_capable(const termpaint_terminal *terminal, int capability)

  Features supported differ among terminal implementations. Termpaint uses as set of capabilities to decide how to interface with terminals. This function allows to query currently set capabilities.

  Capabilities start with some defaults and get setup during terminal auto-detection.

  The following capabilities are available:

  > TERMPAINT_CAPABILITY_7BIT_ST

  >   The terminals fully supports using `ESC\\` as string terminator. This is the string terminator specified by ECMA-48.

  > TERMPAINT_CAPABILITY_88_COLOR

  >   The terminal uses 88 colors for indexed colors instead of the more widely supported 256 colors.

  > TERMPAINT_CAPABILITY_CLEARED_COLORING

  >   The terminal supports using “clear to end of line” for trailing sequences of insignificant spaces. This includes support for setting up multiple colored ranges per line using this sequence.

  > TERMPAINT_CAPABILITY_CLEARED_COLORING_DEFCOLOR

  >   If TERMPAINT_CAPABILITY_CLEARED_COLORING is supported this indicated if this sequence also works for the special “default” terminal color.

  > TERMPAINT_CAPABILITY_CSI_EQUALS

  >   The terminal’s escape sequence parser properly handles sequences starting with `ESC[=` and ignores unknown sequences of this type.

  > TERMPAINT_CAPABILITY_CSI_GREATER

  >   The terminal’s escape sequence parser properly handles sequences starting with `ESC[>` and ignores unknown sequences of this type.

  > TERMPAINT_CAPABILITY_CSI_POSTFIX_MOD

  >   The terminal’s escape sequence parser properly handles sequences that use a intermediate character before the final character of a CSI sequence.

  > TERMPAINT_CAPABILITY_CURSOR_SHAPE_OSC50

  >   Cursor shape needs to be setup with a konsole specific escape sequence.

  > TERMPAINT_CAPABILITY_EXTENDED_CHARSET

  >   The terminal is capable of displaying a font with more than 512 different characters.

  > TERMPAINT_CAPABILITY_MAY_TRY_CURSOR_SHAPE

  >   The terminal’s parser is expected to cope with the cursor setup CSI sequence without glitches.

  > TERMPAINT_CAPABILITY_MAY_TRY_CURSOR_SHAPE_BAR

  >   The terminal either does not support cursor shapes or it does support bar cursor shape.

  > TERMPAINT_CAPABILITY_MAY_TRY_TAGGED_PASTE

  >   The terminal supports bracketed/tagged paste.

  > TERMPAINT_CAPABILITY_SAFE_POSITION_REPORT

  >   The terminal uses a format for cursor position reports that is distinct from key press reports.

  > TERMPAINT_CAPABILITY_TITLE_RESTORE

  >   The terminal has a title stack that can be used to restore the title.

  > TERMPAINT_CAPABILITY_TRUECOLOR_MAYBE_SUPPORTED

  >   The terminal is not known to have problems with rgb(truecolor) color types.

  > TERMPAINT_CAPABILITY_TRUECOLOR_SUPPORTED

  >   The terminal is known to support rgb(truecolor) color types.

void termpaint_terminal_promise_capability(termpaint_terminal *terminal, int capability)

  This function allows overriding terminal type auto-detection of terminal capabilities.

  Use this with care, if the terminal is not able to handle the enabled capabilities the rendering might break.

void termpaint_terminal_disable_capability(termpaint_terminal *terminal, int capability)

  This function allows overriding terminal type auto-detection of terminal capabilities.

  On specific use is to disable `TERMPAINT_CAPABILITY_TRUECOLOR_MAYBE_SUPPORTED` to switch to a more conservative estamination of a terminals capability to support rgb color modes.

void termpaint_terminal_expect_apc_input_sequences(termpaint_terminal *term, _Bool enabled)

  This is a wrapper for using `termpaint_input_expect_apc_sequences()` with a terminal object.

  APC sequences are only known to be used by kitty in an extended keyboard reporting mode that is currently not supported by termpaint.

void termpaint_terminal_expect_cursor_position_report(termpaint_terminal *term)

  This is a wrapper for using `termpaint_input_expect_cursor_position_report()` with a terminal object.

  Needs to be called for each `ESC[6n` sequence send manually to the terminal to ensure the result is interpreted as cursor position report instead of a key press.

  If the terminal `properly supports ESC[?6n` that sequence should be used and this function does not need to be called.

void termpaint_terminal_expect_legacy_mouse_reports(termpaint_terminal *term, int s)

  This is a wrapper for using `termpaint_input_expect_legacy_mouse_reports()` with a terminal object.

  When mouse reporting is enabled this function is internally called with `TERMPAINT_INPUT_EXPECT_LEGACY_MOUSE`, so it should be rarely needed to call this explicitly.

void termpaint_terminal_glitch_on_out_of_memory(termpaint_terminal *term)

  Normally termpaint aborts the process on memory allocation failure to avoid hard to debug glitches.

  When this function is called instead termpaint tries to continue, but potentially discarding output characters and attributes where allocation would be needed.

  Call this function if your application needs to be resilient against memory allocation failures.

  To use termpaint in such environments it’s additionally required to call variants of functions ending in _or_nullptr or _mustcheck instead of the base variant whenever those exist in the header file.

  See Environments that need to handle malloc failure for details.

## Functions for integrations

See Safety for general rules for calling functions in termpaint.

const char *termpaint_terminal_restore_sequence(const termpaint_terminal *term)

  Returns a null terminated string that can be used to restore the terminal to it’s base state.

  The restore string is the same string that is used when calling `termpaint_terminal_free_with_restore()` or `termpaint_terminal_pause()`.

void termpaint_terminal_callback(termpaint_terminal *term)

  If the application has set `request_callback` in the integration structure, this function needs to be called after a delay when the terminal object requests it by invoking the `request_callback` callback.

void termpaint_terminal_add_input_data(termpaint_terminal *term, const char *data, unsigned length)

  The integration part of the application has to call this function to pass terminal input data to the terminal object. See Integration for details.

  The application has to ensure that this function is never called recursively from a callback with any `termpaint_input` object that is already in a call to `termpaint_terminal_add_input_data`.

  This is a wrapper for using `termpaint_input_add_data()` with a terminal object.