From ad851bcc060cabdaf9600a846dc75a5314975f04 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 7 Jan 2018 22:56:14 +0100 Subject: [PATCH] yaft: prepare for neutrino shellwindow compatibility * add sigc function to collect terminal output * terminal output is collected without escape codes, "text only" * if a newline is seen, each newline starts a new line, * else, some cursor move escape sequences start a new line --- src/gui/widget/yaft/ctrlseq/esc.h | 6 +++++- src/gui/widget/yaft/terminal.h | 14 ++++++++++++++ src/gui/widget/yaft/yaft.h | 6 ++++++ src/gui/widget/yaft/yaft_class.cpp | 26 ++++++++++++++++++++++++-- src/gui/widget/yaft/yaft_class.h | 9 +++++++-- 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/gui/widget/yaft/ctrlseq/esc.h b/src/gui/widget/yaft/ctrlseq/esc.h index 324b916c6..410714857 100644 --- a/src/gui/widget/yaft/ctrlseq/esc.h +++ b/src/gui/widget/yaft/ctrlseq/esc.h @@ -13,7 +13,8 @@ void bs(struct terminal_t *term) void tab(struct terminal_t *term) { int i; - + const char *c = " "; + term->txt.back().append(c, 1); for (i = term->cursor.x + 1; i < term->cols; i++) { if (term->tabstop[i]) { set_cursor(term, term->cursor.y, i); @@ -25,6 +26,9 @@ void tab(struct terminal_t *term) void nl(struct terminal_t *term) { + term->nlseen = true; + term->txt.push(""); + term->lines_available++; move_cursor(term, 1, 0); } diff --git a/src/gui/widget/yaft/terminal.h b/src/gui/widget/yaft/terminal.h index 22ee2d214..5befd49a8 100644 --- a/src/gui/widget/yaft/terminal.h +++ b/src/gui/widget/yaft/terminal.h @@ -150,6 +150,11 @@ void move_cursor(struct terminal_t *term, int y_offset, int x_offset) scroll(term, top, bottom, y_offset); } term->cursor.y = y; + + if (y_offset > 0 && !term->nlseen) { + term->txt.push(""); + term->lines_available++; + } } /* absolute movement: never scroll */ @@ -169,6 +174,11 @@ void set_cursor(struct terminal_t *term, int y, int x) x = (x < 0) ? 0: (x >= term->cols) ? term->cols - 1: x; y = (y < top) ? top: (y > bottom) ? bottom: y; + if (term->cursor.y != y && !term->nlseen) { + term->txt.push(""); + term->lines_available++; + } + term->cursor.x = x; term->cursor.y = y; term->wrap_occured = false; @@ -204,6 +214,10 @@ void addch(struct terminal_t *term, uint32_t code) width = wcwidth(code); + if (code <= 0xff) { /* non-ascii not supported */ + char c = (char)code; + term->txt.back().append(&c, 1); + } if (width <= 0) /* zero width: not support comibining character */ return; else if (0x100000 <= code && code <= 0x10FFFD) /* unicode private area: plane 16 (DRCSMMv1) */ diff --git a/src/gui/widget/yaft/yaft.h b/src/gui/widget/yaft/yaft.h index 135926eea..3262d9a59 100644 --- a/src/gui/widget/yaft/yaft.h +++ b/src/gui/widget/yaft/yaft.h @@ -22,6 +22,9 @@ #include #include +#include +#include + #include "glyph.h" #include "color.h" @@ -177,6 +180,9 @@ struct terminal_t { struct sixel_canvas_t sixel; #endif CFrameBuffer *cfb; + std::queue txt; /* contains "sanitized" (without control chars) output text */ + int lines_available; /* lines available in txt */ + bool nlseen; }; struct parm_t { /* for parse_arg() */ diff --git a/src/gui/widget/yaft/yaft_class.cpp b/src/gui/widget/yaft/yaft_class.cpp index 736608092..cb13b4e7c 100644 --- a/src/gui/widget/yaft/yaft_class.cpp +++ b/src/gui/widget/yaft/yaft_class.cpp @@ -125,9 +125,15 @@ static int check_fds(fd_set *fds, struct timeval *tv, int input, int master) return eselect(master + 1, fds, NULL, NULL, tv); } -YaFT::YaFT(const char * const *argv) +YaFT::YaFT(const char * const *argv, int *Res, sigc::signalfunc) { yaft_argv = argv; + res = Res; + OnShellOutputLoop = func; +} + +YaFT::~YaFT(void) +{ } int YaFT::run(void) @@ -138,12 +144,15 @@ int YaFT::run(void) struct timeval tv; struct framebuffer_t fb; struct terminal_t term; + bool ok = true; /* global */ extern volatile sig_atomic_t need_redraw; extern volatile sig_atomic_t child_alive; term.cfb = fb.info.cfb = CFrameBuffer::getInstance(); + term.txt.push(""); + term.lines_available = 0; + term.nlseen = false; - memset(&term, 0, sizeof(term)); /* init */ if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ logging(WARN, "setlocale falied\n"); @@ -191,6 +200,19 @@ int YaFT::run(void) if (VERBOSE) ewrite(STDOUT_FILENO, buf, size); parse(&term, buf, size); + while (term.lines_available > 0) { + std::string s = term.txt.front(); + OnShellOutputLoop(&s, res, &ok); +#if 0 + if (res) + printf("[CTermWindow] [%s:%d] res=%d ok=%d\n", __func__, __LINE__, *res, ok); + else + printf("[CTermWindow] [%s:%d] res=NULL ok=%d\n", __func__, __LINE__, ok); +#endif + // fprintf(stderr, "%d %s\n", term.lines_available, term.txt.front().c_str()); + term.txt.pop(); + term.lines_available--; + } if (LAZY_DRAW && size == BUFSIZE) continue; /* maybe more data arrives soon */ refresh(&fb, &term); diff --git a/src/gui/widget/yaft/yaft_class.h b/src/gui/widget/yaft/yaft_class.h index 16c4fbdb1..a7bba2115 100644 --- a/src/gui/widget/yaft/yaft_class.h +++ b/src/gui/widget/yaft/yaft_class.h @@ -9,11 +9,16 @@ */ #ifndef __yaft_class__ #define __yaft_class__ -class YaFT +#include + +class YaFT : public sigc::trackable { + private: + int *res; public: - YaFT(const char * const *argv); + YaFT(const char * const *argv, int *Res, sigc::signal); ~YaFT(); int run(); + sigc::signal OnShellOutputLoop; }; #endif