User:Joeeagar/TerminalEmulation
Unix text terminals do a number of things: move the cursor around, format text, change colors, clear the screen, etc. There's a special command language for controlling all of this, originally based on the VT100 series of physical terminals (but over the years a bunch of stuff was added, and now it's a huge mess).
This tutorial covers emulating a (subset of) xterm's command language. Xterm is something of a de facto standard, so it seemed like a good place to start.
How terminals work
Terminals control how Unix users interact with applications. A Unix terminal will handle keyboard input, render formatted/colored text, and send signals to host applications when the user presses special control codes, e.g. CTRL-C to abort an application.
Terminals can be implemented in the kernel (linuxconsole) or outside of it (xterm/rxvt and derivatives). Terminals provide stdin, and are fed stdout.
Command Reference
Basic Info on Commands
Commands typically start with the ESC key (ascii 27). They can include a number of arguments, which are drawn with grey color, and take the form name = $type=default. For example, ch=$c=1 has type c and defaults to '1' (in this case the character '1').
Note that if an argument has a default value, it can be omitted. Also, control sequences don't have spaces in them.
Types
- $c : any printable characters (be careful of numerals)
- $[...] : any character in set
- $d : ascii-encoded base-10 integer
- $i : raw binary integer (0-255)
Basic Commands
Terminfo Code | Escape Sequence | Description | Notes |
---|---|---|---|
cup | ESC [ y=$d ; x=$d H | Set cursor position | origin is at (1, 1), not (0, 0). |
cub | ESC [ i=$d=1 A | Move cursor up i steps | |
cud | ESC [ i=$d=1 B | Move cursor down i steps | |
cuf | ESC [ i=$d=1 C | Move cursor right i steps | |
cub | ESC [ i=$d=1 D | Move cursor left i steps | |
clear | ESC [ 2 J | Erase entire screen | |
home | ESC [ H | Move cursor to home position. | |
dch | ESC [ i=$d=1 P | Delete i preceding characters | |
decsc | ESC 7 | Save cursor | |
decrc | ESC 8 | Restore cursor | |
setaf | ESC [ 3 color=$d=1 m | Set foreground color to a valid SGR color. | This forms an SGR code. |
smcup | ESC ? 1 ; 0 ; 4 ; 7 h | Use alternative screen buffer. | Full-screen text apps use this to avoid messing up the scroll buffer. |
rmcup | ESC ? 1 ; 0 ; 4 ; 9 l | Switch back to normal screen buffer. | |
??? | ESC ? 1 ; 0 ; 4 ; 7 l | Switch back to normal screen buffer, then clear the screen. | |
??? | ESC ? 1 ; 0 ; 4 ; 9 h | Save cursor as in decsc, switch to alternate screen buffer, clearing it first. |
Mouse Tracking (xterm)
Source: [[1]]
Xterm supports a number of mouse modes. For this tutorial we'll focus on the X11 xterm's "normal", "cell" and "any" modes. "Normal" mode only button press/release events, while "any" sends both button press/release and motion events. "Cell" mode only sends events if the mouse has moved to another character cell.
Code | Description | Notes |
---|---|---|
ESC [ 1 ; 0 ; 0 ; 0 h | Normal mouse mode | Does not send motion events. |
ESC [ 1 ; 0 ; 0 ; 1 h | Cell mouse mode | Does not send motion events. Only sends events when mouse cursor enters a different text cell. |
ESC [ 1 ; 0 ; 0 ; 2 h | Any mouse mode | Sends mouse motion events as well as button press/release. |
ESC [ 1 ; 0 ; 0 ; 2 h | Send mouse focus events. |
Code | Description | Notes |
---|---|---|
ESC M d=$i x=$i y=$i | d is an information bitmask. x and y are coordinates | |
ESC [ I | Got mouse focus | |
ESC [ O | Lost mouse focus | The letter O, not zero |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
Button 1 pressed (or 3 if bit 6 is set) | Button 2 pressed (or 4 if bit 6 is set). If previous bit is set, interpret this as a button release event (apparently with no info on which button was released?). | Shift modifier key | Meta/Alt modifier key | Control modifier key |
SGR Codes
SGR codes are used for formatting text. An SGR code has the form:
ESC [ mode=$d m
mode is a special code specifying either text attributes (e.g. bold) or colors.
Code | Description | Notes |
---|---|---|
0 | Reset to default | |
1 | Light color mode | |
2 | Faint/dark color mode | Not widely supported (according to wikipedia) |
3 | Italic: on | |
4 | Underline single | |
5 | Slow Blink | Not widely supported (according to wikipedia) |
6 | Fast Blink | Not widely supported (according to wikipedia) |
7 | Swap foreground and background colors | |
8 | Conceal. Temporarily sets foreground color to background color. | Not widely supported (according to wikipedia) |
9 | Striketru | |
10 | Set default font | |
11-19 | Choose font | |
20 | Fraktur | Does anything support this? Seems like an odd option to have. |
22 | Normal color, bold off | |
23 | Turn off italic and Fraktur | |
24 | Turn off underline | |
25 | Turn off blink | |
26 | Reserved | |
27 | Unswap foreground and background colors | |
28 | Turn off conceal | |
29 | Turn off strikethru | |
30-37 | Foreground color | |
38 | Terminal-specific custom foreground code | |
39 | Default foreground color | |
40-47 | Background color | |
48 | Terminal-specific custom background code | |
49 | Default background color | |
50 | Reserved | |
51 | Framed | |
52 | Encircled | |
53 | Overlined | |
54 | Turn off frame/encircled | |
55 | Turn off overline |
SGR Colors
Number | Default Mode | Light Mode | Name |
---|---|---|---|
0 | black | ||
1 | red | ||
2 | green | ||
3 | yellow | ||
4 | blue | ||
5 | magenta | ||
6 | cyan | ||
7 | white |
The stty command
Terminal modes can be controlled with the stty utility (as well as a rather annoying POSIX API). You can invoke stty from C code with the system command. For example, to turn off echo and line mode, you could do this:
system("stty raw -echo");
To turn echo and line mode back on:
system("stty -raw echo");