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");