1 /*-
2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer as
10 * the first lines of this file unmodified.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #ifndef _DEV_SYSCONS_SCTERMVAR_H_
28 #define _DEV_SYSCONS_SCTERMVAR_H_
29
30 /*
31 * building blocks for terminal emulator modules.
32 */
33
34 static __inline void sc_term_ins_line(scr_stat *scp, int y, int n, int ch,
35 int attr, int tail);
36 static __inline void sc_term_del_line(scr_stat *scp, int y, int n, int ch,
37 int attr, int tail);
38 static __inline void sc_term_ins_char(scr_stat *scp, int n, int ch,
39 int attr);
40 static __inline void sc_term_del_char(scr_stat *scp, int n, int ch,
41 int attr);
42 static __inline void sc_term_col(scr_stat *scp, int n);
43 static __inline void sc_term_row(scr_stat *scp, int n);
44 static __inline void sc_term_up(scr_stat *scp, int n, int head);
45 static __inline void sc_term_down(scr_stat *scp, int n, int tail);
46 static __inline void sc_term_left(scr_stat *scp, int n);
47 static __inline void sc_term_right(scr_stat *scp, int n);
48 static __inline void sc_term_up_scroll(scr_stat *scp, int n, int ch,
49 int attr, int head, int tail);
50 static __inline void sc_term_down_scroll(scr_stat *scp, int n, int ch,
51 int attr, int head, int tail);
52 static __inline void sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr);
53 static __inline void sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr);
54 static __inline void sc_term_tab(scr_stat *scp, int n);
55 static __inline void sc_term_backtab(scr_stat *scp, int n);
56 static __inline void sc_term_respond(scr_stat *scp, u_char *s);
57 static __inline void sc_term_gen_print(scr_stat *scp, u_char **buf, int *len,
58 int attr);
59 static __inline void sc_term_gen_scroll(scr_stat *scp, int ch, int attr);
60
61 static __inline void
sc_term_ins_line(scr_stat * scp,int y,int n,int ch,int attr,int tail)62 sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
63 {
64 if (tail <= 0)
65 tail = scp->ysize;
66 if (n < 1)
67 n = 1;
68 if (n > tail - y)
69 n = tail - y;
70 sc_vtb_ins(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
71 mark_for_update(scp, y*scp->xsize);
72 mark_for_update(scp, scp->xsize*tail - 1);
73 }
74
75 static __inline void
sc_term_del_line(scr_stat * scp,int y,int n,int ch,int attr,int tail)76 sc_term_del_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
77 {
78 if (tail <= 0)
79 tail = scp->ysize;
80 if (n < 1)
81 n = 1;
82 if (n > tail - y)
83 n = tail - y;
84 sc_vtb_delete(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
85 mark_for_update(scp, y*scp->xsize);
86 mark_for_update(scp, scp->xsize*tail - 1);
87 }
88
89 static __inline void
sc_term_ins_char(scr_stat * scp,int n,int ch,int attr)90 sc_term_ins_char(scr_stat *scp, int n, int ch, int attr)
91 {
92 int count;
93
94 if (n < 1)
95 n = 1;
96 if (n > scp->xsize - scp->xpos)
97 n = scp->xsize - scp->xpos;
98 count = scp->xsize - (scp->xpos + n);
99 sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count);
100 sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr);
101 mark_for_update(scp, scp->cursor_pos);
102 mark_for_update(scp, scp->cursor_pos + n + count - 1);
103 }
104
105 static __inline void
sc_term_del_char(scr_stat * scp,int n,int ch,int attr)106 sc_term_del_char(scr_stat *scp, int n, int ch, int attr)
107 {
108 int count;
109
110 if (n < 1)
111 n = 1;
112 if (n > scp->xsize - scp->xpos)
113 n = scp->xsize - scp->xpos;
114 count = scp->xsize - (scp->xpos + n);
115 sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count);
116 sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n, ch, attr);
117 mark_for_update(scp, scp->cursor_pos);
118 mark_for_update(scp, scp->cursor_pos + n + count - 1);
119 }
120
121 static __inline void
sc_term_col(scr_stat * scp,int n)122 sc_term_col(scr_stat *scp, int n)
123 {
124 if (n < 1)
125 n = 1;
126 sc_move_cursor(scp, n - 1, scp->ypos);
127 }
128
129 static __inline void
sc_term_row(scr_stat * scp,int n)130 sc_term_row(scr_stat *scp, int n)
131 {
132 if (n < 1)
133 n = 1;
134 sc_move_cursor(scp, scp->xpos, n - 1);
135 }
136
137 static __inline void
sc_term_up(scr_stat * scp,int n,int head)138 sc_term_up(scr_stat *scp, int n, int head)
139 {
140 if (n < 1)
141 n = 1;
142 n = imin(n, scp->ypos - head);
143 if (n <= 0)
144 return;
145 sc_move_cursor(scp, scp->xpos, scp->ypos - n);
146 }
147
148 static __inline void
sc_term_down(scr_stat * scp,int n,int tail)149 sc_term_down(scr_stat *scp, int n, int tail)
150 {
151 if (tail <= 0)
152 tail = scp->ysize;
153 if (n < 1)
154 n = 1;
155 n = imin(n, tail - scp->ypos - 1);
156 if (n <= 0)
157 return;
158 sc_move_cursor(scp, scp->xpos, scp->ypos + n);
159 }
160
161 static __inline void
sc_term_left(scr_stat * scp,int n)162 sc_term_left(scr_stat *scp, int n)
163 {
164 if (n < 1)
165 n = 1;
166 sc_move_cursor(scp, scp->xpos - n, scp->ypos);
167 }
168
169 static __inline void
sc_term_right(scr_stat * scp,int n)170 sc_term_right(scr_stat *scp, int n)
171 {
172 if (n < 1)
173 n = 1;
174 sc_move_cursor(scp, scp->xpos + n, scp->ypos);
175 }
176
177 static __inline void
sc_term_up_scroll(scr_stat * scp,int n,int ch,int attr,int head,int tail)178 sc_term_up_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
179 {
180 if (tail <= 0)
181 tail = scp->ysize;
182 if (n < 1)
183 n = 1;
184 if (n <= scp->ypos - head) {
185 sc_move_cursor(scp, scp->xpos, scp->ypos - n);
186 } else {
187 sc_term_ins_line(scp, head, n - (scp->ypos - head),
188 ch, attr, tail);
189 sc_move_cursor(scp, scp->xpos, head);
190 }
191 }
192
193 static __inline void
sc_term_down_scroll(scr_stat * scp,int n,int ch,int attr,int head,int tail)194 sc_term_down_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
195 {
196 if (tail <= 0)
197 tail = scp->ysize;
198 if (n < 1)
199 n = 1;
200 if (n < tail - scp->ypos) {
201 sc_move_cursor(scp, scp->xpos, scp->ypos + n);
202 } else {
203 sc_term_del_line(scp, head, n - (tail - scp->ypos) + 1,
204 ch, attr, tail);
205 sc_move_cursor(scp, scp->xpos, tail - 1);
206 }
207 }
208
209 static __inline void
sc_term_clr_eos(scr_stat * scp,int n,int ch,int attr)210 sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr)
211 {
212 switch (n) {
213 case 0: /* clear form cursor to end of display */
214 sc_vtb_erase(&scp->vtb, scp->cursor_pos,
215 scp->xsize*scp->ysize - scp->cursor_pos,
216 ch, attr);
217 mark_for_update(scp, scp->cursor_pos);
218 mark_for_update(scp, scp->xsize*scp->ysize - 1);
219 sc_remove_cutmarking(scp);
220 break;
221 case 1: /* clear from beginning of display to cursor */
222 sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos + 1, ch, attr);
223 mark_for_update(scp, 0);
224 mark_for_update(scp, scp->cursor_pos);
225 sc_remove_cutmarking(scp);
226 break;
227 case 2: /* clear entire display */
228 sc_vtb_erase(&scp->vtb, 0, scp->xsize*scp->ysize, ch, attr);
229 mark_for_update(scp, 0);
230 mark_for_update(scp, scp->xsize*scp->ysize - 1);
231 sc_remove_cutmarking(scp);
232 break;
233 }
234 }
235
236 static __inline void
sc_term_clr_eol(scr_stat * scp,int n,int ch,int attr)237 sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr)
238 {
239 switch (n) {
240 case 0: /* clear form cursor to end of line */
241 sc_vtb_erase(&scp->vtb, scp->cursor_pos,
242 scp->xsize - scp->xpos, ch, attr);
243 mark_for_update(scp, scp->cursor_pos);
244 mark_for_update(scp, scp->cursor_pos +
245 scp->xsize - 1 - scp->xpos);
246 break;
247 case 1: /* clear from beginning of line to cursor */
248 sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
249 scp->xpos + 1, ch, attr);
250 mark_for_update(scp, scp->ypos*scp->xsize);
251 mark_for_update(scp, scp->cursor_pos);
252 break;
253 case 2: /* clear entire line */
254 sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
255 scp->xsize, ch, attr);
256 mark_for_update(scp, scp->ypos*scp->xsize);
257 mark_for_update(scp, (scp->ypos + 1)*scp->xsize - 1);
258 break;
259 }
260 }
261
262 static __inline void
sc_term_tab(scr_stat * scp,int n)263 sc_term_tab(scr_stat *scp, int n)
264 {
265 int i;
266
267 if (n < 1)
268 n = 1;
269 i = (scp->xpos & ~7) + 8*n;
270 if (i >= scp->xsize) {
271 if (scp->ypos >= scp->ysize - 1) {
272 scp->xpos = 0;
273 scp->ypos++;
274 scp->cursor_pos = scp->ypos*scp->xsize;
275 } else
276 sc_move_cursor(scp, 0, scp->ypos + 1);
277 } else
278 sc_move_cursor(scp, i, scp->ypos);
279 }
280
281 static __inline void
sc_term_backtab(scr_stat * scp,int n)282 sc_term_backtab(scr_stat *scp, int n)
283 {
284 int i;
285
286 if (n < 1)
287 n = 1;
288 if ((i = scp->xpos & ~7) == scp->xpos)
289 i -= 8*n;
290 else
291 i -= 8*(n - 1);
292 if (i < 0)
293 i = 0;
294 sc_move_cursor(scp, i, scp->ypos);
295 }
296
297 static __inline void
sc_term_respond(scr_stat * scp,u_char * s)298 sc_term_respond(scr_stat *scp, u_char *s)
299 {
300 sc_paste(scp, s, strlen(s)); /* XXX: not correct, don't use rmap */
301 }
302
303 static __inline void
sc_term_gen_print(scr_stat * scp,u_char ** buf,int * len,int attr)304 sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, int attr)
305 {
306 vm_offset_t p;
307 u_char *ptr;
308 u_char *map;
309 int cnt;
310 int l;
311 int i;
312
313 ptr = *buf;
314 l = *len;
315
316 if (PRINTABLE(*ptr)) {
317 p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
318 map = scp->sc->scr_map;
319
320 cnt = imin(l, scp->xsize - scp->xpos);
321 i = cnt;
322 do {
323 p = sc_vtb_putchar(&scp->vtb, p, map[*ptr], attr);
324 ++ptr;
325 --i;
326 } while ((i > 0) && PRINTABLE(*ptr));
327
328 l -= cnt - i;
329 mark_for_update(scp, scp->cursor_pos);
330 scp->cursor_pos += cnt - i;
331 mark_for_update(scp, scp->cursor_pos - 1);
332 scp->xpos += cnt - i;
333
334 if (scp->xpos >= scp->xsize) {
335 scp->xpos = 0;
336 scp->ypos++;
337 /* we may have to scroll the screen */
338 }
339 } else {
340 switch(*ptr) {
341 case 0x07:
342 sc_bell(scp, scp->bell_pitch, scp->bell_duration);
343 break;
344
345 case 0x08: /* non-destructive backspace */
346 /* XXX */
347 if (scp->cursor_pos > 0) {
348 #if 0
349 mark_for_update(scp, scp->cursor_pos);
350 scp->cursor_pos--;
351 mark_for_update(scp, scp->cursor_pos);
352 #else
353 scp->cursor_pos--;
354 #endif
355 if (scp->xpos > 0) {
356 scp->xpos--;
357 } else {
358 scp->xpos += scp->xsize - 1;
359 scp->ypos--;
360 }
361 }
362 break;
363
364 case 0x09: /* non-destructive tab */
365 sc_term_tab(scp, 1);
366 /* we may have to scroll the screen */
367 #if 0
368 mark_for_update(scp, scp->cursor_pos);
369 scp->cursor_pos += (8 - scp->xpos % 8u);
370 mark_for_update(scp, scp->cursor_pos);
371 scp->xpos += (8 - scp->xpos % 8u);
372 if (scp->xpos >= scp->xsize) {
373 scp->xpos = 0;
374 scp->ypos++;
375 }
376 #endif
377 break;
378
379 case 0x0a: /* newline, same pos */
380 #if 0
381 mark_for_update(scp, scp->cursor_pos);
382 scp->cursor_pos += scp->xsize;
383 mark_for_update(scp, scp->cursor_pos);
384 #else
385 scp->cursor_pos += scp->xsize;
386 /* we may have to scroll the screen */
387 #endif
388 scp->ypos++;
389 break;
390
391 case 0x0c: /* form feed, clears screen */
392 sc_clear_screen(scp);
393 break;
394
395 case 0x0d: /* return, return to pos 0 */
396 #if 0
397 mark_for_update(scp, scp->cursor_pos);
398 scp->cursor_pos -= scp->xpos;
399 mark_for_update(scp, scp->cursor_pos);
400 #else
401 scp->cursor_pos -= scp->xpos;
402 #endif
403 scp->xpos = 0;
404 break;
405 }
406 ptr++; l--;
407 }
408
409 *buf = ptr;
410 *len = l;
411 }
412
413 static __inline void
sc_term_gen_scroll(scr_stat * scp,int ch,int attr)414 sc_term_gen_scroll(scr_stat *scp, int ch, int attr)
415 {
416 /* do we have to scroll ?? */
417 if (scp->cursor_pos >= scp->ysize*scp->xsize) {
418 sc_remove_cutmarking(scp); /* XXX */
419 #ifndef SC_NO_HISTORY
420 if (scp->history != NULL)
421 sc_hist_save_one_line(scp, 0); /* XXX */
422 #endif
423 sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr);
424 scp->cursor_pos -= scp->xsize;
425 scp->ypos--;
426 mark_all(scp);
427 }
428 }
429
430 #endif /* _DEV_SYSCONS_SCTERMVAR_H_ */
431