teken_subr.h revision 197520
133965Sjdp/*- 238889Sjdp * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 338889Sjdp * All rights reserved. 433965Sjdp * 533965Sjdp * Redistribution and use in source and binary forms, with or without 633965Sjdp * modification, are permitted provided that the following conditions 733965Sjdp * are met: 833965Sjdp * 1. Redistributions of source code must retain the above copyright 933965Sjdp * notice, this list of conditions and the following disclaimer. 1033965Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1133965Sjdp * notice, this list of conditions and the following disclaimer in the 1233965Sjdp * documentation and/or other materials provided with the distribution. 1333965Sjdp * 1433965Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1533965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1633965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1733965Sjdp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1833965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1933965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2033965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2133965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2233965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2333965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2433965Sjdp * SUCH DAMAGE. 2533965Sjdp * 2633965Sjdp * $FreeBSD: head/sys/teken/teken_subr.h 197520 2009-09-26 15:03:42Z ed $ 2733965Sjdp */ 2833965Sjdp 2933965Sjdpstatic void teken_subr_cursor_up(teken_t *, unsigned int); 3033965Sjdpstatic void teken_subr_erase_line(teken_t *, unsigned int); 3133965Sjdpstatic void teken_subr_regular_character(teken_t *, teken_char_t); 3233965Sjdpstatic void teken_subr_reset_to_initial_state(teken_t *); 3333965Sjdpstatic void teken_subr_save_cursor(teken_t *); 3433965Sjdp 3533965Sjdpstatic inline int 3677298Sobrienteken_tab_isset(teken_t *t, unsigned int col) 3733965Sjdp{ 3833965Sjdp unsigned int b, o; 3933965Sjdp 4033965Sjdp if (col >= T_NUMCOL) 4133965Sjdp return ((col % 8) == 0); 4233965Sjdp 4333965Sjdp b = col / (sizeof(unsigned int) * 8); 4433965Sjdp o = col % (sizeof(unsigned int) * 8); 4533965Sjdp 4633965Sjdp return (t->t_tabstops[b] & (1 << o)); 4733965Sjdp} 4833965Sjdp 4933965Sjdpstatic inline void 5033965Sjdpteken_tab_clear(teken_t *t, unsigned int col) 5133965Sjdp{ 5233965Sjdp unsigned int b, o; 5333965Sjdp 5433965Sjdp if (col >= T_NUMCOL) 5533965Sjdp return; 5633965Sjdp 5733965Sjdp b = col / (sizeof(unsigned int) * 8); 5833965Sjdp o = col % (sizeof(unsigned int) * 8); 5933965Sjdp 6033965Sjdp t->t_tabstops[b] &= ~(1 << o); 6133965Sjdp} 6233965Sjdp 6333965Sjdpstatic inline void 6433965Sjdpteken_tab_set(teken_t *t, unsigned int col) 6533965Sjdp{ 6633965Sjdp unsigned int b, o; 6733965Sjdp 6833965Sjdp if (col >= T_NUMCOL) 6933965Sjdp return; 7033965Sjdp 7133965Sjdp b = col / (sizeof(unsigned int) * 8); 7233965Sjdp o = col % (sizeof(unsigned int) * 8); 7333965Sjdp 7433965Sjdp t->t_tabstops[b] |= 1 << o; 7533965Sjdp} 7633965Sjdp 7733965Sjdpstatic void 7833965Sjdpteken_tab_default(teken_t *t) 7933965Sjdp{ 8033965Sjdp unsigned int i; 8133965Sjdp 8233965Sjdp memset(&t->t_tabstops, 0, T_NUMCOL / 8); 8333965Sjdp 8433965Sjdp for (i = 8; i < T_NUMCOL; i += 8) 8533965Sjdp teken_tab_set(t, i); 8633965Sjdp} 8733965Sjdp 8833965Sjdpstatic void 8933965Sjdpteken_subr_do_scroll(teken_t *t, int amount) 9033965Sjdp{ 9133965Sjdp teken_rect_t tr; 9233965Sjdp teken_pos_t tp; 9333965Sjdp 9433965Sjdp teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); 9533965Sjdp teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); 9633965Sjdp teken_assert(amount != 0); 9733965Sjdp 9833965Sjdp /* Copy existing data 1 line up. */ 9933965Sjdp if (amount > 0) { 10033965Sjdp /* Scroll down. */ 10133965Sjdp 10233965Sjdp /* Copy existing data up. */ 10333965Sjdp if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 10433965Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; 10533965Sjdp tr.tr_begin.tp_col = 0; 10633965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end; 10733965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 10833965Sjdp tp.tp_row = t->t_scrollreg.ts_begin; 10933965Sjdp tp.tp_col = 0; 11033965Sjdp teken_funcs_copy(t, &tr, &tp); 11133965Sjdp 11233965Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; 11333965Sjdp } else { 11433965Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 11533965Sjdp } 11633965Sjdp 11733965Sjdp /* Clear the last lines. */ 11833965Sjdp tr.tr_begin.tp_col = 0; 11933965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end; 12033965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 12133965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 12233965Sjdp } else { 12333965Sjdp /* Scroll up. */ 12433965Sjdp amount = -amount; 12533965Sjdp 12677298Sobrien /* Copy existing data down. */ 12733965Sjdp if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 12838889Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 12933965Sjdp tr.tr_begin.tp_col = 0; 13033965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; 13133965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 13233965Sjdp tp.tp_row = t->t_scrollreg.ts_begin + amount; 13333965Sjdp tp.tp_col = 0; 13438889Sjdp teken_funcs_copy(t, &tr, &tp); 13533965Sjdp 13633965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; 13733965Sjdp } else { 13833965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end; 13933965Sjdp } 14038889Sjdp 14133965Sjdp /* Clear the first lines. */ 14233965Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 14333965Sjdp tr.tr_begin.tp_col = 0; 14433965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 14533965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 14633965Sjdp } 14733965Sjdp} 14833965Sjdp 14933965Sjdpstatic ssize_t 15033965Sjdpteken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16]) 15133965Sjdp{ 15233965Sjdp 15360484Sobrien switch (cmd) { 15460484Sobrien case 5: /* Operating status. */ 15560484Sobrien strcpy(response, "0n"); 15660484Sobrien return (2); 15760484Sobrien case 6: { /* Cursor position. */ 15833965Sjdp int len; 15933965Sjdp 16033965Sjdp len = snprintf(response, 16, "%u;%uR", 16133965Sjdp (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, 16233965Sjdp t->t_cursor.tp_col + 1); 16333965Sjdp 16433965Sjdp if (len >= 16) 16533965Sjdp return (-1); 16633965Sjdp return (len); 16733965Sjdp } 16833965Sjdp case 15: /* Printer status. */ 16933965Sjdp strcpy(response, "13n"); 17033965Sjdp return (3); 17133965Sjdp case 25: /* UDK status. */ 17233965Sjdp strcpy(response, "20n"); 17333965Sjdp return (3); 17433965Sjdp case 26: /* Keyboard status. */ 17533965Sjdp strcpy(response, "27;1n"); 17633965Sjdp return (5); 17733965Sjdp default: 17833965Sjdp teken_printf("Unknown DSR\n"); 17933965Sjdp return (-1); 18033965Sjdp } 18133965Sjdp} 18233965Sjdp 18377298Sobrienstatic void 18433965Sjdpteken_subr_alignment_test(teken_t *t) 18533965Sjdp{ 18633965Sjdp teken_rect_t tr; 18733965Sjdp 18833965Sjdp t->t_scrollreg.ts_begin = 0; 18933965Sjdp t->t_scrollreg.ts_end = t->t_winsize.tp_row; 19033965Sjdp 19133965Sjdp t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 19233965Sjdp t->t_stateflags &= ~TS_WRAPPED; 19333965Sjdp teken_funcs_cursor(t); 19433965Sjdp 19533965Sjdp tr.tr_begin.tp_row = 0; 19633965Sjdp tr.tr_begin.tp_col = 0; 19733965Sjdp tr.tr_end = t->t_winsize; 19833965Sjdp teken_funcs_fill(t, &tr, 'E', &t->t_defattr); 19933965Sjdp} 20033965Sjdp 20133965Sjdpstatic void 20233965Sjdpteken_subr_backspace(teken_t *t) 20333965Sjdp{ 20433965Sjdp 20533965Sjdp if (t->t_stateflags & TS_CONS25) { 20633965Sjdp if (t->t_cursor.tp_col == 0) { 20733965Sjdp if (t->t_cursor.tp_row == t->t_originreg.ts_begin) 20833965Sjdp return; 20933965Sjdp t->t_cursor.tp_row--; 21033965Sjdp t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 21133965Sjdp } else { 21233965Sjdp t->t_cursor.tp_col--; 21333965Sjdp } 21433965Sjdp } else { 21533965Sjdp if (t->t_cursor.tp_col == 0) 21633965Sjdp return; 21733965Sjdp 21833965Sjdp t->t_cursor.tp_col--; 21933965Sjdp t->t_stateflags &= ~TS_WRAPPED; 22033965Sjdp } 22133965Sjdp 22238889Sjdp teken_funcs_cursor(t); 22333965Sjdp} 22433965Sjdp 22538889Sjdpstatic void 22633965Sjdpteken_subr_bell(teken_t *t) 22733965Sjdp{ 22833965Sjdp 22938889Sjdp teken_funcs_bell(t); 23033965Sjdp} 23133965Sjdp 23233965Sjdpstatic void 23333965Sjdpteken_subr_carriage_return(teken_t *t) 23433965Sjdp{ 23533965Sjdp 23633965Sjdp t->t_cursor.tp_col = 0; 23733965Sjdp t->t_stateflags &= ~TS_WRAPPED; 23833965Sjdp teken_funcs_cursor(t); 23933965Sjdp} 24060484Sobrien 24160484Sobrienstatic void 24260484Sobrienteken_subr_cursor_backward(teken_t *t, unsigned int ncols) 24333965Sjdp{ 24433965Sjdp 24533965Sjdp if (ncols > t->t_cursor.tp_col) 24633965Sjdp t->t_cursor.tp_col = 0; 24733965Sjdp else 24833965Sjdp t->t_cursor.tp_col -= ncols; 24933965Sjdp t->t_stateflags &= ~TS_WRAPPED; 25033965Sjdp teken_funcs_cursor(t); 25133965Sjdp} 25233965Sjdp 25333965Sjdpstatic void 25433965Sjdpteken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) 25533965Sjdp{ 25633965Sjdp 25733965Sjdp do { 25833965Sjdp /* Stop when we've reached the beginning of the line. */ 25933965Sjdp if (t->t_cursor.tp_col == 0) 26033965Sjdp break; 26133965Sjdp 26233965Sjdp t->t_cursor.tp_col--; 26333965Sjdp 26433965Sjdp /* Tab marker set. */ 26533965Sjdp if (teken_tab_isset(t, t->t_cursor.tp_col)) 26633965Sjdp ntabs--; 26733965Sjdp } while (ntabs > 0); 26833965Sjdp 26933965Sjdp teken_funcs_cursor(t); 27033965Sjdp} 27133965Sjdp 27233965Sjdpstatic void 27333965Sjdpteken_subr_cursor_down(teken_t *t, unsigned int nrows) 27433965Sjdp{ 27533965Sjdp 27633965Sjdp if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) 27733965Sjdp t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 27877298Sobrien else 27933965Sjdp t->t_cursor.tp_row += nrows; 28033965Sjdp t->t_stateflags &= ~TS_WRAPPED; 28133965Sjdp teken_funcs_cursor(t); 28277298Sobrien} 28333965Sjdp 28433965Sjdpstatic void 28533965Sjdpteken_subr_cursor_forward(teken_t *t, unsigned int ncols) 28633965Sjdp{ 28733965Sjdp 28833965Sjdp if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 28933965Sjdp t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 29033965Sjdp else 29133965Sjdp t->t_cursor.tp_col += ncols; 29233965Sjdp t->t_stateflags &= ~TS_WRAPPED; 29333965Sjdp teken_funcs_cursor(t); 29433965Sjdp} 29533965Sjdp 29633965Sjdpstatic void 29733965Sjdpteken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) 29833965Sjdp{ 29933965Sjdp 30033965Sjdp do { 30133965Sjdp /* Stop when we've reached the end of the line. */ 30233965Sjdp if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) 30333965Sjdp break; 30433965Sjdp 30533965Sjdp t->t_cursor.tp_col++; 30633965Sjdp 30733965Sjdp /* Tab marker set. */ 30833965Sjdp if (teken_tab_isset(t, t->t_cursor.tp_col)) 30933965Sjdp ntabs--; 31033965Sjdp } while (ntabs > 0); 31133965Sjdp 31233965Sjdp teken_funcs_cursor(t); 31333965Sjdp} 31433965Sjdp 31533965Sjdpstatic void 31633965Sjdpteken_subr_cursor_next_line(teken_t *t, unsigned int ncols) 31733965Sjdp{ 31833965Sjdp 31933965Sjdp t->t_cursor.tp_col = 0; 32033965Sjdp teken_subr_cursor_down(t, ncols); 32133965Sjdp} 32233965Sjdp 32333965Sjdpstatic void 32433965Sjdpteken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) 32533965Sjdp{ 32633965Sjdp 32733965Sjdp t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 32833965Sjdp if (row >= t->t_originreg.ts_end) 32933965Sjdp t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 33033965Sjdp 33133965Sjdp t->t_cursor.tp_col = col - 1; 33233965Sjdp if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 33333965Sjdp t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 33433965Sjdp 33533965Sjdp t->t_stateflags &= ~TS_WRAPPED; 33633965Sjdp teken_funcs_cursor(t); 33733965Sjdp} 33833965Sjdp 33933965Sjdpstatic void 34033965Sjdpteken_subr_cursor_position_report(teken_t *t, unsigned int cmd) 34133965Sjdp{ 34233965Sjdp char response[18] = "\x1B["; 34333965Sjdp ssize_t len; 34433965Sjdp 34533965Sjdp len = teken_subr_do_cpr(t, cmd, response + 2); 34633965Sjdp if (len < 0) 34733965Sjdp return; 34833965Sjdp 34933965Sjdp teken_funcs_respond(t, response, len + 2); 35033965Sjdp} 35133965Sjdp 35233965Sjdpstatic void 35333965Sjdpteken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) 35433965Sjdp{ 35533965Sjdp 35633965Sjdp t->t_cursor.tp_col = 0; 35733965Sjdp teken_subr_cursor_up(t, ncols); 35833965Sjdp} 35933965Sjdp 36033965Sjdpstatic void 36133965Sjdpteken_subr_cursor_up(teken_t *t, unsigned int nrows) 36233965Sjdp{ 36333965Sjdp 36433965Sjdp if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) 36533965Sjdp t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 36633965Sjdp else 36733965Sjdp t->t_cursor.tp_row -= nrows; 36833965Sjdp t->t_stateflags &= ~TS_WRAPPED; 36933965Sjdp teken_funcs_cursor(t); 37033965Sjdp} 37133965Sjdp 37233965Sjdpstatic void 37333965Sjdpteken_subr_delete_character(teken_t *t, unsigned int ncols) 37433965Sjdp{ 37533965Sjdp teken_rect_t tr; 37633965Sjdp 37733965Sjdp tr.tr_begin.tp_row = t->t_cursor.tp_row; 37833965Sjdp tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 37933965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 38033965Sjdp 38133965Sjdp if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 38233965Sjdp tr.tr_begin.tp_col = t->t_cursor.tp_col; 38333965Sjdp } else { 38433965Sjdp /* Copy characters to the left. */ 38533965Sjdp tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; 38633965Sjdp teken_funcs_copy(t, &tr, &t->t_cursor); 38733965Sjdp 38833965Sjdp tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; 38933965Sjdp } 39033965Sjdp 39133965Sjdp /* Blank trailing columns. */ 39233965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 39333965Sjdp} 39433965Sjdp 39533965Sjdpstatic void 39633965Sjdpteken_subr_delete_line(teken_t *t, unsigned int nrows) 39733965Sjdp{ 39833965Sjdp teken_rect_t tr; 39933965Sjdp 40033965Sjdp /* Ignore if outside scrolling region. */ 40133965Sjdp if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 40233965Sjdp t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 40333965Sjdp return; 40433965Sjdp 40533965Sjdp tr.tr_begin.tp_col = 0; 40633965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end; 40733965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 40833965Sjdp 40933965Sjdp if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 41033965Sjdp tr.tr_begin.tp_row = t->t_cursor.tp_row; 41133965Sjdp } else { 41233965Sjdp teken_pos_t tp; 41333965Sjdp 41433965Sjdp /* Copy rows up. */ 41533965Sjdp tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; 41633965Sjdp tp.tp_row = t->t_cursor.tp_row; 41733965Sjdp tp.tp_col = 0; 41833965Sjdp teken_funcs_copy(t, &tr, &tp); 41933965Sjdp 42033965Sjdp tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; 42133965Sjdp } 42233965Sjdp 42333965Sjdp /* Blank trailing rows. */ 42433965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 42533965Sjdp} 42633965Sjdp 42733965Sjdpstatic void 42833965Sjdpteken_subr_device_control_string(teken_t *t __unused) 42933965Sjdp{ 43033965Sjdp 43133965Sjdp teken_printf("device control string???\n"); 43233965Sjdp} 43333965Sjdp 43433965Sjdpstatic void 43533965Sjdpteken_subr_device_status_report(teken_t *t, unsigned int cmd) 43633965Sjdp{ 43733965Sjdp char response[19] = "\x1B[?"; 43833965Sjdp ssize_t len; 43933965Sjdp 44033965Sjdp len = teken_subr_do_cpr(t, cmd, response + 3); 44133965Sjdp if (len < 0) 44277298Sobrien return; 44333965Sjdp 44433965Sjdp teken_funcs_respond(t, response, len + 3); 44533965Sjdp} 44633965Sjdp 44733965Sjdpstatic void 44833965Sjdpteken_subr_double_height_double_width_line_top(teken_t *t __unused) 44933965Sjdp{ 45033965Sjdp 45133965Sjdp teken_printf("double height double width top\n"); 45233965Sjdp} 45333965Sjdp 45433965Sjdpstatic void 45533965Sjdpteken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 45633965Sjdp{ 45733965Sjdp 45833965Sjdp teken_printf("double height double width bottom\n"); 45933965Sjdp} 46033965Sjdp 46133965Sjdpstatic void 46233965Sjdpteken_subr_erase_character(teken_t *t, unsigned int ncols) 46333965Sjdp{ 46433965Sjdp teken_rect_t tr; 46533965Sjdp 46633965Sjdp tr.tr_begin = t->t_cursor; 46733965Sjdp tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 46833965Sjdp 46933965Sjdp if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 47033965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 47133965Sjdp else 47233965Sjdp tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 47333965Sjdp 47433965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 47533965Sjdp} 47633965Sjdp 47733965Sjdpstatic void 47877298Sobrienteken_subr_erase_display(teken_t *t, unsigned int mode) 47933965Sjdp{ 48033965Sjdp teken_rect_t r; 48133965Sjdp 48233965Sjdp r.tr_begin.tp_col = 0; 48333965Sjdp r.tr_end.tp_col = t->t_winsize.tp_col; 48433965Sjdp 48533965Sjdp switch (mode) { 48633965Sjdp case 1: /* Erase from the top to the cursor. */ 48733965Sjdp teken_subr_erase_line(t, 1); 48833965Sjdp 48933965Sjdp /* Erase lines above. */ 49033965Sjdp if (t->t_cursor.tp_row == 0) 49133965Sjdp return; 49233965Sjdp r.tr_begin.tp_row = 0; 49333965Sjdp r.tr_end.tp_row = t->t_cursor.tp_row; 49433965Sjdp break; 49533965Sjdp case 2: /* Erase entire display. */ 49633965Sjdp r.tr_begin.tp_row = 0; 49733965Sjdp r.tr_end.tp_row = t->t_winsize.tp_row; 49833965Sjdp break; 49933965Sjdp default: /* Erase from cursor to the bottom. */ 50033965Sjdp teken_subr_erase_line(t, 0); 50133965Sjdp 50233965Sjdp /* Erase lines below. */ 50333965Sjdp if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 50433965Sjdp return; 50533965Sjdp r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 50633965Sjdp r.tr_end.tp_row = t->t_winsize.tp_row; 50733965Sjdp break; 50833965Sjdp } 50933965Sjdp 51033965Sjdp teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 51133965Sjdp} 51233965Sjdp 51333965Sjdpstatic void 51433965Sjdpteken_subr_erase_line(teken_t *t, unsigned int mode) 51533965Sjdp{ 51633965Sjdp teken_rect_t r; 51733965Sjdp 51833965Sjdp r.tr_begin.tp_row = t->t_cursor.tp_row; 51933965Sjdp r.tr_end.tp_row = t->t_cursor.tp_row + 1; 52033965Sjdp 52133965Sjdp switch (mode) { 52233965Sjdp case 1: /* Erase from the beginning of the line to the cursor. */ 52333965Sjdp r.tr_begin.tp_col = 0; 52433965Sjdp r.tr_end.tp_col = t->t_cursor.tp_col + 1; 52533965Sjdp break; 52633965Sjdp case 2: /* Erase entire line. */ 52733965Sjdp r.tr_begin.tp_col = 0; 52833965Sjdp r.tr_end.tp_col = t->t_winsize.tp_col; 52933965Sjdp break; 53033965Sjdp default: /* Erase from cursor to the end of the line. */ 53133965Sjdp r.tr_begin.tp_col = t->t_cursor.tp_col; 53233965Sjdp r.tr_end.tp_col = t->t_winsize.tp_col; 53333965Sjdp break; 53433965Sjdp } 53533965Sjdp 53633965Sjdp teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 53733965Sjdp} 53833965Sjdp 53933965Sjdpstatic void 54033965Sjdpteken_subr_g0_scs_special_graphics(teken_t *t __unused) 54133965Sjdp{ 54233965Sjdp 54333965Sjdp t->t_scs[0] = teken_scs_special_graphics; 54433965Sjdp} 54533965Sjdp 54677298Sobrienstatic void 54733965Sjdpteken_subr_g0_scs_uk_national(teken_t *t __unused) 54833965Sjdp{ 54933965Sjdp 55033965Sjdp t->t_scs[0] = teken_scs_uk_national; 55133965Sjdp} 55233965Sjdp 55333965Sjdpstatic void 55433965Sjdpteken_subr_g0_scs_us_ascii(teken_t *t __unused) 55533965Sjdp{ 55633965Sjdp 55733965Sjdp t->t_scs[0] = teken_scs_us_ascii; 55833965Sjdp} 55933965Sjdp 56033965Sjdpstatic void 56133965Sjdpteken_subr_g1_scs_special_graphics(teken_t *t __unused) 56233965Sjdp{ 56333965Sjdp 56433965Sjdp t->t_scs[1] = teken_scs_special_graphics; 56533965Sjdp} 56633965Sjdp 56733965Sjdpstatic void 56833965Sjdpteken_subr_g1_scs_uk_national(teken_t *t __unused) 56933965Sjdp{ 57033965Sjdp 57133965Sjdp t->t_scs[1] = teken_scs_uk_national; 57233965Sjdp} 57333965Sjdp 57433965Sjdpstatic void 57533965Sjdpteken_subr_g1_scs_us_ascii(teken_t *t __unused) 57633965Sjdp{ 57733965Sjdp 57833965Sjdp t->t_scs[1] = teken_scs_us_ascii; 57933965Sjdp} 58033965Sjdp 58133965Sjdpstatic void 58233965Sjdpteken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 58333965Sjdp{ 58433965Sjdp 58533965Sjdp t->t_cursor.tp_col = col - 1; 58633965Sjdp if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 58733965Sjdp t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 58833965Sjdp 58933965Sjdp t->t_stateflags &= ~TS_WRAPPED; 59033965Sjdp teken_funcs_cursor(t); 59133965Sjdp} 59233965Sjdp 59333965Sjdpstatic void 59433965Sjdpteken_subr_horizontal_tab(teken_t *t) 59533965Sjdp{ 59633965Sjdp 59733965Sjdp if (t->t_stateflags & TS_CONS25) { 59833965Sjdp teken_subr_cursor_forward_tabulation(t, 1); 59933965Sjdp } else { 60033965Sjdp teken_rect_t tr; 60133965Sjdp 60233965Sjdp tr.tr_begin = t->t_cursor; 60333965Sjdp teken_subr_cursor_forward_tabulation(t, 1); 60433965Sjdp tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 60533965Sjdp tr.tr_end.tp_col = t->t_cursor.tp_col; 60633965Sjdp 60733965Sjdp /* Blank region that we skipped. */ 60833965Sjdp if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 60933965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 61033965Sjdp } 61133965Sjdp} 61233965Sjdp 61333965Sjdpstatic void 61433965Sjdpteken_subr_horizontal_tab_set(teken_t *t) 61533965Sjdp{ 61633965Sjdp 61733965Sjdp teken_tab_set(t, t->t_cursor.tp_col); 61833965Sjdp} 61933965Sjdp 62033965Sjdpstatic void 62133965Sjdpteken_subr_index(teken_t *t) 62233965Sjdp{ 62333965Sjdp 62433965Sjdp if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 62533965Sjdp t->t_cursor.tp_row++; 62633965Sjdp t->t_stateflags &= ~TS_WRAPPED; 62733965Sjdp teken_funcs_cursor(t); 62833965Sjdp } else { 62933965Sjdp teken_subr_do_scroll(t, 1); 63033965Sjdp } 63133965Sjdp} 63233965Sjdp 63333965Sjdpstatic void 63433965Sjdpteken_subr_insert_character(teken_t *t, unsigned int ncols) 63533965Sjdp{ 63633965Sjdp teken_rect_t tr; 63733965Sjdp 63833965Sjdp tr.tr_begin = t->t_cursor; 63933965Sjdp tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 64033965Sjdp 64133965Sjdp if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 64233965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 64333965Sjdp } else { 64433965Sjdp teken_pos_t tp; 64533965Sjdp 64633965Sjdp /* Copy characters to the right. */ 64733965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 64833965Sjdp tp.tp_row = t->t_cursor.tp_row; 64933965Sjdp tp.tp_col = t->t_cursor.tp_col + ncols; 65033965Sjdp teken_funcs_copy(t, &tr, &tp); 65133965Sjdp 65233965Sjdp tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 65333965Sjdp } 65433965Sjdp 65533965Sjdp /* Blank current location. */ 65633965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 65733965Sjdp} 65833965Sjdp 65933965Sjdpstatic void 66033965Sjdpteken_subr_insert_line(teken_t *t, unsigned int nrows) 66133965Sjdp{ 66233965Sjdp teken_rect_t tr; 66333965Sjdp 66433965Sjdp /* Ignore if outside scrolling region. */ 66533965Sjdp if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin || 66633965Sjdp t->t_cursor.tp_row >= t->t_scrollreg.ts_end) 66733965Sjdp return; 66833965Sjdp 66933965Sjdp tr.tr_begin.tp_row = t->t_cursor.tp_row; 67033965Sjdp tr.tr_begin.tp_col = 0; 67133965Sjdp tr.tr_end.tp_col = t->t_winsize.tp_col; 67233965Sjdp 67333965Sjdp if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 67433965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end; 67533965Sjdp } else { 67633965Sjdp teken_pos_t tp; 67733965Sjdp 67833965Sjdp /* Copy lines down. */ 67933965Sjdp tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 68033965Sjdp tp.tp_row = t->t_cursor.tp_row + nrows; 68133965Sjdp tp.tp_col = 0; 68233965Sjdp teken_funcs_copy(t, &tr, &tp); 68333965Sjdp 68433965Sjdp tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 68533965Sjdp } 68633965Sjdp 68733965Sjdp /* Blank current location. */ 68833965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 68933965Sjdp} 69033965Sjdp 69133965Sjdpstatic void 69233965Sjdpteken_subr_keypad_application_mode(teken_t *t) 69333965Sjdp{ 69433965Sjdp 69533965Sjdp teken_funcs_param(t, TP_KEYPADAPP, 1); 69633965Sjdp} 69733965Sjdp 69833965Sjdpstatic void 69933965Sjdpteken_subr_keypad_numeric_mode(teken_t *t) 70033965Sjdp{ 70133965Sjdp 70233965Sjdp teken_funcs_param(t, TP_KEYPADAPP, 0); 70333965Sjdp} 70433965Sjdp 70533965Sjdpstatic void 70633965Sjdpteken_subr_newline(teken_t *t) 70733965Sjdp{ 70833965Sjdp 70933965Sjdp t->t_cursor.tp_row++; 71033965Sjdp 71133965Sjdp if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 71233965Sjdp teken_subr_do_scroll(t, 1); 71333965Sjdp t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 71433965Sjdp } 71533965Sjdp 71633965Sjdp t->t_stateflags &= ~TS_WRAPPED; 71733965Sjdp teken_funcs_cursor(t); 71833965Sjdp} 71933965Sjdp 72033965Sjdpstatic void 72133965Sjdpteken_subr_newpage(teken_t *t) 72233965Sjdp{ 72333965Sjdp 72433965Sjdp if (t->t_stateflags & TS_CONS25) { 72533965Sjdp teken_rect_t tr; 72633965Sjdp 72733965Sjdp tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0; 72833965Sjdp tr.tr_end = t->t_winsize; 72933965Sjdp teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 73033965Sjdp 73133965Sjdp t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 73233965Sjdp teken_funcs_cursor(t); 73333965Sjdp } else { 73433965Sjdp teken_subr_newline(t); 73533965Sjdp } 73633965Sjdp} 73733965Sjdp 73833965Sjdpstatic void 73933965Sjdpteken_subr_next_line(teken_t *t) 74033965Sjdp{ 74133965Sjdp 74233965Sjdp t->t_cursor.tp_col = 0; 74333965Sjdp teken_subr_newline(t); 74433965Sjdp} 74533965Sjdp 74633965Sjdpstatic void 74733965Sjdpteken_subr_pan_down(teken_t *t, unsigned int nrows) 74833965Sjdp{ 74933965Sjdp 75033965Sjdp teken_subr_do_scroll(t, (int)nrows); 75133965Sjdp} 75233965Sjdp 75333965Sjdpstatic void 75433965Sjdpteken_subr_pan_up(teken_t *t, unsigned int nrows) 75533965Sjdp{ 75633965Sjdp 75733965Sjdp teken_subr_do_scroll(t, -(int)nrows); 75833965Sjdp} 75933965Sjdp 76033965Sjdpstatic void 76133965Sjdpteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 76233965Sjdp{ 76333965Sjdp 76433965Sjdp if (request == 0) { 76533965Sjdp const char response[] = "\x1B[?1;2c"; 76677298Sobrien 76733965Sjdp teken_funcs_respond(t, response, sizeof response - 1); 76833965Sjdp } else { 76933965Sjdp teken_printf("Unknown DA1\n"); 77033965Sjdp } 77133965Sjdp} 77233965Sjdp 77333965Sjdpstatic void 77433965Sjdpteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 77533965Sjdp int width) 77633965Sjdp{ 77733965Sjdp 77833965Sjdp if (t->t_stateflags & TS_INSERT && 77933965Sjdp tp->tp_col < t->t_winsize.tp_col - width) { 78033965Sjdp teken_rect_t ctr; 78133965Sjdp teken_pos_t ctp; 78233965Sjdp 78333965Sjdp /* Insert mode. Move existing characters to the right. */ 78433965Sjdp ctr.tr_begin = *tp; 78533965Sjdp ctr.tr_end.tp_row = tp->tp_row + 1; 78633965Sjdp ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 78733965Sjdp ctp.tp_row = tp->tp_row; 78833965Sjdp ctp.tp_col = tp->tp_col + width; 78933965Sjdp teken_funcs_copy(t, &ctr, &ctp); 79033965Sjdp } 79133965Sjdp 79233965Sjdp if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 79333965Sjdp teken_pos_t tp2; 79433965Sjdp 79533965Sjdp /* 79633965Sjdp * Store a space behind double width characters before 79733965Sjdp * actually printing them. This prevents artifacts when 79833965Sjdp * the consumer doesn't render it using double width 79933965Sjdp * glyphs. 80033965Sjdp */ 80133965Sjdp tp2.tp_row = tp->tp_row; 80233965Sjdp tp2.tp_col = tp->tp_col + 1; 80333965Sjdp teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 80433965Sjdp } 80533965Sjdp 80633965Sjdp teken_funcs_putchar(t, tp, c, &t->t_curattr); 80733965Sjdp} 80833965Sjdp 80933965Sjdpstatic void 81033965Sjdpteken_subr_regular_character(teken_t *t, teken_char_t c) 81133965Sjdp{ 81233965Sjdp int width; 81333965Sjdp 81433965Sjdp if (t->t_stateflags & TS_8BIT) { 81533965Sjdp if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f)) 81633965Sjdp return; 81733965Sjdp c = teken_scs_process(t, c); 81833965Sjdp width = 1; 81933965Sjdp } else { 82033965Sjdp c = teken_scs_process(t, c); 82133965Sjdp width = teken_wcwidth(c); 82233965Sjdp /* XXX: Don't process zero-width characters yet. */ 82333965Sjdp if (width <= 0) 82433965Sjdp return; 82533965Sjdp } 82633965Sjdp 82733965Sjdp if (t->t_stateflags & TS_CONS25) { 82833965Sjdp teken_subr_do_putchar(t, &t->t_cursor, c, width); 82933965Sjdp t->t_cursor.tp_col += width; 83033965Sjdp 83133965Sjdp if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 83233965Sjdp if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 83333965Sjdp /* Perform scrolling. */ 83433965Sjdp teken_subr_do_scroll(t, 1); 83533965Sjdp } else { 83633965Sjdp /* No scrolling needed. */ 83733965Sjdp if (t->t_cursor.tp_row < 83833965Sjdp t->t_winsize.tp_row - 1) 83933965Sjdp t->t_cursor.tp_row++; 84033965Sjdp } 84133965Sjdp t->t_cursor.tp_col = 0; 84233965Sjdp } 84333965Sjdp } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 84433965Sjdp (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 84533965Sjdp (TS_WRAPPED|TS_AUTOWRAP)) { 84633965Sjdp teken_pos_t tp; 84733965Sjdp 84833965Sjdp /* Perform line wrapping. */ 84933965Sjdp 85033965Sjdp if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 85133965Sjdp /* Perform scrolling. */ 85233965Sjdp teken_subr_do_scroll(t, 1); 85333965Sjdp tp.tp_row = t->t_scrollreg.ts_end - 1; 85433965Sjdp } else { 85533965Sjdp /* No scrolling needed. */ 85633965Sjdp tp.tp_row = t->t_cursor.tp_row + 1; 85733965Sjdp if (tp.tp_row == t->t_winsize.tp_row) { 85833965Sjdp /* 859 * Corner case: regular character 860 * outside scrolling region, but at the 861 * bottom of the screen. 862 */ 863 teken_subr_do_putchar(t, &t->t_cursor, 864 c, width); 865 return; 866 } 867 } 868 869 tp.tp_col = 0; 870 teken_subr_do_putchar(t, &tp, c, width); 871 872 t->t_cursor.tp_row = tp.tp_row; 873 t->t_cursor.tp_col = width; 874 t->t_stateflags &= ~TS_WRAPPED; 875 } else { 876 /* No line wrapping needed. */ 877 teken_subr_do_putchar(t, &t->t_cursor, c, width); 878 t->t_cursor.tp_col += width; 879 880 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 881 t->t_stateflags |= TS_WRAPPED; 882 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 883 } else { 884 t->t_stateflags &= ~TS_WRAPPED; 885 } 886 } 887 888 teken_funcs_cursor(t); 889} 890 891static void 892teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 893{ 894 895 switch (cmd) { 896 case 1: /* Cursor keys mode. */ 897 teken_funcs_param(t, TP_CURSORKEYS, 0); 898 break; 899 case 2: /* DECANM: ANSI/VT52 mode. */ 900 teken_printf("DECRST VT52\n"); 901 break; 902 case 3: /* 132 column mode. */ 903 teken_funcs_param(t, TP_132COLS, 0); 904 teken_subr_reset_to_initial_state(t); 905 break; 906 case 5: /* Inverse video. */ 907 teken_printf("DECRST inverse video\n"); 908 break; 909 case 6: /* Origin mode. */ 910 t->t_stateflags &= ~TS_ORIGIN; 911 t->t_originreg.ts_begin = 0; 912 t->t_originreg.ts_end = t->t_winsize.tp_row; 913 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 914 t->t_stateflags &= ~TS_WRAPPED; 915 teken_funcs_cursor(t); 916 break; 917 case 7: /* Autowrap mode. */ 918 t->t_stateflags &= ~TS_AUTOWRAP; 919 break; 920 case 8: /* Autorepeat mode. */ 921 teken_funcs_param(t, TP_AUTOREPEAT, 0); 922 break; 923 case 25: /* Hide cursor. */ 924 teken_funcs_param(t, TP_SHOWCURSOR, 0); 925 break; 926 case 40: /* Disallow 132 columns. */ 927 teken_printf("DECRST allow 132\n"); 928 break; 929 case 45: /* Disable reverse wraparound. */ 930 teken_printf("DECRST reverse wraparound\n"); 931 break; 932 case 47: /* Switch to alternate buffer. */ 933 teken_printf("Switch to alternate buffer\n"); 934 break; 935 default: 936 teken_printf("Unknown DECRST: %u\n", cmd); 937 } 938} 939 940static void 941teken_subr_reset_mode(teken_t *t, unsigned int cmd) 942{ 943 944 switch (cmd) { 945 case 4: 946 t->t_stateflags &= ~TS_INSERT; 947 break; 948 default: 949 teken_printf("Unknown reset mode: %u\n", cmd); 950 } 951} 952 953static void 954teken_subr_do_reset(teken_t *t) 955{ 956 957 t->t_curattr = t->t_defattr; 958 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 959 t->t_scrollreg.ts_begin = 0; 960 t->t_scrollreg.ts_end = t->t_winsize.tp_row; 961 t->t_originreg = t->t_scrollreg; 962 t->t_stateflags &= TS_8BIT|TS_CONS25; 963 t->t_stateflags |= TS_AUTOWRAP; 964 965 t->t_scs[0] = teken_scs_us_ascii; 966 t->t_scs[1] = teken_scs_us_ascii; 967 t->t_curscs = 0; 968 969 teken_subr_save_cursor(t); 970 teken_tab_default(t); 971} 972 973static void 974teken_subr_reset_to_initial_state(teken_t *t) 975{ 976 977 teken_subr_do_reset(t); 978 teken_subr_erase_display(t, 2); 979 teken_funcs_param(t, TP_SHOWCURSOR, 1); 980 teken_funcs_cursor(t); 981} 982 983static void 984teken_subr_restore_cursor(teken_t *t) 985{ 986 987 t->t_cursor = t->t_saved_cursor; 988 t->t_curattr = t->t_saved_curattr; 989 t->t_scs[t->t_curscs] = t->t_saved_curscs; 990 t->t_stateflags &= ~TS_WRAPPED; 991 teken_funcs_cursor(t); 992} 993 994static void 995teken_subr_reverse_index(teken_t *t) 996{ 997 998 if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 999 t->t_cursor.tp_row--; 1000 t->t_stateflags &= ~TS_WRAPPED; 1001 teken_funcs_cursor(t); 1002 } else { 1003 teken_subr_do_scroll(t, -1); 1004 } 1005} 1006 1007static void 1008teken_subr_save_cursor(teken_t *t) 1009{ 1010 1011 t->t_saved_cursor = t->t_cursor; 1012 t->t_saved_curattr = t->t_curattr; 1013 t->t_saved_curscs = t->t_scs[t->t_curscs]; 1014} 1015 1016static void 1017teken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1018{ 1019 1020 if (request == 0) { 1021 const char response[] = "\x1B[>0;10;0c"; 1022 teken_funcs_respond(t, response, sizeof response - 1); 1023 } else { 1024 teken_printf("Unknown DA2\n"); 1025 } 1026} 1027 1028static void 1029teken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1030{ 1031 1032 switch (cmd) { 1033 case 1: /* Cursor keys mode. */ 1034 teken_funcs_param(t, TP_CURSORKEYS, 1); 1035 break; 1036 case 2: /* DECANM: ANSI/VT52 mode. */ 1037 teken_printf("DECSET VT52\n"); 1038 break; 1039 case 3: /* 132 column mode. */ 1040 teken_funcs_param(t, TP_132COLS, 1); 1041 teken_subr_reset_to_initial_state(t); 1042 break; 1043 case 5: /* Inverse video. */ 1044 teken_printf("DECSET inverse video\n"); 1045 break; 1046 case 6: /* Origin mode. */ 1047 t->t_stateflags |= TS_ORIGIN; 1048 t->t_originreg = t->t_scrollreg; 1049 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1050 t->t_cursor.tp_col = 0; 1051 t->t_stateflags &= ~TS_WRAPPED; 1052 teken_funcs_cursor(t); 1053 break; 1054 case 7: /* Autowrap mode. */ 1055 t->t_stateflags |= TS_AUTOWRAP; 1056 break; 1057 case 8: /* Autorepeat mode. */ 1058 teken_funcs_param(t, TP_AUTOREPEAT, 1); 1059 break; 1060 case 25: /* Display cursor. */ 1061 teken_funcs_param(t, TP_SHOWCURSOR, 1); 1062 break; 1063 case 40: /* Allow 132 columns. */ 1064 teken_printf("DECSET allow 132\n"); 1065 break; 1066 case 45: /* Enable reverse wraparound. */ 1067 teken_printf("DECSET reverse wraparound\n"); 1068 break; 1069 case 47: /* Switch to alternate buffer. */ 1070 teken_printf("Switch away from alternate buffer\n"); 1071 break; 1072 default: 1073 teken_printf("Unknown DECSET: %u\n", cmd); 1074 } 1075} 1076 1077static void 1078teken_subr_set_mode(teken_t *t, unsigned int cmd) 1079{ 1080 1081 switch (cmd) { 1082 case 4: 1083 teken_printf("Insert mode\n"); 1084 t->t_stateflags |= TS_INSERT; 1085 break; 1086 default: 1087 teken_printf("Unknown set mode: %u\n", cmd); 1088 } 1089} 1090 1091static void 1092teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1093 unsigned int cmds[]) 1094{ 1095 unsigned int i, n; 1096 1097 /* No attributes means reset. */ 1098 if (ncmds == 0) { 1099 t->t_curattr = t->t_defattr; 1100 return; 1101 } 1102 1103 for (i = 0; i < ncmds; i++) { 1104 n = cmds[i]; 1105 1106 switch (n) { 1107 case 0: /* Reset. */ 1108 t->t_curattr = t->t_defattr; 1109 break; 1110 case 1: /* Bold. */ 1111 t->t_curattr.ta_format |= TF_BOLD; 1112 break; 1113 case 4: /* Underline. */ 1114 t->t_curattr.ta_format |= TF_UNDERLINE; 1115 break; 1116 case 5: /* Blink. */ 1117 t->t_curattr.ta_format |= TF_BLINK; 1118 break; 1119 case 7: /* Reverse. */ 1120 t->t_curattr.ta_format |= TF_REVERSE; 1121 break; 1122 case 22: /* Remove bold. */ 1123 t->t_curattr.ta_format &= ~TF_BOLD; 1124 break; 1125 case 24: /* Remove underline. */ 1126 t->t_curattr.ta_format &= ~TF_UNDERLINE; 1127 break; 1128 case 25: /* Remove blink. */ 1129 t->t_curattr.ta_format &= ~TF_BLINK; 1130 break; 1131 case 27: /* Remove reverse. */ 1132 t->t_curattr.ta_format &= ~TF_REVERSE; 1133 break; 1134 case 30: /* Set foreground color: black */ 1135 case 31: /* Set foreground color: red */ 1136 case 32: /* Set foreground color: green */ 1137 case 33: /* Set foreground color: brown */ 1138 case 34: /* Set foreground color: blue */ 1139 case 35: /* Set foreground color: magenta */ 1140 case 36: /* Set foreground color: cyan */ 1141 case 37: /* Set foreground color: white */ 1142 t->t_curattr.ta_fgcolor = n - 30; 1143 break; 1144 case 39: /* Set default foreground color. */ 1145 t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1146 break; 1147 case 40: /* Set background color: black */ 1148 case 41: /* Set background color: red */ 1149 case 42: /* Set background color: green */ 1150 case 43: /* Set background color: brown */ 1151 case 44: /* Set background color: blue */ 1152 case 45: /* Set background color: magenta */ 1153 case 46: /* Set background color: cyan */ 1154 case 47: /* Set background color: white */ 1155 t->t_curattr.ta_bgcolor = n - 40; 1156 break; 1157 case 49: /* Set default background color. */ 1158 t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1159 break; 1160 default: 1161 teken_printf("unsupported attribute %u\n", n); 1162 } 1163 } 1164} 1165 1166static void 1167teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1168 unsigned int bottom) 1169{ 1170 1171 /* Adjust top row number. */ 1172 if (top > 0) 1173 top--; 1174 /* Adjust bottom row number. */ 1175 if (bottom == 0 || bottom > t->t_winsize.tp_row) 1176 bottom = t->t_winsize.tp_row; 1177 1178 /* Invalid arguments. */ 1179 if (top >= bottom - 1) { 1180 top = 0; 1181 bottom = t->t_winsize.tp_row; 1182 } 1183 1184 t->t_scrollreg.ts_begin = top; 1185 t->t_scrollreg.ts_end = bottom; 1186 if (t->t_stateflags & TS_ORIGIN) { 1187 /* XXX: home cursor? */ 1188 t->t_originreg = t->t_scrollreg; 1189 t->t_cursor.tp_row = t->t_originreg.ts_begin; 1190 t->t_cursor.tp_col = 0; 1191 t->t_stateflags &= ~TS_WRAPPED; 1192 teken_funcs_cursor(t); 1193 } 1194} 1195 1196static void 1197teken_subr_single_height_double_width_line(teken_t *t __unused) 1198{ 1199 1200 teken_printf("single height double width???\n"); 1201} 1202 1203static void 1204teken_subr_single_height_single_width_line(teken_t *t __unused) 1205{ 1206 1207 teken_printf("single height single width???\n"); 1208} 1209 1210static void 1211teken_subr_string_terminator(teken_t *t __unused) 1212{ 1213 1214 teken_printf("string terminator???\n"); 1215} 1216 1217static void 1218teken_subr_tab_clear(teken_t *t, unsigned int cmd) 1219{ 1220 1221 switch (cmd) { 1222 case 0: 1223 teken_tab_clear(t, t->t_cursor.tp_col); 1224 break; 1225 case 3: 1226 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1227 break; 1228 } 1229} 1230 1231static void 1232teken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1233{ 1234 1235 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1236 if (row >= t->t_originreg.ts_end) 1237 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1238 1239 1240 t->t_stateflags &= ~TS_WRAPPED; 1241 teken_funcs_cursor(t); 1242} 1243