diff --git a/Kernel/core/driver/scancode.cpp b/Kernel/core/driver/scancode.cpp index 4728feaf..dec98781 100644 --- a/Kernel/core/driver/scancode.cpp +++ b/Kernel/core/driver/scancode.cpp @@ -331,6 +331,80 @@ namespace Driver : ScanCodeConversionTableLower[ScanCode]; } + char GetControlCharacter(KeyScanCodes ScanCode) + { + ScanCode = static_cast(static_cast(ScanCode) & 0x7F); /* Remove KEY_PRESSED bit */ + switch (ScanCode) + { + case KEY_2: + return 0x00; /* Ctrl-@ (NUL) */ + case KEY_A: + return 0x01; /* Ctrl-A (SOH) */ + case KEY_B: + return 0x02; /* Ctrl-B (STX) */ + case KEY_C: + return 0x03; /* Ctrl-C (ETX) */ + case KEY_D: + return 0x04; /* Ctrl-D (EOT) */ + case KEY_E: + return 0x05; /* Ctrl-E (ENQ) */ + case KEY_F: + return 0x06; /* Ctrl-F (ACK) */ + case KEY_G: + return 0x07; /* Ctrl-G (BEL) */ + case KEY_H: + return 0x08; /* Ctrl-H (BS) */ + case KEY_I: + return 0x09; /* Ctrl-I (HT) */ + case KEY_J: + return 0x0A; /* Ctrl-J (LF) */ + case KEY_K: + return 0x0B; /* Ctrl-K (VT) */ + case KEY_L: + return 0x0C; /* Ctrl-L (FF) */ + case KEY_M: + return 0x0D; /* Ctrl-M (CR) */ + case KEY_N: + return 0x0E; /* Ctrl-N (SO) */ + case KEY_O: + return 0x0F; /* Ctrl-O (SI) */ + case KEY_P: + return 0x10; /* Ctrl-P (DLE) */ + case KEY_Q: + return 0x11; /* Ctrl-Q (DC1) */ + case KEY_R: + return 0x12; /* Ctrl-R (DC2) */ + case KEY_S: + return 0x13; /* Ctrl-S (DC3) */ + case KEY_T: + return 0x14; /* Ctrl-T (DC4) */ + case KEY_U: + return 0x15; /* Ctrl-U (NAK) */ + case KEY_V: + return 0x16; /* Ctrl-V (SYN) */ + case KEY_W: + return 0x17; /* Ctrl-W (ETB) */ + case KEY_X: + return 0x18; /* Ctrl-X (CAN) */ + case KEY_Y: + return 0x19; /* Ctrl-Y (EM) */ + case KEY_Z: + return 0x1A; /* Ctrl-Z (SUB) */ + case KEY_LEFT_BRACKET: + return 0x1B; /* Ctrl-[ (ESC) */ + case KEY_BACKSLASH: + return 0x1C; /* Ctrl-\ (FS) */ + case KEY_RIGHT_BRACKET: + return 0x1D; /* Ctrl-] (GS) */ + case KEY_6: + return 0x1E; /* Ctrl-^ (RS) */ + case KEY_MINUS: + return 0x1F; /* Ctrl-_ (US) */ + default: + return 0x00; /* Not a control character */ + } + } + bool IsValidChar(uint8_t ScanCode) { ScanCode &= 0x7F; /* Remove KEY_PRESSED bit */ diff --git a/Kernel/include/kcon.hpp b/Kernel/include/kcon.hpp index 3fcda3a9..38797d43 100644 --- a/Kernel/include/kcon.hpp +++ b/Kernel/include/kcon.hpp @@ -97,7 +97,7 @@ namespace KernelConsole PaintCallback PaintCB = nullptr; CursorCallback CursorCB = nullptr; - std::mutex Mutex; + std::mutex vt_mutex; public: termios *GetTermios() { return &this->TerminalConfig; } @@ -124,6 +124,7 @@ namespace KernelConsole void csi_cnl(ANSIArgument *Args, int ArgsCount); void csi_cpl(ANSIArgument *Args, int ArgsCount); void csi_cha(ANSIArgument *Args, int ArgsCount); + void ProcessControlCharacter(char c); void Process(char c); TerminalCell *GetCell(size_t index) { return &Cells[index]; } diff --git a/Kernel/include/tty.hpp b/Kernel/include/tty.hpp index 940a5a4f..b86f1e27 100644 --- a/Kernel/include/tty.hpp +++ b/Kernel/include/tty.hpp @@ -34,8 +34,34 @@ namespace TTY public: TerminalBuffer(size_t Size) : Buffer(Size), ReadIndex(0), WriteIndex(0) {} - ssize_t Read(char *OutputBuffer, size_t Size); - ssize_t Write(const char *InputBuffer, size_t Size); + ssize_t Read(char *OutputBuffer, size_t Size) + { + std::lock_guard lock(Mutex); + size_t bytesRead = 0; + + while (bytesRead < Size && ReadIndex != WriteIndex) + { + OutputBuffer[bytesRead++] = Buffer[ReadIndex]; + ReadIndex = (ReadIndex + 1) % Buffer.size(); + } + + return bytesRead; + } + + ssize_t Write(const char *InputBuffer, size_t Size) + { + std::lock_guard lock(Mutex); + size_t bytesWritten = 0; + + for (size_t i = 0; i < Size; ++i) + { + Buffer[WriteIndex] = InputBuffer[i]; + WriteIndex = (WriteIndex + 1) % Buffer.size(); + bytesWritten++; + } + + return bytesWritten; + } void DrainOutput() { @@ -57,9 +83,10 @@ namespace TTY class TeletypeDriver { protected: - termios TerminalConfig; - winsize TerminalSize; + termios TerminalConfig{}; + winsize TerminalSize{}; TerminalBuffer TermBuf; + pid_t ProcessGroup; public: virtual int Open(int Flags, mode_t Mode); @@ -69,7 +96,7 @@ namespace TTY virtual int Ioctl(unsigned long Request, void *Argp); TeletypeDriver(); - virtual ~TeletypeDriver(); + virtual ~TeletypeDriver() = default; }; class PTYDevice @@ -81,10 +108,18 @@ namespace TTY TerminalBuffer TermBuf; public: - PTYMaster(); - ~PTYMaster(); - ssize_t Read(void *Buffer, size_t Size); - ssize_t Write(const void *Buffer, size_t Size); + PTYMaster() : TermBuf(1024) {} + ~PTYMaster() = default; + + ssize_t Read(void *Buffer, size_t Size) + { + return TermBuf.Read((char *)Buffer, Size); + } + + ssize_t Write(const void *Buffer, size_t Size) + { + return TermBuf.Write((const char *)Buffer, Size); + } }; class PTYSlave @@ -93,22 +128,48 @@ namespace TTY TerminalBuffer TermBuf; public: - PTYSlave(); - ~PTYSlave(); - ssize_t Read(void *Buffer, size_t Size); - ssize_t Write(const void *Buffer, size_t Size); + PTYSlave() : TermBuf(1024) {} + ~PTYSlave() = default; + + ssize_t Read(void *Buffer, size_t Size) + { + return TermBuf.Read((char *)Buffer, Size); + } + + ssize_t Write(const void *Buffer, size_t Size) + { + return TermBuf.Write((const char *)Buffer, Size); + } }; PTYMaster Master; PTYSlave Slave; public: - PTYDevice(); - ~PTYDevice(); - int Open(); - int Close(); - ssize_t Read(void *Buffer, size_t Size); - ssize_t Write(const void *Buffer, size_t Size); + PTYDevice() : Master(), Slave() {} + ~PTYDevice() = default; + + int Open() + { + stub; + return -ENOSYS; + } + + int Close() + { + stub; + return -ENOSYS; + } + + ssize_t Read(void *Buffer, size_t Size) + { + return Slave.Read(Buffer, Size); + } + + ssize_t Write(const void *Buffer, size_t Size) + { + return Master.Write(Buffer, Size); + } }; class PTMXDevice @@ -118,8 +179,14 @@ namespace TTY std::mutex PTYMutex; public: - PTMXDevice(); - ~PTMXDevice(); + PTMXDevice() = default; + + ~PTMXDevice() + { + for (auto pty : PTYs) + delete pty; + } + int Open(); int Close(); PTYDevice *CreatePTY(); diff --git a/Kernel/tty/ptmx.cpp b/Kernel/tty/ptmx.cpp index 293e1019..62c3f01b 100644 --- a/Kernel/tty/ptmx.cpp +++ b/Kernel/tty/ptmx.cpp @@ -24,16 +24,6 @@ namespace TTY { - PTMXDevice::PTMXDevice() - { - } - - PTMXDevice::~PTMXDevice() - { - for (auto pty : PTYs) - delete pty; - } - int PTMXDevice::Open() { stub; diff --git a/Kernel/tty/pty.cpp b/Kernel/tty/pty.cpp deleted file mode 100644 index 03733874..00000000 --- a/Kernel/tty/pty.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - This file is part of Fennix Kernel. - - Fennix Kernel 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 (at your option) any later version. - - Fennix Kernel 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 Fennix Kernel. If not, see . -*/ - -#include -#include -#include -#include - -#include "../kernel.h" - -namespace TTY -{ - PTYDevice::PTYDevice() - : Master(), Slave() - { - } - - PTYDevice::~PTYDevice() - { - } - - int PTYDevice::Open() - { - stub; - return -ENOSYS; - } - - int PTYDevice::Close() - { - stub; - return -ENOSYS; - } - - ssize_t PTYDevice::Read(void *Buffer, size_t Size) - { - return Slave.Read(Buffer, Size); - } - - ssize_t PTYDevice::Write(const void *Buffer, size_t Size) - { - return Master.Write(Buffer, Size); - } - - PTYDevice::PTYMaster::PTYMaster() - : TermBuf(1024) - { - } - - PTYDevice::PTYMaster::~PTYMaster() - { - } - - ssize_t PTYDevice::PTYMaster::Read(void *Buffer, size_t Size) - { - return TermBuf.Read((char *)Buffer, Size); - } - - ssize_t PTYDevice::PTYMaster::Write(const void *Buffer, size_t Size) - { - return TermBuf.Write((const char *)Buffer, Size); - } - - PTYDevice::PTYSlave::PTYSlave() - : TermBuf(1024) - { - } - - PTYDevice::PTYSlave::~PTYSlave() - { - } - - ssize_t PTYDevice::PTYSlave::Read(void *Buffer, size_t Size) - { - return TermBuf.Read((char *)Buffer, Size); - } - - ssize_t PTYDevice::PTYSlave::Write(const void *Buffer, size_t Size) - { - return TermBuf.Write((const char *)Buffer, Size); - } -} diff --git a/Kernel/tty/teletype.cpp b/Kernel/tty/teletype.cpp index 54d1a5ad..a2c67779 100644 --- a/Kernel/tty/teletype.cpp +++ b/Kernel/tty/teletype.cpp @@ -26,76 +26,12 @@ namespace TTY { - ssize_t TerminalBuffer::Read(char *OutputBuffer, size_t Size) + TeletypeDriver::TeletypeDriver() : TermBuf(1024) { - std::lock_guard lock(Mutex); - size_t bytesRead = 0; - - while (bytesRead < Size && ReadIndex != WriteIndex) - { - OutputBuffer[bytesRead++] = Buffer[ReadIndex]; - ReadIndex = (ReadIndex + 1) % Buffer.size(); - } - - return bytesRead; - } - - ssize_t TerminalBuffer::Write(const char *InputBuffer, size_t Size) - { - std::lock_guard lock(Mutex); - size_t bytesWritten = 0; - - for (size_t i = 0; i < Size; ++i) - { - Buffer[WriteIndex] = InputBuffer[i]; - WriteIndex = (WriteIndex + 1) % Buffer.size(); - bytesWritten++; - } - - return bytesWritten; - } - - /* ======================================================================== */ - - int TeletypeDriver::Open(int Flags, mode_t Mode) - { - warn("Unimplemented open(%#x, %#x)", Flags, Mode); - return -ENOSYS; - } - - int TeletypeDriver::Close() - { - warn("Unimplemented close()"); - return -ENOSYS; - } - - ssize_t TeletypeDriver::Read(void *Buffer, size_t Size, off_t Offset) - { - warn("Unimplemented read(%#lx, %#lx, %#lx)", Buffer, Size, Offset); - return -ENOSYS; - } - - ssize_t TeletypeDriver::Write(const void *Buffer, size_t Size, off_t Offset) - { - warn("Unimplemented write(%#lx, %#lx, %#lx)", Buffer, Size, Offset); - return -ENOSYS; - } - - int TeletypeDriver::Ioctl(unsigned long Request, void *Argp) - { - warn("Unimplemented ioctl(%#lx, %#lx)", Request, Argp); - return -ENOSYS; - } - - TeletypeDriver::TeletypeDriver() - : TermBuf(1024) - { - this->TerminalSize = { - .ws_row = 0, - .ws_col = 0, - .ws_xpixel = 0, - .ws_ypixel = 0, - }; + if (thisProcess) + this->ProcessGroup = thisProcess->Security.ProcessGroupID; + else + this->ProcessGroup = 0; /* - ICRNL - Map Carriage Return to New Line @@ -110,32 +46,24 @@ namespace TTY - ECHO - Echo input characters - ICANON - Enable canonical input (enable line editing) + - ISIG - Enable signals */ this->TerminalConfig.c_iflag = /*ICRNL |*/ IXON; this->TerminalConfig.c_oflag = OPOST | ONLCR; this->TerminalConfig.c_cflag = CS8 | CREAD | HUPCL; - this->TerminalConfig.c_lflag = ECHO | ICANON; + this->TerminalConfig.c_lflag = ECHO | ICANON | ISIG; - this->TerminalConfig.c_cc[VINTR] = 0x03; /* ^C */ - this->TerminalConfig.c_cc[VQUIT] = 0x1C; /* ^\ */ - this->TerminalConfig.c_cc[VERASE] = 0x7F; /* DEL */ - this->TerminalConfig.c_cc[VKILL] = 0x15; /* ^U */ - this->TerminalConfig.c_cc[VEOF] = 0x04; /* ^D */ - this->TerminalConfig.c_cc[VTIME] = 0; /* Timeout for non-canonical read */ - this->TerminalConfig.c_cc[VMIN] = 1; /* Minimum number of characters for non-canonical read */ - this->TerminalConfig.c_cc[VSWTC] = 0; /* ^O */ - this->TerminalConfig.c_cc[VSTART] = 0x11; /* ^Q */ - this->TerminalConfig.c_cc[VSTOP] = 0x13; /* ^S */ - this->TerminalConfig.c_cc[VSUSP] = 0x1A; /* ^Z */ - this->TerminalConfig.c_cc[VEOL] = 0x00; /* NUL */ - this->TerminalConfig.c_cc[VREPRINT] = 0x12; /* ^R */ - this->TerminalConfig.c_cc[VDISCARD] = 0x14; /* ^T */ - this->TerminalConfig.c_cc[VWERASE] = 0x17; /* ^W */ - this->TerminalConfig.c_cc[VLNEXT] = 0x19; /* ^Y */ - this->TerminalConfig.c_cc[VEOL2] = 0x7F; /* DEL (or sometimes EOF) */ - } - - TeletypeDriver::~TeletypeDriver() - { + this->TerminalConfig.c_cc[VINTR] = 'C' - 0x40; + this->TerminalConfig.c_cc[VQUIT] = '\\' - 0x40; + this->TerminalConfig.c_cc[VERASE] = '\177'; + this->TerminalConfig.c_cc[VKILL] = 'U' - 0x40; + this->TerminalConfig.c_cc[VEOF] = 'D' - 0x40; + this->TerminalConfig.c_cc[VSTART] = 'Q' - 0x40; + this->TerminalConfig.c_cc[VSTOP] = 'S' - 0x40; + this->TerminalConfig.c_cc[VSUSP] = 'Z' - 0x40; + this->TerminalConfig.c_cc[VREPRINT] = 'R' - 0x40; + this->TerminalConfig.c_cc[VDISCARD] = 'O' - 0x40; + this->TerminalConfig.c_cc[VWERASE] = 'W' - 0x40; + this->TerminalConfig.c_cc[VLNEXT] = 'V' - 0x40; } } diff --git a/Kernel/tty/vt.cpp b/Kernel/tty/vt.cpp index 774e6d91..90d5d27a 100644 --- a/Kernel/tty/vt.cpp +++ b/Kernel/tty/vt.cpp @@ -29,26 +29,27 @@ namespace KernelConsole { int VirtualTerminal::Open(int Flags, mode_t Mode) { - std::lock_guard lock(Mutex); + std::lock_guard lock(vt_mutex); stub; return 0; } int VirtualTerminal::Close() { - std::lock_guard lock(Mutex); + std::lock_guard lock(vt_mutex); stub; return 0; } ssize_t VirtualTerminal::Read(void *Buffer, size_t Size, off_t Offset) { - std::lock_guard lock(Mutex); + std::lock_guard lock(vt_mutex); KeyboardReport report{}; /* FIXME: this is a hack, "static" is not a good idea */ static bool upperCase = false; + static bool controlKey = false; RecheckKeyboard: while (DriverManager->GlobalKeyboardInputReports.Count() == 0) @@ -65,6 +66,36 @@ namespace KernelConsole upperCase = false; goto RecheckKeyboard; } + else if (pkey == KEY_LEFT_CTRL || pkey == KEY_RIGHT_CTRL) + { + if (report.Key & KEY_PRESSED) + controlKey = true; + else + controlKey = false; + debug("controlKey = %d", controlKey); + goto RecheckKeyboard; + } + + if (controlKey && this->TerminalConfig.c_lflag & ICANON) + { + if (report.Key & KEY_PRESSED) + { + char cc = Driver::GetControlCharacter(report.Key); + if (cc == 0x00) + goto RecheckKeyboard; + + if (this->TerminalConfig.c_lflag & ECHO) + { + char c = Driver::GetScanCode(report.Key, true); + this->Append('^'); + this->Append(c); + this->Append('\n'); + } + + this->Process(cc); + goto RecheckKeyboard; + } + } if (!(report.Key & KEY_PRESSED)) goto RecheckKeyboard; @@ -99,7 +130,7 @@ namespace KernelConsole ssize_t VirtualTerminal::Write(const void *Buffer, size_t Size, off_t Offset) { - std::lock_guard lock(Mutex); + std::lock_guard lock(vt_mutex); char *buf = (char *)Buffer; debug("string: \"%*s\"", Size, buf); @@ -117,7 +148,7 @@ namespace KernelConsole int VirtualTerminal::Ioctl(unsigned long Request, void *Argp) { - std::lock_guard lock(Mutex); + std::lock_guard lock(vt_mutex); switch (Request) { @@ -166,14 +197,14 @@ namespace KernelConsole } case TIOCGPGRP: { - *((pid_t *)Argp) = thisProcess->Security.ProcessGroupID; - debug("returning pgid %d", thisProcess->Security.ProcessGroupID); + *((pid_t *)Argp) = this->ProcessGroup; + debug("returning pgid %d", this->ProcessGroup); return 0; } case TIOCSPGRP: { - thisProcess->Security.ProcessGroupID = *((pid_t *)Argp); - debug("updated pgid to %d", thisProcess->Security.ProcessGroupID); + this->ProcessGroup = *((pid_t *)Argp); + debug("updated pgid to %d", this->ProcessGroup); return 0; } case TIOCGSID: @@ -461,6 +492,133 @@ namespace KernelConsole CursorCB(&Cursor); } + void VirtualTerminal::ProcessControlCharacter(char c) + { + auto ccheck = [&](int v) + { + return (this->TerminalConfig.c_cc[v] != 0x00 && + this->TerminalConfig.c_cc[v] == c); + }; + + auto ciflag = [&](int f) + { + return (this->TerminalConfig.c_iflag & f) != 0; + }; + + auto clflag = [&](int f) + { + return (this->TerminalConfig.c_lflag & f) != 0; + }; + + if (ciflag(IXON) && ccheck(VSTOP)) + { + fixme("flow control: stopping output"); + return; + } + + if (ciflag(IXON) && ccheck(VSTART)) + { + fixme("flow control: resuming output"); + return; + } + + if (clflag(ISIG)) + { + if (ccheck(VINTR)) + { + if (this->ProcessGroup == 0) + { + debug("Process group is 0!!!"); + return; + } + + for (auto proc : thisProcess->GetContext()->GetProcessList()) + { + if (proc->Security.ProcessGroupID != this->ProcessGroup) + continue; + + debug("Sending signal SIGINT to %s(%d)", proc->Name, proc->ID); + proc->SendSignal(SIGINT); + } + return; + } + else if (ccheck(VQUIT)) + { + if (this->ProcessGroup == 0) + { + debug("Process group is 0!!!"); + return; + } + + for (auto proc : thisProcess->GetContext()->GetProcessList()) + { + if (proc->Security.ProcessGroupID != this->ProcessGroup) + continue; + + debug("Sending signal SIGQUIT to %s(%d)", proc->Name, proc->ID); + proc->SendSignal(SIGQUIT); + } + return; + } + else if (ccheck(VSUSP)) + { + if (this->ProcessGroup == 0) + { + debug("Process group is 0!!!"); + return; + } + + for (auto proc : thisProcess->GetContext()->GetProcessList()) + { + if (proc->Security.ProcessGroupID != this->ProcessGroup) + continue; + + debug("Sending signal SIGTSTP to %s(%d)", proc->Name, proc->ID); + proc->SendSignal(SIGTSTP); + } + return; + } + } + + if (c == '\r') + { + if (ciflag(IGNCR)) + return; + if (ciflag(ICRNL)) + c = '\n'; + } + else if (c == '\n' && (ciflag(INLCR))) + c = '\r'; + + if (clflag(ICANON)) + { + if (ccheck(VERASE)) + { + if (this->Cursor.X > 0) + { + this->Cursor.X--; + this->Append('\b'); + this->Append(' '); + this->Append('\b'); + } + return; + } + else if (ccheck(VKILL)) + { + fixme("clear the current line"); + return; + } + } + + if (clflag(ECHO)) + { + if (c == '\n') + this->Append('\n'); + else + this->Append(c); + } + } + void VirtualTerminal::Process(char c) { #ifdef DEBUG @@ -496,6 +654,15 @@ namespace KernelConsole #endif #endif + if (this->TerminalConfig.c_lflag & ICANON) + { + if ((c > 0x00 && c <= 0x1F) && c != '\x1b') + { + this->ProcessControlCharacter(c); + return; + } + } + ANSIParser *parser = &this->Parser; switch (parser->State) @@ -636,30 +803,28 @@ namespace KernelConsole - ECHO - Echo input characters - ICANON - Enable canonical input (enable line editing) + - ISIG - Enable signals */ this->TerminalConfig.c_iflag = /*ICRNL |*/ IXON; this->TerminalConfig.c_oflag = OPOST | ONLCR; this->TerminalConfig.c_cflag = CS8 | CREAD | HUPCL; - this->TerminalConfig.c_lflag = ECHO | ICANON; - this->TerminalConfig.c_lflag &= ~ICANON; /* FIXME: not ready for this yet */ + this->TerminalConfig.c_lflag = ECHO | ICANON | ISIG; - this->TerminalConfig.c_cc[VINTR] = 0x03; /* ^C */ - this->TerminalConfig.c_cc[VQUIT] = 0x1C; /* ^\ */ - this->TerminalConfig.c_cc[VERASE] = 0x7F; /* DEL */ - this->TerminalConfig.c_cc[VKILL] = 0x15; /* ^U */ - this->TerminalConfig.c_cc[VEOF] = 0x04; /* ^D */ - this->TerminalConfig.c_cc[VTIME] = 0; /* Timeout for non-canonical read */ - this->TerminalConfig.c_cc[VMIN] = 1; /* Minimum number of characters for non-canonical read */ - this->TerminalConfig.c_cc[VSWTC] = 0; /* ^O */ - this->TerminalConfig.c_cc[VSTART] = 0x11; /* ^Q */ - this->TerminalConfig.c_cc[VSTOP] = 0x13; /* ^S */ - this->TerminalConfig.c_cc[VSUSP] = 0x1A; /* ^Z */ - this->TerminalConfig.c_cc[VEOL] = 0x00; /* NUL */ - this->TerminalConfig.c_cc[VREPRINT] = 0x12; /* ^R */ - this->TerminalConfig.c_cc[VDISCARD] = 0x14; /* ^T */ - this->TerminalConfig.c_cc[VWERASE] = 0x17; /* ^W */ - this->TerminalConfig.c_cc[VLNEXT] = 0x19; /* ^Y */ - this->TerminalConfig.c_cc[VEOL2] = 0x7F; /* DEL (or sometimes EOF) */ + this->TerminalConfig.c_cc[VINTR] = 'C' - 0x40; + this->TerminalConfig.c_cc[VQUIT] = '\\' - 0x40; + this->TerminalConfig.c_cc[VERASE] = '\177'; + this->TerminalConfig.c_cc[VKILL] = 'U' - 0x40; + this->TerminalConfig.c_cc[VEOF] = 'D' - 0x40; + this->TerminalConfig.c_cc[VSTART] = 'Q' - 0x40; + this->TerminalConfig.c_cc[VSTOP] = 'S' - 0x40; + this->TerminalConfig.c_cc[VSUSP] = 'Z' - 0x40; + this->TerminalConfig.c_cc[VREPRINT] = 'R' - 0x40; + this->TerminalConfig.c_cc[VDISCARD] = 'O' - 0x40; + this->TerminalConfig.c_cc[VWERASE] = 'W' - 0x40; + this->TerminalConfig.c_cc[VLNEXT] = 'V' - 0x40; + + this->TerminalConfig.c_cc[VTIME] = 0; /* Timeout for non-canonical read */ + this->TerminalConfig.c_cc[VMIN] = 1; /* Minimum number of characters for non-canonical read */ this->Cells = new TerminalCell[Rows * Columns]; @@ -667,8 +832,5 @@ namespace KernelConsole (Rows * Columns) * sizeof(TerminalCell)); } - VirtualTerminal::~VirtualTerminal() - { - delete[] this->Cells; - } + VirtualTerminal::~VirtualTerminal() { delete[] this->Cells; } }