teken_subr.h revision 211113
1186681Sed/*- 2186681Sed * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 3186681Sed * All rights reserved. 4186681Sed * 5186681Sed * Redistribution and use in source and binary forms, with or without 6186681Sed * modification, are permitted provided that the following conditions 7186681Sed * are met: 8186681Sed * 1. Redistributions of source code must retain the above copyright 9186681Sed * notice, this list of conditions and the following disclaimer. 10186681Sed * 2. Redistributions in binary form must reproduce the above copyright 11186681Sed * notice, this list of conditions and the following disclaimer in the 12186681Sed * documentation and/or other materials provided with the distribution. 13186681Sed * 14186681Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15186681Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16186681Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17186681Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18186681Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19186681Sed * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20186681Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21186681Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22186681Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23186681Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24186681Sed * SUCH DAMAGE. 25186681Sed * 26186681Sed * $FreeBSD: head/sys/teken/teken_subr.h 211113 2010-08-09 18:07:15Z ed $ 27186681Sed */ 28186681Sed 29186681Sedstatic void teken_subr_cursor_up(teken_t *, unsigned int); 30186681Sedstatic void teken_subr_erase_line(teken_t *, unsigned int); 31186681Sedstatic void teken_subr_regular_character(teken_t *, teken_char_t); 32186681Sedstatic void teken_subr_reset_to_initial_state(teken_t *); 33187469Sedstatic void teken_subr_save_cursor(teken_t *); 34186681Sed 35186681Sedstatic inline int 36186681Sedteken_tab_isset(teken_t *t, unsigned int col) 37186681Sed{ 38186681Sed unsigned int b, o; 39186681Sed 40190157Sed if (col >= T_NUMCOL) 41190158Sed return ((col % 8) == 0); 42186681Sed 43186681Sed b = col / (sizeof(unsigned int) * 8); 44186681Sed o = col % (sizeof(unsigned int) * 8); 45186681Sed 46186681Sed return (t->t_tabstops[b] & (1 << o)); 47186681Sed} 48186681Sed 49186681Sedstatic inline void 50186681Sedteken_tab_clear(teken_t *t, unsigned int col) 51186681Sed{ 52186681Sed unsigned int b, o; 53186681Sed 54190157Sed if (col >= T_NUMCOL) 55190157Sed return; 56186681Sed 57186681Sed b = col / (sizeof(unsigned int) * 8); 58186681Sed o = col % (sizeof(unsigned int) * 8); 59186681Sed 60186681Sed t->t_tabstops[b] &= ~(1 << o); 61186681Sed} 62186681Sed 63186681Sedstatic inline void 64186681Sedteken_tab_set(teken_t *t, unsigned int col) 65186681Sed{ 66186681Sed unsigned int b, o; 67186681Sed 68190157Sed if (col >= T_NUMCOL) 69190157Sed return; 70186681Sed 71186681Sed b = col / (sizeof(unsigned int) * 8); 72186681Sed o = col % (sizeof(unsigned int) * 8); 73186681Sed 74186681Sed t->t_tabstops[b] |= 1 << o; 75186681Sed} 76186681Sed 77186681Sedstatic void 78186681Sedteken_tab_default(teken_t *t) 79186681Sed{ 80186681Sed unsigned int i; 81186681Sed 82186681Sed memset(&t->t_tabstops, 0, T_NUMCOL / 8); 83186681Sed 84186681Sed for (i = 8; i < T_NUMCOL; i += 8) 85186681Sed teken_tab_set(t, i); 86186681Sed} 87186681Sed 88186681Sedstatic void 89186681Sedteken_subr_do_scroll(teken_t *t, int amount) 90186681Sed{ 91186681Sed teken_rect_t tr; 92186681Sed teken_pos_t tp; 93186681Sed 94186681Sed teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); 95186681Sed teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); 96186681Sed teken_assert(amount != 0); 97186681Sed 98186681Sed /* Copy existing data 1 line up. */ 99186681Sed if (amount > 0) { 100186681Sed /* Scroll down. */ 101186681Sed 102186681Sed /* Copy existing data up. */ 103186681Sed if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 104186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; 105186681Sed tr.tr_begin.tp_col = 0; 106186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 107186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 108186681Sed tp.tp_row = t->t_scrollreg.ts_begin; 109186681Sed tp.tp_col = 0; 110186681Sed teken_funcs_copy(t, &tr, &tp); 111186681Sed 112186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; 113186681Sed } else { 114186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 115186681Sed } 116186681Sed 117186681Sed /* Clear the last lines. */ 118186681Sed tr.tr_begin.tp_col = 0; 119186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 120186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 121186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 122186681Sed } else { 123186681Sed /* Scroll up. */ 124186681Sed amount = -amount; 125186681Sed 126186681Sed /* Copy existing data down. */ 127186681Sed if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 128186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 129186681Sed tr.tr_begin.tp_col = 0; 130186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; 131186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 132186681Sed tp.tp_row = t->t_scrollreg.ts_begin + amount; 133186681Sed tp.tp_col = 0; 134186681Sed teken_funcs_copy(t, &tr, &tp); 135186681Sed 136186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; 137186681Sed } else { 138186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 139186681Sed } 140186681Sed 141186681Sed /* Clear the first lines. */ 142186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 143186681Sed tr.tr_begin.tp_col = 0; 144186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 145186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 146186681Sed } 147186681Sed} 148186681Sed 149186681Sedstatic ssize_t 150186681Sedteken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16]) 151186681Sed{ 152186681Sed 153186681Sed switch (cmd) { 154186681Sed case 5: /* Operating status. */ 155186681Sed strcpy(response, "0n"); 156186681Sed return (2); 157186681Sed case 6: { /* Cursor position. */ 158186681Sed int len; 159186681Sed 160186681Sed len = snprintf(response, 16, "%u;%uR", 161186681Sed (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, 162186681Sed t->t_cursor.tp_col + 1); 163186681Sed 164186681Sed if (len >= 16) 165186681Sed return (-1); 166186681Sed return (len); 167186681Sed } 168186681Sed case 15: /* Printer status. */ 169186681Sed strcpy(response, "13n"); 170186681Sed return (3); 171186681Sed case 25: /* UDK status. */ 172186681Sed strcpy(response, "20n"); 173186681Sed return (3); 174186681Sed case 26: /* Keyboard status. */ 175186681Sed strcpy(response, "27;1n"); 176186681Sed return (5); 177186681Sed default: 178186681Sed teken_printf("Unknown DSR\n"); 179186681Sed return (-1); 180186681Sed } 181186681Sed} 182186681Sed 183186681Sedstatic void 184186681Sedteken_subr_alignment_test(teken_t *t) 185186681Sed{ 186186681Sed teken_rect_t tr; 187186681Sed 188197521Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 189186681Sed t->t_scrollreg.ts_begin = 0; 190186681Sed t->t_scrollreg.ts_end = t->t_winsize.tp_row; 191197521Sed t->t_originreg = t->t_scrollreg; 192197521Sed t->t_stateflags &= ~(TS_WRAPPED|TS_ORIGIN); 193186681Sed teken_funcs_cursor(t); 194186681Sed 195186681Sed tr.tr_begin.tp_row = 0; 196186681Sed tr.tr_begin.tp_col = 0; 197186681Sed tr.tr_end = t->t_winsize; 198186681Sed teken_funcs_fill(t, &tr, 'E', &t->t_defattr); 199186681Sed} 200186681Sed 201186681Sedstatic void 202186681Sedteken_subr_backspace(teken_t *t) 203186681Sed{ 204186681Sed 205197117Sed if (t->t_stateflags & TS_CONS25) { 206197117Sed if (t->t_cursor.tp_col == 0) { 207197117Sed if (t->t_cursor.tp_row == t->t_originreg.ts_begin) 208197117Sed return; 209197117Sed t->t_cursor.tp_row--; 210197117Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 211197117Sed } else { 212197117Sed t->t_cursor.tp_col--; 213197117Sed } 214197117Sed } else { 215197117Sed if (t->t_cursor.tp_col == 0) 216197117Sed return; 217187367Sed 218186753Sed t->t_cursor.tp_col--; 219197117Sed t->t_stateflags &= ~TS_WRAPPED; 220186753Sed } 221186681Sed 222186681Sed teken_funcs_cursor(t); 223186681Sed} 224186681Sed 225186681Sedstatic void 226186681Sedteken_subr_bell(teken_t *t) 227186681Sed{ 228186681Sed 229186681Sed teken_funcs_bell(t); 230186681Sed} 231186681Sed 232186681Sedstatic void 233186681Sedteken_subr_carriage_return(teken_t *t) 234186681Sed{ 235186681Sed 236186681Sed t->t_cursor.tp_col = 0; 237186681Sed t->t_stateflags &= ~TS_WRAPPED; 238186681Sed teken_funcs_cursor(t); 239186681Sed} 240186681Sed 241186681Sedstatic void 242186681Sedteken_subr_cursor_backward(teken_t *t, unsigned int ncols) 243186681Sed{ 244186681Sed 245186681Sed if (ncols > t->t_cursor.tp_col) 246186681Sed t->t_cursor.tp_col = 0; 247186681Sed else 248186681Sed t->t_cursor.tp_col -= ncols; 249186681Sed t->t_stateflags &= ~TS_WRAPPED; 250186681Sed teken_funcs_cursor(t); 251186681Sed} 252186681Sed 253186681Sedstatic void 254186681Sedteken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) 255186681Sed{ 256186681Sed 257186681Sed do { 258186681Sed /* Stop when we've reached the beginning of the line. */ 259186681Sed if (t->t_cursor.tp_col == 0) 260186681Sed break; 261186681Sed 262186681Sed t->t_cursor.tp_col--; 263186681Sed 264186681Sed /* Tab marker set. */ 265186681Sed if (teken_tab_isset(t, t->t_cursor.tp_col)) 266186681Sed ntabs--; 267186681Sed } while (ntabs > 0); 268186729Sed 269186729Sed teken_funcs_cursor(t); 270186681Sed} 271186681Sed 272186681Sedstatic void 273186681Sedteken_subr_cursor_down(teken_t *t, unsigned int nrows) 274186681Sed{ 275186681Sed 276186681Sed if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) 277186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 278186681Sed else 279186681Sed t->t_cursor.tp_row += nrows; 280186681Sed t->t_stateflags &= ~TS_WRAPPED; 281186681Sed teken_funcs_cursor(t); 282186681Sed} 283186681Sed 284186681Sedstatic void 285186681Sedteken_subr_cursor_forward(teken_t *t, unsigned int ncols) 286186681Sed{ 287186681Sed 288186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 289186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 290186681Sed else 291186681Sed t->t_cursor.tp_col += ncols; 292186681Sed t->t_stateflags &= ~TS_WRAPPED; 293186681Sed teken_funcs_cursor(t); 294186681Sed} 295186681Sed 296186681Sedstatic void 297186681Sedteken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) 298186681Sed{ 299186681Sed 300186681Sed do { 301186681Sed /* Stop when we've reached the end of the line. */ 302186681Sed if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) 303186681Sed break; 304186681Sed 305186681Sed t->t_cursor.tp_col++; 306186681Sed 307186681Sed /* Tab marker set. */ 308186681Sed if (teken_tab_isset(t, t->t_cursor.tp_col)) 309186681Sed ntabs--; 310186681Sed } while (ntabs > 0); 311186729Sed 312186729Sed teken_funcs_cursor(t); 313186681Sed} 314186681Sed 315186681Sedstatic void 316186681Sedteken_subr_cursor_next_line(teken_t *t, unsigned int ncols) 317186681Sed{ 318186681Sed 319186681Sed t->t_cursor.tp_col = 0; 320186681Sed teken_subr_cursor_down(t, ncols); 321186681Sed} 322186681Sed 323186681Sedstatic void 324186681Sedteken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) 325186681Sed{ 326186681Sed 327186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 328186681Sed if (row >= t->t_originreg.ts_end) 329186681Sed t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 330186681Sed 331186681Sed t->t_cursor.tp_col = col - 1; 332186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 333186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 334186681Sed 335186681Sed t->t_stateflags &= ~TS_WRAPPED; 336186681Sed teken_funcs_cursor(t); 337186681Sed} 338186681Sed 339186681Sedstatic void 340186681Sedteken_subr_cursor_position_report(teken_t *t, unsigned int cmd) 341186681Sed{ 342186681Sed char response[18] = "\x1B["; 343186681Sed ssize_t len; 344186681Sed 345186681Sed len = teken_subr_do_cpr(t, cmd, response + 2); 346186681Sed if (len < 0) 347186681Sed return; 348186681Sed 349186681Sed teken_funcs_respond(t, response, len + 2); 350186681Sed} 351186681Sed 352186681Sedstatic void 353186681Sedteken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) 354186681Sed{ 355186681Sed 356186681Sed t->t_cursor.tp_col = 0; 357186681Sed teken_subr_cursor_up(t, ncols); 358186681Sed} 359186681Sed 360186681Sedstatic void 361186681Sedteken_subr_cursor_up(teken_t *t, unsigned int nrows) 362186681Sed{ 363186681Sed 364186681Sed if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) 365186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 366186681Sed else 367186681Sed t->t_cursor.tp_row -= nrows; 368186681Sed t->t_stateflags &= ~TS_WRAPPED; 369186681Sed teken_funcs_cursor(t); 370186681Sed} 371186681Sed 372186681Sedstatic void 373186681Sedteken_subr_delete_character(teken_t *t, unsigned int ncols) 374186681Sed{ 375186681Sed teken_rect_t tr; 376186681Sed 377186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row; 378186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 379186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 380186681Sed 381186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 382186681Sed tr.tr_begin.tp_col = t->t_cursor.tp_col; 383186681Sed } else { 384186681Sed /* Copy characters to the left. */ 385186681Sed tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; 386186681Sed teken_funcs_copy(t, &tr, &t->t_cursor); 387186681Sed 388186681Sed tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; 389186681Sed } 390186681Sed 391186681Sed /* Blank trailing columns. */ 392186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 393186681Sed} 394186681Sed 395186681Sedstatic void 396186681Sedteken_subr_delete_line(teken_t *t, unsigned int nrows) 397186681Sed{ 398186681Sed teken_rect_t tr; 399186681Sed 400197480Sed /* Ignore if outside scrolling region. */ 401197480Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 402197480Sed t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 403197480Sed return; 404197480Sed 405186681Sed tr.tr_begin.tp_col = 0; 406186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 407186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 408186681Sed 409186681Sed if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 410186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row; 411186681Sed } else { 412186681Sed teken_pos_t tp; 413186681Sed 414186681Sed /* Copy rows up. */ 415186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; 416186681Sed tp.tp_row = t->t_cursor.tp_row; 417186681Sed tp.tp_col = 0; 418186681Sed teken_funcs_copy(t, &tr, &tp); 419186681Sed 420186681Sed tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; 421186681Sed } 422186681Sed 423186681Sed /* Blank trailing rows. */ 424186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 425186681Sed} 426186681Sed 427186681Sedstatic void 428197853Sedteken_subr_device_control_string(teken_t *t) 429186681Sed{ 430186681Sed 431197853Sed teken_printf("Unsupported device control string\n"); 432197853Sed t->t_stateflags |= TS_INSTRING; 433186681Sed} 434186681Sed 435186681Sedstatic void 436186681Sedteken_subr_device_status_report(teken_t *t, unsigned int cmd) 437186681Sed{ 438186681Sed char response[19] = "\x1B[?"; 439186681Sed ssize_t len; 440186681Sed 441186681Sed len = teken_subr_do_cpr(t, cmd, response + 3); 442186681Sed if (len < 0) 443186681Sed return; 444186681Sed 445186681Sed teken_funcs_respond(t, response, len + 3); 446186681Sed} 447186681Sed 448186681Sedstatic void 449186681Sedteken_subr_double_height_double_width_line_top(teken_t *t __unused) 450186681Sed{ 451186681Sed 452186681Sed teken_printf("double height double width top\n"); 453186681Sed} 454186681Sed 455186681Sedstatic void 456186681Sedteken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 457186681Sed{ 458186681Sed 459186681Sed teken_printf("double height double width bottom\n"); 460186681Sed} 461186681Sed 462186681Sedstatic void 463186681Sedteken_subr_erase_character(teken_t *t, unsigned int ncols) 464186681Sed{ 465186681Sed teken_rect_t tr; 466186681Sed 467186681Sed tr.tr_begin = t->t_cursor; 468186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 469186681Sed 470186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 471186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 472186681Sed else 473186681Sed tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 474186681Sed 475186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 476186681Sed} 477186681Sed 478186681Sedstatic void 479186681Sedteken_subr_erase_display(teken_t *t, unsigned int mode) 480186681Sed{ 481186681Sed teken_rect_t r; 482186681Sed 483186681Sed r.tr_begin.tp_col = 0; 484186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 485186681Sed 486186681Sed switch (mode) { 487186681Sed case 1: /* Erase from the top to the cursor. */ 488186681Sed teken_subr_erase_line(t, 1); 489186681Sed 490186681Sed /* Erase lines above. */ 491186681Sed if (t->t_cursor.tp_row == 0) 492186681Sed return; 493186681Sed r.tr_begin.tp_row = 0; 494186681Sed r.tr_end.tp_row = t->t_cursor.tp_row; 495186681Sed break; 496186681Sed case 2: /* Erase entire display. */ 497186681Sed r.tr_begin.tp_row = 0; 498186681Sed r.tr_end.tp_row = t->t_winsize.tp_row; 499186681Sed break; 500186681Sed default: /* Erase from cursor to the bottom. */ 501186681Sed teken_subr_erase_line(t, 0); 502186681Sed 503186681Sed /* Erase lines below. */ 504186681Sed if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 505186681Sed return; 506186681Sed r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 507186681Sed r.tr_end.tp_row = t->t_winsize.tp_row; 508186681Sed break; 509186681Sed } 510186681Sed 511186681Sed teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 512186681Sed} 513186681Sed 514186681Sedstatic void 515186681Sedteken_subr_erase_line(teken_t *t, unsigned int mode) 516186681Sed{ 517186681Sed teken_rect_t r; 518186681Sed 519186681Sed r.tr_begin.tp_row = t->t_cursor.tp_row; 520186681Sed r.tr_end.tp_row = t->t_cursor.tp_row + 1; 521186681Sed 522186681Sed switch (mode) { 523186681Sed case 1: /* Erase from the beginning of the line to the cursor. */ 524186681Sed r.tr_begin.tp_col = 0; 525186681Sed r.tr_end.tp_col = t->t_cursor.tp_col + 1; 526186681Sed break; 527186681Sed case 2: /* Erase entire line. */ 528186681Sed r.tr_begin.tp_col = 0; 529186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 530186681Sed break; 531186681Sed default: /* Erase from cursor to the end of the line. */ 532186681Sed r.tr_begin.tp_col = t->t_cursor.tp_col; 533186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 534186681Sed break; 535186681Sed } 536186681Sed 537186681Sed teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 538186681Sed} 539186681Sed 540186681Sedstatic void 541187469Sedteken_subr_g0_scs_special_graphics(teken_t *t __unused) 542187469Sed{ 543187469Sed 544197520Sed t->t_scs[0] = teken_scs_special_graphics; 545187469Sed} 546187469Sed 547187469Sedstatic void 548187469Sedteken_subr_g0_scs_uk_national(teken_t *t __unused) 549187469Sed{ 550187469Sed 551197520Sed t->t_scs[0] = teken_scs_uk_national; 552187469Sed} 553187469Sed 554187469Sedstatic void 555187469Sedteken_subr_g0_scs_us_ascii(teken_t *t __unused) 556187469Sed{ 557187469Sed 558197520Sed t->t_scs[0] = teken_scs_us_ascii; 559187469Sed} 560187469Sed 561187469Sedstatic void 562187469Sedteken_subr_g1_scs_special_graphics(teken_t *t __unused) 563187469Sed{ 564187469Sed 565197520Sed t->t_scs[1] = teken_scs_special_graphics; 566187469Sed} 567187469Sed 568187469Sedstatic void 569187469Sedteken_subr_g1_scs_uk_national(teken_t *t __unused) 570187469Sed{ 571187469Sed 572197520Sed t->t_scs[1] = teken_scs_uk_national; 573187469Sed} 574187469Sed 575187469Sedstatic void 576187469Sedteken_subr_g1_scs_us_ascii(teken_t *t __unused) 577187469Sed{ 578187469Sed 579197520Sed t->t_scs[1] = teken_scs_us_ascii; 580187469Sed} 581187469Sed 582187469Sedstatic void 583186681Sedteken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 584186681Sed{ 585186681Sed 586186681Sed t->t_cursor.tp_col = col - 1; 587186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 588186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 589186681Sed 590186681Sed t->t_stateflags &= ~TS_WRAPPED; 591186681Sed teken_funcs_cursor(t); 592186681Sed} 593186681Sed 594186681Sedstatic void 595186681Sedteken_subr_horizontal_tab(teken_t *t) 596186681Sed{ 597186681Sed 598197117Sed if (t->t_stateflags & TS_CONS25) { 599197117Sed teken_subr_cursor_forward_tabulation(t, 1); 600197117Sed } else { 601197117Sed teken_rect_t tr; 602186681Sed 603197117Sed tr.tr_begin = t->t_cursor; 604197117Sed teken_subr_cursor_forward_tabulation(t, 1); 605197117Sed tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 606197117Sed tr.tr_end.tp_col = t->t_cursor.tp_col; 607187367Sed 608197117Sed /* Blank region that we skipped. */ 609197117Sed if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 610197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 611197117Sed } 612186681Sed} 613186681Sed 614186681Sedstatic void 615186681Sedteken_subr_horizontal_tab_set(teken_t *t) 616186681Sed{ 617186681Sed 618186681Sed teken_tab_set(t, t->t_cursor.tp_col); 619186681Sed} 620186681Sed 621186681Sedstatic void 622186681Sedteken_subr_index(teken_t *t) 623186681Sed{ 624186681Sed 625186681Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 626186681Sed t->t_cursor.tp_row++; 627186681Sed t->t_stateflags &= ~TS_WRAPPED; 628186681Sed teken_funcs_cursor(t); 629186681Sed } else { 630186681Sed teken_subr_do_scroll(t, 1); 631186681Sed } 632186681Sed} 633186681Sed 634186681Sedstatic void 635186681Sedteken_subr_insert_character(teken_t *t, unsigned int ncols) 636186681Sed{ 637186681Sed teken_rect_t tr; 638186681Sed 639186681Sed tr.tr_begin = t->t_cursor; 640186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 641186681Sed 642186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 643186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 644186681Sed } else { 645186681Sed teken_pos_t tp; 646186681Sed 647186681Sed /* Copy characters to the right. */ 648186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 649186681Sed tp.tp_row = t->t_cursor.tp_row; 650186681Sed tp.tp_col = t->t_cursor.tp_col + ncols; 651186681Sed teken_funcs_copy(t, &tr, &tp); 652186681Sed 653186681Sed tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 654186681Sed } 655186681Sed 656186681Sed /* Blank current location. */ 657186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 658186681Sed} 659186681Sed 660186681Sedstatic void 661186681Sedteken_subr_insert_line(teken_t *t, unsigned int nrows) 662186681Sed{ 663186681Sed teken_rect_t tr; 664186681Sed 665197480Sed /* Ignore if outside scrolling region. */ 666197480Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 667197480Sed t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 668197480Sed return; 669197480Sed 670186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row; 671186681Sed tr.tr_begin.tp_col = 0; 672186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 673186681Sed 674186681Sed if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 675186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 676186681Sed } else { 677186681Sed teken_pos_t tp; 678186681Sed 679186681Sed /* Copy lines down. */ 680186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 681186681Sed tp.tp_row = t->t_cursor.tp_row + nrows; 682186681Sed tp.tp_col = 0; 683186681Sed teken_funcs_copy(t, &tr, &tp); 684186681Sed 685186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 686186681Sed } 687186681Sed 688186681Sed /* Blank current location. */ 689186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 690186681Sed} 691186681Sed 692186681Sedstatic void 693186681Sedteken_subr_keypad_application_mode(teken_t *t) 694186681Sed{ 695186681Sed 696186681Sed teken_funcs_param(t, TP_KEYPADAPP, 1); 697186681Sed} 698186681Sed 699186681Sedstatic void 700186681Sedteken_subr_keypad_numeric_mode(teken_t *t) 701186681Sed{ 702186681Sed 703186681Sed teken_funcs_param(t, TP_KEYPADAPP, 0); 704186681Sed} 705186681Sed 706186681Sedstatic void 707186681Sedteken_subr_newline(teken_t *t) 708186681Sed{ 709186681Sed 710186681Sed t->t_cursor.tp_row++; 711186681Sed 712186681Sed if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 713186681Sed teken_subr_do_scroll(t, 1); 714186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 715186681Sed } 716186681Sed 717186681Sed t->t_stateflags &= ~TS_WRAPPED; 718186681Sed teken_funcs_cursor(t); 719186681Sed} 720186681Sed 721186681Sedstatic void 722186798Sedteken_subr_newpage(teken_t *t) 723186798Sed{ 724187367Sed 725197117Sed if (t->t_stateflags & TS_CONS25) { 726197117Sed teken_rect_t tr; 727186798Sed 728211113Sed /* Clear screen. */ 729211113Sed tr.tr_begin.tp_row = t->t_originreg.ts_begin; 730211113Sed tr.tr_begin.tp_col = 0; 731211113Sed tr.tr_end.tp_row = t->t_originreg.ts_end; 732211113Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 733197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 734186798Sed 735211113Sed /* Cursor at top left. */ 736211113Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 737211113Sed t->t_cursor.tp_col = 0; 738211113Sed t->t_stateflags &= ~TS_WRAPPED; 739197117Sed teken_funcs_cursor(t); 740197117Sed } else { 741197117Sed teken_subr_newline(t); 742197117Sed } 743186798Sed} 744186798Sed 745186798Sedstatic void 746186681Sedteken_subr_next_line(teken_t *t) 747186681Sed{ 748186681Sed 749186681Sed t->t_cursor.tp_col = 0; 750186681Sed teken_subr_newline(t); 751186681Sed} 752186681Sed 753186681Sedstatic void 754197853Sedteken_subr_operating_system_command(teken_t *t) 755197853Sed{ 756197853Sed 757197853Sed teken_printf("Unsupported operating system command\n"); 758197853Sed t->t_stateflags |= TS_INSTRING; 759197853Sed} 760197853Sed 761197853Sedstatic void 762186681Sedteken_subr_pan_down(teken_t *t, unsigned int nrows) 763186681Sed{ 764186681Sed 765186681Sed teken_subr_do_scroll(t, (int)nrows); 766186681Sed} 767186681Sed 768186681Sedstatic void 769186681Sedteken_subr_pan_up(teken_t *t, unsigned int nrows) 770186681Sed{ 771186681Sed 772186681Sed teken_subr_do_scroll(t, -(int)nrows); 773186681Sed} 774186681Sed 775186681Sedstatic void 776186681Sedteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 777186681Sed{ 778186681Sed 779186681Sed if (request == 0) { 780186681Sed const char response[] = "\x1B[?1;2c"; 781186681Sed 782186681Sed teken_funcs_respond(t, response, sizeof response - 1); 783186681Sed } else { 784186681Sed teken_printf("Unknown DA1\n"); 785186681Sed } 786186681Sed} 787186681Sed 788186681Sedstatic void 789186681Sedteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 790186681Sed int width) 791186681Sed{ 792186681Sed 793186681Sed if (t->t_stateflags & TS_INSERT && 794186681Sed tp->tp_col < t->t_winsize.tp_col - width) { 795186681Sed teken_rect_t ctr; 796186681Sed teken_pos_t ctp; 797186681Sed 798186681Sed /* Insert mode. Move existing characters to the right. */ 799186681Sed ctr.tr_begin = *tp; 800186681Sed ctr.tr_end.tp_row = tp->tp_row + 1; 801186681Sed ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 802186681Sed ctp.tp_row = tp->tp_row; 803186681Sed ctp.tp_col = tp->tp_col + width; 804186681Sed teken_funcs_copy(t, &ctr, &ctp); 805186681Sed } 806186681Sed 807197117Sed if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 808197117Sed teken_pos_t tp2; 809197117Sed 810197117Sed /* 811197117Sed * Store a space behind double width characters before 812197117Sed * actually printing them. This prevents artifacts when 813197117Sed * the consumer doesn't render it using double width 814197117Sed * glyphs. 815197117Sed */ 816197117Sed tp2.tp_row = tp->tp_row; 817197117Sed tp2.tp_col = tp->tp_col + 1; 818197117Sed teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 819197117Sed } 820197117Sed 821186681Sed teken_funcs_putchar(t, tp, c, &t->t_curattr); 822186681Sed} 823186681Sed 824186681Sedstatic void 825186681Sedteken_subr_regular_character(teken_t *t, teken_char_t c) 826186681Sed{ 827186681Sed int width; 828186681Sed 829197117Sed if (t->t_stateflags & TS_8BIT) { 830197470Sed if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) 831197115Sed return; 832197470Sed c = teken_scs_process(t, c); 833197115Sed width = 1; 834197115Sed } else { 835197115Sed c = teken_scs_process(t, c); 836197115Sed width = teken_wcwidth(c); 837197115Sed /* XXX: Don't process zero-width characters yet. */ 838197115Sed if (width <= 0) 839197115Sed return; 840197115Sed } 841186681Sed 842197117Sed if (t->t_stateflags & TS_CONS25) { 843197117Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 844197117Sed t->t_cursor.tp_col += width; 845197117Sed 846197117Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 847197117Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 848197117Sed /* Perform scrolling. */ 849197117Sed teken_subr_do_scroll(t, 1); 850197117Sed } else { 851197117Sed /* No scrolling needed. */ 852197117Sed if (t->t_cursor.tp_row < 853197117Sed t->t_winsize.tp_row - 1) 854197117Sed t->t_cursor.tp_row++; 855197117Sed } 856197117Sed t->t_cursor.tp_col = 0; 857197117Sed } 858197117Sed } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 859186681Sed (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 860186681Sed (TS_WRAPPED|TS_AUTOWRAP)) { 861186681Sed teken_pos_t tp; 862186681Sed 863186681Sed /* Perform line wrapping. */ 864186681Sed 865186681Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 866186681Sed /* Perform scrolling. */ 867186681Sed teken_subr_do_scroll(t, 1); 868186681Sed tp.tp_row = t->t_scrollreg.ts_end - 1; 869186681Sed } else { 870186681Sed /* No scrolling needed. */ 871186681Sed tp.tp_row = t->t_cursor.tp_row + 1; 872186681Sed if (tp.tp_row == t->t_winsize.tp_row) { 873186681Sed /* 874186681Sed * Corner case: regular character 875186681Sed * outside scrolling region, but at the 876186681Sed * bottom of the screen. 877186681Sed */ 878186681Sed teken_subr_do_putchar(t, &t->t_cursor, 879186681Sed c, width); 880186681Sed return; 881186681Sed } 882186681Sed } 883186681Sed 884186681Sed tp.tp_col = 0; 885186681Sed teken_subr_do_putchar(t, &tp, c, width); 886186681Sed 887186681Sed t->t_cursor.tp_row = tp.tp_row; 888186681Sed t->t_cursor.tp_col = width; 889186681Sed t->t_stateflags &= ~TS_WRAPPED; 890186681Sed } else { 891186681Sed /* No line wrapping needed. */ 892186681Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 893186681Sed t->t_cursor.tp_col += width; 894186681Sed 895186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 896186681Sed t->t_stateflags |= TS_WRAPPED; 897186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 898186681Sed } else { 899186681Sed t->t_stateflags &= ~TS_WRAPPED; 900186681Sed } 901186681Sed } 902186681Sed 903186681Sed teken_funcs_cursor(t); 904186681Sed} 905186681Sed 906186681Sedstatic void 907186681Sedteken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 908186681Sed{ 909186681Sed 910186681Sed switch (cmd) { 911186681Sed case 1: /* Cursor keys mode. */ 912199171Sed t->t_stateflags &= ~TS_CURSORKEYS; 913186681Sed break; 914186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 915186681Sed teken_printf("DECRST VT52\n"); 916186681Sed break; 917186681Sed case 3: /* 132 column mode. */ 918186681Sed teken_funcs_param(t, TP_132COLS, 0); 919186681Sed teken_subr_reset_to_initial_state(t); 920186681Sed break; 921186681Sed case 5: /* Inverse video. */ 922186681Sed teken_printf("DECRST inverse video\n"); 923186681Sed break; 924186681Sed case 6: /* Origin mode. */ 925186681Sed t->t_stateflags &= ~TS_ORIGIN; 926186681Sed t->t_originreg.ts_begin = 0; 927186681Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 928186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 929186681Sed t->t_stateflags &= ~TS_WRAPPED; 930186681Sed teken_funcs_cursor(t); 931186681Sed break; 932186681Sed case 7: /* Autowrap mode. */ 933186681Sed t->t_stateflags &= ~TS_AUTOWRAP; 934186681Sed break; 935186681Sed case 8: /* Autorepeat mode. */ 936186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 0); 937186681Sed break; 938186681Sed case 25: /* Hide cursor. */ 939186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 0); 940186681Sed break; 941186681Sed case 40: /* Disallow 132 columns. */ 942186681Sed teken_printf("DECRST allow 132\n"); 943186681Sed break; 944186681Sed case 45: /* Disable reverse wraparound. */ 945186681Sed teken_printf("DECRST reverse wraparound\n"); 946186681Sed break; 947186681Sed case 47: /* Switch to alternate buffer. */ 948186681Sed teken_printf("Switch to alternate buffer\n"); 949186681Sed break; 950197539Sed case 1000: /* Mouse input. */ 951197539Sed teken_funcs_param(t, TP_MOUSE, 0); 952197539Sed break; 953186681Sed default: 954186681Sed teken_printf("Unknown DECRST: %u\n", cmd); 955186681Sed } 956186681Sed} 957186681Sed 958186681Sedstatic void 959186681Sedteken_subr_reset_mode(teken_t *t, unsigned int cmd) 960186681Sed{ 961186681Sed 962186681Sed switch (cmd) { 963186681Sed case 4: 964186681Sed t->t_stateflags &= ~TS_INSERT; 965186681Sed break; 966186681Sed default: 967186681Sed teken_printf("Unknown reset mode: %u\n", cmd); 968186681Sed } 969186681Sed} 970186681Sed 971186681Sedstatic void 972186681Sedteken_subr_do_reset(teken_t *t) 973186681Sed{ 974186681Sed 975187469Sed t->t_curattr = t->t_defattr; 976186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 977197114Sed t->t_scrollreg.ts_begin = 0; 978197114Sed t->t_scrollreg.ts_end = t->t_winsize.tp_row; 979197114Sed t->t_originreg = t->t_scrollreg; 980197117Sed t->t_stateflags &= TS_8BIT|TS_CONS25; 981197117Sed t->t_stateflags |= TS_AUTOWRAP; 982186681Sed 983197520Sed t->t_scs[0] = teken_scs_us_ascii; 984197520Sed t->t_scs[1] = teken_scs_us_ascii; 985197520Sed t->t_curscs = 0; 986187469Sed 987187469Sed teken_subr_save_cursor(t); 988186681Sed teken_tab_default(t); 989186681Sed} 990186681Sed 991186681Sedstatic void 992186681Sedteken_subr_reset_to_initial_state(teken_t *t) 993186681Sed{ 994186681Sed 995186681Sed teken_subr_do_reset(t); 996186681Sed teken_subr_erase_display(t, 2); 997186753Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 998186681Sed teken_funcs_cursor(t); 999186681Sed} 1000186681Sed 1001186681Sedstatic void 1002186681Sedteken_subr_restore_cursor(teken_t *t) 1003186681Sed{ 1004186681Sed 1005186681Sed t->t_cursor = t->t_saved_cursor; 1006186681Sed t->t_curattr = t->t_saved_curattr; 1007197520Sed t->t_scs[t->t_curscs] = t->t_saved_curscs; 1008186681Sed t->t_stateflags &= ~TS_WRAPPED; 1009197521Sed 1010197521Sed /* Get out of origin mode when the cursor is moved outside. */ 1011197521Sed if (t->t_cursor.tp_row < t->t_originreg.ts_begin || 1012197521Sed t->t_cursor.tp_row >= t->t_originreg.ts_end) { 1013197521Sed t->t_stateflags &= ~TS_ORIGIN; 1014197521Sed t->t_originreg.ts_begin = 0; 1015197521Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 1016197521Sed } 1017197521Sed 1018186681Sed teken_funcs_cursor(t); 1019186681Sed} 1020186681Sed 1021186681Sedstatic void 1022186681Sedteken_subr_reverse_index(teken_t *t) 1023186681Sed{ 1024186681Sed 1025186681Sed if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 1026186681Sed t->t_cursor.tp_row--; 1027186681Sed t->t_stateflags &= ~TS_WRAPPED; 1028186681Sed teken_funcs_cursor(t); 1029186681Sed } else { 1030186681Sed teken_subr_do_scroll(t, -1); 1031186681Sed } 1032186681Sed} 1033186681Sed 1034186681Sedstatic void 1035186681Sedteken_subr_save_cursor(teken_t *t) 1036186681Sed{ 1037186681Sed 1038186681Sed t->t_saved_cursor = t->t_cursor; 1039186681Sed t->t_saved_curattr = t->t_curattr; 1040197520Sed t->t_saved_curscs = t->t_scs[t->t_curscs]; 1041186681Sed} 1042186681Sed 1043186681Sedstatic void 1044186681Sedteken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1045186681Sed{ 1046186681Sed 1047186681Sed if (request == 0) { 1048186681Sed const char response[] = "\x1B[>0;10;0c"; 1049186681Sed teken_funcs_respond(t, response, sizeof response - 1); 1050186681Sed } else { 1051186681Sed teken_printf("Unknown DA2\n"); 1052186681Sed } 1053186681Sed} 1054186681Sed 1055186681Sedstatic void 1056186681Sedteken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1057186681Sed{ 1058186681Sed 1059186681Sed switch (cmd) { 1060186681Sed case 1: /* Cursor keys mode. */ 1061199171Sed t->t_stateflags |= TS_CURSORKEYS; 1062186681Sed break; 1063186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 1064186681Sed teken_printf("DECSET VT52\n"); 1065186681Sed break; 1066186681Sed case 3: /* 132 column mode. */ 1067186681Sed teken_funcs_param(t, TP_132COLS, 1); 1068186681Sed teken_subr_reset_to_initial_state(t); 1069186681Sed break; 1070186681Sed case 5: /* Inverse video. */ 1071186681Sed teken_printf("DECSET inverse video\n"); 1072186681Sed break; 1073186681Sed case 6: /* Origin mode. */ 1074186681Sed t->t_stateflags |= TS_ORIGIN; 1075186681Sed t->t_originreg = t->t_scrollreg; 1076186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1077186681Sed t->t_cursor.tp_col = 0; 1078186681Sed t->t_stateflags &= ~TS_WRAPPED; 1079186681Sed teken_funcs_cursor(t); 1080186681Sed break; 1081186681Sed case 7: /* Autowrap mode. */ 1082186681Sed t->t_stateflags |= TS_AUTOWRAP; 1083186681Sed break; 1084186681Sed case 8: /* Autorepeat mode. */ 1085186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 1); 1086186681Sed break; 1087186681Sed case 25: /* Display cursor. */ 1088186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 1089186681Sed break; 1090186681Sed case 40: /* Allow 132 columns. */ 1091186681Sed teken_printf("DECSET allow 132\n"); 1092186681Sed break; 1093186681Sed case 45: /* Enable reverse wraparound. */ 1094186681Sed teken_printf("DECSET reverse wraparound\n"); 1095186681Sed break; 1096186681Sed case 47: /* Switch to alternate buffer. */ 1097186681Sed teken_printf("Switch away from alternate buffer\n"); 1098186681Sed break; 1099197539Sed case 1000: /* Mouse input. */ 1100197539Sed teken_funcs_param(t, TP_MOUSE, 1); 1101197539Sed break; 1102186681Sed default: 1103186681Sed teken_printf("Unknown DECSET: %u\n", cmd); 1104186681Sed } 1105186681Sed} 1106186681Sed 1107186681Sedstatic void 1108186681Sedteken_subr_set_mode(teken_t *t, unsigned int cmd) 1109186681Sed{ 1110186681Sed 1111186681Sed switch (cmd) { 1112186681Sed case 4: 1113186681Sed teken_printf("Insert mode\n"); 1114186681Sed t->t_stateflags |= TS_INSERT; 1115186681Sed break; 1116186681Sed default: 1117186681Sed teken_printf("Unknown set mode: %u\n", cmd); 1118186681Sed } 1119186681Sed} 1120186681Sed 1121186681Sedstatic void 1122186681Sedteken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1123186681Sed unsigned int cmds[]) 1124186681Sed{ 1125186681Sed unsigned int i, n; 1126186681Sed 1127186681Sed /* No attributes means reset. */ 1128186681Sed if (ncmds == 0) { 1129186681Sed t->t_curattr = t->t_defattr; 1130186681Sed return; 1131186681Sed } 1132186681Sed 1133186681Sed for (i = 0; i < ncmds; i++) { 1134186681Sed n = cmds[i]; 1135186681Sed 1136186681Sed switch (n) { 1137186681Sed case 0: /* Reset. */ 1138186681Sed t->t_curattr = t->t_defattr; 1139186681Sed break; 1140186681Sed case 1: /* Bold. */ 1141186681Sed t->t_curattr.ta_format |= TF_BOLD; 1142186681Sed break; 1143186681Sed case 4: /* Underline. */ 1144186681Sed t->t_curattr.ta_format |= TF_UNDERLINE; 1145186681Sed break; 1146186681Sed case 5: /* Blink. */ 1147186681Sed t->t_curattr.ta_format |= TF_BLINK; 1148186681Sed break; 1149186681Sed case 7: /* Reverse. */ 1150186681Sed t->t_curattr.ta_format |= TF_REVERSE; 1151186681Sed break; 1152186681Sed case 22: /* Remove bold. */ 1153186681Sed t->t_curattr.ta_format &= ~TF_BOLD; 1154186681Sed break; 1155186681Sed case 24: /* Remove underline. */ 1156186681Sed t->t_curattr.ta_format &= ~TF_UNDERLINE; 1157186681Sed break; 1158186681Sed case 25: /* Remove blink. */ 1159186681Sed t->t_curattr.ta_format &= ~TF_BLINK; 1160186681Sed break; 1161186681Sed case 27: /* Remove reverse. */ 1162186681Sed t->t_curattr.ta_format &= ~TF_REVERSE; 1163186681Sed break; 1164186681Sed case 30: /* Set foreground color: black */ 1165186681Sed case 31: /* Set foreground color: red */ 1166186681Sed case 32: /* Set foreground color: green */ 1167186681Sed case 33: /* Set foreground color: brown */ 1168186681Sed case 34: /* Set foreground color: blue */ 1169186681Sed case 35: /* Set foreground color: magenta */ 1170186681Sed case 36: /* Set foreground color: cyan */ 1171186681Sed case 37: /* Set foreground color: white */ 1172186681Sed t->t_curattr.ta_fgcolor = n - 30; 1173186681Sed break; 1174197522Sed case 38: /* Set foreground color: 256 color mode */ 1175197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1176197522Sed continue; 1177197522Sed t->t_curattr.ta_fgcolor = cmds[i + 2]; 1178197522Sed i += 2; 1179197522Sed break; 1180186681Sed case 39: /* Set default foreground color. */ 1181186681Sed t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1182186681Sed break; 1183186681Sed case 40: /* Set background color: black */ 1184186681Sed case 41: /* Set background color: red */ 1185186681Sed case 42: /* Set background color: green */ 1186186681Sed case 43: /* Set background color: brown */ 1187186681Sed case 44: /* Set background color: blue */ 1188186681Sed case 45: /* Set background color: magenta */ 1189186681Sed case 46: /* Set background color: cyan */ 1190186681Sed case 47: /* Set background color: white */ 1191186681Sed t->t_curattr.ta_bgcolor = n - 40; 1192186681Sed break; 1193197522Sed case 48: /* Set background color: 256 color mode */ 1194197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1195197522Sed continue; 1196197522Sed t->t_curattr.ta_bgcolor = cmds[i + 2]; 1197197522Sed i += 2; 1198197522Sed break; 1199186681Sed case 49: /* Set default background color. */ 1200186681Sed t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1201186681Sed break; 1202197522Sed case 90: /* Set bright foreground color: black */ 1203197522Sed case 91: /* Set bright foreground color: red */ 1204197522Sed case 92: /* Set bright foreground color: green */ 1205197522Sed case 93: /* Set bright foreground color: brown */ 1206197522Sed case 94: /* Set bright foreground color: blue */ 1207197522Sed case 95: /* Set bright foreground color: magenta */ 1208197522Sed case 96: /* Set bright foreground color: cyan */ 1209197522Sed case 97: /* Set bright foreground color: white */ 1210197522Sed t->t_curattr.ta_fgcolor = n - 90 + 8; 1211197522Sed break; 1212197522Sed case 100: /* Set bright background color: black */ 1213197522Sed case 101: /* Set bright background color: red */ 1214197522Sed case 102: /* Set bright background color: green */ 1215197522Sed case 103: /* Set bright background color: brown */ 1216197522Sed case 104: /* Set bright background color: blue */ 1217197522Sed case 105: /* Set bright background color: magenta */ 1218197522Sed case 106: /* Set bright background color: cyan */ 1219197522Sed case 107: /* Set bright background color: white */ 1220197522Sed t->t_curattr.ta_bgcolor = n - 100 + 8; 1221197522Sed break; 1222186681Sed default: 1223186681Sed teken_printf("unsupported attribute %u\n", n); 1224186681Sed } 1225186681Sed } 1226186681Sed} 1227186681Sed 1228186681Sedstatic void 1229186681Sedteken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1230186681Sed unsigned int bottom) 1231186681Sed{ 1232186681Sed 1233186681Sed /* Adjust top row number. */ 1234186681Sed if (top > 0) 1235186681Sed top--; 1236186681Sed /* Adjust bottom row number. */ 1237186681Sed if (bottom == 0 || bottom > t->t_winsize.tp_row) 1238186681Sed bottom = t->t_winsize.tp_row; 1239186681Sed 1240186681Sed /* Invalid arguments. */ 1241186681Sed if (top >= bottom - 1) { 1242186681Sed top = 0; 1243186681Sed bottom = t->t_winsize.tp_row; 1244186681Sed } 1245186681Sed 1246199170Sed /* Apply scrolling region. */ 1247186681Sed t->t_scrollreg.ts_begin = top; 1248186681Sed t->t_scrollreg.ts_end = bottom; 1249199170Sed if (t->t_stateflags & TS_ORIGIN) 1250186681Sed t->t_originreg = t->t_scrollreg; 1251199170Sed 1252199170Sed /* Home cursor to the top left of the scrolling region. */ 1253199170Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 1254199170Sed t->t_cursor.tp_col = 0; 1255199170Sed t->t_stateflags &= ~TS_WRAPPED; 1256199170Sed teken_funcs_cursor(t); 1257186681Sed} 1258186681Sed 1259186681Sedstatic void 1260186681Sedteken_subr_single_height_double_width_line(teken_t *t __unused) 1261186681Sed{ 1262186681Sed 1263186681Sed teken_printf("single height double width???\n"); 1264186681Sed} 1265186681Sed 1266186681Sedstatic void 1267186681Sedteken_subr_single_height_single_width_line(teken_t *t __unused) 1268186681Sed{ 1269186681Sed 1270186681Sed teken_printf("single height single width???\n"); 1271186681Sed} 1272186681Sed 1273186681Sedstatic void 1274186681Sedteken_subr_string_terminator(teken_t *t __unused) 1275186681Sed{ 1276186681Sed 1277197853Sed /* 1278197853Sed * Strings are already terminated in teken_input_char() when ^[ 1279197853Sed * is inserted. 1280197853Sed */ 1281186681Sed} 1282186681Sed 1283186681Sedstatic void 1284186681Sedteken_subr_tab_clear(teken_t *t, unsigned int cmd) 1285186681Sed{ 1286186681Sed 1287186681Sed switch (cmd) { 1288186681Sed case 0: 1289186681Sed teken_tab_clear(t, t->t_cursor.tp_col); 1290186681Sed break; 1291186681Sed case 3: 1292186681Sed memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1293186681Sed break; 1294186681Sed } 1295186681Sed} 1296186681Sed 1297186681Sedstatic void 1298186681Sedteken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1299186681Sed{ 1300186681Sed 1301186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1302186681Sed if (row >= t->t_originreg.ts_end) 1303186681Sed t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1304186681Sed 1305186681Sed 1306186681Sed t->t_stateflags &= ~TS_WRAPPED; 1307186681Sed teken_funcs_cursor(t); 1308186681Sed} 1309