Multiple changes

Former-commit-id: db8e674358
This commit is contained in:
Leroy Hopson 2020-09-29 16:16:59 +07:00
parent a55a05d3a4
commit 9bd17ec8dc
31 changed files with 5058 additions and 1031 deletions

View file

@ -1,6 +1,7 @@
#include "pseudoterminal.h"
#include <pty.h>
#include <unistd.h>
#include <sys/wait.h>
#include <termios.h>
using namespace godot;
@ -11,9 +12,11 @@ void Pseudoterminal::_register_methods()
register_method("_init", &Pseudoterminal::_init);
register_method("_ready", &Pseudoterminal::_ready);
register_method("put_data", &Pseudoterminal::put_data);
register_method("write", &Pseudoterminal::write);
register_method("resize", &Pseudoterminal::resize);
register_signal<Pseudoterminal>((char *)"data_received", "data", GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY);
register_signal<Pseudoterminal>((char *)"data_sent", "data", GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY);
register_signal<Pseudoterminal>((char *)"exited", "status", GODOT_VARIANT_TYPE_INT);
}
Pseudoterminal::Pseudoterminal()
@ -22,18 +25,20 @@ Pseudoterminal::Pseudoterminal()
Pseudoterminal::~Pseudoterminal()
{
pty_thread.join();
}
void Pseudoterminal::_init()
{
pty_thread = std::thread(&Pseudoterminal::process_pty, this);
bytes_to_write = 0;
pty_thread = std::thread(&Pseudoterminal::process_pty, this);
}
void Pseudoterminal::process_pty()
{
int fd;
char *name;
int status;
should_process_pty = true;
@ -68,9 +73,30 @@ void Pseudoterminal::process_pty()
}
else
{
Vector2 zero = Vector2(0, 0);
/* Parent */
while (1)
{
{
std::lock_guard<std::mutex> guard(size_mutex);
if (size != zero)
{
struct winsize ws;
memset(&ws, 0, sizeof(ws));
ws.ws_col = size.x;
ws.ws_row = size.y;
ioctl(fd, TIOCSWINSZ, &ws);
}
}
if (waitpid(pty_pid, &status, WNOHANG))
{
emit_signal("exited", status);
return;
}
int ready = -1;
fd_set read_fds;
fd_set write_fds;
@ -93,10 +119,7 @@ void Pseudoterminal::process_pty()
if (bytes_to_write > 0)
{
write(fd, write_buffer, bytes_to_write);
Godot::print(String("wrote {0} bytes").format(Array::make(bytes_to_write)));
::write(fd, write_buffer, bytes_to_write);
bytes_to_write = 0;
}
}
@ -114,30 +137,11 @@ void Pseudoterminal::process_pty()
if (bytes_read <= 0)
continue;
//while (1)
//{
// ret = read(fd, read_buffer, 1);
// if (ret == -1 || ret == 0)
// {
// break;
// }
// else
// {
// bytes_read += ret;
// }
//}
PoolByteArray data = PoolByteArray();
data.resize(bytes_read);
memcpy(data.write().ptr(), read_buffer, bytes_read);
emit_signal("data_received", PoolByteArray(data));
if (bytes_read > 0)
{
//Godot::print(String("read {0} bytes").format(Array::make(bytes_read)));
}
emit_signal("data_sent", PoolByteArray(data));
}
}
}
@ -148,9 +152,15 @@ void Pseudoterminal::_ready()
{
}
void Pseudoterminal::put_data(PoolByteArray data)
void Pseudoterminal::write(PoolByteArray data)
{
std::lock_guard<std::mutex> guard(write_buffer_mutex);
bytes_to_write = data.size();
memcpy(write_buffer, data.read().ptr(), bytes_to_write);
}
void Pseudoterminal::resize(Vector2 new_size)
{
std::lock_guard<std::mutex> guard(size_mutex);
size = new_size;
}

View file

@ -29,6 +29,9 @@ namespace godot
int bytes_to_read;
std::mutex read_buffer_mutex;
Vector2 size;
std::mutex size_mutex;
void process_pty();
public:
@ -40,7 +43,8 @@ namespace godot
void _init();
void _ready();
void put_data(PoolByteArray data);
void write(PoolByteArray data);
void resize(Vector2 size);
};
} // namespace godot

View file

@ -215,7 +215,17 @@ static void write_cb(struct tsm_vte *vte, const char *u8, size_t len, void *data
for (int i = 0; i < len; i++)
bytes.append(u8[i]);
term->emit_signal("data_read", bytes);
if (len > 0)
{
if (term->input_event_key.is_valid())
{
// The callback was fired from a key press event so emit the "key_pressed" signal.
term->emit_signal("key_pressed", String(u8), term->input_event_key);
term->input_event_key.unref();
}
term->emit_signal("data_sent", bytes);
}
}
static int text_draw_cb(struct tsm_screen *con,
@ -258,7 +268,6 @@ static int text_draw_cb(struct tsm_screen *con,
void Terminal::_register_methods()
{
register_method("_init", &Terminal::_init);
register_method("_ready", &Terminal::_ready);
register_method("_gui_input", &Terminal::_gui_input);
@ -267,10 +276,12 @@ void Terminal::_register_methods()
register_method("write", &Terminal::write);
register_method("update_size", &Terminal::update_size);
//register_property<Terminal, int>("rows", &Terminal::rows, 24);
//register_property<Terminal, int>("cols", &Terminal::cols, 80);
register_property<Terminal, int>("rows", &Terminal::rows, 24);
register_property<Terminal, int>("cols", &Terminal::cols, 80);
register_signal<Terminal>("data_read", "data", GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY);
register_signal<Terminal>("data_sent", "data", GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY);
register_signal<Terminal>("key_pressed", "data", GODOT_VARIANT_TYPE_STRING, "event", GODOT_VARIANT_TYPE_OBJECT);
register_signal<Terminal>("size_changed", "new_size", GODOT_VARIANT_TYPE_VECTOR2);
}
Terminal::Terminal()
@ -349,6 +360,7 @@ void Terminal::_gui_input(Variant event)
auto iter = keymap.find({unicode, scancode});
uint32_t keysym = (iter != keymap.end() ? iter->second : XKB_KEY_NoSymbol);
input_event_key = k;
tsm_vte_handle_keyboard(vte, keysym, ascii, mods, unicode ? unicode : TSM_VTE_INVALID);
}
}
@ -425,6 +437,9 @@ void Terminal::draw_foreground(int row, int col, Color fgcolor)
struct cell cell = cells[row][col];
if (cell.ch == nullptr)
return; // No foreground to draw
/* Set the font */
Ref<Font> fontref = get_font("");
@ -448,9 +463,6 @@ void Terminal::draw_foreground(int row, int col, Color fgcolor)
/* Draw the foreground */
if (cell.ch == nullptr)
return; // No foreground to draw
if (cell.attr.blink)
; // TODO: Handle blink
@ -523,7 +535,7 @@ void Terminal::update_size()
rows = std::max(2, (int)floor(get_rect().size.y / cell_size.y));
cols = std::max(1, (int)floor(get_rect().size.x / cell_size.x));
Godot::print(String("resized_rows: {0}, resized_cols: {1}").format(Array::make(rows, cols)));
emit_signal("size_changed", Vector2(cols, rows));
Cells new_cells = {};

View file

@ -28,6 +28,8 @@ namespace godot
Cells cells;
Ref<InputEventKey> input_event_key;
protected:
tsm_screen *screen;
tsm_vte *vte;