diff --git a/addons/godot_xterm_native/.sconsign.dblite b/addons/godot_xterm_native/.sconsign.dblite index 5cac49d..6274a54 100644 Binary files a/addons/godot_xterm_native/.sconsign.dblite and b/addons/godot_xterm_native/.sconsign.dblite differ diff --git a/addons/godot_xterm_native/bin/x11/libgodotxtermnative.so b/addons/godot_xterm_native/bin/x11/libgodotxtermnative.so index ae254c9..0ecaef6 100755 Binary files a/addons/godot_xterm_native/bin/x11/libgodotxtermnative.so and b/addons/godot_xterm_native/bin/x11/libgodotxtermnative.so differ diff --git a/addons/godot_xterm_native/src/libgodotxtermnative.os b/addons/godot_xterm_native/src/libgodotxtermnative.os index c052d83..c70e3d0 100644 Binary files a/addons/godot_xterm_native/src/libgodotxtermnative.os and b/addons/godot_xterm_native/src/libgodotxtermnative.os differ diff --git a/addons/godot_xterm_native/src/terminal.cpp b/addons/godot_xterm_native/src/terminal.cpp index 7a7204b..a40371c 100644 --- a/addons/godot_xterm_native/src/terminal.cpp +++ b/addons/godot_xterm_native/src/terminal.cpp @@ -1,54 +1,59 @@ #include "terminal.h" +#include #include using namespace godot; // Use xterm default for default color palette. const uint8_t Terminal::default_color_palette[TSM_COLOR_NUM][3] = { - [TSM_COLOR_BLACK] = { 0x00, 0x00, 0x00 }, - [TSM_COLOR_RED] = { 0x80, 0x00, 0x00 }, - [TSM_COLOR_GREEN] = { 0x00, 0x80, 0x00 }, - [TSM_COLOR_YELLOW] = { 0x80, 0x80, 0x00 }, - [TSM_COLOR_BLUE] = { 0x00, 0x00, 0x80 }, - [TSM_COLOR_MAGENTA] = { 0x80, 0x00, 0x80 }, - [TSM_COLOR_CYAN] = { 0x00, 0x80, 0x80 }, - [TSM_COLOR_LIGHT_GREY] = { 0xc0, 0xc0, 0xc0 }, - [TSM_COLOR_DARK_GREY] = { 0x80, 0x80, 0x80 }, - [TSM_COLOR_LIGHT_RED] = { 0xff, 0x00, 0x00 }, - [TSM_COLOR_LIGHT_GREEN] = { 0x00, 0xff, 0x00 }, - [TSM_COLOR_LIGHT_YELLOW] = { 0xff, 0xff, 0x00 }, - [TSM_COLOR_LIGHT_BLUE] = { 0x00, 0x00, 0xff }, - [TSM_COLOR_LIGHT_MAGENTA] = { 0xff, 0x00, 0xff }, - [TSM_COLOR_LIGHT_CYAN] = { 0x00, 0xff, 0xff }, - [TSM_COLOR_WHITE] = { 0xff, 0xff, 0xff }, + [TSM_COLOR_BLACK] = {0x00, 0x00, 0x00}, + [TSM_COLOR_RED] = {0x80, 0x00, 0x00}, + [TSM_COLOR_GREEN] = {0x00, 0x80, 0x00}, + [TSM_COLOR_YELLOW] = {0x80, 0x80, 0x00}, + [TSM_COLOR_BLUE] = {0x00, 0x00, 0x80}, + [TSM_COLOR_MAGENTA] = {0x80, 0x00, 0x80}, + [TSM_COLOR_CYAN] = {0x00, 0x80, 0x80}, + [TSM_COLOR_LIGHT_GREY] = {0xc0, 0xc0, 0xc0}, + [TSM_COLOR_DARK_GREY] = {0x80, 0x80, 0x80}, + [TSM_COLOR_LIGHT_RED] = {0xff, 0x00, 0x00}, + [TSM_COLOR_LIGHT_GREEN] = {0x00, 0xff, 0x00}, + [TSM_COLOR_LIGHT_YELLOW] = {0xff, 0xff, 0x00}, + [TSM_COLOR_LIGHT_BLUE] = {0x00, 0x00, 0xff}, + [TSM_COLOR_LIGHT_MAGENTA] = {0xff, 0x00, 0xff}, + [TSM_COLOR_LIGHT_CYAN] = {0x00, 0xff, 0xff}, + [TSM_COLOR_WHITE] = {0xff, 0xff, 0xff}, - [TSM_COLOR_FOREGROUND] = { 0xff, 0xff, 0xff }, - [TSM_COLOR_BACKGROUND] = { 0x00, 0x00, 0x00 }, + [TSM_COLOR_FOREGROUND] = {0xff, 0xff, 0xff}, + [TSM_COLOR_BACKGROUND] = {0x00, 0x00, 0x00}, }; -static struct { +static struct +{ Color col; bool is_set; } colours[16]; -static void term_output(const char *s, size_t len, void *user) { +static void term_output(const char *s, size_t len, void *user) +{ } -static void write_cb(struct tsm_vte *vte, const char *u8, size_t len, void *data) { +static void write_cb(struct tsm_vte *vte, const char *u8, size_t len, void *data) +{ Terminal *term = static_cast(data); } static int text_draw_cb(struct tsm_screen *con, - uint64_t id, - const uint32_t *ch, - size_t len, - unsigned int width, - unsigned int posx, - unsigned int posy, - const struct tsm_screen_attr *attr, - tsm_age_t age, - void *data) { + uint64_t id, + const uint32_t *ch, + size_t len, + unsigned int width, + unsigned int posx, + unsigned int posy, + const struct tsm_screen_attr *attr, + tsm_age_t age, + void *data) +{ Terminal *terminal = static_cast(data); @@ -56,23 +61,28 @@ static int text_draw_cb(struct tsm_screen *con, return 0; size_t ulen; - char buf[5] = { 0 }; + char buf[5] = {0}; - if (len > 0) { + if (len > 0) + { char *utf8 = tsm_ucs4_to_utf8_alloc(ch, len, &ulen); memcpy(terminal->cells[posy][posx].ch, utf8, ulen); - } else { + } + else + { terminal->cells[posy][posx] = {}; } memcpy(&terminal->cells[posy][posx].attr, attr, sizeof(tsm_screen_attr)); - terminal->update(); + if (!terminal->sleep) + terminal->update(); return 0; } -void Terminal::_register_methods() { +void Terminal::_register_methods() +{ register_method("_init", &Terminal::_init); register_method("_ready", &Terminal::_ready); @@ -80,89 +90,101 @@ void Terminal::_register_methods() { register_method("_draw", &Terminal::_draw); register_method("write", &Terminal::write); + register_method("update_size", &Terminal::update_size); - register_property("rows", &Terminal::rows, 24); - register_property("cols", &Terminal::cols, 80); + //register_property("rows", &Terminal::rows, 24); + //register_property("cols", &Terminal::cols, 80); } -Terminal::Terminal() { +Terminal::Terminal() +{ } -Terminal::~Terminal() { +Terminal::~Terminal() +{ } -void Terminal::_init() { +void Terminal::_init() +{ + sleep = true; - rows = 24; - cols = 80; - - for (int x = 0; x < rows; x++) { - Row row(cols); - - for (int y = 0; y < cols; y++) { - row[y] = empty_cell; - } - - cells.push_back(row); - } - - cell_size = Vector2(12, 21); // TODO: Get proper cell_size based on font. - - sleep = false; - - int ret; - - if (tsm_screen_new(&screen, NULL, NULL)) { + if (tsm_screen_new(&screen, NULL, NULL)) + { ERR_PRINT("Error creating new tsm screen"); } tsm_screen_set_max_sb(screen, 1000); // TODO: Use config var for scrollback size. - if (tsm_vte_new(&vte, screen, write_cb, this, NULL, NULL)) { + if (tsm_vte_new(&vte, screen, write_cb, this, NULL, NULL)) + { ERR_PRINT("Error creating new tsm vte"); } - /* Set the color palette */ update_color_palette(); - if (tsm_vte_set_custom_palette(vte, color_palette)) { + if (tsm_vte_set_custom_palette(vte, color_palette)) + { ERR_PRINT("Error setting custom palette"); } - if (tsm_vte_set_palette(vte, "custom")) { + if (tsm_vte_set_palette(vte, "custom")) + { ERR_PRINT("Error setting palette"); } + + update_size(); +} + +void Terminal::_ready() +{ + connect("resized", this, "update_size"); +} + +void Terminal::_notification(int what) +{ + switch (what) + { + case NOTIFICATION_RESIZED: + Godot::print("resized!"); + update_size(); + break; + } } -void Terminal::_ready() { +void Terminal::_input(Variant event) +{ } -void Terminal::_input(Variant event) { -} - -void Terminal::_draw() { - +void Terminal::_draw() +{ if (sleep) return; /* Draw the background */ + draw_rect(get_rect(), get_color("Background", "Terminal")); + + /* Draw the cell backgrounds */ // Draw the background first so subsequent rows don't overlap // foreground characters such as y that may extend below the baseline. - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { draw_background(row, col, get_cell_colors(row, col).first); } } - /* Draw the foreground */ + /* Draw the cell foregrounds */ - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { + for (int row = 0; row < rows; row++) + { + for (int col = 0; col < cols; col++) + { draw_foreground(row, col, get_cell_colors(row, col).second); } } } -void Terminal::update_color_palette() { - +void Terminal::update_color_palette() +{ // Start with a copy of the default color palette memcpy(color_palette, Terminal::default_color_palette, sizeof(Terminal::default_color_palette)); @@ -199,7 +221,8 @@ void Terminal::update_color_palette() { set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground"); } -void Terminal::draw_background(int row, int col, Color bgcolor) { +void Terminal::draw_background(int row, int col, Color bgcolor) +{ /* Draw the background */ Vector2 background_pos = Vector2(col * cell_size.x, row * cell_size.y); @@ -207,7 +230,8 @@ void Terminal::draw_background(int row, int col, Color bgcolor) { draw_rect(background_rect, bgcolor); } -void Terminal::draw_foreground(int row, int col, Color fgcolor) { +void Terminal::draw_foreground(int row, int col, Color fgcolor) +{ struct cell cell = cells[row][col]; @@ -215,13 +239,20 @@ void Terminal::draw_foreground(int row, int col, Color fgcolor) { Ref fontref = get_font(""); - if (cell.attr.bold && cell.attr.italic) { + if (cell.attr.bold && cell.attr.italic) + { fontref = get_font("Bold Italic", "Terminal"); - } else if (cell.attr.bold) { + } + else if (cell.attr.bold) + { fontref = get_font("Bold", "Terminal"); - } else if (cell.attr.italic) { + } + else if (cell.attr.italic) + { fontref = get_font("Italic", "Terminal"); - } else { + } + else + { fontref = get_font("Regular", "Terminal"); } @@ -241,7 +272,8 @@ void Terminal::draw_foreground(int row, int col, Color fgcolor) { draw_string(fontref, foreground_pos, "_", fgcolor); } -std::pair Terminal::get_cell_colors(int row, int col) { +std::pair Terminal::get_cell_colors(int row, int col) +{ struct cell cell = cells[row][col]; Color fgcol, bgcol; float fr = 1, fg = 1, fb = 1, br = 0, bg = 0, bb = 0; @@ -249,30 +281,38 @@ std::pair Terminal::get_cell_colors(int row, int col) { /* Get foreground color */ - if (cell.attr.fccode && palette.count(cell.attr.fccode)) { + if (cell.attr.fccode && palette.count(cell.attr.fccode)) + { fgcol = palette[cell.attr.fccode]; - } else { + } + else + { fr = (float)cell.attr.fr / 255.0; fg = (float)cell.attr.fg / 255.0; fb = (float)cell.attr.fb / 255.0; fgcol = Color(fr, fg, fb); - if (cell.attr.fccode) { + if (cell.attr.fccode) + { palette.insert(std::pair(cell.attr.fccode, Color(fr, fg, fb))); } } /* Get background color */ - if (cell.attr.bccode && palette.count(cell.attr.bccode)) { + if (cell.attr.bccode && palette.count(cell.attr.bccode)) + { bgcol = palette[cell.attr.bccode]; - } else { + } + else + { br = (float)cell.attr.br / 255.0; bg = (float)cell.attr.bg / 255.0; bb = (float)cell.attr.bb / 255.0; bgcol = Color(br, bg, bb); - if (cell.attr.bccode) { + if (cell.attr.bccode) + { palette.insert(std::pair(cell.attr.bccode, Color(br, bg, bb))); } } @@ -283,8 +323,40 @@ std::pair Terminal::get_cell_colors(int row, int col) { return std::make_pair(bgcol, fgcol); } -void Terminal::write(PoolByteArray data) { +// Recalculates the cell_size and number of cols/rows based on font size and the Control's rect_size +void Terminal::update_size() +{ + sleep = true; + cell_size = get_font("Regular", "Terminal").ptr()->get_string_size("W"); + + 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))); + + cells = {}; + + for (int x = 0; x < rows; x++) + { + Row row(cols); + + for (int y = 0; y < cols; y++) + { + row[y] = empty_cell; + } + + cells.push_back(row); + } + + tsm_screen_resize(screen, cols, rows); + + sleep = false; + update(); +} + +void Terminal::write(PoolByteArray data) +{ tsm_vte_input(vte, (char *)data.read().ptr(), data.size()); framebuffer_age = tsm_screen_draw(screen, text_draw_cb, this); } \ No newline at end of file diff --git a/addons/godot_xterm_native/src/terminal.h b/addons/godot_xterm_native/src/terminal.h index f4de4b1..b10447a 100644 --- a/addons/godot_xterm_native/src/terminal.h +++ b/addons/godot_xterm_native/src/terminal.h @@ -8,19 +8,22 @@ #include #include -namespace godot { +namespace godot +{ -class Terminal : public Control { +class Terminal : public Control +{ GODOT_CLASS(Terminal, Control) public: - struct cell { + struct cell + { char ch[5]; struct tsm_screen_attr attr; - } empty_cell = { ch : { 0, 0, 0, 0, 0 }, attr : {} }; + } empty_cell = {ch : {0, 0, 0, 0, 0}, attr : {}}; public: - typedef std::vector > Cells; + typedef std::vector> Cells; typedef std::vector Row; Cells cells; @@ -35,6 +38,8 @@ private: Vector2 cell_size; std::map palette = {}; + void update_size(); + void update_color_palette(); std::pair get_cell_colors(int row, int col); void draw_background(int row, int col, Color bgcol); @@ -48,6 +53,7 @@ public: void _init(); void _ready(); + void _notification(int what); void _input(Variant event); void _draw(); diff --git a/addons/godot_xterm_native/src/terminal.os b/addons/godot_xterm_native/src/terminal.os index 8d57c6e..a0e1acf 100644 Binary files a/addons/godot_xterm_native/src/terminal.os and b/addons/godot_xterm_native/src/terminal.os differ diff --git a/examples/terminal/Terminal.tscn b/examples/terminal/Terminal.tscn index d6fd049..71be21b 100644 --- a/examples/terminal/Terminal.tscn +++ b/examples/terminal/Terminal.tscn @@ -6,6 +6,8 @@ [ext_resource path="res://examples/terminal/container.gd" type="Script" id=4] [node name="Container" type="Container"] +margin_right = 40.0 +margin_bottom = 40.0 script = ExtResource( 4 ) __meta__ = { "_edit_use_anchors_": false @@ -16,9 +18,6 @@ margin_right = 40.0 margin_bottom = 40.0 theme = ExtResource( 2 ) script = ExtResource( 1 ) -__meta__ = { -"_edit_use_anchors_": false -} [node name="Pseudoterminal" type="Node" parent="."] script = ExtResource( 3 )