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

Annotation of src/usr.bin/tmux/tty-features.c, Revision 1.4

1.4     ! nicm        1: /* $OpenBSD: tty-features.c,v 1.3 2020/04/20 15:37:32 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com>
                      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>
                     22: #include <string.h>
                     23:
                     24: #include "tmux.h"
                     25:
                     26: /*
                     27:  * Still hardcoded:
                     28:  * - bracket paste (sent if application asks for it);
                     29:  * - mouse (under kmous capability);
                     30:  * - focus events (under focus-events option);
                     31:  * - default colours (under AX or op capabilities);
                     32:  * - AIX colours (under colors >= 16);
                     33:  * - alternate escape (under XT).
                     34:  *
                     35:  * Also:
                     36:  * - XT is used to decide whether to send DA and DSR,
                     37:  * - DECSLRM and DECFRA use a flag instead of capabilities.
                     38:  * - UTF-8 is a separate flag on the client; needed for unattached clients.
                     39:  */
                     40:
                     41: /* A named terminal feature. */
                     42: struct tty_feature {
                     43:        const char       *name;
                     44:        const char      **capabilities;
                     45:        int               flags;
                     46: };
                     47:
                     48: /* Terminal has xterm(1) title setting. */
                     49: static const char *tty_feature_title_capabilities[] = {
                     50:        "tsl=\\E]0;", /* should be using TS really */
                     51:        "fsl=\\a",
                     52:        NULL
                     53: };
                     54: static struct tty_feature tty_feature_title = {
                     55:        "title",
                     56:        tty_feature_title_capabilities,
                     57:        0
                     58: };
                     59:
                     60: /* Terminal can set the clipboard with OSC 52. */
                     61: static const char *tty_feature_clipboard_capabilities[] = {
                     62:        "Ms=\\E]52;%p1%s;%p2%s\\a",
                     63:        NULL
                     64: };
                     65: static struct tty_feature tty_feature_clipboard = {
                     66:        "clipboard",
                     67:        tty_feature_clipboard_capabilities,
                     68:        0
                     69: };
                     70:
                     71: /*
                     72:  * Terminal supports RGB colour. This replaces setab and setaf also since
                     73:  * terminals with RGB have versions that do not allow setting colours from the
                     74:  * 256 palette.
                     75:  */
                     76: static const char *tty_feature_rgb_capabilities[] = {
1.4     ! nicm       77:        "AX",
1.1       nicm       78:        "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm",
                     79:        "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm",
                     80:        "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
                     81:        "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
                     82:        NULL
                     83: };
                     84: static struct tty_feature tty_feature_rgb = {
                     85:        "RGB",
                     86:        tty_feature_rgb_capabilities,
                     87:        (TERM_256COLOURS|TERM_RGBCOLOURS)
                     88: };
                     89:
                     90: /* Terminal supports 256 colours. */
                     91: static const char *tty_feature_256_capabilities[] = {
1.4     ! nicm       92:        "AX",
1.1       nicm       93:        "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
                     94:        "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
                     95:        NULL
                     96: };
                     97: static struct tty_feature tty_feature_256 = {
                     98:        "256",
                     99:        tty_feature_256_capabilities,
                    100:        TERM_256COLOURS
                    101: };
                    102:
                    103: /* Terminal supports overline. */
                    104: static const char *tty_feature_overline_capabilities[] = {
                    105:        "Smol=\\E[53m",
                    106:        NULL
                    107: };
                    108: static struct tty_feature tty_feature_overline = {
                    109:        "overline",
                    110:        tty_feature_overline_capabilities,
                    111:        0
                    112: };
                    113:
                    114: /* Terminal supports underscore styles. */
                    115: static const char *tty_feature_usstyle_capabilities[] = {
                    116:        "Smulx=\E[4::%p1%dm",
                    117:        "Setulc=\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m",
                    118:        NULL
                    119: };
                    120: static struct tty_feature tty_feature_usstyle = {
                    121:        "usstyle",
                    122:        tty_feature_usstyle_capabilities,
                    123:        0
                    124: };
                    125:
                    126: /* Terminal supports cursor styles. */
                    127: static const char *tty_feature_cstyle_capabilities[] = {
                    128:        "Ss=\\E[%p1%d q",
                    129:        "Se=\\E[2 q",
                    130:        NULL
                    131: };
                    132: static struct tty_feature tty_feature_cstyle = {
                    133:        "cstyle",
                    134:        tty_feature_cstyle_capabilities,
                    135:        0
                    136: };
                    137:
                    138: /* Terminal supports cursor colours. */
                    139: static const char *tty_feature_ccolour_capabilities[] = {
                    140:        "Cs=\\E]12;%p1%s\\a",
                    141:        "Cr=\\E]112\\a",
                    142:        NULL
                    143: };
                    144: static struct tty_feature tty_feature_ccolour = {
                    145:        "ccolour",
                    146:        tty_feature_ccolour_capabilities,
                    147:        0
                    148: };
                    149:
                    150: /* Terminal supports synchronized updates. */
                    151: static const char *tty_feature_sync_capabilities[] = {
1.2       nicm      152:        "Sync=\\EP=%p1%ds\\E\\\\",
1.1       nicm      153:        NULL
                    154: };
                    155: static struct tty_feature tty_feature_sync = {
                    156:        "sync",
                    157:        tty_feature_sync_capabilities,
                    158:        0
                    159: };
                    160:
                    161: /* Terminal supports DECSLRM margins. */
                    162: static struct tty_feature tty_feature_margins = {
                    163:        "margins",
                    164:        NULL,
                    165:        TERM_DECSLRM
                    166: };
                    167:
                    168: /* Terminal supports DECFRA rectangle fill. */
                    169: static struct tty_feature tty_feature_rectfill = {
                    170:        "rectfill",
                    171:        NULL,
                    172:        TERM_DECFRA
                    173: };
                    174:
                    175: /* Available terminal features. */
                    176: static const struct tty_feature *tty_features[] = {
                    177:        &tty_feature_256,
                    178:        &tty_feature_clipboard,
                    179:        &tty_feature_ccolour,
                    180:        &tty_feature_cstyle,
                    181:        &tty_feature_margins,
                    182:        &tty_feature_overline,
                    183:        &tty_feature_rectfill,
                    184:        &tty_feature_rgb,
                    185:        &tty_feature_sync,
                    186:        &tty_feature_title,
                    187:        &tty_feature_usstyle
                    188: };
                    189:
                    190: void
                    191: tty_add_features(int *feat, const char *s, const char *separators)
                    192: {
                    193:        const struct tty_feature         *tf;
                    194:        char                             *next, *loop, *copy;
                    195:        u_int                             i;
                    196:
                    197:        loop = copy = xstrdup(s);
                    198:        while ((next = strsep(&loop, separators)) != NULL) {
                    199:                for (i = 0; i < nitems(tty_features); i++) {
                    200:                        tf = tty_features[i];
                    201:                        if (strcasecmp(tf->name, next) == 0)
                    202:                                break;
                    203:                }
                    204:                if (i == nitems(tty_features)) {
                    205:                        log_debug("unknown terminal feature: %s", next);
                    206:                        break;
                    207:                }
                    208:                if (~(*feat) & (1 << i)) {
                    209:                        log_debug("adding terminal feature: %s", tf->name);
                    210:                        (*feat) |= (1 << i);
                    211:                }
                    212:        }
                    213:        free(copy);
                    214: }
                    215:
                    216: const char *
                    217: tty_get_features(int feat)
                    218: {
                    219:        const struct tty_feature        *tf;
                    220:        static char                      s[512];
                    221:        u_int                            i;
                    222:
                    223:        *s = '\0';
                    224:        for (i = 0; i < nitems(tty_features); i++) {
                    225:                if (~feat & (1 << i))
                    226:                        continue;
                    227:                tf = tty_features[i];
                    228:
                    229:                strlcat(s, tf->name, sizeof s);
                    230:                strlcat(s, ",", sizeof s);
                    231:        }
                    232:        if (*s != '\0')
                    233:                s[strlen(s) - 1] = '\0';
                    234:        return (s);
                    235: }
                    236:
