Coverage Report

Created: 2026-10-17 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/tty-features.c
Line
Count
Source
1
/* $OpenBSD: tty-features.c,v 1.51 2026/10/16 16:49:13 nicm Exp $ */
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
#if defined(HAVE_CURSES_H)
25
#include <curses.h>
26
#elif defined(HAVE_NCURSES_H)
27
#include <ncurses.h>
28
#endif
29
30
#include "tmux.h"
31
32
/*
33
 * Still hardcoded:
34
 * - default colours (under AX or op capabilities);
35
 * - AIX colours (under colors >= 16);
36
 * - alternate escape (if terminal is VT100-like).
37
 *
38
 * Also:
39
 * - DECFRA uses a flag instead of capabilities;
40
 * - UTF-8 is a separate flag on the client; needed for unattached clients.
41
 */
42
43
/* A named terminal feature. */
44
struct tty_feature {
45
  const char    *name;
46
  const char *const *capabilities;
47
  int      flags;
48
};
49
50
/* Terminal has xterm(1) title setting. */
51
static const char *const tty_feature_title_capabilities[] = {
52
  "tsl=\\E]0;", /* should be using TS really */
53
  "fsl=\\a",
54
  NULL
55
};
56
static const struct tty_feature tty_feature_title = {
57
  "title",
58
  tty_feature_title_capabilities,
59
  0
60
};
61
62
/* Terminal has OSC 7 working directory. */
63
static const char *const tty_feature_osc7_capabilities[] = {
64
  "Swd=\\E]7;",
65
  "fsl=\\a",
66
  NULL
67
};
68
static const struct tty_feature tty_feature_osc7 = {
69
  "osc7",
70
  tty_feature_osc7_capabilities,
71
  0
72
};
73
74
/* Terminal has mouse support. */
75
static const char *const tty_feature_mouse_capabilities[] = {
76
  "kmous=\\E[M",
77
  NULL
78
};
79
static const struct tty_feature tty_feature_mouse = {
80
  "mouse",
81
  tty_feature_mouse_capabilities,
82
  0
83
};
84
85
/* Terminal can set the clipboard with OSC 52. */
86
static const char *const tty_feature_clipboard_capabilities[] = {
87
  "Ms=\\E]52;%p1%s;%p2%s\\a",
88
  NULL
89
};
90
static const struct tty_feature tty_feature_clipboard = {
91
  "clipboard",
92
  tty_feature_clipboard_capabilities,
93
  0
94
};
95
96
/* Terminal supports OSC 8 hyperlinks. */
97
static const char *tty_feature_hyperlinks_capabilities[] = {
98
#if defined (__OpenBSD__) || (defined(NCURSES_VERSION_MAJOR) && \
99
  (NCURSES_VERSION_MAJOR > 5 || \
100
  (NCURSES_VERSION_MAJOR == 5 && NCURSES_VERSION_MINOR > 8)))
101
  "Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\",
102
#endif
103
  NULL
104
};
105
static const struct tty_feature tty_feature_hyperlinks = {
106
  "hyperlinks",
107
  tty_feature_hyperlinks_capabilities,
108
  0
109
};
110
111
/*
112
 * Terminal supports RGB colour. This replaces setab and setaf also since
113
 * terminals with RGB have versions that do not allow setting colours from the
114
 * 256 palette.
115
 */
