diff --git a/tty/pc-tty/ttypc.c b/tty/pc-tty/ttypc.c index bb17d7a5..94b16305 100644 --- a/tty/pc-tty/ttypc.c +++ b/tty/pc-tty/ttypc.c @@ -133,22 +133,34 @@ int main(void) if ((err = mutexCreate(&ttypc_common.lock)) < 0) return err; + /* Initialize VGA display */ + if ((err = ttypc_vga_init(&ttypc_common)) < 0) + return err; + /* Initialize VTs */ for (i = 0; i < NVTS; i++) { - if ((err = ttypc_vt_init(&ttypc_common, _PAGE_SIZE, ttypc_common.vts + i)) < 0) + if ((err = ttypc_vt_init(&ttypc_common, ttypc_common.memsz, ttypc_common.vts + i)) < 0) return err; } - /* Initialize VGA display */ - if ((err = ttypc_vga_init(&ttypc_common)) < 0) - return err; - /* Set active virtual terminal */ ttypc_common.vt = ttypc_common.vts; ttypc_common.vt->vram = ttypc_common.vga; + if (ttypc_common.vt->fbmode == TTY_FBCON_ENABLED) { + /* Resize active virtual terminal to match fbcon maximum resolution */ + ttypc_vt_resize(ttypc_common.vt, ttypc_common.fbmaxcols, ttypc_common.fbmaxrows); + } + /* Initialize cursor */ - _ttypc_vga_getcursor(ttypc_common.vt); + if (ttypc_common.vt->fbmode == TTY_FBCON_DISABLED) { + /* If fbcon is not available, retrieve the cursor so we don't overwrite the tty as + * some earlier component might have written something to the text mode buffer (i.e. plo) */ + _ttypc_vga_getcursor(ttypc_common.vt); + } + /* else: In case of fbcon, we don't care about the text mode buffer, because we're + * in the graphic mode already and the text mode buffer may contain garbage */ + /* Set default cursor color */ _ttypc_vga_set(ttypc_common.vt, ttypc_common.vt->vram + ttypc_common.vt->cpos, FG_LIGHTGREY << 8, ttypc_common.vt->rows * ttypc_common.vt->cols - ttypc_common.vt->cpos); diff --git a/tty/pc-tty/ttypc.h b/tty/pc-tty/ttypc.h index f3bf74d5..9313f1a9 100644 --- a/tty/pc-tty/ttypc.h +++ b/tty/pc-tty/ttypc.h @@ -50,6 +50,7 @@ struct _ttypc_t { /* VGA */ volatile void *vga; /* VGA screen memory */ + uint32_t memsz; /* VGA screen memory size */ void *crtc; /* Video Display Controller (CRTC) */ unsigned color; /* Color support */ @@ -77,8 +78,8 @@ struct _ttypc_t { /* Framebuffer console */ uint16_t fbw; /* Width in pixels */ uint16_t fbh; /* Height in pixels */ - int16_t fbcols; /* Console columns count */ - int16_t fbrows; /* Console rows count */ + int16_t fbmaxcols; /* Maximum console columns count */ + int16_t fbmaxrows; /* Maximum console rows count */ uint16_t fbbpp; /* Bits per pixel */ uint16_t fbpitch; /* Pitch (framebuffer line length)*/ volatile void *fbaddr; /* Framebuffer address */ diff --git a/tty/pc-tty/ttypc_fbcon.c b/tty/pc-tty/ttypc_fbcon.c index 053feaf5..d16401e5 100644 --- a/tty/pc-tty/ttypc_fbcon.c +++ b/tty/pc-tty/ttypc_fbcon.c @@ -148,9 +148,8 @@ int ttypc_fbcon_init(ttypc_t *ttypc) ttypc->fbbpp = pctl.graphmode.bpp; ttypc->fbpitch = pctl.graphmode.pitch; - /* TODO use fbcols, fbrows to operate in higher resolutions than 80x25 in tty/vt */ - ttypc->fbcols = ttypc->fbw / TTYPC_FBFONT_W; - ttypc->fbrows = ttypc->fbh / TTYPC_FBFONT_H; + ttypc->fbmaxcols = ttypc->fbw / TTYPC_FBFONT_W; + ttypc->fbmaxrows = ttypc->fbh / TTYPC_FBFONT_H; return EOK; } diff --git a/tty/pc-tty/ttypc_vga.c b/tty/pc-tty/ttypc_vga.c index d19de74b..d19d75cd 100644 --- a/tty/pc-tty/ttypc_vga.c +++ b/tty/pc-tty/ttypc_vga.c @@ -192,6 +192,11 @@ void _ttypc_vga_switch(ttypc_vt_t *vt) _ttypc_vga_read(cvt->vram, cvt->mem, cvt->rows * cvt->cols); cvt->vram = cvt->mem; + if (vt->fbmode == TTY_FBCON_ENABLED) { + /* Resize the virtual terminal to match fbcon maximum resolution */ + ttypc_vt_resize(vt, vt->ttypc->fbmaxcols, vt->ttypc->fbmaxrows); + } + mutexLock(vt->lock); /* VT memory -> VGA memory */ vt->vram = ttypc->vga; @@ -210,7 +215,7 @@ void _ttypc_vga_switch(ttypc_vt_t *vt) /* Returns scrollback capacity in lines */ static unsigned int _ttypc_vga_scrollbackcapacity(ttypc_vt_t *vt) { - return (SCRB_PAGES * (vt->cols * vt->rows + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1)) / (vt->cols * CHR_VGA); + return (SCRB_PAGES * vt->buffsz) / (vt->cols * CHR_VGA); } @@ -368,34 +373,33 @@ void _ttypc_vga_togglecursor(ttypc_vt_t *vt, uint8_t state) void ttypc_vga_destroy(ttypc_t *ttypc) { ttypc_fbcon_destroy(ttypc); - munmap((void *)ttypc->vga, _PAGE_SIZE); + munmap((void *)ttypc->vga, ttypc->memsz); } int ttypc_vga_init(ttypc_t *ttypc) { - int memsz; - /* Test monitor type */ ttypc->color = inb((void *)GN_MISCOUTR) & 0x01; ttypc->crtc = (ttypc->color) ? (void *)CRTC_COLOR : (void *)CRTC_MONO; if (ttypc_fbcon_init(ttypc) < 0) { /* Map video memory */ - ttypc->vga = mmap(NULL, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PHYSMEM | MAP_ANONYMOUS, -1, (ttypc->color) ? VGA_COLOR : VGA_MONO); + ttypc->memsz = _PAGE_SIZE; + ttypc->vga = mmap(NULL, ttypc->memsz, PROT_READ | PROT_WRITE, MAP_PHYSMEM | MAP_ANONYMOUS, -1, (ttypc->color) ? VGA_COLOR : VGA_MONO); if (ttypc->vga == MAP_FAILED) return -ENOMEM; ttypc->fbaddr = NULL; - ttypc->fbcols = -1; - ttypc->fbrows = -1; + ttypc->fbmaxcols = -1; + ttypc->fbmaxrows = -1; } else { /* Map general purpose memory, not video memory. If fbcon is present, then we're * in graphics mode already, so the standard VGA_MONO/VGA_COLOR framebuffers can * be inactive and contain garbage. */ - memsz = (ttypc->fbcols * ttypc->fbrows + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1); - ttypc->vga = mmap(NULL, memsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ttypc->memsz = (ttypc->fbmaxcols * ttypc->fbmaxrows * CHR_VGA + _PAGE_SIZE - 1) & ~(_PAGE_SIZE - 1); + ttypc->vga = mmap(NULL, ttypc->memsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (ttypc->vga == MAP_FAILED) { ttypc_fbcon_destroy(ttypc); return -ENOMEM; diff --git a/tty/pc-tty/ttypc_vt.c b/tty/pc-tty/ttypc_vt.c index 2e1d03a2..05b7c961 100644 --- a/tty/pc-tty/ttypc_vt.c +++ b/tty/pc-tty/ttypc_vt.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -711,6 +712,18 @@ static void _ttypc_vt_signaltxready(void *arg) } +void ttypc_vt_resize(ttypc_vt_t *vt, uint8_t cols, uint8_t rows) +{ + vt->tty.ws.ws_col = cols; + vt->tty.ws.ws_row = rows; + libtty_signal_pgrp(&vt->tty, SIGWINCH); + + vt->cols = cols; + vt->rows = rows; + _ttypc_vtf_str(vt); +} + + int ttypc_vt_init(ttypc_t *ttypc, unsigned int ttybuffsz, ttypc_vt_t *vt) { libtty_callbacks_t cb = { @@ -724,7 +737,7 @@ int ttypc_vt_init(ttypc_t *ttypc, unsigned int ttybuffsz, ttypc_vt_t *vt) if ((err = mutexCreate(&vt->lock)) < 0) return err; - vt->mem = mmap(NULL, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + vt->mem = mmap(NULL, ttybuffsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (vt->mem == MAP_FAILED) { resourceDestroy(vt->lock); return -ENOMEM; @@ -732,31 +745,33 @@ int ttypc_vt_init(ttypc_t *ttypc, unsigned int ttybuffsz, ttypc_vt_t *vt) vt->vram = vt->mem; if (SCRB_PAGES) { - vt->scro = mmap(NULL, _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + vt->scro = mmap(NULL, ttybuffsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (vt->scro == MAP_FAILED) { resourceDestroy(vt->lock); - munmap(vt->mem, _PAGE_SIZE); + munmap(vt->mem, ttybuffsz); return -ENOMEM; } - vt->scrb = mmap(NULL, SCRB_PAGES * _PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + vt->scrb = mmap(NULL, SCRB_PAGES * ttybuffsz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (vt->scrb == MAP_FAILED) { resourceDestroy(vt->lock); - munmap(vt->mem, _PAGE_SIZE); - munmap(vt->scro, _PAGE_SIZE); + munmap(vt->mem, ttybuffsz); + munmap(vt->scro, ttybuffsz); return -ENOMEM; } } if ((err = libtty_init(&vt->tty, &cb, ttybuffsz, TTYDEF_SPEED)) < 0) { resourceDestroy(vt->lock); - munmap(vt->mem, _PAGE_SIZE); + munmap(vt->mem, ttybuffsz); if (SCRB_PAGES) { - munmap(vt->scro, _PAGE_SIZE); - munmap(vt->scrb, SCRB_PAGES * _PAGE_SIZE); + munmap(vt->scro, ttybuffsz); + munmap(vt->scrb, SCRB_PAGES * ttybuffsz); } return err; } + vt->buffsz = ttybuffsz; + /* Disable default libtty tab expansion */ vt->tty.term.c_oflag &= ~(XTABS); @@ -769,7 +784,7 @@ int ttypc_vt_init(ttypc_t *ttypc, unsigned int ttybuffsz, ttypc_vt_t *vt) /* Clear screen */ _ttypc_vga_set(vt, vt->vram, vt->attr | ' ', vt->cols * vt->rows); - vt->fbmode = ttypc->fbrows != -1 && ttypc->fbcols != -1 ? TTY_FBCON_ENABLED : TTY_FBCON_DISABLED; + vt->fbmode = ttypc->fbmaxrows != -1 && ttypc->fbmaxcols != -1 ? TTY_FBCON_ENABLED : TTY_FBCON_DISABLED; return EOK; } diff --git a/tty/pc-tty/ttypc_vt.h b/tty/pc-tty/ttypc_vt.h index b93b6c2c..db6f6a39 100644 --- a/tty/pc-tty/ttypc_vt.h +++ b/tty/pc-tty/ttypc_vt.h @@ -130,6 +130,7 @@ typedef struct { libtty_common_t tty; /* Terminal character processing (using libtty) */ uint8_t fbmode; /* Framebuffer mode: enabled (0x0) or disabled (0x1) */ + uint32_t buffsz; /* Virtual terminal buffer size */ /* Synchronization */ handle_t lock; /* Access lock */ @@ -160,6 +161,10 @@ extern int ttypc_vt_pollstatus(ttypc_vt_t *vt); extern int ttypc_vt_ioctl(ttypc_vt_t *vt, pid_t pid, unsigned int cmd, const void *idata, const void **odata); +/* Resizes virtual terminal */ +extern void ttypc_vt_resize(ttypc_vt_t *vt, uint8_t cols, uint8_t rows); + + /* Destroys virtual terminal */ extern void ttypc_vt_destroy(ttypc_vt_t *vt);