[BACK]Return to tty-acs.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/tty-acs.c, Revision 1.13

1.13    ! nicm        1: /* $OpenBSD: tty-acs.c,v 1.12 2021/10/18 09:15:56 nicm Exp $ */
1.1       nicm        2:
                      3: /*
1.4       nicm        4:  * Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1       nicm        5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/types.h>
                     20:
                     21: #include <stdlib.h>
1.10      nicm       22: #include <string.h>
1.1       nicm       23:
                     24: #include "tmux.h"
                     25:
                     26: /* Table mapping ACS entries to UTF-8. */
                     27: struct tty_acs_entry {
1.12      nicm       28:        u_char           key;
1.1       nicm       29:        const char      *string;
                     30: };
1.5       nicm       31: static const struct tty_acs_entry tty_acs_table[] = {
1.2       nicm       32:        { '+', "\342\206\222" },        /* arrow pointing right */
                     33:        { ',', "\342\206\220" },        /* arrow pointing left */
                     34:        { '-', "\342\206\221" },        /* arrow pointing up */
                     35:        { '.', "\342\206\223" },        /* arrow pointing down */
                     36:        { '0', "\342\226\256" },        /* solid square block */
                     37:        { '`', "\342\227\206" },        /* diamond */
                     38:        { 'a', "\342\226\222" },        /* checker board (stipple) */
1.7       nicm       39:        { 'b', "\342\220\211" },
                     40:        { 'c', "\342\220\214" },
                     41:        { 'd', "\342\220\215" },
                     42:        { 'e', "\342\220\212" },
1.2       nicm       43:        { 'f', "\302\260" },            /* degree symbol */
                     44:        { 'g', "\302\261" },            /* plus/minus */
1.7       nicm       45:        { 'h', "\342\220\244" },
                     46:        { 'i', "\342\220\213" },
1.2       nicm       47:        { 'j', "\342\224\230" },        /* lower right corner */
                     48:        { 'k', "\342\224\220" },        /* upper right corner */
                     49:        { 'l', "\342\224\214" },        /* upper left corner */
                     50:        { 'm', "\342\224\224" },        /* lower left corner */
                     51:        { 'n', "\342\224\274" },        /* large plus or crossover */
                     52:        { 'o', "\342\216\272" },        /* scan line 1 */
                     53:        { 'p', "\342\216\273" },        /* scan line 3 */
                     54:        { 'q', "\342\224\200" },        /* horizontal line */
                     55:        { 'r', "\342\216\274" },        /* scan line 7 */
                     56:        { 's', "\342\216\275" },        /* scan line 9 */
                     57:        { 't', "\342\224\234" },        /* tee pointing right */
                     58:        { 'u', "\342\224\244" },        /* tee pointing left */
                     59:        { 'v', "\342\224\264" },        /* tee pointing up */
                     60:        { 'w', "\342\224\254" },        /* tee pointing down */
                     61:        { 'x', "\342\224\202" },        /* vertical line */
                     62:        { 'y', "\342\211\244" },        /* less-than-or-equal-to */
                     63:        { 'z', "\342\211\245" },        /* greater-than-or-equal-to */
1.12      nicm       64:        { '{', "\317\200" },            /* greek pi */
1.2       nicm       65:        { '|', "\342\211\240" },        /* not-equal */
                     66:        { '}', "\302\243" },            /* UK pound sign */
                     67:        { '~', "\302\267" }             /* bullet */
1.1       nicm       68: };
                     69:
1.10      nicm       70: /* Table mapping UTF-8 to ACS entries. */
                     71: struct tty_acs_reverse_entry {
                     72:        const char      *string;
                     73:        u_char           key;
                     74: };
                     75: static const struct tty_acs_reverse_entry tty_acs_reverse2[] = {
                     76:        { "\302\267", '~' }
                     77: };
                     78: static const struct tty_acs_reverse_entry tty_acs_reverse3[] = {
                     79:        { "\342\224\200", 'q' },
                     80:        { "\342\224\201", 'q' },
                     81:        { "\342\224\202", 'x' },
                     82:        { "\342\224\203", 'x' },
                     83:        { "\342\224\214", 'l' },
                     84:        { "\342\224\217", 'k' },
                     85:        { "\342\224\220", 'k' },
                     86:        { "\342\224\223", 'l' },
                     87:        { "\342\224\224", 'm' },
                     88:        { "\342\224\227", 'm' },
                     89:        { "\342\224\230", 'j' },
                     90:        { "\342\224\233", 'j' },
                     91:        { "\342\224\234", 't' },
                     92:        { "\342\224\243", 't' },
                     93:        { "\342\224\244", 'u' },
                     94:        { "\342\224\253", 'u' },
                     95:        { "\342\224\263", 'w' },
                     96:        { "\342\224\264", 'v' },
                     97:        { "\342\224\273", 'v' },
                     98:        { "\342\224\274", 'n' },
                     99:        { "\342\225\213", 'n' },
                    100:        { "\342\225\220", 'q' },
                    101:        { "\342\225\221", 'x' },
                    102:        { "\342\225\224", 'l' },
                    103:        { "\342\225\227", 'k' },
                    104:        { "\342\225\232", 'm' },
                    105:        { "\342\225\235", 'j' },
                    106:        { "\342\225\240", 't' },
                    107:        { "\342\225\243", 'u' },
                    108:        { "\342\225\246", 'w' },
                    109:        { "\342\225\251", 'v' },
                    110:        { "\342\225\254", 'n' },
                    111: };
