14 #define SQRADDR(r, c) (&screen[(r) * pad_cols() + (c)])
16 #define MODE_NOCURSOR 0x01
17 #define MODE_NOWRAP 0x02
18 #define MODE_ORIGIN 0x04
19 #define MODE_NOAUTOCR 0x08
20 #define BIT_SET(i, b, val) ((val) ? ((i) | (b)) : ((i) & ~(b)))
26 static struct square screen
[MAXCHARS
];
29 static struct miscterm_state saved
;
31 static int origin(void)
33 return mode
& MODE_ORIGIN
;
36 static void setsize(void)
39 size
.ws_col
= pad_cols();
40 size
.ws_row
= pad_rows();
43 ioctl(fd
, TIOCSWINSZ
, &size
);
46 static int readpty(void)
49 if (read(fd
, &b
, 1) > 0)
54 static void term_show(int r
, int c
, int cursor
)
56 struct square
*sqr
= SQRADDR(r
, c
);
57 int fgcolor
= sqr
->c
? sqr
->fg
: fg
;
58 int bgcolor
= sqr
->c
? sqr
->bg
: bg
;
59 if (cursor
&& !(mode
& MODE_NOCURSOR
)) {
64 pad_put(sqr
->c
, r
, c
, fgcolor
, bgcolor
);
67 void term_put(int ch
, int r
, int c
)
69 struct square
*sqr
= SQRADDR(r
, c
);
76 static void empty_rows(int sr
, int er
)
78 memset(SQRADDR(sr
, 0), 0, (er
- sr
) * sizeof(screen
[0]) * pad_cols());
81 static void draw_rows(int sr
, int er
)
84 for (i
= sr
* pad_cols(); i
< er
* pad_cols(); i
++)
85 term_show(i
/ pad_cols(), i
% pad_cols(), 0);
88 static void blank_rows(int sr
, int er
)
92 term_show(row
, col
, 1);
95 static void scroll_screen(int sr
, int nr
, int n
)
97 term_show(row
, col
, 0);
98 memmove(SQRADDR(sr
+ n
, 0), SQRADDR(sr
, 0),
99 nr
* pad_cols() * sizeof(screen
[0]));
101 empty_rows(sr
, sr
+ n
);
103 empty_rows(sr
+ nr
+ n
, sr
+ nr
);
104 /* draw_rows(MIN(sr, sr + n), MAX(sr + nr, sr + nr +n)); */
105 pad_scroll(sr
, nr
, n
, bg
);
106 term_show(row
, col
, 1);
109 static void insert_lines(int n
)
111 int sr
= MAX(top
, row
);
112 int nr
= bot
- row
- n
;
114 scroll_screen(sr
, nr
, n
);
117 static void delete_lines(int n
)
119 int r
= MAX(top
, row
);
121 int nr
= bot
- r
- n
;
123 scroll_screen(sr
, nr
, -n
);
126 static void move_cursor(int r
, int c
)
128 term_show(row
, col
, 0);
129 row
= MAX(origin() ? top
: 0, MIN(r
, (origin() ? bot
: pad_rows()) - 1));
130 col
= MAX(0, MIN(c
, pad_cols() - 1));
131 term_show(row
, col
, 1);
134 static void advance(int dr
, int dc
, int scrl
)
138 int t
= origin() ? top
: 0;
139 int b
= origin() ? bot
: pad_rows();
140 if (c
>= pad_cols()) {
141 if (!scrl
|| (mode
& MODE_NOWRAP
)) {
148 if (r
>= b
&& scrl
) {
150 int nr
= (b
- t
) + n
;
151 scroll_screen(-n
, nr
, n
);
155 int nr
= (b
- t
) - n
;
156 scroll_screen(t
, nr
, n
);
158 r
= MIN(b
- 1, MAX(t
, r
));
159 move_cursor(r
, MAX(0, c
));
162 void term_send(int c
)
164 unsigned char b
= (unsigned char) c
;
169 void term_sendstr(char *s
)
172 write(fd
, s
, strlen(s
));
175 static void setmode(int m
)
188 if (m
>= 30 && m
<= 37)
190 if (m
>= 40 && m
<= 47)
194 static void kill_chars(int sc
, int ec
)
197 memset(SQRADDR(row
, sc
), 0, (ec
- sc
) * sizeof(screen
[0]));
198 for (i
= sc
; i
< ec
; i
++)
199 term_show(row
, i
, 0);
200 move_cursor(row
, col
);
203 static void move_chars(int sc
, int nc
, int n
)
206 term_show(row
, col
, 0);
207 memmove(SQRADDR(row
, sc
+ n
), SQRADDR(row
, sc
),
208 nc
* sizeof(screen
[0]));
210 memset(SQRADDR(row
, sc
), 0, n
* sizeof(screen
[0]));
212 memset(SQRADDR(row
, pad_rows() + n
), 0, -n
* sizeof(screen
[0]));
213 for (i
= MIN(sc
, sc
+ n
); i
< pad_cols(); i
++)
214 term_show(row
, i
, 0);
215 term_show(row
, col
, 1);
218 static void delete_chars(int n
)
220 move_chars(col
+ n
, pad_cols(), -n
);
223 static void insert_chars(int n
)
225 int nc
= pad_cols() - col
- n
;
226 move_chars(col
, nc
, n
);
229 void term_blank(void)
232 memset(screen
, 0, sizeof(screen
));
235 static void ctlseq(void);
241 void term_exec(char *cmd
)
243 if ((pid
= forkpty(&fd
, NULL
, NULL
, NULL
)) == -1)
244 xerror("failed to create a pty");
246 setenv("TERM", "linux", 1);
247 execl(cmd
, cmd
, NULL
);
255 static void misc_save(struct miscterm_state
*state
)
266 static void misc_load(struct miscterm_state
*state
)
277 void term_save(struct term_state
*state
)
281 memcpy(state
->screen
, screen
,
282 pad_rows() * pad_cols() * sizeof(screen
[0]));
284 misc_save(&state
->cur
);
287 void term_load(struct term_state
*state
)
291 misc_load(&state
->cur
);
293 memcpy(screen
, state
->screen
,
294 pad_rows() * pad_cols() * sizeof(screen
[0]));
295 draw_rows(0, pad_rows());
296 term_show(row
, col
, 1);
325 void set_region(int t
, int b
)
327 top
= MIN(pad_rows(), MAX(0, t
- 1));
328 bot
= MIN(pad_rows(), MAX(0, b
? b
: pad_rows()));