Code:
// gcc app.c -lncurses
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
void print_status(WINDOW * win, const char *str) {
init_pair(1, COLOR_RED, COLOR_WHITE);
clear();
wattron(win, COLOR_PAIR(1));
mvwhline(win, 0, 0, ' ', COLS);
mvwaddnstr(win, 0, 0, str, COLS);
wattroff(win, COLOR_PAIR(1));
wrefresh(win);
}
void print_line(WINDOW * win, const char *str, int *i) {
init_pair(2, COLOR_RED, COLOR_BLACK);
if (*i > LINES - 2) {
*i = 1;
wclear(win);
}
wattron(win, COLOR_PAIR(2));
mvwprintw(win, (*i)++, 0, str);
wattroff(win, COLOR_PAIR(2));
wrefresh(win);
}
#define TTY "/dev/tty"
static int open_terminal(char **result, int mode) {
const char *device = TTY;
*result = strdup(device);
return open(device, mode);
}
int main() {
WINDOW *menu_win, *tail;
int i = 1, q = 1, fd1, fd2, is_atty = 1;
char buf[1024];
initscr();
clear();
noecho();
halfdelay(5);
start_color();
nonl();
keypad(stdscr, TRUE);
intrflush(stdscr, FALSE);
menu_win = newwin(1, COLS, 0, 0);
tail = newwin(LINES - 1, COLS, 1, 0);
keypad(menu_win, TRUE);
char *device = NULL;
FILE *pipe_input = stdin;
if(!isatty(fileno(stdin))) {
is_atty = 0;
if((fd1 = open_terminal(&device, O_RDONLY)) >= 0) {
if((fd2 = dup(fileno(stdin))) >= 0) {
pipe_input = fdopen(fd2, "r");
if(freopen(device, "r", stdin) == 0)
perror("cannot open tty-input");
if(fileno(stdin) != 0) /* some functions may read fd #0 */
(void)dup2(fileno(stdin), 0);
}
}
}
// freopen("/dev/tty", "r", stdin);
print_status(menu_win, "Use arrow keys to go up and down");
while(q) {
switch (wgetch(menu_win)) {
case KEY_UP:
print_status(menu_win, "Moved up");
break;
case KEY_DOWN:
print_status(menu_win, "Moved down");
break;
case 'q':
q = 0;
break;
default:
if(is_atty)
break;
while (fgets(buf, 1024, pipe_input) != NULL) {
print_line(tail, buf, &i);
}
break;
}
}
endwin();
return 0;
}