1.11      nicm      112:
                    113: /* UTF-8 double borders. */
                    114: static const struct utf8_data tty_acs_double_borders_list[] = {
                    115:        { "", 0, 0, 0 },
                    116:        { "\342\225\221", 0, 3, 1 }, /* U+2551 */
                    117:        { "\342\225\220", 0, 3, 1 }, /* U+2550 */
                    118:        { "\342\225\224", 0, 3, 1 }, /* U+2554 */
                    119:        { "\342\225\227", 0, 3, 1 }, /* U+2557 */
                    120:        { "\342\225\232", 0, 3, 1 }, /* U+255A */
                    121:        { "\342\225\235", 0, 3, 1 }, /* U+255D */
                    122:        { "\342\225\246", 0, 3, 1 }, /* U+2566 */
                    123:        { "\342\225\251", 0, 3, 1 }, /* U+2569 */
                    124:        { "\342\225\240", 0, 3, 1 }, /* U+2560 */
                    125:        { "\342\225\243", 0, 3, 1 }, /* U+2563 */
                    126:        { "\342\225\254", 0, 3, 1 }, /* U+256C */
1.12      nicm      127:        { "\302\267",     0, 2, 1 }  /* U+00B7 */
1.11      nicm      128: };
                    129:
                    130: /* UTF-8 heavy borders. */
                    131: static const struct utf8_data tty_acs_heavy_borders_list[] = {
                    132:        { "", 0, 0, 0 },
                    133:        { "\342\224\203", 0, 3, 1 }, /* U+2503 */
                    134:        { "\342\224\201", 0, 3, 1 }, /* U+2501 */
                    135:        { "\342\224\217", 0, 3, 1 }, /* U+250F */
                    136:        { "\342\224\223", 0, 3, 1 }, /* U+2513 */
                    137:        { "\342\224\227", 0, 3, 1 }, /* U+2517 */
                    138:        { "\342\224\233", 0, 3, 1 }, /* U+251B */
                    139:        { "\342\224\263", 0, 3, 1 }, /* U+2533 */
                    140:        { "\342\224\273", 0, 3, 1 }, /* U+253B */
                    141:        { "\342\224\243", 0, 3, 1 }, /* U+2523 */
                    142:        { "\342\224\253", 0, 3, 1 }, /* U+252B */
                    143:        { "\342\225\213", 0, 3, 1 }, /* U+254B */
1.12      nicm      144:        { "\302\267",     0, 2, 1 }  /* U+00B7 */
1.11      nicm      145: };
                    146:
                    147: /* UTF-8 rounded borders. */
                    148: static const struct utf8_data tty_acs_rounded_borders_list[] = {
1.12      nicm      149:        { "", 0, 0, 0 },
                    150:        { "\342\224\202", 0, 3, 1 }, /* U+2502 */
                    151:        { "\342\224\200", 0, 3, 1 }, /* U+2500 */
                    152:        { "\342\225\255", 0, 3, 1 }, /* U+256D */
                    153:        { "\342\225\256", 0, 3, 1 }, /* U+256E */
                    154:        { "\342\225\260", 0, 3, 1 }, /* U+2570 */
                    155:        { "\342\225\257", 0, 3, 1 }, /* U+256F */
                    156:        { "\342\224\263", 0, 3, 1 }, /* U+2533 */
                    157:        { "\342\224\273", 0, 3, 1 }, /* U+253B */
1.13    ! nicm      158:        { "\342\224\234", 0, 3, 1 }, /* U+2524 */
        !           159:        { "\342\224\244", 0, 3, 1 }, /* U+251C */
1.12      nicm      160:        { "\342\225\213", 0, 3, 1 }, /* U+254B */
                    161:        { "\302\267",     0, 2, 1 }  /* U+00B7 */
1.11      nicm      162: };
                    163:
                    164: /* Get cell border character for double style. */
                    165: const struct utf8_data *
                    166: tty_acs_double_borders(int cell_type)
                    167: {
                    168:        return (&tty_acs_double_borders_list[cell_type]);
                    169: }
                    170:
                    171: /* Get cell border character for heavy style. */
                    172: const struct utf8_data *
                    173: tty_acs_heavy_borders(int cell_type)
                    174: {
                    175:        return (&tty_acs_heavy_borders_list[cell_type]);
                    176: }
                    177:
                    178: /* Get cell border character for rounded style. */
                    179: const struct utf8_data *
                    180: tty_acs_rounded_borders(int cell_type)
                    181: {
                    182:        return (&tty_acs_rounded_borders_list[cell_type]);
                    183: }
