| ---
tterm.c (3557B)
---
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include "vi.h"
10
11 static struct sbuf *term_sbuf;
12 static int rows, cols;
13 static struct termios termios;
14
15 void term_init(void)
16 {
17 struct winsize win;
18 struct termios newtermios;
19 tcgetattr(0, &termios);
20 newtermios = termios;
21 newtermios.c_lflag &= ~(ICANON | ISIG);
22 newtermios.c_lflag &= ~ECHO;
23 tcsetattr(0, TCSAFLUSH, &newtermios);
24 if (getenv("LINES"))
25 rows = atoi(getenv("LINES"));
26 if (getenv("COLUMNS"))
27 cols = atoi(getenv("COLUMNS"));
28 if (!ioctl(0, TIOCGWINSZ, &win)) {
29 cols = win.ws_col;
30 rows = win.ws_row;
31 }
32 cols = cols ? cols : 80;
33 rows = rows ? rows : 25;
34 term_str("\33[m");
35 }
36
37 void term_done(void)
38 {
39 term_commit();
40 tcsetattr(0, 0, &termios);
41 }
42
43 void term_suspend(void)
44 {
45 term_done();
46 kill(getpid(), SIGSTOP);
47 term_init();
48 }
49
50 void term_record(void)
51 {
52 if (!term_sbuf)
53 term_sbuf = sbuf_make();
54 }
55
56 void term_commit(void)
57 {
58 if (term_sbuf) {
59 write(1, sbuf_buf(term_sbuf), sbuf_len(term_sbuf));
60 sbuf_free(term_sbuf);
61 term_sbuf = NULL;
62 }
63 }
64
65 static void term_out(char *s)
66 {
67 if (term_sbuf)
68 sbuf_str(term_sbuf, s);
69 else
70 write(1, s, strlen(s));
71 }
72
73 void term_str(char *s)
74 {
75 term_out(s);
76 }
77
78 void term_chr(int ch)
79 {
80 char s[4] = {ch};
81 term_out(s);
82 }
83
84 void term_kill(void)
85 {
86 term_out("\33[K");
87 }
88
89 void term_room(int n)
90 {
91 char cmd[16];
92 if (n < 0)
93 sprintf(cmd, "\33[%dM", -n);
94 if (n > 0)
95 sprintf(cmd, "\33[%dL", n);
96 if (n)
97 term_out(cmd);
98 }
99
100 void term_pos(int r, int c)
101 {
102 char buf[32] = "\r";
103 if (c < 0)
104 c = 0;
105 if (c >= xcols)
106 c = cols - 1;
107 if (r < 0)
108 sprintf(buf, "\r\33[%d%c", abs(c), c > 0 ? 'C' : 'D');
109 else
110 sprintf(buf, "\33[%d;%dH", r + 1, c + 1);
111 term_out(buf);
112 }
113
114 int term_rows(void)
115 {
116 return rows;
117 }
118
119 int term_cols(void)
120 {
121 return cols;
122 }
123
124 static char ibuf[4096]; /* input character buffer */
125 static char icmd[4096]; /* read after the last term_cmd() */
126 static int ibuf_pos, ibuf_cnt; /* ibuf[] position and length */
127 static int icmd_pos; /* icmd[] position */
128
129 /* read s before reading from the terminal */
130 void term_push(char *s, int n)
131 {
132 n = MIN(n, sizeof(ibuf) - ibuf_cnt);
133 memcpy(ibuf + ibuf_cnt, s, n);
134 ibuf_cnt += n;
135 }
136
137 /* return a static buffer containing inputs read since the last term_cmd() */
138 char *term_cmd(int *n)
139 {
140 *n = icmd_pos;
141 icmd_pos = 0;
142 return icmd;
143 }
144
145 int term_read(void)
146 {
147 struct pollfd ufds[1];
148 int n, c;
149 if (ibuf_pos >= ibuf_cnt) {
150 ufds[0].fd = 0;
151 ufds[0].events = POLLIN;
152 if (poll(ufds, 1, -1) <= 0)
153 return -1;
154 /* read a single input character */
155 if ((n = read(0, ibuf, 1)) <= 0)
156 return -1;
157 ibuf_cnt = n;
158 ibuf_pos = 0;
159 }
160 c = ibuf_pos < ibuf_cnt ? (unsigned char) ibuf[ibuf_pos++] : -1;
161 if (icmd_pos < sizeof(icmd))
162 icmd[icmd_pos++] = c;
163 return c;
164 }
165
166 /* return a static string that changes text attributes from old to att */
167 char *term_att(int att, int old)
168 {
169 static char buf[128];
170 char *s = buf;
171 int fg = SYN_FG(att);
172 int bg = SYN_BG(att);
173 if (att == old)
174 return "";
175 s += sprintf(s, "\33[");
176 if (att & SYN_BD)
177 s += sprintf(s, ";1");
178 if (att & SYN_IT)
179 s += sprintf(s, ";3");
180 else if (att & SYN_RV)
181 s += sprintf(s, ";7");
182 if (SYN_FGSET(att)) {
183 if ((fg & 0xff) < 8)
184 s += sprintf(s, ";%d", 30 + (fg & 0xff));
185 else
186 s += sprintf(s, ";38;5;%d", (fg & 0xff));
187 }
188 if (SYN_BGSET(att)) {
189 if ((bg & 0xff) < 8)
190 s += sprintf(s, ";%d", 40 + (bg & 0xff));
191 else
192 s += sprintf(s, ";48;5;%d", (bg & 0xff));
193 }
194 s += sprintf(s, "m");
195 return buf;
196 } |