19fb66d81Schristos /* $OpenBSD$ */ 29fb66d81Schristos 39fb66d81Schristos /* 49fb66d81Schristos * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com> 59fb66d81Schristos * 69fb66d81Schristos * Permission to use, copy, modify, and distribute this software for any 79fb66d81Schristos * purpose with or without fee is hereby granted, provided that the above 89fb66d81Schristos * copyright notice and this permission notice appear in all copies. 99fb66d81Schristos * 109fb66d81Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 119fb66d81Schristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 129fb66d81Schristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 139fb66d81Schristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 149fb66d81Schristos * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 159fb66d81Schristos * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 169fb66d81Schristos * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 179fb66d81Schristos */ 189fb66d81Schristos 199fb66d81Schristos #include <sys/types.h> 209fb66d81Schristos 219fb66d81Schristos #include <stdlib.h> 229fb66d81Schristos #include <string.h> 239fb66d81Schristos 24c23f9150Swiz #if defined(HAVE_CURSES_H) 25c23f9150Swiz #include <curses.h> 26c23f9150Swiz #elif defined(HAVE_NCURSES_H) 27c23f9150Swiz #include <ncurses.h> 28c23f9150Swiz #endif 29c23f9150Swiz 309fb66d81Schristos #include "tmux.h" 319fb66d81Schristos 329fb66d81Schristos /* 339fb66d81Schristos * Still hardcoded: 349fb66d81Schristos * - default colours (under AX or op capabilities); 359fb66d81Schristos * - AIX colours (under colors >= 16); 369fb66d81Schristos * - alternate escape (if terminal is VT100-like). 379fb66d81Schristos * 389fb66d81Schristos * Also: 399fb66d81Schristos * - DECFRA uses a flag instead of capabilities; 409fb66d81Schristos * - UTF-8 is a separate flag on the client; needed for unattached clients. 419fb66d81Schristos */ 429fb66d81Schristos 439fb66d81Schristos /* A named terminal feature. */ 449fb66d81Schristos struct tty_feature { 459fb66d81Schristos const char *name; 46c23f9150Swiz const char *const *capabilities; 479fb66d81Schristos int flags; 489fb66d81Schristos }; 499fb66d81Schristos 509fb66d81Schristos /* Terminal has xterm(1) title setting. */ 51c23f9150Swiz static const char *const tty_feature_title_capabilities[] = { 529fb66d81Schristos "tsl=\\E]0;", /* should be using TS really */ 539fb66d81Schristos "fsl=\\a", 549fb66d81Schristos NULL 559fb66d81Schristos }; 569fb66d81Schristos static const struct tty_feature tty_feature_title = { 579fb66d81Schristos "title", 589fb66d81Schristos tty_feature_title_capabilities, 599fb66d81Schristos 0 609fb66d81Schristos }; 619fb66d81Schristos 626db26757Swiz /* Terminal has OSC 7 working directory. */ 63c23f9150Swiz static const char *const tty_feature_osc7_capabilities[] = { 646db26757Swiz "Swd=\\E]7;", 656db26757Swiz "fsl=\\a", 666db26757Swiz NULL 676db26757Swiz }; 686db26757Swiz static const struct tty_feature tty_feature_osc7 = { 696db26757Swiz "osc7", 706db26757Swiz tty_feature_osc7_capabilities, 716db26757Swiz 0 726db26757Swiz }; 736db26757Swiz 74de7701e2Schristos /* Terminal has mouse support. */ 75c23f9150Swiz static const char *const tty_feature_mouse_capabilities[] = { 76de7701e2Schristos "kmous=\\E[M", 77de7701e2Schristos NULL 78de7701e2Schristos }; 79de7701e2Schristos static const struct tty_feature tty_feature_mouse = { 80de7701e2Schristos "mouse", 81de7701e2Schristos tty_feature_mouse_capabilities, 82de7701e2Schristos 0 83de7701e2Schristos }; 84de7701e2Schristos 859fb66d81Schristos /* Terminal can set the clipboard with OSC 52. */ 86c23f9150Swiz static const char *const tty_feature_clipboard_capabilities[] = { 879fb66d81Schristos "Ms=\\E]52;%p1%s;%p2%s\\a", 889fb66d81Schristos NULL 899fb66d81Schristos }; 909fb66d81Schristos static const struct tty_feature tty_feature_clipboard = { 919fb66d81Schristos "clipboard", 929fb66d81Schristos tty_feature_clipboard_capabilities, 939fb66d81Schristos 0 949fb66d81Schristos }; 959fb66d81Schristos 96c23f9150Swiz /* Terminal supports OSC 8 hyperlinks. */ 97c23f9150Swiz static const char *tty_feature_hyperlinks_capabilities[] = { 98c23f9150Swiz #if defined (__OpenBSD__) || (defined(NCURSES_VERSION_MAJOR) && \ 99c23f9150Swiz (NCURSES_VERSION_MAJOR > 5 || \ 100c23f9150Swiz (NCURSES_VERSION_MAJOR == 5 && NCURSES_VERSION_MINOR > 8))) 101c23f9150Swiz "*:Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\", 102c23f9150Swiz #endif 103c23f9150Swiz NULL 104c23f9150Swiz }; 105c23f9150Swiz static const struct tty_feature tty_feature_hyperlinks = { 106c23f9150Swiz "hyperlinks", 107c23f9150Swiz tty_feature_hyperlinks_capabilities, 108c23f9150Swiz 0 109c23f9150Swiz }; 110c23f9150Swiz 1119fb66d81Schristos /* 1129fb66d81Schristos * Terminal supports RGB colour. This replaces setab and setaf also since 1139fb66d81Schristos * terminals with RGB have versions that do not allow setting colours from the 1149fb66d81Schristos * 256 palette. 1159fb66d81Schristos */ 116c23f9150Swiz static const char *const tty_feature_rgb_capabilities[] = { 1179fb66d81Schristos "AX", 1189fb66d81Schristos "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm", 1199fb66d81Schristos "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm", 1209fb66d81Schristos "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", 1219fb66d81Schristos "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", 1229fb66d81Schristos NULL 1239fb66d81Schristos }; 1249fb66d81Schristos static const struct tty_feature tty_feature_rgb = { 1259fb66d81Schristos "RGB", 1269fb66d81Schristos tty_feature_rgb_capabilities, 1279fb66d81Schristos TERM_256COLOURS|TERM_RGBCOLOURS 1289fb66d81Schristos }; 1299fb66d81Schristos 1309fb66d81Schristos /* Terminal supports 256 colours. */ 131c23f9150Swiz static const char *const tty_feature_256_capabilities[] = { 1329fb66d81Schristos "AX", 1339fb66d81Schristos "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", 1349fb66d81Schristos "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", 1359fb66d81Schristos NULL 1369fb66d81Schristos }; 1379fb66d81Schristos static const struct tty_feature tty_feature_256 = { 1389fb66d81Schristos "256", 1399fb66d81Schristos tty_feature_256_capabilities, 1409fb66d81Schristos TERM_256COLOURS 1419fb66d81Schristos }; 1429fb66d81Schristos 1439fb66d81Schristos /* Terminal supports overline. */ 144c23f9150Swiz static const char *const tty_feature_overline_capabilities[] = { 1459fb66d81Schristos "Smol=\\E[53m", 1469fb66d81Schristos NULL 1479fb66d81Schristos }; 1489fb66d81Schristos static const struct tty_feature tty_feature_overline = { 1499fb66d81Schristos "overline", 1509fb66d81Schristos tty_feature_overline_capabilities, 1519fb66d81Schristos 0 1529fb66d81Schristos }; 1539fb66d81Schristos 1549fb66d81Schristos /* Terminal supports underscore styles. */ 155c23f9150Swiz static const char *const tty_feature_usstyle_capabilities[] = { 1569fb66d81Schristos "Smulx=\\E[4::%p1%dm", 1579fb66d81Schristos "Setulc=\\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m", 158c23f9150Swiz "Setulc1=\\E[58::5::%p1%dm", 1599fb66d81Schristos "ol=\\E[59m", 1609fb66d81Schristos NULL 1619fb66d81Schristos }; 1629fb66d81Schristos static const struct tty_feature tty_feature_usstyle = { 1639fb66d81Schristos "usstyle", 1649fb66d81Schristos tty_feature_usstyle_capabilities, 1659fb66d81Schristos 0 1669fb66d81Schristos }; 1679fb66d81Schristos 1689fb66d81Schristos /* Terminal supports bracketed paste. */ 169c23f9150Swiz static const char *const tty_feature_bpaste_capabilities[] = { 1709fb66d81Schristos "Enbp=\\E[?2004h", 1719fb66d81Schristos "Dsbp=\\E[?2004l", 1729fb66d81Schristos NULL 1739fb66d81Schristos }; 1749fb66d81Schristos static const struct tty_feature tty_feature_bpaste = { 1759fb66d81Schristos "bpaste", 1769fb66d81Schristos tty_feature_bpaste_capabilities, 1779fb66d81Schristos 0 1789fb66d81Schristos }; 1799fb66d81Schristos 1809fb66d81Schristos /* Terminal supports focus reporting. */ 181c23f9150Swiz static const char *const tty_feature_focus_capabilities[] = { 1829fb66d81Schristos "Enfcs=\\E[?1004h", 1839fb66d81Schristos "Dsfcs=\\E[?1004l", 1849fb66d81Schristos NULL 1859fb66d81Schristos }; 1869fb66d81Schristos static const struct tty_feature tty_feature_focus = { 1879fb66d81Schristos "focus", 1889fb66d81Schristos tty_feature_focus_capabilities, 1899fb66d81Schristos 0 1909fb66d81Schristos }; 1919fb66d81Schristos 1929fb66d81Schristos /* Terminal supports cursor styles. */ 193c23f9150Swiz static const char *const tty_feature_cstyle_capabilities[] = { 1949fb66d81Schristos "Ss=\\E[%p1%d q", 1959fb66d81Schristos "Se=\\E[2 q", 1969fb66d81Schristos NULL 1979fb66d81Schristos }; 1989fb66d81Schristos static const struct tty_feature tty_feature_cstyle = { 1999fb66d81Schristos "cstyle", 2009fb66d81Schristos tty_feature_cstyle_capabilities, 2019fb66d81Schristos 0 2029fb66d81Schristos }; 2039fb66d81Schristos 2049fb66d81Schristos /* Terminal supports cursor colours. */ 205c23f9150Swiz static const char *const tty_feature_ccolour_capabilities[] = { 2069fb66d81Schristos "Cs=\\E]12;%p1%s\\a", 2079fb66d81Schristos "Cr=\\E]112\\a", 2089fb66d81Schristos NULL 2099fb66d81Schristos }; 2109fb66d81Schristos static const struct tty_feature tty_feature_ccolour = { 2119fb66d81Schristos "ccolour", 2129fb66d81Schristos tty_feature_ccolour_capabilities, 2139fb66d81Schristos 0 2149fb66d81Schristos }; 2159fb66d81Schristos 2169fb66d81Schristos /* Terminal supports strikethrough. */ 217c23f9150Swiz static const char *const tty_feature_strikethrough_capabilities[] = { 2189fb66d81Schristos "smxx=\\E[9m", 2199fb66d81Schristos NULL 2209fb66d81Schristos }; 2219fb66d81Schristos static const struct tty_feature tty_feature_strikethrough = { 2229fb66d81Schristos "strikethrough", 2239fb66d81Schristos tty_feature_strikethrough_capabilities, 2249fb66d81Schristos 0 2259fb66d81Schristos }; 2269fb66d81Schristos 2279fb66d81Schristos /* Terminal supports synchronized updates. */ 228c23f9150Swiz static const char *const tty_feature_sync_capabilities[] = { 229c23f9150Swiz "Sync=\\E[?2026%?%p1%{1}%-%tl%eh%;", 2309fb66d81Schristos NULL 2319fb66d81Schristos }; 2329fb66d81Schristos static const struct tty_feature tty_feature_sync = { 2339fb66d81Schristos "sync", 2349fb66d81Schristos tty_feature_sync_capabilities, 2359fb66d81Schristos 0 2369fb66d81Schristos }; 2379fb66d81Schristos 2389fb66d81Schristos /* Terminal supports extended keys. */ 239c23f9150Swiz static const char *const tty_feature_extkeys_capabilities[] = { 240*f8cf1a91Swiz "Eneks=\\E[>4;2m", 2419fb66d81Schristos "Dseks=\\E[>4m", 2429fb66d81Schristos NULL 2439fb66d81Schristos }; 2449fb66d81Schristos static const struct tty_feature tty_feature_extkeys = { 2459fb66d81Schristos "extkeys", 2469fb66d81Schristos tty_feature_extkeys_capabilities, 2479fb66d81Schristos 0 2489fb66d81Schristos }; 2499fb66d81Schristos 2509fb66d81Schristos /* Terminal supports DECSLRM margins. */ 251c23f9150Swiz static const char *const tty_feature_margins_capabilities[] = { 2529fb66d81Schristos "Enmg=\\E[?69h", 2539fb66d81Schristos "Dsmg=\\E[?69l", 2549fb66d81Schristos "Clmg=\\E[s", 2559fb66d81Schristos "Cmg=\\E[%i%p1%d;%p2%ds", 2569fb66d81Schristos NULL 2579fb66d81Schristos }; 2589fb66d81Schristos static const struct tty_feature tty_feature_margins = { 2599fb66d81Schristos "margins", 2609fb66d81Schristos tty_feature_margins_capabilities, 2619fb66d81Schristos TERM_DECSLRM 2629fb66d81Schristos }; 2639fb66d81Schristos 2649fb66d81Schristos /* Terminal supports DECFRA rectangle fill. */ 265c23f9150Swiz static const char *const tty_feature_rectfill_capabilities[] = { 266de7701e2Schristos "Rect", 267de7701e2Schristos NULL 268de7701e2Schristos }; 2699fb66d81Schristos static const struct tty_feature tty_feature_rectfill = { 2709fb66d81Schristos "rectfill", 271de7701e2Schristos tty_feature_rectfill_capabilities, 2729fb66d81Schristos TERM_DECFRA 2739fb66d81Schristos }; 2749fb66d81Schristos 275c23f9150Swiz /* Use builtin function keys only. */ 276c23f9150Swiz static const char *const tty_feature_ignorefkeys_capabilities[] = { 277c23f9150Swiz "kf0@", 278c23f9150Swiz "kf1@", 279c23f9150Swiz "kf2@", 280c23f9150Swiz "kf3@", 281c23f9150Swiz "kf4@", 282c23f9150Swiz "kf5@", 283c23f9150Swiz "kf6@", 284c23f9150Swiz "kf7@", 285c23f9150Swiz "kf8@", 286c23f9150Swiz "kf9@", 287c23f9150Swiz "kf10@", 288c23f9150Swiz "kf11@", 289c23f9150Swiz "kf12@", 290c23f9150Swiz "kf13@", 291c23f9150Swiz "kf14@", 292c23f9150Swiz "kf15@", 293c23f9150Swiz "kf16@", 294c23f9150Swiz "kf17@", 295c23f9150Swiz "kf18@", 296c23f9150Swiz "kf19@", 297c23f9150Swiz "kf20@", 298c23f9150Swiz "kf21@", 299c23f9150Swiz "kf22@", 300c23f9150Swiz "kf23@", 301c23f9150Swiz "kf24@", 302c23f9150Swiz "kf25@", 303c23f9150Swiz "kf26@", 304c23f9150Swiz "kf27@", 305c23f9150Swiz "kf28@", 306c23f9150Swiz "kf29@", 307c23f9150Swiz "kf30@", 308c23f9150Swiz "kf31@", 309c23f9150Swiz "kf32@", 310c23f9150Swiz "kf33@", 311c23f9150Swiz "kf34@", 312c23f9150Swiz "kf35@", 313c23f9150Swiz "kf36@", 314c23f9150Swiz "kf37@", 315c23f9150Swiz "kf38@", 316c23f9150Swiz "kf39@", 317c23f9150Swiz "kf40@", 318c23f9150Swiz "kf41@", 319c23f9150Swiz "kf42@", 320c23f9150Swiz "kf43@", 321c23f9150Swiz "kf44@", 322c23f9150Swiz "kf45@", 323c23f9150Swiz "kf46@", 324c23f9150Swiz "kf47@", 325c23f9150Swiz "kf48@", 326c23f9150Swiz "kf49@", 327c23f9150Swiz "kf50@", 328c23f9150Swiz "kf51@", 329c23f9150Swiz "kf52@", 330c23f9150Swiz "kf53@", 331c23f9150Swiz "kf54@", 332c23f9150Swiz "kf55@", 333c23f9150Swiz "kf56@", 334c23f9150Swiz "kf57@", 335c23f9150Swiz "kf58@", 336c23f9150Swiz "kf59@", 337c23f9150Swiz "kf60@", 338c23f9150Swiz "kf61@", 339c23f9150Swiz "kf62@", 340c23f9150Swiz "kf63@", 341c23f9150Swiz NULL 342c23f9150Swiz }; 343c23f9150Swiz static const struct tty_feature tty_feature_ignorefkeys = { 344c23f9150Swiz "ignorefkeys", 345c23f9150Swiz tty_feature_ignorefkeys_capabilities, 346c23f9150Swiz 0 347c23f9150Swiz }; 348c23f9150Swiz 349c23f9150Swiz /* Terminal has sixel capability. */ 350c23f9150Swiz static const char *const tty_feature_sixel_capabilities[] = { 351c23f9150Swiz "Sxl", 352c23f9150Swiz NULL 353c23f9150Swiz }; 354c23f9150Swiz static const struct tty_feature tty_feature_sixel = { 355c23f9150Swiz "sixel", 356c23f9150Swiz tty_feature_sixel_capabilities, 357c23f9150Swiz TERM_SIXEL 358c23f9150Swiz }; 359c23f9150Swiz 3609fb66d81Schristos /* Available terminal features. */ 361c23f9150Swiz static const struct tty_feature *const tty_features[] = { 3629fb66d81Schristos &tty_feature_256, 3639fb66d81Schristos &tty_feature_bpaste, 3649fb66d81Schristos &tty_feature_ccolour, 3659fb66d81Schristos &tty_feature_clipboard, 366c23f9150Swiz &tty_feature_hyperlinks, 3679fb66d81Schristos &tty_feature_cstyle, 3689fb66d81Schristos &tty_feature_extkeys, 3699fb66d81Schristos &tty_feature_focus, 370c23f9150Swiz &tty_feature_ignorefkeys, 3719fb66d81Schristos &tty_feature_margins, 372de7701e2Schristos &tty_feature_mouse, 3736db26757Swiz &tty_feature_osc7, 3749fb66d81Schristos &tty_feature_overline, 3759fb66d81Schristos &tty_feature_rectfill, 3769fb66d81Schristos &tty_feature_rgb, 377c23f9150Swiz &tty_feature_sixel, 3789fb66d81Schristos &tty_feature_strikethrough, 3799fb66d81Schristos &tty_feature_sync, 3809fb66d81Schristos &tty_feature_title, 3819fb66d81Schristos &tty_feature_usstyle 3829fb66d81Schristos }; 3839fb66d81Schristos 3849fb66d81Schristos void 3859fb66d81Schristos tty_add_features(int *feat, const char *s, const char *separators) 3869fb66d81Schristos { 3879fb66d81Schristos const struct tty_feature *tf; 3889fb66d81Schristos char *next, *loop, *copy; 3899fb66d81Schristos u_int i; 3909fb66d81Schristos 3919fb66d81Schristos log_debug("adding terminal features %s", s); 3929fb66d81Schristos 3939fb66d81Schristos loop = copy = xstrdup(s); 3949fb66d81Schristos while ((next = strsep(&loop, separators)) != NULL) { 3959fb66d81Schristos for (i = 0; i < nitems(tty_features); i++) { 3969fb66d81Schristos tf = tty_features[i]; 3979fb66d81Schristos if (strcasecmp(tf->name, next) == 0) 3989fb66d81Schristos break; 3999fb66d81Schristos } 4009fb66d81Schristos if (i == nitems(tty_features)) { 4019fb66d81Schristos log_debug("unknown terminal feature: %s", next); 4029fb66d81Schristos break; 4039fb66d81Schristos } 4049fb66d81Schristos if (~(*feat) & (1 << i)) { 4059fb66d81Schristos log_debug("adding terminal feature: %s", tf->name); 4069fb66d81Schristos (*feat) |= (1 << i); 4079fb66d81Schristos } 4089fb66d81Schristos } 4099fb66d81Schristos free(copy); 4109fb66d81Schristos } 4119fb66d81Schristos 4129fb66d81Schristos const char * 4139fb66d81Schristos tty_get_features(int feat) 4149fb66d81Schristos { 4159fb66d81Schristos const struct tty_feature *tf; 4169fb66d81Schristos static char s[512]; 4179fb66d81Schristos u_int i; 4189fb66d81Schristos 4199fb66d81Schristos *s = '\0'; 4209fb66d81Schristos for (i = 0; i < nitems(tty_features); i++) { 4219fb66d81Schristos if (~feat & (1 << i)) 4229fb66d81Schristos continue; 4239fb66d81Schristos tf = tty_features[i]; 4249fb66d81Schristos 4259fb66d81Schristos strlcat(s, tf->name, sizeof s); 4269fb66d81Schristos strlcat(s, ",", sizeof s); 4279fb66d81Schristos } 4289fb66d81Schristos if (*s != '\0') 4299fb66d81Schristos s[strlen(s) - 1] = '\0'; 4309fb66d81Schristos return (s); 4319fb66d81Schristos } 4329fb66d81Schristos 4339fb66d81Schristos int 4349fb66d81Schristos tty_apply_features(struct tty_term *term, int feat) 4359fb66d81Schristos { 4369fb66d81Schristos const struct tty_feature *tf; 437c23f9150Swiz const char *const *capability; 4389fb66d81Schristos u_int i; 4399fb66d81Schristos 4409fb66d81Schristos if (feat == 0) 4419fb66d81Schristos return (0); 4429fb66d81Schristos log_debug("applying terminal features: %s", tty_get_features(feat)); 4439fb66d81Schristos 4449fb66d81Schristos for (i = 0; i < nitems(tty_features); i++) { 4459fb66d81Schristos if ((term->features & (1 << i)) || (~feat & (1 << i))) 4469fb66d81Schristos continue; 4479fb66d81Schristos tf = tty_features[i]; 4489fb66d81Schristos 4499fb66d81Schristos log_debug("applying terminal feature: %s", tf->name); 4509fb66d81Schristos if (tf->capabilities != NULL) { 4519fb66d81Schristos capability = tf->capabilities; 4529fb66d81Schristos while (*capability != NULL) { 4539fb66d81Schristos log_debug("adding capability: %s", *capability); 4549fb66d81Schristos tty_term_apply(term, *capability, 1); 4559fb66d81Schristos capability++; 4569fb66d81Schristos } 4579fb66d81Schristos } 4589fb66d81Schristos term->flags |= tf->flags; 4599fb66d81Schristos } 4609fb66d81Schristos if ((term->features | feat) == term->features) 4619fb66d81Schristos return (0); 4629fb66d81Schristos term->features |= feat; 4639fb66d81Schristos return (1); 4649fb66d81Schristos } 4659fb66d81Schristos 4669fb66d81Schristos void 4679fb66d81Schristos tty_default_features(int *feat, const char *name, u_int version) 4689fb66d81Schristos { 469c23f9150Swiz static const struct { 4709fb66d81Schristos const char *name; 4719fb66d81Schristos u_int version; 4729fb66d81Schristos const char *features; 4739fb66d81Schristos } table[] = { 4749fb66d81Schristos #define TTY_FEATURES_BASE_MODERN_XTERM \ 475de7701e2Schristos "256,RGB,bpaste,clipboard,mouse,strikethrough,title" 4769fb66d81Schristos { .name = "mintty", 4779fb66d81Schristos .features = TTY_FEATURES_BASE_MODERN_XTERM 4789fb66d81Schristos ",ccolour,cstyle,extkeys,margins,overline,usstyle" 4799fb66d81Schristos }, 4809fb66d81Schristos { .name = "tmux", 4819fb66d81Schristos .features = TTY_FEATURES_BASE_MODERN_XTERM 482c23f9150Swiz ",ccolour,cstyle,focus,overline,usstyle,hyperlinks" 4839fb66d81Schristos }, 4849fb66d81Schristos { .name = "rxvt-unicode", 485c23f9150Swiz .features = "256,bpaste,ccolour,cstyle,mouse,title,ignorefkeys" 4869fb66d81Schristos }, 4879fb66d81Schristos { .name = "iTerm2", 4889fb66d81Schristos .features = TTY_FEATURES_BASE_MODERN_XTERM 489c23f9150Swiz ",cstyle,extkeys,margins,usstyle,sync,osc7,hyperlinks" 4909fb66d81Schristos }, 4919fb66d81Schristos { .name = "XTerm", 492de7701e2Schristos /* 493de7701e2Schristos * xterm also supports DECSLRM and DECFRA, but they can be 494de7701e2Schristos * disabled so not set it here - they will be added if 495de7701e2Schristos * secondary DA shows VT420. 496de7701e2Schristos */ 4979fb66d81Schristos .features = TTY_FEATURES_BASE_MODERN_XTERM 498de7701e2Schristos ",ccolour,cstyle,extkeys,focus" 4999fb66d81Schristos } 5009fb66d81Schristos }; 5019fb66d81Schristos u_int i; 5029fb66d81Schristos 5039fb66d81Schristos for (i = 0; i < nitems(table); i++) { 5049fb66d81Schristos if (strcmp(table[i].name, name) != 0) 5059fb66d81Schristos continue; 5069fb66d81Schristos if (version != 0 && version < table[i].version) 5079fb66d81Schristos continue; 5089fb66d81Schristos tty_add_features(feat, table[i].features, ","); 5099fb66d81Schristos } 5109fb66d81Schristos } 511