---
name: "libtty"
section: "3"
platform: "linux"
package: "libtty-dev"
version: "0.19-2"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/libtty"
---

# libtty(3)

a library for handling vt100-like pseudo-terminals

## NAME

libtty - a library for handling vt100-like pseudo-terminals

## SYNOPSIS

**#include \<tty.h\>**

Link with *-ltty*.

## DESCRIPTION

### Functions:

- **tty tty\_init(int** *sx***, int** *sy***, int** *resizable***);**

  Creates a new vt100 terminal, of size *sx*X*sy*.  If you want user input to be allowed to change that size, set *resizable* to non-zero.

- **int tty\_resize(tty** *vt***, int** *nsx***, int** *nsy***);**

  Resizes the *vt* to *nsx*X*nsy*.  This works even on terminals marked as non-resizable since that prevents only user input from resizing, not you.

- **void tty\_reset(tty** *vt***);**

  Clears the screen and attributes.

- **void tty\_free(tty** *vt***);**

  Deallocates the *vt* and all its internal structures.

- **void tty\_write(tty** *vt***, const char \****buf***, int** *len***);**

  Writes *len* bytes into the terminal, parsing them as vt100 codes.

- **void tty\_printf(tty** *vt***, const char \****fmt***,** *...***);**

  Does a **printf** into the terminal.

- **tty tty\_copy(tty** *vt***);**

  Allocates a new vt100 terminal, making it an exact copy of an existing one, including its internal state.  Attached event callbacks are not copied.

- **uint32\_t tty\_color\_convert(uint32\_t** *c***, uint32\_t** *to***);**

  Converts color values between modes: VT100\_COLOR\_OFF, VT100\_COLOR\_16, VT100\_COLOR\_256, VT100\_COLOR\_RGB.

### Inside the terminal

You'll most likely be interested in the following fields of the structure:

- tty {

  - int *sx*,*sy*; // screen size

  - int *cx*,*cy*; // cursor position

  - attrchar \**scr*; // screen buffer

  - int *attr*; // current attribute

  - char \**title*; // window title

  *scr* is an array of character/attribute pairs, more exactly, each element is a struct `"{ ucs ch; int attr; }"`. The array is a flat one of *vt***-\>***sx*\**vt***-\>***sy* elements, arranged row by row.  A screen coordinate *x*,*y* is stored at *x*+*y*\**vt***-\>***sy*.

For other fields, please RTFS the header itself: **tty.h**

### TTY event callbacks

Well, you have written some data to the terminal.  Now you probably want to put it somewhere.  What now?  The tty structure has a number of *event hooks* that you can attach your functions to.

These hooks are callbacks inside the **tty** structure that you can set.  The callback fields are:

- **void \*l\_data;**

  it's a place to put your private data in

- **void (\*l\_char)(tty** *vt***, int** *x***, int** *y***, ucs** *ch***, int** *attr***, int** *width***);**

  after a character has been written to the screen; the cursor advances by *width* which might be 1 (regular) or 2 (CJK "fullwidth")

- **void (\*l\_cursor)(tty** *vt***, int** *x***, int** *y***);**

  after the cursor has moved

- **void (\*l\_clear)(tty** *vt***, int** *x***, int** *y***, int** *len***);**

  after a chunk of screen has been cleared

  If an endpoint spills outside of the current line, it will go all the way to an end of screen.

  If the cursor moves, you'll get a separate *l\_cursor*, although it is already in place during the *l\_clear* call.

- **void (\*l\_scroll)(tty** *vt***, int** *nl***);**

  after the region s1\<=y\<s2 is scrolled nl lines (nl\<0 -\> backwards, nl\>0 -\> forward).

  There's no separare *l\_cursor* event, *cx* and *cy* are already updated.

- **void (\*l\_flag)(tty** *vt***, int** *f***, int** *v***);**

  when a flag changes to *v*.  Flags that are likely to be of interest to you are:

  - •

    **VT100\_FLAG\_CURSOR**

    cursor visibility

  - •

    **VT100\_FLAG\_KPAD**

    application keypad mode (more detailed codes for keypad arrow keys)

- **void (\*l\_osc)(tty** *vt***, int** *cmd***, const char \****str***);**

  when a string command has been issued; most commands alter a color palette, but the most interesting one is **0**: "set window title"

- **void (\*l\_resize)(tty** *vt***, int** *sx***, int** *sy***);**

  after the terminal has been resized

- **void (\*l\_flush)(tty** *vt***);**

  when a write chunk ends

- **void (\*l\_bell)(tty** *vt***);**

  upon a beep

- **void (\*l\_free)(tty** *vt***);**

  before the terminal is destroyed

### Vt-on-vt redirection

For the case when you want the output go to a real terminal, there are:

- **void vtvt\_attach(tty** *vt***, FILE \****f***, int** *dump***);**

  Attaches the FILE stream *f* to terminal *vt*.  Usually, *f* will be **stdout**. Whenever the contents of *vt* changes, appropriate data will be written to the stream as well.  If *dump* is non-zero, the current state will be drawn, otherwise, only subsequent changes will be shown.

  The redirection will last until the terminal is destroyed by **tty\_free()**.

- **void vtvt\_resize(tty** *vt***, int** *sx***, int** *sy***);**

  Tells libtty that the **real** terminal has been resized (for resizing the virtual one, please use **tty\_resize()**).

- **void vtvt\_dump(tty** *vt***);**

  Forces a full-screen redraw of the current contents of *vt*.

## SEE ALSO

[**libttyrec**(3)](/libttyrec/3.md)
