fa7d2eeba098adf0373720c1a2db4d61beca7e8f
[apps/madtty.git] / demo / boxshell.c
1 /* Just a simple example program that creates a terminal in a frame
2  * and lets the user interact with it.
3  *
4  * To compile:
5  *    gcc -o boxshell boxshell.c $(pkg-config madtty --cflags --libs)
6  */
7
8 #include <ncurses.h>
9
10 #include <fcntl.h>
11 #include <signal.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <sys/ioctl.h>
15 #include <sys/time.h>
16 #include <termios.h>
17 #include <time.h>
18
19 #include <madtty/madtty.h>
20
21 static int getout = 0, sigwinch = 0;
22 static int screen_w, screen_h;
23 static WINDOW *term_win;
24
25 void handler(int signo)
26 {
27     switch (signo) {
28       case SIGCHLD:
29         getout = 1;
30         break;
31       case SIGWINCH:
32         sigwinch = 1;
33         break;
34     }
35 }
36
37 int main(void)
38 {
39     madtty_t *rt;
40     int dirty = 0;
41
42     signal(SIGCHLD, handler);
43     signal(SIGWINCH, handler);
44
45     madtty_initialize();
46     getmaxyx(stdscr, screen_h, screen_w);
47
48     /* create a window with a frame */
49     term_win = newwin(screen_h - 2, screen_w - 2, 1, 1);
50     rt = madtty_create(screen_h - 2, screen_w -2);
51     {
52         const char *path = getenv("SHELL") ?: "/bin/sh";
53         const char *args[] = { path, "--login", NULL};
54
55         madtty_forkpty(rt, path, args);
56     }
57
58     /* keep reading keypresses from the user and passing them to the terminal;
59      * also, redraw the terminal to the window at each iteration */
60     while (!getout) {
61         fd_set rfds;
62         struct timeval tv = { 0, 1000 * 1000 / 50 };
63         int ch;
64
65         FD_ZERO(&rfds);
66         FD_SET(0, &rfds);
67         FD_SET(rt->pty, &rfds);
68
69         if (select(rt->pty + 1, &rfds, NULL, NULL, &tv) > 0) {
70             if (FD_ISSET(rt->pty, &rfds)) {
71                 madtty_process(rt);
72                 dirty = 1;
73             }
74         }
75
76         if (sigwinch) {
77             int fd, cols = -1, rows = -1;
78             struct winsize w;
79
80             if ((fd = open("/dev/tty", O_RDONLY)) != -1) {
81                 if (ioctl(fd, TIOCGWINSZ, &w) != -1) {
82                     rows = w.ws_row;
83                     cols = w.ws_col;
84                 }
85                 close(fd);
86             }
87             if (rows <= 0) {
88                 rows = atoi(getenv("LINES") ?: "24");
89             }
90             if (cols <= 0) {
91                 cols = atoi(getenv("COLUMNS") ?: "80");
92             }
93
94             resizeterm(rows, cols);
95             madtty_resize(rt, rows - 2, cols - 2);
96             wresize(term_win, rows - 2, cols - 2);
97             sigwinch = 0;
98             erase();
99         }
100
101         while ((ch = getch()) != ERR) {
102             madtty_keypress(rt, ch); /* pass the keypress for handling */
103             dirty = 1;
104         }
105
106         if (dirty) {
107             madtty_draw(rt, term_win, 0, 0);
108             wrefresh(term_win);
109             dirty = 0;
110         }
111     }
112
113     endwin();
114     return 0;
115 }