Coverage Report

Created: 2026-07-16 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/tmux/window-border.c
Line
Count
Source
1
/* $OpenBSD: window-border.c,v 1.1 2026/06/22 08:47:46 nicm Exp $ */
2
3
/*
4
 * Copyright (c) 2026 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
/* Get border cell. */
27
void
28
window_get_border_cell(struct window *w, struct window_pane *wp,
29
    enum pane_lines pane_lines, int cell_type, struct grid_cell *gc)
30
0
{
31
0
  u_int idx;
32
33
0
  if (cell_type == CELL_NONE && w->fill_character != NULL) {
34
0
    utf8_copy(&gc->data, &w->fill_character[0]);
35
0
    return;
36
0
  }
37
38
0
  switch (pane_lines) {
39
0
  case PANE_LINES_NUMBER:
40
0
    if (cell_type == CELL_NONE) {
41
0
      gc->attr |= GRID_ATTR_CHARSET;
42
0
      utf8_set(&gc->data, CELL_BORDERS[CELL_NONE]);
43
0
      break;
44
0
    }
45
0
    gc->attr &= ~GRID_ATTR_CHARSET;
46
0
    if (wp != NULL && window_pane_index(wp, &idx) == 0)
47
0
      utf8_set(&gc->data, '0' + (idx % 10));
48
0
    else
49
0
      utf8_set(&gc->data, '*');
50
0
    break;
51
0
  case PANE_LINES_DOUBLE:
52
0
    gc->attr &= ~GRID_ATTR_CHARSET;
53
0
    utf8_copy(&gc->data, tty_acs_double_borders(cell_type));
54
0
    break;
55
0
  case PANE_LINES_HEAVY:
56
0
    gc->attr &= ~GRID_ATTR_CHARSET;
57
0
    utf8_copy(&gc->data, tty_acs_heavy_borders(cell_type));
58
0
    break;
59
0
  case PANE_LINES_SIMPLE:
60
0
    gc->attr &= ~GRID_ATTR_CHARSET;
61
0
    utf8_set(&gc->data, SIMPLE_BORDERS[cell_type]);
62
0
    break;
63
0
  case PANE_LINES_NONE:
64
0
  case PANE_LINES_SPACES:
65
0
    gc->attr &= ~GRID_ATTR_CHARSET;
66
0
    utf8_set(&gc->data, ' ');
67
0
    break;
68
0
  default:
69
0
    gc->attr |= GRID_ATTR_CHARSET;
70
0
    utf8_set(&gc->data, CELL_BORDERS[cell_type]);
71
0
    break;
72
0
  }
73
0
}
74
75
/* Get pane border cell. */
76
void
77
window_pane_get_border_cell(struct window_pane *wp, int cell_type,
78
    struct grid_cell *gc)
79
0
{
80
0
  enum pane_lines pane_lines = window_pane_get_pane_lines(wp);
81
82
0
  window_get_border_cell(wp->window, wp, pane_lines, cell_type, gc);
83
0
}
84
85
/* Get pane border style. */
86
void
87
window_pane_get_border_style(struct window_pane *wp, struct client *c,
88
    struct grid_cell *gc)
89
0
{
90
0
  struct session    *s = c->session;
91
0
  struct format_tree  *ft;
92
0
  const char    *option;
93
0
  struct grid_cell  *saved;
94
0
  int     *flag;
95
96
0
  if (wp == server_client_get_pane(c)) {
97
0
    flag = &wp->active_border_gc_set;
98
0
    saved = &wp->active_border_gc;
99
0
    option = "pane-active-border-style";
100
0
  } else {
101
0
    flag = &wp->border_gc_set;
102
0
    saved = &wp->border_gc;
103
0
    option = "pane-border-style";
104
0
  }
105
106
0
  if (!*flag) {
107
0
    ft = format_create_defaults(NULL, c, s, s->curw, wp);
108
0
    style_apply(saved, wp->options, option, ft);
109
0
    format_free(ft);
110
0
    *flag = 1;
111
0
  }
112
0
  memcpy(gc, saved, sizeof *gc);
113
0
}
114
115
/* Build pane status line. */
116
int
117
window_make_pane_status(struct window_pane *wp, struct client *c, u_int width,
118
    struct redraw_span *span)
119
0
{
120
0
  struct grid_cell   gc;
121
0
  const char    *fmt;
122
0
  struct format_tree  *ft;
123
0
  struct style_line_entry *sle = &wp->border_status_line;
124
0
  struct screen_write_ctx  ctx;
125
0
  struct screen    old;
126
0
  char      *expanded;
127
0
  u_int      i;
128
0
  enum pane_lines    pane_lines;
129
0
  int      pane_status, cell_type;
130
131
0
  pane_status = window_pane_get_pane_status(wp);
132
0
  if (pane_status == PANE_STATUS_OFF || width == 0)
133
0
    return (0);
134
135
0
  ft = format_create(c, NULL, FORMAT_PANE|wp->id, FORMAT_STATUS);
136
0
  format_defaults(ft, c, c->session, c->session->curw, wp);
137
138
0
  fmt = options_get_string(wp->options, "pane-border-format");
139
0
  expanded = format_expand_time(ft, fmt);
140
141
0
  memcpy(&old, &wp->status_screen, sizeof old);
142
0
  screen_init(&wp->status_screen, width, 1, 0);
143
0
  wp->status_screen.mode = 0;
144
0
  screen_write_start(&ctx, &wp->status_screen);
145
146
0
  window_pane_get_border_style(wp, c, &gc);
147
0
  pane_lines = window_pane_get_pane_lines(wp);
148
0
  for (i = 0; i < width; i++) {
149
0
    cell_type = redraw_get_status_border_cell_type(&span, i);
150
0
    window_get_border_cell(wp->window, wp, pane_lines, cell_type, &gc);
151
0
    screen_write_cell(&ctx, &gc);
152
0
  }
153
0
  gc.attr &= ~GRID_ATTR_CHARSET;
154
155
0
  screen_write_cursormove(&ctx, 0, 0, 0);
156
0
  style_ranges_free(&sle->ranges);
157
0
  format_draw(&ctx, &gc, width, expanded, &sle->ranges, 0);
158
159
0
  screen_write_stop(&ctx);
160
0
  format_free(ft);
161
162
0
  free(sle->expanded);
163
0
  sle->expanded = expanded;
164
165
0
  if (grid_compare(wp->status_screen.grid, old.grid) == 0) {
166
0
    screen_free(&old);
167
0
    return (0);
168
0
  }
169
0
  screen_free(&old);
170
0
  return (1);
171
0
}