2019-02-06 14:07:38 +01:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
// GNU GPL OS/K //
|
|
|
|
// //
|
2019-02-16 23:36:33 +01:00
|
|
|
// Desc: Terminal-related functions //
|
2019-02-06 14:07:38 +01:00
|
|
|
// //
|
2019-02-16 23:36:33 +01:00
|
|
|
// //
|
|
|
|
// Copyright © 2018-2019 The OS/K Team //
|
|
|
|
// //
|
|
|
|
// This file is part of OS/K. //
|
|
|
|
// //
|
|
|
|
// OS/K is free software: you can redistribute it and/or modify //
|
|
|
|
// it under the terms of the GNU General Public License as published by //
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or //
|
|
|
|
// any later version. //
|
|
|
|
// //
|
|
|
|
// OS/K is distributed in the hope that it will be useful, //
|
|
|
|
// but WITHOUT ANY WARRANTY//without even the implied warranty of //
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
|
|
|
|
// GNU General Public License for more details. //
|
|
|
|
// //
|
|
|
|
// You should have received a copy of the GNU General Public License //
|
|
|
|
// along with OS/K. If not, see <https://www.gnu.org/licenses/>. //
|
2019-02-06 14:07:38 +01:00
|
|
|
//----------------------------------------------------------------------------//
|
|
|
|
|
2019-02-16 23:36:33 +01:00
|
|
|
#include <kernel/term.h>
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
extern void VGA_Init(void);
|
|
|
|
extern Terminal_t VGA_Terminal;
|
|
|
|
|
|
|
|
//
|
2019-03-18 17:25:44 +01:00
|
|
|
// Initializes standard output
|
2019-02-06 14:07:38 +01:00
|
|
|
//
|
|
|
|
void InitTerms(void)
|
|
|
|
{
|
2019-03-19 13:37:23 +01:00
|
|
|
KalAssert(!StdOut && !StdDbg);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
VGA_Init();
|
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
StdDbg = &VGA_Terminal;
|
|
|
|
StdOut = &VGA_Terminal;
|
2019-02-06 14:07:38 +01:00
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
ClearTerm(StdOut);
|
2019-02-06 14:07:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-03-18 17:25:44 +01:00
|
|
|
// Fills terminal with spaces
|
2019-02-06 14:07:38 +01:00
|
|
|
//
|
|
|
|
error_t ClearTerm(Terminal_t *term)
|
|
|
|
{
|
|
|
|
error_t retcode;
|
|
|
|
|
|
|
|
if (term == NULL) return EINVAL;
|
|
|
|
KalAssert(term->initDone == INITOK);
|
|
|
|
|
2019-03-24 14:44:59 +01:00
|
|
|
ExAcquireLock(&term->lock);
|
2019-03-19 13:37:23 +01:00
|
|
|
retcode = term->clear(term);
|
2019-03-24 14:44:59 +01:00
|
|
|
ExReleaseLock(&term->lock);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
return retcode;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-03-18 17:25:44 +01:00
|
|
|
// Changes the color code
|
2019-02-06 14:07:38 +01:00
|
|
|
//
|
|
|
|
error_t ChTermColor(Terminal_t *term, TermColor_t fgColor, TermColor_t bgColor)
|
|
|
|
{
|
|
|
|
if (fgColor > KTERM_COLOR_WHITE || bgColor > KTERM_COLOR_WHITE)
|
|
|
|
return EINVAL;
|
|
|
|
|
|
|
|
if (term == NULL)
|
|
|
|
return EINVAL;
|
|
|
|
|
2019-03-24 14:44:59 +01:00
|
|
|
ExAcquireLock(&term->lock);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
term->fgColor = fgColor;
|
|
|
|
term->bgColor = bgColor;
|
|
|
|
|
2019-03-24 14:44:59 +01:00
|
|
|
ExReleaseLock(&term->lock);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
return EOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-03-19 13:37:23 +01:00
|
|
|
// Writes a single character on the terminal (UNLOCKED version)
|
|
|
|
//
|
|
|
|
error_t PutOnTermUnlocked(Terminal_t *term, char ch)
|
|
|
|
{
|
|
|
|
uint i;
|
|
|
|
size_t prevY;
|
|
|
|
error_t rc = EOK;
|
|
|
|
|
|
|
|
if (ch == '\r') {
|
|
|
|
term->currentX = 0;
|
|
|
|
return EOK;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Line feed first takes us to the very end of the line
|
|
|
|
// Later in this function we actually do the line feed
|
|
|
|
else if (ch == '\n') {
|
|
|
|
term->currentX = term->width - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tabulations account for "term->tabSize" spaces
|
|
|
|
else if (ch == '\t') {
|
|
|
|
prevY = term->currentX;
|
|
|
|
for (i = 0; i < term->tabSize; i++) {
|
|
|
|
// Make sure tabulations can't spread over two lines
|
|
|
|
if (term->currentX == prevY) {
|
|
|
|
rc = term->putchar(term, ' ');
|
|
|
|
if (rc) return rc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else rc = term->putchar(term, ch);
|
|
|
|
|
|
|
|
// Did we reach the end of line?
|
|
|
|
if (!rc && ++term->currentX == term->width) {
|
|
|
|
term->currentX = 0;
|
|
|
|
|
|
|
|
// Did we reach the buffer's end?
|
|
|
|
if (++term->currentY == term->height) {
|
|
|
|
term->currentY = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Writes a single character on the terminal (LOCKED version)
|
2019-02-06 14:07:38 +01:00
|
|
|
//
|
|
|
|
error_t PutOnTerm(Terminal_t *term, char ch)
|
|
|
|
{
|
2019-03-19 13:37:23 +01:00
|
|
|
error_t rc;
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
if (term == NULL) return EINVAL;
|
|
|
|
KalAssert(term->initDone == INITOK);
|
|
|
|
|
2019-03-24 14:44:59 +01:00
|
|
|
ExAcquireLock(&term->lock);
|
2019-03-19 13:37:23 +01:00
|
|
|
rc = PutOnTermUnlocked(term, ch);
|
2019-03-24 14:44:59 +01:00
|
|
|
ExReleaseLock(&term->lock);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Prints string on terminal (UNLOCKED version)
|
|
|
|
//
|
|
|
|
error_t PrintOnTermUnlocked(Terminal_t *term, const char *str)
|
|
|
|
{
|
|
|
|
error_t rc = EOK;
|
|
|
|
|
|
|
|
while (*str && rc == EOK) {
|
|
|
|
rc = PutOnTermUnlocked(term, *str++);
|
|
|
|
}
|
|
|
|
|
|
|
|
return rc;
|
2019-02-06 14:07:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
2019-03-19 13:37:23 +01:00
|
|
|
// Prints string on terminal (LOCKED version)
|
2019-02-06 14:07:38 +01:00
|
|
|
//
|
|
|
|
error_t PrintOnTerm(Terminal_t *term, const char *str)
|
|
|
|
{
|
2019-03-19 13:37:23 +01:00
|
|
|
error_t rc = EOK;
|
2019-02-06 14:07:38 +01:00
|
|
|
|
|
|
|
if (term == NULL) return EINVAL;
|
|
|
|
KalAssert(term->initDone == INITOK);
|
|
|
|
|
2019-03-24 14:44:59 +01:00
|
|
|
ExAcquireLock(&term->lock);
|
2019-03-19 13:37:23 +01:00
|
|
|
rc = PrintOnTermUnlocked(term, str);
|
2019-03-24 14:44:59 +01:00
|
|
|
ExReleaseLock(&term->lock);
|
2019-02-06 14:07:38 +01:00
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
return rc;
|
2019-02-06 14:07:38 +01:00
|
|
|
}
|
|
|
|
|
2019-03-18 14:21:00 +01:00
|
|
|
//
|
2019-03-18 17:25:44 +01:00
|
|
|
// Prints formatted string on standard output
|
2019-03-18 14:21:00 +01:00
|
|
|
// Prints at most KLOG_MAX_BUFSIZE characters
|
|
|
|
//
|
|
|
|
error_t KernLog(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
char logbuf[KLOG_MAX_BUFSIZE];
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
return PrintOnTerm(StdOut, logbuf);
|
2019-03-18 14:21:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef _NO_DEBUG
|
|
|
|
//
|
2019-03-18 17:25:44 +01:00
|
|
|
// Prints formatted string on debug output
|
2019-03-18 14:21:00 +01:00
|
|
|
// Prints at most KLOG_MAX_BUFSIZE characters
|
|
|
|
//
|
|
|
|
error_t DebugLog(const char *fmt, ...)
|
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
char logbuf[KLOG_MAX_BUFSIZE];
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vsnprintf(logbuf, KLOG_MAX_BUFSIZE, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
|
2019-03-19 13:37:23 +01:00
|
|
|
return PrintOnTerm(StdDbg, logbuf);
|
2019-03-18 14:21:00 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|