1.3       nicm      237: int
1.1       nicm      238: tty_apply_features(struct tty_term *term, int feat)
                    239: {
                    240:        const struct tty_feature         *tf;
                    241:        const char                      **capability;
                    242:        u_int                             i;
                    243:
                    244:        if (feat == 0)
1.3       nicm      245:                return (0);
1.1       nicm      246:        log_debug("applying terminal features: %s", tty_get_features(feat));
                    247:
                    248:        for (i = 0; i < nitems(tty_features); i++) {
                    249:                if ((term->features & (1 << i)) || (~feat & (1 << i)))
                    250:                        continue;
                    251:                tf = tty_features[i];
                    252:
                    253:                log_debug("applying terminal feature: %s", tf->name);
                    254:                if (tf->capabilities != NULL) {
                    255:                        capability = tf->capabilities;
                    256:                        while (*capability != NULL) {
                    257:                                log_debug("adding capability: %s", *capability);
                    258:                                tty_term_apply(term, *capability, 1);
                    259:                                capability++;
                    260:                        }
                    261:                }
                    262:                term->flags |= tf->flags;
                    263:        }
1.3       nicm      264:        if ((term->features | feat) == term->features)
                    265:                return (0);
1.1       nicm      266:        term->features |= feat;
1.3       nicm      267:        return (1);
1.1       nicm      268: }