From d2f6f7a35913c48c7050d1bb9b643a19fbbc8921 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Wed, 24 Jan 2018 22:47:10 +0100 Subject: [PATCH] yaft: use c++ YaFT_p implementation in yaft_class --- src/gui/widget/yaft/yaft_class.cpp | 148 ++++++++++++++--------------- src/gui/widget/yaft/yaft_class.h | 1 + 2 files changed, 74 insertions(+), 75 deletions(-) diff --git a/src/gui/widget/yaft/yaft_class.cpp b/src/gui/widget/yaft/yaft_class.cpp index 8bc9d9596..ea2afa131 100644 --- a/src/gui/widget/yaft/yaft_class.cpp +++ b/src/gui/widget/yaft/yaft_class.cpp @@ -21,37 +21,34 @@ * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. */ -#ifdef DEBUG -/* maybe on command line? */ -#undef DEBUG -#endif -static int CELL_WIDTH, CELL_HEIGHT; -#include "yaft.h" -#include "conf.h" -#include "util.h" -#include "fb/common.h" -#include "terminal.h" -#include "ctrlseq/esc.h" -#include "ctrlseq/csi.h" -#include "ctrlseq/osc.h" -#include "parse.h" + +#include +#include +#include +#include +#include +#include +#include +#include + #include "yaft_class.h" +#include "yaft_priv.h" #include -#ifdef DEBUG -#warning DEBUG redefined! -#undef DEBUG -#endif +#include + +const char *term_name = "linux"; /* this will not fly with more than one instance */ static pid_t childpid; static int exitcode; +static volatile sig_atomic_t child_alive; static void sig_handler(int signo) { /* global */ extern volatile sig_atomic_t child_alive; - logging(DEBUG, "caught signal! no:%d\n", signo); + logging(INFO, "caught signal! no:%d\n", signo); if (signo != SIGCHLD) return; @@ -60,7 +57,7 @@ static void sig_handler(int signo) int ret = waitpid(childpid, &wstatus, 0); if (ret < 0) { int e = errno; - logging(ERROR, "terminal: wait for %d returned %m\n", childpid); + logging(NORMAL, "wait for child %d returned %m\n", childpid); if (e == ECHILD) return; /* don_t reset child_alive */ } @@ -68,7 +65,7 @@ static void sig_handler(int signo) exitcode = WEXITSTATUS(wstatus); else if (WIFSIGNALED(wstatus)) exitcode = 128 + WTERMSIG(wstatus); /* simulate shell behaviour */ - logging(WARN, "terminal: %d exited with %d\n", childpid, exitcode); + logging(NORMAL, "child %d exited with %d\n", childpid, exitcode); child_alive = false; } @@ -80,13 +77,17 @@ static pid_t fork_and_exec(int *master, int lines, int cols) ws.ws_col = cols; /* XXX: this variables are UNUSED (man tty_ioctl), but useful for calculating terminal cell size */ +#if 0 ws.ws_ypixel = CELL_HEIGHT * lines; ws.ws_xpixel = CELL_WIDTH * cols; +#endif pid_t pid; - pid = eforkpty(master, NULL, NULL, &ws); + pid = forkpty(master, NULL, NULL, &ws); if (pid == 0) { /* child */ - esetenv("TERM", term_name, 1); + for (int i = 3; i < getdtablesize(); i++) + close(i); + setenv("TERM", term_name, 1); execvp(yaft_argv[0], (char * const *)yaft_argv); /* never reach here */ exit(EXIT_FAILURE); @@ -101,8 +102,8 @@ static int check_fds(fd_set *fds, struct timeval *tv, int input, int master) FD_SET(input, fds); FD_SET(master, fds); tv->tv_sec = 0; - tv->tv_usec = SELECT_TIMEOUT; - return eselect(master + 1, fds, NULL, NULL, tv); + tv->tv_usec = 100000; + return select(master + 1, fds, NULL, NULL, tv); } YaFT::YaFT(const char * const *argv, int *Res, bool Paint, sigc::signalfunc) @@ -123,56 +124,47 @@ int YaFT::run(void) ssize_t size; fd_set fds; 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; - fb.info.cfb = CFrameBuffer::getInstance(); - term.txt.push(""); - term.lines_available = 0; - term.nlseen = false; + bool need_redraw = false; exitcode = 0; - + YaFT_p *term = new YaFT_p(paint); + int flags; /* init */ if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ - logging(WARN, "setlocale falied\n"); - - if (!fb_init(&fb)) { - logging(FATAL, "framebuffer initialize failed\n"); - goto fb_init_failed; - } - - if (!term_init(&term, fb.info.width, fb.info.height)) { - logging(FATAL, "terminal initialize failed\n"); - goto term_init_failed; - } + logging(NORMAL, "setlocale falied\n"); + if (!term->init()) + goto init_failed; struct sigaction sigact; memset(&sigact, 0, sizeof(struct sigaction)); sigact.sa_handler = sig_handler; sigact.sa_flags = SA_RESTART; - esigaction(SIGCHLD, &sigact, NULL); + sigaction(SIGCHLD, &sigact, NULL); /* fork and exec shell */ - if ((childpid = fork_and_exec(&term.fd, term.lines, term.cols)) < 0) { - logging(FATAL, "forkpty failed\n"); - goto tty_init_failed; + if ((childpid = fork_and_exec(&term->fd, term->lines, term->cols)) < 0) { + logging(NORMAL, "forkpty failed\n"); + goto init_failed; } child_alive = true; - + flags = fcntl(term->fd, F_GETFL); + fcntl(term->fd, F_SETFL, flags | O_NONBLOCK); +# if 0 + fprintf(stderr, "forked child %d, command: '", childpid); + const char * const *p = yaft_argv; + while (*p) { + fprintf(stderr, "%s ", *p); + p++; + } + fprintf(stderr, "'\n"); +#endif /* main loop */ while (child_alive) { if (need_redraw) { need_redraw = false; - if (paint) { - redraw(&term); - refresh(&fb, &term); - } + term->refresh(); } - - if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) + if (check_fds(&fds, &tv, STDIN_FILENO, term->fd) == -1) continue; #if 0 if (FD_ISSET(STDIN_FILENO, &fds)) { @@ -180,13 +172,11 @@ int YaFT::run(void) ewrite(term.fd, buf, size); } #endif - if (FD_ISSET(term.fd, &fds)) { - while ((size = read(term.fd, buf, BUFSIZE)) > 0) { - if (VERBOSE) - ewrite(STDOUT_FILENO, buf, size); - parse(&term, buf, size); - while (term.lines_available > 0) { - std::string s = term.txt.front(); + if (FD_ISSET(term->fd, &fds)) { + while ((size = read(term->fd, buf, BUFSIZE)) > 0) { + term->parse(buf, size); + while (term->lines_available > 0) { + std::string s = term->txt.front(); OnShellOutputLoop(&s, res, &ok); #if 0 if (res) @@ -195,28 +185,36 @@ int YaFT::run(void) 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--; + term->txt.pop(); + term->lines_available--; } if (! paint) continue; - if (LAZY_DRAW && size == BUFSIZE) + need_redraw = true; + if (/*LAZY_DRAW && */size == BUFSIZE) continue; /* maybe more data arrives soon */ - refresh(&fb, &term); + time_t now = time_monotonic_ms(); + if (now - term->last_paint < 100) + continue; + term->refresh(); + need_redraw = false; } } } - if (paint) - refresh(&fb, &term); + term->refresh(); + /* get the last partial line if there was no newline. The loop should only ever run once... */ + while (!term->txt.empty()) { + std::string s = term->txt.front(); + OnShellOutputLoop(&s, res, &ok); + term->txt.pop(); + } /* normal exit */ - term_die(&term); + delete term; return exitcode; /* error exit */ -tty_init_failed: - term_die(&term); -term_init_failed: -fb_init_failed: +init_failed: + delete term; return EXIT_FAILURE; } diff --git a/src/gui/widget/yaft/yaft_class.h b/src/gui/widget/yaft/yaft_class.h index 6ce208b11..5107edbaa 100644 --- a/src/gui/widget/yaft/yaft_class.h +++ b/src/gui/widget/yaft/yaft_class.h @@ -9,6 +9,7 @@ */ #ifndef __yaft_class__ #define __yaft_class__ +#include #include class YaFT : public sigc::trackable