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

Cache object: 0dbccde88b93ffc82c407f472c1fc3fc


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