Home | History | Annotate | Line # | Download | only in dist
screen-redraw.c revision 1.1.1.2.8.1
      1  1.1.1.2.8.1   tls /* Id */
      2          1.1  jmmv 
      3          1.1  jmmv /*
      4          1.1  jmmv  * Copyright (c) 2007 Nicholas Marriott <nicm (at) users.sourceforge.net>
      5          1.1  jmmv  *
      6          1.1  jmmv  * Permission to use, copy, modify, and distribute this software for any
      7          1.1  jmmv  * purpose with or without fee is hereby granted, provided that the above
      8          1.1  jmmv  * copyright notice and this permission notice appear in all copies.
      9          1.1  jmmv  *
     10          1.1  jmmv  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11          1.1  jmmv  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12          1.1  jmmv  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13          1.1  jmmv  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14          1.1  jmmv  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     15          1.1  jmmv  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     16          1.1  jmmv  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17          1.1  jmmv  */
     18          1.1  jmmv 
     19          1.1  jmmv #include <sys/types.h>
     20          1.1  jmmv 
     21          1.1  jmmv #include <string.h>
     22          1.1  jmmv 
     23          1.1  jmmv #include "tmux.h"
     24          1.1  jmmv 
     25          1.1  jmmv int	screen_redraw_cell_border1(struct window_pane *, u_int, u_int);
     26          1.1  jmmv int	screen_redraw_cell_border(struct client *, u_int, u_int);
     27  1.1.1.2.8.1   tls int	screen_redraw_check_cell(struct client *, u_int, u_int,
     28  1.1.1.2.8.1   tls 	    struct window_pane **);
     29  1.1.1.2.8.1   tls int	screen_redraw_check_active(u_int, u_int, int, struct window *,
     30  1.1.1.2.8.1   tls 	    struct window_pane *);
     31  1.1.1.2.8.1   tls 
     32  1.1.1.2.8.1   tls void	screen_redraw_draw_borders(struct client *, int, u_int);
     33  1.1.1.2.8.1   tls void	screen_redraw_draw_panes(struct client *, u_int);
     34  1.1.1.2.8.1   tls void	screen_redraw_draw_status(struct client *, u_int);
     35          1.1  jmmv void	screen_redraw_draw_number(struct client *, struct window_pane *);
     36          1.1  jmmv 
     37          1.1  jmmv #define CELL_INSIDE 0
     38          1.1  jmmv #define CELL_LEFTRIGHT 1
     39          1.1  jmmv #define CELL_TOPBOTTOM 2
     40          1.1  jmmv #define CELL_TOPLEFT 3
     41          1.1  jmmv #define CELL_TOPRIGHT 4
     42          1.1  jmmv #define CELL_BOTTOMLEFT 5
     43          1.1  jmmv #define CELL_BOTTOMRIGHT 6
     44          1.1  jmmv #define CELL_TOPJOIN 7
     45          1.1  jmmv #define CELL_BOTTOMJOIN 8
     46          1.1  jmmv #define CELL_LEFTJOIN 9
     47          1.1  jmmv #define CELL_RIGHTJOIN 10
     48          1.1  jmmv #define CELL_JOIN 11
     49          1.1  jmmv #define CELL_OUTSIDE 12
     50          1.1  jmmv 
     51          1.1  jmmv #define CELL_BORDERS " xqlkmjwvtun~"
     52          1.1  jmmv 
     53          1.1  jmmv /* Check if cell is on the border of a particular pane. */
     54          1.1  jmmv int
     55          1.1  jmmv screen_redraw_cell_border1(struct window_pane *wp, u_int px, u_int py)
     56          1.1  jmmv {
     57          1.1  jmmv 	/* Inside pane. */
     58          1.1  jmmv 	if (px >= wp->xoff && px < wp->xoff + wp->sx &&
     59          1.1  jmmv 	    py >= wp->yoff && py < wp->yoff + wp->sy)
     60          1.1  jmmv 		return (0);
     61          1.1  jmmv 
     62          1.1  jmmv 	/* Left/right borders. */
     63          1.1  jmmv 	if ((wp->yoff == 0 || py >= wp->yoff - 1) && py <= wp->yoff + wp->sy) {
     64          1.1  jmmv 		if (wp->xoff != 0 && px == wp->xoff - 1)
     65          1.1  jmmv 			return (1);
     66          1.1  jmmv 		if (px == wp->xoff + wp->sx)
     67          1.1  jmmv 			return (1);
     68          1.1  jmmv 	}
     69          1.1  jmmv 
     70          1.1  jmmv 	/* Top/bottom borders. */
     71          1.1  jmmv 	if ((wp->xoff == 0 || px >= wp->xoff - 1) && px <= wp->xoff + wp->sx) {
     72          1.1  jmmv 		if (wp->yoff != 0 && py == wp->yoff - 1)
     73          1.1  jmmv 			return (1);
     74          1.1  jmmv 		if (py == wp->yoff + wp->sy)
     75          1.1  jmmv 			return (1);
     76          1.1  jmmv 	}
     77          1.1  jmmv 
     78          1.1  jmmv 	/* Outside pane. */
     79          1.1  jmmv 	return (-1);
     80          1.1  jmmv }
     81          1.1  jmmv 
     82          1.1  jmmv /* Check if a cell is on the pane border. */
     83          1.1  jmmv int
     84          1.1  jmmv screen_redraw_cell_border(struct client *c, u_int px, u_int py)
     85          1.1  jmmv {
     86          1.1  jmmv 	struct window		*w = c->session->curw->window;
     87          1.1  jmmv 	struct window_pane	*wp;
     88          1.1  jmmv 	int			 retval;
     89          1.1  jmmv 
     90          1.1  jmmv 	/* Check all the panes. */
     91          1.1  jmmv 	TAILQ_FOREACH(wp, &w->panes, entry) {
     92          1.1  jmmv 		if (!window_pane_visible(wp))
     93          1.1  jmmv 			continue;
     94          1.1  jmmv 		if ((retval = screen_redraw_cell_border1(wp, px, py)) != -1)
     95          1.1  jmmv 			return (retval);
     96          1.1  jmmv 	}
     97          1.1  jmmv 
     98          1.1  jmmv 	return (0);
     99          1.1  jmmv }
    100          1.1  jmmv 
    101          1.1  jmmv /* Check if cell inside a pane. */
    102          1.1  jmmv int
    103  1.1.1.2.8.1   tls screen_redraw_check_cell(struct client *c, u_int px, u_int py,
    104  1.1.1.2.8.1   tls     struct window_pane **wpp)
    105          1.1  jmmv {
    106          1.1  jmmv 	struct window		*w = c->session->curw->window;
    107          1.1  jmmv 	struct window_pane	*wp;
    108          1.1  jmmv 	int			 borders;
    109          1.1  jmmv 
    110          1.1  jmmv 	if (px > w->sx || py > w->sy)
    111          1.1  jmmv 		return (CELL_OUTSIDE);
    112          1.1  jmmv 
    113          1.1  jmmv 	TAILQ_FOREACH(wp, &w->panes, entry) {
    114          1.1  jmmv 		if (!window_pane_visible(wp))
    115          1.1  jmmv 			continue;
    116  1.1.1.2.8.1   tls 		*wpp = wp;
    117          1.1  jmmv 
    118          1.1  jmmv 		/* If outside the pane and its border, skip it. */
    119          1.1  jmmv 		if ((wp->xoff != 0 && px < wp->xoff - 1) ||
    120          1.1  jmmv 		    px > wp->xoff + wp->sx ||
    121          1.1  jmmv 		    (wp->yoff != 0 && py < wp->yoff - 1) ||
    122          1.1  jmmv 		    py > wp->yoff + wp->sy)
    123          1.1  jmmv 			continue;
    124          1.1  jmmv 
    125          1.1  jmmv 		/* If definitely inside, return so. */
    126          1.1  jmmv 		if (!screen_redraw_cell_border(c, px, py))
    127          1.1  jmmv 			return (CELL_INSIDE);
    128          1.1  jmmv 
    129          1.1  jmmv 		/*
    130          1.1  jmmv 		 * Construct a bitmask of whether the cells to the left (bit
    131          1.1  jmmv 		 * 4), right, top, and bottom (bit 1) of this cell are borders.
    132          1.1  jmmv 		 */
    133          1.1  jmmv 		borders = 0;
    134          1.1  jmmv 		if (px == 0 || screen_redraw_cell_border(c, px - 1, py))
    135          1.1  jmmv 			borders |= 8;
    136          1.1  jmmv 		if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
    137          1.1  jmmv 			borders |= 4;
    138          1.1  jmmv 		if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
    139          1.1  jmmv 			borders |= 2;
    140          1.1  jmmv 		if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
    141          1.1  jmmv 			borders |= 1;
    142          1.1  jmmv 
    143          1.1  jmmv 		/*
    144          1.1  jmmv 		 * Figure out what kind of border this cell is. Only one bit
    145          1.1  jmmv 		 * set doesn't make sense (can't have a border cell with no
    146          1.1  jmmv 		 * others connected).
    147          1.1  jmmv 		 */
    148          1.1  jmmv 		switch (borders) {
    149          1.1  jmmv 		case 15:	/* 1111, left right top bottom */
    150          1.1  jmmv 			return (CELL_JOIN);
    151          1.1  jmmv 		case 14:	/* 1110, left right top */
    152          1.1  jmmv 			return (CELL_BOTTOMJOIN);
    153          1.1  jmmv 		case 13:	/* 1101, left right bottom */
    154          1.1  jmmv 			return (CELL_TOPJOIN);
    155          1.1  jmmv 		case 12:	/* 1100, left right */
    156          1.1  jmmv 			return (CELL_TOPBOTTOM);
    157          1.1  jmmv 		case 11:	/* 1011, left top bottom */
    158          1.1  jmmv 			return (CELL_RIGHTJOIN);
    159          1.1  jmmv 		case 10:	/* 1010, left top */
    160          1.1  jmmv 			return (CELL_BOTTOMRIGHT);
    161          1.1  jmmv 		case 9:		/* 1001, left bottom */
    162          1.1  jmmv 			return (CELL_TOPRIGHT);
    163          1.1  jmmv 		case 7:		/* 0111, right top bottom */
    164          1.1  jmmv 			return (CELL_LEFTJOIN);
    165          1.1  jmmv 		case 6:		/* 0110, right top */
    166          1.1  jmmv 			return (CELL_BOTTOMLEFT);
    167          1.1  jmmv 		case 5:		/* 0101, right bottom */
    168          1.1  jmmv 			return (CELL_TOPLEFT);
    169          1.1  jmmv 		case 3:		/* 0011, top bottom */
    170          1.1  jmmv 			return (CELL_LEFTRIGHT);
    171          1.1  jmmv 		}
    172          1.1  jmmv 	}
    173          1.1  jmmv 
    174  1.1.1.2.8.1   tls 	*wpp = NULL;
    175          1.1  jmmv 	return (CELL_OUTSIDE);
    176          1.1  jmmv }
    177          1.1  jmmv 
    178  1.1.1.2.8.1   tls /* Check active pane indicator. */
    179  1.1.1.2.8.1   tls int
    180  1.1.1.2.8.1   tls screen_redraw_check_active(u_int px, u_int py, int type, struct window *w,
    181  1.1.1.2.8.1   tls     struct window_pane *wp)
    182  1.1.1.2.8.1   tls {
    183  1.1.1.2.8.1   tls 	/* Is this off the active pane border? */
    184  1.1.1.2.8.1   tls 	if (screen_redraw_cell_border1(w->active, px, py) != 1)
    185  1.1.1.2.8.1   tls 		return (0);
    186  1.1.1.2.8.1   tls 
    187  1.1.1.2.8.1   tls 	/* If there are more than two panes, that's enough. */
    188  1.1.1.2.8.1   tls 	if (window_count_panes(w) != 2)
    189  1.1.1.2.8.1   tls 		return (1);
    190  1.1.1.2.8.1   tls 
    191  1.1.1.2.8.1   tls 	/* Else if the cell is not a border cell, forget it. */
    192  1.1.1.2.8.1   tls 	if (wp == NULL || (type == CELL_OUTSIDE || type == CELL_INSIDE))
    193  1.1.1.2.8.1   tls 		return (1);
    194  1.1.1.2.8.1   tls 
    195  1.1.1.2.8.1   tls 	/* Check if the pane covers the whole width. */
    196  1.1.1.2.8.1   tls 	if (wp->xoff == 0 && wp->sx == w->sx) {
    197  1.1.1.2.8.1   tls 		/* This can either be the top pane or the bottom pane. */
    198  1.1.1.2.8.1   tls 		if (wp->yoff == 0) { /* top pane */
    199  1.1.1.2.8.1   tls 			if (wp == w->active)
    200  1.1.1.2.8.1   tls 				return (px <= wp->sx / 2);
    201  1.1.1.2.8.1   tls 			return (px > wp->sx / 2);
    202  1.1.1.2.8.1   tls 		}
    203  1.1.1.2.8.1   tls 		return (0);
    204  1.1.1.2.8.1   tls 	}
    205  1.1.1.2.8.1   tls 
    206  1.1.1.2.8.1   tls 	/* Check if the pane covers the whole height. */
    207  1.1.1.2.8.1   tls 	if (wp->yoff == 0 && wp->sy == w->sy) {
    208  1.1.1.2.8.1   tls 		/* This can either be the left pane or the right pane. */
    209  1.1.1.2.8.1   tls 		if (wp->xoff == 0) { /* left pane */
    210  1.1.1.2.8.1   tls 			if (wp == w->active)
    211  1.1.1.2.8.1   tls 				return (py <= wp->sy / 2);
    212  1.1.1.2.8.1   tls 			return (py > wp->sy / 2);
    213  1.1.1.2.8.1   tls 		}
    214  1.1.1.2.8.1   tls 		return (0);
    215  1.1.1.2.8.1   tls 	}
    216  1.1.1.2.8.1   tls 
    217  1.1.1.2.8.1   tls 	return (type);
    218  1.1.1.2.8.1   tls }
    219  1.1.1.2.8.1   tls 
    220          1.1  jmmv /* Redraw entire screen. */
    221          1.1  jmmv void
    222  1.1.1.2.8.1   tls screen_redraw_screen(struct client *c, int draw_panes, int draw_status,
    223  1.1.1.2.8.1   tls     int draw_borders)
    224          1.1  jmmv {
    225  1.1.1.2.8.1   tls 	struct options	*oo = &c->session->options;
    226  1.1.1.2.8.1   tls 	struct tty	*tty = &c->tty;
    227  1.1.1.2.8.1   tls 	u_int		 top;
    228  1.1.1.2.8.1   tls 	int	 	 status, spos;
    229          1.1  jmmv 
    230      1.1.1.2  jmmv 	/* Suspended clients should not be updated. */
    231      1.1.1.2  jmmv 	if (c->flags & CLIENT_SUSPENDED)
    232      1.1.1.2  jmmv 		return;
    233      1.1.1.2  jmmv 
    234          1.1  jmmv 	/* Get status line, er, status. */
    235  1.1.1.2.8.1   tls 	spos = options_get_number(oo, "status-position");
    236          1.1  jmmv 	if (c->message_string != NULL || c->prompt_string != NULL)
    237          1.1  jmmv 		status = 1;
    238          1.1  jmmv 	else
    239  1.1.1.2.8.1   tls 		status = options_get_number(oo, "status");
    240  1.1.1.2.8.1   tls 	top = 0;
    241  1.1.1.2.8.1   tls 	if (status && spos == 0)
    242  1.1.1.2.8.1   tls 		top = 1;
    243  1.1.1.2.8.1   tls 	if (!status)
    244  1.1.1.2.8.1   tls 		draw_status = 0;
    245  1.1.1.2.8.1   tls 
    246  1.1.1.2.8.1   tls 	if (draw_borders)
    247  1.1.1.2.8.1   tls 		screen_redraw_draw_borders(c, status, top);
    248  1.1.1.2.8.1   tls 	if (draw_panes)
    249  1.1.1.2.8.1   tls 		screen_redraw_draw_panes(c, top);
    250  1.1.1.2.8.1   tls 	if (draw_status)
    251  1.1.1.2.8.1   tls 		screen_redraw_draw_status(c, top);
    252  1.1.1.2.8.1   tls 	tty_reset(tty);
    253  1.1.1.2.8.1   tls }
    254          1.1  jmmv 
    255  1.1.1.2.8.1   tls /* Draw a single pane. */
    256  1.1.1.2.8.1   tls void
    257  1.1.1.2.8.1   tls screen_redraw_pane(struct client *c, struct window_pane *wp)
    258  1.1.1.2.8.1   tls {
    259  1.1.1.2.8.1   tls 	u_int	i, yoff;
    260  1.1.1.2.8.1   tls 
    261  1.1.1.2.8.1   tls 	if (!window_pane_visible(wp))
    262          1.1  jmmv 		return;
    263          1.1  jmmv 
    264  1.1.1.2.8.1   tls 	yoff = wp->yoff;
    265  1.1.1.2.8.1   tls 	if (status_at_line(c) == 0)
    266  1.1.1.2.8.1   tls 		yoff++;
    267  1.1.1.2.8.1   tls 
    268  1.1.1.2.8.1   tls 	for (i = 0; i < wp->sy; i++)
    269  1.1.1.2.8.1   tls 		tty_draw_line(&c->tty, wp->screen, i, wp->xoff, yoff);
    270  1.1.1.2.8.1   tls 	tty_reset(&c->tty);
    271  1.1.1.2.8.1   tls }
    272  1.1.1.2.8.1   tls 
    273  1.1.1.2.8.1   tls /* Draw the borders. */
    274  1.1.1.2.8.1   tls void
    275  1.1.1.2.8.1   tls screen_redraw_draw_borders(struct client *c, int status, u_int top)
    276  1.1.1.2.8.1   tls {
    277  1.1.1.2.8.1   tls 	struct window		*w = c->session->curw->window;
    278  1.1.1.2.8.1   tls 	struct options		*oo = &c->session->options;
    279  1.1.1.2.8.1   tls 	struct tty		*tty = &c->tty;
    280  1.1.1.2.8.1   tls 	struct window_pane	*wp;
    281  1.1.1.2.8.1   tls 	struct grid_cell	 active_gc, other_gc;
    282  1.1.1.2.8.1   tls 	u_int		 	 i, j, type;
    283  1.1.1.2.8.1   tls 
    284  1.1.1.2.8.1   tls 	style_apply(&other_gc, oo, "pane-border-style");
    285  1.1.1.2.8.1   tls 	style_apply(&active_gc, oo, "pane-active-border-style");
    286          1.1  jmmv 	active_gc.attr = other_gc.attr = GRID_ATTR_CHARSET;
    287          1.1  jmmv 
    288          1.1  jmmv 	for (j = 0; j < tty->sy - status; j++) {
    289          1.1  jmmv 		for (i = 0; i < tty->sx; i++) {
    290  1.1.1.2.8.1   tls 			type = screen_redraw_check_cell(c, i, j, &wp);
    291          1.1  jmmv 			if (type == CELL_INSIDE)
    292          1.1  jmmv 				continue;
    293  1.1.1.2.8.1   tls 			if (screen_redraw_check_active(i, j, type, w, wp))
    294          1.1  jmmv 				tty_attributes(tty, &active_gc);
    295          1.1  jmmv 			else
    296          1.1  jmmv 				tty_attributes(tty, &other_gc);
    297  1.1.1.2.8.1   tls 			tty_cursor(tty, i, top + j);
    298          1.1  jmmv 			tty_putc(tty, CELL_BORDERS[type]);
    299          1.1  jmmv 		}
    300          1.1  jmmv 	}
    301  1.1.1.2.8.1   tls }
    302          1.1  jmmv 
    303  1.1.1.2.8.1   tls /* Draw the panes. */
    304  1.1.1.2.8.1   tls void
    305  1.1.1.2.8.1   tls screen_redraw_draw_panes(struct client *c, u_int top)
    306  1.1.1.2.8.1   tls {
    307  1.1.1.2.8.1   tls 	struct window		*w = c->session->curw->window;
    308  1.1.1.2.8.1   tls 	struct tty		*tty = &c->tty;
    309  1.1.1.2.8.1   tls 	struct window_pane	*wp;
    310  1.1.1.2.8.1   tls 	struct screen		*s;
    311  1.1.1.2.8.1   tls 	u_int		 	 i;
    312          1.1  jmmv 
    313          1.1  jmmv 	TAILQ_FOREACH(wp, &w->panes, entry) {
    314          1.1  jmmv 		if (!window_pane_visible(wp))
    315          1.1  jmmv 			continue;
    316  1.1.1.2.8.1   tls 		s = wp->screen;
    317  1.1.1.2.8.1   tls 		for (i = 0; i < wp->sy; i++)
    318  1.1.1.2.8.1   tls 			tty_draw_line(tty, s, i, wp->xoff, top + wp->yoff);
    319          1.1  jmmv 		if (c->flags & CLIENT_IDENTIFY)
    320          1.1  jmmv 			screen_redraw_draw_number(c, wp);
    321          1.1  jmmv 	}
    322          1.1  jmmv }
    323          1.1  jmmv 
    324  1.1.1.2.8.1   tls /* Draw the status line. */
    325          1.1  jmmv void
    326  1.1.1.2.8.1   tls screen_redraw_draw_status(struct client *c, u_int top)
    327          1.1  jmmv {
    328  1.1.1.2.8.1   tls 	struct tty	*tty = &c->tty;
    329          1.1  jmmv 
    330  1.1.1.2.8.1   tls 	if (top)
    331  1.1.1.2.8.1   tls 		tty_draw_line(tty, &c->status, 0, 0, 0);
    332  1.1.1.2.8.1   tls 	else
    333  1.1.1.2.8.1   tls 		tty_draw_line(tty, &c->status, 0, 0, tty->sy - 1);
    334          1.1  jmmv }
    335          1.1  jmmv 
    336          1.1  jmmv /* Draw number on a pane. */
    337          1.1  jmmv void
    338          1.1  jmmv screen_redraw_draw_number(struct client *c, struct window_pane *wp)
    339          1.1  jmmv {
    340          1.1  jmmv 	struct tty		*tty = &c->tty;
    341          1.1  jmmv 	struct session		*s = c->session;
    342  1.1.1.2.8.1   tls 	struct options		*oo = &s->options;
    343          1.1  jmmv 	struct window		*w = wp->window;
    344          1.1  jmmv 	struct grid_cell	 gc;
    345          1.1  jmmv 	u_int			 idx, px, py, i, j, xoff, yoff;
    346          1.1  jmmv 	int			 colour, active_colour;
    347          1.1  jmmv 	char			 buf[16], *ptr;
    348          1.1  jmmv 	size_t			 len;
    349          1.1  jmmv 
    350  1.1.1.2.8.1   tls 	if (window_pane_index(wp, &idx) != 0)
    351  1.1.1.2.8.1   tls 		fatalx("index not found");
    352          1.1  jmmv 	len = xsnprintf(buf, sizeof buf, "%u", idx);
    353          1.1  jmmv 
    354          1.1  jmmv 	if (wp->sx < len)
    355          1.1  jmmv 		return;
    356          1.1  jmmv 	colour = options_get_number(oo, "display-panes-colour");
    357          1.1  jmmv 	active_colour = options_get_number(oo, "display-panes-active-colour");
    358          1.1  jmmv 
    359          1.1  jmmv 	px = wp->sx / 2; py = wp->sy / 2;
    360          1.1  jmmv 	xoff = wp->xoff; yoff = wp->yoff;
    361          1.1  jmmv 
    362          1.1  jmmv 	if (wp->sx < len * 6 || wp->sy < 5) {
    363          1.1  jmmv 		tty_cursor(tty, xoff + px - len / 2, yoff + py);
    364  1.1.1.2.8.1   tls 		goto draw_text;
    365          1.1  jmmv 	}
    366          1.1  jmmv 
    367          1.1  jmmv 	px -= len * 3;
    368          1.1  jmmv 	py -= 2;
    369          1.1  jmmv 
    370          1.1  jmmv 	memcpy(&gc, &grid_default_cell, sizeof gc);
    371          1.1  jmmv 	if (w->active == wp)
    372          1.1  jmmv 		colour_set_bg(&gc, active_colour);
    373          1.1  jmmv 	else
    374          1.1  jmmv 		colour_set_bg(&gc, colour);
    375          1.1  jmmv 	tty_attributes(tty, &gc);
    376          1.1  jmmv 	for (ptr = buf; *ptr != '\0'; ptr++) {
    377          1.1  jmmv 		if (*ptr < '0' || *ptr > '9')
    378          1.1  jmmv 			continue;
    379          1.1  jmmv 		idx = *ptr - '0';
    380          1.1  jmmv 
    381          1.1  jmmv 		for (j = 0; j < 5; j++) {
    382          1.1  jmmv 			for (i = px; i < px + 5; i++) {
    383          1.1  jmmv 				tty_cursor(tty, xoff + i, yoff + py + j);
    384          1.1  jmmv 				if (clock_table[idx][j][i - px])
    385          1.1  jmmv 					tty_putc(tty, ' ');
    386          1.1  jmmv 			}
    387          1.1  jmmv 		}
    388          1.1  jmmv 		px += 6;
    389          1.1  jmmv 	}
    390  1.1.1.2.8.1   tls 
    391  1.1.1.2.8.1   tls 	len = xsnprintf(buf, sizeof buf, "%ux%u", wp->sx, wp->sy);
    392  1.1.1.2.8.1   tls 	if (wp->sx < len || wp->sy < 6)
    393  1.1.1.2.8.1   tls 		return;
    394  1.1.1.2.8.1   tls 	tty_cursor(tty, xoff + wp->sx - len, yoff);
    395  1.1.1.2.8.1   tls 
    396  1.1.1.2.8.1   tls draw_text:
    397  1.1.1.2.8.1   tls 	memcpy(&gc, &grid_default_cell, sizeof gc);
    398  1.1.1.2.8.1   tls 	if (w->active == wp)
    399  1.1.1.2.8.1   tls 		colour_set_fg(&gc, active_colour);
    400  1.1.1.2.8.1   tls 	else
    401  1.1.1.2.8.1   tls 		colour_set_fg(&gc, colour);
    402  1.1.1.2.8.1   tls 	tty_attributes(tty, &gc);
    403  1.1.1.2.8.1   tls 	tty_puts(tty, buf);
    404  1.1.1.2.8.1   tls 
    405  1.1.1.2.8.1   tls 	tty_cursor(tty, 0, 0);
    406          1.1  jmmv }
    407