11 static struct sbuf
*term_sbuf
; /* output buffer if not NULL */
12 static int rows
, cols
; /* number of terminal rows and columns */
13 static int win_beg
, win_rows
; /* active window rows */
14 static struct termios termios
;
19 struct termios newtermios
;
20 tcgetattr(0, &termios
);
22 newtermios
.c_lflag
&= ~(ICANON
| ISIG
);
23 newtermios
.c_lflag
&= ~ECHO
;
24 tcsetattr(0, TCSAFLUSH
, &newtermios
);
26 rows
= atoi(getenv("LINES"));
27 if (getenv("COLUMNS"))
28 cols
= atoi(getenv("COLUMNS"));
29 if (!ioctl(0, TIOCGWINSZ
, &win
)) {
33 cols
= cols
? cols
: 80;
34 rows
= rows
? rows
: 25;
36 term_window(win_beg
, win_rows
> 0 ? win_rows
: rows
);
39 void term_window(int row
, int cnt
)
44 if (row
== 0 && win_rows
== rows
) {
47 sprintf(cmd
, "\33[%d;%dr", win_beg
+ 1, win_beg
+ win_rows
);
55 term_pos(rows
- 1, 0);
58 tcsetattr(0, 0, &termios
);
61 void term_suspend(void)
68 void term_record(void)
71 term_sbuf
= sbuf_make();
74 void term_commit(void)
77 write(1, sbuf_buf(term_sbuf
), sbuf_len(term_sbuf
));
83 static void term_out(char *s
)
86 sbuf_str(term_sbuf
, s
);
88 write(1, s
, strlen(s
));
91 void term_str(char *s
)
107 void term_room(int n
)
111 sprintf(cmd
, "\33[%dM", -n
);
113 sprintf(cmd
, "\33[%dL", n
);
118 void term_pos(int r
, int c
)
123 if (c
>= term_cols())
126 sprintf(buf
, "\r\33[%d%c", abs(c
), c
> 0 ? 'C' : 'D');
128 sprintf(buf
, "\33[%d;%dH", win_beg
+ r
+ 1, c
+ 1);
147 static char ibuf
[4096]; /* input character buffer */
148 static char icmd
[4096]; /* read after the last term_cmd() */
149 static int ibuf_pos
, ibuf_cnt
; /* ibuf[] position and length */
150 static int icmd_pos
; /* icmd[] position */
152 /* read s before reading from the terminal */
153 void term_push(char *s
, int n
)
155 n
= MIN(n
, sizeof(ibuf
) - ibuf_cnt
);
156 memcpy(ibuf
+ ibuf_cnt
, s
, n
);
160 /* return a static buffer containing inputs read since the last term_cmd() */
161 char *term_cmd(int *n
)
170 struct pollfd ufds
[1];
172 if (ibuf_pos
>= ibuf_cnt
) {
174 ufds
[0].events
= POLLIN
;
175 if (poll(ufds
, 1, -1) <= 0)
177 /* read a single input character */
178 if ((n
= read(0, ibuf
, 1)) <= 0)
183 c
= ibuf_pos
< ibuf_cnt
? (unsigned char) ibuf
[ibuf_pos
++] : -1;
184 if (icmd_pos
< sizeof(icmd
))
185 icmd
[icmd_pos
++] = c
;
189 /* return a static string that changes text attributes from old to att */
190 char *term_seqattr(int att
, int old
)
192 static char buf
[128];
194 int fg
= SYN_FG(att
);
195 int bg
= SYN_BG(att
);
198 s
+= sprintf(s
, "\33[");
200 s
+= sprintf(s
, ";1");
202 s
+= sprintf(s
, ";3");
203 else if (att
& SYN_RV
)
204 s
+= sprintf(s
, ";7");
205 if (SYN_FGSET(att
)) {
207 s
+= sprintf(s
, ";%d", 30 + (fg
& 0xff));
209 s
+= sprintf(s
, ";38;5;%d", (fg
& 0xff));
211 if (SYN_BGSET(att
)) {
213 s
+= sprintf(s
, ";%d", 40 + (bg
& 0xff));
215 s
+= sprintf(s
, ";48;5;%d", (bg
& 0xff));
217 s
+= sprintf(s
, "m");
221 char *term_seqkill(void)