[metal] Start refactoring VGA console code, for graphics modes

This commit is contained in:
tkchia 2022-10-01 08:32:21 +00:00
parent f8eb68a3b8
commit d278e327b8
3 changed files with 84 additions and 42 deletions

View file

@ -240,7 +240,7 @@ static uint8_t TtyGetVgaAttr(struct Tty *tty) {
return attr; return attr;
} }
void _TtyErase(struct Tty *tty, size_t dst, size_t n) { static void TtyErase(struct Tty *tty, size_t dst, size_t n) {
uint8_t attr = TtyGetVgaAttr(tty); uint8_t attr = TtyGetVgaAttr(tty);
size_t i; size_t i;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
@ -248,11 +248,32 @@ void _TtyErase(struct Tty *tty, size_t dst, size_t n) {
if (Wcs(tty)) wmemset(Wcs(tty) + dst, L' ', n); if (Wcs(tty)) wmemset(Wcs(tty) + dst, L' ', n);
} }
void _TtyMemmove(struct Tty *tty, size_t dst, size_t src, size_t n) { void _TtyEraseLineCells(struct Tty *tty, size_t dsty, size_t dstx, size_t n) {
size_t xn = Xn(tty);
TtyErase(tty, dsty * xn + dstx, n);
}
void _TtyEraseLines(struct Tty *tty, size_t dsty, size_t n) {
size_t xn = Xn(tty);
TtyErase(tty, dsty * xn, n * xn);
}
static void TtyMemmove(struct Tty *tty, size_t dst, size_t src, size_t n) {
memmove(tty->ccs + dst, tty->ccs + src, n * sizeof(struct VgaTextCharCell)); memmove(tty->ccs + dst, tty->ccs + src, n * sizeof(struct VgaTextCharCell));
if (Wcs(tty)) wmemmove(Wcs(tty) + dst, Wcs(tty) + src, n); if (Wcs(tty)) wmemmove(Wcs(tty) + dst, Wcs(tty) + src, n);
} }
void _TtyMoveLineCells(struct Tty *tty, size_t dsty, size_t dstx,
size_t srcy, size_t srcx, size_t n) {
size_t xn = Xn(tty);
TtyMemmove(tty, dsty * xn + dstx, srcy * xn + srcx, n);
}
void _TtyMoveLines(struct Tty *tty, size_t dsty, size_t srcy, size_t n) {
size_t xn = Xn(tty);
TtyMemmove(tty, dsty * xn, srcy * xn, n * xn);
}
void _TtyResetOutputMode(struct Tty *tty) { void _TtyResetOutputMode(struct Tty *tty) {
tty->pr = 0; tty->pr = 0;
tty->fg = DEFAULT_FG; tty->fg = DEFAULT_FG;
@ -272,7 +293,7 @@ void _TtyFullReset(struct Tty *tty) {
_TtyResetOutputMode(tty); _TtyResetOutputMode(tty);
tty->y = 0; tty->y = 0;
tty->x = 0; tty->x = 0;
_TtyErase(tty, 0, Yn(tty) * Xn(tty)); _TtyEraseLines(tty, 0, Yn(tty));
} }
void _TtySetY(struct Tty *tty, unsigned short y) { void _TtySetY(struct Tty *tty, unsigned short y) {
@ -286,13 +307,13 @@ void _TtySetX(struct Tty *tty, unsigned short x) {
} }
static void TtyScroll(struct Tty *tty) { static void TtyScroll(struct Tty *tty) {
_TtyMemmove(tty, 0, Xn(tty), Xn(tty) * (Yn(tty) - 1)); _TtyMoveLines(tty, 0, 1, Yn(tty) - 1);
_TtyErase(tty, Xn(tty) * (Yn(tty) - 1), Xn(tty)); _TtyEraseLines(tty, Yn(tty) - 1, 1);
} }
static void TtyReverse(struct Tty *tty) { static void TtyReverse(struct Tty *tty) {
_TtyMemmove(tty, Xn(tty), 0, Xn(tty) * (Yn(tty) - 1)); _TtyMoveLines(tty, 1, 0, Yn(tty) - 1);
_TtyErase(tty, 0, Xn(tty)); _TtyEraseLines(tty, 0, 1);
} }
static void TtyIndex(struct Tty *tty) { static void TtyIndex(struct Tty *tty) {
@ -464,15 +485,16 @@ static void TtyRestoreCursorPosition(struct Tty *tty) {
static void TtyEraseDisplay(struct Tty *tty) { static void TtyEraseDisplay(struct Tty *tty) {
switch (TtyAtoi(tty->esc.s, NULL)) { switch (TtyAtoi(tty->esc.s, NULL)) {
case 0: case 0:
_TtyErase(tty, tty->y * Xn(tty) + tty->x, _TtyEraseLineCells(tty, tty->y, tty->x, Xn(tty) - tty->x);
Yn(tty) * Xn(tty) - (tty->y * Xn(tty) + tty->x)); _TtyEraseLines(tty, tty->y + 1, Yn(tty) - tty->y - 1);
break; break;
case 1: case 1:
_TtyErase(tty, 0, tty->y * Xn(tty) + tty->x); _TtyEraseLines(tty, 0, tty->y);
_TtyEraseLineCells(tty, tty->y, 0, tty->x);
break; break;
case 2: case 2:
case 3: case 3:
_TtyErase(tty, 0, Yn(tty) * Xn(tty)); _TtyEraseLines(tty, 0, Yn(tty));
break; break;
default: default:
break; break;
@ -482,13 +504,13 @@ static void TtyEraseDisplay(struct Tty *tty) {
static void TtyEraseLine(struct Tty *tty) { static void TtyEraseLine(struct Tty *tty) {
switch (TtyAtoi(tty->esc.s, NULL)) { switch (TtyAtoi(tty->esc.s, NULL)) {
case 0: case 0:
_TtyErase(tty, tty->y * Xn(tty) + tty->x, Xn(tty) - tty->x); _TtyEraseLineCells(tty, tty->y, tty->x, Xn(tty) - tty->x);
break; break;
case 1: case 1:
_TtyErase(tty, tty->y * Xn(tty), tty->x); _TtyEraseLineCells(tty, tty->y, 0, tty->x);
break; break;
case 2: case 2:
_TtyErase(tty, tty->y * Xn(tty), Xn(tty)); _TtyEraseLines(tty, tty->y, 1);
break; break;
default: default:
break; break;
@ -496,11 +518,23 @@ static void TtyEraseLine(struct Tty *tty) {
} }
static void TtyEraseCells(struct Tty *tty) { static void TtyEraseCells(struct Tty *tty) {
int i, n, x; int yn, xn, yi, xi, n, left;
i = tty->y * Xn(tty) + tty->x; yn = Yn(tty);
n = Yn(tty) * Xn(tty); xn = Xn(tty);
x = min(max(TtyAtoi(tty->esc.s, NULL), 1), n - i); yi = tty->y;
_TtyErase(tty, i, x); xi = tty->x;
left = min(max(TtyAtoi(tty->esc.s, NULL), 1), yn * xn - (yi * xn + xi));
while (left) {
if (left >= xn - xi) {
_TtyEraseLineCells(tty, yi, xi, xn - xi);
left -= xn - xi;
++yi;
xi = 0;
} else {
_TtyEraseLineCells(tty, yi, xi, left);
left = 0;
}
}
} }
static int TtyArg1(struct Tty *tty) { static int TtyArg1(struct Tty *tty) {
@ -509,30 +543,28 @@ static int TtyArg1(struct Tty *tty) {
static void TtyInsertCells(struct Tty *tty) { static void TtyInsertCells(struct Tty *tty) {
int n = min(Xn(tty) - tty->x, TtyArg1(tty)); int n = min(Xn(tty) - tty->x, TtyArg1(tty));
_TtyMemmove(tty, tty->y * Xn(tty) + tty->x + n, tty->y * Xn(tty) + tty->x, _TtyMoveLineCells(tty, tty->y, tty->x + n, tty->y, tty->x,
Xn(tty) - (tty->x + n)); Xn(tty) - (tty->x + n));
_TtyErase(tty, tty->y * Xn(tty) + tty->x, n); _TtyEraseLineCells(tty, tty->y, tty->x, n);
} }
static void TtyInsertLines(struct Tty *tty) { static void TtyInsertLines(struct Tty *tty) {
int n = min(Yn(tty) - tty->y, TtyArg1(tty)); int n = min(Yn(tty) - tty->y, TtyArg1(tty));
_TtyMemmove(tty, (tty->y + n) * Xn(tty), tty->y * Xn(tty), _TtyMoveLines(tty, tty->y + n, tty->y, Yn(tty) - tty->y - n);
(Yn(tty) - tty->y - n) * Xn(tty)); _TtyEraseLines(tty, tty->y, n);
_TtyErase(tty, tty->y * Xn(tty), n * Xn(tty));
} }
static void TtyDeleteCells(struct Tty *tty) { static void TtyDeleteCells(struct Tty *tty) {
int n = min(Xn(tty) - tty->x, TtyArg1(tty)); int n = min(Xn(tty) - tty->x, TtyArg1(tty));
_TtyMemmove(tty, tty->y * Xn(tty) + tty->x, tty->y * Xn(tty) + tty->x + n, _TtyMoveLineCells(tty, tty->y, tty->x, tty->y, tty->x + n,
Xn(tty) - (tty->x + n)); Xn(tty) - (tty->x + n));
_TtyErase(tty, tty->y * Xn(tty) + tty->x, n); _TtyEraseLineCells(tty, tty->y, tty->x, n);
} }
static void TtyDeleteLines(struct Tty *tty) { static void TtyDeleteLines(struct Tty *tty) {
int n = min(Yn(tty) - tty->y, TtyArg1(tty)); int n = min(Yn(tty) - tty->y, TtyArg1(tty));
_TtyMemmove(tty, tty->y * Xn(tty), (tty->y + n) * Xn(tty), _TtyMoveLines(tty, tty->y, tty->y + n, Yn(tty) - tty->y - n);
(Yn(tty) - tty->y - n) * Xn(tty)); _TtyEraseLines(tty, tty->y + n, n);
_TtyErase(tty, (tty->y + n) * Xn(tty), n * Xn(tty));
} }
static void TtyReportDeviceStatus(struct Tty *tty) { static void TtyReportDeviceStatus(struct Tty *tty) {

View file

@ -112,8 +112,22 @@ struct VgaTextCharCell {
}; };
struct Tty { struct Tty {
/**
* Cursor position. (y, x) = (0, 0) means the cursor is on the top left
* character cell of the terminal.
*/
unsigned short y, x; unsigned short y, x;
/** Height and width of terminal, in character units. */
unsigned short yn, xn; unsigned short yn, xn;
/** Height and width of terminal, in pixels (if in graphics video mode). */
unsigned short yp, xp;
/**
* Number of bytes (NOTE) occupied by each row of pixels, including any
* invisible "pixels".
*/
unsigned short xs;
/** Type of video buffer (from mman::pc_video_type). */
unsigned char type;
uint32_t u8; uint32_t u8;
uint32_t n8; uint32_t n8;
uint32_t pr; uint32_t pr;
@ -149,8 +163,10 @@ ssize_t _TtyWrite(struct Tty *, const void *, size_t);
ssize_t _TtyWriteInput(struct Tty *, const void *, size_t); ssize_t _TtyWriteInput(struct Tty *, const void *, size_t);
void _TtyResetOutputMode(struct Tty *); void _TtyResetOutputMode(struct Tty *);
void _TtyFullReset(struct Tty *); void _TtyFullReset(struct Tty *);
void _TtyMemmove(struct Tty *, size_t, size_t, size_t); void _TtyMoveLineCells(struct Tty *, size_t, size_t, size_t, size_t, size_t);
void _TtyErase(struct Tty *, size_t, size_t); void _TtyMoveLines(struct Tty *, size_t, size_t, size_t);
void _TtyEraseLineCells(struct Tty *, size_t, size_t, size_t);
void _TtyEraseLines(struct Tty *, size_t, size_t);
void _TtySetY(struct Tty *, unsigned short); void _TtySetY(struct Tty *, unsigned short);
void _TtySetX(struct Tty *, unsigned short); void _TtySetX(struct Tty *, unsigned short);

View file

@ -32,12 +32,6 @@
#include "libc/runtime/pc.internal.h" #include "libc/runtime/pc.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#ifdef VGA_USE_WCS
static wchar_t vga_wcs[VGA_TTY_HEIGHT * VGA_TTY_WIDTH];
#else
static wchar_t * const vga_wcs = NULL;
#endif
struct Tty _vga_tty; struct Tty _vga_tty;
ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) { ssize_t sys_writev_vga(struct Fd *fd, const struct iovec *iov, int iovlen) {
@ -266,10 +260,10 @@ __attribute__((__constructor__)) static textstartup void _vga_init(void) {
_vga_init_test(vid_buf, vid_type, stride); _vga_init_test(vid_buf, vid_type, stride);
#endif #endif
/* /*
* Initialize our tty structure from the current screen contents, * Initialize our tty structure from the current screen geometry,
* current cursor position, & character height. * screen contents, cursor position, & character height.
*/ */
_StartTty(&_vga_tty, height, width, pos.row, pos.col, chr_ht, _StartTty(&_vga_tty, height, width, pos.row, pos.col, chr_ht,
vid_buf, vga_wcs); vid_buf, NULL);
} }
} }