summaryrefslogtreecommitdiffstats
path: root/screen-redraw.c
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@openbsd.org>2009-07-24 19:14:38 +0000
committerNicholas Marriott <nicm@openbsd.org>2009-07-24 19:14:38 +0000
commit133173850c4e9986e27d5d1733b4771e209d0015 (patch)
tree0d1f1a4ebcf7e42963e061b0911fb00559369483 /screen-redraw.c
parentc6dac5c3c96ecbc43abc3de16bdcb6569141c379 (diff)
Use the full range of ACS line drawing characters to draw pane borders,
including intersections.
Diffstat (limited to 'screen-redraw.c')
-rw-r--r--screen-redraw.c122
1 files changed, 102 insertions, 20 deletions
diff --git a/screen-redraw.c b/screen-redraw.c
index baecb613..f3c718a9 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -22,25 +22,31 @@
#include "tmux.h"
+int screen_redraw_cell_border(struct client *, u_int, u_int);
int screen_redraw_check_cell(struct client *, u_int, u_int);
#define CELL_INSIDE 0
-#define CELL_LEFT 1
-#define CELL_RIGHT 2
-#define CELL_TOP 3
-#define CELL_BOTTOM 4
-#define CELL_OUTSIDE 5
-
-/* Check if cell inside a pane. */
+#define CELL_LEFTRIGHT 1
+#define CELL_TOPBOTTOM 2
+#define CELL_TOPLEFT 3
+#define CELL_TOPRIGHT 4
+#define CELL_BOTTOMLEFT 5
+#define CELL_BOTTOMRIGHT 6
+#define CELL_TOPJOIN 7
+#define CELL_BOTTOMJOIN 8
+#define CELL_LEFTJOIN 9
+#define CELL_RIGHTJOIN 10
+#define CELL_JOIN 11
+#define CELL_OUTSIDE 12
+
+/* Check if a cell is on the pane border. */
int
-screen_redraw_check_cell(struct client *c, u_int px, u_int py)
+screen_redraw_cell_border(struct client *c, u_int px, u_int py)
{
struct window *w = c->session->curw->window;
struct window_pane *wp;
- if (px > w->sx || py > w->sy)
- return (CELL_OUTSIDE);
-
+ /* Check all the panes. */
TAILQ_FOREACH(wp, &w->panes, entry) {
if (!window_pane_visible(wp))
continue;
@@ -48,22 +54,98 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py)
/* Inside pane. */
if (px >= wp->xoff && px < wp->xoff + wp->sx &&
py >= wp->yoff && py < wp->yoff + wp->sy)
- return (CELL_INSIDE);
+ return (0);
/* Left/right borders. */
- if (py >= wp->yoff && py < wp->yoff + wp->sy) {
+ if ((wp->yoff == 0 || py >= wp->yoff - 1) &&
+ py <= wp->yoff + wp->sy) {
if (wp->xoff != 0 && px == wp->xoff - 1)
- return (CELL_LEFT);
+ return (1);
if (px == wp->xoff + wp->sx)
- return (CELL_RIGHT);
+ return (1);
}
/* Top/bottom borders. */
- if (px >= wp->xoff && px < wp->xoff + wp->sx) {
+ if ((wp->xoff == 0 || px >= wp->xoff - 1) &&
+ px <= wp->xoff + wp->sx) {
if (wp->yoff != 0 && py == wp->yoff - 1)
- return (CELL_TOP);
+ return (1);
if (py == wp->yoff + wp->sy)
- return (CELL_BOTTOM);
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
+/* Check if cell inside a pane. */
+int
+screen_redraw_check_cell(struct client *c, u_int px, u_int py)
+{
+ struct window *w = c->session->curw->window;
+ struct window_pane *wp;
+ int borders;
+
+ if (px > w->sx || py > w->sy)
+ return (CELL_OUTSIDE);
+
+ TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (!window_pane_visible(wp))
+ continue;
+
+ /* If outside the pane and its border, skip it. */
+ if ((wp->xoff != 0 && px < wp->xoff - 1) ||
+ px > wp->xoff + wp->sx ||
+ (wp->yoff != 0 && py < wp->yoff - 1) ||
+ py > wp->yoff + wp->sy)
+ continue;
+
+ /* If definitely inside, return so. */
+ if (!screen_redraw_cell_border(c, px, py))
+ return (CELL_INSIDE);
+
+ /*
+ * Construct a bitmask of whether the cells to the left (bit
+ * 4), right, top, and bottom (bit 1) of this cell are borders.
+ */
+ borders = 0;
+ if (px == 0 || screen_redraw_cell_border(c, px - 1, py))
+ borders |= 8;
+ if (px <= w->sx && screen_redraw_cell_border(c, px + 1, py))
+ borders |= 4;
+ if (py == 0 || screen_redraw_cell_border(c, px, py - 1))
+ borders |= 2;
+ if (py <= w->sy && screen_redraw_cell_border(c, px, py + 1))
+ borders |= 1;
+
+ /*
+ * Figure out what kind of border this cell is. Only one bit
+ * set doesn't make sense (can't have a border cell with no
+ * others connected).
+ */
+ switch (borders) {
+ case 15: /* 1111, left right top bottom */
+ return (CELL_JOIN);
+ case 14: /* 1110, left right top */
+ return (CELL_BOTTOMJOIN);
+ case 13: /* 1101, left right bottom */
+ return (CELL_TOPJOIN);
+ case 12: /* 1100, left right */
+ return (CELL_TOPBOTTOM);
+ case 11: /* 1011, left top bottom */
+ return (CELL_RIGHTJOIN);
+ case 10: /* 1010, left top */
+ return (CELL_BOTTOMRIGHT);
+ case 9: /* 1001, left bottom */
+ return (CELL_TOPRIGHT);
+ case 7: /* 0111, right top bottom */
+ return (CELL_LEFTJOIN);
+ case 6: /* 0110, right top */
+ return (CELL_BOTTOMLEFT);
+ case 5: /* 0101, right bottom */
+ return (CELL_TOPLEFT);
+ case 3: /* 0011, top bottom */
+ return (CELL_LEFTRIGHT);
}
}
@@ -96,10 +178,10 @@ screen_redraw_screen(struct client *c, int status_only)
/* Draw background and borders. */
tty_reset(tty);
if (tty_term_has(tty->term, TTYC_ACSC)) {
- border = " xxqq~";
+ border = " xqlkmjwvtun~";
tty_putcode(tty, TTYC_SMACS);
} else
- border = " ||--.";
+ border = " |-....--||+.";
for (j = 0; j < tty->sy - status; j++) {
if (status_only && j != tty->sy - 1)
continue;