Annotation of src/usr.bin/tmux/screen-redraw.c, Revision 1.37
1.37 ! nicm 1: /* $OpenBSD: screen-redraw.c,v 1.36 2016/04/29 15:00:48 nicm Exp $ */
1.1 nicm 2:
3: /*
1.35 nicm 4: * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
1.1 nicm 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:
1.15 nicm 25: int screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
1.7 nicm 26: int screen_redraw_cell_border(struct client *, u_int, u_int);
1.36 nicm 27: int screen_redraw_check_cell(struct client *, u_int, u_int, int,
1.24 nicm 28: struct window_pane **);
1.36 nicm 29: int screen_redraw_check_is(u_int, u_int, int, int, struct window *,
1.32 nicm 30: struct window_pane *, struct window_pane *);
1.24 nicm 31:
1.36 nicm 32: int screen_redraw_make_pane_status(struct client *, struct window *,
33: struct window_pane *);
34: void screen_redraw_draw_pane_status(struct client *, int);
35:
36: void screen_redraw_draw_borders(struct client *, int, int, u_int);
1.26 nicm 37: void screen_redraw_draw_panes(struct client *, u_int);
38: void screen_redraw_draw_status(struct client *, u_int);
1.31 nicm 39: void screen_redraw_draw_number(struct client *, struct window_pane *, u_int);
1.1 nicm 40:
1.6 nicm 41: #define CELL_INSIDE 0
1.7 nicm 42: #define CELL_LEFTRIGHT 1
43: #define CELL_TOPBOTTOM 2
44: #define CELL_TOPLEFT 3
45: #define CELL_TOPRIGHT 4
46: #define CELL_BOTTOMLEFT 5
47: #define CELL_BOTTOMRIGHT 6
48: #define CELL_TOPJOIN 7
49: #define CELL_BOTTOMJOIN 8
50: #define CELL_LEFTJOIN 9
51: #define CELL_RIGHTJOIN 10
52: #define CELL_JOIN 11
53: #define CELL_OUTSIDE 12
1.6 nicm 54:
1.17 nicm 55: #define CELL_BORDERS " xqlkmjwvtun~"
56:
1.36 nicm 57: #define CELL_STATUS_OFF 0
58: #define CELL_STATUS_TOP 1
59: #define CELL_STATUS_BOTTOM 2
60:
1.15 nicm 61: /* Check if cell is on the border of a particular pane. */
62: int
63: screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
64: {
65: /* Inside pane. */
66: if (px >= wp->xoff && px < wp->xoff + wp->sx &&
67: py >= wp->yoff && py < wp->yoff + wp->sy)
68: return (0);
69:
70: /* Left/right borders. */
71: if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= wp->yoff + wp->sy) {
72: if (wp->xoff != 0 && px == wp->xoff - 1)
73: return (1);
74: if (px == wp->xoff + wp->sx)
1.36 nicm 75: return (2);
1.15 nicm 76: }
77:
78: /* Top/bottom borders. */
79: if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
80: if (wp->yoff != 0 && py == wp->yoff - 1)
1.36 nicm 81: return (3);
1.15 nicm 82: if (py == wp->yoff + wp->sy)
1.36 nicm 83: return (4);
1.15 nicm 84: }
85:
86: /* Outside pane. */
87: return (-1);
88: }
89:
1.7 nicm 90: /* Check if a cell is on the pane border. */
1.1 nicm 91: int
1.7 nicm 92: screen_redraw_cell_border(struct client *c, u_int px, u_int py)
1.1 nicm 93: {
94: struct window *w = c->session->curw->window;
95: struct window_pane *wp;
1.15 nicm 96: int retval;
1.1 nicm 97:
1.7 nicm 98: /* Check all the panes. */
1.1 nicm 99: TAILQ_FOREACH(wp, &w->panes, entry) {
1.3 nicm 100: if (!window_pane_visible(wp))
101: continue;
1.15 nicm 102: if ((retval = screen_redraw_cell_border1(wp, px, py)) != -1)
1.36 nicm 103: return (!!retval);
1.7 nicm 104: }
105:
106: return (0);
107: }
108:
109: /* Check if cell inside a pane. */
110: int
1.36 nicm 111: screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
1.24 nicm 112: struct window_pane **wpp)
1.7 nicm 113: {
114: struct window *w = c->session->curw->window;
115: struct window_pane *wp;
116: int borders;
1.36 nicm 117: u_int right, line;
1.7 nicm 118:
119: if (px > w->sx || py > w->sy)
120: return (CELL_OUTSIDE);
121:
1.36 nicm 122: if (pane_status != CELL_STATUS_OFF) {
123: TAILQ_FOREACH(wp, &w->panes, entry) {
124: if (!window_pane_visible(wp))
125: continue;
126:
127: if (pane_status == CELL_STATUS_TOP)
128: line = wp->yoff - 1;
129: else
130: line = wp->yoff + wp->sy;
131: right = wp->xoff + 2 + wp->status_size - 1;
132:
133: if (py == line && px >= wp->xoff + 2 && px <= right)
134: return (CELL_INSIDE);
135: }
136: }
137:
1.7 nicm 138: TAILQ_FOREACH(wp, &w->panes, entry) {
139: if (!window_pane_visible(wp))
140: continue;
1.24 nicm 141: *wpp = wp;
1.7 nicm 142:
143: /* If outside the pane and its border, skip it. */
144: if ((wp->xoff != 0 && px < wp->xoff - 1) ||
145: px > wp->xoff + wp->sx ||
146: (wp->yoff != 0 && py < wp->yoff - 1) ||
147: py > wp->yoff + wp->sy)
148: continue;
149:
150: /* If definitely inside, return so. */
151: if (!screen_redraw_cell_border(c, px, py))
152: return (CELL_INSIDE);
153:
1.14 nicm 154: /*
1.7 nicm 155: * Construct a bitmask of whether the cells to the left (bit
156: * 4), right, top, and bottom (bit 1) of this cell are borders.
157: */
158: borders = 0;
159: if (px == 0 || screen_redraw_cell_border(c, px - 1, py))
160: borders |= 8;
161: if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
162: borders |= 4;
1.36 nicm 163: if (pane_status == CELL_STATUS_TOP) {
164: if (py != 0 && screen_redraw_cell_border(c, px, py - 1))
165: borders |= 2;
166: } else {
167: if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
168: borders |= 2;
169: }
1.7 nicm 170: if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
171: borders |= 1;
172:
1.14 nicm 173: /*
1.7 nicm 174: * Figure out what kind of border this cell is. Only one bit
175: * set doesn't make sense (can't have a border cell with no
176: * others connected).
177: */
178: switch (borders) {
179: case 15: /* 1111, left right top bottom */
180: return (CELL_JOIN);
181: case 14: /* 1110, left right top */
182: return (CELL_BOTTOMJOIN);
183: case 13: /* 1101, left right bottom */
184: return (CELL_TOPJOIN);
185: case 12: /* 1100, left right */
186: return (CELL_TOPBOTTOM);
187: case 11: /* 1011, left top bottom */
188: return (CELL_RIGHTJOIN);
189: case 10: /* 1010, left top */
190: return (CELL_BOTTOMRIGHT);
191: case 9: /* 1001, left bottom */
192: return (CELL_TOPRIGHT);
193: case 7: /* 0111, right top bottom */
194: return (CELL_LEFTJOIN);
195: case 6: /* 0110, right top */
196: return (CELL_BOTTOMLEFT);
197: case 5: /* 0101, right bottom */
198: return (CELL_TOPLEFT);
199: case 3: /* 0011, top bottom */
200: return (CELL_LEFTRIGHT);
1.1 nicm 201: }
202: }
203:
1.24 nicm 204: *wpp = NULL;
1.6 nicm 205: return (CELL_OUTSIDE);
1.1 nicm 206: }
207:
1.32 nicm 208: /* Check if the border of a particular pane. */
1.24 nicm 209: int
1.36 nicm 210: screen_redraw_check_is(u_int px, u_int py, int type, int pane_status,
211: struct window *w, struct window_pane *wantwp, struct window_pane *wp)
1.24 nicm 212: {
1.36 nicm 213: int border;
214:
1.24 nicm 215: /* Is this off the active pane border? */
1.36 nicm 216: border = screen_redraw_cell_border1(wantwp, px, py);
217: if (border == 0 || border == -1)
218: return (0);
219: if (pane_status == CELL_STATUS_TOP && border == 4)
220: return (0);
221: if (pane_status == CELL_STATUS_BOTTOM && border == 3)
1.24 nicm 222: return (0);
223:
224: /* If there are more than two panes, that's enough. */
225: if (window_count_panes(w) != 2)
226: return (1);
227:
228: /* Else if the cell is not a border cell, forget it. */
229: if (wp == NULL || (type == CELL_OUTSIDE || type == CELL_INSIDE))
230: return (1);
231:
1.36 nicm 232: /* With status lines mark the entire line. */
233: if (pane_status != CELL_STATUS_OFF)
234: return (1);
235:
1.24 nicm 236: /* Check if the pane covers the whole width. */
237: if (wp->xoff == 0 && wp->sx == w->sx) {
238: /* This can either be the top pane or the bottom pane. */
239: if (wp->yoff == 0) { /* top pane */
1.32 nicm 240: if (wp == wantwp)
1.24 nicm 241: return (px <= wp->sx / 2);
242: return (px > wp->sx / 2);
243: }
244: return (0);
245: }
246:
247: /* Check if the pane covers the whole height. */
248: if (wp->yoff == 0 && wp->sy == w->sy) {
249: /* This can either be the left pane or the right pane. */
250: if (wp->xoff == 0) { /* left pane */
1.32 nicm 251: if (wp == wantwp)
1.24 nicm 252: return (py <= wp->sy / 2);
253: return (py > wp->sy / 2);
254: }
255: return (0);
256: }
257:
1.36 nicm 258: return (1);
259: }
260:
261: /* Update pane status. */
262: int
263: screen_redraw_make_pane_status(struct client *c, struct window *w,
264: struct window_pane *wp)
265: {
266: struct grid_cell gc;
267: const char *fmt;
268: struct format_tree *ft;
269: char *out;
270: size_t outlen, old_size = wp->status_size;
271: struct screen_write_ctx ctx;
272:
273: if (wp == w->active)
274: style_apply(&gc, w->options, "pane-active-border-style");
275: else
276: style_apply(&gc, w->options, "pane-border-style");
277:
278: fmt = options_get_string(w->options, "pane-border-format");
279:
280: ft = format_create(NULL, 0);
281: format_defaults(ft, c, NULL, NULL, wp);
282:
283: screen_free(&wp->status_screen);
284: screen_init(&wp->status_screen, wp->sx, 1, 0);
285: wp->status_screen.mode = 0;
286:
287: out = format_expand(ft, fmt);
288: outlen = screen_write_cstrlen("%s", out);
289: if (outlen > wp->sx - 4)
290: outlen = wp->sx - 4;
291: screen_resize(&wp->status_screen, outlen, 1, 0);
292:
293: screen_write_start(&ctx, NULL, &wp->status_screen);
294: screen_write_cursormove(&ctx, 0, 0);
295: screen_write_clearline(&ctx);
296: screen_write_cnputs(&ctx, outlen, &gc, "%s", out);
297: screen_write_stop(&ctx);
298:
299: format_free(ft);
300:
301: wp->status_size = outlen;
302: return (wp->status_size != old_size);
303: }
304:
305: /* Draw pane status. */
306: void
307: screen_redraw_draw_pane_status(struct client *c, int pane_status)
308: {
309: struct window *w = c->session->curw->window;
310: struct options *oo = c->session->options;
311: struct tty *tty = &c->tty;
312: struct window_pane *wp;
313: int spos;
314: u_int yoff;
315:
316: spos = options_get_number(oo, "status-position");
317: TAILQ_FOREACH(wp, &w->panes, entry) {
318: if (pane_status == CELL_STATUS_TOP)
319: yoff = wp->yoff - 1;
320: else
321: yoff = wp->yoff + wp->sy;
322: if (spos == 0)
323: yoff += 1;
324:
325: tty_draw_line(tty, NULL, &wp->status_screen, 0, wp->xoff + 2,
326: yoff);
327: }
328: tty_cursor(tty, 0, 0);
1.24 nicm 329: }
330:
1.4 nicm 331: /* Redraw entire screen. */
1.1 nicm 332: void
1.26 nicm 333: screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
334: int draw_borders)
1.1 nicm 335: {
1.36 nicm 336: struct options *oo = c->session->options;
337: struct tty *tty = &c->tty;
338: struct window *w = c->session->curw->window;
339: struct window_pane *wp;
340: u_int top;
341: int status, pane_status, spos;
1.18 nicm 342:
343: /* Suspended clients should not be updated. */
344: if (c->flags & CLIENT_SUSPENDED)
345: return;
1.1 nicm 346:
347: /* Get status line, er, status. */
1.21 nicm 348: spos = options_get_number(oo, "status-position");
1.4 nicm 349: if (c->message_string != NULL || c->prompt_string != NULL)
350: status = 1;
351: else
1.21 nicm 352: status = options_get_number(oo, "status");
353: top = 0;
354: if (status && spos == 0)
355: top = 1;
1.26 nicm 356: if (!status)
357: draw_status = 0;
358:
1.36 nicm 359: /* Update pane status lines. */
360: pane_status = options_get_number(w->options, "pane-border-status");
361: if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status)) {
362: TAILQ_FOREACH(wp, &w->panes, entry) {
363: if (screen_redraw_make_pane_status(c, w, wp))
364: draw_borders = draw_status = 1;
365: }
366: }
367:
368: /* Draw the elements. */
1.26 nicm 369: if (draw_borders)
1.36 nicm 370: screen_redraw_draw_borders(c, status, pane_status, top);
1.26 nicm 371: if (draw_panes)
372: screen_redraw_draw_panes(c, top);
373: if (draw_status)
374: screen_redraw_draw_status(c, top);
1.36 nicm 375: if (pane_status != CELL_STATUS_OFF && (draw_borders || draw_status))
376: screen_redraw_draw_pane_status(c, pane_status);
1.26 nicm 377: tty_reset(tty);
378: }
1.4 nicm 379:
1.26 nicm 380: /* Draw a single pane. */
381: void
382: screen_redraw_pane(struct client *c, struct window_pane *wp)
383: {
384: u_int i, yoff;
385:
386: if (!window_pane_visible(wp))
1.4 nicm 387: return;
1.1 nicm 388:
1.26 nicm 389: yoff = wp->yoff;
390: if (status_at_line(c) == 0)
391: yoff++;
392:
393: for (i = 0; i < wp->sy; i++)
1.30 nicm 394: tty_draw_pane(&c->tty, wp, i, wp->xoff, yoff);
1.26 nicm 395: tty_reset(&c->tty);
396: }
397:
398: /* Draw the borders. */
399: void
1.36 nicm 400: screen_redraw_draw_borders(struct client *c, int status, int pane_status,
401: u_int top)
1.26 nicm 402: {
1.32 nicm 403: struct session *s = c->session;
404: struct window *w = s->curw->window;
1.33 nicm 405: struct options *oo = w->options;
1.26 nicm 406: struct tty *tty = &c->tty;
407: struct window_pane *wp;
1.32 nicm 408: struct grid_cell m_active_gc, active_gc, m_other_gc, other_gc;
409: struct grid_cell msg_gc;
1.28 nicm 410: u_int i, j, type, msgx = 0, msgy = 0;
1.32 nicm 411: int active, small, flags;
1.28 nicm 412: char msg[256];
413: const char *tmp;
414: size_t msglen = 0;
415:
416: small = (tty->sy - status + top > w->sy) || (tty->sx > w->sx);
417: if (small) {
418: flags = w->flags & (WINDOW_FORCEWIDTH|WINDOW_FORCEHEIGHT);
419: if (flags == (WINDOW_FORCEWIDTH|WINDOW_FORCEHEIGHT))
420: tmp = "force-width, force-height";
421: else if (flags == WINDOW_FORCEWIDTH)
422: tmp = "force-width";
423: else if (flags == WINDOW_FORCEHEIGHT)
424: tmp = "force-height";
425: else
426: tmp = "a smaller client";
427: xsnprintf(msg, sizeof msg, "(size %ux%u from %s)",
428: w->sx, w->sy, tmp);
429: msglen = strlen(msg);
430:
431: if (tty->sy - 1 - status + top > w->sy && tty->sx >= msglen) {
432: msgx = tty->sx - msglen;
433: msgy = tty->sy - 1 - status + top;
434: } else if (tty->sx - w->sx > msglen) {
435: msgx = tty->sx - msglen;
436: msgy = tty->sy - 1 - status + top;
437: } else
438: small = 0;
439: }
1.26 nicm 440:
1.25 nicm 441: style_apply(&other_gc, oo, "pane-border-style");
442: style_apply(&active_gc, oo, "pane-active-border-style");
1.26 nicm 443: active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
1.15 nicm 444:
1.32 nicm 445: memcpy(&m_other_gc, &other_gc, sizeof m_other_gc);
446: m_other_gc.attr ^= GRID_ATTR_REVERSE;
447: memcpy(&m_active_gc, &active_gc, sizeof m_active_gc);
448: m_active_gc.attr ^= GRID_ATTR_REVERSE;
449:
1.1 nicm 450: for (j = 0; j < tty->sy - status; j++) {
451: for (i = 0; i < tty->sx; i++) {
1.36 nicm 452: type = screen_redraw_check_cell(c, i, j, pane_status,
453: &wp);
1.15 nicm 454: if (type == CELL_INSIDE)
455: continue;
1.32 nicm 456: if (type == CELL_OUTSIDE && small &&
457: i > msgx && j == msgy)
1.28 nicm 458: continue;
1.36 nicm 459: active = screen_redraw_check_is(i, j, type, pane_status,
460: w, w->active, wp);
1.34 nicm 461: if (server_is_marked(s, s->curw, marked_pane.wp) &&
1.36 nicm 462: screen_redraw_check_is(i, j, type, pane_status, w,
1.34 nicm 463: marked_pane.wp, wp)) {
1.32 nicm 464: if (active)
465: tty_attributes(tty, &m_active_gc, NULL);
466: else
467: tty_attributes(tty, &m_other_gc, NULL);
468: } else if (active)
1.30 nicm 469: tty_attributes(tty, &active_gc, NULL);
1.15 nicm 470: else
1.30 nicm 471: tty_attributes(tty, &other_gc, NULL);
1.21 nicm 472: tty_cursor(tty, i, top + j);
1.17 nicm 473: tty_putc(tty, CELL_BORDERS[type]);
1.1 nicm 474: }
1.28 nicm 475: }
476:
477: if (small) {
478: memcpy(&msg_gc, &grid_default_cell, sizeof msg_gc);
1.30 nicm 479: tty_attributes(tty, &msg_gc, NULL);
1.28 nicm 480: tty_cursor(tty, msgx, msgy);
481: tty_puts(tty, msg);
1.1 nicm 482: }
1.26 nicm 483: }
1.1 nicm 484:
1.26 nicm 485: /* Draw the panes. */
486: void
487: screen_redraw_draw_panes(struct client *c, u_int top)
488: {
489: struct window *w = c->session->curw->window;
490: struct tty *tty = &c->tty;
491: struct window_pane *wp;
492: u_int i;
1.15 nicm 493:
1.1 nicm 494: TAILQ_FOREACH(wp, &w->panes, entry) {
1.3 nicm 495: if (!window_pane_visible(wp))
1.1 nicm 496: continue;
1.26 nicm 497: for (i = 0; i < wp->sy; i++)
1.30 nicm 498: tty_draw_pane(tty, wp, i, wp->xoff, top + wp->yoff);
1.10 nicm 499: if (c->flags & CLIENT_IDENTIFY)
1.31 nicm 500: screen_redraw_draw_number(c, wp, top);
1.1 nicm 501: }
502: }
503:
1.26 nicm 504: /* Draw the status line. */
1.1 nicm 505: void
1.26 nicm 506: screen_redraw_draw_status(struct client *c, u_int top)
1.1 nicm 507: {
1.26 nicm 508: struct tty *tty = &c->tty;
1.23 nicm 509:
1.26 nicm 510: if (top)
1.30 nicm 511: tty_draw_line(tty, NULL, &c->status, 0, 0, 0);
1.26 nicm 512: else
1.30 nicm 513: tty_draw_line(tty, NULL, &c->status, 0, 0, tty->sy - 1);
1.10 nicm 514: }
515:
516: /* Draw number on a pane. */
517: void
1.31 nicm 518: screen_redraw_draw_number(struct client *c, struct window_pane *wp, u_int top)
1.10 nicm 519: {
520: struct tty *tty = &c->tty;
521: struct session *s = c->session;
1.33 nicm 522: struct options *oo = s->options;
1.16 nicm 523: struct window *w = wp->window;
1.10 nicm 524: struct grid_cell gc;
1.12 nicm 525: u_int idx, px, py, i, j, xoff, yoff;
1.16 nicm 526: int colour, active_colour;
1.10 nicm 527: char buf[16], *ptr;
528: size_t len;
529:
1.19 nicm 530: if (window_pane_index(wp, &idx) != 0)
531: fatalx("index not found");
1.10 nicm 532: len = xsnprintf(buf, sizeof buf, "%u", idx);
533:
534: if (wp->sx < len)
535: return;
1.16 nicm 536: colour = options_get_number(oo, "display-panes-colour");
537: active_colour = options_get_number(oo, "display-panes-active-colour");
1.10 nicm 538:
1.12 nicm 539: px = wp->sx / 2; py = wp->sy / 2;
540: xoff = wp->xoff; yoff = wp->yoff;
1.31 nicm 541:
542: if (top)
543: yoff++;
1.12 nicm 544:
1.10 nicm 545: if (wp->sx < len * 6 || wp->sy < 5) {
1.12 nicm 546: tty_cursor(tty, xoff + px - len / 2, yoff + py);
1.20 nicm 547: goto draw_text;
1.10 nicm 548: }
1.14 nicm 549:
1.10 nicm 550: px -= len * 3;
551: py -= 2;
552:
1.25 nicm 553: memcpy(&gc, &grid_default_cell, sizeof gc);
1.16 nicm 554: if (w->active == wp)
1.37 ! nicm 555: gc.bg = active_colour;
1.16 nicm 556: else
1.37 ! nicm 557: gc.bg = colour;
1.30 nicm 558: tty_attributes(tty, &gc, wp);
1.10 nicm 559: for (ptr = buf; *ptr != '\0'; ptr++) {
560: if (*ptr < '0' || *ptr > '9')
561: continue;
562: idx = *ptr - '0';
1.14 nicm 563:
1.10 nicm 564: for (j = 0; j < 5; j++) {
565: for (i = px; i < px + 5; i++) {
1.12 nicm 566: tty_cursor(tty, xoff + i, yoff + py + j);
1.27 nicm 567: if (window_clock_table[idx][j][i - px])
1.11 nicm 568: tty_putc(tty, ' ');
1.10 nicm 569: }
570: }
571: px += 6;
572: }
1.20 nicm 573:
574: len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy);
575: if (wp->sx < len || wp->sy < 6)
576: return;
577: tty_cursor(tty, xoff + wp->sx - len, yoff);
578:
579: draw_text:
1.25 nicm 580: memcpy(&gc, &grid_default_cell, sizeof gc);
1.20 nicm 581: if (w->active == wp)
1.37 ! nicm 582: gc.fg = active_colour;
1.20 nicm 583: else
1.37 ! nicm 584: gc.fg = colour;
1.30 nicm 585: tty_attributes(tty, &gc, wp);
1.20 nicm 586: tty_puts(tty, buf);
587:
588: tty_cursor(tty, 0, 0);
1.1 nicm 589: }