teken_subr.h revision 259016
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 259016 2013-12-05 22:38:53Z ray $ 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--; 263223574Sed 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++; 306223574Sed 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; 328226183Sed if (t->t_cursor.tp_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 598226099Sed teken_subr_cursor_forward_tabulation(t, 1); 599186681Sed} 600186681Sed 601186681Sedstatic void 602186681Sedteken_subr_horizontal_tab_set(teken_t *t) 603186681Sed{ 604186681Sed 605186681Sed teken_tab_set(t, t->t_cursor.tp_col); 606186681Sed} 607186681Sed 608186681Sedstatic void 609186681Sedteken_subr_index(teken_t *t) 610186681Sed{ 611186681Sed 612186681Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 613186681Sed t->t_cursor.tp_row++; 614186681Sed t->t_stateflags &= ~TS_WRAPPED; 615186681Sed teken_funcs_cursor(t); 616186681Sed } else { 617186681Sed teken_subr_do_scroll(t, 1); 618186681Sed } 619186681Sed} 620186681Sed 621186681Sedstatic void 622186681Sedteken_subr_insert_character(teken_t *t, unsigned int ncols) 623186681Sed{ 624186681Sed teken_rect_t tr; 625186681Sed 626186681Sed tr.tr_begin = t->t_cursor; 627186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 628186681Sed 629186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 630186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 631186681Sed } else { 632186681Sed teken_pos_t tp; 633186681Sed 634186681Sed /* Copy characters to the right. */ 635186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 636186681Sed tp.tp_row = t->t_cursor.tp_row; 637186681Sed tp.tp_col = t->t_cursor.tp_col + ncols; 638186681Sed teken_funcs_copy(t, &tr, &tp); 639186681Sed 640186681Sed tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 641186681Sed } 642186681Sed 643186681Sed /* Blank current location. */ 644186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 645186681Sed} 646186681Sed 647186681Sedstatic void 648186681Sedteken_subr_insert_line(teken_t *t, unsigned int nrows) 649186681Sed{ 650186681Sed teken_rect_t tr; 651186681Sed 652197480Sed /* Ignore if outside scrolling region. */ 653197480Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 654197480Sed t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 655197480Sed return; 656197480Sed 657186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row; 658186681Sed tr.tr_begin.tp_col = 0; 659186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 660186681Sed 661186681Sed if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 662186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 663186681Sed } else { 664186681Sed teken_pos_t tp; 665186681Sed 666186681Sed /* Copy lines down. */ 667186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 668186681Sed tp.tp_row = t->t_cursor.tp_row + nrows; 669186681Sed tp.tp_col = 0; 670186681Sed teken_funcs_copy(t, &tr, &tp); 671186681Sed 672186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 673186681Sed } 674186681Sed 675186681Sed /* Blank current location. */ 676186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 677186681Sed} 678186681Sed 679186681Sedstatic void 680186681Sedteken_subr_keypad_application_mode(teken_t *t) 681186681Sed{ 682186681Sed 683186681Sed teken_funcs_param(t, TP_KEYPADAPP, 1); 684186681Sed} 685186681Sed 686186681Sedstatic void 687186681Sedteken_subr_keypad_numeric_mode(teken_t *t) 688186681Sed{ 689186681Sed 690186681Sed teken_funcs_param(t, TP_KEYPADAPP, 0); 691186681Sed} 692186681Sed 693186681Sedstatic void 694186681Sedteken_subr_newline(teken_t *t) 695186681Sed{ 696186681Sed 697186681Sed t->t_cursor.tp_row++; 698186681Sed 699186681Sed if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 700186681Sed teken_subr_do_scroll(t, 1); 701186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 702186681Sed } 703186681Sed 704186681Sed t->t_stateflags &= ~TS_WRAPPED; 705186681Sed teken_funcs_cursor(t); 706186681Sed} 707186681Sed 708186681Sedstatic void 709186798Sedteken_subr_newpage(teken_t *t) 710186798Sed{ 711187367Sed 712197117Sed if (t->t_stateflags & TS_CONS25) { 713197117Sed teken_rect_t tr; 714186798Sed 715211113Sed /* Clear screen. */ 716211113Sed tr.tr_begin.tp_row = t->t_originreg.ts_begin; 717211113Sed tr.tr_begin.tp_col = 0; 718211113Sed tr.tr_end.tp_row = t->t_originreg.ts_end; 719211113Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 720197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 721186798Sed 722211113Sed /* Cursor at top left. */ 723211113Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 724211113Sed t->t_cursor.tp_col = 0; 725211113Sed t->t_stateflags &= ~TS_WRAPPED; 726197117Sed teken_funcs_cursor(t); 727197117Sed } else { 728197117Sed teken_subr_newline(t); 729197117Sed } 730186798Sed} 731186798Sed 732186798Sedstatic void 733186681Sedteken_subr_next_line(teken_t *t) 734186681Sed{ 735186681Sed 736186681Sed t->t_cursor.tp_col = 0; 737186681Sed teken_subr_newline(t); 738186681Sed} 739186681Sed 740186681Sedstatic void 741197853Sedteken_subr_operating_system_command(teken_t *t) 742197853Sed{ 743197853Sed 744197853Sed teken_printf("Unsupported operating system command\n"); 745197853Sed t->t_stateflags |= TS_INSTRING; 746197853Sed} 747197853Sed 748197853Sedstatic void 749186681Sedteken_subr_pan_down(teken_t *t, unsigned int nrows) 750186681Sed{ 751186681Sed 752186681Sed teken_subr_do_scroll(t, (int)nrows); 753186681Sed} 754186681Sed 755186681Sedstatic void 756186681Sedteken_subr_pan_up(teken_t *t, unsigned int nrows) 757186681Sed{ 758186681Sed 759186681Sed teken_subr_do_scroll(t, -(int)nrows); 760186681Sed} 761186681Sed 762186681Sedstatic void 763186681Sedteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 764186681Sed{ 765186681Sed 766186681Sed if (request == 0) { 767186681Sed const char response[] = "\x1B[?1;2c"; 768186681Sed 769186681Sed teken_funcs_respond(t, response, sizeof response - 1); 770186681Sed } else { 771186681Sed teken_printf("Unknown DA1\n"); 772186681Sed } 773186681Sed} 774186681Sed 775186681Sedstatic void 776186681Sedteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 777186681Sed int width) 778186681Sed{ 779186681Sed 780186681Sed if (t->t_stateflags & TS_INSERT && 781186681Sed tp->tp_col < t->t_winsize.tp_col - width) { 782186681Sed teken_rect_t ctr; 783186681Sed teken_pos_t ctp; 784186681Sed 785186681Sed /* Insert mode. Move existing characters to the right. */ 786186681Sed ctr.tr_begin = *tp; 787186681Sed ctr.tr_end.tp_row = tp->tp_row + 1; 788186681Sed ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 789186681Sed ctp.tp_row = tp->tp_row; 790186681Sed ctp.tp_col = tp->tp_col + width; 791186681Sed teken_funcs_copy(t, &ctr, &ctp); 792186681Sed } 793186681Sed 794197117Sed if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 795197117Sed teken_pos_t tp2; 796197117Sed 797197117Sed /* 798197117Sed * Store a space behind double width characters before 799197117Sed * actually printing them. This prevents artifacts when 800197117Sed * the consumer doesn't render it using double width 801197117Sed * glyphs. 802197117Sed */ 803197117Sed tp2.tp_row = tp->tp_row; 804197117Sed tp2.tp_col = tp->tp_col + 1; 805197117Sed teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 806197117Sed } 807197117Sed 808186681Sed teken_funcs_putchar(t, tp, c, &t->t_curattr); 809186681Sed} 810186681Sed 811186681Sedstatic void 812186681Sedteken_subr_regular_character(teken_t *t, teken_char_t c) 813186681Sed{ 814186681Sed int width; 815186681Sed 816197117Sed if (t->t_stateflags & TS_8BIT) { 817197470Sed if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) 818197115Sed return; 819197470Sed c = teken_scs_process(t, c); 820197115Sed width = 1; 821197115Sed } else { 822197115Sed c = teken_scs_process(t, c); 823197115Sed width = teken_wcwidth(c); 824197115Sed /* XXX: Don't process zero-width characters yet. */ 825197115Sed if (width <= 0) 826197115Sed return; 827197115Sed } 828186681Sed 829197117Sed if (t->t_stateflags & TS_CONS25) { 830197117Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 831197117Sed t->t_cursor.tp_col += width; 832197117Sed 833197117Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 834197117Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 835197117Sed /* Perform scrolling. */ 836197117Sed teken_subr_do_scroll(t, 1); 837197117Sed } else { 838197117Sed /* No scrolling needed. */ 839197117Sed if (t->t_cursor.tp_row < 840197117Sed t->t_winsize.tp_row - 1) 841197117Sed t->t_cursor.tp_row++; 842197117Sed } 843197117Sed t->t_cursor.tp_col = 0; 844197117Sed } 845197117Sed } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 846186681Sed (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 847186681Sed (TS_WRAPPED|TS_AUTOWRAP)) { 848186681Sed teken_pos_t tp; 849186681Sed 850186681Sed /* Perform line wrapping. */ 851186681Sed 852186681Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 853186681Sed /* Perform scrolling. */ 854186681Sed teken_subr_do_scroll(t, 1); 855186681Sed tp.tp_row = t->t_scrollreg.ts_end - 1; 856186681Sed } else { 857186681Sed /* No scrolling needed. */ 858186681Sed tp.tp_row = t->t_cursor.tp_row + 1; 859186681Sed if (tp.tp_row == t->t_winsize.tp_row) { 860186681Sed /* 861186681Sed * Corner case: regular character 862186681Sed * outside scrolling region, but at the 863186681Sed * bottom of the screen. 864186681Sed */ 865186681Sed teken_subr_do_putchar(t, &t->t_cursor, 866186681Sed c, width); 867186681Sed return; 868186681Sed } 869186681Sed } 870186681Sed 871186681Sed tp.tp_col = 0; 872186681Sed teken_subr_do_putchar(t, &tp, c, width); 873186681Sed 874186681Sed t->t_cursor.tp_row = tp.tp_row; 875186681Sed t->t_cursor.tp_col = width; 876186681Sed t->t_stateflags &= ~TS_WRAPPED; 877186681Sed } else { 878186681Sed /* No line wrapping needed. */ 879186681Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 880186681Sed t->t_cursor.tp_col += width; 881186681Sed 882186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 883186681Sed t->t_stateflags |= TS_WRAPPED; 884186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 885186681Sed } else { 886186681Sed t->t_stateflags &= ~TS_WRAPPED; 887186681Sed } 888186681Sed } 889186681Sed 890186681Sed teken_funcs_cursor(t); 891186681Sed} 892186681Sed 893186681Sedstatic void 894186681Sedteken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 895186681Sed{ 896186681Sed 897186681Sed switch (cmd) { 898186681Sed case 1: /* Cursor keys mode. */ 899199171Sed t->t_stateflags &= ~TS_CURSORKEYS; 900186681Sed break; 901186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 902186681Sed teken_printf("DECRST VT52\n"); 903186681Sed break; 904186681Sed case 3: /* 132 column mode. */ 905186681Sed teken_funcs_param(t, TP_132COLS, 0); 906186681Sed teken_subr_reset_to_initial_state(t); 907186681Sed break; 908186681Sed case 5: /* Inverse video. */ 909186681Sed teken_printf("DECRST inverse video\n"); 910186681Sed break; 911186681Sed case 6: /* Origin mode. */ 912186681Sed t->t_stateflags &= ~TS_ORIGIN; 913186681Sed t->t_originreg.ts_begin = 0; 914186681Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 915186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 916186681Sed t->t_stateflags &= ~TS_WRAPPED; 917186681Sed teken_funcs_cursor(t); 918186681Sed break; 919186681Sed case 7: /* Autowrap mode. */ 920186681Sed t->t_stateflags &= ~TS_AUTOWRAP; 921186681Sed break; 922186681Sed case 8: /* Autorepeat mode. */ 923186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 0); 924186681Sed break; 925186681Sed case 25: /* Hide cursor. */ 926186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 0); 927186681Sed break; 928186681Sed case 40: /* Disallow 132 columns. */ 929186681Sed teken_printf("DECRST allow 132\n"); 930186681Sed break; 931186681Sed case 45: /* Disable reverse wraparound. */ 932186681Sed teken_printf("DECRST reverse wraparound\n"); 933186681Sed break; 934186681Sed case 47: /* Switch to alternate buffer. */ 935186681Sed teken_printf("Switch to alternate buffer\n"); 936186681Sed break; 937197539Sed case 1000: /* Mouse input. */ 938197539Sed teken_funcs_param(t, TP_MOUSE, 0); 939197539Sed break; 940186681Sed default: 941186681Sed teken_printf("Unknown DECRST: %u\n", cmd); 942186681Sed } 943186681Sed} 944186681Sed 945186681Sedstatic void 946186681Sedteken_subr_reset_mode(teken_t *t, unsigned int cmd) 947186681Sed{ 948186681Sed 949186681Sed switch (cmd) { 950186681Sed case 4: 951186681Sed t->t_stateflags &= ~TS_INSERT; 952186681Sed break; 953186681Sed default: 954186681Sed teken_printf("Unknown reset mode: %u\n", cmd); 955186681Sed } 956186681Sed} 957186681Sed 958186681Sedstatic void 959259016Srayteken_subr_do_resize(teken_t *t) 960259016Sray{ 961259016Sray 962259016Sray t->t_scrollreg.ts_begin = 0; 963259016Sray t->t_scrollreg.ts_end = t->t_winsize.tp_row; 964259016Sray t->t_originreg = t->t_scrollreg; 965259016Sray} 966259016Sray 967259016Sraystatic void 968186681Sedteken_subr_do_reset(teken_t *t) 969186681Sed{ 970186681Sed 971187469Sed t->t_curattr = t->t_defattr; 972186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 973197114Sed t->t_scrollreg.ts_begin = 0; 974197114Sed t->t_scrollreg.ts_end = t->t_winsize.tp_row; 975197114Sed t->t_originreg = t->t_scrollreg; 976197117Sed t->t_stateflags &= TS_8BIT|TS_CONS25; 977197117Sed t->t_stateflags |= TS_AUTOWRAP; 978186681Sed 979197520Sed t->t_scs[0] = teken_scs_us_ascii; 980197520Sed t->t_scs[1] = teken_scs_us_ascii; 981197520Sed t->t_curscs = 0; 982187469Sed 983187469Sed teken_subr_save_cursor(t); 984186681Sed teken_tab_default(t); 985186681Sed} 986186681Sed 987186681Sedstatic void 988186681Sedteken_subr_reset_to_initial_state(teken_t *t) 989186681Sed{ 990186681Sed 991186681Sed teken_subr_do_reset(t); 992186681Sed teken_subr_erase_display(t, 2); 993186753Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 994186681Sed teken_funcs_cursor(t); 995186681Sed} 996186681Sed 997186681Sedstatic void 998186681Sedteken_subr_restore_cursor(teken_t *t) 999186681Sed{ 1000186681Sed 1001186681Sed t->t_cursor = t->t_saved_cursor; 1002186681Sed t->t_curattr = t->t_saved_curattr; 1003197520Sed t->t_scs[t->t_curscs] = t->t_saved_curscs; 1004186681Sed t->t_stateflags &= ~TS_WRAPPED; 1005197521Sed 1006197521Sed /* Get out of origin mode when the cursor is moved outside. */ 1007197521Sed if (t->t_cursor.tp_row < t->t_originreg.ts_begin || 1008197521Sed t->t_cursor.tp_row >= t->t_originreg.ts_end) { 1009197521Sed t->t_stateflags &= ~TS_ORIGIN; 1010197521Sed t->t_originreg.ts_begin = 0; 1011197521Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 1012197521Sed } 1013197521Sed 1014186681Sed teken_funcs_cursor(t); 1015186681Sed} 1016186681Sed 1017186681Sedstatic void 1018186681Sedteken_subr_reverse_index(teken_t *t) 1019186681Sed{ 1020186681Sed 1021186681Sed if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 1022186681Sed t->t_cursor.tp_row--; 1023186681Sed t->t_stateflags &= ~TS_WRAPPED; 1024186681Sed teken_funcs_cursor(t); 1025186681Sed } else { 1026186681Sed teken_subr_do_scroll(t, -1); 1027186681Sed } 1028186681Sed} 1029186681Sed 1030186681Sedstatic void 1031186681Sedteken_subr_save_cursor(teken_t *t) 1032186681Sed{ 1033186681Sed 1034186681Sed t->t_saved_cursor = t->t_cursor; 1035186681Sed t->t_saved_curattr = t->t_curattr; 1036197520Sed t->t_saved_curscs = t->t_scs[t->t_curscs]; 1037186681Sed} 1038186681Sed 1039186681Sedstatic void 1040186681Sedteken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1041186681Sed{ 1042186681Sed 1043186681Sed if (request == 0) { 1044186681Sed const char response[] = "\x1B[>0;10;0c"; 1045186681Sed teken_funcs_respond(t, response, sizeof response - 1); 1046186681Sed } else { 1047186681Sed teken_printf("Unknown DA2\n"); 1048186681Sed } 1049186681Sed} 1050186681Sed 1051186681Sedstatic void 1052186681Sedteken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1053186681Sed{ 1054186681Sed 1055186681Sed switch (cmd) { 1056186681Sed case 1: /* Cursor keys mode. */ 1057199171Sed t->t_stateflags |= TS_CURSORKEYS; 1058186681Sed break; 1059186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 1060186681Sed teken_printf("DECSET VT52\n"); 1061186681Sed break; 1062186681Sed case 3: /* 132 column mode. */ 1063186681Sed teken_funcs_param(t, TP_132COLS, 1); 1064186681Sed teken_subr_reset_to_initial_state(t); 1065186681Sed break; 1066186681Sed case 5: /* Inverse video. */ 1067186681Sed teken_printf("DECSET inverse video\n"); 1068186681Sed break; 1069186681Sed case 6: /* Origin mode. */ 1070186681Sed t->t_stateflags |= TS_ORIGIN; 1071186681Sed t->t_originreg = t->t_scrollreg; 1072186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1073186681Sed t->t_cursor.tp_col = 0; 1074186681Sed t->t_stateflags &= ~TS_WRAPPED; 1075186681Sed teken_funcs_cursor(t); 1076186681Sed break; 1077186681Sed case 7: /* Autowrap mode. */ 1078186681Sed t->t_stateflags |= TS_AUTOWRAP; 1079186681Sed break; 1080186681Sed case 8: /* Autorepeat mode. */ 1081186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 1); 1082186681Sed break; 1083186681Sed case 25: /* Display cursor. */ 1084186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 1085186681Sed break; 1086186681Sed case 40: /* Allow 132 columns. */ 1087186681Sed teken_printf("DECSET allow 132\n"); 1088186681Sed break; 1089186681Sed case 45: /* Enable reverse wraparound. */ 1090186681Sed teken_printf("DECSET reverse wraparound\n"); 1091186681Sed break; 1092186681Sed case 47: /* Switch to alternate buffer. */ 1093186681Sed teken_printf("Switch away from alternate buffer\n"); 1094186681Sed break; 1095197539Sed case 1000: /* Mouse input. */ 1096197539Sed teken_funcs_param(t, TP_MOUSE, 1); 1097197539Sed break; 1098186681Sed default: 1099186681Sed teken_printf("Unknown DECSET: %u\n", cmd); 1100186681Sed } 1101186681Sed} 1102186681Sed 1103186681Sedstatic void 1104186681Sedteken_subr_set_mode(teken_t *t, unsigned int cmd) 1105186681Sed{ 1106186681Sed 1107186681Sed switch (cmd) { 1108186681Sed case 4: 1109186681Sed teken_printf("Insert mode\n"); 1110186681Sed t->t_stateflags |= TS_INSERT; 1111186681Sed break; 1112186681Sed default: 1113186681Sed teken_printf("Unknown set mode: %u\n", cmd); 1114186681Sed } 1115186681Sed} 1116186681Sed 1117186681Sedstatic void 1118186681Sedteken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1119186681Sed unsigned int cmds[]) 1120186681Sed{ 1121186681Sed unsigned int i, n; 1122186681Sed 1123186681Sed /* No attributes means reset. */ 1124186681Sed if (ncmds == 0) { 1125186681Sed t->t_curattr = t->t_defattr; 1126186681Sed return; 1127186681Sed } 1128186681Sed 1129186681Sed for (i = 0; i < ncmds; i++) { 1130186681Sed n = cmds[i]; 1131186681Sed 1132186681Sed switch (n) { 1133186681Sed case 0: /* Reset. */ 1134186681Sed t->t_curattr = t->t_defattr; 1135186681Sed break; 1136186681Sed case 1: /* Bold. */ 1137186681Sed t->t_curattr.ta_format |= TF_BOLD; 1138186681Sed break; 1139186681Sed case 4: /* Underline. */ 1140186681Sed t->t_curattr.ta_format |= TF_UNDERLINE; 1141186681Sed break; 1142186681Sed case 5: /* Blink. */ 1143186681Sed t->t_curattr.ta_format |= TF_BLINK; 1144186681Sed break; 1145186681Sed case 7: /* Reverse. */ 1146186681Sed t->t_curattr.ta_format |= TF_REVERSE; 1147186681Sed break; 1148186681Sed case 22: /* Remove bold. */ 1149186681Sed t->t_curattr.ta_format &= ~TF_BOLD; 1150186681Sed break; 1151186681Sed case 24: /* Remove underline. */ 1152186681Sed t->t_curattr.ta_format &= ~TF_UNDERLINE; 1153186681Sed break; 1154186681Sed case 25: /* Remove blink. */ 1155186681Sed t->t_curattr.ta_format &= ~TF_BLINK; 1156186681Sed break; 1157186681Sed case 27: /* Remove reverse. */ 1158186681Sed t->t_curattr.ta_format &= ~TF_REVERSE; 1159186681Sed break; 1160186681Sed case 30: /* Set foreground color: black */ 1161186681Sed case 31: /* Set foreground color: red */ 1162186681Sed case 32: /* Set foreground color: green */ 1163186681Sed case 33: /* Set foreground color: brown */ 1164186681Sed case 34: /* Set foreground color: blue */ 1165186681Sed case 35: /* Set foreground color: magenta */ 1166186681Sed case 36: /* Set foreground color: cyan */ 1167186681Sed case 37: /* Set foreground color: white */ 1168186681Sed t->t_curattr.ta_fgcolor = n - 30; 1169186681Sed break; 1170197522Sed case 38: /* Set foreground color: 256 color mode */ 1171197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1172197522Sed continue; 1173197522Sed t->t_curattr.ta_fgcolor = cmds[i + 2]; 1174197522Sed i += 2; 1175197522Sed break; 1176186681Sed case 39: /* Set default foreground color. */ 1177186681Sed t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1178186681Sed break; 1179186681Sed case 40: /* Set background color: black */ 1180186681Sed case 41: /* Set background color: red */ 1181186681Sed case 42: /* Set background color: green */ 1182186681Sed case 43: /* Set background color: brown */ 1183186681Sed case 44: /* Set background color: blue */ 1184186681Sed case 45: /* Set background color: magenta */ 1185186681Sed case 46: /* Set background color: cyan */ 1186186681Sed case 47: /* Set background color: white */ 1187186681Sed t->t_curattr.ta_bgcolor = n - 40; 1188186681Sed break; 1189197522Sed case 48: /* Set background color: 256 color mode */ 1190197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1191197522Sed continue; 1192197522Sed t->t_curattr.ta_bgcolor = cmds[i + 2]; 1193197522Sed i += 2; 1194197522Sed break; 1195186681Sed case 49: /* Set default background color. */ 1196186681Sed t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1197186681Sed break; 1198197522Sed case 90: /* Set bright foreground color: black */ 1199197522Sed case 91: /* Set bright foreground color: red */ 1200197522Sed case 92: /* Set bright foreground color: green */ 1201197522Sed case 93: /* Set bright foreground color: brown */ 1202197522Sed case 94: /* Set bright foreground color: blue */ 1203197522Sed case 95: /* Set bright foreground color: magenta */ 1204197522Sed case 96: /* Set bright foreground color: cyan */ 1205197522Sed case 97: /* Set bright foreground color: white */ 1206197522Sed t->t_curattr.ta_fgcolor = n - 90 + 8; 1207197522Sed break; 1208197522Sed case 100: /* Set bright background color: black */ 1209197522Sed case 101: /* Set bright background color: red */ 1210197522Sed case 102: /* Set bright background color: green */ 1211197522Sed case 103: /* Set bright background color: brown */ 1212197522Sed case 104: /* Set bright background color: blue */ 1213197522Sed case 105: /* Set bright background color: magenta */ 1214197522Sed case 106: /* Set bright background color: cyan */ 1215197522Sed case 107: /* Set bright background color: white */ 1216197522Sed t->t_curattr.ta_bgcolor = n - 100 + 8; 1217197522Sed break; 1218186681Sed default: 1219186681Sed teken_printf("unsupported attribute %u\n", n); 1220186681Sed } 1221186681Sed } 1222186681Sed} 1223186681Sed 1224186681Sedstatic void 1225186681Sedteken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1226186681Sed unsigned int bottom) 1227186681Sed{ 1228186681Sed 1229186681Sed /* Adjust top row number. */ 1230186681Sed if (top > 0) 1231186681Sed top--; 1232186681Sed /* Adjust bottom row number. */ 1233186681Sed if (bottom == 0 || bottom > t->t_winsize.tp_row) 1234186681Sed bottom = t->t_winsize.tp_row; 1235186681Sed 1236186681Sed /* Invalid arguments. */ 1237186681Sed if (top >= bottom - 1) { 1238186681Sed top = 0; 1239186681Sed bottom = t->t_winsize.tp_row; 1240186681Sed } 1241186681Sed 1242199170Sed /* Apply scrolling region. */ 1243186681Sed t->t_scrollreg.ts_begin = top; 1244186681Sed t->t_scrollreg.ts_end = bottom; 1245199170Sed if (t->t_stateflags & TS_ORIGIN) 1246186681Sed t->t_originreg = t->t_scrollreg; 1247199170Sed 1248199170Sed /* Home cursor to the top left of the scrolling region. */ 1249199170Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 1250199170Sed t->t_cursor.tp_col = 0; 1251199170Sed t->t_stateflags &= ~TS_WRAPPED; 1252199170Sed teken_funcs_cursor(t); 1253186681Sed} 1254186681Sed 1255186681Sedstatic void 1256186681Sedteken_subr_single_height_double_width_line(teken_t *t __unused) 1257186681Sed{ 1258186681Sed 1259186681Sed teken_printf("single height double width???\n"); 1260186681Sed} 1261186681Sed 1262186681Sedstatic void 1263186681Sedteken_subr_single_height_single_width_line(teken_t *t __unused) 1264186681Sed{ 1265186681Sed 1266186681Sed teken_printf("single height single width???\n"); 1267186681Sed} 1268186681Sed 1269186681Sedstatic void 1270186681Sedteken_subr_string_terminator(teken_t *t __unused) 1271186681Sed{ 1272186681Sed 1273197853Sed /* 1274197853Sed * Strings are already terminated in teken_input_char() when ^[ 1275197853Sed * is inserted. 1276197853Sed */ 1277186681Sed} 1278186681Sed 1279186681Sedstatic void 1280186681Sedteken_subr_tab_clear(teken_t *t, unsigned int cmd) 1281186681Sed{ 1282186681Sed 1283186681Sed switch (cmd) { 1284186681Sed case 0: 1285186681Sed teken_tab_clear(t, t->t_cursor.tp_col); 1286186681Sed break; 1287186681Sed case 3: 1288186681Sed memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1289186681Sed break; 1290186681Sed } 1291186681Sed} 1292186681Sed 1293186681Sedstatic void 1294186681Sedteken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1295186681Sed{ 1296186681Sed 1297186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1298216198Sed if (t->t_cursor.tp_row >= t->t_originreg.ts_end) 1299186681Sed t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1300186681Sed 1301186681Sed t->t_stateflags &= ~TS_WRAPPED; 1302186681Sed teken_funcs_cursor(t); 1303186681Sed} 1304