1/*- 2 * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 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. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 *
| 1/*- 2 * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 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. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 *
|
27 */ 28 29static void teken_subr_cursor_up(teken_t *, unsigned int); 30static void teken_subr_erase_line(teken_t *, unsigned int); 31static void teken_subr_regular_character(teken_t *, teken_char_t); 32static void teken_subr_reset_to_initial_state(teken_t *); 33 34static inline int 35teken_tab_isset(teken_t *t, unsigned int col) 36{ 37 unsigned int b, o; 38 39 teken_assert(col <= T_NUMCOL); 40 41 b = col / (sizeof(unsigned int) * 8); 42 o = col % (sizeof(unsigned int) * 8); 43 44 return (t->t_tabstops[b] & (1 << o)); 45} 46 47static inline void 48teken_tab_clear(teken_t *t, unsigned int col) 49{ 50 unsigned int b, o; 51 52 teken_assert(col <= T_NUMCOL); 53 54 b = col / (sizeof(unsigned int) * 8); 55 o = col % (sizeof(unsigned int) * 8); 56 57 t->t_tabstops[b] &= ~(1 << o); 58} 59 60static inline void 61teken_tab_set(teken_t *t, unsigned int col) 62{ 63 unsigned int b, o; 64 65 teken_assert(col <= T_NUMCOL); 66 67 b = col / (sizeof(unsigned int) * 8); 68 o = col % (sizeof(unsigned int) * 8); 69 70 t->t_tabstops[b] |= 1 << o; 71} 72 73static void 74teken_tab_default(teken_t *t) 75{ 76 unsigned int i; 77 78 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 79 80 for (i = 8; i < T_NUMCOL; i += 8) 81 teken_tab_set(t, i); 82} 83 84static void 85teken_subr_do_scroll(teken_t *t, int amount) 86{ 87 teken_rect_t tr; 88 teken_pos_t tp; 89 90 teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); 91 teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); 92 teken_assert(amount != 0); 93 94 /* Copy existing data 1 line up. */ 95 if (amount > 0) { 96 /* Scroll down. */ 97 98 /* Copy existing data up. */ 99 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 100 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; 101 tr.tr_begin.tp_col = 0; 102 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 103 tr.tr_end.tp_col = t->t_winsize.tp_col; 104 tp.tp_row = t->t_scrollreg.ts_begin; 105 tp.tp_col = 0; 106 teken_funcs_copy(t, &tr, &tp); 107 108 tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; 109 } else { 110 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 111 } 112 113 /* Clear the last lines. */ 114 tr.tr_begin.tp_col = 0; 115 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 116 tr.tr_end.tp_col = t->t_winsize.tp_col; 117 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 118 } else { 119 /* Scroll up. */ 120 amount = -amount; 121 122 /* Copy existing data down. */ 123 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 124 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 125 tr.tr_begin.tp_col = 0; 126 tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; 127 tr.tr_end.tp_col = t->t_winsize.tp_col; 128 tp.tp_row = t->t_scrollreg.ts_begin + amount; 129 tp.tp_col = 0; 130 teken_funcs_copy(t, &tr, &tp); 131 132 tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; 133 } else { 134 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 135 } 136 137 /* Clear the first lines. */ 138 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 139 tr.tr_begin.tp_col = 0; 140 tr.tr_end.tp_col = t->t_winsize.tp_col; 141 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 142 } 143} 144 145static ssize_t 146teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16]) 147{ 148 149 switch (cmd) { 150 case 5: /* Operating status. */ 151 strcpy(response, "0n"); 152 return (2); 153 case 6: { /* Cursor position. */ 154 int len; 155 156 len = snprintf(response, 16, "%u;%uR", 157 (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, 158 t->t_cursor.tp_col + 1); 159 160 if (len >= 16) 161 return (-1); 162 return (len); 163 } 164 case 15: /* Printer status. */ 165 strcpy(response, "13n"); 166 return (3); 167 case 25: /* UDK status. */ 168 strcpy(response, "20n"); 169 return (3); 170 case 26: /* Keyboard status. */ 171 strcpy(response, "27;1n"); 172 return (5); 173 default: 174 teken_printf("Unknown DSR\n"); 175 return (-1); 176 } 177} 178 179static void 180teken_subr_alignment_test(teken_t *t) 181{ 182 teken_rect_t tr; 183 184 t->t_scrollreg.ts_begin = 0; 185 t->t_scrollreg.ts_end = t->t_winsize.tp_row; 186 187 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 188 t->t_stateflags &= ~TS_WRAPPED; 189 teken_funcs_cursor(t); 190 191 tr.tr_begin.tp_row = 0; 192 tr.tr_begin.tp_col = 0; 193 tr.tr_end = t->t_winsize; 194 teken_funcs_fill(t, &tr, 'E', &t->t_defattr); 195} 196 197static void 198teken_subr_backspace(teken_t *t) 199{ 200 201#ifdef TEKEN_CONS25 202 if (t->t_cursor.tp_col == 0) { 203 if (t->t_cursor.tp_row == t->t_originreg.ts_begin) 204 return; 205 t->t_cursor.tp_row--; 206 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 207 } else { 208 t->t_cursor.tp_col--; 209 } 210#else /* !TEKEN_CONS25 */ 211 if (t->t_cursor.tp_col == 0) 212 return; 213 214 t->t_cursor.tp_col--; 215 t->t_stateflags &= ~TS_WRAPPED; 216#endif /* TEKEN_CONS25 */ 217 218 teken_funcs_cursor(t); 219} 220 221static void 222teken_subr_bell(teken_t *t) 223{ 224 225 teken_funcs_bell(t); 226} 227 228static void 229teken_subr_carriage_return(teken_t *t) 230{ 231 232 t->t_cursor.tp_col = 0; 233 t->t_stateflags &= ~TS_WRAPPED; 234 teken_funcs_cursor(t); 235} 236 237static void 238teken_subr_cursor_backward(teken_t *t, unsigned int ncols) 239{ 240 241 if (ncols > t->t_cursor.tp_col) 242 t->t_cursor.tp_col = 0; 243 else 244 t->t_cursor.tp_col -= ncols; 245 t->t_stateflags &= ~TS_WRAPPED; 246 teken_funcs_cursor(t); 247} 248 249static void 250teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) 251{ 252 253 do { 254 /* Stop when we've reached the beginning of the line. */ 255 if (t->t_cursor.tp_col == 0) 256 break; 257 258 t->t_cursor.tp_col--; 259 260 /* Tab marker set. */ 261 if (teken_tab_isset(t, t->t_cursor.tp_col)) 262 ntabs--; 263 } while (ntabs > 0); 264 265 teken_funcs_cursor(t); 266} 267 268static void 269teken_subr_cursor_down(teken_t *t, unsigned int nrows) 270{ 271 272 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) 273 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 274 else 275 t->t_cursor.tp_row += nrows; 276 t->t_stateflags &= ~TS_WRAPPED; 277 teken_funcs_cursor(t); 278} 279 280static void 281teken_subr_cursor_forward(teken_t *t, unsigned int ncols) 282{ 283 284 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 285 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 286 else 287 t->t_cursor.tp_col += ncols; 288 t->t_stateflags &= ~TS_WRAPPED; 289 teken_funcs_cursor(t); 290} 291 292static void 293teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) 294{ 295 296 do { 297 /* Stop when we've reached the end of the line. */ 298 if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) 299 break; 300 301 t->t_cursor.tp_col++; 302 303 /* Tab marker set. */ 304 if (teken_tab_isset(t, t->t_cursor.tp_col)) 305 ntabs--; 306 } while (ntabs > 0); 307 308 teken_funcs_cursor(t); 309} 310 311static void 312teken_subr_cursor_next_line(teken_t *t, unsigned int ncols) 313{ 314 315 t->t_cursor.tp_col = 0; 316 teken_subr_cursor_down(t, ncols); 317} 318 319static void 320teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) 321{ 322 323 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 324 if (row >= t->t_originreg.ts_end) 325 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 326 327 t->t_cursor.tp_col = col - 1; 328 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 329 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 330 331 t->t_stateflags &= ~TS_WRAPPED; 332 teken_funcs_cursor(t); 333} 334 335static void 336teken_subr_cursor_position_report(teken_t *t, unsigned int cmd) 337{ 338 char response[18] = "\x1B["; 339 ssize_t len; 340 341 len = teken_subr_do_cpr(t, cmd, response + 2); 342 if (len < 0) 343 return; 344 345 teken_funcs_respond(t, response, len + 2); 346} 347 348static void 349teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) 350{ 351 352 t->t_cursor.tp_col = 0; 353 teken_subr_cursor_up(t, ncols); 354} 355 356static void 357teken_subr_cursor_up(teken_t *t, unsigned int nrows) 358{ 359 360 if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) 361 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 362 else 363 t->t_cursor.tp_row -= nrows; 364 t->t_stateflags &= ~TS_WRAPPED; 365 teken_funcs_cursor(t); 366} 367 368static void 369teken_subr_delete_character(teken_t *t, unsigned int ncols) 370{ 371 teken_rect_t tr; 372 373 tr.tr_begin.tp_row = t->t_cursor.tp_row; 374 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 375 tr.tr_end.tp_col = t->t_winsize.tp_col; 376 377 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 378 tr.tr_begin.tp_col = t->t_cursor.tp_col; 379 } else { 380 /* Copy characters to the left. */ 381 tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; 382 teken_funcs_copy(t, &tr, &t->t_cursor); 383 384 tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; 385 } 386 387 /* Blank trailing columns. */ 388 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 389} 390 391static void 392teken_subr_delete_line(teken_t *t, unsigned int nrows) 393{ 394 teken_rect_t tr; 395 396 tr.tr_begin.tp_col = 0; 397 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 398 tr.tr_end.tp_col = t->t_winsize.tp_col; 399 400 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 401 tr.tr_begin.tp_row = t->t_cursor.tp_row; 402 } else { 403 teken_pos_t tp; 404 405 /* Copy rows up. */ 406 tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; 407 tp.tp_row = t->t_cursor.tp_row; 408 tp.tp_col = 0; 409 teken_funcs_copy(t, &tr, &tp); 410 411 tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; 412 } 413 414 /* Blank trailing rows. */ 415 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 416} 417 418static void 419teken_subr_device_control_string(teken_t *t __unused) 420{ 421 422 teken_printf("device control string???\n"); 423} 424 425static void 426teken_subr_device_status_report(teken_t *t, unsigned int cmd) 427{ 428 char response[19] = "\x1B[?"; 429 ssize_t len; 430 431 len = teken_subr_do_cpr(t, cmd, response + 3); 432 if (len < 0) 433 return; 434 435 teken_funcs_respond(t, response, len + 3); 436} 437 438static void 439teken_subr_double_height_double_width_line_top(teken_t *t __unused) 440{ 441 442 teken_printf("double height double width top\n"); 443} 444 445static void 446teken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 447{ 448 449 teken_printf("double height double width bottom\n"); 450} 451 452static void 453teken_subr_erase_character(teken_t *t, unsigned int ncols) 454{ 455 teken_rect_t tr; 456 457 tr.tr_begin = t->t_cursor; 458 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 459 460 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 461 tr.tr_end.tp_col = t->t_winsize.tp_col; 462 else 463 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 464 465 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 466} 467 468static void 469teken_subr_erase_display(teken_t *t, unsigned int mode) 470{ 471 teken_rect_t r; 472 473 r.tr_begin.tp_col = 0; 474 r.tr_end.tp_col = t->t_winsize.tp_col; 475 476 switch (mode) { 477 case 1: /* Erase from the top to the cursor. */ 478 teken_subr_erase_line(t, 1); 479 480 /* Erase lines above. */ 481 if (t->t_cursor.tp_row == 0) 482 return; 483 r.tr_begin.tp_row = 0; 484 r.tr_end.tp_row = t->t_cursor.tp_row; 485 break; 486 case 2: /* Erase entire display. */ 487 r.tr_begin.tp_row = 0; 488 r.tr_end.tp_row = t->t_winsize.tp_row; 489 break; 490 default: /* Erase from cursor to the bottom. */ 491 teken_subr_erase_line(t, 0); 492 493 /* Erase lines below. */ 494 if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 495 return; 496 r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 497 r.tr_end.tp_row = t->t_winsize.tp_row; 498 break; 499 } 500 501 teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 502} 503 504static void 505teken_subr_erase_line(teken_t *t, unsigned int mode) 506{ 507 teken_rect_t r; 508 509 r.tr_begin.tp_row = t->t_cursor.tp_row; 510 r.tr_end.tp_row = t->t_cursor.tp_row + 1; 511 512 switch (mode) { 513 case 1: /* Erase from the beginning of the line to the cursor. */ 514 r.tr_begin.tp_col = 0; 515 r.tr_end.tp_col = t->t_cursor.tp_col + 1; 516 break; 517 case 2: /* Erase entire line. */ 518 r.tr_begin.tp_col = 0; 519 r.tr_end.tp_col = t->t_winsize.tp_col; 520 break; 521 default: /* Erase from cursor to the end of the line. */ 522 r.tr_begin.tp_col = t->t_cursor.tp_col; 523 r.tr_end.tp_col = t->t_winsize.tp_col; 524 break; 525 } 526 527 teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 528} 529 530static void 531teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 532{ 533 534 t->t_cursor.tp_col = col - 1; 535 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 536 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 537 538 t->t_stateflags &= ~TS_WRAPPED; 539 teken_funcs_cursor(t); 540} 541 542static void 543teken_subr_horizontal_tab(teken_t *t) 544{ 545#ifdef TEKEN_CONS25 546 547 teken_subr_cursor_forward_tabulation(t, 1); 548#else /* !TEKEN_CONS25 */ 549 teken_rect_t tr; 550 551 tr.tr_begin = t->t_cursor; 552 teken_subr_cursor_forward_tabulation(t, 1); 553 tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 554 tr.tr_end.tp_col = t->t_cursor.tp_col; 555 556 /* Blank region that we skipped. */ 557 if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 558 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 559#endif /* TEKEN_CONS25 */ 560} 561 562static void 563teken_subr_horizontal_tab_set(teken_t *t) 564{ 565 566 teken_tab_set(t, t->t_cursor.tp_col); 567} 568 569static void 570teken_subr_index(teken_t *t) 571{ 572 573 if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 574 t->t_cursor.tp_row++; 575 t->t_stateflags &= ~TS_WRAPPED; 576 teken_funcs_cursor(t); 577 } else { 578 teken_subr_do_scroll(t, 1); 579 } 580} 581 582static void 583teken_subr_insert_character(teken_t *t, unsigned int ncols) 584{ 585 teken_rect_t tr; 586 587 tr.tr_begin = t->t_cursor; 588 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 589 590 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 591 tr.tr_end.tp_col = t->t_winsize.tp_col; 592 } else { 593 teken_pos_t tp; 594 595 /* Copy characters to the right. */ 596 tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 597 tp.tp_row = t->t_cursor.tp_row; 598 tp.tp_col = t->t_cursor.tp_col + ncols; 599 teken_funcs_copy(t, &tr, &tp); 600 601 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 602 } 603 604 /* Blank current location. */ 605 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 606} 607 608static void 609teken_subr_insert_line(teken_t *t, unsigned int nrows) 610{ 611 teken_rect_t tr; 612 613 tr.tr_begin.tp_row = t->t_cursor.tp_row; 614 tr.tr_begin.tp_col = 0; 615 tr.tr_end.tp_col = t->t_winsize.tp_col; 616 617 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 618 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 619 } else { 620 teken_pos_t tp; 621 622 /* Copy lines down. */ 623 tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 624 tp.tp_row = t->t_cursor.tp_row + nrows; 625 tp.tp_col = 0; 626 teken_funcs_copy(t, &tr, &tp); 627 628 tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 629 } 630 631 /* Blank current location. */ 632 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 633} 634 635static void 636teken_subr_keypad_application_mode(teken_t *t) 637{ 638 639 teken_funcs_param(t, TP_KEYPADAPP, 1); 640} 641 642static void 643teken_subr_keypad_numeric_mode(teken_t *t) 644{ 645 646 teken_funcs_param(t, TP_KEYPADAPP, 0); 647} 648 649static void 650teken_subr_newline(teken_t *t) 651{ 652 653 t->t_cursor.tp_row++; 654 655 if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 656 teken_subr_do_scroll(t, 1); 657 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 658 } 659 660 t->t_stateflags &= ~TS_WRAPPED; 661 teken_funcs_cursor(t); 662} 663 664static void
| 27 */ 28 29static void teken_subr_cursor_up(teken_t *, unsigned int); 30static void teken_subr_erase_line(teken_t *, unsigned int); 31static void teken_subr_regular_character(teken_t *, teken_char_t); 32static void teken_subr_reset_to_initial_state(teken_t *); 33 34static inline int 35teken_tab_isset(teken_t *t, unsigned int col) 36{ 37 unsigned int b, o; 38 39 teken_assert(col <= T_NUMCOL); 40 41 b = col / (sizeof(unsigned int) * 8); 42 o = col % (sizeof(unsigned int) * 8); 43 44 return (t->t_tabstops[b] & (1 << o)); 45} 46 47static inline void 48teken_tab_clear(teken_t *t, unsigned int col) 49{ 50 unsigned int b, o; 51 52 teken_assert(col <= T_NUMCOL); 53 54 b = col / (sizeof(unsigned int) * 8); 55 o = col % (sizeof(unsigned int) * 8); 56 57 t->t_tabstops[b] &= ~(1 << o); 58} 59 60static inline void 61teken_tab_set(teken_t *t, unsigned int col) 62{ 63 unsigned int b, o; 64 65 teken_assert(col <= T_NUMCOL); 66 67 b = col / (sizeof(unsigned int) * 8); 68 o = col % (sizeof(unsigned int) * 8); 69 70 t->t_tabstops[b] |= 1 << o; 71} 72 73static void 74teken_tab_default(teken_t *t) 75{ 76 unsigned int i; 77 78 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 79 80 for (i = 8; i < T_NUMCOL; i += 8) 81 teken_tab_set(t, i); 82} 83 84static void 85teken_subr_do_scroll(teken_t *t, int amount) 86{ 87 teken_rect_t tr; 88 teken_pos_t tp; 89 90 teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); 91 teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); 92 teken_assert(amount != 0); 93 94 /* Copy existing data 1 line up. */ 95 if (amount > 0) { 96 /* Scroll down. */ 97 98 /* Copy existing data up. */ 99 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 100 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; 101 tr.tr_begin.tp_col = 0; 102 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 103 tr.tr_end.tp_col = t->t_winsize.tp_col; 104 tp.tp_row = t->t_scrollreg.ts_begin; 105 tp.tp_col = 0; 106 teken_funcs_copy(t, &tr, &tp); 107 108 tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; 109 } else { 110 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 111 } 112 113 /* Clear the last lines. */ 114 tr.tr_begin.tp_col = 0; 115 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 116 tr.tr_end.tp_col = t->t_winsize.tp_col; 117 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 118 } else { 119 /* Scroll up. */ 120 amount = -amount; 121 122 /* Copy existing data down. */ 123 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 124 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 125 tr.tr_begin.tp_col = 0; 126 tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; 127 tr.tr_end.tp_col = t->t_winsize.tp_col; 128 tp.tp_row = t->t_scrollreg.ts_begin + amount; 129 tp.tp_col = 0; 130 teken_funcs_copy(t, &tr, &tp); 131 132 tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; 133 } else { 134 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 135 } 136 137 /* Clear the first lines. */ 138 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 139 tr.tr_begin.tp_col = 0; 140 tr.tr_end.tp_col = t->t_winsize.tp_col; 141 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 142 } 143} 144 145static ssize_t 146teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16]) 147{ 148 149 switch (cmd) { 150 case 5: /* Operating status. */ 151 strcpy(response, "0n"); 152 return (2); 153 case 6: { /* Cursor position. */ 154 int len; 155 156 len = snprintf(response, 16, "%u;%uR", 157 (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, 158 t->t_cursor.tp_col + 1); 159 160 if (len >= 16) 161 return (-1); 162 return (len); 163 } 164 case 15: /* Printer status. */ 165 strcpy(response, "13n"); 166 return (3); 167 case 25: /* UDK status. */ 168 strcpy(response, "20n"); 169 return (3); 170 case 26: /* Keyboard status. */ 171 strcpy(response, "27;1n"); 172 return (5); 173 default: 174 teken_printf("Unknown DSR\n"); 175 return (-1); 176 } 177} 178 179static void 180teken_subr_alignment_test(teken_t *t) 181{ 182 teken_rect_t tr; 183 184 t->t_scrollreg.ts_begin = 0; 185 t->t_scrollreg.ts_end = t->t_winsize.tp_row; 186 187 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 188 t->t_stateflags &= ~TS_WRAPPED; 189 teken_funcs_cursor(t); 190 191 tr.tr_begin.tp_row = 0; 192 tr.tr_begin.tp_col = 0; 193 tr.tr_end = t->t_winsize; 194 teken_funcs_fill(t, &tr, 'E', &t->t_defattr); 195} 196 197static void 198teken_subr_backspace(teken_t *t) 199{ 200 201#ifdef TEKEN_CONS25 202 if (t->t_cursor.tp_col == 0) { 203 if (t->t_cursor.tp_row == t->t_originreg.ts_begin) 204 return; 205 t->t_cursor.tp_row--; 206 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 207 } else { 208 t->t_cursor.tp_col--; 209 } 210#else /* !TEKEN_CONS25 */ 211 if (t->t_cursor.tp_col == 0) 212 return; 213 214 t->t_cursor.tp_col--; 215 t->t_stateflags &= ~TS_WRAPPED; 216#endif /* TEKEN_CONS25 */ 217 218 teken_funcs_cursor(t); 219} 220 221static void 222teken_subr_bell(teken_t *t) 223{ 224 225 teken_funcs_bell(t); 226} 227 228static void 229teken_subr_carriage_return(teken_t *t) 230{ 231 232 t->t_cursor.tp_col = 0; 233 t->t_stateflags &= ~TS_WRAPPED; 234 teken_funcs_cursor(t); 235} 236 237static void 238teken_subr_cursor_backward(teken_t *t, unsigned int ncols) 239{ 240 241 if (ncols > t->t_cursor.tp_col) 242 t->t_cursor.tp_col = 0; 243 else 244 t->t_cursor.tp_col -= ncols; 245 t->t_stateflags &= ~TS_WRAPPED; 246 teken_funcs_cursor(t); 247} 248 249static void 250teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) 251{ 252 253 do { 254 /* Stop when we've reached the beginning of the line. */ 255 if (t->t_cursor.tp_col == 0) 256 break; 257 258 t->t_cursor.tp_col--; 259 260 /* Tab marker set. */ 261 if (teken_tab_isset(t, t->t_cursor.tp_col)) 262 ntabs--; 263 } while (ntabs > 0); 264 265 teken_funcs_cursor(t); 266} 267 268static void 269teken_subr_cursor_down(teken_t *t, unsigned int nrows) 270{ 271 272 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) 273 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 274 else 275 t->t_cursor.tp_row += nrows; 276 t->t_stateflags &= ~TS_WRAPPED; 277 teken_funcs_cursor(t); 278} 279 280static void 281teken_subr_cursor_forward(teken_t *t, unsigned int ncols) 282{ 283 284 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 285 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 286 else 287 t->t_cursor.tp_col += ncols; 288 t->t_stateflags &= ~TS_WRAPPED; 289 teken_funcs_cursor(t); 290} 291 292static void 293teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) 294{ 295 296 do { 297 /* Stop when we've reached the end of the line. */ 298 if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) 299 break; 300 301 t->t_cursor.tp_col++; 302 303 /* Tab marker set. */ 304 if (teken_tab_isset(t, t->t_cursor.tp_col)) 305 ntabs--; 306 } while (ntabs > 0); 307 308 teken_funcs_cursor(t); 309} 310 311static void 312teken_subr_cursor_next_line(teken_t *t, unsigned int ncols) 313{ 314 315 t->t_cursor.tp_col = 0; 316 teken_subr_cursor_down(t, ncols); 317} 318 319static void 320teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) 321{ 322 323 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 324 if (row >= t->t_originreg.ts_end) 325 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 326 327 t->t_cursor.tp_col = col - 1; 328 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 329 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 330 331 t->t_stateflags &= ~TS_WRAPPED; 332 teken_funcs_cursor(t); 333} 334 335static void 336teken_subr_cursor_position_report(teken_t *t, unsigned int cmd) 337{ 338 char response[18] = "\x1B["; 339 ssize_t len; 340 341 len = teken_subr_do_cpr(t, cmd, response + 2); 342 if (len < 0) 343 return; 344 345 teken_funcs_respond(t, response, len + 2); 346} 347 348static void 349teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) 350{ 351 352 t->t_cursor.tp_col = 0; 353 teken_subr_cursor_up(t, ncols); 354} 355 356static void 357teken_subr_cursor_up(teken_t *t, unsigned int nrows) 358{ 359 360 if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) 361 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 362 else 363 t->t_cursor.tp_row -= nrows; 364 t->t_stateflags &= ~TS_WRAPPED; 365 teken_funcs_cursor(t); 366} 367 368static void 369teken_subr_delete_character(teken_t *t, unsigned int ncols) 370{ 371 teken_rect_t tr; 372 373 tr.tr_begin.tp_row = t->t_cursor.tp_row; 374 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 375 tr.tr_end.tp_col = t->t_winsize.tp_col; 376 377 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 378 tr.tr_begin.tp_col = t->t_cursor.tp_col; 379 } else { 380 /* Copy characters to the left. */ 381 tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; 382 teken_funcs_copy(t, &tr, &t->t_cursor); 383 384 tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; 385 } 386 387 /* Blank trailing columns. */ 388 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 389} 390 391static void 392teken_subr_delete_line(teken_t *t, unsigned int nrows) 393{ 394 teken_rect_t tr; 395 396 tr.tr_begin.tp_col = 0; 397 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 398 tr.tr_end.tp_col = t->t_winsize.tp_col; 399 400 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 401 tr.tr_begin.tp_row = t->t_cursor.tp_row; 402 } else { 403 teken_pos_t tp; 404 405 /* Copy rows up. */ 406 tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; 407 tp.tp_row = t->t_cursor.tp_row; 408 tp.tp_col = 0; 409 teken_funcs_copy(t, &tr, &tp); 410 411 tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; 412 } 413 414 /* Blank trailing rows. */ 415 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 416} 417 418static void 419teken_subr_device_control_string(teken_t *t __unused) 420{ 421 422 teken_printf("device control string???\n"); 423} 424 425static void 426teken_subr_device_status_report(teken_t *t, unsigned int cmd) 427{ 428 char response[19] = "\x1B[?"; 429 ssize_t len; 430 431 len = teken_subr_do_cpr(t, cmd, response + 3); 432 if (len < 0) 433 return; 434 435 teken_funcs_respond(t, response, len + 3); 436} 437 438static void 439teken_subr_double_height_double_width_line_top(teken_t *t __unused) 440{ 441 442 teken_printf("double height double width top\n"); 443} 444 445static void 446teken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 447{ 448 449 teken_printf("double height double width bottom\n"); 450} 451 452static void 453teken_subr_erase_character(teken_t *t, unsigned int ncols) 454{ 455 teken_rect_t tr; 456 457 tr.tr_begin = t->t_cursor; 458 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 459 460 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 461 tr.tr_end.tp_col = t->t_winsize.tp_col; 462 else 463 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 464 465 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 466} 467 468static void 469teken_subr_erase_display(teken_t *t, unsigned int mode) 470{ 471 teken_rect_t r; 472 473 r.tr_begin.tp_col = 0; 474 r.tr_end.tp_col = t->t_winsize.tp_col; 475 476 switch (mode) { 477 case 1: /* Erase from the top to the cursor. */ 478 teken_subr_erase_line(t, 1); 479 480 /* Erase lines above. */ 481 if (t->t_cursor.tp_row == 0) 482 return; 483 r.tr_begin.tp_row = 0; 484 r.tr_end.tp_row = t->t_cursor.tp_row; 485 break; 486 case 2: /* Erase entire display. */ 487 r.tr_begin.tp_row = 0; 488 r.tr_end.tp_row = t->t_winsize.tp_row; 489 break; 490 default: /* Erase from cursor to the bottom. */ 491 teken_subr_erase_line(t, 0); 492 493 /* Erase lines below. */ 494 if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 495 return; 496 r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 497 r.tr_end.tp_row = t->t_winsize.tp_row; 498 break; 499 } 500 501 teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 502} 503 504static void 505teken_subr_erase_line(teken_t *t, unsigned int mode) 506{ 507 teken_rect_t r; 508 509 r.tr_begin.tp_row = t->t_cursor.tp_row; 510 r.tr_end.tp_row = t->t_cursor.tp_row + 1; 511 512 switch (mode) { 513 case 1: /* Erase from the beginning of the line to the cursor. */ 514 r.tr_begin.tp_col = 0; 515 r.tr_end.tp_col = t->t_cursor.tp_col + 1; 516 break; 517 case 2: /* Erase entire line. */ 518 r.tr_begin.tp_col = 0; 519 r.tr_end.tp_col = t->t_winsize.tp_col; 520 break; 521 default: /* Erase from cursor to the end of the line. */ 522 r.tr_begin.tp_col = t->t_cursor.tp_col; 523 r.tr_end.tp_col = t->t_winsize.tp_col; 524 break; 525 } 526 527 teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 528} 529 530static void 531teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 532{ 533 534 t->t_cursor.tp_col = col - 1; 535 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 536 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 537 538 t->t_stateflags &= ~TS_WRAPPED; 539 teken_funcs_cursor(t); 540} 541 542static void 543teken_subr_horizontal_tab(teken_t *t) 544{ 545#ifdef TEKEN_CONS25 546 547 teken_subr_cursor_forward_tabulation(t, 1); 548#else /* !TEKEN_CONS25 */ 549 teken_rect_t tr; 550 551 tr.tr_begin = t->t_cursor; 552 teken_subr_cursor_forward_tabulation(t, 1); 553 tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 554 tr.tr_end.tp_col = t->t_cursor.tp_col; 555 556 /* Blank region that we skipped. */ 557 if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 558 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 559#endif /* TEKEN_CONS25 */ 560} 561 562static void 563teken_subr_horizontal_tab_set(teken_t *t) 564{ 565 566 teken_tab_set(t, t->t_cursor.tp_col); 567} 568 569static void 570teken_subr_index(teken_t *t) 571{ 572 573 if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 574 t->t_cursor.tp_row++; 575 t->t_stateflags &= ~TS_WRAPPED; 576 teken_funcs_cursor(t); 577 } else { 578 teken_subr_do_scroll(t, 1); 579 } 580} 581 582static void 583teken_subr_insert_character(teken_t *t, unsigned int ncols) 584{ 585 teken_rect_t tr; 586 587 tr.tr_begin = t->t_cursor; 588 tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 589 590 if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 591 tr.tr_end.tp_col = t->t_winsize.tp_col; 592 } else { 593 teken_pos_t tp; 594 595 /* Copy characters to the right. */ 596 tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 597 tp.tp_row = t->t_cursor.tp_row; 598 tp.tp_col = t->t_cursor.tp_col + ncols; 599 teken_funcs_copy(t, &tr, &tp); 600 601 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 602 } 603 604 /* Blank current location. */ 605 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 606} 607 608static void 609teken_subr_insert_line(teken_t *t, unsigned int nrows) 610{ 611 teken_rect_t tr; 612 613 tr.tr_begin.tp_row = t->t_cursor.tp_row; 614 tr.tr_begin.tp_col = 0; 615 tr.tr_end.tp_col = t->t_winsize.tp_col; 616 617 if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 618 tr.tr_end.tp_row = t->t_scrollreg.ts_end; 619 } else { 620 teken_pos_t tp; 621 622 /* Copy lines down. */ 623 tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 624 tp.tp_row = t->t_cursor.tp_row + nrows; 625 tp.tp_col = 0; 626 teken_funcs_copy(t, &tr, &tp); 627 628 tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 629 } 630 631 /* Blank current location. */ 632 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 633} 634 635static void 636teken_subr_keypad_application_mode(teken_t *t) 637{ 638 639 teken_funcs_param(t, TP_KEYPADAPP, 1); 640} 641 642static void 643teken_subr_keypad_numeric_mode(teken_t *t) 644{ 645 646 teken_funcs_param(t, TP_KEYPADAPP, 0); 647} 648 649static void 650teken_subr_newline(teken_t *t) 651{ 652 653 t->t_cursor.tp_row++; 654 655 if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 656 teken_subr_do_scroll(t, 1); 657 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 658 } 659 660 t->t_stateflags &= ~TS_WRAPPED; 661 teken_funcs_cursor(t); 662} 663 664static void
|
665teken_subr_next_line(teken_t *t) 666{ 667 668 t->t_cursor.tp_col = 0; 669 teken_subr_newline(t); 670} 671 672static void 673teken_subr_pan_down(teken_t *t, unsigned int nrows) 674{ 675 676 teken_subr_do_scroll(t, (int)nrows); 677} 678 679static void 680teken_subr_pan_up(teken_t *t, unsigned int nrows) 681{ 682 683 teken_subr_do_scroll(t, -(int)nrows); 684} 685 686static void 687teken_subr_primary_device_attributes(teken_t *t, unsigned int request) 688{ 689 690 if (request == 0) { 691 const char response[] = "\x1B[?1;2c"; 692 693 teken_funcs_respond(t, response, sizeof response - 1); 694 } else { 695 teken_printf("Unknown DA1\n"); 696 } 697} 698 699static void 700teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 701 int width) 702{ 703 704 if (t->t_stateflags & TS_INSERT && 705 tp->tp_col < t->t_winsize.tp_col - width) { 706 teken_rect_t ctr; 707 teken_pos_t ctp; 708 709 /* Insert mode. Move existing characters to the right. */ 710 ctr.tr_begin = *tp; 711 ctr.tr_end.tp_row = tp->tp_row + 1; 712 ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 713 ctp.tp_row = tp->tp_row; 714 ctp.tp_col = tp->tp_col + width; 715 teken_funcs_copy(t, &ctr, &ctp); 716 } 717 718 teken_funcs_putchar(t, tp, c, &t->t_curattr); 719} 720 721static void 722teken_subr_regular_character(teken_t *t, teken_char_t c) 723{ 724 int width; 725 726 /* XXX: Don't process zero-width characters yet. */ 727 width = teken_wcwidth(c); 728 if (width <= 0) 729 return; 730 731#ifdef TEKEN_CONS25 732 teken_subr_do_putchar(t, &t->t_cursor, c, width); 733 t->t_cursor.tp_col += width; 734 735 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 736 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 737 /* Perform scrolling. */ 738 teken_subr_do_scroll(t, 1); 739 } else { 740 /* No scrolling needed. */ 741 if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1) 742 t->t_cursor.tp_row++; 743 } 744 t->t_cursor.tp_col = 0; 745 } 746#else /* !TEKEN_CONS25 */ 747 if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 748 (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 749 (TS_WRAPPED|TS_AUTOWRAP)) { 750 teken_pos_t tp; 751 752 /* Perform line wrapping. */ 753 754 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 755 /* Perform scrolling. */ 756 teken_subr_do_scroll(t, 1); 757 tp.tp_row = t->t_scrollreg.ts_end - 1; 758 } else { 759 /* No scrolling needed. */ 760 tp.tp_row = t->t_cursor.tp_row + 1; 761 if (tp.tp_row == t->t_winsize.tp_row) { 762 /* 763 * Corner case: regular character 764 * outside scrolling region, but at the 765 * bottom of the screen. 766 */ 767 teken_subr_do_putchar(t, &t->t_cursor, 768 c, width); 769 return; 770 } 771 } 772 773 tp.tp_col = 0; 774 teken_subr_do_putchar(t, &tp, c, width); 775 776 t->t_cursor.tp_row = tp.tp_row; 777 t->t_cursor.tp_col = width; 778 t->t_stateflags &= ~TS_WRAPPED; 779 } else { 780 /* No line wrapping needed. */ 781 teken_subr_do_putchar(t, &t->t_cursor, c, width); 782 t->t_cursor.tp_col += width; 783 784 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 785 t->t_stateflags |= TS_WRAPPED; 786 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 787 } else { 788 t->t_stateflags &= ~TS_WRAPPED; 789 } 790 } 791#endif /* TEKEN_CONS25 */ 792 793 teken_funcs_cursor(t); 794} 795 796static void 797teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 798{ 799 800 switch (cmd) { 801 case 1: /* Cursor keys mode. */ 802 teken_funcs_param(t, TP_CURSORKEYS, 0); 803 break; 804 case 2: /* DECANM: ANSI/VT52 mode. */ 805 teken_printf("DECRST VT52\n"); 806 break; 807 case 3: /* 132 column mode. */ 808 teken_funcs_param(t, TP_132COLS, 0); 809 teken_subr_reset_to_initial_state(t); 810 break; 811 case 5: /* Inverse video. */ 812 teken_printf("DECRST inverse video\n"); 813 break; 814 case 6: /* Origin mode. */ 815 t->t_stateflags &= ~TS_ORIGIN; 816 t->t_originreg.ts_begin = 0; 817 t->t_originreg.ts_end = t->t_winsize.tp_row; 818 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 819 t->t_stateflags &= ~TS_WRAPPED; 820 teken_funcs_cursor(t); 821 break; 822 case 7: /* Autowrap mode. */ 823 t->t_stateflags &= ~TS_AUTOWRAP; 824 break; 825 case 8: /* Autorepeat mode. */ 826 teken_funcs_param(t, TP_AUTOREPEAT, 0); 827 break; 828 case 25: /* Hide cursor. */ 829 teken_funcs_param(t, TP_SHOWCURSOR, 0); 830 break; 831 case 40: /* Disallow 132 columns. */ 832 teken_printf("DECRST allow 132\n"); 833 break; 834 case 45: /* Disable reverse wraparound. */ 835 teken_printf("DECRST reverse wraparound\n"); 836 break; 837 case 47: /* Switch to alternate buffer. */ 838 teken_printf("Switch to alternate buffer\n"); 839 break; 840 default: 841 teken_printf("Unknown DECRST: %u\n", cmd); 842 } 843} 844 845static void 846teken_subr_reset_mode(teken_t *t, unsigned int cmd) 847{ 848 849 switch (cmd) { 850 case 4: 851 t->t_stateflags &= ~TS_INSERT; 852 break; 853 default: 854 teken_printf("Unknown reset mode: %u\n", cmd); 855 } 856} 857 858static void 859teken_subr_do_reset(teken_t *t) 860{ 861 862 t->t_curattr = t->t_saved_curattr = t->t_defattr; 863 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 864 t->t_saved_cursor = t->t_cursor; 865 t->t_stateflags = TS_AUTOWRAP; 866 867 teken_tab_default(t); 868} 869 870static void 871teken_subr_reset_to_initial_state(teken_t *t) 872{ 873 874 teken_subr_do_reset(t); 875 teken_subr_erase_display(t, 2); 876 teken_funcs_param(t, TP_SHOWCURSOR, 1); 877 teken_funcs_cursor(t); 878} 879 880static void 881teken_subr_restore_cursor(teken_t *t) 882{ 883 884 t->t_cursor = t->t_saved_cursor; 885 t->t_curattr = t->t_saved_curattr; 886 t->t_stateflags &= ~TS_WRAPPED; 887 teken_funcs_cursor(t); 888} 889 890static void 891teken_subr_reverse_index(teken_t *t) 892{ 893 894 if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 895 t->t_cursor.tp_row--; 896 t->t_stateflags &= ~TS_WRAPPED; 897 teken_funcs_cursor(t); 898 } else { 899 teken_subr_do_scroll(t, -1); 900 } 901} 902 903static void 904teken_subr_save_cursor(teken_t *t) 905{ 906 907 t->t_saved_cursor = t->t_cursor; 908 t->t_saved_curattr = t->t_curattr; 909} 910 911static void 912teken_subr_scs(teken_t *t __unused) 913{ 914 915 teken_printf("scs???\n"); 916} 917 918static void 919teken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 920{ 921 922 if (request == 0) { 923 const char response[] = "\x1B[>0;10;0c"; 924 teken_funcs_respond(t, response, sizeof response - 1); 925 } else { 926 teken_printf("Unknown DA2\n"); 927 } 928} 929 930static void 931teken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 932{ 933 934 switch (cmd) { 935 case 1: /* Cursor keys mode. */ 936 teken_funcs_param(t, TP_CURSORKEYS, 1); 937 break; 938 case 2: /* DECANM: ANSI/VT52 mode. */ 939 teken_printf("DECSET VT52\n"); 940 break; 941 case 3: /* 132 column mode. */ 942 teken_funcs_param(t, TP_132COLS, 1); 943 teken_subr_reset_to_initial_state(t); 944 break; 945 case 5: /* Inverse video. */ 946 teken_printf("DECSET inverse video\n"); 947 break; 948 case 6: /* Origin mode. */ 949 t->t_stateflags |= TS_ORIGIN; 950 t->t_originreg = t->t_scrollreg; 951 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 952 t->t_cursor.tp_col = 0; 953 t->t_stateflags &= ~TS_WRAPPED; 954 teken_funcs_cursor(t); 955 break; 956 case 7: /* Autowrap mode. */ 957 t->t_stateflags |= TS_AUTOWRAP; 958 break; 959 case 8: /* Autorepeat mode. */ 960 teken_funcs_param(t, TP_AUTOREPEAT, 1); 961 break; 962 case 25: /* Display cursor. */ 963 teken_funcs_param(t, TP_SHOWCURSOR, 1); 964 break; 965 case 40: /* Allow 132 columns. */ 966 teken_printf("DECSET allow 132\n"); 967 break; 968 case 45: /* Enable reverse wraparound. */ 969 teken_printf("DECSET reverse wraparound\n"); 970 break; 971 case 47: /* Switch to alternate buffer. */ 972 teken_printf("Switch away from alternate buffer\n"); 973 break; 974 default: 975 teken_printf("Unknown DECSET: %u\n", cmd); 976 } 977} 978 979static void 980teken_subr_set_mode(teken_t *t, unsigned int cmd) 981{ 982 983 switch (cmd) { 984 case 4: 985 teken_printf("Insert mode\n"); 986 t->t_stateflags |= TS_INSERT; 987 break; 988 default: 989 teken_printf("Unknown set mode: %u\n", cmd); 990 } 991} 992 993static void 994teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 995 unsigned int cmds[]) 996{ 997 unsigned int i, n; 998 999 /* No attributes means reset. */ 1000 if (ncmds == 0) { 1001 t->t_curattr = t->t_defattr; 1002 return; 1003 } 1004 1005 for (i = 0; i < ncmds; i++) { 1006 n = cmds[i]; 1007 1008 switch (n) { 1009 case 0: /* Reset. */ 1010 t->t_curattr = t->t_defattr; 1011 break; 1012 case 1: /* Bold. */ 1013 t->t_curattr.ta_format |= TF_BOLD; 1014 break; 1015 case 4: /* Underline. */ 1016 t->t_curattr.ta_format |= TF_UNDERLINE; 1017 break; 1018 case 5: /* Blink. */ 1019 t->t_curattr.ta_format |= TF_BLINK; 1020 break; 1021 case 7: /* Reverse. */ 1022 t->t_curattr.ta_format |= TF_REVERSE; 1023 break; 1024 case 22: /* Remove bold. */ 1025 t->t_curattr.ta_format &= ~TF_BOLD; 1026 break; 1027 case 24: /* Remove underline. */ 1028 t->t_curattr.ta_format &= ~TF_UNDERLINE; 1029 break; 1030 case 25: /* Remove blink. */ 1031 t->t_curattr.ta_format &= ~TF_BLINK; 1032 break; 1033 case 27: /* Remove reverse. */ 1034 t->t_curattr.ta_format &= ~TF_REVERSE; 1035 break; 1036 case 30: /* Set foreground color: black */ 1037 case 31: /* Set foreground color: red */ 1038 case 32: /* Set foreground color: green */ 1039 case 33: /* Set foreground color: brown */ 1040 case 34: /* Set foreground color: blue */ 1041 case 35: /* Set foreground color: magenta */ 1042 case 36: /* Set foreground color: cyan */ 1043 case 37: /* Set foreground color: white */ 1044 t->t_curattr.ta_fgcolor = n - 30; 1045 break; 1046 case 39: /* Set default foreground color. */ 1047 t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1048 break; 1049 case 40: /* Set background color: black */ 1050 case 41: /* Set background color: red */ 1051 case 42: /* Set background color: green */ 1052 case 43: /* Set background color: brown */ 1053 case 44: /* Set background color: blue */ 1054 case 45: /* Set background color: magenta */ 1055 case 46: /* Set background color: cyan */ 1056 case 47: /* Set background color: white */ 1057 t->t_curattr.ta_bgcolor = n - 40; 1058 break; 1059 case 49: /* Set default background color. */ 1060 t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1061 break; 1062 default: 1063 teken_printf("unsupported attribute %u\n", n); 1064 } 1065 } 1066} 1067 1068static void 1069teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1070 unsigned int bottom) 1071{ 1072 1073 /* Adjust top row number. */ 1074 if (top > 0) 1075 top--; 1076 /* Adjust bottom row number. */ 1077 if (bottom == 0 || bottom > t->t_winsize.tp_row) 1078 bottom = t->t_winsize.tp_row; 1079 1080 /* Invalid arguments. */ 1081 if (top >= bottom - 1) { 1082 top = 0; 1083 bottom = t->t_winsize.tp_row; 1084 } 1085 1086 t->t_scrollreg.ts_begin = top; 1087 t->t_scrollreg.ts_end = bottom; 1088 if (t->t_stateflags & TS_ORIGIN) { 1089 /* XXX: home cursor? */ 1090 t->t_originreg = t->t_scrollreg; 1091 t->t_cursor.tp_row = t->t_originreg.ts_begin; 1092 t->t_cursor.tp_col = 0; 1093 t->t_stateflags &= ~TS_WRAPPED; 1094 teken_funcs_cursor(t); 1095 } 1096} 1097 1098static void 1099teken_subr_single_height_double_width_line(teken_t *t __unused) 1100{ 1101 1102 teken_printf("single height double width???\n"); 1103} 1104 1105static void 1106teken_subr_single_height_single_width_line(teken_t *t __unused) 1107{ 1108 1109 teken_printf("single height single width???\n"); 1110} 1111 1112static void 1113teken_subr_string_terminator(teken_t *t __unused) 1114{ 1115 1116 teken_printf("string terminator???\n"); 1117} 1118 1119static void 1120teken_subr_tab_clear(teken_t *t, unsigned int cmd) 1121{ 1122 1123 switch (cmd) { 1124 case 0: 1125 teken_tab_clear(t, t->t_cursor.tp_col); 1126 break; 1127 case 3: 1128 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1129 break; 1130 } 1131} 1132 1133static void 1134teken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1135{ 1136 1137 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1138 if (row >= t->t_originreg.ts_end) 1139 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1140 1141 1142 t->t_stateflags &= ~TS_WRAPPED; 1143 teken_funcs_cursor(t); 1144}
| 683teken_subr_next_line(teken_t *t) 684{ 685 686 t->t_cursor.tp_col = 0; 687 teken_subr_newline(t); 688} 689 690static void 691teken_subr_pan_down(teken_t *t, unsigned int nrows) 692{ 693 694 teken_subr_do_scroll(t, (int)nrows); 695} 696 697static void 698teken_subr_pan_up(teken_t *t, unsigned int nrows) 699{ 700 701 teken_subr_do_scroll(t, -(int)nrows); 702} 703 704static void 705teken_subr_primary_device_attributes(teken_t *t, unsigned int request) 706{ 707 708 if (request == 0) { 709 const char response[] = "\x1B[?1;2c"; 710 711 teken_funcs_respond(t, response, sizeof response - 1); 712 } else { 713 teken_printf("Unknown DA1\n"); 714 } 715} 716 717static void 718teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 719 int width) 720{ 721 722 if (t->t_stateflags & TS_INSERT && 723 tp->tp_col < t->t_winsize.tp_col - width) { 724 teken_rect_t ctr; 725 teken_pos_t ctp; 726 727 /* Insert mode. Move existing characters to the right. */ 728 ctr.tr_begin = *tp; 729 ctr.tr_end.tp_row = tp->tp_row + 1; 730 ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 731 ctp.tp_row = tp->tp_row; 732 ctp.tp_col = tp->tp_col + width; 733 teken_funcs_copy(t, &ctr, &ctp); 734 } 735 736 teken_funcs_putchar(t, tp, c, &t->t_curattr); 737} 738 739static void 740teken_subr_regular_character(teken_t *t, teken_char_t c) 741{ 742 int width; 743 744 /* XXX: Don't process zero-width characters yet. */ 745 width = teken_wcwidth(c); 746 if (width <= 0) 747 return; 748 749#ifdef TEKEN_CONS25 750 teken_subr_do_putchar(t, &t->t_cursor, c, width); 751 t->t_cursor.tp_col += width; 752 753 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 754 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 755 /* Perform scrolling. */ 756 teken_subr_do_scroll(t, 1); 757 } else { 758 /* No scrolling needed. */ 759 if (t->t_cursor.tp_row < t->t_winsize.tp_row - 1) 760 t->t_cursor.tp_row++; 761 } 762 t->t_cursor.tp_col = 0; 763 } 764#else /* !TEKEN_CONS25 */ 765 if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 766 (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 767 (TS_WRAPPED|TS_AUTOWRAP)) { 768 teken_pos_t tp; 769 770 /* Perform line wrapping. */ 771 772 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 773 /* Perform scrolling. */ 774 teken_subr_do_scroll(t, 1); 775 tp.tp_row = t->t_scrollreg.ts_end - 1; 776 } else { 777 /* No scrolling needed. */ 778 tp.tp_row = t->t_cursor.tp_row + 1; 779 if (tp.tp_row == t->t_winsize.tp_row) { 780 /* 781 * Corner case: regular character 782 * outside scrolling region, but at the 783 * bottom of the screen. 784 */ 785 teken_subr_do_putchar(t, &t->t_cursor, 786 c, width); 787 return; 788 } 789 } 790 791 tp.tp_col = 0; 792 teken_subr_do_putchar(t, &tp, c, width); 793 794 t->t_cursor.tp_row = tp.tp_row; 795 t->t_cursor.tp_col = width; 796 t->t_stateflags &= ~TS_WRAPPED; 797 } else { 798 /* No line wrapping needed. */ 799 teken_subr_do_putchar(t, &t->t_cursor, c, width); 800 t->t_cursor.tp_col += width; 801 802 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 803 t->t_stateflags |= TS_WRAPPED; 804 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 805 } else { 806 t->t_stateflags &= ~TS_WRAPPED; 807 } 808 } 809#endif /* TEKEN_CONS25 */ 810 811 teken_funcs_cursor(t); 812} 813 814static void 815teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 816{ 817 818 switch (cmd) { 819 case 1: /* Cursor keys mode. */ 820 teken_funcs_param(t, TP_CURSORKEYS, 0); 821 break; 822 case 2: /* DECANM: ANSI/VT52 mode. */ 823 teken_printf("DECRST VT52\n"); 824 break; 825 case 3: /* 132 column mode. */ 826 teken_funcs_param(t, TP_132COLS, 0); 827 teken_subr_reset_to_initial_state(t); 828 break; 829 case 5: /* Inverse video. */ 830 teken_printf("DECRST inverse video\n"); 831 break; 832 case 6: /* Origin mode. */ 833 t->t_stateflags &= ~TS_ORIGIN; 834 t->t_originreg.ts_begin = 0; 835 t->t_originreg.ts_end = t->t_winsize.tp_row; 836 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 837 t->t_stateflags &= ~TS_WRAPPED; 838 teken_funcs_cursor(t); 839 break; 840 case 7: /* Autowrap mode. */ 841 t->t_stateflags &= ~TS_AUTOWRAP; 842 break; 843 case 8: /* Autorepeat mode. */ 844 teken_funcs_param(t, TP_AUTOREPEAT, 0); 845 break; 846 case 25: /* Hide cursor. */ 847 teken_funcs_param(t, TP_SHOWCURSOR, 0); 848 break; 849 case 40: /* Disallow 132 columns. */ 850 teken_printf("DECRST allow 132\n"); 851 break; 852 case 45: /* Disable reverse wraparound. */ 853 teken_printf("DECRST reverse wraparound\n"); 854 break; 855 case 47: /* Switch to alternate buffer. */ 856 teken_printf("Switch to alternate buffer\n"); 857 break; 858 default: 859 teken_printf("Unknown DECRST: %u\n", cmd); 860 } 861} 862 863static void 864teken_subr_reset_mode(teken_t *t, unsigned int cmd) 865{ 866 867 switch (cmd) { 868 case 4: 869 t->t_stateflags &= ~TS_INSERT; 870 break; 871 default: 872 teken_printf("Unknown reset mode: %u\n", cmd); 873 } 874} 875 876static void 877teken_subr_do_reset(teken_t *t) 878{ 879 880 t->t_curattr = t->t_saved_curattr = t->t_defattr; 881 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 882 t->t_saved_cursor = t->t_cursor; 883 t->t_stateflags = TS_AUTOWRAP; 884 885 teken_tab_default(t); 886} 887 888static void 889teken_subr_reset_to_initial_state(teken_t *t) 890{ 891 892 teken_subr_do_reset(t); 893 teken_subr_erase_display(t, 2); 894 teken_funcs_param(t, TP_SHOWCURSOR, 1); 895 teken_funcs_cursor(t); 896} 897 898static void 899teken_subr_restore_cursor(teken_t *t) 900{ 901 902 t->t_cursor = t->t_saved_cursor; 903 t->t_curattr = t->t_saved_curattr; 904 t->t_stateflags &= ~TS_WRAPPED; 905 teken_funcs_cursor(t); 906} 907 908static void 909teken_subr_reverse_index(teken_t *t) 910{ 911 912 if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 913 t->t_cursor.tp_row--; 914 t->t_stateflags &= ~TS_WRAPPED; 915 teken_funcs_cursor(t); 916 } else { 917 teken_subr_do_scroll(t, -1); 918 } 919} 920 921static void 922teken_subr_save_cursor(teken_t *t) 923{ 924 925 t->t_saved_cursor = t->t_cursor; 926 t->t_saved_curattr = t->t_curattr; 927} 928 929static void 930teken_subr_scs(teken_t *t __unused) 931{ 932 933 teken_printf("scs???\n"); 934} 935 936static void 937teken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 938{ 939 940 if (request == 0) { 941 const char response[] = "\x1B[>0;10;0c"; 942 teken_funcs_respond(t, response, sizeof response - 1); 943 } else { 944 teken_printf("Unknown DA2\n"); 945 } 946} 947 948static void 949teken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 950{ 951 952 switch (cmd) { 953 case 1: /* Cursor keys mode. */ 954 teken_funcs_param(t, TP_CURSORKEYS, 1); 955 break; 956 case 2: /* DECANM: ANSI/VT52 mode. */ 957 teken_printf("DECSET VT52\n"); 958 break; 959 case 3: /* 132 column mode. */ 960 teken_funcs_param(t, TP_132COLS, 1); 961 teken_subr_reset_to_initial_state(t); 962 break; 963 case 5: /* Inverse video. */ 964 teken_printf("DECSET inverse video\n"); 965 break; 966 case 6: /* Origin mode. */ 967 t->t_stateflags |= TS_ORIGIN; 968 t->t_originreg = t->t_scrollreg; 969 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 970 t->t_cursor.tp_col = 0; 971 t->t_stateflags &= ~TS_WRAPPED; 972 teken_funcs_cursor(t); 973 break; 974 case 7: /* Autowrap mode. */ 975 t->t_stateflags |= TS_AUTOWRAP; 976 break; 977 case 8: /* Autorepeat mode. */ 978 teken_funcs_param(t, TP_AUTOREPEAT, 1); 979 break; 980 case 25: /* Display cursor. */ 981 teken_funcs_param(t, TP_SHOWCURSOR, 1); 982 break; 983 case 40: /* Allow 132 columns. */ 984 teken_printf("DECSET allow 132\n"); 985 break; 986 case 45: /* Enable reverse wraparound. */ 987 teken_printf("DECSET reverse wraparound\n"); 988 break; 989 case 47: /* Switch to alternate buffer. */ 990 teken_printf("Switch away from alternate buffer\n"); 991 break; 992 default: 993 teken_printf("Unknown DECSET: %u\n", cmd); 994 } 995} 996 997static void 998teken_subr_set_mode(teken_t *t, unsigned int cmd) 999{ 1000 1001 switch (cmd) { 1002 case 4: 1003 teken_printf("Insert mode\n"); 1004 t->t_stateflags |= TS_INSERT; 1005 break; 1006 default: 1007 teken_printf("Unknown set mode: %u\n", cmd); 1008 } 1009} 1010 1011static void 1012teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1013 unsigned int cmds[]) 1014{ 1015 unsigned int i, n; 1016 1017 /* No attributes means reset. */ 1018 if (ncmds == 0) { 1019 t->t_curattr = t->t_defattr; 1020 return; 1021 } 1022 1023 for (i = 0; i < ncmds; i++) { 1024 n = cmds[i]; 1025 1026 switch (n) { 1027 case 0: /* Reset. */ 1028 t->t_curattr = t->t_defattr; 1029 break; 1030 case 1: /* Bold. */ 1031 t->t_curattr.ta_format |= TF_BOLD; 1032 break; 1033 case 4: /* Underline. */ 1034 t->t_curattr.ta_format |= TF_UNDERLINE; 1035 break; 1036 case 5: /* Blink. */ 1037 t->t_curattr.ta_format |= TF_BLINK; 1038 break; 1039 case 7: /* Reverse. */ 1040 t->t_curattr.ta_format |= TF_REVERSE; 1041 break; 1042 case 22: /* Remove bold. */ 1043 t->t_curattr.ta_format &= ~TF_BOLD; 1044 break; 1045 case 24: /* Remove underline. */ 1046 t->t_curattr.ta_format &= ~TF_UNDERLINE; 1047 break; 1048 case 25: /* Remove blink. */ 1049 t->t_curattr.ta_format &= ~TF_BLINK; 1050 break; 1051 case 27: /* Remove reverse. */ 1052 t->t_curattr.ta_format &= ~TF_REVERSE; 1053 break; 1054 case 30: /* Set foreground color: black */ 1055 case 31: /* Set foreground color: red */ 1056 case 32: /* Set foreground color: green */ 1057 case 33: /* Set foreground color: brown */ 1058 case 34: /* Set foreground color: blue */ 1059 case 35: /* Set foreground color: magenta */ 1060 case 36: /* Set foreground color: cyan */ 1061 case 37: /* Set foreground color: white */ 1062 t->t_curattr.ta_fgcolor = n - 30; 1063 break; 1064 case 39: /* Set default foreground color. */ 1065 t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1066 break; 1067 case 40: /* Set background color: black */ 1068 case 41: /* Set background color: red */ 1069 case 42: /* Set background color: green */ 1070 case 43: /* Set background color: brown */ 1071 case 44: /* Set background color: blue */ 1072 case 45: /* Set background color: magenta */ 1073 case 46: /* Set background color: cyan */ 1074 case 47: /* Set background color: white */ 1075 t->t_curattr.ta_bgcolor = n - 40; 1076 break; 1077 case 49: /* Set default background color. */ 1078 t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1079 break; 1080 default: 1081 teken_printf("unsupported attribute %u\n", n); 1082 } 1083 } 1084} 1085 1086static void 1087teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1088 unsigned int bottom) 1089{ 1090 1091 /* Adjust top row number. */ 1092 if (top > 0) 1093 top--; 1094 /* Adjust bottom row number. */ 1095 if (bottom == 0 || bottom > t->t_winsize.tp_row) 1096 bottom = t->t_winsize.tp_row; 1097 1098 /* Invalid arguments. */ 1099 if (top >= bottom - 1) { 1100 top = 0; 1101 bottom = t->t_winsize.tp_row; 1102 } 1103 1104 t->t_scrollreg.ts_begin = top; 1105 t->t_scrollreg.ts_end = bottom; 1106 if (t->t_stateflags & TS_ORIGIN) { 1107 /* XXX: home cursor? */ 1108 t->t_originreg = t->t_scrollreg; 1109 t->t_cursor.tp_row = t->t_originreg.ts_begin; 1110 t->t_cursor.tp_col = 0; 1111 t->t_stateflags &= ~TS_WRAPPED; 1112 teken_funcs_cursor(t); 1113 } 1114} 1115 1116static void 1117teken_subr_single_height_double_width_line(teken_t *t __unused) 1118{ 1119 1120 teken_printf("single height double width???\n"); 1121} 1122 1123static void 1124teken_subr_single_height_single_width_line(teken_t *t __unused) 1125{ 1126 1127 teken_printf("single height single width???\n"); 1128} 1129 1130static void 1131teken_subr_string_terminator(teken_t *t __unused) 1132{ 1133 1134 teken_printf("string terminator???\n"); 1135} 1136 1137static void 1138teken_subr_tab_clear(teken_t *t, unsigned int cmd) 1139{ 1140 1141 switch (cmd) { 1142 case 0: 1143 teken_tab_clear(t, t->t_cursor.tp_col); 1144 break; 1145 case 3: 1146 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1147 break; 1148 } 1149} 1150 1151static void 1152teken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1153{ 1154 1155 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1156 if (row >= t->t_originreg.ts_end) 1157 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1158 1159 1160 t->t_stateflags &= ~TS_WRAPPED; 1161 teken_funcs_cursor(t); 1162}
|