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

Cache object: 902da89948e1c4d495e763b236b47974


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