teken_subr.h revision 199171
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 199171 2009-11-11 08:20:19Z 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 728197117Sed tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0; 729197117Sed tr.tr_end = t->t_winsize; 730197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 731186798Sed 732197117Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 733197117Sed teken_funcs_cursor(t); 734197117Sed } else { 735197117Sed teken_subr_newline(t); 736197117Sed } 737186798Sed} 738186798Sed 739186798Sedstatic void 740186681Sedteken_subr_next_line(teken_t *t) 741186681Sed{ 742186681Sed 743186681Sed t->t_cursor.tp_col = 0; 744186681Sed teken_subr_newline(t); 745186681Sed} 746186681Sed 747186681Sedstatic void 748197853Sedteken_subr_operating_system_command(teken_t *t) 749197853Sed{ 750197853Sed 751197853Sed teken_printf("Unsupported operating system command\n"); 752197853Sed t->t_stateflags |= TS_INSTRING; 753197853Sed} 754197853Sed 755197853Sedstatic void 756186681Sedteken_subr_pan_down(teken_t *t, unsigned int nrows) 757186681Sed{ 758186681Sed 759186681Sed teken_subr_do_scroll(t, (int)nrows); 760186681Sed} 761186681Sed 762186681Sedstatic void 763186681Sedteken_subr_pan_up(teken_t *t, unsigned int nrows) 764186681Sed{ 765186681Sed 766186681Sed teken_subr_do_scroll(t, -(int)nrows); 767186681Sed} 768186681Sed 769186681Sedstatic void 770186681Sedteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 771186681Sed{ 772186681Sed 773186681Sed if (request == 0) { 774186681Sed const char response[] = "\x1B[?1;2c"; 775186681Sed 776186681Sed teken_funcs_respond(t, response, sizeof response - 1); 777186681Sed } else { 778186681Sed teken_printf("Unknown DA1\n"); 779186681Sed } 780186681Sed} 781186681Sed 782186681Sedstatic void 783186681Sedteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 784186681Sed int width) 785186681Sed{ 786186681Sed 787186681Sed if (t->t_stateflags & TS_INSERT && 788186681Sed tp->tp_col < t->t_winsize.tp_col - width) { 789186681Sed teken_rect_t ctr; 790186681Sed teken_pos_t ctp; 791186681Sed 792186681Sed /* Insert mode. Move existing characters to the right. */ 793186681Sed ctr.tr_begin = *tp; 794186681Sed ctr.tr_end.tp_row = tp->tp_row + 1; 795186681Sed ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 796186681Sed ctp.tp_row = tp->tp_row; 797186681Sed ctp.tp_col = tp->tp_col + width; 798186681Sed teken_funcs_copy(t, &ctr, &ctp); 799186681Sed } 800186681Sed 801197117Sed if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 802197117Sed teken_pos_t tp2; 803197117Sed 804197117Sed /* 805197117Sed * Store a space behind double width characters before 806197117Sed * actually printing them. This prevents artifacts when 807197117Sed * the consumer doesn't render it using double width 808197117Sed * glyphs. 809197117Sed */ 810197117Sed tp2.tp_row = tp->tp_row; 811197117Sed tp2.tp_col = tp->tp_col + 1; 812197117Sed teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 813197117Sed } 814197117Sed 815186681Sed teken_funcs_putchar(t, tp, c, &t->t_curattr); 816186681Sed} 817186681Sed 818186681Sedstatic void 819186681Sedteken_subr_regular_character(teken_t *t, teken_char_t c) 820186681Sed{ 821186681Sed int width; 822186681Sed 823197117Sed if (t->t_stateflags & TS_8BIT) { 824197470Sed if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) 825197115Sed return; 826197470Sed c = teken_scs_process(t, c); 827197115Sed width = 1; 828197115Sed } else { 829197115Sed c = teken_scs_process(t, c); 830197115Sed width = teken_wcwidth(c); 831197115Sed /* XXX: Don't process zero-width characters yet. */ 832197115Sed if (width <= 0) 833197115Sed return; 834197115Sed } 835186681Sed 836197117Sed if (t->t_stateflags & TS_CONS25) { 837197117Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 838197117Sed t->t_cursor.tp_col += width; 839197117Sed 840197117Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 841197117Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 842197117Sed /* Perform scrolling. */ 843197117Sed teken_subr_do_scroll(t, 1); 844197117Sed } else { 845197117Sed /* No scrolling needed. */ 846197117Sed if (t->t_cursor.tp_row < 847197117Sed t->t_winsize.tp_row - 1) 848197117Sed t->t_cursor.tp_row++; 849197117Sed } 850197117Sed t->t_cursor.tp_col = 0; 851197117Sed } 852197117Sed } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 853186681Sed (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 854186681Sed (TS_WRAPPED|TS_AUTOWRAP)) { 855186681Sed teken_pos_t tp; 856186681Sed 857186681Sed /* Perform line wrapping. */ 858186681Sed 859186681Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 860186681Sed /* Perform scrolling. */ 861186681Sed teken_subr_do_scroll(t, 1); 862186681Sed tp.tp_row = t->t_scrollreg.ts_end - 1; 863186681Sed } else { 864186681Sed /* No scrolling needed. */ 865186681Sed tp.tp_row = t->t_cursor.tp_row + 1; 866186681Sed if (tp.tp_row == t->t_winsize.tp_row) { 867186681Sed /* 868186681Sed * Corner case: regular character 869186681Sed * outside scrolling region, but at the 870186681Sed * bottom of the screen. 871186681Sed */ 872186681Sed teken_subr_do_putchar(t, &t->t_cursor, 873186681Sed c, width); 874186681Sed return; 875186681Sed } 876186681Sed } 877186681Sed 878186681Sed tp.tp_col = 0; 879186681Sed teken_subr_do_putchar(t, &tp, c, width); 880186681Sed 881186681Sed t->t_cursor.tp_row = tp.tp_row; 882186681Sed t->t_cursor.tp_col = width; 883186681Sed t->t_stateflags &= ~TS_WRAPPED; 884186681Sed } else { 885186681Sed /* No line wrapping needed. */ 886186681Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 887186681Sed t->t_cursor.tp_col += width; 888186681Sed 889186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 890186681Sed t->t_stateflags |= TS_WRAPPED; 891186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 892186681Sed } else { 893186681Sed t->t_stateflags &= ~TS_WRAPPED; 894186681Sed } 895186681Sed } 896186681Sed 897186681Sed teken_funcs_cursor(t); 898186681Sed} 899186681Sed 900186681Sedstatic void 901186681Sedteken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 902186681Sed{ 903186681Sed 904186681Sed switch (cmd) { 905186681Sed case 1: /* Cursor keys mode. */ 906199171Sed t->t_stateflags &= ~TS_CURSORKEYS; 907186681Sed break; 908186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 909186681Sed teken_printf("DECRST VT52\n"); 910186681Sed break; 911186681Sed case 3: /* 132 column mode. */ 912186681Sed teken_funcs_param(t, TP_132COLS, 0); 913186681Sed teken_subr_reset_to_initial_state(t); 914186681Sed break; 915186681Sed case 5: /* Inverse video. */ 916186681Sed teken_printf("DECRST inverse video\n"); 917186681Sed break; 918186681Sed case 6: /* Origin mode. */ 919186681Sed t->t_stateflags &= ~TS_ORIGIN; 920186681Sed t->t_originreg.ts_begin = 0; 921186681Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 922186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 923186681Sed t->t_stateflags &= ~TS_WRAPPED; 924186681Sed teken_funcs_cursor(t); 925186681Sed break; 926186681Sed case 7: /* Autowrap mode. */ 927186681Sed t->t_stateflags &= ~TS_AUTOWRAP; 928186681Sed break; 929186681Sed case 8: /* Autorepeat mode. */ 930186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 0); 931186681Sed break; 932186681Sed case 25: /* Hide cursor. */ 933186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 0); 934186681Sed break; 935186681Sed case 40: /* Disallow 132 columns. */ 936186681Sed teken_printf("DECRST allow 132\n"); 937186681Sed break; 938186681Sed case 45: /* Disable reverse wraparound. */ 939186681Sed teken_printf("DECRST reverse wraparound\n"); 940186681Sed break; 941186681Sed case 47: /* Switch to alternate buffer. */ 942186681Sed teken_printf("Switch to alternate buffer\n"); 943186681Sed break; 944197539Sed case 1000: /* Mouse input. */ 945197539Sed teken_funcs_param(t, TP_MOUSE, 0); 946197539Sed break; 947186681Sed default: 948186681Sed teken_printf("Unknown DECRST: %u\n", cmd); 949186681Sed } 950186681Sed} 951186681Sed 952186681Sedstatic void 953186681Sedteken_subr_reset_mode(teken_t *t, unsigned int cmd) 954186681Sed{ 955186681Sed 956186681Sed switch (cmd) { 957186681Sed case 4: 958186681Sed t->t_stateflags &= ~TS_INSERT; 959186681Sed break; 960186681Sed default: 961186681Sed teken_printf("Unknown reset mode: %u\n", cmd); 962186681Sed } 963186681Sed} 964186681Sed 965186681Sedstatic void 966186681Sedteken_subr_do_reset(teken_t *t) 967186681Sed{ 968186681Sed 969187469Sed t->t_curattr = t->t_defattr; 970186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 971197114Sed t->t_scrollreg.ts_begin = 0; 972197114Sed t->t_scrollreg.ts_end = t->t_winsize.tp_row; 973197114Sed t->t_originreg = t->t_scrollreg; 974197117Sed t->t_stateflags &= TS_8BIT|TS_CONS25; 975197117Sed t->t_stateflags |= TS_AUTOWRAP; 976186681Sed 977197520Sed t->t_scs[0] = teken_scs_us_ascii; 978197520Sed t->t_scs[1] = teken_scs_us_ascii; 979197520Sed t->t_curscs = 0; 980187469Sed 981187469Sed teken_subr_save_cursor(t); 982186681Sed teken_tab_default(t); 983186681Sed} 984186681Sed 985186681Sedstatic void 986186681Sedteken_subr_reset_to_initial_state(teken_t *t) 987186681Sed{ 988186681Sed 989186681Sed teken_subr_do_reset(t); 990186681Sed teken_subr_erase_display(t, 2); 991186753Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 992186681Sed teken_funcs_cursor(t); 993186681Sed} 994186681Sed 995186681Sedstatic void 996186681Sedteken_subr_restore_cursor(teken_t *t) 997186681Sed{ 998186681Sed 999186681Sed t->t_cursor = t->t_saved_cursor; 1000186681Sed t->t_curattr = t->t_saved_curattr; 1001197520Sed t->t_scs[t->t_curscs] = t->t_saved_curscs; 1002186681Sed t->t_stateflags &= ~TS_WRAPPED; 1003197521Sed 1004197521Sed /* Get out of origin mode when the cursor is moved outside. */ 1005197521Sed if (t->t_cursor.tp_row < t->t_originreg.ts_begin || 1006197521Sed t->t_cursor.tp_row >= t->t_originreg.ts_end) { 1007197521Sed t->t_stateflags &= ~TS_ORIGIN; 1008197521Sed t->t_originreg.ts_begin = 0; 1009197521Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 1010197521Sed } 1011197521Sed 1012186681Sed teken_funcs_cursor(t); 1013186681Sed} 1014186681Sed 1015186681Sedstatic void 1016186681Sedteken_subr_reverse_index(teken_t *t) 1017186681Sed{ 1018186681Sed 1019186681Sed if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 1020186681Sed t->t_cursor.tp_row--; 1021186681Sed t->t_stateflags &= ~TS_WRAPPED; 1022186681Sed teken_funcs_cursor(t); 1023186681Sed } else { 1024186681Sed teken_subr_do_scroll(t, -1); 1025186681Sed } 1026186681Sed} 1027186681Sed 1028186681Sedstatic void 1029186681Sedteken_subr_save_cursor(teken_t *t) 1030186681Sed{ 1031186681Sed 1032186681Sed t->t_saved_cursor = t->t_cursor; 1033186681Sed t->t_saved_curattr = t->t_curattr; 1034197520Sed t->t_saved_curscs = t->t_scs[t->t_curscs]; 1035186681Sed} 1036186681Sed 1037186681Sedstatic void 1038186681Sedteken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1039186681Sed{ 1040186681Sed 1041186681Sed if (request == 0) { 1042186681Sed const char response[] = "\x1B[>0;10;0c"; 1043186681Sed teken_funcs_respond(t, response, sizeof response - 1); 1044186681Sed } else { 1045186681Sed teken_printf("Unknown DA2\n"); 1046186681Sed } 1047186681Sed} 1048186681Sed 1049186681Sedstatic void 1050186681Sedteken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1051186681Sed{ 1052186681Sed 1053186681Sed switch (cmd) { 1054186681Sed case 1: /* Cursor keys mode. */ 1055199171Sed t->t_stateflags |= TS_CURSORKEYS; 1056186681Sed break; 1057186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 1058186681Sed teken_printf("DECSET VT52\n"); 1059186681Sed break; 1060186681Sed case 3: /* 132 column mode. */ 1061186681Sed teken_funcs_param(t, TP_132COLS, 1); 1062186681Sed teken_subr_reset_to_initial_state(t); 1063186681Sed break; 1064186681Sed case 5: /* Inverse video. */ 1065186681Sed teken_printf("DECSET inverse video\n"); 1066186681Sed break; 1067186681Sed case 6: /* Origin mode. */ 1068186681Sed t->t_stateflags |= TS_ORIGIN; 1069186681Sed t->t_originreg = t->t_scrollreg; 1070186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1071186681Sed t->t_cursor.tp_col = 0; 1072186681Sed t->t_stateflags &= ~TS_WRAPPED; 1073186681Sed teken_funcs_cursor(t); 1074186681Sed break; 1075186681Sed case 7: /* Autowrap mode. */ 1076186681Sed t->t_stateflags |= TS_AUTOWRAP; 1077186681Sed break; 1078186681Sed case 8: /* Autorepeat mode. */ 1079186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 1); 1080186681Sed break; 1081186681Sed case 25: /* Display cursor. */ 1082186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 1083186681Sed break; 1084186681Sed case 40: /* Allow 132 columns. */ 1085186681Sed teken_printf("DECSET allow 132\n"); 1086186681Sed break; 1087186681Sed case 45: /* Enable reverse wraparound. */ 1088186681Sed teken_printf("DECSET reverse wraparound\n"); 1089186681Sed break; 1090186681Sed case 47: /* Switch to alternate buffer. */ 1091186681Sed teken_printf("Switch away from alternate buffer\n"); 1092186681Sed break; 1093197539Sed case 1000: /* Mouse input. */ 1094197539Sed teken_funcs_param(t, TP_MOUSE, 1); 1095197539Sed break; 1096186681Sed default: 1097186681Sed teken_printf("Unknown DECSET: %u\n", cmd); 1098186681Sed } 1099186681Sed} 1100186681Sed 1101186681Sedstatic void 1102186681Sedteken_subr_set_mode(teken_t *t, unsigned int cmd) 1103186681Sed{ 1104186681Sed 1105186681Sed switch (cmd) { 1106186681Sed case 4: 1107186681Sed teken_printf("Insert mode\n"); 1108186681Sed t->t_stateflags |= TS_INSERT; 1109186681Sed break; 1110186681Sed default: 1111186681Sed teken_printf("Unknown set mode: %u\n", cmd); 1112186681Sed } 1113186681Sed} 1114186681Sed 1115186681Sedstatic void 1116186681Sedteken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1117186681Sed unsigned int cmds[]) 1118186681Sed{ 1119186681Sed unsigned int i, n; 1120186681Sed 1121186681Sed /* No attributes means reset. */ 1122186681Sed if (ncmds == 0) { 1123186681Sed t->t_curattr = t->t_defattr; 1124186681Sed return; 1125186681Sed } 1126186681Sed 1127186681Sed for (i = 0; i < ncmds; i++) { 1128186681Sed n = cmds[i]; 1129186681Sed 1130186681Sed switch (n) { 1131186681Sed case 0: /* Reset. */ 1132186681Sed t->t_curattr = t->t_defattr; 1133186681Sed break; 1134186681Sed case 1: /* Bold. */ 1135186681Sed t->t_curattr.ta_format |= TF_BOLD; 1136186681Sed break; 1137186681Sed case 4: /* Underline. */ 1138186681Sed t->t_curattr.ta_format |= TF_UNDERLINE; 1139186681Sed break; 1140186681Sed case 5: /* Blink. */ 1141186681Sed t->t_curattr.ta_format |= TF_BLINK; 1142186681Sed break; 1143186681Sed case 7: /* Reverse. */ 1144186681Sed t->t_curattr.ta_format |= TF_REVERSE; 1145186681Sed break; 1146186681Sed case 22: /* Remove bold. */ 1147186681Sed t->t_curattr.ta_format &= ~TF_BOLD; 1148186681Sed break; 1149186681Sed case 24: /* Remove underline. */ 1150186681Sed t->t_curattr.ta_format &= ~TF_UNDERLINE; 1151186681Sed break; 1152186681Sed case 25: /* Remove blink. */ 1153186681Sed t->t_curattr.ta_format &= ~TF_BLINK; 1154186681Sed break; 1155186681Sed case 27: /* Remove reverse. */ 1156186681Sed t->t_curattr.ta_format &= ~TF_REVERSE; 1157186681Sed break; 1158186681Sed case 30: /* Set foreground color: black */ 1159186681Sed case 31: /* Set foreground color: red */ 1160186681Sed case 32: /* Set foreground color: green */ 1161186681Sed case 33: /* Set foreground color: brown */ 1162186681Sed case 34: /* Set foreground color: blue */ 1163186681Sed case 35: /* Set foreground color: magenta */ 1164186681Sed case 36: /* Set foreground color: cyan */ 1165186681Sed case 37: /* Set foreground color: white */ 1166186681Sed t->t_curattr.ta_fgcolor = n - 30; 1167186681Sed break; 1168197522Sed case 38: /* Set foreground color: 256 color mode */ 1169197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1170197522Sed continue; 1171197522Sed t->t_curattr.ta_fgcolor = cmds[i + 2]; 1172197522Sed i += 2; 1173197522Sed break; 1174186681Sed case 39: /* Set default foreground color. */ 1175186681Sed t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1176186681Sed break; 1177186681Sed case 40: /* Set background color: black */ 1178186681Sed case 41: /* Set background color: red */ 1179186681Sed case 42: /* Set background color: green */ 1180186681Sed case 43: /* Set background color: brown */ 1181186681Sed case 44: /* Set background color: blue */ 1182186681Sed case 45: /* Set background color: magenta */ 1183186681Sed case 46: /* Set background color: cyan */ 1184186681Sed case 47: /* Set background color: white */ 1185186681Sed t->t_curattr.ta_bgcolor = n - 40; 1186186681Sed break; 1187197522Sed case 48: /* Set background color: 256 color mode */ 1188197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1189197522Sed continue; 1190197522Sed t->t_curattr.ta_bgcolor = cmds[i + 2]; 1191197522Sed i += 2; 1192197522Sed break; 1193186681Sed case 49: /* Set default background color. */ 1194186681Sed t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1195186681Sed break; 1196197522Sed case 90: /* Set bright foreground color: black */ 1197197522Sed case 91: /* Set bright foreground color: red */ 1198197522Sed case 92: /* Set bright foreground color: green */ 1199197522Sed case 93: /* Set bright foreground color: brown */ 1200197522Sed case 94: /* Set bright foreground color: blue */ 1201197522Sed case 95: /* Set bright foreground color: magenta */ 1202197522Sed case 96: /* Set bright foreground color: cyan */ 1203197522Sed case 97: /* Set bright foreground color: white */ 1204197522Sed t->t_curattr.ta_fgcolor = n - 90 + 8; 1205197522Sed break; 1206197522Sed case 100: /* Set bright background color: black */ 1207197522Sed case 101: /* Set bright background color: red */ 1208197522Sed case 102: /* Set bright background color: green */ 1209197522Sed case 103: /* Set bright background color: brown */ 1210197522Sed case 104: /* Set bright background color: blue */ 1211197522Sed case 105: /* Set bright background color: magenta */ 1212197522Sed case 106: /* Set bright background color: cyan */ 1213197522Sed case 107: /* Set bright background color: white */ 1214197522Sed t->t_curattr.ta_bgcolor = n - 100 + 8; 1215197522Sed break; 1216186681Sed default: 1217186681Sed teken_printf("unsupported attribute %u\n", n); 1218186681Sed } 1219186681Sed } 1220186681Sed} 1221186681Sed 1222186681Sedstatic void 1223186681Sedteken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1224186681Sed unsigned int bottom) 1225186681Sed{ 1226186681Sed 1227186681Sed /* Adjust top row number. */ 1228186681Sed if (top > 0) 1229186681Sed top--; 1230186681Sed /* Adjust bottom row number. */ 1231186681Sed if (bottom == 0 || bottom > t->t_winsize.tp_row) 1232186681Sed bottom = t->t_winsize.tp_row; 1233186681Sed 1234186681Sed /* Invalid arguments. */ 1235186681Sed if (top >= bottom - 1) { 1236186681Sed top = 0; 1237186681Sed bottom = t->t_winsize.tp_row; 1238186681Sed } 1239186681Sed 1240199170Sed /* Apply scrolling region. */ 1241186681Sed t->t_scrollreg.ts_begin = top; 1242186681Sed t->t_scrollreg.ts_end = bottom; 1243199170Sed if (t->t_stateflags & TS_ORIGIN) 1244186681Sed t->t_originreg = t->t_scrollreg; 1245199170Sed 1246199170Sed /* Home cursor to the top left of the scrolling region. */ 1247199170Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 1248199170Sed t->t_cursor.tp_col = 0; 1249199170Sed t->t_stateflags &= ~TS_WRAPPED; 1250199170Sed teken_funcs_cursor(t); 1251186681Sed} 1252186681Sed 1253186681Sedstatic void 1254186681Sedteken_subr_single_height_double_width_line(teken_t *t __unused) 1255186681Sed{ 1256186681Sed 1257186681Sed teken_printf("single height double width???\n"); 1258186681Sed} 1259186681Sed 1260186681Sedstatic void 1261186681Sedteken_subr_single_height_single_width_line(teken_t *t __unused) 1262186681Sed{ 1263186681Sed 1264186681Sed teken_printf("single height single width???\n"); 1265186681Sed} 1266186681Sed 1267186681Sedstatic void 1268186681Sedteken_subr_string_terminator(teken_t *t __unused) 1269186681Sed{ 1270186681Sed 1271197853Sed /* 1272197853Sed * Strings are already terminated in teken_input_char() when ^[ 1273197853Sed * is inserted. 1274197853Sed */ 1275186681Sed} 1276186681Sed 1277186681Sedstatic void 1278186681Sedteken_subr_tab_clear(teken_t *t, unsigned int cmd) 1279186681Sed{ 1280186681Sed 1281186681Sed switch (cmd) { 1282186681Sed case 0: 1283186681Sed teken_tab_clear(t, t->t_cursor.tp_col); 1284186681Sed break; 1285186681Sed case 3: 1286186681Sed memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1287186681Sed break; 1288186681Sed } 1289186681Sed} 1290186681Sed 1291186681Sedstatic void 1292186681Sedteken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1293186681Sed{ 1294186681Sed 1295186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1296186681Sed if (row >= t->t_originreg.ts_end) 1297186681Sed t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1298186681Sed 1299186681Sed 1300186681Sed t->t_stateflags &= ~TS_WRAPPED; 1301186681Sed teken_funcs_cursor(t); 1302186681Sed} 1303