.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "LIBTTY 3" .TH LIBTTY 3 "2018-09-30" "UNKNOWN" "termrec" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" libtty \- a library for handling vt100\-like pseudo\-terminals .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fB#include \fR .PP Link with \fI\-ltty\fR. .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "Functions:" .IX Subsection "Functions:" .IP "\fBtty tty_init(int \fR\fIsx\fR\fB, int \fR\fIsy\fR\fB, int \fR\fIresizable\fR\fB);\fR" 4 .IX Item "tty tty_init(int sx, int sy, int resizable);" Creates a new vt100 terminal, of size \fIsx\fRX\fIsy\fR. If you want user input to be allowed to change that size, set \fIresizable\fR to non-zero. .IP "\fBint tty_resize(tty \fR\fIvt\fR\fB, int \fR\fInsx\fR\fB, int \fR\fInsy\fR\fB);\fR" 4 .IX Item "int tty_resize(tty vt, int nsx, int nsy);" Resizes the \fIvt\fR to \fInsx\fRX\fInsy\fR. This works even on terminals marked as non-resizable since that prevents only user input from resizing, not you. .IP "\fBvoid tty_reset(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void tty_reset(tty vt);" Clears the screen and attributes. .IP "\fBvoid tty_free(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void tty_free(tty vt);" Deallocates the \fIvt\fR and all its internal structures. .IP "\fBvoid tty_write(tty \fR\fIvt\fR\fB, const char *\fR\fIbuf\fR\fB, int \fR\fIlen\fR\fB);\fR" 4 .IX Item "void tty_write(tty vt, const char *buf, int len);" Writes \fIlen\fR bytes into the terminal, parsing them as vt100 codes. .IP "\fBvoid tty_printf(tty \fR\fIvt\fR\fB, const char *\fR\fIfmt\fR\fB, \fR\fI...\fR\fB);\fR" 4 .IX Item "void tty_printf(tty vt, const char *fmt, ...);" Does a \fBprintf\fR into the terminal. .IP "\fBtty tty_copy(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "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. .IP "\fBuint32_t tty_color_convert(uint32_t \fR\fIc\fR\fB, uint32_t \fR\fIto\fR\fB);\fR" 4 .IX Item "uint32_t tty_color_convert(uint32_t c, uint32_t to);" Converts color values between modes: \s-1VT100_COLOR_OFF, VT100_COLOR_16, VT100_COLOR_256, VT100_COLOR_RGB.\s0 .SS "Inside the terminal" .IX Subsection "Inside the terminal" You'll most likely be interested in the following fields of the structure: .IP "tty {" 4 .IX Item "tty {" .PD 0 .IP "int \fIsx\fR,\fIsy\fR; // screen size" 4 .IX Item "int sx,sy; // screen size" .IP "int \fIcx\fR,\fIcy\fR; // cursor position" 4 .IX Item "int cx,cy; // cursor position" .IP "attrchar *\fIscr\fR; // screen buffer" 4 .IX Item "attrchar *scr; // screen buffer" .IP "int \fIattr\fR; // current attribute" 4 .IX Item "int attr; // current attribute" .IP "char *\fItitle\fR; // window title" 4 .IX Item "char *title; // window title" .PD .PP \&\fIscr\fR is an array of character/attribute pairs, more exactly, each element is a struct \f(CW\*(C`{ ucs ch; int attr; }\*(C'\fR. The array is a flat one of \fIvt\fR\fB\->\fR\fIsx\fR*\fIvt\fR\fB\->\fR\fIsy\fR elements, arranged row by row. A screen coordinate \fIx\fR,\fIy\fR is stored at \fIx\fR+\fIy\fR*\fIvt\fR\fB\->\fR\fIsy\fR. .PP For other fields, please \s-1RTFS\s0 the header itself: \fBtty.h\fR .SS "\s-1TTY\s0 event callbacks" .IX Subsection "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 \fIevent hooks\fR that you can attach your functions to. .PP These hooks are callbacks inside the \fBtty\fR structure that you can set. The callback fields are: .IP "\fBvoid *l_data;\fR" 4 .IX Item "void *l_data;" it's a place to put your private data in .IP "\fBvoid (*l_char)(tty \fR\fIvt\fR\fB, int \fR\fIx\fR\fB, int \fR\fIy\fR\fB, ucs \fR\fIch\fR\fB, int \fR\fIattr\fR\fB, int \fR\fIwidth\fR\fB);\fR" 4 .IX Item "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 \&\fIwidth\fR which might be 1 (regular) or 2 (\s-1CJK\s0 \*(L"fullwidth\*(R") .IP "\fBvoid (*l_cursor)(tty \fR\fIvt\fR\fB, int \fR\fIx\fR\fB, int \fR\fIy\fR\fB);\fR" 4 .IX Item "void (*l_cursor)(tty vt, int x, int y);" after the cursor has moved .IP "\fBvoid (*l_clear)(tty \fR\fIvt\fR\fB, int \fR\fIx\fR\fB, int \fR\fIy\fR\fB, int \fR\fIlen\fR\fB);\fR" 4 .IX Item "void (*l_clear)(tty vt, int x, int y, int len);" after a chunk of screen has been cleared .Sp If an endpoint spills outside of the current line, it will go all the way to an end of screen. .Sp If the cursor moves, you'll get a separate \fIl_cursor\fR, although it is already in place during the \fIl_clear\fR call. .IP "\fBvoid (*l_scroll)(tty \fR\fIvt\fR\fB, int \fR\fInl\fR\fB);\fR" 4 .IX Item "void (*l_scroll)(tty vt, int nl);" after the region s1<=y backwards, nl>0 \-> forward). .Sp There's no separare \fIl_cursor\fR event, \fIcx\fR and \fIcy\fR are already updated. .IP "\fBvoid (*l_flag)(tty \fR\fIvt\fR\fB, int \fR\fIf\fR\fB, int \fR\fIv\fR\fB);\fR" 4 .IX Item "void (*l_flag)(tty vt, int f, int v);" when a flag changes to \fIv\fR. Flags that are likely to be of interest to you are: .RS 4 .IP "\(bu" 4 \&\fB\s-1VT100_FLAG_CURSOR\s0\fR .Sp cursor visibility .IP "\(bu" 4 \&\fB\s-1VT100_FLAG_KPAD\s0\fR .Sp application keypad mode (more detailed codes for keypad arrow keys) .RE .RS 4 .RE .IP "\fBvoid (*l_osc)(tty \fR\fIvt\fR\fB, int \fR\fIcmd\fR\fB, const char *\fR\fIstr\fR\fB);\fR" 4 .IX Item "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 \fB0\fR: \*(L"set window title\*(R" .IP "\fBvoid (*l_resize)(tty \fR\fIvt\fR\fB, int \fR\fIsx\fR\fB, int \fR\fIsy\fR\fB);\fR" 4 .IX Item "void (*l_resize)(tty vt, int sx, int sy);" after the terminal has been resized .IP "\fBvoid (*l_flush)(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void (*l_flush)(tty vt);" when a write chunk ends .IP "\fBvoid (*l_bell)(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void (*l_bell)(tty vt);" upon a beep .IP "\fBvoid (*l_free)(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void (*l_free)(tty vt);" before the terminal is destroyed .SS "Vt-on-vt redirection" .IX Subsection "Vt-on-vt redirection" For the case when you want the output go to a real terminal, there are: .IP "\fBvoid vtvt_attach(tty \fR\fIvt\fR\fB, \s-1FILE\s0 *\fR\fIf\fR\fB, int \fR\fIdump\fR\fB);\fR" 4 .IX Item "void vtvt_attach(tty vt, FILE *f, int dump);" Attaches the \s-1FILE\s0 stream \fIf\fR to terminal \fIvt\fR. Usually, \fIf\fR will be \fBstdout\fR. Whenever the contents of \fIvt\fR changes, appropriate data will be written to the stream as well. If \fIdump\fR is non-zero, the current state will be drawn, otherwise, only subsequent changes will be shown. .Sp The redirection will last until the terminal is destroyed by \fB\fBtty_free()\fB\fR. .IP "\fBvoid vtvt_resize(tty \fR\fIvt\fR\fB, int \fR\fIsx\fR\fB, int \fR\fIsy\fR\fB);\fR" 4 .IX Item "void vtvt_resize(tty vt, int sx, int sy);" Tells libtty that the \fBreal\fR terminal has been resized (for resizing the virtual one, please use \fB\fBtty_resize()\fB\fR). .IP "\fBvoid vtvt_dump(tty \fR\fIvt\fR\fB);\fR" 4 .IX Item "void vtvt_dump(tty vt);" Forces a full-screen redraw of the current contents of \fIvt\fR. .SH "SEE ALSO" .IX Header "SEE ALSO" \&\fBlibttyrec\fR\|(3)