Annotation of embedaddon/tmux/screen-redraw.c, revision 1.1
1.1 ! misho 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>