xref: /dragonfly/sys/dev/misc/syscons/sctermvar.h (revision 539fbd92996b1ec2a93228c56a318b53fa514df1)
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.4 2005/05/27 20:57:40 swildner 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
sc_term_ins_line(scr_stat * scp,int y,int n,int ch,int attr,int tail)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
sc_term_del_line(scr_stat * scp,int y,int n,int ch,int attr,int tail)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
sc_term_ins_char(scr_stat * scp,int n,int ch,int attr)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
sc_term_del_char(scr_stat * scp,int n,int ch,int attr)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
sc_term_col(scr_stat * scp,int n)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
sc_term_row(scr_stat * scp,int n)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
sc_term_up(scr_stat * scp,int n,int head)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
sc_term_down(scr_stat * scp,int n,int tail)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
sc_term_left(scr_stat * scp,int n)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
sc_term_right(scr_stat * scp,int n)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
sc_term_up_scroll(scr_stat * scp,int n,int ch,int attr,int head,int tail)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
sc_term_down_scroll(scr_stat * scp,int n,int ch,int attr,int head,int tail)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
sc_term_clr_eos(scr_stat * scp,int n,int ch,int attr)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
sc_term_clr_eol(scr_stat * scp,int n,int ch,int attr)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
sc_term_tab(scr_stat * scp,int n)266 sc_term_tab(scr_stat *scp, int n)
267 {
268           int ypos;
269           int i;
270 
271           if (n < 1)
272                     n = 1;
273           i = (scp->xpos & ~7) + 8*n;
274           if (i >= scp->xsize) {
275                     ypos = scp->ypos;
276                     if (ypos >= scp->ysize - 1) {
277                               scp->xpos = 0;
278                               scp->ypos = ypos + 1;
279                               scp->cursor_pos = scp->ypos*scp->xsize;
280                     } else {
281                               sc_move_cursor(scp, 0, ypos + 1);
282                     }
283           } else {
284                     sc_move_cursor(scp, i, scp->ypos);
285           }
286 }
287 
288 static __inline void
sc_term_backtab(scr_stat * scp,int n)289 sc_term_backtab(scr_stat *scp, int n)
290 {
291           int i;
292 
293           if (n < 1)
294                     n = 1;
295           if ((i = scp->xpos & ~7) == scp->xpos)
296                     i -= 8*n;
297           else
298                     i -= 8*(n - 1);
299           if (i < 0)
300                     i = 0;
301           sc_move_cursor(scp, i, scp->ypos);
302 }
303 
304 static __inline void
sc_term_respond(scr_stat * scp,u_char * s)305 sc_term_respond(scr_stat *scp, u_char *s)
306 {
307           sc_paste(scp, s, strlen(s));  /* XXX: not correct, don't use rmap */
308 }
309 
310 static __inline void
sc_term_gen_print(scr_stat * scp,u_char ** buf,int * len,int attr)311 sc_term_gen_print(scr_stat *scp, u_char **buf, int *len, int attr)
312 {
313           uint16_t *p;
314           u_char *ptr;
315           u_char *map;
316           int cnt;
317           int l;
318           int i;
319 
320           ptr = *buf;
321           l = *len;
322 
323           if (PRINTABLE(*ptr)) {
324                     p = scp->vtb.vtb_buffer + scp->cursor_pos;
325                     map = scp->sc->scr_map;
326 
327                     cnt = imin(l, scp->xsize - scp->xpos);
328                     i = cnt;
329                     do {
330                               p = sc_vtb_putchar(&scp->vtb, p, map[*ptr], attr);
331                               ++ptr;
332                               --i;
333                     } while ((i > 0) && PRINTABLE(*ptr));
334 
335                     l -= cnt - i;
336                     mark_for_update(scp, scp->cursor_pos);
337                     scp->cursor_pos += cnt - i;
338                     mark_for_update(scp, scp->cursor_pos - 1);
339                     scp->xpos += cnt - i;
340 
341                     if (scp->xpos >= scp->xsize) {
342                               scp->xpos = 0;
343                               scp->ypos++;
344                               /* we may have to scroll the screen */
345                     }
346           } else {
347                     switch(*ptr) {
348                     case 0x07:
349                               sc_bell(scp, scp->bell_pitch, scp->bell_duration);
350                               break;
351 
352                     case 0x08:          /* non-destructive backspace */
353                               /* XXX */
354                               if (scp->cursor_pos > 0) {
355 #if 0
356                                         mark_for_update(scp, scp->cursor_pos);
357                                         scp->cursor_pos--;
358                                         mark_for_update(scp, scp->cursor_pos);
359 #else
360                                         scp->cursor_pos--;
361 #endif
362                                         if (scp->xpos > 0) {
363                                                   scp->xpos--;
364                                         } else {
365                                                   scp->xpos += scp->xsize - 1;
366                                                   scp->ypos--;
367                                         }
368                               }
369                               break;
370 
371                     case 0x09:          /* non-destructive tab */
372                               sc_term_tab(scp, 1);
373                               /* we may have to scroll the screen */
374 #if 0
375                               mark_for_update(scp, scp->cursor_pos);
376                               scp->cursor_pos += (8 - scp->xpos % 8u);
377                               mark_for_update(scp, scp->cursor_pos);
378                               scp->xpos += (8 - scp->xpos % 8u);
379                               if (scp->xpos >= scp->xsize) {
380                                         scp->xpos = 0;
381                                         scp->ypos++;
382                               }
383 #endif
384                               break;
385 
386                     case 0x0a:          /* newline, same pos */
387 #if 0
388                               mark_for_update(scp, scp->cursor_pos);
389                               scp->cursor_pos += scp->xsize;
390                               mark_for_update(scp, scp->cursor_pos);
391 #else
392                               scp->cursor_pos += scp->xsize;
393                               /* we may have to scroll the screen */
394 #endif
395                               scp->ypos++;
396                               break;
397 
398                     case 0x0c:          /* form feed, clears screen */
399                               sc_clear_screen(scp);
400                               break;
401 
402                     case 0x0d:          /* return, return to pos 0 */
403 #if 0
404                               mark_for_update(scp, scp->cursor_pos);
405                               scp->cursor_pos -= scp->xpos;
406                               mark_for_update(scp, scp->cursor_pos);
407 #else
408                               scp->cursor_pos -= scp->xpos;
409 #endif
410                               scp->xpos = 0;
411                               break;
412                     }
413                     ptr++; l--;
414           }
415 
416           *buf = ptr;
417           *len = l;
418 }
419 
420 /*
421  * Handle scrolling, take care to ensure that we don't implode the
422  * fields if we happen to be multi-entrant during a panic.
423  */
424 static __inline void
sc_term_gen_scroll(scr_stat * scp,int ch,int attr)425 sc_term_gen_scroll(scr_stat *scp, int ch, int attr)
426 {
427           int pos;
428           int ypos;
429 
430           pos = scp->cursor_pos;
431           cpu_ccfence();
432           /* do we have to scroll ?? */
433           if (pos >= scp->ysize*scp->xsize) {
434                     sc_remove_cutmarking(scp);              /* XXX */
435 #ifndef SC_NO_HISTORY
436                     if (scp->history != NULL)
437                               sc_hist_save_one_line(scp, 0);          /* XXX */
438 #endif
439                     sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr);
440                     scp->cursor_pos = pos - scp->xsize;
441                     ypos = scp->ypos - 1;
442                     if (ypos <= 0)
443                               ypos = 0;
444                     scp->ypos = ypos;
445                     mark_all(scp);
446           }
447 }
448 
449 #endif /* _DEV_SYSCONS_SCTERMVAR_H_ */
450