teken_subr.h revision 197539
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 197539 2009-09-27 18:19:41Z 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 428186681Sedteken_subr_device_control_string(teken_t *t __unused) 429186681Sed{ 430186681Sed 431186681Sed teken_printf("device control string???\n"); 432186681Sed} 433186681Sed 434186681Sedstatic void 435186681Sedteken_subr_device_status_report(teken_t *t, unsigned int cmd) 436186681Sed{ 437186681Sed char response[19] = "\x1B[?"; 438186681Sed ssize_t len; 439186681Sed 440186681Sed len = teken_subr_do_cpr(t, cmd, response + 3); 441186681Sed if (len < 0) 442186681Sed return; 443186681Sed 444186681Sed teken_funcs_respond(t, response, len + 3); 445186681Sed} 446186681Sed 447186681Sedstatic void 448186681Sedteken_subr_double_height_double_width_line_top(teken_t *t __unused) 449186681Sed{ 450186681Sed 451186681Sed teken_printf("double height double width top\n"); 452186681Sed} 453186681Sed 454186681Sedstatic void 455186681Sedteken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 456186681Sed{ 457186681Sed 458186681Sed teken_printf("double height double width bottom\n"); 459186681Sed} 460186681Sed 461186681Sedstatic void 462186681Sedteken_subr_erase_character(teken_t *t, unsigned int ncols) 463186681Sed{ 464186681Sed teken_rect_t tr; 465186681Sed 466186681Sed tr.tr_begin = t->t_cursor; 467186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 468186681Sed 469186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 470186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 471186681Sed else 472186681Sed tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 473186681Sed 474186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 475186681Sed} 476186681Sed 477186681Sedstatic void 478186681Sedteken_subr_erase_display(teken_t *t, unsigned int mode) 479186681Sed{ 480186681Sed teken_rect_t r; 481186681Sed 482186681Sed r.tr_begin.tp_col = 0; 483186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 484186681Sed 485186681Sed switch (mode) { 486186681Sed case 1: /* Erase from the top to the cursor. */ 487186681Sed teken_subr_erase_line(t, 1); 488186681Sed 489186681Sed /* Erase lines above. */ 490186681Sed if (t->t_cursor.tp_row == 0) 491186681Sed return; 492186681Sed r.tr_begin.tp_row = 0; 493186681Sed r.tr_end.tp_row = t->t_cursor.tp_row; 494186681Sed break; 495186681Sed case 2: /* Erase entire display. */ 496186681Sed r.tr_begin.tp_row = 0; 497186681Sed r.tr_end.tp_row = t->t_winsize.tp_row; 498186681Sed break; 499186681Sed default: /* Erase from cursor to the bottom. */ 500186681Sed teken_subr_erase_line(t, 0); 501186681Sed 502186681Sed /* Erase lines below. */ 503186681Sed if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 504186681Sed return; 505186681Sed r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 506186681Sed r.tr_end.tp_row = t->t_winsize.tp_row; 507186681Sed break; 508186681Sed } 509186681Sed 510186681Sed teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 511186681Sed} 512186681Sed 513186681Sedstatic void 514186681Sedteken_subr_erase_line(teken_t *t, unsigned int mode) 515186681Sed{ 516186681Sed teken_rect_t r; 517186681Sed 518186681Sed r.tr_begin.tp_row = t->t_cursor.tp_row; 519186681Sed r.tr_end.tp_row = t->t_cursor.tp_row + 1; 520186681Sed 521186681Sed switch (mode) { 522186681Sed case 1: /* Erase from the beginning of the line to the cursor. */ 523186681Sed r.tr_begin.tp_col = 0; 524186681Sed r.tr_end.tp_col = t->t_cursor.tp_col + 1; 525186681Sed break; 526186681Sed case 2: /* Erase entire line. */ 527186681Sed r.tr_begin.tp_col = 0; 528186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 529186681Sed break; 530186681Sed default: /* Erase from cursor to the end of the line. */ 531186681Sed r.tr_begin.tp_col = t->t_cursor.tp_col; 532186681Sed r.tr_end.tp_col = t->t_winsize.tp_col; 533186681Sed break; 534186681Sed } 535186681Sed 536186681Sed teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 537186681Sed} 538186681Sed 539186681Sedstatic void 540187469Sedteken_subr_g0_scs_special_graphics(teken_t *t __unused) 541187469Sed{ 542187469Sed 543197520Sed t->t_scs[0] = teken_scs_special_graphics; 544187469Sed} 545187469Sed 546187469Sedstatic void 547187469Sedteken_subr_g0_scs_uk_national(teken_t *t __unused) 548187469Sed{ 549187469Sed 550197520Sed t->t_scs[0] = teken_scs_uk_national; 551187469Sed} 552187469Sed 553187469Sedstatic void 554187469Sedteken_subr_g0_scs_us_ascii(teken_t *t __unused) 555187469Sed{ 556187469Sed 557197520Sed t->t_scs[0] = teken_scs_us_ascii; 558187469Sed} 559187469Sed 560187469Sedstatic void 561187469Sedteken_subr_g1_scs_special_graphics(teken_t *t __unused) 562187469Sed{ 563187469Sed 564197520Sed t->t_scs[1] = teken_scs_special_graphics; 565187469Sed} 566187469Sed 567187469Sedstatic void 568187469Sedteken_subr_g1_scs_uk_national(teken_t *t __unused) 569187469Sed{ 570187469Sed 571197520Sed t->t_scs[1] = teken_scs_uk_national; 572187469Sed} 573187469Sed 574187469Sedstatic void 575187469Sedteken_subr_g1_scs_us_ascii(teken_t *t __unused) 576187469Sed{ 577187469Sed 578197520Sed t->t_scs[1] = teken_scs_us_ascii; 579187469Sed} 580187469Sed 581187469Sedstatic void 582186681Sedteken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 583186681Sed{ 584186681Sed 585186681Sed t->t_cursor.tp_col = col - 1; 586186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 587186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 588186681Sed 589186681Sed t->t_stateflags &= ~TS_WRAPPED; 590186681Sed teken_funcs_cursor(t); 591186681Sed} 592186681Sed 593186681Sedstatic void 594186681Sedteken_subr_horizontal_tab(teken_t *t) 595186681Sed{ 596186681Sed 597197117Sed if (t->t_stateflags & TS_CONS25) { 598197117Sed teken_subr_cursor_forward_tabulation(t, 1); 599197117Sed } else { 600197117Sed teken_rect_t tr; 601186681Sed 602197117Sed tr.tr_begin = t->t_cursor; 603197117Sed teken_subr_cursor_forward_tabulation(t, 1); 604197117Sed tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 605197117Sed tr.tr_end.tp_col = t->t_cursor.tp_col; 606187367Sed 607197117Sed /* Blank region that we skipped. */ 608197117Sed if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 609197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 610197117Sed } 611186681Sed} 612186681Sed 613186681Sedstatic void 614186681Sedteken_subr_horizontal_tab_set(teken_t *t) 615186681Sed{ 616186681Sed 617186681Sed teken_tab_set(t, t->t_cursor.tp_col); 618186681Sed} 619186681Sed 620186681Sedstatic void 621186681Sedteken_subr_index(teken_t *t) 622186681Sed{ 623186681Sed 624186681Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 625186681Sed t->t_cursor.tp_row++; 626186681Sed t->t_stateflags &= ~TS_WRAPPED; 627186681Sed teken_funcs_cursor(t); 628186681Sed } else { 629186681Sed teken_subr_do_scroll(t, 1); 630186681Sed } 631186681Sed} 632186681Sed 633186681Sedstatic void 634186681Sedteken_subr_insert_character(teken_t *t, unsigned int ncols) 635186681Sed{ 636186681Sed teken_rect_t tr; 637186681Sed 638186681Sed tr.tr_begin = t->t_cursor; 639186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 640186681Sed 641186681Sed if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 642186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 643186681Sed } else { 644186681Sed teken_pos_t tp; 645186681Sed 646186681Sed /* Copy characters to the right. */ 647186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 648186681Sed tp.tp_row = t->t_cursor.tp_row; 649186681Sed tp.tp_col = t->t_cursor.tp_col + ncols; 650186681Sed teken_funcs_copy(t, &tr, &tp); 651186681Sed 652186681Sed tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 653186681Sed } 654186681Sed 655186681Sed /* Blank current location. */ 656186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 657186681Sed} 658186681Sed 659186681Sedstatic void 660186681Sedteken_subr_insert_line(teken_t *t, unsigned int nrows) 661186681Sed{ 662186681Sed teken_rect_t tr; 663186681Sed 664197480Sed /* Ignore if outside scrolling region. */ 665197480Sed if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 666197480Sed t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 667197480Sed return; 668197480Sed 669186681Sed tr.tr_begin.tp_row = t->t_cursor.tp_row; 670186681Sed tr.tr_begin.tp_col = 0; 671186681Sed tr.tr_end.tp_col = t->t_winsize.tp_col; 672186681Sed 673186681Sed if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 674186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end; 675186681Sed } else { 676186681Sed teken_pos_t tp; 677186681Sed 678186681Sed /* Copy lines down. */ 679186681Sed tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 680186681Sed tp.tp_row = t->t_cursor.tp_row + nrows; 681186681Sed tp.tp_col = 0; 682186681Sed teken_funcs_copy(t, &tr, &tp); 683186681Sed 684186681Sed tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 685186681Sed } 686186681Sed 687186681Sed /* Blank current location. */ 688186681Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 689186681Sed} 690186681Sed 691186681Sedstatic void 692186681Sedteken_subr_keypad_application_mode(teken_t *t) 693186681Sed{ 694186681Sed 695186681Sed teken_funcs_param(t, TP_KEYPADAPP, 1); 696186681Sed} 697186681Sed 698186681Sedstatic void 699186681Sedteken_subr_keypad_numeric_mode(teken_t *t) 700186681Sed{ 701186681Sed 702186681Sed teken_funcs_param(t, TP_KEYPADAPP, 0); 703186681Sed} 704186681Sed 705186681Sedstatic void 706186681Sedteken_subr_newline(teken_t *t) 707186681Sed{ 708186681Sed 709186681Sed t->t_cursor.tp_row++; 710186681Sed 711186681Sed if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 712186681Sed teken_subr_do_scroll(t, 1); 713186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 714186681Sed } 715186681Sed 716186681Sed t->t_stateflags &= ~TS_WRAPPED; 717186681Sed teken_funcs_cursor(t); 718186681Sed} 719186681Sed 720186681Sedstatic void 721186798Sedteken_subr_newpage(teken_t *t) 722186798Sed{ 723187367Sed 724197117Sed if (t->t_stateflags & TS_CONS25) { 725197117Sed teken_rect_t tr; 726186798Sed 727197117Sed tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0; 728197117Sed tr.tr_end = t->t_winsize; 729197117Sed teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 730186798Sed 731197117Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 732197117Sed teken_funcs_cursor(t); 733197117Sed } else { 734197117Sed teken_subr_newline(t); 735197117Sed } 736186798Sed} 737186798Sed 738186798Sedstatic void 739186681Sedteken_subr_next_line(teken_t *t) 740186681Sed{ 741186681Sed 742186681Sed t->t_cursor.tp_col = 0; 743186681Sed teken_subr_newline(t); 744186681Sed} 745186681Sed 746186681Sedstatic void 747186681Sedteken_subr_pan_down(teken_t *t, unsigned int nrows) 748186681Sed{ 749186681Sed 750186681Sed teken_subr_do_scroll(t, (int)nrows); 751186681Sed} 752186681Sed 753186681Sedstatic void 754186681Sedteken_subr_pan_up(teken_t *t, unsigned int nrows) 755186681Sed{ 756186681Sed 757186681Sed teken_subr_do_scroll(t, -(int)nrows); 758186681Sed} 759186681Sed 760186681Sedstatic void 761186681Sedteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 762186681Sed{ 763186681Sed 764186681Sed if (request == 0) { 765186681Sed const char response[] = "\x1B[?1;2c"; 766186681Sed 767186681Sed teken_funcs_respond(t, response, sizeof response - 1); 768186681Sed } else { 769186681Sed teken_printf("Unknown DA1\n"); 770186681Sed } 771186681Sed} 772186681Sed 773186681Sedstatic void 774186681Sedteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 775186681Sed int width) 776186681Sed{ 777186681Sed 778186681Sed if (t->t_stateflags & TS_INSERT && 779186681Sed tp->tp_col < t->t_winsize.tp_col - width) { 780186681Sed teken_rect_t ctr; 781186681Sed teken_pos_t ctp; 782186681Sed 783186681Sed /* Insert mode. Move existing characters to the right. */ 784186681Sed ctr.tr_begin = *tp; 785186681Sed ctr.tr_end.tp_row = tp->tp_row + 1; 786186681Sed ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 787186681Sed ctp.tp_row = tp->tp_row; 788186681Sed ctp.tp_col = tp->tp_col + width; 789186681Sed teken_funcs_copy(t, &ctr, &ctp); 790186681Sed } 791186681Sed 792197117Sed if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 793197117Sed teken_pos_t tp2; 794197117Sed 795197117Sed /* 796197117Sed * Store a space behind double width characters before 797197117Sed * actually printing them. This prevents artifacts when 798197117Sed * the consumer doesn't render it using double width 799197117Sed * glyphs. 800197117Sed */ 801197117Sed tp2.tp_row = tp->tp_row; 802197117Sed tp2.tp_col = tp->tp_col + 1; 803197117Sed teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 804197117Sed } 805197117Sed 806186681Sed teken_funcs_putchar(t, tp, c, &t->t_curattr); 807186681Sed} 808186681Sed 809186681Sedstatic void 810186681Sedteken_subr_regular_character(teken_t *t, teken_char_t c) 811186681Sed{ 812186681Sed int width; 813186681Sed 814197117Sed if (t->t_stateflags & TS_8BIT) { 815197470Sed if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) 816197115Sed return; 817197470Sed c = teken_scs_process(t, c); 818197115Sed width = 1; 819197115Sed } else { 820197115Sed c = teken_scs_process(t, c); 821197115Sed width = teken_wcwidth(c); 822197115Sed /* XXX: Don't process zero-width characters yet. */ 823197115Sed if (width <= 0) 824197115Sed return; 825197115Sed } 826186681Sed 827197117Sed if (t->t_stateflags & TS_CONS25) { 828197117Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 829197117Sed t->t_cursor.tp_col += width; 830197117Sed 831197117Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 832197117Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 833197117Sed /* Perform scrolling. */ 834197117Sed teken_subr_do_scroll(t, 1); 835197117Sed } else { 836197117Sed /* No scrolling needed. */ 837197117Sed if (t->t_cursor.tp_row < 838197117Sed t->t_winsize.tp_row - 1) 839197117Sed t->t_cursor.tp_row++; 840197117Sed } 841197117Sed t->t_cursor.tp_col = 0; 842197117Sed } 843197117Sed } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 844186681Sed (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 845186681Sed (TS_WRAPPED|TS_AUTOWRAP)) { 846186681Sed teken_pos_t tp; 847186681Sed 848186681Sed /* Perform line wrapping. */ 849186681Sed 850186681Sed if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 851186681Sed /* Perform scrolling. */ 852186681Sed teken_subr_do_scroll(t, 1); 853186681Sed tp.tp_row = t->t_scrollreg.ts_end - 1; 854186681Sed } else { 855186681Sed /* No scrolling needed. */ 856186681Sed tp.tp_row = t->t_cursor.tp_row + 1; 857186681Sed if (tp.tp_row == t->t_winsize.tp_row) { 858186681Sed /* 859186681Sed * Corner case: regular character 860186681Sed * outside scrolling region, but at the 861186681Sed * bottom of the screen. 862186681Sed */ 863186681Sed teken_subr_do_putchar(t, &t->t_cursor, 864186681Sed c, width); 865186681Sed return; 866186681Sed } 867186681Sed } 868186681Sed 869186681Sed tp.tp_col = 0; 870186681Sed teken_subr_do_putchar(t, &tp, c, width); 871186681Sed 872186681Sed t->t_cursor.tp_row = tp.tp_row; 873186681Sed t->t_cursor.tp_col = width; 874186681Sed t->t_stateflags &= ~TS_WRAPPED; 875186681Sed } else { 876186681Sed /* No line wrapping needed. */ 877186681Sed teken_subr_do_putchar(t, &t->t_cursor, c, width); 878186681Sed t->t_cursor.tp_col += width; 879186681Sed 880186681Sed if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 881186681Sed t->t_stateflags |= TS_WRAPPED; 882186681Sed t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 883186681Sed } else { 884186681Sed t->t_stateflags &= ~TS_WRAPPED; 885186681Sed } 886186681Sed } 887186681Sed 888186681Sed teken_funcs_cursor(t); 889186681Sed} 890186681Sed 891186681Sedstatic void 892186681Sedteken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 893186681Sed{ 894186681Sed 895186681Sed switch (cmd) { 896186681Sed case 1: /* Cursor keys mode. */ 897186681Sed teken_funcs_param(t, TP_CURSORKEYS, 0); 898186681Sed break; 899186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 900186681Sed teken_printf("DECRST VT52\n"); 901186681Sed break; 902186681Sed case 3: /* 132 column mode. */ 903186681Sed teken_funcs_param(t, TP_132COLS, 0); 904186681Sed teken_subr_reset_to_initial_state(t); 905186681Sed break; 906186681Sed case 5: /* Inverse video. */ 907186681Sed teken_printf("DECRST inverse video\n"); 908186681Sed break; 909186681Sed case 6: /* Origin mode. */ 910186681Sed t->t_stateflags &= ~TS_ORIGIN; 911186681Sed t->t_originreg.ts_begin = 0; 912186681Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 913186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 914186681Sed t->t_stateflags &= ~TS_WRAPPED; 915186681Sed teken_funcs_cursor(t); 916186681Sed break; 917186681Sed case 7: /* Autowrap mode. */ 918186681Sed t->t_stateflags &= ~TS_AUTOWRAP; 919186681Sed break; 920186681Sed case 8: /* Autorepeat mode. */ 921186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 0); 922186681Sed break; 923186681Sed case 25: /* Hide cursor. */ 924186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 0); 925186681Sed break; 926186681Sed case 40: /* Disallow 132 columns. */ 927186681Sed teken_printf("DECRST allow 132\n"); 928186681Sed break; 929186681Sed case 45: /* Disable reverse wraparound. */ 930186681Sed teken_printf("DECRST reverse wraparound\n"); 931186681Sed break; 932186681Sed case 47: /* Switch to alternate buffer. */ 933186681Sed teken_printf("Switch to alternate buffer\n"); 934186681Sed break; 935197539Sed case 1000: /* Mouse input. */ 936197539Sed teken_funcs_param(t, TP_MOUSE, 0); 937197539Sed break; 938186681Sed default: 939186681Sed teken_printf("Unknown DECRST: %u\n", cmd); 940186681Sed } 941186681Sed} 942186681Sed 943186681Sedstatic void 944186681Sedteken_subr_reset_mode(teken_t *t, unsigned int cmd) 945186681Sed{ 946186681Sed 947186681Sed switch (cmd) { 948186681Sed case 4: 949186681Sed t->t_stateflags &= ~TS_INSERT; 950186681Sed break; 951186681Sed default: 952186681Sed teken_printf("Unknown reset mode: %u\n", cmd); 953186681Sed } 954186681Sed} 955186681Sed 956186681Sedstatic void 957186681Sedteken_subr_do_reset(teken_t *t) 958186681Sed{ 959186681Sed 960187469Sed t->t_curattr = t->t_defattr; 961186681Sed t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 962197114Sed t->t_scrollreg.ts_begin = 0; 963197114Sed t->t_scrollreg.ts_end = t->t_winsize.tp_row; 964197114Sed t->t_originreg = t->t_scrollreg; 965197117Sed t->t_stateflags &= TS_8BIT|TS_CONS25; 966197117Sed t->t_stateflags |= TS_AUTOWRAP; 967186681Sed 968197520Sed t->t_scs[0] = teken_scs_us_ascii; 969197520Sed t->t_scs[1] = teken_scs_us_ascii; 970197520Sed t->t_curscs = 0; 971187469Sed 972187469Sed teken_subr_save_cursor(t); 973186681Sed teken_tab_default(t); 974186681Sed} 975186681Sed 976186681Sedstatic void 977186681Sedteken_subr_reset_to_initial_state(teken_t *t) 978186681Sed{ 979186681Sed 980186681Sed teken_subr_do_reset(t); 981186681Sed teken_subr_erase_display(t, 2); 982186753Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 983186681Sed teken_funcs_cursor(t); 984186681Sed} 985186681Sed 986186681Sedstatic void 987186681Sedteken_subr_restore_cursor(teken_t *t) 988186681Sed{ 989186681Sed 990186681Sed t->t_cursor = t->t_saved_cursor; 991186681Sed t->t_curattr = t->t_saved_curattr; 992197520Sed t->t_scs[t->t_curscs] = t->t_saved_curscs; 993186681Sed t->t_stateflags &= ~TS_WRAPPED; 994197521Sed 995197521Sed /* Get out of origin mode when the cursor is moved outside. */ 996197521Sed if (t->t_cursor.tp_row < t->t_originreg.ts_begin || 997197521Sed t->t_cursor.tp_row >= t->t_originreg.ts_end) { 998197521Sed t->t_stateflags &= ~TS_ORIGIN; 999197521Sed t->t_originreg.ts_begin = 0; 1000197521Sed t->t_originreg.ts_end = t->t_winsize.tp_row; 1001197521Sed } 1002197521Sed 1003186681Sed teken_funcs_cursor(t); 1004186681Sed} 1005186681Sed 1006186681Sedstatic void 1007186681Sedteken_subr_reverse_index(teken_t *t) 1008186681Sed{ 1009186681Sed 1010186681Sed if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 1011186681Sed t->t_cursor.tp_row--; 1012186681Sed t->t_stateflags &= ~TS_WRAPPED; 1013186681Sed teken_funcs_cursor(t); 1014186681Sed } else { 1015186681Sed teken_subr_do_scroll(t, -1); 1016186681Sed } 1017186681Sed} 1018186681Sed 1019186681Sedstatic void 1020186681Sedteken_subr_save_cursor(teken_t *t) 1021186681Sed{ 1022186681Sed 1023186681Sed t->t_saved_cursor = t->t_cursor; 1024186681Sed t->t_saved_curattr = t->t_curattr; 1025197520Sed t->t_saved_curscs = t->t_scs[t->t_curscs]; 1026186681Sed} 1027186681Sed 1028186681Sedstatic void 1029186681Sedteken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1030186681Sed{ 1031186681Sed 1032186681Sed if (request == 0) { 1033186681Sed const char response[] = "\x1B[>0;10;0c"; 1034186681Sed teken_funcs_respond(t, response, sizeof response - 1); 1035186681Sed } else { 1036186681Sed teken_printf("Unknown DA2\n"); 1037186681Sed } 1038186681Sed} 1039186681Sed 1040186681Sedstatic void 1041186681Sedteken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1042186681Sed{ 1043186681Sed 1044186681Sed switch (cmd) { 1045186681Sed case 1: /* Cursor keys mode. */ 1046186681Sed teken_funcs_param(t, TP_CURSORKEYS, 1); 1047186681Sed break; 1048186681Sed case 2: /* DECANM: ANSI/VT52 mode. */ 1049186681Sed teken_printf("DECSET VT52\n"); 1050186681Sed break; 1051186681Sed case 3: /* 132 column mode. */ 1052186681Sed teken_funcs_param(t, TP_132COLS, 1); 1053186681Sed teken_subr_reset_to_initial_state(t); 1054186681Sed break; 1055186681Sed case 5: /* Inverse video. */ 1056186681Sed teken_printf("DECSET inverse video\n"); 1057186681Sed break; 1058186681Sed case 6: /* Origin mode. */ 1059186681Sed t->t_stateflags |= TS_ORIGIN; 1060186681Sed t->t_originreg = t->t_scrollreg; 1061186681Sed t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1062186681Sed t->t_cursor.tp_col = 0; 1063186681Sed t->t_stateflags &= ~TS_WRAPPED; 1064186681Sed teken_funcs_cursor(t); 1065186681Sed break; 1066186681Sed case 7: /* Autowrap mode. */ 1067186681Sed t->t_stateflags |= TS_AUTOWRAP; 1068186681Sed break; 1069186681Sed case 8: /* Autorepeat mode. */ 1070186681Sed teken_funcs_param(t, TP_AUTOREPEAT, 1); 1071186681Sed break; 1072186681Sed case 25: /* Display cursor. */ 1073186681Sed teken_funcs_param(t, TP_SHOWCURSOR, 1); 1074186681Sed break; 1075186681Sed case 40: /* Allow 132 columns. */ 1076186681Sed teken_printf("DECSET allow 132\n"); 1077186681Sed break; 1078186681Sed case 45: /* Enable reverse wraparound. */ 1079186681Sed teken_printf("DECSET reverse wraparound\n"); 1080186681Sed break; 1081186681Sed case 47: /* Switch to alternate buffer. */ 1082186681Sed teken_printf("Switch away from alternate buffer\n"); 1083186681Sed break; 1084197539Sed case 1000: /* Mouse input. */ 1085197539Sed teken_funcs_param(t, TP_MOUSE, 1); 1086197539Sed break; 1087186681Sed default: 1088186681Sed teken_printf("Unknown DECSET: %u\n", cmd); 1089186681Sed } 1090186681Sed} 1091186681Sed 1092186681Sedstatic void 1093186681Sedteken_subr_set_mode(teken_t *t, unsigned int cmd) 1094186681Sed{ 1095186681Sed 1096186681Sed switch (cmd) { 1097186681Sed case 4: 1098186681Sed teken_printf("Insert mode\n"); 1099186681Sed t->t_stateflags |= TS_INSERT; 1100186681Sed break; 1101186681Sed default: 1102186681Sed teken_printf("Unknown set mode: %u\n", cmd); 1103186681Sed } 1104186681Sed} 1105186681Sed 1106186681Sedstatic void 1107186681Sedteken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1108186681Sed unsigned int cmds[]) 1109186681Sed{ 1110186681Sed unsigned int i, n; 1111186681Sed 1112186681Sed /* No attributes means reset. */ 1113186681Sed if (ncmds == 0) { 1114186681Sed t->t_curattr = t->t_defattr; 1115186681Sed return; 1116186681Sed } 1117186681Sed 1118186681Sed for (i = 0; i < ncmds; i++) { 1119186681Sed n = cmds[i]; 1120186681Sed 1121186681Sed switch (n) { 1122186681Sed case 0: /* Reset. */ 1123186681Sed t->t_curattr = t->t_defattr; 1124186681Sed break; 1125186681Sed case 1: /* Bold. */ 1126186681Sed t->t_curattr.ta_format |= TF_BOLD; 1127186681Sed break; 1128186681Sed case 4: /* Underline. */ 1129186681Sed t->t_curattr.ta_format |= TF_UNDERLINE; 1130186681Sed break; 1131186681Sed case 5: /* Blink. */ 1132186681Sed t->t_curattr.ta_format |= TF_BLINK; 1133186681Sed break; 1134186681Sed case 7: /* Reverse. */ 1135186681Sed t->t_curattr.ta_format |= TF_REVERSE; 1136186681Sed break; 1137186681Sed case 22: /* Remove bold. */ 1138186681Sed t->t_curattr.ta_format &= ~TF_BOLD; 1139186681Sed break; 1140186681Sed case 24: /* Remove underline. */ 1141186681Sed t->t_curattr.ta_format &= ~TF_UNDERLINE; 1142186681Sed break; 1143186681Sed case 25: /* Remove blink. */ 1144186681Sed t->t_curattr.ta_format &= ~TF_BLINK; 1145186681Sed break; 1146186681Sed case 27: /* Remove reverse. */ 1147186681Sed t->t_curattr.ta_format &= ~TF_REVERSE; 1148186681Sed break; 1149186681Sed case 30: /* Set foreground color: black */ 1150186681Sed case 31: /* Set foreground color: red */ 1151186681Sed case 32: /* Set foreground color: green */ 1152186681Sed case 33: /* Set foreground color: brown */ 1153186681Sed case 34: /* Set foreground color: blue */ 1154186681Sed case 35: /* Set foreground color: magenta */ 1155186681Sed case 36: /* Set foreground color: cyan */ 1156186681Sed case 37: /* Set foreground color: white */ 1157186681Sed t->t_curattr.ta_fgcolor = n - 30; 1158186681Sed break; 1159197522Sed case 38: /* Set foreground color: 256 color mode */ 1160197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1161197522Sed continue; 1162197522Sed t->t_curattr.ta_fgcolor = cmds[i + 2]; 1163197522Sed i += 2; 1164197522Sed break; 1165186681Sed case 39: /* Set default foreground color. */ 1166186681Sed t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1167186681Sed break; 1168186681Sed case 40: /* Set background color: black */ 1169186681Sed case 41: /* Set background color: red */ 1170186681Sed case 42: /* Set background color: green */ 1171186681Sed case 43: /* Set background color: brown */ 1172186681Sed case 44: /* Set background color: blue */ 1173186681Sed case 45: /* Set background color: magenta */ 1174186681Sed case 46: /* Set background color: cyan */ 1175186681Sed case 47: /* Set background color: white */ 1176186681Sed t->t_curattr.ta_bgcolor = n - 40; 1177186681Sed break; 1178197522Sed case 48: /* Set background color: 256 color mode */ 1179197522Sed if (i + 2 >= ncmds || cmds[i + 1] != 5) 1180197522Sed continue; 1181197522Sed t->t_curattr.ta_bgcolor = cmds[i + 2]; 1182197522Sed i += 2; 1183197522Sed break; 1184186681Sed case 49: /* Set default background color. */ 1185186681Sed t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1186186681Sed break; 1187197522Sed case 90: /* Set bright foreground color: black */ 1188197522Sed case 91: /* Set bright foreground color: red */ 1189197522Sed case 92: /* Set bright foreground color: green */ 1190197522Sed case 93: /* Set bright foreground color: brown */ 1191197522Sed case 94: /* Set bright foreground color: blue */ 1192197522Sed case 95: /* Set bright foreground color: magenta */ 1193197522Sed case 96: /* Set bright foreground color: cyan */ 1194197522Sed case 97: /* Set bright foreground color: white */ 1195197522Sed t->t_curattr.ta_fgcolor = n - 90 + 8; 1196197522Sed break; 1197197522Sed case 100: /* Set bright background color: black */ 1198197522Sed case 101: /* Set bright background color: red */ 1199197522Sed case 102: /* Set bright background color: green */ 1200197522Sed case 103: /* Set bright background color: brown */ 1201197522Sed case 104: /* Set bright background color: blue */ 1202197522Sed case 105: /* Set bright background color: magenta */ 1203197522Sed case 106: /* Set bright background color: cyan */ 1204197522Sed case 107: /* Set bright background color: white */ 1205197522Sed t->t_curattr.ta_bgcolor = n - 100 + 8; 1206197522Sed break; 1207186681Sed default: 1208186681Sed teken_printf("unsupported attribute %u\n", n); 1209186681Sed } 1210186681Sed } 1211186681Sed} 1212186681Sed 1213186681Sedstatic void 1214186681Sedteken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1215186681Sed unsigned int bottom) 1216186681Sed{ 1217186681Sed 1218186681Sed /* Adjust top row number. */ 1219186681Sed if (top > 0) 1220186681Sed top--; 1221186681Sed /* Adjust bottom row number. */ 1222186681Sed if (bottom == 0 || bottom > t->t_winsize.tp_row) 1223186681Sed bottom = t->t_winsize.tp_row; 1224186681Sed 1225186681Sed /* Invalid arguments. */ 1226186681Sed if (top >= bottom - 1) { 1227186681Sed top = 0; 1228186681Sed bottom = t->t_winsize.tp_row; 1229186681Sed } 1230186681Sed 1231186681Sed t->t_scrollreg.ts_begin = top; 1232186681Sed t->t_scrollreg.ts_end = bottom; 1233186681Sed if (t->t_stateflags & TS_ORIGIN) { 1234186681Sed /* XXX: home cursor? */ 1235186681Sed t->t_originreg = t->t_scrollreg; 1236186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin; 1237186681Sed t->t_cursor.tp_col = 0; 1238186681Sed t->t_stateflags &= ~TS_WRAPPED; 1239186681Sed teken_funcs_cursor(t); 1240186681Sed } 1241186681Sed} 1242186681Sed 1243186681Sedstatic void 1244186681Sedteken_subr_single_height_double_width_line(teken_t *t __unused) 1245186681Sed{ 1246186681Sed 1247186681Sed teken_printf("single height double width???\n"); 1248186681Sed} 1249186681Sed 1250186681Sedstatic void 1251186681Sedteken_subr_single_height_single_width_line(teken_t *t __unused) 1252186681Sed{ 1253186681Sed 1254186681Sed teken_printf("single height single width???\n"); 1255186681Sed} 1256186681Sed 1257186681Sedstatic void 1258186681Sedteken_subr_string_terminator(teken_t *t __unused) 1259186681Sed{ 1260186681Sed 1261186681Sed teken_printf("string terminator???\n"); 1262186681Sed} 1263186681Sed 1264186681Sedstatic void 1265186681Sedteken_subr_tab_clear(teken_t *t, unsigned int cmd) 1266186681Sed{ 1267186681Sed 1268186681Sed switch (cmd) { 1269186681Sed case 0: 1270186681Sed teken_tab_clear(t, t->t_cursor.tp_col); 1271186681Sed break; 1272186681Sed case 3: 1273186681Sed memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1274186681Sed break; 1275186681Sed } 1276186681Sed} 1277186681Sed 1278186681Sedstatic void 1279186681Sedteken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1280186681Sed{ 1281186681Sed 1282186681Sed t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1283186681Sed if (row >= t->t_originreg.ts_end) 1284186681Sed t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1285186681Sed 1286186681Sed 1287186681Sed t->t_stateflags &= ~TS_WRAPPED; 1288186681Sed teken_funcs_cursor(t); 1289186681Sed} 1290