Initial import from FreeBSD RELENG_4:
[games.git] / sys / dev / misc / syscons / sctermvar.h
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: src/sys/dev/syscons/sctermvar.h,v 1.1.2.2 2001/07/28 12:51:47 yokota Exp $
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
36 static __inline void    sc_term_ins_line(scr_stat *scp, int y, int n, int ch,
37                                          int attr, int tail);
38 static __inline void    sc_term_del_line(scr_stat *scp, int y, int n, int ch,
39                                          int attr, int tail);
40 static __inline void    sc_term_ins_char(scr_stat *scp, int n, int ch,
41                                          int attr);
42 static __inline void    sc_term_del_char(scr_stat *scp, int n, int ch,
43                                          int attr);
44 static __inline void    sc_term_col(scr_stat *scp, int n);
45 static __inline void    sc_term_row(scr_stat *scp, int n);
46 static __inline void    sc_term_up(scr_stat *scp, int n, int head);
47 static __inline void    sc_term_down(scr_stat *scp, int n, int tail);
48 static __inline void    sc_term_left(scr_stat *scp, int n);
49 static __inline void    sc_term_right(scr_stat *scp, int n);
50 static __inline void    sc_term_up_scroll(scr_stat *scp, int n, int ch,
51                                           int attr, int head, int tail);
52 static __inline void    sc_term_down_scroll(scr_stat *scp, int n, int ch,
53                                             int attr, int head, int tail);
54 static __inline void    sc_term_clr_eos(scr_stat *scp, int n, int ch, int attr);
55 static __inline void    sc_term_clr_eol(scr_stat *scp, int n, int ch, int attr);
56 static __inline void    sc_term_tab(scr_stat *scp, int n);
57 static __inline void    sc_term_backtab(scr_stat *scp, int n);
58 static __inline void    sc_term_respond(scr_stat *scp, u_char *s);
59 static __inline void    sc_term_gen_print(scr_stat *scp, u_char **buf, int *len,
60                                           int attr);
61 static __inline void    sc_term_gen_scroll(scr_stat *scp, int ch, int attr);
62
63 static __inline void
64 sc_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
77 static __inline void
78 sc_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
91 static __inline void
92 sc_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
107 static __inline void
108 sc_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
123 static __inline void
124 sc_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
131 static __inline void
132 sc_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
139 static __inline void
140 sc_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
150 static __inline void
151 sc_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
163 static __inline void
164 sc_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
171 static __inline void
172 sc_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
179 static __inline void
180 sc_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
195 static __inline void
196 sc_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
211 static __inline void
212 sc_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
238 static __inline void
239 sc_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
264 static __inline void
265 sc_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
283 static __inline void
284 sc_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
299 static __inline void
300 sc_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
305 static __inline void
306 sc_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                         /*
326                          * gcc-2.6.3 generates poor (un)sign extension code.
327                          * Casting the pointers in the following to volatile 
328                          * should have no effect, but in fact speeds up this 
329                          * inner loop from 26 to 18 cycles (+ cache misses) 
330                          * on i486's.
331                          * XXX: out of date?
332                          */
333 #define UCVP(ucp)       ((u_char volatile *)(ucp))
334                         p = sc_vtb_putchar(&scp->vtb, p,
335                                            UCVP(map)[*UCVP(ptr)], attr);
336                         ++ptr;
337                         --i;
338                 } while ((i > 0) && PRINTABLE(*ptr));
339
340                 l -= cnt - i;
341                 mark_for_update(scp, scp->cursor_pos);
342                 scp->cursor_pos += cnt - i;
343                 mark_for_update(scp, scp->cursor_pos - 1);
344                 scp->xpos += cnt - i;
345
346                 if (scp->xpos >= scp->xsize) {
347                         scp->xpos = 0;
348                         scp->ypos++;
349                         /* we may have to scroll the screen */
350                 }
351         } else {
352                 switch(*ptr) {
353                 case 0x07:
354                         sc_bell(scp, scp->bell_pitch, scp->bell_duration);
355                         break;
356
357                 case 0x08:      /* non-destructive backspace */
358                         /* XXX */
359                         if (scp->cursor_pos > 0) {
360 #if 0
361                                 mark_for_update(scp, scp->cursor_pos);
362                                 scp->cursor_pos--;
363                                 mark_for_update(scp, scp->cursor_pos);
364 #else
365                                 scp->cursor_pos--;
366 #endif
367                                 if (scp->xpos > 0) {
368                                         scp->xpos--;
369                                 } else {
370                                         scp->xpos += scp->xsize - 1;
371                                         scp->ypos--;
372                                 }
373                         }
374                         break;
375
376                 case 0x09:      /* non-destructive tab */
377                         sc_term_tab(scp, 1);
378                         /* we may have to scroll the screen */
379 #if 0
380                         mark_for_update(scp, scp->cursor_pos);
381                         scp->cursor_pos += (8 - scp->xpos % 8u);
382                         mark_for_update(scp, scp->cursor_pos);
383                         scp->xpos += (8 - scp->xpos % 8u);
384                         if (scp->xpos >= scp->xsize) {
385                                 scp->xpos = 0;
386                                 scp->ypos++;
387                         }
388 #endif
389                         break;
390
391                 case 0x0a:      /* newline, same pos */
392 #if 0
393                         mark_for_update(scp, scp->cursor_pos);
394                         scp->cursor_pos += scp->xsize;
395                         mark_for_update(scp, scp->cursor_pos);
396 #else
397                         scp->cursor_pos += scp->xsize;
398                         /* we may have to scroll the screen */
399 #endif
400                         scp->ypos++;
401                         break;
402
403                 case 0x0c:      /* form feed, clears screen */
404                         sc_clear_screen(scp);
405                         break;
406
407                 case 0x0d:      /* return, return to pos 0 */
408 #if 0
409                         mark_for_update(scp, scp->cursor_pos);
410                         scp->cursor_pos -= scp->xpos;
411                         mark_for_update(scp, scp->cursor_pos);
412 #else
413                         scp->cursor_pos -= scp->xpos;
414 #endif
415                         scp->xpos = 0;
416                         break;
417                 }
418                 ptr++; l--;
419         }
420
421         *buf = ptr;
422         *len = l;
423 }
424
425 static __inline void
426 sc_term_gen_scroll(scr_stat *scp, int ch, int attr)
427 {
428         /* do we have to scroll ?? */
429         if (scp->cursor_pos >= scp->ysize*scp->xsize) {
430                 sc_remove_cutmarking(scp);              /* XXX */
431 #ifndef SC_NO_HISTORY
432                 if (scp->history != NULL)
433                         sc_hist_save_one_line(scp, 0);  /* XXX */
434 #endif
435                 sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr);
436                 scp->cursor_pos -= scp->xsize;
437                 scp->ypos--;
438                 mark_all(scp);
439         }
440 }
441
442 #endif /* _DEV_SYSCONS_SCTERMVAR_H_ */