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.c

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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2008-2009 Ed Schouten <ed@FreeBSD.org>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * $FreeBSD: releng/12.0/sys/teken/teken.c 333683 2018-05-16 18:12:49Z cem $
   29  */
   30 
   31 #include <sys/cdefs.h>
   32 #if defined(__FreeBSD__) && defined(_KERNEL)
   33 #include <sys/param.h>
   34 #include <sys/limits.h>
   35 #include <sys/lock.h>
   36 #include <sys/systm.h>
   37 #define teken_assert(x)         MPASS(x)
   38 #else /* !(__FreeBSD__ && _KERNEL) */
   39 #include <sys/types.h>
   40 #include <assert.h>
   41 #include <limits.h>
   42 #include <stdint.h>
   43 #include <stdio.h>
   44 #include <string.h>
   45 #define teken_assert(x)         assert(x)
   46 #endif /* __FreeBSD__ && _KERNEL */
   47 
   48 /* debug messages */
   49 #define teken_printf(x,...)
   50 
   51 /* Private flags for t_stateflags. */
   52 #define TS_FIRSTDIGIT   0x0001  /* First numeric digit in escape sequence. */
   53 #define TS_INSERT       0x0002  /* Insert mode. */
   54 #define TS_AUTOWRAP     0x0004  /* Autowrap. */
   55 #define TS_ORIGIN       0x0008  /* Origin mode. */
   56 #define TS_WRAPPED      0x0010  /* Next character should be printed on col 0. */
   57 #define TS_8BIT         0x0020  /* UTF-8 disabled. */
   58 #define TS_CONS25       0x0040  /* cons25 emulation. */
   59 #define TS_INSTRING     0x0080  /* Inside string. */
   60 #define TS_CURSORKEYS   0x0100  /* Cursor keys mode. */
   61 
   62 /* Character that blanks a cell. */
   63 #define BLANK   ' '
   64 
   65 #include "teken.h"
   66 #include "teken_wcwidth.h"
   67 #include "teken_scs.h"
   68 
   69 static teken_state_t    teken_state_init;
   70 
   71 /*
   72  * Wrappers for hooks.
   73  */
   74 
   75 static inline void
   76 teken_funcs_bell(const teken_t *t)
   77 {
   78 
   79         teken_assert(t->t_funcs->tf_bell != NULL);
   80         t->t_funcs->tf_bell(t->t_softc);
   81 }
   82 
   83 static inline void
   84 teken_funcs_cursor(const teken_t *t)
   85 {
   86 
   87         teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
   88         teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
   89 
   90         teken_assert(t->t_funcs->tf_cursor != NULL);
   91         t->t_funcs->tf_cursor(t->t_softc, &t->t_cursor);
   92 }
   93 
   94 static inline void
   95 teken_funcs_putchar(const teken_t *t, const teken_pos_t *p, teken_char_t c,
   96     const teken_attr_t *a)
   97 {
   98 
   99         teken_assert(p->tp_row < t->t_winsize.tp_row);
  100         teken_assert(p->tp_col < t->t_winsize.tp_col);
  101 
  102         teken_assert(t->t_funcs->tf_putchar != NULL);
  103         t->t_funcs->tf_putchar(t->t_softc, p, c, a);
  104 }
  105 
  106 static inline void
  107 teken_funcs_fill(const teken_t *t, const teken_rect_t *r,
  108     const teken_char_t c, const teken_attr_t *a)
  109 {
  110 
  111         teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
  112         teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
  113         teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
  114         teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
  115 
  116         teken_assert(t->t_funcs->tf_fill != NULL);
  117         t->t_funcs->tf_fill(t->t_softc, r, c, a);
  118 }
  119 
  120 static inline void
  121 teken_funcs_copy(const teken_t *t, const teken_rect_t *r, const teken_pos_t *p)
  122 {
  123 
  124         teken_assert(r->tr_end.tp_row > r->tr_begin.tp_row);
  125         teken_assert(r->tr_end.tp_row <= t->t_winsize.tp_row);
  126         teken_assert(r->tr_end.tp_col > r->tr_begin.tp_col);
  127         teken_assert(r->tr_end.tp_col <= t->t_winsize.tp_col);
  128         teken_assert(p->tp_row + (r->tr_end.tp_row - r->tr_begin.tp_row) <= t->t_winsize.tp_row);
  129         teken_assert(p->tp_col + (r->tr_end.tp_col - r->tr_begin.tp_col) <= t->t_winsize.tp_col);
  130 
  131         teken_assert(t->t_funcs->tf_copy != NULL);
  132         t->t_funcs->tf_copy(t->t_softc, r, p);
  133 }
  134 
  135 static inline void
  136 teken_funcs_pre_input(const teken_t *t)
  137 {
  138 
  139         if (t->t_funcs->tf_pre_input != NULL)
  140                 t->t_funcs->tf_pre_input(t->t_softc);
  141 }
  142 
  143 static inline void
  144 teken_funcs_post_input(const teken_t *t)
  145 {
  146 
  147         if (t->t_funcs->tf_post_input != NULL)
  148                 t->t_funcs->tf_post_input(t->t_softc);
  149 }
  150 
  151 static inline void
  152 teken_funcs_param(const teken_t *t, int cmd, unsigned int value)
  153 {
  154 
  155         teken_assert(t->t_funcs->tf_param != NULL);
  156         t->t_funcs->tf_param(t->t_softc, cmd, value);
  157 }
  158 
  159 static inline void
  160 teken_funcs_respond(const teken_t *t, const void *buf, size_t len)
  161 {
  162 
  163         teken_assert(t->t_funcs->tf_respond != NULL);
  164         t->t_funcs->tf_respond(t->t_softc, buf, len);
  165 }
  166 
  167 #include "teken_subr.h"
  168 #include "teken_subr_compat.h"
  169 
  170 /*
  171  * Programming interface.
  172  */
  173 
  174 void
  175 teken_init(teken_t *t, const teken_funcs_t *tf, void *softc)
  176 {
  177         teken_pos_t tp = { .tp_row = 24, .tp_col = 80 };
  178 
  179         t->t_funcs = tf;
  180         t->t_softc = softc;
  181 
  182         t->t_nextstate = teken_state_init;
  183         t->t_stateflags = 0;
  184         t->t_utf8_left = 0;
  185 
  186         t->t_defattr.ta_format = 0;
  187         t->t_defattr.ta_fgcolor = TC_WHITE;
  188         t->t_defattr.ta_bgcolor = TC_BLACK;
  189         teken_subr_do_reset(t);
  190 
  191         teken_set_winsize(t, &tp);
  192 }
  193 
  194 static void
  195 teken_input_char(teken_t *t, teken_char_t c)
  196 {
  197 
  198         /*
  199          * There is no support for DCS and OSC.  Just discard strings
  200          * until we receive characters that may indicate string
  201          * termination.
  202          */
  203         if (t->t_stateflags & TS_INSTRING) {
  204                 switch (c) {
  205                 case '\x1B':
  206                         t->t_stateflags &= ~TS_INSTRING;
  207                         break;
  208                 case '\a':
  209                         t->t_stateflags &= ~TS_INSTRING;
  210                         return;
  211                 default:
  212                         return;
  213                 }
  214         }
  215 
  216         switch (c) {
  217         case '\0':
  218                 break;
  219         case '\a':
  220                 teken_subr_bell(t);
  221                 break;
  222         case '\b':
  223                 teken_subr_backspace(t);
  224                 break;
  225         case '\n':
  226         case '\x0B':
  227                 teken_subr_newline(t);
  228                 break;
  229         case '\x0C':
  230                 teken_subr_newpage(t);
  231                 break;
  232         case '\x0E':
  233                 if (t->t_stateflags & TS_CONS25)
  234                         t->t_nextstate(t, c);
  235                 else
  236                         t->t_curscs = 1;
  237                 break;
  238         case '\x0F':
  239                 if (t->t_stateflags & TS_CONS25)
  240                         t->t_nextstate(t, c);
  241                 else
  242                         t->t_curscs = 0;
  243                 break;
  244         case '\r':
  245                 teken_subr_carriage_return(t);
  246                 break;
  247         case '\t':
  248                 teken_subr_horizontal_tab(t);
  249                 break;
  250         default:
  251                 t->t_nextstate(t, c);
  252                 break;
  253         }
  254 
  255         /* Post-processing assertions. */
  256         teken_assert(t->t_cursor.tp_row >= t->t_originreg.ts_begin);
  257         teken_assert(t->t_cursor.tp_row < t->t_originreg.ts_end);
  258         teken_assert(t->t_cursor.tp_row < t->t_winsize.tp_row);
  259         teken_assert(t->t_cursor.tp_col < t->t_winsize.tp_col);
  260         teken_assert(t->t_saved_cursor.tp_row < t->t_winsize.tp_row);
  261         teken_assert(t->t_saved_cursor.tp_col < t->t_winsize.tp_col);
  262         teken_assert(t->t_scrollreg.ts_end <= t->t_winsize.tp_row);
  263         teken_assert(t->t_scrollreg.ts_begin < t->t_scrollreg.ts_end);
  264         /* Origin region has to be window size or the same as scrollreg. */
  265         teken_assert((t->t_originreg.ts_begin == t->t_scrollreg.ts_begin &&
  266             t->t_originreg.ts_end == t->t_scrollreg.ts_end) ||
  267             (t->t_originreg.ts_begin == 0 &&
  268             t->t_originreg.ts_end == t->t_winsize.tp_row));
  269 }
  270 
  271 static void
  272 teken_input_byte(teken_t *t, unsigned char c)
  273 {
  274 
  275         /*
  276          * UTF-8 handling.
  277          */
  278         if ((c & 0x80) == 0x00 || t->t_stateflags & TS_8BIT) {
  279                 /* One-byte sequence. */
  280                 t->t_utf8_left = 0;
  281                 teken_input_char(t, c);
  282         } else if ((c & 0xe0) == 0xc0) {
  283                 /* Two-byte sequence. */
  284                 t->t_utf8_left = 1;
  285                 t->t_utf8_partial = c & 0x1f;
  286         } else if ((c & 0xf0) == 0xe0) {
  287                 /* Three-byte sequence. */
  288                 t->t_utf8_left = 2;
  289                 t->t_utf8_partial = c & 0x0f;
  290         } else if ((c & 0xf8) == 0xf0) {
  291                 /* Four-byte sequence. */
  292                 t->t_utf8_left = 3;
  293                 t->t_utf8_partial = c & 0x07;
  294         } else if ((c & 0xc0) == 0x80) {
  295                 if (t->t_utf8_left == 0)
  296                         return;
  297                 t->t_utf8_left--;
  298                 t->t_utf8_partial = (t->t_utf8_partial << 6) | (c & 0x3f);
  299                 if (t->t_utf8_left == 0) {
  300                         teken_printf("Got UTF-8 char %x\n", t->t_utf8_partial);
  301                         teken_input_char(t, t->t_utf8_partial);
  302                 }
  303         }
  304 }
  305 
  306 void
  307 teken_input(teken_t *t, const void *buf, size_t len)
  308 {
  309         const char *c = buf;
  310 
  311         teken_funcs_pre_input(t);
  312         while (len-- > 0)
  313                 teken_input_byte(t, *c++);
  314         teken_funcs_post_input(t);
  315 }
  316 
  317 const teken_pos_t *
  318 teken_get_cursor(const teken_t *t)
  319 {
  320 
  321         return (&t->t_cursor);
  322 }
  323 
  324 void
  325 teken_set_cursor(teken_t *t, const teken_pos_t *p)
  326 {
  327 
  328         /* XXX: bounds checking with originreg! */
  329         teken_assert(p->tp_row < t->t_winsize.tp_row);
  330         teken_assert(p->tp_col < t->t_winsize.tp_col);
  331 
  332         t->t_cursor = *p;
  333 }
  334 
  335 const teken_attr_t *
  336 teken_get_curattr(const teken_t *t)
  337 {
  338 
  339         return (&t->t_curattr);
  340 }
  341 
  342 void
  343 teken_set_curattr(teken_t *t, const teken_attr_t *a)
  344 {
  345 
  346         t->t_curattr = *a;
  347 }
  348 
  349 const teken_attr_t *
  350 teken_get_defattr(const teken_t *t)
  351 {
  352 
  353         return (&t->t_defattr);
  354 }
  355 
  356 void
  357 teken_set_defattr(teken_t *t, const teken_attr_t *a)
  358 {
  359 
  360         t->t_curattr = t->t_saved_curattr = t->t_defattr = *a;
  361 }
  362 
  363 const teken_pos_t *
  364 teken_get_winsize(const teken_t *t)
  365 {
  366 
  367         return (&t->t_winsize);
  368 }
  369 
  370 static void
  371 teken_trim_cursor_pos(teken_t *t, const teken_pos_t *new)
  372 {
  373         const teken_pos_t *cur;
  374 
  375         cur = &t->t_winsize;
  376 
  377         if (cur->tp_row < new->tp_row || cur->tp_col < new->tp_col)
  378                 return;
  379         if (t->t_cursor.tp_row >= new->tp_row)
  380                 t->t_cursor.tp_row = new->tp_row - 1;
  381         if (t->t_cursor.tp_col >= new->tp_col)
  382                 t->t_cursor.tp_col = new->tp_col - 1;
  383 }
  384 
  385 void
  386 teken_set_winsize(teken_t *t, const teken_pos_t *p)
  387 {
  388 
  389         teken_trim_cursor_pos(t, p);
  390         t->t_winsize = *p;
  391         teken_subr_do_reset(t);
  392 }
  393 
  394 void
  395 teken_set_winsize_noreset(teken_t *t, const teken_pos_t *p)
  396 {
  397 
  398         teken_trim_cursor_pos(t, p);
  399         t->t_winsize = *p;
  400         teken_subr_do_resize(t);
  401 }
  402 
  403 void
  404 teken_set_8bit(teken_t *t)
  405 {
  406 
  407         t->t_stateflags |= TS_8BIT;
  408 }
  409 
  410 void
  411 teken_set_cons25(teken_t *t)
  412 {
  413 
  414         t->t_stateflags |= TS_CONS25;
  415 }
  416 
  417 /*
  418  * State machine.
  419  */
  420 
  421 static void
  422 teken_state_switch(teken_t *t, teken_state_t *s)
  423 {
  424 
  425         t->t_nextstate = s;
  426         t->t_curnum = 0;
  427         t->t_stateflags |= TS_FIRSTDIGIT;
  428 }
  429 
  430 static int
  431 teken_state_numbers(teken_t *t, teken_char_t c)
  432 {
  433 
  434         teken_assert(t->t_curnum < T_NUMSIZE);
  435 
  436         if (c >= '' && c <= '9') {
  437                 if (t->t_stateflags & TS_FIRSTDIGIT) {
  438                         /* First digit. */
  439                         t->t_stateflags &= ~TS_FIRSTDIGIT;
  440                         t->t_nums[t->t_curnum] = c - '';
  441                 } else if (t->t_nums[t->t_curnum] < UINT_MAX / 100) {
  442                         /*
  443                          * There is no need to continue parsing input
  444                          * once the value exceeds the size of the
  445                          * terminal. It would only allow for integer
  446                          * overflows when performing arithmetic on the
  447                          * cursor position.
  448                          *
  449                          * Ignore any further digits if the value is
  450                          * already UINT_MAX / 100.
  451                          */
  452                         t->t_nums[t->t_curnum] =
  453                             t->t_nums[t->t_curnum] * 10 + c - '';
  454                 }
  455                 return (1);
  456         } else if (c == ';') {
  457                 if (t->t_stateflags & TS_FIRSTDIGIT)
  458                         t->t_nums[t->t_curnum] = 0;
  459 
  460                 /* Only allow a limited set of arguments. */
  461                 if (++t->t_curnum == T_NUMSIZE) {
  462                         teken_state_switch(t, teken_state_init);
  463                         return (1);
  464                 }
  465 
  466                 t->t_stateflags |= TS_FIRSTDIGIT;
  467                 return (1);
  468         } else {
  469                 if (t->t_stateflags & TS_FIRSTDIGIT && t->t_curnum > 0) {
  470                         /* Finish off the last empty argument. */
  471                         t->t_nums[t->t_curnum] = 0;
  472                         t->t_curnum++;
  473                 } else if ((t->t_stateflags & TS_FIRSTDIGIT) == 0) {
  474                         /* Also count the last argument. */
  475                         t->t_curnum++;
  476                 }
  477         }
  478 
  479         return (0);
  480 }
  481 
  482 #define k       TC_BLACK
  483 #define b       TC_BLUE
  484 #define y       TC_BROWN
  485 #define c       TC_CYAN
  486 #define g       TC_GREEN
  487 #define m       TC_MAGENTA
  488 #define r       TC_RED
  489 #define w       TC_WHITE
  490 #define K       (TC_BLACK | TC_LIGHT)
  491 #define B       (TC_BLUE | TC_LIGHT)
  492 #define Y       (TC_BROWN | TC_LIGHT)
  493 #define C       (TC_CYAN | TC_LIGHT)
  494 #define G       (TC_GREEN | TC_LIGHT)
  495 #define M       (TC_MAGENTA | TC_LIGHT)
  496 #define R       (TC_RED | TC_LIGHT)
  497 #define W       (TC_WHITE | TC_LIGHT)
  498 
  499 /**
  500  * The xterm-256 color map has steps of 0x28 (in the range 0-0xff), except
  501  * for the first step which is 0x5f.  Scale to the range 0-6 by dividing
  502  * by 0x28 and rounding down.  The range of 0-5 cannot represent the
  503  * larger first step.
  504  *
  505  * This table is generated by the follow rules:
  506  * - if all components are equal, the result is black for (0, 0, 0) and
  507  *   (2, 2, 2), else white; otherwise:
  508  * - subtract the smallest component from all components
  509  * - if this gives only one nonzero component, then that is the color
  510  * - else if one component is 2 or more larger than the other nonzero one,
  511  *   then that component gives the color
  512  * - else there are 2 nonzero components.  The color is that of a small
  513  *   equal mixture of these components (cyan, yellow or magenta).  E.g.,
  514  *   (0, 5, 6) (Turquoise2) is a much purer cyan than (0, 2, 3)
  515  *   (DeepSkyBlue4), but we map both to cyan since we can't represent
  516  *   delicate shades of either blue or cyan and blue would be worse.
  517  *   Here it is important that components of 1 never occur.  Blue would
  518  *   be twice as large as green in (0, 1, 2).
  519  */
  520 static const teken_color_t teken_256to8tab[] = {
  521         /* xterm normal colors: */
  522         k, r, g, y, b, m, c, w,
  523 
  524         /* xterm bright colors: */
  525         k, r, g, y, b, m, c, w,
  526 
  527         /* Red0 submap. */
  528         k, b, b, b, b, b,
  529         g, c, c, b, b, b,
  530         g, c, c, c, b, b,
  531         g, g, c, c, c, b,
  532         g, g, g, c, c, c,
  533         g, g, g, g, c, c,
  534 
  535         /* Red2 submap. */
  536         r, m, m, b, b, b,
  537         y, k, b, b, b, b,
  538         y, g, c, c, b, b,
  539         g, g, c, c, c, b,
  540         g, g, g, c, c, c,
  541         g, g, g, g, c, c,
  542 
  543         /* Red3 submap. */
  544         r, m, m, m, b, b,
  545         y, r, m, m, b, b,
  546         y, y, w, b, b, b,
  547         y, y, g, c, c, b,
  548         g, g, g, c, c, c,
  549         g, g, g, g, c, c,
  550 
  551         /* Red4 submap. */
  552         r, r, m, m, m, b,
  553         r, r, m, m, m, b,
  554         y, y, r, m, m, b,
  555         y, y, y, w, b, b,
  556         y, y, y, g, c, c,
  557         g, g, g, g, c, c,
  558 
  559         /* Red5 submap. */
  560         r, r, r, m, m, m,
  561         r, r, r, m, m, m,
  562         r, r, r, m, m, m,
  563         y, y, y, r, m, m,
  564         y, y, y, y, w, b,
  565         y, y, y, y, g, c,
  566 
  567         /* Red6 submap. */
  568         r, r, r, r, m, m,
  569         r, r, r, r, m, m,
  570         r, r, r, r, m, m,
  571         r, r, r, r, m, m,
  572         y, y, y, y, r, m,
  573         y, y, y, y, y, w,
  574 
  575         /* Grey submap. */
  576         k, k, k, k, k, k,
  577         k, k, k, k, k, k,
  578         w, w, w, w, w, w,
  579         w, w, w, w, w, w,
  580 };
  581 
  582 /*
  583  * This table is generated from the previous one by setting TC_LIGHT for
  584  * entries whose luminosity in the xterm256 color map is 60% or larger.
  585  * Thus the previous table is currently not really needed.  It will be
  586  * used for different fine tuning of the tables.
  587  */
  588 static const teken_color_t teken_256to16tab[] = {
  589         /* xterm normal colors: */
  590         k, r, g, y, b, m, c, w,
  591 
  592         /* xterm bright colors: */
  593         K, R, G, Y, B, M, C, W,
  594 
  595         /* Red0 submap. */
  596         k, b, b, b, b, b,
  597         g, c, c, b, b, b,
  598         g, c, c, c, b, b,
  599         g, g, c, c, c, b,
  600         g, g, g, c, c, c,
  601         g, g, g, g, c, c,
  602 
  603         /* Red2 submap. */
  604         r, m, m, b, b, b,
  605         y, K, b, b, B, B,
  606         y, g, c, c, B, B,
  607         g, g, c, c, C, B,
  608         g, G, G, C, C, C,
  609         g, G, G, G, C, C,
  610 
  611         /* Red3 submap. */
  612         r, m, m, m, b, b,
  613         y, r, m, m, B, B,
  614         y, y, w, B, B, B,
  615         y, y, G, C, C, B,
  616         g, G, G, C, C, C,
  617         g, G, G, G, C, C,
  618 
  619         /* Red4 submap. */
  620         r, r, m, m, m, b,
  621         r, r, m, m, M, B,
  622         y, y, R, M, M, B,
  623         y, y, Y, W, B, B,
  624         y, Y, Y, G, C, C,
  625         g, G, G, G, C, C,
  626 
  627         /* Red5 submap. */
  628         r, r, r, m, m, m,
  629         r, R, R, M, M, M,
  630         r, R, R, M, M, M,
  631         y, Y, Y, R, M, M,
  632         y, Y, Y, Y, W, B,
  633         y, Y, Y, Y, G, C,
  634 
  635         /* Red6 submap. */
  636         r, r, r, r, m, m,
  637         r, R, R, R, M, M,
  638         r, R, R, R, M, M,
  639         r, R, R, R, M, M,
  640         y, Y, Y, Y, R, M,
  641         y, Y, Y, Y, Y, W,
  642 
  643         /* Grey submap. */
  644         k, k, k, k, k, k,
  645         K, K, K, K, K, K,
  646         w, w, w, w, w, w,
  647         W, W, W, W, W, W,
  648 };
  649 
  650 #undef  k
  651 #undef  b
  652 #undef  y
  653 #undef  c
  654 #undef  g
  655 #undef  m
  656 #undef  r
  657 #undef  w
  658 #undef  K
  659 #undef  B
  660 #undef  Y
  661 #undef  C
  662 #undef  G
  663 #undef  M
  664 #undef  R
  665 #undef  W
  666 
  667 teken_color_t
  668 teken_256to8(teken_color_t c)
  669 {
  670 
  671         return (teken_256to8tab[c % 256]);
  672 }
  673 
  674 teken_color_t
  675 teken_256to16(teken_color_t c)
  676 {
  677 
  678         return (teken_256to16tab[c % 256]);
  679 }
  680 
  681 static const char * const special_strings_cons25[] = {
  682         [TKEY_UP] = "\x1B[A",           [TKEY_DOWN] = "\x1B[B",
  683         [TKEY_LEFT] = "\x1B[D",         [TKEY_RIGHT] = "\x1B[C",
  684 
  685         [TKEY_HOME] = "\x1B[H",         [TKEY_END] = "\x1B[F",
  686         [TKEY_INSERT] = "\x1B[L",       [TKEY_DELETE] = "\x7F",
  687         [TKEY_PAGE_UP] = "\x1B[I",      [TKEY_PAGE_DOWN] = "\x1B[G",
  688 
  689         [TKEY_F1] = "\x1B[M",           [TKEY_F2] = "\x1B[N",
  690         [TKEY_F3] = "\x1B[O",           [TKEY_F4] = "\x1B[P",
  691         [TKEY_F5] = "\x1B[Q",           [TKEY_F6] = "\x1B[R",
  692         [TKEY_F7] = "\x1B[S",           [TKEY_F8] = "\x1B[T",
  693         [TKEY_F9] = "\x1B[U",           [TKEY_F10] = "\x1B[V",
  694         [TKEY_F11] = "\x1B[W",          [TKEY_F12] = "\x1B[X",
  695 };
  696 
  697 static const char * const special_strings_ckeys[] = {
  698         [TKEY_UP] = "\x1BOA",           [TKEY_DOWN] = "\x1BOB",
  699         [TKEY_LEFT] = "\x1BOD",         [TKEY_RIGHT] = "\x1BOC",
  700 
  701         [TKEY_HOME] = "\x1BOH",         [TKEY_END] = "\x1BOF",
  702 };
  703 
  704 static const char * const special_strings_normal[] = {
  705         [TKEY_UP] = "\x1B[A",           [TKEY_DOWN] = "\x1B[B",
  706         [TKEY_LEFT] = "\x1B[D",         [TKEY_RIGHT] = "\x1B[C",
  707 
  708         [TKEY_HOME] = "\x1B[H",         [TKEY_END] = "\x1B[F",
  709         [TKEY_INSERT] = "\x1B[2~",      [TKEY_DELETE] = "\x1B[3~",
  710         [TKEY_PAGE_UP] = "\x1B[5~",     [TKEY_PAGE_DOWN] = "\x1B[6~",
  711 
  712         [TKEY_F1] = "\x1BOP",           [TKEY_F2] = "\x1BOQ",
  713         [TKEY_F3] = "\x1BOR",           [TKEY_F4] = "\x1BOS",
  714         [TKEY_F5] = "\x1B[15~",         [TKEY_F6] = "\x1B[17~",
  715         [TKEY_F7] = "\x1B[18~",         [TKEY_F8] = "\x1B[19~",
  716         [TKEY_F9] = "\x1B[20~",         [TKEY_F10] = "\x1B[21~",
  717         [TKEY_F11] = "\x1B[23~",        [TKEY_F12] = "\x1B[24~",
  718 };
  719 
  720 const char *
  721 teken_get_sequence(const teken_t *t, unsigned int k)
  722 {
  723 
  724         /* Cons25 mode. */
  725         if (t->t_stateflags & TS_CONS25 &&
  726             k < sizeof special_strings_cons25 / sizeof(char *))
  727                 return (special_strings_cons25[k]);
  728 
  729         /* Cursor keys mode. */
  730         if (t->t_stateflags & TS_CURSORKEYS &&
  731             k < sizeof special_strings_ckeys / sizeof(char *))
  732                 return (special_strings_ckeys[k]);
  733 
  734         /* Default xterm sequences. */
  735         if (k < sizeof special_strings_normal / sizeof(char *))
  736                 return (special_strings_normal[k]);
  737 
  738         return (NULL);
  739 }
  740 
  741 #include "teken_state.h"

Cache object: 69efbc805da183e1faf65fa4e1698b6c


[ 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.