start using git
[fbpad.git] / fbpterm.c
blob09ab2e6357cabefea4606bda5efe6856aa7d3c6a
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <poll.h>
5 #include <unistd.h>
6 #include <ctype.h>
7 #include <pty.h>
8 #include "pad.h"
9 #include "util.h"
11 #define SHELL "/bin/bash"
12 #define ESC 27
13 #define MAXESCARGS 32
14 #define FGCOLOR 0
15 #define BGCOLOR 7
17 static pid_t pid;
18 static int fd;
20 static void execshell(void)
22 if ((pid = forkpty(&fd, NULL, NULL, NULL)) == -1)
23 xerror("failed to create a pty");
24 if (!pid) {
25 setenv("TERM", "linux", 1);
26 execl(SHELL, SHELL, NULL);
27 exit(1);
31 static void setsize(void)
33 struct winsize size;
34 size.ws_col = pad_cols();
35 size.ws_row = pad_rows();
36 size.ws_xpixel = 0;
37 size.ws_ypixel = 0;
38 ioctl(fd, TIOCSWINSZ, &size);
41 static int readpty(void)
43 char b;
44 if (read(fd, &b, 1) > 0)
45 return (int) b;
46 return -1;
49 static int readchar(void)
51 char b;
52 if (read(STDIN_FILENO, &b, 1) > 0)
53 return (int) b;
54 return -1;
57 static void writechar(int c)
59 unsigned char b = (unsigned char) c;
60 write(fd, &b, 1);
63 static void writepty(int c)
65 pad_add(c);
68 static void setmode(int m)
70 if (m == 0) {
71 pad_fg(FGCOLOR);
72 pad_bg(BGCOLOR);
74 if (m >= 30 && m <= 37)
75 pad_fg(m - 30);
76 if (m >= 40 && m <= 47)
77 pad_bg(m - 40);
80 static void kill_line(void)
82 int i;
83 for (i = pad_col(); i < pad_cols(); i++)
84 pad_put(' ', pad_row(), i);
87 static void escape(void)
89 int args[MAXESCARGS] = {0};
90 int i;
91 int n = -1;
92 int c = readpty();
93 if (c != '[') {
94 writepty(ESC);
95 writepty(c);
96 return;
98 for (i = 0; i < ARRAY_SIZE(args) && !isalpha(c); i++) {
99 int arg = 0;
100 while (isdigit((c = readpty())))
101 arg = arg * 10 + (c - '0');
102 args[n++] = arg;
104 switch (c) {
105 case 'H':
106 case 'f':
107 pad_move(args[0], args[1]);
108 break;
109 case 'J':
110 pad_blank();
111 pad_move(0, 0);
112 break;
113 case 'A':
114 pad_move(pad_row() - args[0], pad_col());
115 break;
116 case 'B':
117 pad_move(pad_row() + args[0], pad_col());
118 break;
119 case 'C':
120 pad_move(pad_row(), pad_col() + args[0]);
121 break;
122 case 'D':
123 pad_move(pad_row(), pad_col() - args[0]);
124 break;
125 case 'K':
126 kill_line();
127 break;
128 case 'm':
129 for (i = 0; i < n; i++)
130 setmode(args[i]);
131 if (!n)
132 setmode(0);
133 break;
134 default:
135 printf("unknown escapse <%c>\n", c);
139 static void shcmds(void)
141 int c = readpty();
142 if (c == ESC)
143 escape();
144 else
145 writepty(c);
148 static void directkey(void)
150 int c = readchar();
151 writechar(c);
154 static void mainloop(void)
156 struct pollfd ufds[2];
157 int rv;
158 struct termios oldtermios, termios;
159 tcgetattr(STDIN_FILENO, &termios);
160 oldtermios = termios;
161 cfmakeraw(&termios);
162 tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios);
163 ufds[0].fd = STDIN_FILENO;
164 ufds[0].events = POLLIN;
165 ufds[1].fd = fd;
166 ufds[1].events = POLLIN;
167 while ((rv = poll(ufds, 2, 1000)) != -1) {
168 if ((ufds[0].revents | ufds[1].revents) &
169 (POLLHUP | POLLERR | POLLNVAL))
170 break;
171 if (ufds[0].revents & POLLIN)
172 directkey();
173 if (ufds[1].revents & POLLIN)
174 shcmds();
176 tcsetattr(STDIN_FILENO, 0, &oldtermios);
179 int main(void)
181 execshell();
182 pad_init();
183 setsize();
184 setmode(0);
185 pad_blank();
186 mainloop();
187 pad_free();
188 return 0;