From 9f85296597ce946ae78601565dbb65bd9f249e78 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Tue, 2 Jan 2018 00:16:19 +0100 Subject: [PATCH] yaft_class: first somehow working version --- src/gui/widget/yaft/yaft_class.cpp | 143 +++++++++++------------------ src/gui/widget/yaft/yaft_class.h | 19 ++++ 2 files changed, 74 insertions(+), 88 deletions(-) create mode 100644 src/gui/widget/yaft/yaft_class.h diff --git a/src/gui/widget/yaft/yaft_class.cpp b/src/gui/widget/yaft/yaft_class.cpp index 4ece9209f..2aa6f2d54 100644 --- a/src/gui/widget/yaft/yaft_class.cpp +++ b/src/gui/widget/yaft/yaft_class.cpp @@ -1,5 +1,26 @@ -/* See LICENSE for licence details. */ -/* yaft.c: include main function */ +/* + * yaft framebuffer terminal as C++ class for embedding in neutrino-MP + * (C) 2018 Stefan Seyfried + * License: GPL-2.0 + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * derived from yaft/yaft.c, + * original code + * Copyright (c) 2012 haru + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + */ #include "yaft.h" #include "conf.h" #include "util.h" @@ -8,55 +29,24 @@ #include "ctrlseq/esc.h" #include "ctrlseq/csi.h" #include "ctrlseq/osc.h" -#include "ctrlseq/dcs.h" #include "parse.h" +#include "yaft_class.h" +#include -void sig_handler(int signo) +static void sig_handler(int signo) { - sigset_t sigset; /* global */ - extern volatile sig_atomic_t vt_active; extern volatile sig_atomic_t child_alive; - extern volatile sig_atomic_t need_redraw; logging(DEBUG, "caught signal! no:%d\n", signo); if (signo == SIGCHLD) { child_alive = false; wait(NULL); - } else if (signo == SIGUSR1) { /* vt activate */ - vt_active = true; - need_redraw = true; - ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); - } else if (signo == SIGUSR2) { /* vt deactivate */ - vt_active = false; - ioctl(STDIN_FILENO, VT_RELDISP, 1); - - if (BACKGROUND_DRAW) { /* update passive cursor */ - need_redraw = true; - } else { /* sleep until next vt switching */ - sigfillset(&sigset); - sigdelset(&sigset, SIGUSR1); - sigsuspend(&sigset); - } } } -void set_rawmode(int fd, struct termios *save_tm) -{ - struct termios tm; - - tm = *save_tm; - tm.c_iflag = tm.c_oflag = 0; - tm.c_cflag &= ~CSIZE; - tm.c_cflag |= CS8; - tm.c_lflag &= ~(ECHO | ISIG | ICANON); - tm.c_cc[VMIN] = 1; /* min data size (byte) */ - tm.c_cc[VTIME] = 0; /* time out */ - etcsetattr(fd, TCSAFLUSH, &tm); -} - -bool tty_init(struct termios *termios_orig) +bool tty_init(void) { struct sigaction sigact; @@ -64,7 +54,7 @@ bool tty_init(struct termios *termios_orig) sigact.sa_handler = sig_handler; sigact.sa_flags = SA_RESTART; esigaction(SIGCHLD, &sigact, NULL); - +#if 0 if (VT_CONTROL) { esigaction(SIGUSR1, &sigact, NULL); esigaction(SIGUSR2, &sigact, NULL); @@ -88,75 +78,51 @@ bool tty_init(struct termios *termios_orig) etcgetattr(STDIN_FILENO, termios_orig); set_rawmode(STDIN_FILENO, termios_orig); ewrite(STDIN_FILENO, "\033[?25l", 6); /* make cusor invisible */ - +#endif return true; } -void tty_die(struct termios *termios_orig) +static const char * const *yaft_argv; +static bool fork_and_exec(int *master, int lines, int cols) { - /* no error handling */ - struct sigaction sigact; - struct vt_mode vtm; + struct winsize ws; + ws.ws_row = lines; + ws.ws_col = cols; + /* XXX: this variables are UNUSED (man tty_ioctl), + but useful for calculating terminal cell size */ + ws.ws_ypixel = CELL_HEIGHT * lines; + ws.ws_xpixel = CELL_WIDTH * cols; - memset(&sigact, 0, sizeof(struct sigaction)); - sigact.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sigact, NULL); - - if (VT_CONTROL) { - sigaction(SIGUSR1, &sigact, NULL); - sigaction(SIGUSR2, &sigact, NULL); - - vtm.mode = VT_AUTO; - vtm.waitv = 0; - vtm.relsig = vtm.acqsig = vtm.frsig = 0; - - ioctl(STDIN_FILENO, VT_SETMODE, &vtm); - - if (FORCE_TEXT_MODE == false) - ioctl(STDIN_FILENO, KDSETMODE, KD_TEXT); - } - - tcsetattr(STDIN_FILENO, TCSAFLUSH, termios_orig); - fflush(stdout); - ewrite(STDIN_FILENO, "\033[?25h", 6); /* make cursor visible */ -} - -bool fork_and_exec(int *master, int lines, int cols) -{ - extern const char *shell_cmd; /* defined in conf.h */ - char *shell_env; pid_t pid; - struct winsize ws = {.ws_row = lines, .ws_col = cols, - /* XXX: this variables are UNUSED (man tty_ioctl), - but useful for calculating terminal cell size */ - .ws_ypixel = CELL_HEIGHT * lines, .ws_xpixel = CELL_WIDTH * cols}; - pid = eforkpty(master, NULL, NULL, &ws); if (pid < 0) return false; else if (pid == 0) { /* child */ esetenv("TERM", term_name, 1); - if ((shell_env = getenv("SHELL")) != NULL) - eexecl(shell_env); - else - eexecl(shell_cmd); + execvp(yaft_argv[0], (char * const *)yaft_argv); /* never reach here */ exit(EXIT_FAILURE); } return true; } -int check_fds(fd_set *fds, struct timeval *tv, int input, int master) +static int check_fds(fd_set *fds, struct timeval *tv, int input, int master) { FD_ZERO(fds); - FD_SET(input, fds); + if (input != STDIN_FILENO) + 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); } -int main() +YaFT::YaFT(const char * const *argv) +{ + yaft_argv = argv; +} + +int YaFT::run(void) { uint8_t buf[BUFSIZE]; ssize_t size; @@ -167,8 +133,9 @@ int main() /* global */ extern volatile sig_atomic_t need_redraw; extern volatile sig_atomic_t child_alive; - extern struct termios termios_orig; + term.cfb = fb.info.cfb = CFrameBuffer::getInstance(); + memset(&term, 0, sizeof(term)); /* init */ if (setlocale(LC_ALL, "") == NULL) /* for wcwidth() */ logging(WARN, "setlocale falied\n"); @@ -183,7 +150,7 @@ int main() goto term_init_failed; } - if (!tty_init(&termios_orig)) { + if (!tty_init()) { logging(FATAL, "tty initialize failed\n"); goto tty_init_failed; } @@ -199,20 +166,20 @@ int main() while (child_alive) { if (need_redraw) { need_redraw = false; - cmap_update(fb.fd, fb.cmap); /* after VT switching, need to restore cmap (in 8bpp mode) */ redraw(&term); refresh(&fb, &term); } if (check_fds(&fds, &tv, STDIN_FILENO, term.fd) == -1) continue; - +#if 0 if (FD_ISSET(STDIN_FILENO, &fds)) { if ((size = read(STDIN_FILENO, buf, BUFSIZE)) > 0) ewrite(term.fd, buf, size); } +#endif if (FD_ISSET(term.fd, &fds)) { - if ((size = read(term.fd, buf, BUFSIZE)) > 0) { + while ((size = read(term.fd, buf, BUFSIZE)) > 0) { if (VERBOSE) ewrite(STDOUT_FILENO, buf, size); parse(&term, buf, size); @@ -222,9 +189,9 @@ int main() } } } + refresh(&fb, &term); /* normal exit */ - tty_die(&termios_orig); term_die(&term); fb_die(&fb); return EXIT_SUCCESS; diff --git a/src/gui/widget/yaft/yaft_class.h b/src/gui/widget/yaft/yaft_class.h new file mode 100644 index 000000000..16c4fbdb1 --- /dev/null +++ b/src/gui/widget/yaft/yaft_class.h @@ -0,0 +1,19 @@ +/* + * definition for embedding the YaFT framebuffer terminal in c++ + * (C) 2018 Stefan Seyfried + * License: GPL-2.0+ + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef __yaft_class__ +#define __yaft_class__ +class YaFT +{ + public: + YaFT(const char * const *argv); + ~YaFT(); + int run(); +}; +#endif