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$ 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 p = sc_vtb_putchar(&scp->vtb, p, map[*ptr], attr); 326 ++ptr; 327 --i; 328 } while ((i > 0) && PRINTABLE(*ptr)); 329 330 l -= cnt - i; 331 mark_for_update(scp, scp->cursor_pos); 332 scp->cursor_pos += cnt - i; 333 mark_for_update(scp, scp->cursor_pos - 1); 334 scp->xpos += cnt - i; 335 336 if (scp->xpos >= scp->xsize) { 337 scp->xpos = 0; 338 scp->ypos++; 339 /* we may have to scroll the screen */ 340 } 341 } else { 342 switch(*ptr) { 343 case 0x07: 344 sc_bell(scp, scp->bell_pitch, scp->bell_duration); 345 break; 346 347 case 0x08: /* non-destructive backspace */ 348 /* XXX */ 349 if (scp->cursor_pos > 0) { 350 #if 0 351 mark_for_update(scp, scp->cursor_pos); 352 scp->cursor_pos--; 353 mark_for_update(scp, scp->cursor_pos); 354 #else 355 scp->cursor_pos--; 356 #endif 357 if (scp->xpos > 0) { 358 scp->xpos--; 359 } else { 360 scp->xpos += scp->xsize - 1; 361 scp->ypos--; 362 } 363 } 364 break; 365 366 case 0x09: /* non-destructive tab */ 367 sc_term_tab(scp, 1); 368 /* we may have to scroll the screen */ 369 #if 0 370 mark_for_update(scp, scp->cursor_pos); 371 scp->cursor_pos += (8 - scp->xpos % 8u); 372 mark_for_update(scp, scp->cursor_pos); 373 scp->xpos += (8 - scp->xpos % 8u); 374 if (scp->xpos >= scp->xsize) { 375 scp->xpos = 0; 376 scp->ypos++; 377 } 378 #endif 379 break; 380 381 case 0x0a: /* newline, same pos */ 382 #if 0 383 mark_for_update(scp, scp->cursor_pos); 384 scp->cursor_pos += scp->xsize; 385 mark_for_update(scp, scp->cursor_pos); 386 #else 387 scp->cursor_pos += scp->xsize; 388 /* we may have to scroll the screen */ 389 #endif 390 scp->ypos++; 391 break; 392 393 case 0x0c: /* form feed, clears screen */ 394 sc_clear_screen(scp); 395 break; 396 397 case 0x0d: /* return, return to pos 0 */ 398 #if 0 399 mark_for_update(scp, scp->cursor_pos); 400 scp->cursor_pos -= scp->xpos; 401 mark_for_update(scp, scp->cursor_pos); 402 #else 403 scp->cursor_pos -= scp->xpos; 404 #endif 405 scp->xpos = 0; 406 break; 407 } 408 ptr++; l--; 409 } 410 411 *buf = ptr; 412 *len = l; 413 } 414 415 static __inline void 416 sc_term_gen_scroll(scr_stat *scp, int ch, int attr) 417 { 418 /* do we have to scroll ?? */ 419 if (scp->cursor_pos >= scp->ysize*scp->xsize) { 420 sc_remove_cutmarking(scp); /* XXX */ 421 #ifndef SC_NO_HISTORY 422 if (scp->history != NULL) 423 sc_hist_save_one_line(scp, 0); /* XXX */ 424 #endif 425 sc_vtb_delete(&scp->vtb, 0, scp->xsize, ch, attr); 426 scp->cursor_pos -= scp->xsize; 427 scp->ypos--; 428 mark_all(scp); 429 } 430 } 431 432 #endif /* _DEV_SYSCONS_SCTERMVAR_H_ */ 433