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