Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 334 lines (289 sloc) 9.171 kb
798186b Romain Francoise Import upstream version 1.6
orebokech authored
1 /* $Id: screen-redraw.c 2673 2012-01-23 12:23:27Z tcunha $ */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
2
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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 <string.h>
22
23 #include "tmux.h"
24
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
25 int screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
26 int screen_redraw_cell_border(struct client *, u_int, u_int);
27 int screen_redraw_check_cell(struct client *, u_int, u_int);
28 void screen_redraw_draw_number(struct client *, struct window_pane *);
29
30 #define CELL_INSIDE 0
31 #define CELL_LEFTRIGHT 1
32 #define CELL_TOPBOTTOM 2
33 #define CELL_TOPLEFT 3
34 #define CELL_TOPRIGHT 4
35 #define CELL_BOTTOMLEFT 5
36 #define CELL_BOTTOMRIGHT 6
37 #define CELL_TOPJOIN 7
38 #define CELL_BOTTOMJOIN 8
39 #define CELL_LEFTJOIN 9
40 #define CELL_RIGHTJOIN 10
41 #define CELL_JOIN 11
42 #define CELL_OUTSIDE 12
43
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
44 #define CELL_BORDERS " xqlkmjwvtun~"
45
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
46 /* Check if cell is on the border of a particular pane. */
47 int
48 screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
49 {
50 /* Inside pane. */
51 if (px >= wp->xoff && px < wp->xoff + wp->sx &&
52 py >= wp->yoff && py < wp->yoff + wp->sy)
53 return (0);
54
55 /* Left/right borders. */
56 if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= wp->yoff + wp->sy) {
57 if (wp->xoff != 0 && px == wp->xoff - 1)
58 return (1);
59 if (px == wp->xoff + wp->sx)
60 return (1);
61 }
62
63 /* Top/bottom borders. */
64 if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
65 if (wp->yoff != 0 && py == wp->yoff - 1)
66 return (1);
67 if (py == wp->yoff + wp->sy)
68 return (1);
69 }
70
71 /* Outside pane. */
72 return (-1);
73 }
74
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
75 /* Check if a cell is on the pane border. */
76 int
77 screen_redraw_cell_border(struct client *c, u_int px, u_int py)
78 {
79 struct window *w = c->session->curw->window;
80 struct window_pane *wp;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
81 int retval;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
82
83 /* Check all the panes. */
84 TAILQ_FOREACH(wp, &w->panes, entry) {
85 if (!window_pane_visible(wp))
86 continue;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
87 if ((retval = screen_redraw_cell_border1(wp, px, py)) != -1)
88 return (retval);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
89 }
90
91 return (0);
92 }
93
94 /* Check if cell inside a pane. */
95 int
96 screen_redraw_check_cell(struct client *c, u_int px, u_int py)
97 {
98 struct window *w = c->session->curw->window;
99 struct window_pane *wp;
100 int borders;
101
102 if (px > w->sx || py > w->sy)
103 return (CELL_OUTSIDE);
104
105 TAILQ_FOREACH(wp, &w->panes, entry) {
106 if (!window_pane_visible(wp))
107 continue;
108
109 /* If outside the pane and its border, skip it. */
110 if ((wp->xoff != 0 && px < wp->xoff - 1) ||
111 px > wp->xoff + wp->sx ||
112 (wp->yoff != 0 && py < wp->yoff - 1) ||
113 py > wp->yoff + wp->sy)
114 continue;
115
116 /* If definitely inside, return so. */
117 if (!screen_redraw_cell_border(c, px, py))
118 return (CELL_INSIDE);
119
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
120 /*
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
121 * Construct a bitmask of whether the cells to the left (bit
122 * 4), right, top, and bottom (bit 1) of this cell are borders.
123 */
124 borders = 0;
125 if (px == 0 || screen_redraw_cell_border(c, px - 1, py))
126 borders |= 8;
127 if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
128 borders |= 4;
129 if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
130 borders |= 2;
131 if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
132 borders |= 1;
133
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
134 /*
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
135 * Figure out what kind of border this cell is. Only one bit
136 * set doesn't make sense (can't have a border cell with no
137 * others connected).
138 */
139 switch (borders) {
140 case 15: /* 1111, left right top bottom */
141 return (CELL_JOIN);
142 case 14: /* 1110, left right top */
143 return (CELL_BOTTOMJOIN);
144 case 13: /* 1101, left right bottom */
145 return (CELL_TOPJOIN);
146 case 12: /* 1100, left right */
147 return (CELL_TOPBOTTOM);
148 case 11: /* 1011, left top bottom */
149 return (CELL_RIGHTJOIN);
150 case 10: /* 1010, left top */
151 return (CELL_BOTTOMRIGHT);
152 case 9: /* 1001, left bottom */
153 return (CELL_TOPRIGHT);
154 case 7: /* 0111, right top bottom */
155 return (CELL_LEFTJOIN);
156 case 6: /* 0110, right top */
157 return (CELL_BOTTOMLEFT);
158 case 5: /* 0101, right bottom */
159 return (CELL_TOPLEFT);
160 case 3: /* 0011, top bottom */
161 return (CELL_LEFTRIGHT);
162 }
163 }
164
165 return (CELL_OUTSIDE);
166 }
167
168 /* Redraw entire screen. */
169 void
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
170 screen_redraw_screen(struct client *c, int status_only, int borders_only)
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
171 {
172 struct window *w = c->session->curw->window;
173 struct tty *tty = &c->tty;
174 struct window_pane *wp;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
175 struct grid_cell active_gc, other_gc;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
176 u_int i, j, type;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
177 int status, fg, bg;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
178
7216c39 Karl Ferdinand Ebert Imported Upstream version 1.5
kfebert authored
179 /* Suspended clients should not be updated. */
180 if (c->flags & CLIENT_SUSPENDED)
181 return;
182
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
183 /* Get status line, er, status. */
184 if (c->message_string != NULL || c->prompt_string != NULL)
185 status = 1;
186 else
187 status = options_get_number(&c->session->options, "status");
188
189 /* If only drawing status and it is present, don't need the rest. */
190 if (status_only && status) {
191 tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
192 tty_reset(tty);
193 return;
194 }
195
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
196 /* Set up pane border attributes. */
197 memcpy(&other_gc, &grid_default_cell, sizeof other_gc);
198 memcpy(&active_gc, &grid_default_cell, sizeof active_gc);
199 active_gc.data = other_gc.data = 'x'; /* not space */
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
200 active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
201 fg = options_get_number(&c->session->options, "pane-border-fg");
202 colour_set_fg(&other_gc, fg);
203 bg = options_get_number(&c->session->options, "pane-border-bg");
204 colour_set_bg(&other_gc, bg);
205 fg = options_get_number(&c->session->options, "pane-active-border-fg");
206 colour_set_fg(&active_gc, fg);
207 bg = options_get_number(&c->session->options, "pane-active-border-bg");
208 colour_set_bg(&active_gc, bg);
209
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
210 /* Draw background and borders. */
211 for (j = 0; j < tty->sy - status; j++) {
212 if (status_only && j != tty->sy - 1)
213 continue;
214 for (i = 0; i < tty->sx; i++) {
215 type = screen_redraw_check_cell(c, i, j);
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
216 if (type == CELL_INSIDE)
217 continue;
218 if (screen_redraw_cell_border1(w->active, i, j) == 1)
219 tty_attributes(tty, &active_gc);
220 else
221 tty_attributes(tty, &other_gc);
222 tty_cursor(tty, i, j);
77c63de Romain Francoise Import upstream version 1.4
orebokech authored
223 tty_putc(tty, CELL_BORDERS[type]);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
224 }
225 }
226
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
227 /* If only drawing borders, that's it. */
228 if (borders_only)
229 return;
230
231 /* Draw the panes, if necessary. */
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
232 TAILQ_FOREACH(wp, &w->panes, entry) {
233 if (!window_pane_visible(wp))
234 continue;
235 for (i = 0; i < wp->sy; i++) {
236 if (status_only && wp->yoff + i != tty->sy - 1)
237 continue;
238 tty_draw_line(tty, wp->screen, i, wp->xoff, wp->yoff);
239 }
240 if (c->flags & CLIENT_IDENTIFY)
241 screen_redraw_draw_number(c, wp);
242 }
243
244 /* Draw the status line. */
245 if (status)
246 tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
247 tty_reset(tty);
248 }
249
250 /* Draw a single pane. */
251 void
252 screen_redraw_pane(struct client *c, struct window_pane *wp)
253 {
254 u_int i;
255
256 for (i = 0; i < wp->sy; i++)
257 tty_draw_line(&c->tty, wp->screen, i, wp->xoff, wp->yoff);
258 tty_reset(&c->tty);
259 }
260
261 /* Draw number on a pane. */
262 void
263 screen_redraw_draw_number(struct client *c, struct window_pane *wp)
264 {
265 struct tty *tty = &c->tty;
266 struct session *s = c->session;
d873474 Romain Francoise Import upstream snapshot from SVN r2642
orebokech authored
267 struct options *oo = &s->options;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
268 struct window *w = wp->window;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
269 struct grid_cell gc;
270 u_int idx, px, py, i, j, xoff, yoff;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
271 int colour, active_colour;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
272 char buf[16], *ptr;
273 size_t len;
274
d873474 Romain Francoise Import upstream snapshot from SVN r2642
orebokech authored
275 if (window_pane_index(wp, &idx) != 0)
276 fatalx("index not found");
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
277 len = xsnprintf(buf, sizeof buf, "%u", idx);
278
279 if (wp->sx < len)
280 return;
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
281 colour = options_get_number(oo, "display-panes-colour");
282 active_colour = options_get_number(oo, "display-panes-active-colour");
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
283
284 px = wp->sx / 2; py = wp->sy / 2;
285 xoff = wp->xoff; yoff = wp->yoff;
286
287 if (wp->sx < len * 6 || wp->sy < 5) {
288 tty_cursor(tty, xoff + px - len / 2, yoff + py);
798186b Romain Francoise Import upstream version 1.6
orebokech authored
289 goto draw_text;
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
290 }
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
291
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
292 px -= len * 3;
293 py -= 2;
294
295 memcpy(&gc, &grid_default_cell, sizeof gc);
296 gc.data = '_'; /* not space */
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
297 if (w->active == wp)
298 colour_set_bg(&gc, active_colour);
299 else
300 colour_set_bg(&gc, colour);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
301 tty_attributes(tty, &gc);
302 for (ptr = buf; *ptr != '\0'; ptr++) {
303 if (*ptr < '0' || *ptr > '9')
304 continue;
305 idx = *ptr - '0';
dda8e8e Karl Ferdinand Ebert Imported Upstream version 1.2
kfebert authored
306
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
307 for (j = 0; j < 5; j++) {
308 for (i = px; i < px + 5; i++) {
309 tty_cursor(tty, xoff + i, yoff + py + j);
310 if (clock_table[idx][j][i - px])
311 tty_putc(tty, ' ');
312 }
313 }
314 px += 6;
315 }
798186b Romain Francoise Import upstream version 1.6
orebokech authored
316
317 len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy);
318 if (wp->sx < len || wp->sy < 6)
319 return;
320 tty_cursor(tty, xoff + wp->sx - len, yoff);
321
322 draw_text:
323 memcpy(&gc, &grid_default_cell, sizeof gc);
324 gc.data = '_'; /* not space */
325 if (w->active == wp)
326 colour_set_fg(&gc, active_colour);
327 else
328 colour_set_fg(&gc, colour);
329 tty_attributes(tty, &gc);
330 tty_puts(tty, buf);
331
332 tty_cursor(tty, 0, 0);
8fade26 Imported Upstream version 1.1
Karl Ferdinand Ebert authored
333 }
Something went wrong with that request. Please try again.