mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-10 18:10:56 +09:00
Rage hacking on TerminalWidget.
There's some really hideous plumbing with globals going on here, but my priority right now is getting a basic VT100 terminal emulator working.
This commit is contained in:
parent
f282df6617
commit
ab5266b924
Notes:
sideshowbarker
2024-07-19 18:50:56 +09:00
Author: https://github.com/awesomekling
Commit: ab5266b924
8 changed files with 136 additions and 15 deletions
|
@ -1,18 +1,47 @@
|
|||
#include "TerminalWidget.h"
|
||||
#include "Painter.h"
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
extern int g_fd;
|
||||
TerminalWidget* g_tw;
|
||||
|
||||
TerminalWidget::TerminalWidget(Widget* parent)
|
||||
: Widget(parent)
|
||||
{
|
||||
g_tw = this;
|
||||
|
||||
setRect({ 100, 300, columns() * 8, rows() * 8 });
|
||||
m_screen = new CharacterWithAttributes[rows() * columns() * 2];
|
||||
printf("rekt: %d x %d\n", width(), height());
|
||||
m_screen = new CharacterWithAttributes[rows() * columns()];
|
||||
for (unsigned row = 0; row < m_rows; ++row) {
|
||||
for (unsigned column = 0; column < m_columns; ++column) {
|
||||
at(row, column).character = ' ';
|
||||
at(row, column).attribute = 0x07;
|
||||
}
|
||||
}
|
||||
onReceive(String("Serenity/OS").toByteBuffer());
|
||||
g_fd = getpt();
|
||||
grantpt(g_fd);
|
||||
unlockpt(g_fd);
|
||||
char buf[1024];
|
||||
ptsname_r(g_fd, buf, sizeof(buf));
|
||||
|
||||
if (fork() == 0) {
|
||||
close(g_fd);
|
||||
setsid();
|
||||
int fd = open(buf, O_RDWR);
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
signal(SIGWINCH, SIG_IGN);
|
||||
ioctl(fd, TIOCSCTTY);
|
||||
execl("/bin/bash", "bash", nullptr);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
}
|
||||
|
||||
TerminalWidget::~TerminalWidget()
|
||||
|
@ -53,17 +82,52 @@ void TerminalWidget::onReceive(const ByteBuffer& buffer)
|
|||
|
||||
void TerminalWidget::onReceive(byte ch)
|
||||
{
|
||||
at(m_cursorRow, m_cursorColumn).character = ch;
|
||||
printf("%2u,%2u -> ", m_cursorRow, m_cursorColumn);
|
||||
if (++m_cursorColumn > m_columns) {
|
||||
m_cursorColumn = 0;
|
||||
//printf("receive %02x\n", ch);
|
||||
auto scrollScreen = [&] () {
|
||||
memmove(m_screen, m_screen + columns(), (m_rows - 1) * columns() * sizeof(CharacterWithAttributes));
|
||||
memset(m_screen + (m_rows - 1) * columns(), ' ', columns() * sizeof(CharacterWithAttributes) * 2);
|
||||
};
|
||||
|
||||
auto addChar = [&] (byte ch) {
|
||||
at(m_cursorRow, m_cursorColumn).character = ch;
|
||||
if (++m_cursorColumn > m_columns) {
|
||||
m_cursorColumn = 0;
|
||||
if (m_cursorRow < (m_rows - 1)) {
|
||||
++m_cursorRow;
|
||||
} else {
|
||||
scrollScreen();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (ch == '\n') {
|
||||
if (m_cursorRow < (m_rows - 1)) {
|
||||
++m_cursorRow;
|
||||
} else {
|
||||
// FIXME: Scroll it!
|
||||
ASSERT_NOT_REACHED();
|
||||
scrollScreen();
|
||||
}
|
||||
} else if (ch == '\r') {
|
||||
m_cursorColumn = 0;
|
||||
} else if (ch == '\t') {
|
||||
while ((m_cursorColumn % 8) != 0 && m_cursorColumn < m_columns) {
|
||||
addChar(' ');
|
||||
}
|
||||
} else {
|
||||
addChar(ch);
|
||||
}
|
||||
printf("%2u,%2u\n", m_cursorRow, m_cursorColumn);
|
||||
update();
|
||||
}
|
||||
|
||||
void TerminalWidget::onKeyDown(KeyEvent& event)
|
||||
{
|
||||
char buf[] = { 0, 0 };
|
||||
buf[0] = event.key();
|
||||
write(g_fd, buf, 2);
|
||||
return Widget::onKeyDown(event);
|
||||
}
|
||||
|
||||
void TerminalWidget::onKeyUp(KeyEvent& event)
|
||||
{
|
||||
return Widget::onKeyUp(event);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue