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_ */ 444