sctermvar.h revision 105584
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 * $FreeBSD: head/sys/dev/syscons/sctermvar.h 105584 2002-10-20 22:50:13Z robert $
27 */
28
29#ifndef _DEV_SYSCONS_SCTERMVAR_H_
30#define _DEV_SYSCONS_SCTERMVAR_H_
31
32/*
33 * building blocks for terminal emulator modules.
34 */
35
36static __inline void	sc_term_ins_line(scr_stat *scp, int y, int n, int ch,
37					 int attr, int tail);
38static __inline void	sc_term_del_line(scr_stat *scp, int y, int n, int ch,
39					 int attr, int tail);
40static __inline void	sc_term_ins_char(scr_stat *scp, int n, int ch,
41					 int attr);
42static __inline void	sc_term_del_char(scr_stat *scp, int n, int ch,
43					 int attr);
44static __inline void	sc_term_col(scr_stat *scp, int n);
45static __inline void	sc_term_row(scr_stat *scp, int n);
46static __inline void	sc_term_up(scr_stat *scp, int n, int head);
47static __inline void	sc_term_down(scr_stat *scp, int n, int tail);
48static __inline void	sc_term_left(scr_stat *scp, int n);
49static __inline void	sc_term_right(scr_stat *scp, int n);
50static __inline void	sc_term_up_scroll(scr_stat *scp, int n, int ch,
51					  int attr, int head, int tail);
52static __inline void	sc_term_down_scroll(scr_stat *scp, int n, int ch,
53					    int attr, int head, int tail);
54static __inline void	sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr);
55static __inline void	sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr);
56static __inline void	sc_term_tab(scr_stat *scp, int n);
57static __inline void	sc_term_backtab(scr_stat *scp, int n);
58static __inline void	sc_term_respond(scr_stat *scp, u_char *s);
59static __inline void	sc_term_gen_print(scr_stat *scp, u_char **buf, int *len,
60					  int attr);
61static __inline void	sc_term_gen_scroll(scr_stat *scp, int ch, int attr);
62
63static __inline void
64sc_term_ins_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
65{
66	if (tail <= 0)
67		tail = scp->ysize;
68	if (n < 1)
69		n = 1;
70	if (n > tail - y)
71		n = tail - y;
72	sc_vtb_ins(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
73	mark_for_update(scp, y*scp->xsize);
74	mark_for_update(scp, scp->xsize*tail - 1);
75}
76
77static __inline void
78sc_term_del_line(scr_stat *scp, int y, int n, int ch, int attr, int tail)
79{
80	if (tail <= 0)
81		tail = scp->ysize;
82	if (n < 1)
83		n = 1;
84	if (n > tail - y)
85		n = tail - y;
86	sc_vtb_delete(&scp->vtb, y*scp->xsize, n*scp->xsize, ch, attr);
87	mark_for_update(scp, y*scp->xsize);
88	mark_for_update(scp, scp->xsize*tail - 1);
89}
90
91static __inline void
92sc_term_ins_char(scr_stat *scp, int n, int ch, int attr)
93{
94	int count;
95
96	if (n < 1)
97		n = 1;
98	if (n > scp->xsize - scp->xpos)
99		n = scp->xsize - scp->xpos;
100	count = scp->xsize - (scp->xpos + n);
101	sc_vtb_move(&scp->vtb, scp->cursor_pos, scp->cursor_pos + n, count);
102	sc_vtb_erase(&scp->vtb, scp->cursor_pos, n, ch, attr);
103	mark_for_update(scp, scp->cursor_pos);
104	mark_for_update(scp, scp->cursor_pos + n + count - 1);
105}
106
107static __inline void
108sc_term_del_char(scr_stat *scp, int n, int ch, int attr)
109{
110	int count;
111
112	if (n < 1)
113		n = 1;
114	if (n > scp->xsize - scp->xpos)
115		n = scp->xsize - scp->xpos;
116	count = scp->xsize - (scp->xpos + n);
117	sc_vtb_move(&scp->vtb, scp->cursor_pos + n, scp->cursor_pos, count);
118	sc_vtb_erase(&scp->vtb, scp->cursor_pos + count, n, ch, attr);
119	mark_for_update(scp, scp->cursor_pos);
120	mark_for_update(scp, scp->cursor_pos + n + count - 1);
121}
122
123static __inline void
124sc_term_col(scr_stat *scp, int n)
125{
126	if (n < 1)
127		n = 1;
128	sc_move_cursor(scp, n - 1, scp->ypos);
129}
130
131static __inline void
132sc_term_row(scr_stat *scp, int n)
133{
134	if (n < 1)
135		n = 1;
136	sc_move_cursor(scp, scp->xpos, n - 1);
137}
138
139static __inline void
140sc_term_up(scr_stat *scp, int n, int head)
141{
142	if (n < 1)
143		n = 1;
144	n = imin(n, scp->ypos - head);
145	if (n <= 0)
146		return;
147	sc_move_cursor(scp, scp->xpos, scp->ypos - n);
148}
149
150static __inline void
151sc_term_down(scr_stat *scp, int n, int tail)
152{
153	if (tail <= 0)
154		tail = scp->ysize;
155	if (n < 1)
156		n = 1;
157	n = imin(n, tail - scp->ypos - 1);
158	if (n <= 0)
159		return;
160	sc_move_cursor(scp, scp->xpos, scp->ypos + n);
161}
162
163static __inline void
164sc_term_left(scr_stat *scp, int n)
165{
166	if (n < 1)
167		n = 1;
168	sc_move_cursor(scp, scp->xpos - n, scp->ypos);
169}
170
171static __inline void
172sc_term_right(scr_stat *scp, int n)
173{
174	if (n < 1)
175		n = 1;
176	sc_move_cursor(scp, scp->xpos + n, scp->ypos);
177}
178
179static __inline void
180sc_term_up_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
181{
182	if (tail <= 0)
183		tail = scp->ysize;
184	if (n < 1)
185		n = 1;
186	if (n <= scp->ypos - head) {
187		sc_move_cursor(scp, scp->xpos, scp->ypos - n);
188	} else {
189		sc_term_ins_line(scp, head, n - (scp->ypos - head),
190				 ch, attr, tail);
191		sc_move_cursor(scp, scp->xpos, head);
192	}
193}
194
195static __inline void
196sc_term_down_scroll(scr_stat *scp, int n, int ch, int attr, int head, int tail)
197{
198	if (tail <= 0)
199		tail = scp->ysize;
200	if (n < 1)
201		n = 1;
202	if (n < tail - scp->ypos) {
203		sc_move_cursor(scp, scp->xpos, scp->ypos + n);
204	} else {
205		sc_term_del_line(scp, head, n - (tail - scp->ypos) + 1,
206				 ch, attr, tail);
207		sc_move_cursor(scp, scp->xpos, tail - 1);
208	}
209}
210
211static __inline void
212sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr)
213{
214	switch (n) {
215	case 0: /* clear form cursor to end of display */
216		sc_vtb_erase(&scp->vtb, scp->cursor_pos,
217			     scp->xsize*scp->ysize - scp->cursor_pos,
218			     ch, attr);
219		mark_for_update(scp, scp->cursor_pos);
220		mark_for_update(scp, scp->xsize*scp->ysize - 1);
221		sc_remove_cutmarking(scp);
222		break;
223	case 1: /* clear from beginning of display to cursor */
224		sc_vtb_erase(&scp->vtb, 0, scp->cursor_pos + 1, ch, attr);
225		mark_for_update(scp, 0);
226		mark_for_update(scp, scp->cursor_pos);
227		sc_remove_cutmarking(scp);
228		break;
229	case 2: /* clear entire display */
230		sc_vtb_erase(&scp->vtb, 0, scp->xsize*scp->ysize, ch, attr);
231		mark_for_update(scp, 0);
232		mark_for_update(scp, scp->xsize*scp->ysize - 1);
233		sc_remove_cutmarking(scp);
234		break;
235	}
236}
237
238static __inline void
239sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr)
240{
241	switch (n) {
242	case 0: /* clear form cursor to end of line */
243		sc_vtb_erase(&scp->vtb, scp->cursor_pos,
244			     scp->xsize - scp->xpos, ch, attr);
245		mark_for_update(scp, scp->cursor_pos);
246		mark_for_update(scp, scp->cursor_pos +
247				scp->xsize - 1 - scp->xpos);
248		break;
249	case 1: /* clear from beginning of line to cursor */
250		sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
251			     scp->xpos + 1, ch, attr);
252		mark_for_update(scp, scp->ypos*scp->xsize);
253		mark_for_update(scp, scp->cursor_pos);
254		break;
255	case 2: /* clear entire line */
256		sc_vtb_erase(&scp->vtb, scp->cursor_pos - scp->xpos,
257			     scp->xsize, ch, attr);
258		mark_for_update(scp, scp->ypos*scp->xsize);
259		mark_for_update(scp, (scp->ypos + 1)*scp->xsize - 1);
260		break;
261	}
262}
263
264static __inline void
265sc_term_tab(scr_stat *scp, int n)
266{
267	int i;
268
269	if (n < 1)
270		n = 1;
271	i = (scp->xpos & ~7) + 8*n;
272	if (i >= scp->xsize) {
273		if (scp->ypos >= scp->ysize - 1) {
274			scp->xpos = 0;
275			scp->ypos++;
276			scp->cursor_pos = scp->ypos*scp->xsize;
277		} else
278			sc_move_cursor(scp, 0, scp->ypos + 1);
279	} else
280		sc_move_cursor(scp, i, scp->ypos);
281}
282
283static __inline void
284sc_term_backtab(scr_stat *scp, int n)
285{
286	int i;
287
288	if (n < 1)
289		n = 1;
290	if ((i = scp->xpos & ~7) == scp->xpos)
291		i -= 8*n;
292	else
293		i -= 8*(n - 1);
294	if (i < 0)
295		i = 0;
296	sc_move_cursor(scp, i, scp->ypos);
297}
298
299static __inline void
300sc_term_respond(scr_stat *scp, u_char *s)
301{
302	sc_paste(scp, s, strlen(s));	/* XXX: not correct, don't use rmap */
303}
304
305static __inline void
306sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, int attr)
307{
308	vm_offset_t p;
309	u_char *ptr;
310	u_char *map;
311 	int cnt;
312	int l;
313	int i;
314
315	ptr = *buf;
316	l = *len;
317
318	if (PRINTABLE(*ptr)) {
319		p = sc_vtb_pointer(&scp->vtb, scp->cursor_pos);
320		map = scp->sc->scr_map;
321
322		cnt = imin(l, scp->xsize - scp->xpos);
323		i = cnt;
324		do {
325			p = sc_vtb_putchar(&scp->vtb, p, map[*ptr], attr);
326			++ptr;
327			--i;
328		} while ((i > 0) && PRINTABLE(*ptr));
329
330		l -= cnt - i;
331		mark_for_update(scp, scp->cursor_pos);
332		scp->cursor_pos += cnt - i;
333		mark_for_update(scp, scp->cursor_pos - 1);
334		scp->xpos += cnt - i;
335
336		if (scp->xpos >= scp->xsize) {
337			scp->xpos = 0;
338			scp->ypos++;
339			/* we may have to scroll the screen */
340		}
341	} else {
342		switch(*ptr) {
343		case 0x07:
344			sc_bell(scp, scp->bell_pitch, scp->bell_duration);
345			break;
346
347		case 0x08:	/* non-destructive backspace */
348			/* XXX */
349			if (scp->cursor_pos > 0) {
350#if 0
351				mark_for_update(scp, scp->cursor_pos);
352				scp->cursor_pos--;
353				mark_for_update(scp, scp->cursor_pos);
354#else
355				scp->cursor_pos--;
356#endif
357				if (scp->xpos > 0) {
358					scp->xpos--;
359				} else {
360					scp->xpos += scp->xsize - 1;
361					scp->ypos--;
362				}
363			}
364			break;
365
366		case 0x09:	/* non-destructive tab */
367			sc_term_tab(scp, 1);
368			/* we may have to scroll the screen */
369#if 0
370			mark_for_update(scp, scp->cursor_pos);
371			scp->cursor_pos += (8 - scp->xpos % 8u);
372			mark_for_update(scp, scp->cursor_pos);
373			scp->xpos += (8 - scp->xpos % 8u);
374			if (scp->xpos >= scp->xsize) {
375				scp->xpos = 0;
376				scp->ypos++;
377			}
378#endif
379			break;
380
381		case 0x0a:	/* newline, same pos */
382#if 0
383			mark_for_update(scp, scp->cursor_pos);
384			scp->cursor_pos += scp->xsize;
385			mark_for_update(scp, scp->cursor_pos);
386#else
387			scp->cursor_pos += scp->xsize;
388			/* we may have to scroll the screen */
389#endif
390			scp->ypos++;
391			break;
392
393		case 0x0c:	/* form feed, clears screen */
394			sc_clear_screen(scp);
395			break;
396
397		case 0x0d:	/* return, return to pos 0 */
398#if 0
399			mark_for_update(scp, scp->cursor_pos);
400			scp->cursor_pos -= scp->xpos;
401			mark_for_update(scp, scp->cursor_pos);
402#else
403			scp->cursor_pos -= scp->xpos;
404#endif
405			scp->xpos = 0;
406			break;
407		}
408		ptr++; l--;
409	}
410
411	*buf = ptr;
412	*len = l;
413}
414
415static __inline void
416sc_term_gen_scroll(scr_stat *scp, int ch, int attr)
417{
418	/* do we have to scroll ?? */
419	if (scp->cursor_pos >= scp->ysize*scp->xsize) {
420		sc_remove_cutmarking(scp);		/* XXX */
421#ifndef SC_NO_HISTORY
422		if (scp->history != NULL)
423			sc_hist_save_one_line(scp, 0);	/* XXX */
424#endif
425		sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr);
426		scp->cursor_pos -= scp->xsize;
427		scp->ypos--;
428		mark_all(scp);
429	}
430}
431
432#endif /* _DEV_SYSCONS_SCTERMVAR_H_ */
433