1.10      nicm      184:
1.5       nicm      185: static int
1.1       nicm      186: tty_acs_cmp(const void *key, const void *value)
                    187: {
                    188:        const struct tty_acs_entry      *entry = value;
1.10      nicm      189:        int                              test = *(u_char *)key;
1.1       nicm      190:
1.10      nicm      191:        return (test - entry->key);
                    192: }
                    193:
                    194: static int
                    195: tty_acs_reverse_cmp(const void *key, const void *value)
                    196: {
                    197:        const struct tty_acs_reverse_entry      *entry = value;
                    198:        const char                              *test = key;
                    199:
                    200:        return (strcmp(test, entry->string));
1.1       nicm      201: }
                    202:
1.6       nicm      203: /* Should this terminal use ACS instead of UTF-8 line drawing? */
                    204: int
                    205: tty_acs_needed(struct tty *tty)
                    206: {
                    207:        if (tty == NULL)
                    208:                return (0);
                    209:
                    210:        /*
                    211:         * If the U8 flag is present, it marks whether a terminal supports
                    212:         * UTF-8 and ACS together.
                    213:         *
                    214:         * If it is present and zero, we force ACS - this gives users a way to
                    215:         * turn off UTF-8 line drawing.
                    216:         *
                    217:         * If it is nonzero, we can fall through to the default and use UTF-8
                    218:         * line drawing on UTF-8 terminals.
                    219:         */
                    220:        if (tty_term_has(tty->term, TTYC_U8) &&
                    221:            tty_term_number(tty->term, TTYC_U8) == 0)
                    222:                return (1);
                    223:
1.9       nicm      224:        if (tty->client->flags & CLIENT_UTF8)
1.6       nicm      225:                return (0);
                    226:        return (1);
                    227: }
                    228:
1.10      nicm      229: /* Retrieve ACS to output as UTF-8. */
1.1       nicm      230: const char *
                    231: tty_acs_get(struct tty *tty, u_char ch)
                    232: {
1.10      nicm      233:        const struct tty_acs_entry      *entry;
1.1       nicm      234:
1.6       nicm      235:        /* Use the ACS set instead of UTF-8 if needed. */
                    236:        if (tty_acs_needed(tty)) {
1.1       nicm      237:                if (tty->term->acs[ch][0] == '\0')
                    238:                        return (NULL);
                    239:                return (&tty->term->acs[ch][0]);
                    240:        }
                    241:
                    242:        /* Otherwise look up the UTF-8 translation. */
1.6       nicm      243:        entry = bsearch(&ch, tty_acs_table, nitems(tty_acs_table),
                    244:            sizeof tty_acs_table[0], tty_acs_cmp);
1.1       nicm      245:        if (entry == NULL)
                    246:                return (NULL);
                    247:        return (entry->string);
1.10      nicm      248: }
                    249:
                    250: /* Reverse UTF-8 into ACS. */
                    251: int
                    252: tty_acs_reverse_get(__unused struct tty *tty, const char *s, size_t slen)
                    253: {
                    254:        const struct tty_acs_reverse_entry      *table, *entry;
                    255:        u_int                                    items;
                    256:
                    257:        if (slen == 2) {
                    258:                table = tty_acs_reverse2;
                    259:                items = nitems(tty_acs_reverse2);
                    260:        } else if (slen == 3) {
                    261:                table = tty_acs_reverse3;
                    262:                items = nitems(tty_acs_reverse3);
                    263:        } else
                    264:                return (-1);
                    265:        entry = bsearch(s, table, items, sizeof table[0], tty_acs_reverse_cmp);
                    266:        if (entry == NULL)
                    267:                return (-1);
                    268:        return (entry->key);
1.1       nicm      269: }