File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / tmux / screen-redraw.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 14 12:22:44 2017 UTC (7 years ago) by misho
Branches: tmux, MAIN
CVS tags: v2_4p0, v2_4, HEAD
tmux 2.4

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>