yaft_class: first somehow working version

This commit is contained in:
Stefan Seyfried
2018-01-02 00:16:19 +01:00
committed by Thilo Graf
parent 2650a62986
commit 9f85296597
2 changed files with 74 additions and 88 deletions

View File

@@ -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 <uobikiemukot at gmail dot com>
* 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 <driver/framebuffer.h>
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;

View File

@@ -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