"Fossies" - the Fresh Open Source Software Archive

Member "tmux-3.2a/tty-features.c" (10 Jun 2021, 9418 Bytes) of package /linux/misc/tmux-3.2a.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "tty-features.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.2_vs_3.2a.

    1 /* $OpenBSD$ */
    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  * - default colours (under AX or op capabilities);
   29  * - AIX colours (under colors >= 16);
   30  * - alternate escape (if terminal is VT100-like).
   31  *
   32  * Also:
   33  * - DECFRA uses a flag instead of capabilities;
   34  * - UTF-8 is a separate flag on the client; needed for unattached clients.
   35  */
   36 
   37 /* A named terminal feature. */
   38 struct tty_feature {
   39     const char   *name;
   40     const char  **capabilities;
   41     int       flags;
   42 };
   43 
   44 /* Terminal has xterm(1) title setting. */
   45 static const char *tty_feature_title_capabilities[] = {
   46     "tsl=\\E]0;", /* should be using TS really */
   47     "fsl=\\a",
   48     NULL
   49 };
   50 static const struct tty_feature tty_feature_title = {
   51     "title",
   52     tty_feature_title_capabilities,
   53     0
   54 };
   55 
   56 /* Terminal has mouse support. */
   57 static const char *tty_feature_mouse_capabilities[] = {
   58     "kmous=\\E[M",
   59     NULL
   60 };
   61 static const struct tty_feature tty_feature_mouse = {
   62     "mouse",
   63     tty_feature_mouse_capabilities,
   64     0
   65 };
   66 
   67 /* Terminal can set the clipboard with OSC 52. */
   68 static const char *tty_feature_clipboard_capabilities[] = {
   69     "Ms=\\E]52;%p1%s;%p2%s\\a",
   70     NULL
   71 };
   72 static const struct tty_feature tty_feature_clipboard = {
   73     "clipboard",
   74     tty_feature_clipboard_capabilities,
   75     0
   76 };
   77 
   78 /*
   79  * Terminal supports RGB colour. This replaces setab and setaf also since
   80  * terminals with RGB have versions that do not allow setting colours from the
   81  * 256 palette.
   82  */
   83 static const char *tty_feature_rgb_capabilities[] = {
   84     "AX",
   85     "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm",
   86     "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm",
   87     "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
   88     "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
   89     NULL
   90 };
   91 static const struct tty_feature tty_feature_rgb = {
   92     "RGB",
   93     tty_feature_rgb_capabilities,
   94     TERM_256COLOURS|TERM_RGBCOLOURS
   95 };
   96 
   97 /* Terminal supports 256 colours. */
   98 static const char *tty_feature_256_capabilities[] = {
   99     "AX",
  100     "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
  101     "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
  102     NULL
  103 };
  104 static const struct tty_feature tty_feature_256 = {
  105     "256",
  106     tty_feature_256_capabilities,
  107     TERM_256COLOURS
  108 };
  109 
  110 /* Terminal supports overline. */
  111 static const char *tty_feature_overline_capabilities[] = {
  112     "Smol=\\E[53m",
  113     NULL
  114 };
  115 static const struct tty_feature tty_feature_overline = {
  116     "overline",
  117     tty_feature_overline_capabilities,
  118     0
  119 };
  120 
  121 /* Terminal supports underscore styles. */
  122 static const char *tty_feature_usstyle_capabilities[] = {
  123     "Smulx=\\E[4::%p1%dm",
  124     "Setulc=\\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m",
  125     "ol=\\E[59m",
  126     NULL
  127 };
  128 static const struct tty_feature tty_feature_usstyle = {
  129     "usstyle",
  130     tty_feature_usstyle_capabilities,
  131     0
  132 };
  133 
  134 /* Terminal supports bracketed paste. */
  135 static const char *tty_feature_bpaste_capabilities[] = {
  136     "Enbp=\\E[?2004h",
  137     "Dsbp=\\E[?2004l",
  138     NULL
  139 };
  140 static const struct tty_feature tty_feature_bpaste = {
  141     "bpaste",
  142     tty_feature_bpaste_capabilities,
  143     0
  144 };
  145 
  146 /* Terminal supports focus reporting. */
  147 static const char *tty_feature_focus_capabilities[] = {
  148     "Enfcs=\\E[?1004h",
  149     "Dsfcs=\\E[?1004l",
  150     NULL
  151 };
  152 static const struct tty_feature tty_feature_focus = {
  153     "focus",
  154     tty_feature_focus_capabilities,
  155     0
  156 };
  157 
  158 /* Terminal supports cursor styles. */
  159 static const char *tty_feature_cstyle_capabilities[] = {
  160     "Ss=\\E[%p1%d q",
  161     "Se=\\E[2 q",
  162     NULL
  163 };
  164 static const struct tty_feature tty_feature_cstyle = {
  165     "cstyle",
  166     tty_feature_cstyle_capabilities,
  167     0
  168 };
  169 
  170 /* Terminal supports cursor colours. */
  171 static const char *tty_feature_ccolour_capabilities[] = {
  172     "Cs=\\E]12;%p1%s\\a",
  173     "Cr=\\E]112\\a",
  174     NULL
  175 };
  176 static const struct tty_feature tty_feature_ccolour = {
  177     "ccolour",
  178     tty_feature_ccolour_capabilities,
  179     0
  180 };
  181 
  182 /* Terminal supports strikethrough. */
  183 static const char *tty_feature_strikethrough_capabilities[] = {
  184     "smxx=\\E[9m",
  185     NULL
  186 };
  187 static const struct tty_feature tty_feature_strikethrough = {
  188     "strikethrough",
  189     tty_feature_strikethrough_capabilities,
  190     0
  191 };
  192 
  193 /* Terminal supports synchronized updates. */
  194 static const char *tty_feature_sync_capabilities[] = {
  195     "Sync=\\EP=%p1%ds\\E\\\\",
  196     NULL
  197 };
  198 static const struct tty_feature tty_feature_sync = {
  199     "sync",
  200     tty_feature_sync_capabilities,
  201     0
  202 };
  203 
  204 /* Terminal supports extended keys. */
  205 static const char *tty_feature_extkeys_capabilities[] = {
  206     "Eneks=\\E[>4;1m",
  207     "Dseks=\\E[>4m",
  208     NULL
  209 };
  210 static const struct tty_feature tty_feature_extkeys = {
  211     "extkeys",
  212     tty_feature_extkeys_capabilities,
  213     0
  214 };
  215 
  216 /* Terminal supports DECSLRM margins. */
  217 static const char *tty_feature_margins_capabilities[] = {
  218     "Enmg=\\E[?69h",
  219     "Dsmg=\\E[?69l",
  220     "Clmg=\\E[s",
  221     "Cmg=\\E[%i%p1%d;%p2%ds",
  222     NULL
  223 };
  224 static const struct tty_feature tty_feature_margins = {
  225     "margins",
  226     tty_feature_margins_capabilities,
  227     TERM_DECSLRM
  228 };
  229 
  230 /* Terminal supports DECFRA rectangle fill. */
  231 static const char *tty_feature_rectfill_capabilities[] = {
  232     "Rect",
  233     NULL
  234 };
  235 static const struct tty_feature tty_feature_rectfill = {
  236     "rectfill",
  237     tty_feature_rectfill_capabilities,
  238     TERM_DECFRA
  239 };
  240 
  241 /* Available terminal features. */
  242 static const struct tty_feature *tty_features[] = {
  243     &tty_feature_256,
  244     &tty_feature_bpaste,
  245     &tty_feature_ccolour,
  246     &tty_feature_clipboard,
  247     &tty_feature_cstyle,
  248     &tty_feature_extkeys,
  249     &tty_feature_focus,
  250     &tty_feature_margins,
  251     &tty_feature_mouse,
  252     &tty_feature_overline,
  253     &tty_feature_rectfill,
  254     &tty_feature_rgb,
  255     &tty_feature_strikethrough,
  256     &tty_feature_sync,
  257     &tty_feature_title,
  258     &tty_feature_usstyle
  259 };
  260 
  261 void
  262 tty_add_features(int *feat, const char *s, const char *separators)
  263 {
  264     const struct tty_feature     *tf;
  265     char                 *next, *loop, *copy;
  266     u_int                 i;
  267 
  268     log_debug("adding terminal features %s", s);
  269 
  270     loop = copy = xstrdup(s);
  271     while ((next = strsep(&loop, separators)) != NULL) {
  272         for (i = 0; i < nitems(tty_features); i++) {
  273             tf = tty_features[i];
  274             if (strcasecmp(tf->name, next) == 0)
  275                 break;
  276         }
  277         if (i == nitems(tty_features)) {
  278             log_debug("unknown terminal feature: %s", next);
  279             break;
  280         }
  281         if (~(*feat) & (1 << i)) {
  282             log_debug("adding terminal feature: %s", tf->name);
  283             (*feat) |= (1 << i);
  284         }
  285     }
  286     free(copy);
  287 }
  288 
  289 const char *
  290 tty_get_features(int feat)
  291 {
  292     const struct tty_feature    *tf;
  293     static char          s[512];
  294     u_int                i;
  295 
  296     *s = '\0';
  297     for (i = 0; i < nitems(tty_features); i++) {
  298         if (~feat & (1 << i))
  299             continue;
  300         tf = tty_features[i];
  301 
  302         strlcat(s, tf->name, sizeof s);
  303         strlcat(s, ",", sizeof s);
  304     }
  305     if (*s != '\0')
  306         s[strlen(s) - 1] = '\0';
  307     return (s);
  308 }
  309 
  310 int
  311 tty_apply_features(struct tty_term *term, int feat)
  312 {
  313     const struct tty_feature     *tf;
  314     const char          **capability;
  315     u_int                 i;
  316 
  317     if (feat == 0)
  318         return (0);
  319     log_debug("applying terminal features: %s", tty_get_features(feat));
  320 
  321     for (i = 0; i < nitems(tty_features); i++) {
  322         if ((term->features & (1 << i)) || (~feat & (1 << i)))
  323             continue;
  324         tf = tty_features[i];
  325 
  326         log_debug("applying terminal feature: %s", tf->name);
  327         if (tf->capabilities != NULL) {
  328             capability = tf->capabilities;
  329             while (*capability != NULL) {
  330                 log_debug("adding capability: %s", *capability);
  331                 tty_term_apply(term, *capability, 1);
  332                 capability++;
  333             }
  334         }
  335         term->flags |= tf->flags;
  336     }
  337     if ((term->features | feat) == term->features)
  338         return (0);
  339     term->features |= feat;
  340     return (1);
  341 }
  342 
  343 void
  344 tty_default_features(int *feat, const char *name, u_int version)
  345 {
  346     static struct {
  347         const char  *name;
  348         u_int        version;
  349         const char  *features;
  350     } table[] = {
  351 #define TTY_FEATURES_BASE_MODERN_XTERM \
  352     "256,RGB,bpaste,clipboard,mouse,strikethrough,title"
  353         { .name = "mintty",
  354           .features = TTY_FEATURES_BASE_MODERN_XTERM
  355                   ",ccolour,cstyle,extkeys,margins,overline,usstyle"
  356         },
  357         { .name = "tmux",
  358           .features = TTY_FEATURES_BASE_MODERN_XTERM
  359                   ",ccolour,cstyle,focus,overline,usstyle"
  360         },
  361         { .name = "rxvt-unicode",
  362           .features = "256,bpaste,ccolour,cstyle,mouse,title"
  363         },
  364         { .name = "iTerm2",
  365           .features = TTY_FEATURES_BASE_MODERN_XTERM
  366                   ",cstyle,extkeys,margins,sync"
  367         },
  368         { .name = "XTerm",
  369           /*
  370            * xterm also supports DECSLRM and DECFRA, but they can be
  371            * disabled so not set it here - they will be added if
  372            * secondary DA shows VT420.
  373            */
  374           .features = TTY_FEATURES_BASE_MODERN_XTERM
  375                   ",ccolour,cstyle,extkeys,focus"
  376         }
  377     };
  378     u_int   i;
  379 
  380     for (i = 0; i < nitems(table); i++) {
  381         if (strcmp(table[i].name, name) != 0)
  382             continue;
  383         if (version != 0 && version < table[i].version)
  384             continue;
  385         tty_add_features(feat, table[i].features, ",");
  386     }
  387 }