The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/teken/teken_subr.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD: releng/9.0/sys/teken/teken_subr.h 226295 2011-10-12 09:28:09Z ed $
   27  */
   28 
   29 static void teken_subr_cursor_up(teken_t *, unsigned int);
   30 static void teken_subr_erase_line(teken_t *, unsigned int);
   31 static void teken_subr_regular_character(teken_t *, teken_char_t);
   32 static void teken_subr_reset_to_initial_state(teken_t *);
   33 static void teken_subr_save_cursor(teken_t *);
   34 
   35 static inline int
   36 teken_tab_isset(teken_t *t, unsigned int col)
   37 {
   38         unsigned int b, o;
   39 
   40         if (col >= T_NUMCOL)
   41                 return ((col % 8) == 0);
   42 
   43         b = col / (sizeof(unsigned int) * 8);
   44         o = col % (sizeof(unsigned int) * 8);
   45 
   46         return (t->t_tabstops[b] & (1 << o));
   47 }
   48 
   49 static inline void
   50 teken_tab_clear(teken_t *t, unsigned int col)
   51 {
   52         unsigned int b, o;
   53 
   54         if (col >= T_NUMCOL)
   55                 return;
   56 
   57         b = col / (sizeof(unsigned int) * 8);
   58         o = col % (sizeof(unsigned int) * 8);
   59 
   60         t->t_tabstops[b] &= ~(1 << o);
   61 }
   62 
   63 static inline void
   64 teken_tab_set(teken_t *t, unsigned int col)
   65 {
   66         unsigned int b, o;
   67 
   68         if (col >= T_NUMCOL)
   69                 return;
   70 
   71         b = col / (sizeof(unsigned int) * 8);
   72         o = col % (sizeof(unsigned int) * 8);
   73 
   74         t->t_tabstops[b] |= 1 << o;
   75 }
   76 
   77 static void
   78 teken_tab_default(teken_t *t)
   79 {
   80         unsigned int i;
   81 
   82         memset(&t->t_tabstops, 0, T_NUMCOL / 8);
   83 
   84         for (i = 8; i < T_NUMCOL; i += 8)
   85                 teken_tab_set(t, i);
   86 }
   87 
   88 static void
   89 teken_subr_do_scroll(teken_t *t, int amount)
   90 {
   91         teken_rect_t tr;
   92         teken_pos_t tp;
   93 
   94         teken_assert(t->t_cursor.tp_row <= t->t_winsize.tp_row);
   95         teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
   96         teken_assert(amount != 0);
   97 
   98         /* Copy existing data 1 line up. */
   99         if (amount > 0) {
  100                 /* Scroll down. */
  101 
  102                 /* Copy existing data up. */
  103                 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
  104                         tr.tr_begin.tp_row = t->t_scrollreg.ts_begin + amount;
  105                         tr.tr_begin.tp_col = 0;
  106                         tr.tr_end.tp_row = t->t_scrollreg.ts_end;
  107                         tr.tr_end.tp_col = t->t_winsize.tp_col;
  108                         tp.tp_row = t->t_scrollreg.ts_begin;
  109                         tp.tp_col = 0;
  110                         teken_funcs_copy(t, &tr, &tp);
  111 
  112                         tr.tr_begin.tp_row = t->t_scrollreg.ts_end - amount;
  113                 } else {
  114                         tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
  115                 }
  116 
  117                 /* Clear the last lines. */
  118                 tr.tr_begin.tp_col = 0;
  119                 tr.tr_end.tp_row = t->t_scrollreg.ts_end;
  120                 tr.tr_end.tp_col = t->t_winsize.tp_col;
  121                 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  122         } else {
  123                 /* Scroll up. */
  124                 amount = -amount;
  125 
  126                 /* Copy existing data down. */
  127                 if (t->t_scrollreg.ts_begin + amount < t->t_scrollreg.ts_end) {
  128                         tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
  129                         tr.tr_begin.tp_col = 0;
  130                         tr.tr_end.tp_row = t->t_scrollreg.ts_end - amount;
  131                         tr.tr_end.tp_col = t->t_winsize.tp_col;
  132                         tp.tp_row = t->t_scrollreg.ts_begin + amount;
  133                         tp.tp_col = 0;
  134                         teken_funcs_copy(t, &tr, &tp);
  135 
  136                         tr.tr_end.tp_row = t->t_scrollreg.ts_begin + amount;
  137                 } else {
  138                         tr.tr_end.tp_row = t->t_scrollreg.ts_end;
  139                 }
  140 
  141                 /* Clear the first lines. */
  142                 tr.tr_begin.tp_row = t->t_scrollreg.ts_begin;
  143                 tr.tr_begin.tp_col = 0;
  144                 tr.tr_end.tp_col = t->t_winsize.tp_col;
  145                 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  146         }
  147 }
  148 
  149 static ssize_t
  150 teken_subr_do_cpr(teken_t *t, unsigned int cmd, char response[16])
  151 {
  152 
  153         switch (cmd) {
  154         case 5: /* Operating status. */
  155                 strcpy(response, "0n");
  156                 return (2);
  157         case 6: { /* Cursor position. */
  158                 int len;
  159 
  160                 len = snprintf(response, 16, "%u;%uR",
  161                     (t->t_cursor.tp_row - t->t_originreg.ts_begin) + 1,
  162                     t->t_cursor.tp_col + 1);
  163 
  164                 if (len >= 16)
  165                         return (-1);
  166                 return (len);
  167         }
  168         case 15: /* Printer status. */
  169                 strcpy(response, "13n");
  170                 return (3);
  171         case 25: /* UDK status. */
  172                 strcpy(response, "20n");
  173                 return (3);
  174         case 26: /* Keyboard status. */
  175                 strcpy(response, "27;1n");
  176                 return (5);
  177         default:
  178                 teken_printf("Unknown DSR\n");
  179                 return (-1);
  180         }
  181 }
  182 
  183 static void
  184 teken_subr_alignment_test(teken_t *t)
  185 {
  186         teken_rect_t tr;
  187 
  188         t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
  189         t->t_scrollreg.ts_begin = 0;
  190         t->t_scrollreg.ts_end = t->t_winsize.tp_row;
  191         t->t_originreg = t->t_scrollreg;
  192         t->t_stateflags &= ~(TS_WRAPPED|TS_ORIGIN);
  193         teken_funcs_cursor(t);
  194 
  195         tr.tr_begin.tp_row = 0;
  196         tr.tr_begin.tp_col = 0;
  197         tr.tr_end = t->t_winsize;
  198         teken_funcs_fill(t, &tr, 'E', &t->t_defattr);
  199 }
  200 
  201 static void
  202 teken_subr_backspace(teken_t *t)
  203 {
  204 
  205         if (t->t_stateflags & TS_CONS25) {
  206                 if (t->t_cursor.tp_col == 0) {
  207                         if (t->t_cursor.tp_row == t->t_originreg.ts_begin)
  208                                 return;
  209                         t->t_cursor.tp_row--;
  210                         t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
  211                 } else {
  212                         t->t_cursor.tp_col--;
  213                 }
  214         } else {
  215                 if (t->t_cursor.tp_col == 0)
  216                         return;
  217 
  218                 t->t_cursor.tp_col--;
  219                 t->t_stateflags &= ~TS_WRAPPED;
  220         }
  221 
  222         teken_funcs_cursor(t);
  223 }
  224 
  225 static void
  226 teken_subr_bell(teken_t *t)
  227 {
  228 
  229         teken_funcs_bell(t);
  230 }
  231 
  232 static void
  233 teken_subr_carriage_return(teken_t *t)
  234 {
  235 
  236         t->t_cursor.tp_col = 0;
  237         t->t_stateflags &= ~TS_WRAPPED;
  238         teken_funcs_cursor(t);
  239 }
  240 
  241 static void
  242 teken_subr_cursor_backward(teken_t *t, unsigned int ncols)
  243 {
  244 
  245         if (ncols > t->t_cursor.tp_col)
  246                 t->t_cursor.tp_col = 0;
  247         else
  248                 t->t_cursor.tp_col -= ncols;
  249         t->t_stateflags &= ~TS_WRAPPED;
  250         teken_funcs_cursor(t);
  251 }
  252 
  253 static void
  254 teken_subr_cursor_backward_tabulation(teken_t *t, unsigned int ntabs)
  255 {
  256 
  257         do {
  258                 /* Stop when we've reached the beginning of the line. */
  259                 if (t->t_cursor.tp_col == 0)
  260                         break;
  261 
  262                 t->t_cursor.tp_col--;
  263 
  264                 /* Tab marker set. */
  265                 if (teken_tab_isset(t, t->t_cursor.tp_col))
  266                         ntabs--;
  267         } while (ntabs > 0);
  268 
  269         teken_funcs_cursor(t);
  270 }
  271 
  272 static void
  273 teken_subr_cursor_down(teken_t *t, unsigned int nrows)
  274 {
  275 
  276         if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end)
  277                 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
  278         else
  279                 t->t_cursor.tp_row += nrows;
  280         t->t_stateflags &= ~TS_WRAPPED;
  281         teken_funcs_cursor(t);
  282 }
  283 
  284 static void
  285 teken_subr_cursor_forward(teken_t *t, unsigned int ncols)
  286 {
  287 
  288         if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
  289                 t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
  290         else
  291                 t->t_cursor.tp_col += ncols;
  292         t->t_stateflags &= ~TS_WRAPPED;
  293         teken_funcs_cursor(t);
  294 }
  295 
  296 static void
  297 teken_subr_cursor_forward_tabulation(teken_t *t, unsigned int ntabs)
  298 {
  299 
  300         do {
  301                 /* Stop when we've reached the end of the line. */
  302                 if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1)
  303                         break;
  304 
  305                 t->t_cursor.tp_col++;
  306 
  307                 /* Tab marker set. */
  308                 if (teken_tab_isset(t, t->t_cursor.tp_col))
  309                         ntabs--;
  310         } while (ntabs > 0);
  311 
  312         teken_funcs_cursor(t);
  313 }
  314 
  315 static void
  316 teken_subr_cursor_next_line(teken_t *t, unsigned int ncols)
  317 {
  318 
  319         t->t_cursor.tp_col = 0;
  320         teken_subr_cursor_down(t, ncols);
  321 }
  322 
  323 static void
  324 teken_subr_cursor_position(teken_t *t, unsigned int row, unsigned int col)
  325 {
  326 
  327         t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
  328         if (t->t_cursor.tp_row >= t->t_originreg.ts_end)
  329                 t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
  330 
  331         t->t_cursor.tp_col = col - 1;
  332         if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
  333                 t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
  334 
  335         t->t_stateflags &= ~TS_WRAPPED;
  336         teken_funcs_cursor(t);
  337 }
  338 
  339 static void
  340 teken_subr_cursor_position_report(teken_t *t, unsigned int cmd)
  341 {
  342         char response[18] = "\x1B[";
  343         ssize_t len;
  344 
  345         len = teken_subr_do_cpr(t, cmd, response + 2);
  346         if (len < 0)
  347                 return;
  348 
  349         teken_funcs_respond(t, response, len + 2);
  350 }
  351 
  352 static void
  353 teken_subr_cursor_previous_line(teken_t *t, unsigned int ncols)
  354 {
  355 
  356         t->t_cursor.tp_col = 0;
  357         teken_subr_cursor_up(t, ncols);
  358 }
  359 
  360 static void
  361 teken_subr_cursor_up(teken_t *t, unsigned int nrows)
  362 {
  363 
  364         if (t->t_scrollreg.ts_begin + nrows >= t->t_cursor.tp_row)
  365                 t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
  366         else
  367                 t->t_cursor.tp_row -= nrows;
  368         t->t_stateflags &= ~TS_WRAPPED;
  369         teken_funcs_cursor(t);
  370 }
  371 
  372 static void
  373 teken_subr_delete_character(teken_t *t, unsigned int ncols)
  374 {
  375         teken_rect_t tr;
  376 
  377         tr.tr_begin.tp_row = t->t_cursor.tp_row;
  378         tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
  379         tr.tr_end.tp_col = t->t_winsize.tp_col;
  380 
  381         if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
  382                 tr.tr_begin.tp_col = t->t_cursor.tp_col;
  383         } else {
  384                 /* Copy characters to the left. */
  385                 tr.tr_begin.tp_col = t->t_cursor.tp_col + ncols;
  386                 teken_funcs_copy(t, &tr, &t->t_cursor);
  387 
  388                 tr.tr_begin.tp_col = t->t_winsize.tp_col - ncols;
  389         }
  390 
  391         /* Blank trailing columns. */
  392         teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  393 }
  394 
  395 static void
  396 teken_subr_delete_line(teken_t *t, unsigned int nrows)
  397 {
  398         teken_rect_t tr;
  399 
  400         /* Ignore if outside scrolling region. */
  401         if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
  402             t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
  403                 return;
  404 
  405         tr.tr_begin.tp_col = 0;
  406         tr.tr_end.tp_row = t->t_scrollreg.ts_end;
  407         tr.tr_end.tp_col = t->t_winsize.tp_col;
  408 
  409         if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
  410                 tr.tr_begin.tp_row = t->t_cursor.tp_row;
  411         } else {
  412                 teken_pos_t tp;
  413 
  414                 /* Copy rows up. */
  415                 tr.tr_begin.tp_row = t->t_cursor.tp_row + nrows;
  416                 tp.tp_row = t->t_cursor.tp_row;
  417                 tp.tp_col = 0;
  418                 teken_funcs_copy(t, &tr, &tp);
  419 
  420                 tr.tr_begin.tp_row = t->t_scrollreg.ts_end - nrows;
  421         }
  422 
  423         /* Blank trailing rows. */
  424         teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  425 }
  426 
  427 static void
  428 teken_subr_device_control_string(teken_t *t)
  429 {
  430 
  431         teken_printf("Unsupported device control string\n");
  432         t->t_stateflags |= TS_INSTRING;
  433 }
  434 
  435 static void
  436 teken_subr_device_status_report(teken_t *t, unsigned int cmd)
  437 {
  438         char response[19] = "\x1B[?";
  439         ssize_t len;
  440 
  441         len = teken_subr_do_cpr(t, cmd, response + 3);
  442         if (len < 0)
  443                 return;
  444 
  445         teken_funcs_respond(t, response, len + 3);
  446 }
  447 
  448 static void
  449 teken_subr_double_height_double_width_line_top(teken_t *t __unused)
  450 {
  451 
  452         teken_printf("double height double width top\n");
  453 }
  454 
  455 static void
  456 teken_subr_double_height_double_width_line_bottom(teken_t *t __unused)
  457 {
  458 
  459         teken_printf("double height double width bottom\n");
  460 }
  461 
  462 static void
  463 teken_subr_erase_character(teken_t *t, unsigned int ncols)
  464 {
  465         teken_rect_t tr;
  466 
  467         tr.tr_begin = t->t_cursor;
  468         tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
  469 
  470         if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col)
  471                 tr.tr_end.tp_col = t->t_winsize.tp_col;
  472         else
  473                 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
  474 
  475         teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  476 }
  477 
  478 static void
  479 teken_subr_erase_display(teken_t *t, unsigned int mode)
  480 {
  481         teken_rect_t r;
  482 
  483         r.tr_begin.tp_col = 0;
  484         r.tr_end.tp_col = t->t_winsize.tp_col;
  485 
  486         switch (mode) {
  487         case 1: /* Erase from the top to the cursor. */
  488                 teken_subr_erase_line(t, 1);
  489 
  490                 /* Erase lines above. */
  491                 if (t->t_cursor.tp_row == 0)
  492                         return;
  493                 r.tr_begin.tp_row = 0;
  494                 r.tr_end.tp_row = t->t_cursor.tp_row;
  495                 break;
  496         case 2: /* Erase entire display. */
  497                 r.tr_begin.tp_row = 0;
  498                 r.tr_end.tp_row = t->t_winsize.tp_row;
  499                 break;
  500         default: /* Erase from cursor to the bottom. */
  501                 teken_subr_erase_line(t, 0);
  502 
  503                 /* Erase lines below. */
  504                 if (t->t_cursor.tp_row == t->t_winsize.tp_row - 1)
  505                         return;
  506                 r.tr_begin.tp_row = t->t_cursor.tp_row + 1;
  507                 r.tr_end.tp_row = t->t_winsize.tp_row;
  508                 break;
  509         }
  510 
  511         teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
  512 }
  513 
  514 static void
  515 teken_subr_erase_line(teken_t *t, unsigned int mode)
  516 {
  517         teken_rect_t r;
  518 
  519         r.tr_begin.tp_row = t->t_cursor.tp_row;
  520         r.tr_end.tp_row = t->t_cursor.tp_row + 1;
  521 
  522         switch (mode) {
  523         case 1: /* Erase from the beginning of the line to the cursor. */
  524                 r.tr_begin.tp_col = 0;
  525                 r.tr_end.tp_col = t->t_cursor.tp_col + 1;
  526                 break;
  527         case 2: /* Erase entire line. */
  528                 r.tr_begin.tp_col = 0;
  529                 r.tr_end.tp_col = t->t_winsize.tp_col;
  530                 break;
  531         default: /* Erase from cursor to the end of the line. */
  532                 r.tr_begin.tp_col = t->t_cursor.tp_col;
  533                 r.tr_end.tp_col = t->t_winsize.tp_col;
  534                 break;
  535         }
  536 
  537         teken_funcs_fill(t, &r, BLANK, &t->t_curattr);
  538 }
  539 
  540 static void
  541 teken_subr_g0_scs_special_graphics(teken_t *t __unused)
  542 {
  543 
  544         t->t_scs[0] = teken_scs_special_graphics;
  545 }
  546 
  547 static void
  548 teken_subr_g0_scs_uk_national(teken_t *t __unused)
  549 {
  550 
  551         t->t_scs[0] = teken_scs_uk_national;
  552 }
  553 
  554 static void
  555 teken_subr_g0_scs_us_ascii(teken_t *t __unused)
  556 {
  557 
  558         t->t_scs[0] = teken_scs_us_ascii;
  559 }
  560 
  561 static void
  562 teken_subr_g1_scs_special_graphics(teken_t *t __unused)
  563 {
  564 
  565         t->t_scs[1] = teken_scs_special_graphics;
  566 }
  567 
  568 static void
  569 teken_subr_g1_scs_uk_national(teken_t *t __unused)
  570 {
  571 
  572         t->t_scs[1] = teken_scs_uk_national;
  573 }
  574 
  575 static void
  576 teken_subr_g1_scs_us_ascii(teken_t *t __unused)
  577 {
  578 
  579         t->t_scs[1] = teken_scs_us_ascii;
  580 }
  581 
  582 static void
  583 teken_subr_horizontal_position_absolute(teken_t *t, unsigned int col)
  584 {
  585 
  586         t->t_cursor.tp_col = col - 1;
  587         if (t->t_cursor.tp_col >= t->t_winsize.tp_col)
  588                 t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
  589 
  590         t->t_stateflags &= ~TS_WRAPPED;
  591         teken_funcs_cursor(t);
  592 }
  593 
  594 static void
  595 teken_subr_horizontal_tab(teken_t *t)
  596 {
  597 
  598         teken_subr_cursor_forward_tabulation(t, 1);
  599 }
  600 
  601 static void
  602 teken_subr_horizontal_tab_set(teken_t *t)
  603 {
  604 
  605         teken_tab_set(t, t->t_cursor.tp_col);
  606 }
  607 
  608 static void
  609 teken_subr_index(teken_t *t)
  610 {
  611 
  612         if (t->t_cursor.tp_row < t->t_scrollreg.ts_end - 1) {
  613                 t->t_cursor.tp_row++;
  614                 t->t_stateflags &= ~TS_WRAPPED;
  615                 teken_funcs_cursor(t);
  616         } else {
  617                 teken_subr_do_scroll(t, 1);
  618         }
  619 }
  620 
  621 static void
  622 teken_subr_insert_character(teken_t *t, unsigned int ncols)
  623 {
  624         teken_rect_t tr;
  625 
  626         tr.tr_begin = t->t_cursor;
  627         tr.tr_end.tp_row = t->t_cursor.tp_row + 1;
  628 
  629         if (t->t_cursor.tp_col + ncols >= t->t_winsize.tp_col) {
  630                 tr.tr_end.tp_col = t->t_winsize.tp_col;
  631         } else {
  632                 teken_pos_t tp;
  633 
  634                 /* Copy characters to the right. */
  635                 tr.tr_end.tp_col = t->t_winsize.tp_col - ncols;
  636                 tp.tp_row = t->t_cursor.tp_row;
  637                 tp.tp_col = t->t_cursor.tp_col + ncols;
  638                 teken_funcs_copy(t, &tr, &tp);
  639 
  640                 tr.tr_end.tp_col = t->t_cursor.tp_col + ncols;
  641         }
  642 
  643         /* Blank current location. */
  644         teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  645 }
  646 
  647 static void
  648 teken_subr_insert_line(teken_t *t, unsigned int nrows)
  649 {
  650         teken_rect_t tr;
  651 
  652         /* Ignore if outside scrolling region. */
  653         if (t->t_cursor.tp_row < t->t_scrollreg.ts_begin ||
  654             t->t_cursor.tp_row >= t->t_scrollreg.ts_end)
  655                 return;
  656 
  657         tr.tr_begin.tp_row = t->t_cursor.tp_row;
  658         tr.tr_begin.tp_col = 0;
  659         tr.tr_end.tp_col = t->t_winsize.tp_col;
  660 
  661         if (t->t_cursor.tp_row + nrows >= t->t_scrollreg.ts_end) {
  662                 tr.tr_end.tp_row = t->t_scrollreg.ts_end;
  663         } else {
  664                 teken_pos_t tp;
  665 
  666                 /* Copy lines down. */
  667                 tr.tr_end.tp_row = t->t_scrollreg.ts_end - nrows;
  668                 tp.tp_row = t->t_cursor.tp_row + nrows;
  669                 tp.tp_col = 0;
  670                 teken_funcs_copy(t, &tr, &tp);
  671 
  672                 tr.tr_end.tp_row = t->t_cursor.tp_row + nrows;
  673         }
  674 
  675         /* Blank current location. */
  676         teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  677 }
  678 
  679 static void
  680 teken_subr_keypad_application_mode(teken_t *t)
  681 {
  682 
  683         teken_funcs_param(t, TP_KEYPADAPP, 1);
  684 }
  685 
  686 static void
  687 teken_subr_keypad_numeric_mode(teken_t *t)
  688 {
  689 
  690         teken_funcs_param(t, TP_KEYPADAPP, 0);
  691 }
  692 
  693 static void
  694 teken_subr_newline(teken_t *t)
  695 {
  696 
  697         t->t_cursor.tp_row++;
  698 
  699         if (t->t_cursor.tp_row >= t->t_scrollreg.ts_end) {
  700                 teken_subr_do_scroll(t, 1);
  701                 t->t_cursor.tp_row = t->t_scrollreg.ts_end - 1;
  702         }
  703 
  704         t->t_stateflags &= ~TS_WRAPPED;
  705         teken_funcs_cursor(t);
  706 }
  707 
  708 static void
  709 teken_subr_newpage(teken_t *t)
  710 {
  711 
  712         if (t->t_stateflags & TS_CONS25) {
  713                 teken_rect_t tr;
  714 
  715                 /* Clear screen. */
  716                 tr.tr_begin.tp_row = t->t_originreg.ts_begin;
  717                 tr.tr_begin.tp_col = 0;
  718                 tr.tr_end.tp_row = t->t_originreg.ts_end;
  719                 tr.tr_end.tp_col = t->t_winsize.tp_col;
  720                 teken_funcs_fill(t, &tr, BLANK, &t->t_curattr);
  721 
  722                 /* Cursor at top left. */
  723                 t->t_cursor.tp_row = t->t_originreg.ts_begin;
  724                 t->t_cursor.tp_col = 0;
  725                 t->t_stateflags &= ~TS_WRAPPED;
  726                 teken_funcs_cursor(t);
  727         } else {
  728                 teken_subr_newline(t);
  729         }
  730 }
  731 
  732 static void
  733 teken_subr_next_line(teken_t *t)
  734 {
  735 
  736         t->t_cursor.tp_col = 0;
  737         teken_subr_newline(t);
  738 }
  739 
  740 static void
  741 teken_subr_operating_system_command(teken_t *t)
  742 {
  743 
  744         teken_printf("Unsupported operating system command\n");
  745         t->t_stateflags |= TS_INSTRING;
  746 }
  747 
  748 static void
  749 teken_subr_pan_down(teken_t *t, unsigned int nrows)
  750 {
  751 
  752         teken_subr_do_scroll(t, (int)nrows);
  753 }
  754 
  755 static void
  756 teken_subr_pan_up(teken_t *t, unsigned int nrows)
  757 {
  758 
  759         teken_subr_do_scroll(t, -(int)nrows);
  760 }
  761 
  762 static void
  763 teken_subr_primary_device_attributes(teken_t *t, unsigned int request)
  764 {
  765 
  766         if (request == 0) {
  767                 const char response[] = "\x1B[?1;2c";
  768 
  769                 teken_funcs_respond(t, response, sizeof response - 1);
  770         } else {
  771                 teken_printf("Unknown DA1\n");
  772         }
  773 }
  774 
  775 static void
  776 teken_subr_do_putchar(teken_t *t, const teken_pos_t *tp, teken_char_t c,
  777     int width)
  778 {
  779 
  780         if (t->t_stateflags & TS_INSERT &&
  781             tp->tp_col < t->t_winsize.tp_col - width) {
  782                 teken_rect_t ctr;
  783                 teken_pos_t ctp;
  784 
  785                 /* Insert mode. Move existing characters to the right. */
  786                 ctr.tr_begin = *tp;
  787                 ctr.tr_end.tp_row = tp->tp_row + 1;
  788                 ctr.tr_end.tp_col = t->t_winsize.tp_col - width;
  789                 ctp.tp_row = tp->tp_row;
  790                 ctp.tp_col = tp->tp_col + width;
  791                 teken_funcs_copy(t, &ctr, &ctp);
  792         }
  793 
  794         if (width == 2 && tp->tp_col + 1 < t->t_winsize.tp_col) {
  795                 teken_pos_t tp2;
  796 
  797                 /*
  798                  * Store a space behind double width characters before
  799                  * actually printing them. This prevents artifacts when
  800                  * the consumer doesn't render it using double width
  801                  * glyphs.
  802                  */
  803                 tp2.tp_row = tp->tp_row;
  804                 tp2.tp_col = tp->tp_col + 1;
  805                 teken_funcs_putchar(t, &tp2, BLANK, &t->t_curattr);
  806         }
  807 
  808         teken_funcs_putchar(t, tp, c, &t->t_curattr);
  809 }
  810 
  811 static void
  812 teken_subr_regular_character(teken_t *t, teken_char_t c)
  813 {
  814         int width;
  815 
  816         if (t->t_stateflags & TS_8BIT) {
  817                 if (!(t->t_stateflags & TS_CONS25) && (c <= 0x1b || c == 0x7f))
  818                         return;
  819                 c = teken_scs_process(t, c);
  820                 width = 1;
  821         } else {
  822                 c = teken_scs_process(t, c);
  823                 width = teken_wcwidth(c);
  824                 /* XXX: Don't process zero-width characters yet. */
  825                 if (width <= 0)
  826                         return;
  827         }
  828 
  829         if (t->t_stateflags & TS_CONS25) {
  830                 teken_subr_do_putchar(t, &t->t_cursor, c, width);
  831                 t->t_cursor.tp_col += width;
  832 
  833                 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
  834                         if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
  835                                 /* Perform scrolling. */
  836                                 teken_subr_do_scroll(t, 1);
  837                         } else {
  838                                 /* No scrolling needed. */
  839                                 if (t->t_cursor.tp_row <
  840                                     t->t_winsize.tp_row - 1)
  841                                         t->t_cursor.tp_row++;
  842                         }
  843                         t->t_cursor.tp_col = 0;
  844                 }
  845         } else if (t->t_cursor.tp_col == t->t_winsize.tp_col - 1 &&
  846             (t->t_stateflags & (TS_WRAPPED|TS_AUTOWRAP)) ==
  847             (TS_WRAPPED|TS_AUTOWRAP)) {
  848                 teken_pos_t tp;
  849 
  850                 /* Perform line wrapping. */
  851 
  852                 if (t->t_cursor.tp_row == t->t_scrollreg.ts_end - 1) {
  853                         /* Perform scrolling. */
  854                         teken_subr_do_scroll(t, 1);
  855                         tp.tp_row = t->t_scrollreg.ts_end - 1;
  856                 } else {
  857                         /* No scrolling needed. */
  858                         tp.tp_row = t->t_cursor.tp_row + 1;
  859                         if (tp.tp_row == t->t_winsize.tp_row) {
  860                                 /*
  861                                  * Corner case: regular character
  862                                  * outside scrolling region, but at the
  863                                  * bottom of the screen.
  864                                  */
  865                                 teken_subr_do_putchar(t, &t->t_cursor,
  866                                     c, width);
  867                                 return;
  868                         }
  869                 }
  870 
  871                 tp.tp_col = 0;
  872                 teken_subr_do_putchar(t, &tp, c, width);
  873 
  874                 t->t_cursor.tp_row = tp.tp_row;
  875                 t->t_cursor.tp_col = width;
  876                 t->t_stateflags &= ~TS_WRAPPED;
  877         } else {
  878                 /* No line wrapping needed. */
  879                 teken_subr_do_putchar(t, &t->t_cursor, c, width);
  880                 t->t_cursor.tp_col += width;
  881 
  882                 if (t->t_cursor.tp_col >= t->t_winsize.tp_col) {
  883                         t->t_stateflags |= TS_WRAPPED;
  884                         t->t_cursor.tp_col = t->t_winsize.tp_col - 1;
  885                 } else {
  886                         t->t_stateflags &= ~TS_WRAPPED;
  887                 }
  888         }
  889 
  890         teken_funcs_cursor(t);
  891 }
  892 
  893 static void
  894 teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
  895 {
  896 
  897         switch (cmd) {
  898         case 1: /* Cursor keys mode. */
  899                 t->t_stateflags &= ~TS_CURSORKEYS;
  900                 break;
  901         case 2: /* DECANM: ANSI/VT52 mode. */
  902                 teken_printf("DECRST VT52\n");
  903                 break;
  904         case 3: /* 132 column mode. */
  905                 teken_funcs_param(t, TP_132COLS, 0);
  906                 teken_subr_reset_to_initial_state(t);
  907                 break;
  908         case 5: /* Inverse video. */
  909                 teken_printf("DECRST inverse video\n");
  910                 break;
  911         case 6: /* Origin mode. */
  912                 t->t_stateflags &= ~TS_ORIGIN;
  913                 t->t_originreg.ts_begin = 0;
  914                 t->t_originreg.ts_end = t->t_winsize.tp_row;
  915                 t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
  916                 t->t_stateflags &= ~TS_WRAPPED;
  917                 teken_funcs_cursor(t);
  918                 break;
  919         case 7: /* Autowrap mode. */
  920                 t->t_stateflags &= ~TS_AUTOWRAP;
  921                 break;
  922         case 8: /* Autorepeat mode. */
  923                 teken_funcs_param(t, TP_AUTOREPEAT, 0);
  924                 break;
  925         case 25: /* Hide cursor. */
  926                 teken_funcs_param(t, TP_SHOWCURSOR, 0);
  927                 break;
  928         case 40: /* Disallow 132 columns. */
  929                 teken_printf("DECRST allow 132\n");
  930                 break;
  931         case 45: /* Disable reverse wraparound. */
  932                 teken_printf("DECRST reverse wraparound\n");
  933                 break;
  934         case 47: /* Switch to alternate buffer. */
  935                 teken_printf("Switch to alternate buffer\n");
  936                 break;
  937         case 1000: /* Mouse input. */
  938                 teken_funcs_param(t, TP_MOUSE, 0);
  939                 break;
  940         default:
  941                 teken_printf("Unknown DECRST: %u\n", cmd);
  942         }
  943 }
  944 
  945 static void
  946 teken_subr_reset_mode(teken_t *t, unsigned int cmd)
  947 {
  948 
  949         switch (cmd) {
  950         case 4:
  951                 t->t_stateflags &= ~TS_INSERT;
  952                 break;
  953         default:
  954                 teken_printf("Unknown reset mode: %u\n", cmd);
  955         }
  956 }
  957 
  958 static void
  959 teken_subr_do_reset(teken_t *t)
  960 {
  961 
  962         t->t_curattr = t->t_defattr;
  963         t->t_cursor.tp_row = t->t_cursor.tp_col = 0;
  964         t->t_scrollreg.ts_begin = 0;
  965         t->t_scrollreg.ts_end = t->t_winsize.tp_row;
  966         t->t_originreg = t->t_scrollreg;
  967         t->t_stateflags &= TS_8BIT|TS_CONS25;
  968         t->t_stateflags |= TS_AUTOWRAP;
  969 
  970         t->t_scs[0] = teken_scs_us_ascii;
  971         t->t_scs[1] = teken_scs_us_ascii;
  972         t->t_curscs = 0;
  973 
  974         teken_subr_save_cursor(t);
  975         teken_tab_default(t);
  976 }
  977 
  978 static void
  979 teken_subr_reset_to_initial_state(teken_t *t)
  980 {
  981 
  982         teken_subr_do_reset(t);
  983         teken_subr_erase_display(t, 2);
  984         teken_funcs_param(t, TP_SHOWCURSOR, 1);
  985         teken_funcs_cursor(t);
  986 }
  987 
  988 static void
  989 teken_subr_restore_cursor(teken_t *t)
  990 {
  991 
  992         t->t_cursor = t->t_saved_cursor;
  993         t->t_curattr = t->t_saved_curattr;
  994         t->t_scs[t->t_curscs] = t->t_saved_curscs;
  995         t->t_stateflags &= ~TS_WRAPPED;
  996 
  997         /* Get out of origin mode when the cursor is moved outside. */
  998         if (t->t_cursor.tp_row < t->t_originreg.ts_begin ||
  999             t->t_cursor.tp_row >= t->t_originreg.ts_end) {
 1000                 t->t_stateflags &= ~TS_ORIGIN;
 1001                 t->t_originreg.ts_begin = 0;
 1002                 t->t_originreg.ts_end = t->t_winsize.tp_row;
 1003         }
 1004 
 1005         teken_funcs_cursor(t);
 1006 }
 1007 
 1008 static void
 1009 teken_subr_reverse_index(teken_t *t)
 1010 {
 1011 
 1012         if (t->t_cursor.tp_row > t->t_scrollreg.ts_begin) {
 1013                 t->t_cursor.tp_row--;
 1014                 t->t_stateflags &= ~TS_WRAPPED;
 1015                 teken_funcs_cursor(t);
 1016         } else {
 1017                 teken_subr_do_scroll(t, -1);
 1018         }
 1019 }
 1020 
 1021 static void
 1022 teken_subr_save_cursor(teken_t *t)
 1023 {
 1024 
 1025         t->t_saved_cursor = t->t_cursor;
 1026         t->t_saved_curattr = t->t_curattr;
 1027         t->t_saved_curscs = t->t_scs[t->t_curscs];
 1028 }
 1029 
 1030 static void
 1031 teken_subr_secondary_device_attributes(teken_t *t, unsigned int request)
 1032 {
 1033 
 1034         if (request == 0) {
 1035                 const char response[] = "\x1B[>0;10;0c";
 1036                 teken_funcs_respond(t, response, sizeof response - 1);
 1037         } else {
 1038                 teken_printf("Unknown DA2\n");
 1039         }
 1040 }
 1041 
 1042 static void
 1043 teken_subr_set_dec_mode(teken_t *t, unsigned int cmd)
 1044 {
 1045 
 1046         switch (cmd) {
 1047         case 1: /* Cursor keys mode. */
 1048                 t->t_stateflags |= TS_CURSORKEYS;
 1049                 break;
 1050         case 2: /* DECANM: ANSI/VT52 mode. */
 1051                 teken_printf("DECSET VT52\n");
 1052                 break;
 1053         case 3: /* 132 column mode. */
 1054                 teken_funcs_param(t, TP_132COLS, 1);
 1055                 teken_subr_reset_to_initial_state(t);
 1056                 break;
 1057         case 5: /* Inverse video. */
 1058                 teken_printf("DECSET inverse video\n");
 1059                 break;
 1060         case 6: /* Origin mode. */
 1061                 t->t_stateflags |= TS_ORIGIN;
 1062                 t->t_originreg = t->t_scrollreg;
 1063                 t->t_cursor.tp_row = t->t_scrollreg.ts_begin;
 1064                 t->t_cursor.tp_col = 0;
 1065                 t->t_stateflags &= ~TS_WRAPPED;
 1066                 teken_funcs_cursor(t);
 1067                 break;
 1068         case 7: /* Autowrap mode. */
 1069                 t->t_stateflags |= TS_AUTOWRAP;
 1070                 break;
 1071         case 8: /* Autorepeat mode. */
 1072                 teken_funcs_param(t, TP_AUTOREPEAT, 1);
 1073                 break;
 1074         case 25: /* Display cursor. */
 1075                 teken_funcs_param(t, TP_SHOWCURSOR, 1);
 1076                 break;
 1077         case 40: /* Allow 132 columns. */
 1078                 teken_printf("DECSET allow 132\n");
 1079                 break;
 1080         case 45: /* Enable reverse wraparound. */
 1081                 teken_printf("DECSET reverse wraparound\n");
 1082                 break;
 1083         case 47: /* Switch to alternate buffer. */
 1084                 teken_printf("Switch away from alternate buffer\n");
 1085                 break;
 1086         case 1000: /* Mouse input. */
 1087                 teken_funcs_param(t, TP_MOUSE, 1);
 1088                 break;
 1089         default:
 1090                 teken_printf("Unknown DECSET: %u\n", cmd);
 1091         }
 1092 }
 1093 
 1094 static void
 1095 teken_subr_set_mode(teken_t *t, unsigned int cmd)
 1096 {
 1097 
 1098         switch (cmd) {
 1099         case 4:
 1100                 teken_printf("Insert mode\n");
 1101                 t->t_stateflags |= TS_INSERT;
 1102                 break;
 1103         default:
 1104                 teken_printf("Unknown set mode: %u\n", cmd);
 1105         }
 1106 }
 1107 
 1108 static void
 1109 teken_subr_set_graphic_rendition(teken_t *t, unsigned int ncmds,
 1110     unsigned int cmds[])
 1111 {
 1112         unsigned int i, n;
 1113 
 1114         /* No attributes means reset. */
 1115         if (ncmds == 0) {
 1116                 t->t_curattr = t->t_defattr;
 1117                 return;
 1118         }
 1119 
 1120         for (i = 0; i < ncmds; i++) {
 1121                 n = cmds[i];
 1122 
 1123                 switch (n) {
 1124                 case 0: /* Reset. */
 1125                         t->t_curattr = t->t_defattr;
 1126                         break;
 1127                 case 1: /* Bold. */
 1128                         t->t_curattr.ta_format |= TF_BOLD;
 1129                         break;
 1130                 case 4: /* Underline. */
 1131                         t->t_curattr.ta_format |= TF_UNDERLINE;
 1132                         break;
 1133                 case 5: /* Blink. */
 1134                         t->t_curattr.ta_format |= TF_BLINK;
 1135                         break;
 1136                 case 7: /* Reverse. */
 1137                         t->t_curattr.ta_format |= TF_REVERSE;
 1138                         break;
 1139                 case 22: /* Remove bold. */
 1140                         t->t_curattr.ta_format &= ~TF_BOLD;
 1141                         break;
 1142                 case 24: /* Remove underline. */
 1143                         t->t_curattr.ta_format &= ~TF_UNDERLINE;
 1144                         break;
 1145                 case 25: /* Remove blink. */
 1146                         t->t_curattr.ta_format &= ~TF_BLINK;
 1147                         break;
 1148                 case 27: /* Remove reverse. */
 1149                         t->t_curattr.ta_format &= ~TF_REVERSE;
 1150                         break;
 1151                 case 30: /* Set foreground color: black */
 1152                 case 31: /* Set foreground color: red */
 1153                 case 32: /* Set foreground color: green */
 1154                 case 33: /* Set foreground color: brown */
 1155                 case 34: /* Set foreground color: blue */
 1156                 case 35: /* Set foreground color: magenta */
 1157                 case 36: /* Set foreground color: cyan */
 1158                 case 37: /* Set foreground color: white */
 1159                         t->t_curattr.ta_fgcolor = n - 30;
 1160                         break;
 1161                 case 38: /* Set foreground color: 256 color mode */
 1162                         if (i + 2 >= ncmds || cmds[i + 1] != 5)
 1163                                 continue;
 1164                         t->t_curattr.ta_fgcolor = cmds[i + 2];
 1165                         i += 2;
 1166                         break;
 1167                 case 39: /* Set default foreground color. */
 1168                         t->t_curattr.ta_fgcolor = t->t_defattr.ta_fgcolor;
 1169                         break;
 1170                 case 40: /* Set background color: black */
 1171                 case 41: /* Set background color: red */
 1172                 case 42: /* Set background color: green */
 1173                 case 43: /* Set background color: brown */
 1174                 case 44: /* Set background color: blue */
 1175                 case 45: /* Set background color: magenta */
 1176                 case 46: /* Set background color: cyan */
 1177                 case 47: /* Set background color: white */
 1178                         t->t_curattr.ta_bgcolor = n - 40;
 1179                         break;
 1180                 case 48: /* Set background color: 256 color mode */
 1181                         if (i + 2 >= ncmds || cmds[i + 1] != 5)
 1182                                 continue;
 1183                         t->t_curattr.ta_bgcolor = cmds[i + 2];
 1184                         i += 2;
 1185                         break;
 1186                 case 49: /* Set default background color. */
 1187                         t->t_curattr.ta_bgcolor = t->t_defattr.ta_bgcolor;
 1188                         break;
 1189                 case 90: /* Set bright foreground color: black */
 1190                 case 91: /* Set bright foreground color: red */
 1191                 case 92: /* Set bright foreground color: green */
 1192                 case 93: /* Set bright foreground color: brown */
 1193                 case 94: /* Set bright foreground color: blue */
 1194                 case 95: /* Set bright foreground color: magenta */
 1195                 case 96: /* Set bright foreground color: cyan */
 1196                 case 97: /* Set bright foreground color: white */
 1197                         t->t_curattr.ta_fgcolor = n - 90 + 8;
 1198                         break;
 1199                 case 100: /* Set bright background color: black */
 1200                 case 101: /* Set bright background color: red */
 1201                 case 102: /* Set bright background color: green */
 1202                 case 103: /* Set bright background color: brown */
 1203                 case 104: /* Set bright background color: blue */
 1204                 case 105: /* Set bright background color: magenta */
 1205                 case 106: /* Set bright background color: cyan */
 1206                 case 107: /* Set bright background color: white */
 1207                         t->t_curattr.ta_bgcolor = n - 100 + 8;
 1208                         break;
 1209                 default:
 1210                         teken_printf("unsupported attribute %u\n", n);
 1211                 }
 1212         }
 1213 }
 1214 
 1215 static void
 1216 teken_subr_set_top_and_bottom_margins(teken_t *t, unsigned int top,
 1217     unsigned int bottom)
 1218 {
 1219 
 1220         /* Adjust top row number. */
 1221         if (top > 0)
 1222                 top--;
 1223         /* Adjust bottom row number. */
 1224         if (bottom == 0 || bottom > t->t_winsize.tp_row)
 1225                 bottom = t->t_winsize.tp_row;
 1226 
 1227         /* Invalid arguments. */
 1228         if (top >= bottom - 1) {
 1229                 top = 0;
 1230                 bottom = t->t_winsize.tp_row;
 1231         }
 1232 
 1233         /* Apply scrolling region. */
 1234         t->t_scrollreg.ts_begin = top;
 1235         t->t_scrollreg.ts_end = bottom;
 1236         if (t->t_stateflags & TS_ORIGIN)
 1237                 t->t_originreg = t->t_scrollreg;
 1238 
 1239         /* Home cursor to the top left of the scrolling region. */
 1240         t->t_cursor.tp_row = t->t_originreg.ts_begin;
 1241         t->t_cursor.tp_col = 0;
 1242         t->t_stateflags &= ~TS_WRAPPED;
 1243         teken_funcs_cursor(t);
 1244 }
 1245 
 1246 static void
 1247 teken_subr_single_height_double_width_line(teken_t *t __unused)
 1248 {
 1249 
 1250         teken_printf("single height double width???\n");
 1251 }
 1252 
 1253 static void
 1254 teken_subr_single_height_single_width_line(teken_t *t __unused)
 1255 {
 1256 
 1257         teken_printf("single height single width???\n");
 1258 }
 1259 
 1260 static void
 1261 teken_subr_string_terminator(teken_t *t __unused)
 1262 {
 1263 
 1264         /*
 1265          * Strings are already terminated in teken_input_char() when ^[
 1266          * is inserted.
 1267          */
 1268 }
 1269 
 1270 static void
 1271 teken_subr_tab_clear(teken_t *t, unsigned int cmd)
 1272 {
 1273 
 1274         switch (cmd) {
 1275         case 0:
 1276                 teken_tab_clear(t, t->t_cursor.tp_col);
 1277                 break;
 1278         case 3:
 1279                 memset(&t->t_tabstops, 0, T_NUMCOL / 8);
 1280                 break;
 1281         }
 1282 }
 1283 
 1284 static void
 1285 teken_subr_vertical_position_absolute(teken_t *t, unsigned int row)
 1286 {
 1287 
 1288         t->t_cursor.tp_row = t->t_originreg.ts_begin + row - 1;
 1289         if (t->t_cursor.tp_row >= t->t_originreg.ts_end)
 1290                 t->t_cursor.tp_row = t->t_originreg.ts_end - 1;
 1291 
 1292         t->t_stateflags &= ~TS_WRAPPED;
 1293         teken_funcs_cursor(t);
 1294 }

Cache object: 8a45826d9456545fe3cf1f8602238df7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.