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