[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;
}
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);
size_t 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);
}
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));
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) {
tty->pr = 0;
tty->fg = DEFAULT_FG;
@ -272,7 +293,7 @@ void _TtyFullReset(struct Tty *tty) {
_TtyResetOutputMode(tty);
tty->y = 0;
tty->x = 0;
_TtyErase(tty, 0, Yn(tty) * Xn(tty));
_TtyEraseLines(tty, 0, Yn(tty));
}
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) {
_TtyMemmove(tty, 0, Xn(tty), Xn(tty) * (Yn(tty) - 1));
_TtyErase(tty, Xn(tty) * (Yn(tty) - 1), Xn(tty));
_TtyMoveLines(tty, 0, 1, Yn(tty) - 1);
_TtyEraseLines(tty, Yn(tty) - 1, 1);
}
static void TtyReverse(struct Tty *tty) {
_TtyMemmove(tty, Xn(tty), 0, Xn(tty) * (Yn(tty) - 1));
_TtyErase(tty, 0, Xn(tty));
_TtyMoveLines(tty, 1, 0, Yn(tty) - 1);
_TtyEraseLines(tty, 0, 1);
}
static void TtyIndex(struct Tty *tty) {
@ -464,15 +485,16 @@ static void TtyRestoreCursorPosition(struct Tty *tty) {
static void TtyEraseDisplay(struct Tty *tty) {
switch (TtyAtoi(tty->esc.s, NULL)) {
case 0:
_TtyErase(tty, tty->y * Xn(tty) + tty->x,
Yn(tty) * Xn(tty) - (tty->y * Xn(tty) + tty->x));
_TtyEraseLineCells(tty, tty->y, tty->x, Xn(tty) - tty->x);
_TtyEraseLines(tty, tty->y + 1, Yn(tty) - tty->y - 1);
break;
case 1:
_TtyErase(tty, 0, tty->y * Xn(tty) + tty->x);
_TtyEraseLines(tty, 0, tty->y);
_TtyEraseLineCells(tty, tty->y, 0, tty->x);
break;
case 2:
case 3:
_TtyErase(tty, 0, Yn(tty) * Xn(tty));
_TtyEraseLines(tty, 0, Yn(tty));
break;
default:
break;
@ -482,13 +504,13 @@ static void TtyEraseDisplay(struct Tty *tty) {
static void TtyEraseLine(struct Tty *tty) {
switch (TtyAtoi(tty->esc.s, NULL)) {
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;
case 1:
_TtyErase(tty, tty->y * Xn(tty), tty->x);
_TtyEraseLineCells(tty, tty->y, 0, tty->x);
break;
case 2:
_TtyErase(tty, tty->y * Xn(tty), Xn(tty));
_TtyEraseLines(tty, tty->y, 1);
break;
default:
break;
@ -496,11 +518,23 @@ static void TtyEraseLine(struct Tty *tty) {
}
static void TtyEraseCells(struct Tty *tty) {
int i, n, x;
i = tty->y * Xn(tty) + tty->x;
n = Yn(tty) * Xn(tty);
x = min(max(TtyAtoi(tty->esc.s, NULL), 1), n - i);
_TtyErase(tty, i, x);
int yn, xn, yi, xi, n, left;
yn = Yn(tty);
xn = Xn(tty);
yi = tty->y;
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) {
@ -509,30 +543,28 @@ static int TtyArg1(struct Tty *tty) {
static void TtyInsertCells(struct Tty *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));
_TtyErase(tty, tty->y * Xn(tty) + tty->x, n);
_TtyEraseLineCells(tty, tty->y, tty->x, n);
}
static void TtyInsertLines(struct Tty *tty) {
int n = min(Yn(tty) - tty->y, TtyArg1(tty));
_TtyMemmove(tty, (tty->y + n) * Xn(tty), tty->y * Xn(tty),
(Yn(tty) - tty->y - n) * Xn(tty));
_TtyErase(tty, tty->y * Xn(tty), n * Xn(tty));
_TtyMoveLines(tty, tty->y + n, tty->y, Yn(tty) - tty->y - n);
_TtyEraseLines(tty, tty->y, n);
}
static void TtyDeleteCells(struct Tty *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));
_TtyErase(tty, tty->y * Xn(tty) + tty->x, n);
_TtyEraseLineCells(tty, tty->y, tty->x, n);
}
static void TtyDeleteLines(struct Tty *tty) {
int n = min(Yn(tty) - tty->y, TtyArg1(tty));
_TtyMemmove(tty, tty->y * Xn(tty), (tty->y + n) * Xn(tty),
(Yn(tty) - tty->y - n) * Xn(tty));
_TtyErase(tty, (tty->y + n) * Xn(tty), n * Xn(tty));
_TtyMoveLines(tty, tty->y, tty->y + n, Yn(tty) - tty->y - n);
_TtyEraseLines(tty, tty->y + n, n);
}
static void TtyReportDeviceStatus(struct Tty *tty) {

View file

@ -112,8 +112,22 @@ struct VgaTextCharCell {
};
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;
/** Height and width of terminal, in character units. */
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 n8;
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);
void _TtyResetOutputMode(struct Tty *);
void _TtyFullReset(struct Tty *);
void _TtyMemmove(struct Tty *, size_t, size_t, size_t);
void _TtyErase(struct Tty *, size_t, size_t);
void _TtyMoveLineCells(struct Tty *, size_t, size_t, size_t, 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 _TtySetX(struct Tty *, unsigned short);

View file

@ -32,12 +32,6 @@
#include "libc/runtime/pc.internal.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;
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);
#endif
/*
* Initialize our tty structure from the current screen contents,
* current cursor position, & character height.
* Initialize our tty structure from the current screen geometry,
* screen contents, cursor position, & character height.
*/
_StartTty(&_vga_tty, height, width, pos.row, pos.col, chr_ht,
vid_buf, vga_wcs);
vid_buf, NULL);
}
}