00a11a099d4c2d98d1eba162cd5fd1cdc7a7c479
[apps/madtty.git] / 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 <signal.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <sys/ioctl.h>
14 #include <sys/time.h>
15 #include <termios.h>
16 #include <time.h>
17
18 #include <madtty/madtty.h>
19
20 static unsigned char getout = 0;
21 static int screen_w, screen_h;
22 static WINDOW *term_win;
23
24 void handler(int signo)
25 {
26     switch (signo) {
27       case SIGCHLD:
28         getout = 1;
29         break;
30       case SIGWINCH:
31         break;
32     }
33 }
34
35 int main(void)
36 {
37     madtty_t *rt;
38     int dirty = 0;
39
40     signal(SIGCHLD, handler);
41     signal(SIGWINCH, handler);
42
43     madtty_initialize();
44     getmaxyx(stdscr, screen_h, screen_w);
45
46     /* create a window with a frame */
47     term_win = newwin(screen_h - 2, screen_w - 2, 1, 1);
48     rt = madtty_create(screen_h - 2, screen_w - 2);
49     {
50         const char *path = getenv("SHELL") ?: "/bin/sh";
51         const char *args[] = { path, "--login", NULL};
52
53         madtty_forkpty(rt, path, args);
54     }
55
56     /* keep reading keypresses from the user and passing them to the terminal;
57      * also, redraw the terminal to the window at each iteration */
58     while (!getout) {
59         fd_set rfds;
60         struct timeval tv = { 0, 1000 * 1000 / 50 };
61         int ch;
62
63         FD_ZERO(&rfds);
64         FD_SET(0, &rfds);
65         FD_SET(rt->pty, &rfds);
66
67         if (select(rt->pty + 1, &rfds, NULL, NULL, &tv) > 0) {
68             if (FD_ISSET(rt->pty, &rfds)) {
69                 madtty_process(rt);
70                 dirty = 1;
71             }
72         }
73
74         while ((ch = getch()) != ERR) {
75 #if 0
76             if (ch == KEY_F(1)) {
77                 struct winsize ws = {
78                     .ws_row = --rt->rows,
79                     .ws_col = --rt->cols,
80                 };
81
82                 erase();
83                 ioctl(rt->pty, TIOCSWINSZ, &ws);
84                 wresize(term_win, rt->rows, rt->cols);
85             }
86 #endif
87             madtty_keypress(rt, ch); /* pass the keypress for handling */
88             dirty = 1;
89         }
90
91         if (dirty) {
92             madtty_draw(rt, term_win, 0, 0);
93             wrefresh(term_win);
94             dirty = 0;
95         }
96     }
97
98     endwin();
99     return 0;
100 }