1*a65ab485Snicm /* $OpenBSD: tty-features.c,v 1.32 2024/11/28 08:49:14 nicm Exp $ */ 25a160f88Snicm 35a160f88Snicm /* 45a160f88Snicm * Copyright (c) 2020 Nicholas Marriott <nicholas.marriott@gmail.com> 55a160f88Snicm * 65a160f88Snicm * Permission to use, copy, modify, and distribute this software for any 75a160f88Snicm * purpose with or without fee is hereby granted, provided that the above 85a160f88Snicm * copyright notice and this permission notice appear in all copies. 95a160f88Snicm * 105a160f88Snicm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 115a160f88Snicm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 125a160f88Snicm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 135a160f88Snicm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 145a160f88Snicm * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 155a160f88Snicm * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 165a160f88Snicm * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 175a160f88Snicm */ 185a160f88Snicm 195a160f88Snicm #include <sys/types.h> 205a160f88Snicm 215a160f88Snicm #include <stdlib.h> 225a160f88Snicm #include <string.h> 235a160f88Snicm 245a160f88Snicm #include "tmux.h" 255a160f88Snicm 265a160f88Snicm /* 275a160f88Snicm * Still hardcoded: 285a160f88Snicm * - default colours (under AX or op capabilities); 295a160f88Snicm * - AIX colours (under colors >= 16); 309884925cSnicm * - alternate escape (if terminal is VT100-like). 315a160f88Snicm * 325a160f88Snicm * Also: 336763df04Snicm * - DECFRA uses a flag instead of capabilities; 345a160f88Snicm * - UTF-8 is a separate flag on the client; needed for unattached clients. 355a160f88Snicm */ 365a160f88Snicm 375a160f88Snicm /* A named terminal feature. */ 385a160f88Snicm struct tty_feature { 395a160f88Snicm const char *name; 40ac937780Snicm const char *const *capabilities; 415a160f88Snicm int flags; 425a160f88Snicm }; 435a160f88Snicm 445a160f88Snicm /* Terminal has xterm(1) title setting. */ 45ac937780Snicm static const char *const tty_feature_title_capabilities[] = { 465a160f88Snicm "tsl=\\E]0;", /* should be using TS really */ 475a160f88Snicm "fsl=\\a", 485a160f88Snicm NULL 495a160f88Snicm }; 50ed2e005dSnicm static const struct tty_feature tty_feature_title = { 515a160f88Snicm "title", 525a160f88Snicm tty_feature_title_capabilities, 535a160f88Snicm 0 545a160f88Snicm }; 555a160f88Snicm 56989dfa67Snicm /* Terminal has OSC 7 working directory. */ 57ac937780Snicm static const char *const tty_feature_osc7_capabilities[] = { 58989dfa67Snicm "Swd=\\E]7;", 59989dfa67Snicm "fsl=\\a", 60989dfa67Snicm NULL 61989dfa67Snicm }; 62989dfa67Snicm static const struct tty_feature tty_feature_osc7 = { 63989dfa67Snicm "osc7", 64989dfa67Snicm tty_feature_osc7_capabilities, 65989dfa67Snicm 0 66989dfa67Snicm }; 67989dfa67Snicm 683893e820Snicm /* Terminal has mouse support. */ 69ac937780Snicm static const char *const tty_feature_mouse_capabilities[] = { 703893e820Snicm "kmous=\\E[M", 713893e820Snicm NULL 723893e820Snicm }; 733893e820Snicm static const struct tty_feature tty_feature_mouse = { 743893e820Snicm "mouse", 753893e820Snicm tty_feature_mouse_capabilities, 763893e820Snicm 0 773893e820Snicm }; 783893e820Snicm 795a160f88Snicm /* Terminal can set the clipboard with OSC 52. */ 80ac937780Snicm static const char *const tty_feature_clipboard_capabilities[] = { 815a160f88Snicm "Ms=\\E]52;%p1%s;%p2%s\\a", 825a160f88Snicm NULL 835a160f88Snicm }; 84ed2e005dSnicm static const struct tty_feature tty_feature_clipboard = { 855a160f88Snicm "clipboard", 865a160f88Snicm tty_feature_clipboard_capabilities, 875a160f88Snicm 0 885a160f88Snicm }; 895a160f88Snicm 902df6775cSnicm /* Terminal supports OSC 8 hyperlinks. */ 91ac937780Snicm static const char *const tty_feature_hyperlinks_capabilities[] = { 922df6775cSnicm "*:Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\", 932df6775cSnicm NULL 942df6775cSnicm }; 952df6775cSnicm static const struct tty_feature tty_feature_hyperlinks = { 962df6775cSnicm "hyperlinks", 972df6775cSnicm tty_feature_hyperlinks_capabilities, 982df6775cSnicm 0 992df6775cSnicm }; 1002df6775cSnicm 1015a160f88Snicm /* 1025a160f88Snicm * Terminal supports RGB colour. This replaces setab and setaf also since 1035a160f88Snicm * terminals with RGB have versions that do not allow setting colours from the 1045a160f88Snicm * 256 palette. 1055a160f88Snicm */ 106ac937780Snicm static const char *const tty_feature_rgb_capabilities[] = { 107ab658049Snicm "AX", 1085a160f88Snicm "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm", 1095a160f88Snicm "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm", 1105a160f88Snicm "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", 1115a160f88Snicm "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", 1125a160f88Snicm NULL 1135a160f88Snicm }; 114ed2e005dSnicm static const struct tty_feature tty_feature_rgb = { 1155a160f88Snicm "RGB", 1165a160f88Snicm tty_feature_rgb_capabilities, 1176763df04Snicm TERM_256COLOURS|TERM_RGBCOLOURS 1185a160f88Snicm }; 1195a160f88Snicm 1205a160f88Snicm /* Terminal supports 256 colours. */ 121ac937780Snicm static const char *const tty_feature_256_capabilities[] = { 122ab658049Snicm "AX", 1235a160f88Snicm "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m", 1245a160f88Snicm "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m", 1255a160f88Snicm NULL 1265a160f88Snicm }; 127ed2e005dSnicm static const struct tty_feature tty_feature_256 = { 1285a160f88Snicm "256", 1295a160f88Snicm tty_feature_256_capabilities, 1305a160f88Snicm TERM_256COLOURS 1315a160f88Snicm }; 1325a160f88Snicm 1335a160f88Snicm /* Terminal supports overline. */ 134ac937780Snicm static const char *const tty_feature_overline_capabilities[] = { 1355a160f88Snicm "Smol=\\E[53m", 1365a160f88Snicm NULL 1375a160f88Snicm }; 138ed2e005dSnicm static const struct tty_feature tty_feature_overline = { 1395a160f88Snicm "overline", 1405a160f88Snicm tty_feature_overline_capabilities, 1415a160f88Snicm 0 1425a160f88Snicm }; 1435a160f88Snicm 1445a160f88Snicm /* Terminal supports underscore styles. */ 145ac937780Snicm static const char *const tty_feature_usstyle_capabilities[] = { 146efa5b6a3Sdaniel "Smulx=\\E[4::%p1%dm", 147efa5b6a3Sdaniel "Setulc=\\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m", 1484620f414Snicm "Setulc1=\\E[58::5::%p1%dm", 149e9a14db2Snicm "ol=\\E[59m", 1505a160f88Snicm NULL 1515a160f88Snicm }; 152ed2e005dSnicm static const struct tty_feature tty_feature_usstyle = { 1535a160f88Snicm "usstyle", 1545a160f88Snicm tty_feature_usstyle_capabilities, 1555a160f88Snicm 0 1565a160f88Snicm }; 1575a160f88Snicm 158ed2e005dSnicm /* Terminal supports bracketed paste. */ 159ac937780Snicm static const char *const tty_feature_bpaste_capabilities[] = { 160ed2e005dSnicm "Enbp=\\E[?2004h", 16180bd3d52Snicm "Dsbp=\\E[?2004l", 16280bd3d52Snicm NULL 16380bd3d52Snicm }; 164ed2e005dSnicm static const struct tty_feature tty_feature_bpaste = { 16580bd3d52Snicm "bpaste", 16680bd3d52Snicm tty_feature_bpaste_capabilities, 16780bd3d52Snicm 0 16880bd3d52Snicm }; 16980bd3d52Snicm 170ed2e005dSnicm /* Terminal supports focus reporting. */ 171ac937780Snicm static const char *const tty_feature_focus_capabilities[] = { 172ed2e005dSnicm "Enfcs=\\E[?1004h", 173ed2e005dSnicm "Dsfcs=\\E[?1004l", 174ed2e005dSnicm NULL 175ed2e005dSnicm }; 176ed2e005dSnicm static const struct tty_feature tty_feature_focus = { 177ed2e005dSnicm "focus", 178ed2e005dSnicm tty_feature_focus_capabilities, 179ed2e005dSnicm 0 180ed2e005dSnicm }; 181ed2e005dSnicm 1825a160f88Snicm /* Terminal supports cursor styles. */ 183ac937780Snicm static const char *const tty_feature_cstyle_capabilities[] = { 1845a160f88Snicm "Ss=\\E[%p1%d q", 1855a160f88Snicm "Se=\\E[2 q", 1865a160f88Snicm NULL 1875a160f88Snicm }; 188ed2e005dSnicm static const struct tty_feature tty_feature_cstyle = { 1895a160f88Snicm "cstyle", 1905a160f88Snicm tty_feature_cstyle_capabilities, 1915a160f88Snicm 0 1925a160f88Snicm }; 1935a160f88Snicm 1945a160f88Snicm /* Terminal supports cursor colours. */ 195ac937780Snicm static const char *const tty_feature_ccolour_capabilities[] = { 1965a160f88Snicm "Cs=\\E]12;%p1%s\\a", 1975a160f88Snicm "Cr=\\E]112\\a", 1985a160f88Snicm NULL 1995a160f88Snicm }; 200ed2e005dSnicm static const struct tty_feature tty_feature_ccolour = { 2015a160f88Snicm "ccolour", 2025a160f88Snicm tty_feature_ccolour_capabilities, 2035a160f88Snicm 0 2045a160f88Snicm }; 2055a160f88Snicm 206dfff4af3Snicm /* Terminal supports strikethrough. */ 207ac937780Snicm static const char *const tty_feature_strikethrough_capabilities[] = { 208dfff4af3Snicm "smxx=\\E[9m", 209dfff4af3Snicm NULL 210dfff4af3Snicm }; 211ed2e005dSnicm static const struct tty_feature tty_feature_strikethrough = { 212dfff4af3Snicm "strikethrough", 213dfff4af3Snicm tty_feature_strikethrough_capabilities, 214dfff4af3Snicm 0 215dfff4af3Snicm }; 216dfff4af3Snicm 2175a160f88Snicm /* Terminal supports synchronized updates. */ 218ac937780Snicm static const char *const tty_feature_sync_capabilities[] = { 219c101cdd2Snicm "Sync=\\E[?2026%?%p1%{1}%-%tl%eh%;", 2205a160f88Snicm NULL 2215a160f88Snicm }; 222ed2e005dSnicm static const struct tty_feature tty_feature_sync = { 2235a160f88Snicm "sync", 2245a160f88Snicm tty_feature_sync_capabilities, 2255a160f88Snicm 0 2265a160f88Snicm }; 2275a160f88Snicm 228dcf80b09Snicm /* Terminal supports extended keys. */ 229ac937780Snicm static const char *const tty_feature_extkeys_capabilities[] = { 230719f5715Snicm "Eneks=\\E[>4;2m", 231dcf80b09Snicm "Dseks=\\E[>4m", 232dcf80b09Snicm NULL 233dcf80b09Snicm }; 234dcf80b09Snicm static const struct tty_feature tty_feature_extkeys = { 235dcf80b09Snicm "extkeys", 236dcf80b09Snicm tty_feature_extkeys_capabilities, 237dcf80b09Snicm 0 238dcf80b09Snicm }; 239dcf80b09Snicm 2405a160f88Snicm /* Terminal supports DECSLRM margins. */ 241ac937780Snicm static const char *const tty_feature_margins_capabilities[] = { 2426763df04Snicm "Enmg=\\E[?69h", 2436763df04Snicm "Dsmg=\\E[?69l", 2446763df04Snicm "Clmg=\\E[s", 2456763df04Snicm "Cmg=\\E[%i%p1%d;%p2%ds", 2466763df04Snicm NULL 2476763df04Snicm }; 248ed2e005dSnicm static const struct tty_feature tty_feature_margins = { 2495a160f88Snicm "margins", 2506763df04Snicm tty_feature_margins_capabilities, 2515a160f88Snicm TERM_DECSLRM 2525a160f88Snicm }; 2535a160f88Snicm 2545a160f88Snicm /* Terminal supports DECFRA rectangle fill. */ 255ac937780Snicm static const char *const tty_feature_rectfill_capabilities[] = { 256dd3a9cf8Snicm "Rect", 257dd3a9cf8Snicm NULL 258dd3a9cf8Snicm }; 259ed2e005dSnicm static const struct tty_feature tty_feature_rectfill = { 2605a160f88Snicm "rectfill", 261dd3a9cf8Snicm tty_feature_rectfill_capabilities, 2625a160f88Snicm TERM_DECFRA 2635a160f88Snicm }; 2645a160f88Snicm 265c620fc9fSnicm /* Use builtin function keys only. */ 266ac937780Snicm static const char *const tty_feature_ignorefkeys_capabilities[] = { 267c620fc9fSnicm "kf0@", 268c620fc9fSnicm "kf1@", 269c620fc9fSnicm "kf2@", 270c620fc9fSnicm "kf3@", 271c620fc9fSnicm "kf4@", 272c620fc9fSnicm "kf5@", 273c620fc9fSnicm "kf6@", 274c620fc9fSnicm "kf7@", 275c620fc9fSnicm "kf8@", 276c620fc9fSnicm "kf9@", 277c620fc9fSnicm "kf10@", 278c620fc9fSnicm "kf11@", 279c620fc9fSnicm "kf12@", 280c620fc9fSnicm "kf13@", 281c620fc9fSnicm "kf14@", 282c620fc9fSnicm "kf15@", 283c620fc9fSnicm "kf16@", 284c620fc9fSnicm "kf17@", 285c620fc9fSnicm "kf18@", 286c620fc9fSnicm "kf19@", 287c620fc9fSnicm "kf20@", 288c620fc9fSnicm "kf21@", 289c620fc9fSnicm "kf22@", 290c620fc9fSnicm "kf23@", 291c620fc9fSnicm "kf24@", 292c620fc9fSnicm "kf25@", 293c620fc9fSnicm "kf26@", 294c620fc9fSnicm "kf27@", 295c620fc9fSnicm "kf28@", 296c620fc9fSnicm "kf29@", 297c620fc9fSnicm "kf30@", 298c620fc9fSnicm "kf31@", 299c620fc9fSnicm "kf32@", 300c620fc9fSnicm "kf33@", 301c620fc9fSnicm "kf34@", 302c620fc9fSnicm "kf35@", 303c620fc9fSnicm "kf36@", 304c620fc9fSnicm "kf37@", 305c620fc9fSnicm "kf38@", 306c620fc9fSnicm "kf39@", 307c620fc9fSnicm "kf40@", 308c620fc9fSnicm "kf41@", 309c620fc9fSnicm "kf42@", 310c620fc9fSnicm "kf43@", 311c620fc9fSnicm "kf44@", 312c620fc9fSnicm "kf45@", 313c620fc9fSnicm "kf46@", 314c620fc9fSnicm "kf47@", 315c620fc9fSnicm "kf48@", 316c620fc9fSnicm "kf49@", 317c620fc9fSnicm "kf50@", 318c620fc9fSnicm "kf51@", 319c620fc9fSnicm "kf52@", 320c620fc9fSnicm "kf53@", 321c620fc9fSnicm "kf54@", 322c620fc9fSnicm "kf55@", 323c620fc9fSnicm "kf56@", 324c620fc9fSnicm "kf57@", 325c620fc9fSnicm "kf58@", 326c620fc9fSnicm "kf59@", 327c620fc9fSnicm "kf60@", 328c620fc9fSnicm "kf61@", 329c620fc9fSnicm "kf62@", 330c620fc9fSnicm "kf63@", 331c620fc9fSnicm NULL 332c620fc9fSnicm }; 333c620fc9fSnicm static const struct tty_feature tty_feature_ignorefkeys = { 334c620fc9fSnicm "ignorefkeys", 335c620fc9fSnicm tty_feature_ignorefkeys_capabilities, 336c620fc9fSnicm 0 337c620fc9fSnicm }; 338c620fc9fSnicm 339e0697ebcSnicm /* Terminal has sixel capability. */ 340e0697ebcSnicm static const char *const tty_feature_sixel_capabilities[] = { 341e0697ebcSnicm "Sxl", 342e0697ebcSnicm NULL 343e0697ebcSnicm }; 344e0697ebcSnicm static const struct tty_feature tty_feature_sixel = { 345e0697ebcSnicm "sixel", 346e0697ebcSnicm tty_feature_sixel_capabilities, 347f4ec6bcaSnicm TERM_SIXEL 348e0697ebcSnicm }; 349e0697ebcSnicm 3505a160f88Snicm /* Available terminal features. */ 351ac937780Snicm static const struct tty_feature *const tty_features[] = { 3525a160f88Snicm &tty_feature_256, 35380bd3d52Snicm &tty_feature_bpaste, 3545a160f88Snicm &tty_feature_ccolour, 355ed2e005dSnicm &tty_feature_clipboard, 3562df6775cSnicm &tty_feature_hyperlinks, 3575a160f88Snicm &tty_feature_cstyle, 358dcf80b09Snicm &tty_feature_extkeys, 359ed2e005dSnicm &tty_feature_focus, 360c620fc9fSnicm &tty_feature_ignorefkeys, 3615a160f88Snicm &tty_feature_margins, 3623893e820Snicm &tty_feature_mouse, 363989dfa67Snicm &tty_feature_osc7, 3645a160f88Snicm &tty_feature_overline, 3655a160f88Snicm &tty_feature_rectfill, 3665a160f88Snicm &tty_feature_rgb, 367e0697ebcSnicm &tty_feature_sixel, 368dfff4af3Snicm &tty_feature_strikethrough, 3695a160f88Snicm &tty_feature_sync, 3705a160f88Snicm &tty_feature_title, 3715a160f88Snicm &tty_feature_usstyle 3725a160f88Snicm }; 3735a160f88Snicm 3745a160f88Snicm void 3755a160f88Snicm tty_add_features(int *feat, const char *s, const char *separators) 3765a160f88Snicm { 3775a160f88Snicm const struct tty_feature *tf; 3785a160f88Snicm char *next, *loop, *copy; 3795a160f88Snicm u_int i; 3805a160f88Snicm 3818942cc58Snicm log_debug("adding terminal features %s", s); 3826763df04Snicm 3835a160f88Snicm loop = copy = xstrdup(s); 3845a160f88Snicm while ((next = strsep(&loop, separators)) != NULL) { 3855a160f88Snicm for (i = 0; i < nitems(tty_features); i++) { 3865a160f88Snicm tf = tty_features[i]; 3875a160f88Snicm if (strcasecmp(tf->name, next) == 0) 3885a160f88Snicm break; 3895a160f88Snicm } 3905a160f88Snicm if (i == nitems(tty_features)) { 3915a160f88Snicm log_debug("unknown terminal feature: %s", next); 3925a160f88Snicm break; 3935a160f88Snicm } 3945a160f88Snicm if (~(*feat) & (1 << i)) { 3955a160f88Snicm log_debug("adding terminal feature: %s", tf->name); 3965a160f88Snicm (*feat) |= (1 << i); 3975a160f88Snicm } 3985a160f88Snicm } 3995a160f88Snicm free(copy); 4005a160f88Snicm } 4015a160f88Snicm 4025a160f88Snicm const char * 4035a160f88Snicm tty_get_features(int feat) 4045a160f88Snicm { 4055a160f88Snicm const struct tty_feature *tf; 4065a160f88Snicm static char s[512]; 4075a160f88Snicm u_int i; 4085a160f88Snicm 4095a160f88Snicm *s = '\0'; 4105a160f88Snicm for (i = 0; i < nitems(tty_features); i++) { 4115a160f88Snicm if (~feat & (1 << i)) 4125a160f88Snicm continue; 4135a160f88Snicm tf = tty_features[i]; 4145a160f88Snicm 4155a160f88Snicm strlcat(s, tf->name, sizeof s); 4165a160f88Snicm strlcat(s, ",", sizeof s); 4175a160f88Snicm } 4185a160f88Snicm if (*s != '\0') 4195a160f88Snicm s[strlen(s) - 1] = '\0'; 4205a160f88Snicm return (s); 4215a160f88Snicm } 4225a160f88Snicm 4239c34abedSnicm int 4245a160f88Snicm tty_apply_features(struct tty_term *term, int feat) 4255a160f88Snicm { 4265a160f88Snicm const struct tty_feature *tf; 427ac937780Snicm const char *const *capability; 4285a160f88Snicm u_int i; 4295a160f88Snicm 4305a160f88Snicm if (feat == 0) 4319c34abedSnicm return (0); 4325a160f88Snicm log_debug("applying terminal features: %s", tty_get_features(feat)); 4335a160f88Snicm 4345a160f88Snicm for (i = 0; i < nitems(tty_features); i++) { 4355a160f88Snicm if ((term->features & (1 << i)) || (~feat & (1 << i))) 4365a160f88Snicm continue; 4375a160f88Snicm tf = tty_features[i]; 4385a160f88Snicm 4395a160f88Snicm log_debug("applying terminal feature: %s", tf->name); 4405a160f88Snicm if (tf->capabilities != NULL) { 4415a160f88Snicm capability = tf->capabilities; 4425a160f88Snicm while (*capability != NULL) { 4435a160f88Snicm log_debug("adding capability: %s", *capability); 4445a160f88Snicm tty_term_apply(term, *capability, 1); 4455a160f88Snicm capability++; 4465a160f88Snicm } 4475a160f88Snicm } 4485a160f88Snicm term->flags |= tf->flags; 4495a160f88Snicm } 4509c34abedSnicm if ((term->features | feat) == term->features) 4519c34abedSnicm return (0); 4525a160f88Snicm term->features |= feat; 4539c34abedSnicm return (1); 4545a160f88Snicm } 4558942cc58Snicm 4568942cc58Snicm void 4578942cc58Snicm tty_default_features(int *feat, const char *name, u_int version) 4588942cc58Snicm { 459ac937780Snicm static const struct { 4608942cc58Snicm const char *name; 4618942cc58Snicm u_int version; 4628942cc58Snicm const char *features; 4638942cc58Snicm } table[] = { 46425373524Snicm #define TTY_FEATURES_BASE_MODERN_XTERM \ 4653893e820Snicm "256,RGB,bpaste,clipboard,mouse,strikethrough,title" 4668942cc58Snicm { .name = "mintty", 46725373524Snicm .features = TTY_FEATURES_BASE_MODERN_XTERM 468e9a14db2Snicm ",ccolour,cstyle,extkeys,margins,overline,usstyle" 4698942cc58Snicm }, 4708942cc58Snicm { .name = "tmux", 47125373524Snicm .features = TTY_FEATURES_BASE_MODERN_XTERM 4722df6775cSnicm ",ccolour,cstyle,focus,overline,usstyle,hyperlinks" 4738942cc58Snicm }, 4748942cc58Snicm { .name = "rxvt-unicode", 475c620fc9fSnicm .features = "256,bpaste,ccolour,cstyle,mouse,title,ignorefkeys" 4768942cc58Snicm }, 4778942cc58Snicm { .name = "iTerm2", 47825373524Snicm .features = TTY_FEATURES_BASE_MODERN_XTERM 4792df6775cSnicm ",cstyle,extkeys,margins,usstyle,sync,osc7,hyperlinks" 4808942cc58Snicm }, 481*a65ab485Snicm { .name = "foot", 482*a65ab485Snicm .features = TTY_FEATURES_BASE_MODERN_XTERM 483*a65ab485Snicm ",cstyle,extkeys" 484*a65ab485Snicm }, 4858942cc58Snicm { .name = "XTerm", 486dd3a9cf8Snicm /* 487dd3a9cf8Snicm * xterm also supports DECSLRM and DECFRA, but they can be 488dd3a9cf8Snicm * disabled so not set it here - they will be added if 489dd3a9cf8Snicm * secondary DA shows VT420. 490dd3a9cf8Snicm */ 49125373524Snicm .features = TTY_FEATURES_BASE_MODERN_XTERM 492dd3a9cf8Snicm ",ccolour,cstyle,extkeys,focus" 4938942cc58Snicm } 4948942cc58Snicm }; 4958942cc58Snicm u_int i; 4968942cc58Snicm 4978942cc58Snicm for (i = 0; i < nitems(table); i++) { 4988942cc58Snicm if (strcmp(table[i].name, name) != 0) 4998942cc58Snicm continue; 5008942cc58Snicm if (version != 0 && version < table[i].version) 5018942cc58Snicm continue; 5028942cc58Snicm tty_add_features(feat, table[i].features, ","); 5038942cc58Snicm } 5048942cc58Snicm } 505