116
static const char *const tty_feature_rgb_capabilities[] = {
117
  "AX",
118
  "setrgbf=\\E[38;2;%p1%d;%p2%d;%p3%dm",
119
  "setrgbb=\\E[48;2;%p1%d;%p2%d;%p3%dm",
120
  "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
121
  "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
122
  NULL
123
};
124
static const struct tty_feature tty_feature_rgb = {
125
  "RGB",
126
  tty_feature_rgb_capabilities,
127
  TERM_256COLOURS|TERM_RGBCOLOURS
128
};
129
130
/* Terminal supports 256 colours. */
131
static const char *const tty_feature_256_capabilities[] = {
132
  "AX",
133
  "setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
134
  "setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
135
  NULL
136
};
137
static const struct tty_feature tty_feature_256 = {
138
  "256",
139
  tty_feature_256_capabilities,
140
  TERM_256COLOURS
141
};
142
143
/* Terminal supports overline. */
144
static const char *const tty_feature_overline_capabilities[] = {
145
  "Smol=\\E[53m",
146
  NULL
147
};
148
static const struct tty_feature tty_feature_overline = {
149
  "overline",
150
  tty_feature_overline_capabilities,
151
  0
152
};
153
154
/* Terminal supports underscore styles. */
155
static const char *const tty_feature_usstyle_capabilities[] = {
156
  "Smulx=\\E[4::%p1%dm",
157
  "Setulc=\\E[58::2::%p1%{65536}%/%d::%p1%{256}%/%{255}%&%d::%p1%{255}%&%d%;m",
158
  "Setulc1=\\E[58::5::%p1%dm",
159
  "ol=\\E[59m",
160
  NULL
161
};
162
static const struct tty_feature tty_feature_usstyle = {
163
  "usstyle",
164
  tty_feature_usstyle_capabilities,
165
  0
166
};
167
168
/* Terminal supports bracketed paste. */
169
static const char *const tty_feature_bpaste_capabilities[] = {
170
  "Enbp=\\E[?2004h",
171
  "Dsbp=\\E[?2004l",
172
  NULL
173
};
174
static const struct tty_feature tty_feature_bpaste = {
175
  "bpaste",
176
  tty_feature_bpaste_capabilities,
177
  0
178
};
179
180
/* Terminal supports focus reporting. */
181
static const char *const tty_feature_focus_capabilities[] = {
182
  "Enfcs=\\E[?1004h",
183
  "Dsfcs=\\E[?1004l",
184
  NULL
185
};
186
static const struct tty_feature tty_feature_focus = {
187
  "focus",
188
  tty_feature_focus_capabilities,
189
  0
190
};
191
192
/* Terminal supports application escape key mode. */
193
static const char *const tty_feature_appesc_capabilities[] = {
194
  "Enesc=\\E[?7727h",
195
  "Dsesc=\\E[?7727l",
196
  NULL
197
};
198
static const struct tty_feature tty_feature_appesc = {
199
  "appesc",
200
  tty_feature_appesc_capabilities,
201
  0
202
};
203
204
/* Terminal supports cursor styles. */
205
static const char *const tty_feature_cstyle_capabilities[] = {
206
  "Ss=\\E[%p1%d q",
207
  "Se=\\E[2 q",
208
  NULL
209
};
210
static const struct tty_feature tty_feature_cstyle = {
211
  "cstyle",
212
  tty_feature_cstyle_capabilities,
213
  TERM_NOREPLACE
214
};
215
216
/* Terminal supports cursor colours. */
217
static const char *const tty_feature_ccolour_capabilities[] = {
218
  "Cs=\\E]12;%p1%s\\a",
219
  "Cr=\\E]112\\a",
220
  NULL
221
};
222
static const struct tty_feature tty_feature_ccolour = {
223
  "ccolour",
224
  tty_feature_ccolour_capabilities,
225
  0
226
};
227
228
/* Terminal supports strikethrough. */
229
static const char *const tty_feature_strikethrough_capabilities[] = {
230
  "smxx=\\E[9m",
231
  NULL
232
};
233
static const struct tty_feature tty_feature_strikethrough = {
234
  "strikethrough",
235
  tty_feature_strikethrough_capabilities,
236
  0
237
};
238
239
/* Terminal supports synchronized updates. */
240
static const char *const tty_feature_sync_capabilities[] = {
241
  "Sync=\\E[?2026%?%p1%{1}%-%tl%eh%;",
242
  NULL
243
};
244
static const struct tty_feature tty_feature_sync = {
245
  "sync",
246
  tty_feature_sync_capabilities,
247
  0
248
};
249
250
/* Terminal supports extended keys. */
251
static const char *const tty_feature_extkeys_capabilities[] = {
252
  "Eneks=\\E[>4;2m",
253
  "Dseks=\\E[>4m",
254
  NULL
255
};
256
static const struct tty_feature tty_feature_extkeys = {
257
  "extkeys",
258
  tty_feature_extkeys_capabilities,
259
  0
260
};
261
262
/* Terminal supports DECSLRM margins. */
263
static const char *const tty_feature_margins_capabilities[] = {
264
  "Enmg=\\E[?69h",
265
  "Dsmg=\\E[?69l",
266
  "Clmg=\\E[s",
267
  "Cmg=\\E[%i%p1%d;%p2%ds",
268
  NULL
269
};
270
static const struct tty_feature tty_feature_margins = {
271
  "margins",
272
  tty_feature_margins_capabilities,
273
  TERM_DECSLRM
274
};
275
276
/* Terminal supports DECFRA rectangle fill. */
277
static const char *const tty_feature_rectfill_capabilities[] = {
278
  "Rect",
279
  NULL
280
};
281
static const struct tty_feature tty_feature_rectfill = {
282
  "rectfill",
283
  tty_feature_rectfill_capabilities,
284
  TERM_DECFRA
285
};
286
287
/* Use builtin function keys only. */
288
static const char *const tty_feature_ignorefkeys_capabilities[] = {
289
  "kf0@",
290
  "kf1@",
291
  "kf2@",
292
  "kf3@",
293
  "kf4@",
294
  "kf5@",
295
  "kf6@",
296
  "kf7@",
297
  "kf8@",
298
  "kf9@",
299
  "kf10@",
300
  "kf11@",
301
  "kf12@",
302
  "kf13@",
303
  "kf14@",
304
  "kf15@",
305
  "kf16@",
306
  "kf17@",
307
  "kf18@",
308
  "kf19@",
309
  "kf20@",
310
  "kf21@",
311
  "kf22@",
312
  "kf23@",
313
  "kf24@",
314
  "kf25@",
315
  "kf26@",
316
  "kf27@",
317
  "kf28@",
318
  "kf29@",
319
  "kf30@",
320
  "kf31@",
321
  "kf32@",
322
  "kf33@",
323
  "kf34@",
324
  "kf35@",
325
  "kf36@",
326
  "kf37@",
327
  "kf38@",
328
  "kf39@",
329
  "kf40@",
330
  "kf41@",
331
  "kf42@",
332
  "kf43@",
333
  "kf44@",
334
  "kf45@",
335
  "kf46@",
336
  "kf47@",
337
  "kf48@",
338
  "kf49@",
339
  "kf50@",
340
  "kf51@",
341
  "kf52@",
342
  "kf53@",
343
  "kf54@",
344
  "kf55@",
345
  "kf56@",
346
  "kf57@",
347
  "kf58@",
348
  "kf59@",
349
  "kf60@",
350
  "kf61@",
351
  "kf62@",
352
  "kf63@",
353
  NULL
354
};
355
static const struct tty_feature tty_feature_ignorefkeys = {
356
  "ignorefkeys",
357
  tty_feature_ignorefkeys_capabilities,
358
  0
359
};
360
361
/* Terminal has sixel capability. */
362
static const char *const tty_feature_sixel_capabilities[] = {
363
  "Sxl",
364
  NULL
365
};
366
static const struct tty_feature tty_feature_sixel = {
367
  "sixel",
368
  tty_feature_sixel_capabilities,
369
  TERM_SIXEL
370
};
371
372
/* Terminal supports the Kitty graphics protocol. */
373
static const struct tty_feature tty_feature_kittygraphics = {
374
  "kittygraphics",
375
  NULL,
376
  TERM_KITTYGRAPHICS
377
};
378
379
/* Terminal moves images with scroll regions. */
380
static const char *const tty_feature_imagescroll_capabilities[] = {
381
  "Iscrl",
382
  NULL
383
};
384
static const struct tty_feature tty_feature_imagescroll = {
385
  "imagescroll",
386
  tty_feature_imagescroll_capabilities,
387
  0
388
};
389
390
/* Terminal supports the OSC 9;4 progress bar. */
391
static const char *const tty_feature_progressbar_capabilities[] = {
392
  "Spb=\\E]9;4;%p1%d;%p2%d\\E\\\\",
393
  NULL
394
};
395
static const struct tty_feature tty_feature_progressbar = {
396
  "progressbar",
397
  tty_feature_progressbar_capabilities,
398
  0
399
};
400
401
/* Terminal supports UTF-8. */
402
static const struct tty_feature tty_feature_utf8 = {
403
  "utf8",
404
  NULL,
405
  0
406
};
407
408
/* Available terminal features. */
409
static const struct tty_feature *const tty_features[] = {
410
  &tty_feature_256,
411
  &tty_feature_appesc,
412
  &tty_feature_bpaste,
413
  &tty_feature_ccolour,
414
  &tty_feature_clipboard,
415
  &tty_feature_hyperlinks,
416
  &tty_feature_cstyle,
417
  &tty_feature_extkeys,
418
  &tty_feature_focus,
419
  &tty_feature_ignorefkeys,
420
  &tty_feature_imagescroll,
421
  &tty_feature_kittygraphics,
422
  &tty_feature_margins,
423
  &tty_feature_mouse,
424
  &tty_feature_osc7,
425
  &tty_feature_overline,
426
  &tty_feature_progressbar,
427
  &tty_feature_rectfill,
428
  &tty_feature_rgb,
429
  &tty_feature_sixel,
430
  &tty_feature_strikethrough,
431
  &tty_feature_sync,
432
  &tty_feature_title,
433
  &tty_feature_usstyle,
434
  &tty_feature_utf8
435
};
436
437
/* Parse features for client. */
438
void
439
tty_parse_client_features(struct client *c, const char *s, const char *sep)
440
0
{
441
0
  tty_parse_features(s, sep, &c->term_features, &c->term_nofeatures);
442
0
}
443
444
/* Parse features list. */
445
void
446
tty_parse_features(const char *s, const char *sep, int *enabled, int *disabled)
447
0
{
448
0
  const struct tty_feature   *tf;
449
0
  char         *next, *loop, *copy;
450
0
  u_int         i;
451
0
  int         remove;
452
453
0
  log_debug("adding terminal features %s", s);
454
455
0
  loop = copy = xstrdup(s);
456
0
  while ((next = strsep(&loop, sep)) != NULL) {
457
0
    remove = (*next != '\0' && next[strlen(next) - 1] == '@');
458
0
    if (remove)
459
0
      next[strlen(next) - 1] = '\0';
460
0
    for (i = 0; i < nitems(tty_features); i++) {
461
0
      tf = tty_features[i];
462
0
      if (strcasecmp(tf->name, next) == 0)
463
0
        break;
464
0
    }
465
0
    if (i == nitems(tty_features)) {
466
0
      log_debug("unknown terminal feature: %s", next);
467
0
      break;
468
0
    }
469
0
    if (remove) {
470
0
      log_debug("removing terminal feature: %s", tf->name);
471
0
      *enabled &= ~(1 << i);
472
0
      if (disabled != NULL)
473
0
        *disabled |= 1 << i;
474
0
      continue;
475
0
    }
476
0
    if (disabled != NULL && *disabled & (1 << i))
477
0
      continue;
478
0
    if (~(*enabled) & (1 << i)) {
479
0
      log_debug("adding terminal feature: %s", tf->name);
480
0
      (*enabled) |= (1 << i);
481
0
    }
482
0
  }
483
0
  free(copy);
484
0
}
485
486
/* Get features as string. */
487
const char *
488
tty_get_features(int feat)
489
0
{
490
0
  const struct tty_feature  *tf;
491
0
  static char      s[512];
492
0
  u_int        i;
493
494
0
  *s = '\0';
495
0
  for (i = 0; i < nitems(tty_features); i++) {
496
0
    if (~feat & (1 << i))
497
0
      continue;
498
0
    tf = tty_features[i];
499
500
0
    strlcat(s, tf->name, sizeof s);
501
0
    strlcat(s, ",", sizeof s);
502
0
  }
503
0
  if (*s != '\0')
504
0
    s[strlen(s) - 1] = '\0';
505
0
  return (s);
506
0
}
507
508
/* Check if feature is present. */
509
int
510
tty_feature_present(struct tty_term *term, const char *name)
511
0
{
512
0
  const struct tty_feature  *tf = NULL;
513
0
  const char *const   *capability;
514
0
  u_int        i;
515
0
  char        *copy;
516
517
0
  if (strcmp(name, "utf8") == 0)
518
0
    return ((term->tty->client->flags & CLIENT_UTF8) != 0);
519
520
0
  for (i = 0; i < nitems(tty_features); i++) {
521
0
    tf = tty_features[i];
522
0
    if (strcmp(tf->name, name) == 0) {
523
0
      if (term->applied_features & (1 << i))
524
0
        return (1);
525
0
      break;
526
0
    }
527
0
  }
528
529
  /*
530
   * We don't just have the feature flag set. Check if the capabilities
531
   * supported by the client are actual set instead.
532
   */
533
0
  if (tf == NULL || tf->capabilities == NULL ||
534
0
      strcmp(name, "ignorefkeys") == 0)
535
0
    return (0);
536
0
  if (tf->flags != 0 && (term->flags & tf->flags) != tf->flags)
537
0
    return (0);
538
0
  capability = tf->capabilities;
539
0
  while (*capability != NULL) {
540
0
    copy = xstrdup(*capability);
541
0
    copy[strcspn(copy, "=")] = '\0';
542
0
    if (!tty_term_has_name(term, copy)) {
543
0
      free(copy);
544
0
      return (0);
545
0
    }
546
0
    free(copy);
547
0
    capability++;
548
0
  }
549
0
  return (1);
550
0
}
551
552
/* Apply featurs to terminal. */
553
int
554
tty_apply_features(struct tty_term *term)
555
0
{
556
0
  struct client     *c = term->tty->client;
557
0
  const struct tty_feature  *tf;
558
0
  const char *const   *capability;
559
0
  int        feat;
560
0
  u_int        i;
561
562
0
  feat = (c->term_features & ~c->term_nofeatures);
563
0
  if (feat == 0)
564
0
    return (0);
565
0
  log_debug("applying terminal features: %s", tty_get_features(feat));
566
567
0
  for (i = 0; i < nitems(tty_features); i++) {
568
0
    if ((term->applied_features & (1 << i)) || (~feat & (1 << i)))
569
0
      continue;
570
0
    tf = tty_features[i];
571
572
0
    log_debug("applying terminal feature: %s", tf->name);
573
0
    if (tf->capabilities != NULL) {
574
0
      capability = tf->capabilities;
575
0
      while (*capability != NULL) {
576
0
        log_debug("adding capability: %s", *capability);
577
0
        tty_term_apply(term, *capability, 1, tf->flags);
578
0
        capability++;
579
0
      }
580
0
    }
581
0
    term->flags |= (tf->flags & ~TERM_NOREPLACE);
582
0
    if (tf == &tty_feature_utf8)
583
0
      c->flags |= CLIENT_UTF8;
584
0
  }
585
0
  if ((term->applied_features|feat) == term->applied_features)
586
0
    return (0);
587
0
  term->applied_features |= feat;
588
0
  return (1);
589
0
}
590
591
/* Add default features for a terminal identified by name and version. */
592
void
593
tty_default_features(struct client *c, const char *name, u_int version)
594
0
{
595
0
  static const struct {
596
0
    const char  *name;
597
0
    u_int    version;
598
0
    const char  *features;
599
0
  } table[] = {
600
0
#define TTY_FEATURES_BASE_MODERN_XTERM \
601
0
  "256,RGB,bpaste,clipboard,mouse,strikethrough,title"
602
0
    { .name = "mintty",
603
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
604
0
            "appesc,"
605
0
            "ccolour,"
606
0
            "cstyle,"
607
0
            "extkeys,"
608
0
            "margins,"
609
0
            "overline,"
610
0
            "usstyle"
611
0
    },
612
0
    { .name = "tmux",
613
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
614
0
            "ccolour,"
615
0
            "cstyle,"
616
0
            "extkeys,"
617
0
            "focus,"
618
0
            "overline,"
619
0
            "usstyle,"
620
0
            "hyperlinks,"
621
0
              "progressbar"
622
0
    },
623
0
    { .name = "rxvt-unicode",
624
0
      .features = "256,"
625
0
            "bpaste,"
626
0
            "ccolour,"
627
0
            "cstyle,"
628
0
            "mouse,"
629
0
            "title,"
630
0
            "ignorefkeys"
631
0
    },
632
0
    { .name = "iTerm2",
633
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
634
0
            "cstyle,"
635
0
            "extkeys,"
636
0
            "margins,"
637
0
            "usstyle,"
638
0
            "sync,"
639
0
            "osc7,"
640
0
            "hyperlinks,"
641
0
              "progressbar"
642
0
    },
643
0
    { .name = "foot",
644
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
645
0
            "ccolour,"
646
0
            "cstyle,"
647
0
            "extkeys,"
648
0
            "usstyle,"
649
0
            "sync,"
650
0
            "osc7,"
651
0
            "hyperlinks"
652
0
    },
653
0
    { .name = "WezTerm",
654
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
655
0
            "ccolour,"
656
0
            "cstyle,"
657
0
            "extkeys,"
658
0
            "focus,"
659
0
              "hyperlinks,"
660
0
            "imagescroll,"
661
0
            "margins,"
662
0
            "sixel,"
663
0
            "usstyle"
664
0
    },
665
0
    { .name = "ghostty",
666
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
667
0
            "ccolour,"
668
0
            "cstyle,"
669
0
            "extkeys,"
670
0
            "focus,"
671
0
            "imagescroll,"
672
0
            "margins,"
673
0
            "overline,"
674
0
            "hyperlinks,"
675
0
            "osc7,"
676
0
            "sync,"
677
0
            "usstyle,"
678
0
            "progressbar,"
679
0
            "kittygraphics"
680
0
    },
681
0
    { .name = "kitty",
682
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
683
0
            "ccolour,"
684
0
            "cstyle,"
685
0
            "extkeys,"
686
0
            "focus,"
687
0
            "hyperlinks,"
688
0
            "imagescroll,"
689
0
            "osc7,"
690
0
            "sync,"
691
0
            "usstyle,"
692
0
            "kittygraphics"
693
0
    },
694
0
    { .name = "Rio",
695
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
696
0
            "ccolour,"
697
0
            "cstyle,"
698
0
            "focus,"
699
0
            "overline,"
700
0
            "hyperlinks,"
701
0
            "osc7,"
702
0
            "sync,"
703
0
            "usstyle,"
704
0
            "progressbar"
705
0
    },
706
0
    { .name = "XTerm",
707
      /*
708
       * xterm also supports DECSLRM and DECFRA, but they can be
709
       * disabled so not set it here - they will be added if
710
       * secondary DA shows VT420.
711
       */
712
0
      .features = TTY_FEATURES_BASE_MODERN_XTERM ","
713
0
            "ccolour,"
714
0
            "cstyle,"
715
0
            "extkeys,"
716
0
            "focus"
717
0
    },
718
0
  };
719
0
  u_int i;
720
721
0
  for (i = 0; i < nitems(table); i++) {
722
0
    if (strcmp(table[i].name, name) != 0)
723
0
      continue;
724
0
    if (version != 0 && version < table[i].version)
725
0
      continue;
726
0
    tty_parse_client_features(c, table[i].features, ",");
727
0
  }
728
0
}