19MALLOC_DEFINE(M_VT_SCREEN,
"vt-screen",
"virtual terminal screen");
40 ' ', 0x04, 0xB1, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8,
41 0xF1, 0xB0, 0x0F, 0xD9, 0xBF, 0xDA, 0xC0, 0xC5,
42 0xC4, 0xC4, 0xC4, 0xC4, 0xC4, 0xC3, 0xB4, 0xC1,
43 0xC2, 0xB3, 0xF3, 0xF2, 0xE3,
'!', 0x9C, 0xFA,
48 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
49 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
50 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
51 0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
52 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
53 0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
54 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
55 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
56 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
57 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
58 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
59 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
60 0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
61 0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
62 0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
63 0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0,
68 0x2302, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
69 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
70 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
71 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
77 {0x256D, 0xDA}, {0x256E, 0xBF}, {0x256F, 0xD9}, {0x2570, 0xC0},
78 {0x2018,
'\''}, {0x2019,
'\''}, {0x201C,
'"'}, {0x201D,
'"'},
79 {0x2010,
'-'}, {0x2013,
'-'}, {0x2014,
'-'}, {0x2212,
'-'},
80 {0x2026, 0xFA}, {0x00B4,
'\''}, {0x00D7,
'x'},
89 for (
int i = 0; i < 128; ++i)
93 for (
int i = 0; i < 32; ++i)
108 int ri = r < 48 ? 0 : r < 115 ? 1 : (r - 35) / 40;
109 int gi = g < 48 ? 0 : g < 115 ? 1 : (g - 35) / 40;
110 int bi = b < 48 ? 0 : b < 115 ? 1 : (b - 35) / 40;
112 if (ri == gi && gi == bi) {
113 int gray = (r + g + b) / 3;
115 if (gray > 8 && gray < 238)
116 return 232 + (gray - 8) / 10;
119 return 16 + 36 * ri + 6 * gi + bi;
136static void erase(
struct vt *
vt,
int row,
int from,
int to)
140 for (
int col = from; col < to; ++col)
148 if (n > bottom - top + 1)
149 n = bottom - top + 1;
154 for (
int row = bottom - n + 1; row <= bottom; ++row)
162 if (n > bottom - top + 1)
163 n = bottom - top + 1;
168 for (
int row = top; row < top + n; ++row)
179 vt->
row = row < min ? min : row > max ? max : row;
188 int row =
vt->
row + n;
190 if (n < 0 && vt->row >=
vt->
top && row < vt->top)
195 row = row < 0 ? 0 : row >=
vt->
rows ?
vt->
rows - 1 : row;
217 else if (
vt->
row > 0)
226 return col < 256 && (
vt->
tabs[col / 8] & (1 << (col % 8)));
236 vt->
tabs[col / 8] |= 1 << (col % 8);
238 vt->
tabs[col / 8] &= ~(1 << (col % 8));
250 while (n < 0 && vt->col > 0) {
287 if (u >= 0x5f && u <= 0x7e) {
309 size_t len = strlen(s);
349 for (
int row = 0; row <
vt->
rows; ++row)
401 for (
int col = 0; col < 256; ++col)
422 size_t size = rows * cols *
sizeof(
struct vt_cell);
506 if (p >= 30 && p <= 37)
508 else if (p >= 40 && p <= 47)
510 else if (p >= 90 && p <= 97)
511 pen->
fg = p - 90 + 8;
512 else if (p >= 100 && p <= 107)
513 pen->
bg = p - 100 + 8;
571 if (f ==
'h' || f ==
'l')
603 case 'I':
tab(
vt, n);
break;
604 case 'Z':
tab(
vt, -n);
break;
609 for (
int row =
vt->
row + 1; row < vt->rows; ++row)
613 for (
int row = 0; row <
vt->
row; ++row)
672 for (
int col = 0; col < 256; ++col)
690 }
else if (
param(
vt, 0, 0) == 6) {
691 snprintf(buf,
sizeof(buf),
"\033[%d;%dR",
761 case 'Z':
reply(
vt,
"\033[?6c");
break;
814 }
else if ((c & 0xc0) == 0x80) {
829 if ((c & 0xe0) == 0xc0) {
832 }
else if ((c & 0xf0) == 0xe0) {
835 }
else if ((c & 0xf8) == 0xf0) {
848 return c >=
'0' && c <=
'9' ? c -
'0' :
849 c >=
'a' && c <=
'f' ? c -
'a' + 10 :
850 c >=
'A' && c <=
'F' ? c -
'A' + 10 : -1;
873 if (c == 0x07 || c == 0x18 || c == 0x1a)
918 for (
int row = 0; row <
vt->
rows; ++row)
919 for (
int col = 0; col <
vt->
cols; ++col)
930 if (c >=
'0' && c <=
'9') {
933 *p = *p * 10 + c -
'0';
934 }
else if (c ==
';' || c ==
':') {
937 }
else if (c >= 0x3c && c <= 0x3f) {
939 }
else if (c >= 0x20 && c <= 0x2f) {
943 if (c >= 0x40 && c <= 0x7e)
959 for (
size_t i = 0; i < size; ++i)
#define MALLOC_DEFINE(type, _name, _desc)
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memmove(void *dst, const void *src, size_t n)
Copies n bytes; dst and src may overlap.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int snprintf(char *s, size_t n, const char *fmt,...)
Formats a string into a buffer.
unsigned short int uint16_t
The cursor's state, saved by DECSC.
A virtual terminal: its screen, its emulator's state, and its tty.
struct vt_cursor saved saved_alt
static void put_char(struct vt *vt, uint32_t u)
Puts a character at the cursor, through the character set in use.
static void linefeed(struct vt *vt)
Moves the cursor down a row, scrolling at the region's bottom.
static uint8_t rgb_color(int r, int g, int b)
Returns the closest colour of the palette's 6 x 6 x 6 cube or greys, for a 24-bit colour.
static void tab_set(struct vt *vt, int col, int set)
Sets or clears the tab stop at a column.
static const uint8_t dec_graphics[]
static const uint16_t cp437[128]
static void reverse_index(struct vt *vt)
Moves the cursor up a row, scrolling at the region's top.
static void put_glyph(struct vt *vt, uint8_t ch)
Puts a glyph at the cursor, in the current colours and attributes, and moves the cursor on,...
static void erase(struct vt *vt, int row, int from, int to)
Erases the cells of a row from column from up to to.
static void csi(struct vt *vt, char f)
Runs a CSI sequence whose final character is f, with its parameters.
static void sgr(struct vt *vt)
Sets the pen's colours and attributes (SGR, CSI ... m).
static void soft_reset(struct vt *vt)
Sets the modes and the pen back to the defaults, but not the screen (DECSTR, a soft reset).
static void decset(struct vt *vt, int set)
Sets or resets DEC private modes.
static const uint16_t cp437_symbols[32]
static void term_char(struct vt *vt, uint8_t c)
Takes one byte of what programs write, in the state of the sequence it may be in.
void vt_term_write(struct vt *vt, const char *buf, size_t size)
Takes what programs write to a terminal, and changes its screen.
static const struct @306303231117275265135041376256327001361236134117 unicode_extra[]
static int tab_stop(struct vt *vt, int col)
Returns whether there is a tab stop at a column.
static void alt_screen(struct vt *vt, int on)
Shows the alternate screen (xterm's), cleared, or the main one again.
void vt_term_reset(struct vt *vt)
Resets a terminal (RIS, ESC c): the defaults, the tab stops every 8 columns, the main screen cleared,...
static void esc(struct vt *vt, char c)
Runs an escape sequence, ESC c, or starts a longer one.
static void move_to(struct vt *vt, int row, int col)
Moves the cursor, within the screen, or within the scrolling region in origin mode.
static struct vt_cell * cell(struct vt *vt, int row, int col)
Returns a cell of the screen.
static void scroll_down(struct vt *vt, int top, int bottom, int n)
Scrolls rows top to bottom down by n rows: n erased rows come at the top.
static void utf8(struct vt *vt, uint8_t c)
Decodes UTF-8, a byte at a time, and puts each character.
static void control(struct vt *vt, char c)
Runs a control character.
static void save_cursor(struct vt *vt, struct vt_cursor *save)
Saves the cursor: its position, colours, character sets and modes.
int vt_term_init(struct vt *vt, int rows, int cols)
Sets a terminal's screens up, the main one and the alternate one, both cleared, and resets it.
static struct vt_cell blank(struct vt *vt)
Returns an erased cell: it takes the current colours, as the Linux console does ("bce").
static void clear_screen(struct vt *vt)
Erases the whole screen.
static void move_rows(struct vt *vt, int n)
Moves the cursor up or down n rows.
static int param(struct vt *vt, int i, int def)
Returns a sequence's parameter i, or def if it is 0 or missing.
static void reply(struct vt *vt, const char *s)
Queues a reply to a request (DSR, DA), which vt.c gives the terminal as input.
static void scroll_up(struct vt *vt, int top, int bottom, int n)
Scrolls rows top to bottom up by n rows: n erased rows come at the bottom.
static void tab(struct vt *vt, int n)
Moves the cursor n tab stops forward, or back if n is negative.
static void restore_cursor(struct vt *vt, struct vt_cursor *save)
Restores a saved cursor, within the screen.
static uint8_t unicode_glyph(uint32_t u)
Returns the code page 437 glyph that shows a character best, or '?
static int hexdigit(char c)
Returns a hex digit's value, or -1.