summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/tmux/screen-write.c36
-rw-r--r--usr.bin/tmux/tmux.h3
-rw-r--r--usr.bin/tmux/tty.c53
3 files changed, 77 insertions, 15 deletions
diff --git a/usr.bin/tmux/screen-write.c b/usr.bin/tmux/screen-write.c
index e66a350afa6..7723d610b77 100644
--- a/usr.bin/tmux/screen-write.c
+++ b/usr.bin/tmux/screen-write.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: screen-write.c,v 1.29 2009/10/12 16:59:55 nicm Exp $ */
+/* $OpenBSD: screen-write.c,v 1.30 2009/10/12 17:19:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -833,15 +833,15 @@ screen_write_mousemode(struct screen_write_ctx *ctx, int state)
s->mode &= ~MODE_MOUSE;
}
-/* Line feed (down with scroll). */
+/*
+ * Line feed the screen only (don't update the tty). Used for printing single
+ * characters, where might want to let the scroll happen naturally.
+ */
void
-screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
+screen_write_linefeedscreen(struct screen_write_ctx *ctx, int wrapped)
{
struct screen *s = ctx->s;
struct grid_line *gl;
- struct tty_ctx ttyctx;
-
- screen_write_initctx(ctx, &ttyctx);
gl = &s->grid->linedata[s->grid->hsize + s->cy];
if (wrapped)
@@ -853,6 +853,17 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
grid_view_scroll_region_up(s->grid, s->rupper, s->rlower);
else if (s->cy < screen_size_y(s) - 1)
s->cy++;
+}
+
+/* Line feed (down with scroll). */
+void
+screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped)
+{
+ struct tty_ctx ttyctx;
+
+ screen_write_initctx(ctx, &ttyctx);
+
+ screen_write_linefeedscreen(ctx, wrapped);
tty_write(tty_cmd_linefeed, &ttyctx);
}
@@ -952,6 +963,7 @@ screen_write_cell(
struct screen_write_ctx *ctx, const struct grid_cell *gc, u_char *udata)
{
struct screen *s = ctx->s;
+ struct window_pane *wp = ctx->wp;
struct grid *gd = s->grid;
struct tty_ctx ttyctx;
struct grid_utf8 gu, *tmp_gu;
@@ -1016,8 +1028,16 @@ screen_write_cell(
/* Check this will fit on the current line and wrap if not. */
if (s->cx > screen_size_x(s) - width) {
- screen_write_carriagereturn(ctx);
- screen_write_linefeed(ctx, 1);
+ /*
+ * Don't update the terminal now, just update the screen and
+ * leave the cursor to scroll naturally, unless this is only
+ * part of the screen width.
+ */
+ if (wp->xoff != 0 || wp->sx != screen_size_x(s))
+ screen_write_linefeed(ctx, 1);
+ else
+ screen_write_linefeedscreen(ctx, 1);
+ s->cx = 0; /* carriage return */
}
/* Sanity checks. */
diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h
index e77ef5d52a0..e11be3804c0 100644
--- a/usr.bin/tmux/tmux.h
+++ b/usr.bin/tmux/tmux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.136 2009/10/12 16:59:55 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.137 2009/10/12 17:19:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -1666,6 +1666,7 @@ void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int);
void screen_write_insertmode(struct screen_write_ctx *, int);
void screen_write_mousemode(struct screen_write_ctx *, int);
void screen_write_linefeed(struct screen_write_ctx *, int);
+void screen_write_linefeedscreen(struct screen_write_ctx *, int);
void screen_write_carriagereturn(struct screen_write_ctx *);
void screen_write_kcursormode(struct screen_write_ctx *, int);
void screen_write_kkeypadmode(struct screen_write_ctx *, int);
diff --git a/usr.bin/tmux/tty.c b/usr.bin/tmux/tty.c
index 04484754705..21269c95df1 100644
--- a/usr.bin/tmux/tty.c
+++ b/usr.bin/tmux/tty.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tty.c,v 1.45 2009/10/12 16:41:02 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.46 2009/10/12 17:19:47 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -327,9 +327,10 @@ tty_putc(struct tty *tty, u_char ch)
if (tty->term->flags & TERM_EARLYWRAP)
sx--;
- if (tty->cx == sx) {
- tty->cx = 0;
- tty->cy++;
+ if (tty->cx >= sx) {
+ tty->cx = 1;
+ if (tty->cy != tty->rlower)
+ tty->cy++;
} else
tty->cx++;
}
@@ -440,6 +441,7 @@ void
tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
{
const struct grid_cell *gc;
+ struct grid_line *gl;
struct grid_cell tmpgc;
const struct grid_utf8 *gu;
u_int i, sx;
@@ -452,7 +454,17 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int py, u_int ox, u_int oy)
if (sx > tty->sx)
sx = tty->sx;
- tty_cursor(tty, ox, oy + py);
+ /*
+ * Don't move the cursor to the start permission if it will wrap there
+ * itself; much the same as the conditions in tty_cmd_cell.
+ */
+ gl = NULL;
+ if (py != 0)
+ gl = &s->grid->linedata[s->grid->hsize + py - 1];
+ if (ox != 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) ||
+ tty->cy != oy + py - 1 || tty->cx < tty->sx)
+ tty_cursor(tty, ox, oy + py);
+
for (i = 0; i < sx; i++) {
gc = grid_view_peek_cell(s->grid, i, py);
@@ -827,7 +839,36 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
+ struct window_pane *wp = ctx->wp;
+ struct screen *s = wp->screen;
+ struct grid_line *gl;
+ u_int wx, wy;
+
+ tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
+
+ wx = ctx->ocx + wp->xoff;
+ wy = ctx->ocy + wp->yoff;
+
+ /*
+ * If:
+ *
+ * - the line was wrapped:
+ * - the cursor is beyond the edge of the screen,
+ * - the desired position is at the left,
+ * - and either a) the desired next line is the one below the current
+ * or b) the current line is the bottom of the scroll region,
+ *
+ * Then just printing the next character will be enough to scroll into
+ * place, so don't do an explicit cursor move.
+ */
+ gl = NULL;
+ if (ctx->ocy != 0)
+ gl = &s->grid->linedata[s->grid->hsize + ctx->ocy - 1];
+ if (wy == 0 || (gl != NULL && !(gl->flags & GRID_LINE_WRAPPED)) ||
+ tty->cx < tty->sx || /* not at edge of screen */
+ wx != 0 || /* don't want 0 next */
+ (wy != tty->cy + 1 && tty->cy != ctx->orlower + wp->yoff))
+ tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_cell(tty, ctx->cell, ctx->utf8);
}