teken_subr.h revision 197117
190926Snectar/*- 255682Smarkm * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org> 390926Snectar * All rights reserved. 478527Sassar * 555682Smarkm * Redistribution and use in source and binary forms, with or without 655682Smarkm * modification, are permitted provided that the following conditions 755682Smarkm * are met: 855682Smarkm * 1. Redistributions of source code must retain the above copyright 955682Smarkm * notice, this list of conditions and the following disclaimer. 1055682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer in the 1255682Smarkm * documentation and/or other materials provided with the distribution. 1355682Smarkm * 1490926Snectar * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1590926Snectar * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1690926Snectar * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1790926Snectar * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1890926Snectar * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1990926Snectar * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2090926Snectar * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2190926Snectar * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2290926Snectar * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2390926Snectar * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2455682Smarkm * SUCH DAMAGE. 2555682Smarkm * 2655682Smarkm * $FreeBSD: head/sys/teken/teken_subr.h 197117 2009-09-12 12:44:21Z ed $ 2755682Smarkm */ 2855682Smarkm 2955682Smarkmstatic void teken_subr_cursor_up(teken_t *, unsigned int); 3055682Smarkmstatic void teken_subr_erase_line(teken_t *, unsigned int); 3155682Smarkmstatic void teken_subr_regular_character(teken_t *, teken_char_t); 3255682Smarkmstatic void teken_subr_reset_to_initial_state(teken_t *); 3355682Smarkmstatic void teken_subr_save_cursor(teken_t *); 3455682Smarkm 3555682Smarkmstatic inline int 3655682Smarkmteken_tab_isset(teken_t *t, unsigned int col) 3755682Smarkm{ 3855682Smarkm unsigned int b, o; 3955682Smarkm 4055682Smarkm if (col >= T_NUMCOL) 4155682Smarkm return ((col % 8) == 0); 4255682Smarkm 4355682Smarkm b = col / (sizeof(unsigned int) * 8); 4455682Smarkm o = col % (sizeof(unsigned int) * 8); 4555682Smarkm 4655682Smarkm return (t->t_tabstops[b] & (1 << o)); 4755682Smarkm} 4855682Smarkm 4955682Smarkmstatic inline void 5055682Smarkmteken_tab_clear(teken_t *t, unsigned int col) 5155682Smarkm{ 5255682Smarkm unsigned int b, o; 5355682Smarkm 5455682Smarkm if (col >= T_NUMCOL) 5572445Sassar return; 5655682Smarkm 5755682Smarkm b = col / (sizeof(unsigned int) * 8); 5890926Snectar o = col % (sizeof(unsigned int) * 8); 5955682Smarkm 6055682Smarkm t->t_tabstops[b] &= ~(1 << o); 6155682Smarkm} 6255682Smarkm 6355682Smarkmstatic inline void 6455682Smarkmteken_tab_set(teken_t *t, unsigned int col) 6555682Smarkm{ 6655682Smarkm unsigned int b, o; 6755682Smarkm 6855682Smarkm if (col >= T_NUMCOL) 6972445Sassar return; 7072445Sassar 7155682Smarkm b = col / (sizeof(unsigned int) * 8); 7255682Smarkm o = col % (sizeof(unsigned int) * 8); 7355682Smarkm 7455682Smarkm t->t_tabstops[b] |= 1 << o; 7555682Smarkm} 7690926Snectar 7772445Sassarstatic void 7855682Smarkmteken_tab_default(teken_t *t) 7972445Sassar{ 8090926Snectar unsigned int i; 8172445Sassar 8272445Sassar memset(&t->t_tabstops, 0, T_NUMCOL / 8); 8372445Sassar 8455682Smarkm for (i = 8; i < T_NUMCOL; i += 8) 8555682Smarkm teken_tab_set(t, i); 8655682Smarkm} 8772445Sassar 8855682Smarkmstatic void 8990926Snectarteken_subr_do_scroll(teken_t *t, int amount) 9090926Snectar{ 9155682Smarkm teken_rect_t tr; 9255682Smarkm teken_pos_t tp; 9355682Smarkm 9455682Smarkm teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row); 9555682Smarkm teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row); 9690926Snectar teken_assert(amount != 0); 9790926Snectar 9890926Snectar /* Copy existing data 1 line up. */ 9990926Snectar if (amount > 0) { 10072445Sassar /* Scroll down. */ 10190926Snectar 10272445Sassar /* Copy existing data up. */ 10390926Snectar if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 10455682Smarkm tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount; 10555682Smarkm tr.tr_begin.tp_col = 0; 10655682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_end; 10755682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 10855682Smarkm tp.tp_row = t->t_scrollreg.ts_begin; 10955682Smarkm tp.tp_col = 0; 11055682Smarkm teken_funcs_copy(t, &tr, &tp); 11155682Smarkm 11255682Smarkm tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount; 11372445Sassar } else { 11455682Smarkm tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 11555682Smarkm } 11655682Smarkm 11755682Smarkm /* Clear the last lines. */ 11855682Smarkm tr.tr_begin.tp_col = 0; 11955682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_end; 12055682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 12155682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 12290926Snectar } else { 12390926Snectar /* Scroll up. */ 12490926Snectar amount = -amount; 12590926Snectar 12655682Smarkm /* Copy existing data down. */ 12790926Snectar if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) { 12890926Snectar tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 12972445Sassar tr.tr_begin.tp_col = 0; 13072445Sassar tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount; 13172445Sassar tr.tr_end.tp_col = t->t_winsize.tp_col; 13255682Smarkm tp.tp_row = t->t_scrollreg.ts_begin + amount; 13390926Snectar tp.tp_col = 0; 13472445Sassar teken_funcs_copy(t, &tr, &tp); 13555682Smarkm 13655682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount; 13790926Snectar } else { 13855682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_end; 13990926Snectar } 14055682Smarkm 14172445Sassar /* Clear the first lines. */ 14272445Sassar tr.tr_begin.tp_row = t->t_scrollreg.ts_begin; 14355682Smarkm tr.tr_begin.tp_col = 0; 14455682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 14555682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 14655682Smarkm } 14755682Smarkm} 14855682Smarkm 14955682Smarkmstatic ssize_t 15055682Smarkmteken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16]) 15155682Smarkm{ 15255682Smarkm 15355682Smarkm switch (cmd) { 15455682Smarkm case 5: /* Operating status. */ 15555682Smarkm strcpy(response, "0n"); 15655682Smarkm return (2); 15755682Smarkm case 6: { /* Cursor position. */ 15855682Smarkm int len; 15955682Smarkm 16090926Snectar len = snprintf(response, 16, "%u;%uR", 16172445Sassar (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1, 16255682Smarkm t->t_cursor.tp_col + 1); 16355682Smarkm 16455682Smarkm if (len >= 16) 16555682Smarkm return (-1); 16655682Smarkm return (len); 16755682Smarkm } 16855682Smarkm case 15: /* Printer status. */ 16972445Sassar strcpy(response, "13n"); 17072445Sassar return (3); 17155682Smarkm case 25: /* UDK status. */ 17255682Smarkm strcpy(response, "20n"); 17355682Smarkm return (3); 17455682Smarkm case 26: /* Keyboard status. */ 17555682Smarkm strcpy(response, "27;1n"); 17655682Smarkm return (5); 17755682Smarkm default: 17855682Smarkm teken_printf("Unknown DSR\n"); 17972445Sassar return (-1); 18072445Sassar } 18172445Sassar} 18255682Smarkm 18390926Snectarstatic void 18455682Smarkmteken_subr_alignment_test(teken_t *t) 18555682Smarkm{ 18655682Smarkm teken_rect_t tr; 18755682Smarkm 18855682Smarkm t->t_scrollreg.ts_begin = 0; 18990926Snectar t->t_scrollreg.ts_end = t->t_winsize.tp_row; 19055682Smarkm 19190926Snectar t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 19272445Sassar t->t_stateflags &= ~TS_WRAPPED; 19355682Smarkm teken_funcs_cursor(t); 19490926Snectar 19578527Sassar tr.tr_begin.tp_row = 0; 19690926Snectar tr.tr_begin.tp_col = 0; 19790926Snectar tr.tr_end = t->t_winsize; 19855682Smarkm teken_funcs_fill(t, &tr, 'E', &t->t_defattr); 19955682Smarkm} 20055682Smarkm 20155682Smarkmstatic void 20255682Smarkmteken_subr_backspace(teken_t *t) 20355682Smarkm{ 20455682Smarkm 20555682Smarkm if (t->t_stateflags & TS_CONS25) { 20672445Sassar if (t->t_cursor.tp_col == 0) { 20755682Smarkm if (t->t_cursor.tp_row == t->t_originreg.ts_begin) 20872445Sassar return; 20972445Sassar t->t_cursor.tp_row--; 21055682Smarkm t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 21155682Smarkm } else { 21255682Smarkm t->t_cursor.tp_col--; 21355682Smarkm } 21455682Smarkm } else { 21590926Snectar if (t->t_cursor.tp_col == 0) 21690926Snectar return; 21790926Snectar 21872445Sassar t->t_cursor.tp_col--; 21972445Sassar t->t_stateflags &= ~TS_WRAPPED; 22072445Sassar } 22172445Sassar 22272445Sassar teken_funcs_cursor(t); 22372445Sassar} 22472445Sassar 22572445Sassarstatic void 22690926Snectarteken_subr_bell(teken_t *t) 22755682Smarkm{ 22855682Smarkm 22972445Sassar teken_funcs_bell(t); 23072445Sassar} 23172445Sassar 23272445Sassarstatic void 23372445Sassarteken_subr_carriage_return(teken_t *t) 23472445Sassar{ 23572445Sassar 23672445Sassar t->t_cursor.tp_col = 0; 23772445Sassar t->t_stateflags &= ~TS_WRAPPED; 23855682Smarkm teken_funcs_cursor(t); 23955682Smarkm} 24072445Sassar 24172445Sassarstatic void 24272445Sassarteken_subr_cursor_backward(teken_t *t, unsigned int ncols) 24372445Sassar{ 24472445Sassar 24572445Sassar if (ncols > t->t_cursor.tp_col) 24672445Sassar t->t_cursor.tp_col = 0; 24772445Sassar else 24872445Sassar t->t_cursor.tp_col -= ncols; 24955682Smarkm t->t_stateflags &= ~TS_WRAPPED; 25055682Smarkm teken_funcs_cursor(t); 25172445Sassar} 25272445Sassar 25372445Sassarstatic void 25472445Sassarteken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs) 25572445Sassar{ 25672445Sassar 25772445Sassar do { 25872445Sassar /* Stop when we've reached the beginning of the line. */ 25955682Smarkm if (t->t_cursor.tp_col == 0) 26072445Sassar break; 26172445Sassar 26272445Sassar t->t_cursor.tp_col--; 26355682Smarkm 26490926Snectar /* Tab marker set. */ 26590926Snectar if (teken_tab_isset(t, t->t_cursor.tp_col)) 26690926Snectar ntabs--; 26790926Snectar } while (ntabs > 0); 26890926Snectar 26990926Snectar teken_funcs_cursor(t); 27055682Smarkm} 27190926Snectar 27290926Snectarstatic void 27390926Snectarteken_subr_cursor_down(teken_t *t, unsigned int nrows) 27490926Snectar{ 27590926Snectar 27690926Snectar if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) 27790926Snectar t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 27890926Snectar else 27990926Snectar t->t_cursor.tp_row += nrows; 28090926Snectar t->t_stateflags &= ~TS_WRAPPED; 28190926Snectar teken_funcs_cursor(t); 28290926Snectar} 28390926Snectar 28490926Snectarstatic void 28590926Snectarteken_subr_cursor_forward(teken_t *t, unsigned int ncols) 28690926Snectar{ 28790926Snectar 28890926Snectar if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 28990926Snectar t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 29090926Snectar else 29190926Snectar t->t_cursor.tp_col += ncols; 29290926Snectar t->t_stateflags &= ~TS_WRAPPED; 29390926Snectar teken_funcs_cursor(t); 29490926Snectar} 29590926Snectar 29690926Snectarstatic void 29790926Snectarteken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs) 29890926Snectar{ 29990926Snectar 30090926Snectar do { 30190926Snectar /* Stop when we've reached the end of the line. */ 30290926Snectar if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1) 30390926Snectar break; 30490926Snectar 30590926Snectar t->t_cursor.tp_col++; 30690926Snectar 30790926Snectar /* Tab marker set. */ 30890926Snectar if (teken_tab_isset(t, t->t_cursor.tp_col)) 30955682Smarkm ntabs--; 31090926Snectar } while (ntabs > 0); 31190926Snectar 31255682Smarkm teken_funcs_cursor(t); 31355682Smarkm} 31490926Snectar 31590926Snectarstatic void 31690926Snectarteken_subr_cursor_next_line(teken_t *t, unsigned int ncols) 31790926Snectar{ 31890926Snectar 31990926Snectar t->t_cursor.tp_col = 0; 32090926Snectar teken_subr_cursor_down(t, ncols); 32190926Snectar} 32272445Sassar 32390926Snectarstatic void 32490926Snectarteken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col) 32590926Snectar{ 32690926Snectar 32755682Smarkm t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 32890926Snectar if (row >= t->t_originreg.ts_end) 32990926Snectar t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 33055682Smarkm 33190926Snectar t->t_cursor.tp_col = col - 1; 33255682Smarkm if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 33355682Smarkm t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 33478527Sassar 33555682Smarkm t->t_stateflags &= ~TS_WRAPPED; 33690926Snectar teken_funcs_cursor(t); 33790926Snectar} 33855682Smarkm 33990926Snectarstatic void 34090926Snectarteken_subr_cursor_position_report(teken_t *t, unsigned int cmd) 34155682Smarkm{ 34290926Snectar char response[18] = "\x1B["; 34390926Snectar ssize_t len; 34490926Snectar 34590926Snectar len = teken_subr_do_cpr(t, cmd, response + 2); 34690926Snectar if (len < 0) 34790926Snectar return; 34890926Snectar 34990926Snectar teken_funcs_respond(t, response, len + 2); 35090926Snectar} 35155682Smarkm 35255682Smarkmstatic void 35355682Smarkmteken_subr_cursor_previous_line(teken_t *t, unsigned int ncols) 35455682Smarkm{ 35590926Snectar 35690926Snectar t->t_cursor.tp_col = 0; 35790926Snectar teken_subr_cursor_up(t, ncols); 35890926Snectar} 35990926Snectar 36090926Snectarstatic void 36190926Snectarteken_subr_cursor_up(teken_t *t, unsigned int nrows) 36255682Smarkm{ 36355682Smarkm 36455682Smarkm if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row) 36555682Smarkm t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 36655682Smarkm else 36772445Sassar t->t_cursor.tp_row -= nrows; 36890926Snectar t->t_stateflags &= ~TS_WRAPPED; 36972445Sassar teken_funcs_cursor(t); 37072445Sassar} 37155682Smarkm 37255682Smarkmstatic void 37390926Snectarteken_subr_delete_character(teken_t *t, unsigned int ncols) 37490926Snectar{ 37555682Smarkm teken_rect_t tr; 37655682Smarkm 37755682Smarkm tr.tr_begin.tp_row = t->t_cursor.tp_row; 37855682Smarkm tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 37990926Snectar tr.tr_end.tp_col = t->t_winsize.tp_col; 38090926Snectar 38190926Snectar if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 38290926Snectar tr.tr_begin.tp_col = t->t_cursor.tp_col; 38390926Snectar } else { 38490926Snectar /* Copy characters to the left. */ 38590926Snectar tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols; 38655682Smarkm teken_funcs_copy(t, &tr, &t->t_cursor); 38755682Smarkm 38855682Smarkm tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols; 38955682Smarkm } 39055682Smarkm 39172445Sassar /* Blank trailing columns. */ 39290926Snectar teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 39372445Sassar} 39472445Sassar 39555682Smarkmstatic void 39655682Smarkmteken_subr_delete_line(teken_t *t, unsigned int nrows) 39790926Snectar{ 39890926Snectar teken_rect_t tr; 39955682Smarkm 40055682Smarkm tr.tr_begin.tp_col = 0; 40155682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_end; 40255682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 40390926Snectar 40490926Snectar if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 40590926Snectar tr.tr_begin.tp_row = t->t_cursor.tp_row; 40690926Snectar } else { 40790926Snectar teken_pos_t tp; 40890926Snectar 40990926Snectar /* Copy rows up. */ 41055682Smarkm tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows; 41155682Smarkm tp.tp_row = t->t_cursor.tp_row; 41255682Smarkm tp.tp_col = 0; 41355682Smarkm teken_funcs_copy(t, &tr, &tp); 41455682Smarkm 41572445Sassar tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows; 41690926Snectar } 41772445Sassar 41872445Sassar /* Blank trailing rows. */ 41955682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 42055682Smarkm} 42190926Snectar 42290926Snectarstatic void 42390926Snectarteken_subr_device_control_string(teken_t *t __unused) 42455682Smarkm{ 42555682Smarkm 42690926Snectar teken_printf("device control string???\n"); 42755682Smarkm} 42855682Smarkm 42990926Snectarstatic void 43055682Smarkmteken_subr_device_status_report(teken_t *t, unsigned int cmd) 43155682Smarkm{ 43290926Snectar char response[19] = "\x1B[?"; 43355682Smarkm ssize_t len; 43455682Smarkm 43590926Snectar len = teken_subr_do_cpr(t, cmd, response + 3); 43672445Sassar if (len < 0) 43772445Sassar return; 43890926Snectar 43990926Snectar teken_funcs_respond(t, response, len + 3); 44090926Snectar} 44190926Snectar 44290926Snectarstatic void 44390926Snectarteken_subr_double_height_double_width_line_top(teken_t *t __unused) 44490926Snectar{ 44572445Sassar 44690926Snectar teken_printf("double height double width top\n"); 44790926Snectar} 44872445Sassar 44972445Sassarstatic void 45090926Snectarteken_subr_double_height_double_width_line_bottom(teken_t *t __unused) 45172445Sassar{ 45290926Snectar 45390926Snectar teken_printf("double height double width bottom\n"); 45472445Sassar} 45590926Snectar 45690926Snectarstatic void 45790926Snectarteken_subr_erase_character(teken_t *t, unsigned int ncols) 45855682Smarkm{ 45990926Snectar teken_rect_t tr; 46090926Snectar 46190926Snectar tr.tr_begin = t->t_cursor; 46255682Smarkm tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 46355682Smarkm 46455682Smarkm if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) 46555682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 46655682Smarkm else 46755682Smarkm tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 46855682Smarkm 46955682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 47055682Smarkm} 47172445Sassar 47255682Smarkmstatic void 47355682Smarkmteken_subr_erase_display(teken_t *t, unsigned int mode) 47455682Smarkm{ 47555682Smarkm teken_rect_t r; 47655682Smarkm 47790926Snectar r.tr_begin.tp_col = 0; 47890926Snectar r.tr_end.tp_col = t->t_winsize.tp_col; 47990926Snectar 48090926Snectar switch (mode) { 48155682Smarkm case 1: /* Erase from the top to the cursor. */ 48255682Smarkm teken_subr_erase_line(t, 1); 48355682Smarkm 48455682Smarkm /* Erase lines above. */ 48555682Smarkm if (t->t_cursor.tp_row == 0) 48655682Smarkm return; 48755682Smarkm r.tr_begin.tp_row = 0; 48872445Sassar r.tr_end.tp_row = t->t_cursor.tp_row; 48955682Smarkm break; 49055682Smarkm case 2: /* Erase entire display. */ 49155682Smarkm r.tr_begin.tp_row = 0; 49255682Smarkm r.tr_end.tp_row = t->t_winsize.tp_row; 49355682Smarkm break; 49455682Smarkm default: /* Erase from cursor to the bottom. */ 49555682Smarkm teken_subr_erase_line(t, 0); 49672445Sassar 49772445Sassar /* Erase lines below. */ 49872445Sassar if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1) 49972445Sassar return; 50072445Sassar r.tr_begin.tp_row = t->t_cursor.tp_row + 1; 50172445Sassar r.tr_end.tp_row = t->t_winsize.tp_row; 50255682Smarkm break; 50372445Sassar } 50455682Smarkm 50572445Sassar teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 50672445Sassar} 50755682Smarkm 50855682Smarkmstatic void 50972445Sassarteken_subr_erase_line(teken_t *t, unsigned int mode) 51072445Sassar{ 51172445Sassar teken_rect_t r; 51272445Sassar 51372445Sassar r.tr_begin.tp_row = t->t_cursor.tp_row; 51455682Smarkm r.tr_end.tp_row = t->t_cursor.tp_row + 1; 51555682Smarkm 51672445Sassar switch (mode) { 51755682Smarkm case 1: /* Erase from the beginning of the line to the cursor. */ 51878527Sassar r.tr_begin.tp_col = 0; 51978527Sassar r.tr_end.tp_col = t->t_cursor.tp_col + 1; 52078527Sassar break; 52190926Snectar case 2: /* Erase entire line. */ 52278527Sassar r.tr_begin.tp_col = 0; 52355682Smarkm r.tr_end.tp_col = t->t_winsize.tp_col; 52490926Snectar break; 52555682Smarkm default: /* Erase from cursor to the end of the line. */ 52690926Snectar r.tr_begin.tp_col = t->t_cursor.tp_col; 52755682Smarkm r.tr_end.tp_col = t->t_winsize.tp_col; 52890926Snectar break; 52990926Snectar } 53055682Smarkm 53155682Smarkm teken_funcs_fill(t, &r, BLANK, &t->t_curattr); 53255682Smarkm} 53390926Snectar 53490926Snectarstatic void 53590926Snectarteken_subr_g0_scs_special_graphics(teken_t *t __unused) 53690926Snectar{ 53790926Snectar 53855682Smarkm teken_scs_set(t, 0, teken_scs_special_graphics); 53972445Sassar} 54072445Sassar 54155682Smarkmstatic void 54255682Smarkmteken_subr_g0_scs_uk_national(teken_t *t __unused) 54372445Sassar{ 54472445Sassar 54555682Smarkm teken_scs_set(t, 0, teken_scs_uk_national); 54655682Smarkm} 54790926Snectar 54890926Snectarstatic void 54990926Snectarteken_subr_g0_scs_us_ascii(teken_t *t __unused) 55055682Smarkm{ 55155682Smarkm 55255682Smarkm teken_scs_set(t, 0, teken_scs_us_ascii); 55390926Snectar} 55490926Snectar 55590926Snectarstatic void 55690926Snectarteken_subr_g1_scs_special_graphics(teken_t *t __unused) 55790926Snectar{ 55890926Snectar 55955682Smarkm teken_scs_set(t, 1, teken_scs_special_graphics); 56055682Smarkm} 56190926Snectar 56255682Smarkmstatic void 56355682Smarkmteken_subr_g1_scs_uk_national(teken_t *t __unused) 56455682Smarkm{ 56590926Snectar 56690926Snectar teken_scs_set(t, 1, teken_scs_uk_national); 56755682Smarkm} 56890926Snectar 56990926Snectarstatic void 57090926Snectarteken_subr_g1_scs_us_ascii(teken_t *t __unused) 57155682Smarkm{ 57255682Smarkm 57355682Smarkm teken_scs_set(t, 1, teken_scs_us_ascii); 57455682Smarkm} 57555682Smarkm 57690926Snectarstatic void 57755682Smarkmteken_subr_horizontal_position_absolute(teken_t *t, unsigned int col) 57855682Smarkm{ 57990926Snectar 58090926Snectar t->t_cursor.tp_col = col - 1; 58190926Snectar if (t->t_cursor.tp_col >= t->t_winsize.tp_col) 58255682Smarkm t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 58390926Snectar 58490926Snectar t->t_stateflags &= ~TS_WRAPPED; 58555682Smarkm teken_funcs_cursor(t); 58690926Snectar} 58755682Smarkm 58890926Snectarstatic void 58990926Snectarteken_subr_horizontal_tab(teken_t *t) 59055682Smarkm{ 59190926Snectar 59255682Smarkm if (t->t_stateflags & TS_CONS25) { 59390926Snectar teken_subr_cursor_forward_tabulation(t, 1); 59455682Smarkm } else { 59590926Snectar teken_rect_t tr; 59655682Smarkm 59790926Snectar tr.tr_begin = t->t_cursor; 59890926Snectar teken_subr_cursor_forward_tabulation(t, 1); 59990926Snectar tr.tr_end.tp_row = tr.tr_begin.tp_row + 1; 60090926Snectar tr.tr_end.tp_col = t->t_cursor.tp_col; 60190926Snectar 60290926Snectar /* Blank region that we skipped. */ 60390926Snectar if (tr.tr_end.tp_col > tr.tr_begin.tp_col) 60490926Snectar teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 60590926Snectar } 60690926Snectar} 60790926Snectar 60890926Snectarstatic void 60990926Snectarteken_subr_horizontal_tab_set(teken_t *t) 61090926Snectar{ 61190926Snectar 61255682Smarkm teken_tab_set(t, t->t_cursor.tp_col); 61355682Smarkm} 61490926Snectar 61555682Smarkmstatic void 61690926Snectarteken_subr_index(teken_t *t) 61755682Smarkm{ 61890926Snectar 61990926Snectar if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) { 62090926Snectar t->t_cursor.tp_row++; 62190926Snectar t->t_stateflags &= ~TS_WRAPPED; 62290926Snectar teken_funcs_cursor(t); 62390926Snectar } else { 62490926Snectar teken_subr_do_scroll(t, 1); 62590926Snectar } 62690926Snectar} 62790926Snectar 62890926Snectarstatic void 62990926Snectarteken_subr_insert_character(teken_t *t, unsigned int ncols) 63090926Snectar{ 63190926Snectar teken_rect_t tr; 63290926Snectar 63390926Snectar tr.tr_begin = t->t_cursor; 63490926Snectar tr.tr_end.tp_row = t->t_cursor.tp_row + 1; 63590926Snectar 63690926Snectar if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) { 63790926Snectar tr.tr_end.tp_col = t->t_winsize.tp_col; 63890926Snectar } else { 63990926Snectar teken_pos_t tp; 64090926Snectar 64190926Snectar /* Copy characters to the right. */ 64290926Snectar tr.tr_end.tp_col = t->t_winsize.tp_col - ncols; 64355682Smarkm tp.tp_row = t->t_cursor.tp_row; 64455682Smarkm tp.tp_col = t->t_cursor.tp_col + ncols; 64555682Smarkm teken_funcs_copy(t, &tr, &tp); 64655682Smarkm 64755682Smarkm tr.tr_end.tp_col = t->t_cursor.tp_col + ncols; 64872445Sassar } 64972445Sassar 65072445Sassar /* Blank current location. */ 65172445Sassar teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 65255682Smarkm} 65355682Smarkm 65455682Smarkmstatic void 65555682Smarkmteken_subr_insert_line(teken_t *t, unsigned int nrows) 65655682Smarkm{ 65755682Smarkm teken_rect_t tr; 65855682Smarkm 65955682Smarkm tr.tr_begin.tp_row = t->t_cursor.tp_row; 66055682Smarkm tr.tr_begin.tp_col = 0; 66155682Smarkm tr.tr_end.tp_col = t->t_winsize.tp_col; 66255682Smarkm 66372445Sassar if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) { 66472445Sassar tr.tr_end.tp_row = t->t_scrollreg.ts_end; 66555682Smarkm } else { 66655682Smarkm teken_pos_t tp; 66755682Smarkm 66855682Smarkm /* Copy lines down. */ 66955682Smarkm tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows; 67055682Smarkm tp.tp_row = t->t_cursor.tp_row + nrows; 67155682Smarkm tp.tp_col = 0; 67255682Smarkm teken_funcs_copy(t, &tr, &tp); 67355682Smarkm 67455682Smarkm tr.tr_end.tp_row = t->t_cursor.tp_row + nrows; 67555682Smarkm } 67655682Smarkm 67755682Smarkm /* Blank current location. */ 67855682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 67955682Smarkm} 68055682Smarkm 68155682Smarkmstatic void 68255682Smarkmteken_subr_keypad_application_mode(teken_t *t) 68355682Smarkm{ 68455682Smarkm 68555682Smarkm teken_funcs_param(t, TP_KEYPADAPP, 1); 68655682Smarkm} 68755682Smarkm 68855682Smarkmstatic void 68955682Smarkmteken_subr_keypad_numeric_mode(teken_t *t) 69055682Smarkm{ 69155682Smarkm 69255682Smarkm teken_funcs_param(t, TP_KEYPADAPP, 0); 69355682Smarkm} 69455682Smarkm 69555682Smarkmstatic void 69655682Smarkmteken_subr_newline(teken_t *t) 69755682Smarkm{ 69855682Smarkm 69955682Smarkm t->t_cursor.tp_row++; 70055682Smarkm 70155682Smarkm if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) { 70255682Smarkm teken_subr_do_scroll(t, 1); 70355682Smarkm t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1; 70455682Smarkm } 70555682Smarkm 70655682Smarkm t->t_stateflags &= ~TS_WRAPPED; 70755682Smarkm teken_funcs_cursor(t); 70855682Smarkm} 70955682Smarkm 71055682Smarkmstatic void 71155682Smarkmteken_subr_newpage(teken_t *t) 71255682Smarkm{ 71355682Smarkm 71455682Smarkm if (t->t_stateflags & TS_CONS25) { 71555682Smarkm teken_rect_t tr; 71655682Smarkm 71755682Smarkm tr.tr_begin.tp_row = tr.tr_begin.tp_col = 0; 71855682Smarkm tr.tr_end = t->t_winsize; 71955682Smarkm teken_funcs_fill(t, &tr, BLANK, &t->t_curattr); 72055682Smarkm 72155682Smarkm t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 72255682Smarkm teken_funcs_cursor(t); 72355682Smarkm } else { 72455682Smarkm teken_subr_newline(t); 72555682Smarkm } 72655682Smarkm} 72755682Smarkm 72855682Smarkmstatic void 72955682Smarkmteken_subr_next_line(teken_t *t) 73055682Smarkm{ 73155682Smarkm 73255682Smarkm t->t_cursor.tp_col = 0; 73372445Sassar teken_subr_newline(t); 73472445Sassar} 73555682Smarkm 73655682Smarkmstatic void 73755682Smarkmteken_subr_pan_down(teken_t *t, unsigned int nrows) 73855682Smarkm{ 73955682Smarkm 74055682Smarkm teken_subr_do_scroll(t, (int)nrows); 74155682Smarkm} 74255682Smarkm 74355682Smarkmstatic void 74455682Smarkmteken_subr_pan_up(teken_t *t, unsigned int nrows) 74555682Smarkm{ 74655682Smarkm 74755682Smarkm teken_subr_do_scroll(t, -(int)nrows); 74855682Smarkm} 74955682Smarkm 75055682Smarkmstatic void 75155682Smarkmteken_subr_primary_device_attributes(teken_t *t, unsigned int request) 75255682Smarkm{ 75355682Smarkm 75455682Smarkm if (request == 0) { 75555682Smarkm const char response[] = "\x1B[?1;2c"; 75655682Smarkm 75755682Smarkm teken_funcs_respond(t, response, sizeof response - 1); 75855682Smarkm } else { 75955682Smarkm teken_printf("Unknown DA1\n"); 76055682Smarkm } 76155682Smarkm} 76255682Smarkm 76355682Smarkmstatic void 76455682Smarkmteken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c, 76555682Smarkm int width) 76655682Smarkm{ 76755682Smarkm 76855682Smarkm if (t->t_stateflags & TS_INSERT && 76955682Smarkm tp->tp_col < t->t_winsize.tp_col - width) { 77055682Smarkm teken_rect_t ctr; 77155682Smarkm teken_pos_t ctp; 77255682Smarkm 773 /* Insert mode. Move existing characters to the right. */ 774 ctr.tr_begin = *tp; 775 ctr.tr_end.tp_row = tp->tp_row + 1; 776 ctr.tr_end.tp_col = t->t_winsize.tp_col - width; 777 ctp.tp_row = tp->tp_row; 778 ctp.tp_col = tp->tp_col + width; 779 teken_funcs_copy(t, &ctr, &ctp); 780 } 781 782 if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) { 783 teken_pos_t tp2; 784 785 /* 786 * Store a space behind double width characters before 787 * actually printing them. This prevents artifacts when 788 * the consumer doesn't render it using double width 789 * glyphs. 790 */ 791 tp2.tp_row = tp->tp_row; 792 tp2.tp_col = tp->tp_col + 1; 793 teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr); 794 } 795 796 teken_funcs_putchar(t, tp, c, &t->t_curattr); 797} 798 799static void 800teken_subr_regular_character(teken_t *t, teken_char_t c) 801{ 802 int width; 803 804 if (t->t_stateflags & TS_8BIT) { 805 if (!(t->t_stateflags & TS_CONS25) && c <= 0x1B) 806 return; 807 width = 1; 808 } else { 809 c = teken_scs_process(t, c); 810 width = teken_wcwidth(c); 811 /* XXX: Don't process zero-width characters yet. */ 812 if (width <= 0) 813 return; 814 } 815 816 if (t->t_stateflags & TS_CONS25) { 817 teken_subr_do_putchar(t, &t->t_cursor, c, width); 818 t->t_cursor.tp_col += width; 819 820 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 821 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 822 /* Perform scrolling. */ 823 teken_subr_do_scroll(t, 1); 824 } else { 825 /* No scrolling needed. */ 826 if (t->t_cursor.tp_row < 827 t->t_winsize.tp_row - 1) 828 t->t_cursor.tp_row++; 829 } 830 t->t_cursor.tp_col = 0; 831 } 832 } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 && 833 (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) == 834 (TS_WRAPPED|TS_AUTOWRAP)) { 835 teken_pos_t tp; 836 837 /* Perform line wrapping. */ 838 839 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) { 840 /* Perform scrolling. */ 841 teken_subr_do_scroll(t, 1); 842 tp.tp_row = t->t_scrollreg.ts_end - 1; 843 } else { 844 /* No scrolling needed. */ 845 tp.tp_row = t->t_cursor.tp_row + 1; 846 if (tp.tp_row == t->t_winsize.tp_row) { 847 /* 848 * Corner case: regular character 849 * outside scrolling region, but at the 850 * bottom of the screen. 851 */ 852 teken_subr_do_putchar(t, &t->t_cursor, 853 c, width); 854 return; 855 } 856 } 857 858 tp.tp_col = 0; 859 teken_subr_do_putchar(t, &tp, c, width); 860 861 t->t_cursor.tp_row = tp.tp_row; 862 t->t_cursor.tp_col = width; 863 t->t_stateflags &= ~TS_WRAPPED; 864 } else { 865 /* No line wrapping needed. */ 866 teken_subr_do_putchar(t, &t->t_cursor, c, width); 867 t->t_cursor.tp_col += width; 868 869 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) { 870 t->t_stateflags |= TS_WRAPPED; 871 t->t_cursor.tp_col = t->t_winsize.tp_col - 1; 872 } else { 873 t->t_stateflags &= ~TS_WRAPPED; 874 } 875 } 876 877 teken_funcs_cursor(t); 878} 879 880static void 881teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd) 882{ 883 884 switch (cmd) { 885 case 1: /* Cursor keys mode. */ 886 teken_funcs_param(t, TP_CURSORKEYS, 0); 887 break; 888 case 2: /* DECANM: ANSI/VT52 mode. */ 889 teken_printf("DECRST VT52\n"); 890 break; 891 case 3: /* 132 column mode. */ 892 teken_funcs_param(t, TP_132COLS, 0); 893 teken_subr_reset_to_initial_state(t); 894 break; 895 case 5: /* Inverse video. */ 896 teken_printf("DECRST inverse video\n"); 897 break; 898 case 6: /* Origin mode. */ 899 t->t_stateflags &= ~TS_ORIGIN; 900 t->t_originreg.ts_begin = 0; 901 t->t_originreg.ts_end = t->t_winsize.tp_row; 902 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 903 t->t_stateflags &= ~TS_WRAPPED; 904 teken_funcs_cursor(t); 905 break; 906 case 7: /* Autowrap mode. */ 907 t->t_stateflags &= ~TS_AUTOWRAP; 908 break; 909 case 8: /* Autorepeat mode. */ 910 teken_funcs_param(t, TP_AUTOREPEAT, 0); 911 break; 912 case 25: /* Hide cursor. */ 913 teken_funcs_param(t, TP_SHOWCURSOR, 0); 914 break; 915 case 40: /* Disallow 132 columns. */ 916 teken_printf("DECRST allow 132\n"); 917 break; 918 case 45: /* Disable reverse wraparound. */ 919 teken_printf("DECRST reverse wraparound\n"); 920 break; 921 case 47: /* Switch to alternate buffer. */ 922 teken_printf("Switch to alternate buffer\n"); 923 break; 924 default: 925 teken_printf("Unknown DECRST: %u\n", cmd); 926 } 927} 928 929static void 930teken_subr_reset_mode(teken_t *t, unsigned int cmd) 931{ 932 933 switch (cmd) { 934 case 4: 935 t->t_stateflags &= ~TS_INSERT; 936 break; 937 default: 938 teken_printf("Unknown reset mode: %u\n", cmd); 939 } 940} 941 942static void 943teken_subr_do_reset(teken_t *t) 944{ 945 946 t->t_curattr = t->t_defattr; 947 t->t_cursor.tp_row = t->t_cursor.tp_col = 0; 948 t->t_scrollreg.ts_begin = 0; 949 t->t_scrollreg.ts_end = t->t_winsize.tp_row; 950 t->t_originreg = t->t_scrollreg; 951 t->t_stateflags &= TS_8BIT|TS_CONS25; 952 t->t_stateflags |= TS_AUTOWRAP; 953 954 teken_scs_set(t, 0, teken_scs_us_ascii); 955 teken_scs_set(t, 1, teken_scs_us_ascii); 956 teken_scs_switch(t, 0); 957 958 teken_subr_save_cursor(t); 959 teken_tab_default(t); 960} 961 962static void 963teken_subr_reset_to_initial_state(teken_t *t) 964{ 965 966 teken_subr_do_reset(t); 967 teken_subr_erase_display(t, 2); 968 teken_funcs_param(t, TP_SHOWCURSOR, 1); 969 teken_funcs_cursor(t); 970} 971 972static void 973teken_subr_restore_cursor(teken_t *t) 974{ 975 976 t->t_cursor = t->t_saved_cursor; 977 t->t_curattr = t->t_saved_curattr; 978 t->t_stateflags &= ~TS_WRAPPED; 979 teken_scs_restore(t); 980 teken_funcs_cursor(t); 981} 982 983static void 984teken_subr_reverse_index(teken_t *t) 985{ 986 987 if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) { 988 t->t_cursor.tp_row--; 989 t->t_stateflags &= ~TS_WRAPPED; 990 teken_funcs_cursor(t); 991 } else { 992 teken_subr_do_scroll(t, -1); 993 } 994} 995 996static void 997teken_subr_save_cursor(teken_t *t) 998{ 999 1000 t->t_saved_cursor = t->t_cursor; 1001 t->t_saved_curattr = t->t_curattr; 1002 teken_scs_save(t); 1003} 1004 1005static void 1006teken_subr_secondary_device_attributes(teken_t *t, unsigned int request) 1007{ 1008 1009 if (request == 0) { 1010 const char response[] = "\x1B[>0;10;0c"; 1011 teken_funcs_respond(t, response, sizeof response - 1); 1012 } else { 1013 teken_printf("Unknown DA2\n"); 1014 } 1015} 1016 1017static void 1018teken_subr_set_dec_mode(teken_t *t, unsigned int cmd) 1019{ 1020 1021 switch (cmd) { 1022 case 1: /* Cursor keys mode. */ 1023 teken_funcs_param(t, TP_CURSORKEYS, 1); 1024 break; 1025 case 2: /* DECANM: ANSI/VT52 mode. */ 1026 teken_printf("DECSET VT52\n"); 1027 break; 1028 case 3: /* 132 column mode. */ 1029 teken_funcs_param(t, TP_132COLS, 1); 1030 teken_subr_reset_to_initial_state(t); 1031 break; 1032 case 5: /* Inverse video. */ 1033 teken_printf("DECSET inverse video\n"); 1034 break; 1035 case 6: /* Origin mode. */ 1036 t->t_stateflags |= TS_ORIGIN; 1037 t->t_originreg = t->t_scrollreg; 1038 t->t_cursor.tp_row = t->t_scrollreg.ts_begin; 1039 t->t_cursor.tp_col = 0; 1040 t->t_stateflags &= ~TS_WRAPPED; 1041 teken_funcs_cursor(t); 1042 break; 1043 case 7: /* Autowrap mode. */ 1044 t->t_stateflags |= TS_AUTOWRAP; 1045 break; 1046 case 8: /* Autorepeat mode. */ 1047 teken_funcs_param(t, TP_AUTOREPEAT, 1); 1048 break; 1049 case 25: /* Display cursor. */ 1050 teken_funcs_param(t, TP_SHOWCURSOR, 1); 1051 break; 1052 case 40: /* Allow 132 columns. */ 1053 teken_printf("DECSET allow 132\n"); 1054 break; 1055 case 45: /* Enable reverse wraparound. */ 1056 teken_printf("DECSET reverse wraparound\n"); 1057 break; 1058 case 47: /* Switch to alternate buffer. */ 1059 teken_printf("Switch away from alternate buffer\n"); 1060 break; 1061 default: 1062 teken_printf("Unknown DECSET: %u\n", cmd); 1063 } 1064} 1065 1066static void 1067teken_subr_set_mode(teken_t *t, unsigned int cmd) 1068{ 1069 1070 switch (cmd) { 1071 case 4: 1072 teken_printf("Insert mode\n"); 1073 t->t_stateflags |= TS_INSERT; 1074 break; 1075 default: 1076 teken_printf("Unknown set mode: %u\n", cmd); 1077 } 1078} 1079 1080static void 1081teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds, 1082 unsigned int cmds[]) 1083{ 1084 unsigned int i, n; 1085 1086 /* No attributes means reset. */ 1087 if (ncmds == 0) { 1088 t->t_curattr = t->t_defattr; 1089 return; 1090 } 1091 1092 for (i = 0; i < ncmds; i++) { 1093 n = cmds[i]; 1094 1095 switch (n) { 1096 case 0: /* Reset. */ 1097 t->t_curattr = t->t_defattr; 1098 break; 1099 case 1: /* Bold. */ 1100 t->t_curattr.ta_format |= TF_BOLD; 1101 break; 1102 case 4: /* Underline. */ 1103 t->t_curattr.ta_format |= TF_UNDERLINE; 1104 break; 1105 case 5: /* Blink. */ 1106 t->t_curattr.ta_format |= TF_BLINK; 1107 break; 1108 case 7: /* Reverse. */ 1109 t->t_curattr.ta_format |= TF_REVERSE; 1110 break; 1111 case 22: /* Remove bold. */ 1112 t->t_curattr.ta_format &= ~TF_BOLD; 1113 break; 1114 case 24: /* Remove underline. */ 1115 t->t_curattr.ta_format &= ~TF_UNDERLINE; 1116 break; 1117 case 25: /* Remove blink. */ 1118 t->t_curattr.ta_format &= ~TF_BLINK; 1119 break; 1120 case 27: /* Remove reverse. */ 1121 t->t_curattr.ta_format &= ~TF_REVERSE; 1122 break; 1123 case 30: /* Set foreground color: black */ 1124 case 31: /* Set foreground color: red */ 1125 case 32: /* Set foreground color: green */ 1126 case 33: /* Set foreground color: brown */ 1127 case 34: /* Set foreground color: blue */ 1128 case 35: /* Set foreground color: magenta */ 1129 case 36: /* Set foreground color: cyan */ 1130 case 37: /* Set foreground color: white */ 1131 t->t_curattr.ta_fgcolor = n - 30; 1132 break; 1133 case 39: /* Set default foreground color. */ 1134 t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor; 1135 break; 1136 case 40: /* Set background color: black */ 1137 case 41: /* Set background color: red */ 1138 case 42: /* Set background color: green */ 1139 case 43: /* Set background color: brown */ 1140 case 44: /* Set background color: blue */ 1141 case 45: /* Set background color: magenta */ 1142 case 46: /* Set background color: cyan */ 1143 case 47: /* Set background color: white */ 1144 t->t_curattr.ta_bgcolor = n - 40; 1145 break; 1146 case 49: /* Set default background color. */ 1147 t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor; 1148 break; 1149 default: 1150 teken_printf("unsupported attribute %u\n", n); 1151 } 1152 } 1153} 1154 1155static void 1156teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top, 1157 unsigned int bottom) 1158{ 1159 1160 /* Adjust top row number. */ 1161 if (top > 0) 1162 top--; 1163 /* Adjust bottom row number. */ 1164 if (bottom == 0 || bottom > t->t_winsize.tp_row) 1165 bottom = t->t_winsize.tp_row; 1166 1167 /* Invalid arguments. */ 1168 if (top >= bottom - 1) { 1169 top = 0; 1170 bottom = t->t_winsize.tp_row; 1171 } 1172 1173 t->t_scrollreg.ts_begin = top; 1174 t->t_scrollreg.ts_end = bottom; 1175 if (t->t_stateflags & TS_ORIGIN) { 1176 /* XXX: home cursor? */ 1177 t->t_originreg = t->t_scrollreg; 1178 t->t_cursor.tp_row = t->t_originreg.ts_begin; 1179 t->t_cursor.tp_col = 0; 1180 t->t_stateflags &= ~TS_WRAPPED; 1181 teken_funcs_cursor(t); 1182 } 1183} 1184 1185static void 1186teken_subr_single_height_double_width_line(teken_t *t __unused) 1187{ 1188 1189 teken_printf("single height double width???\n"); 1190} 1191 1192static void 1193teken_subr_single_height_single_width_line(teken_t *t __unused) 1194{ 1195 1196 teken_printf("single height single width???\n"); 1197} 1198 1199static void 1200teken_subr_string_terminator(teken_t *t __unused) 1201{ 1202 1203 teken_printf("string terminator???\n"); 1204} 1205 1206static void 1207teken_subr_tab_clear(teken_t *t, unsigned int cmd) 1208{ 1209 1210 switch (cmd) { 1211 case 0: 1212 teken_tab_clear(t, t->t_cursor.tp_col); 1213 break; 1214 case 3: 1215 memset(&t->t_tabstops, 0, T_NUMCOL / 8); 1216 break; 1217 } 1218} 1219 1220static void 1221teken_subr_vertical_position_absolute(teken_t *t, unsigned int row) 1222{ 1223 1224 t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1; 1225 if (row >= t->t_originreg.ts_end) 1226 t->t_cursor.tp_row = t->t_originreg.ts_end - 1; 1227 1228 1229 t->t_stateflags &= ~TS_WRAPPED; 1230 teken_funcs_cursor(t); 1231} 1232