From 938156d73b0cc0692c727ac9a94bf65b235cfe40 Mon Sep 17 00:00:00 2001 From: nicm Date: Tue, 12 Mar 2019 20:02:47 +0000 Subject: DECRC and DECSC apparently need to preserve origin mode as well, based on a fix from Marc Reisner. --- input.c | 55 ++++++++++++++++++++++++++++++++++++++----------------- mode-tree.c | 8 ++++---- screen-redraw.c | 2 +- screen-write.c | 5 +++-- server-fn.c | 2 +- status.c | 18 +++++++++--------- tmux.h | 2 +- window-buffer.c | 2 +- window-client.c | 4 ++-- window-clock.c | 4 ++-- window-copy.c | 20 ++++++++++---------- window-tree.c | 28 ++++++++++++++-------------- 12 files changed, 86 insertions(+), 64 deletions(-) diff --git a/input.c b/input.c index dcfb6772..57a45a92 100644 --- a/input.c +++ b/input.c @@ -81,6 +81,7 @@ struct input_ctx { struct input_cell old_cell; u_int old_cx; u_int old_cy; + int old_mode; u_char interm_buf[4]; size_t interm_len; @@ -755,6 +756,32 @@ input_reset_cell(struct input_ctx *ictx) ictx->old_cy = 0; } +/* Save screen state. */ +static void +input_save_state(struct input_ctx *ictx) +{ + struct screen_write_ctx *sctx = &ictx->ctx; + struct screen *s = sctx->s; + + memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); + ictx->old_cx = s->cx; + ictx->old_cy = s->cy; + ictx->old_mode = s->mode; +} + +static void +input_restore_state(struct input_ctx *ictx) +{ + struct screen_write_ctx *sctx = &ictx->ctx; + + memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell); + if (ictx->old_mode & MODE_ORIGIN) + screen_write_mode_set(sctx, MODE_ORIGIN); + else + screen_write_mode_clear(sctx, MODE_ORIGIN); + screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy, 0); +} + /* Initialise input parser. */ void input_init(struct window_pane *wp) @@ -1222,13 +1249,10 @@ input_esc_dispatch(struct input_ctx *ictx) screen_write_mode_clear(sctx, MODE_KKEYPAD); break; case INPUT_ESC_DECSC: - memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); - ictx->old_cx = s->cx; - ictx->old_cy = s->cy; + input_save_state(ictx); break; case INPUT_ESC_DECRC: - memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell); - screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy); + input_restore_state(ictx); break; case INPUT_ESC_DECALN: screen_write_alignmenttest(sctx); @@ -1315,7 +1339,7 @@ input_csi_dispatch(struct input_ctx *ictx) n = input_get(ictx, 0, 1, 1); m = input_get(ictx, 1, 1, 1); if (n != -1 && m != -1) - screen_write_cursormove(sctx, m - 1, n - 1); + screen_write_cursormove(sctx, m - 1, n - 1, 1); break; case INPUT_CSI_WINOPS: input_csi_dispatch_winops(ictx); @@ -1447,7 +1471,7 @@ input_csi_dispatch(struct input_ctx *ictx) case INPUT_CSI_HPA: n = input_get(ictx, 0, 1, 1); if (n != -1) - screen_write_cursormove(sctx, n - 1, -1); + screen_write_cursormove(sctx, n - 1, -1, 1); break; case INPUT_CSI_ICH: n = input_get(ictx, 0, 1, 1); @@ -1472,8 +1496,7 @@ input_csi_dispatch(struct input_ctx *ictx) input_print(ictx); break; case INPUT_CSI_RCP: - memcpy(&ictx->cell, &ictx->old_cell, sizeof ictx->cell); - screen_write_cursormove(sctx, ictx->old_cx, ictx->old_cy); + input_restore_state(ictx); break; case INPUT_CSI_RM: input_csi_dispatch_rm(ictx); @@ -1482,9 +1505,7 @@ input_csi_dispatch(struct input_ctx *ictx) input_csi_dispatch_rm_private(ictx); break; case INPUT_CSI_SCP: - memcpy(&ictx->old_cell, &ictx->cell, sizeof ictx->old_cell); - ictx->old_cx = s->cx; - ictx->old_cy = s->cy; + input_save_state(ictx); break; case INPUT_CSI_SGR: input_csi_dispatch_sgr(ictx); @@ -1519,7 +1540,7 @@ input_csi_dispatch(struct input_ctx *ictx) case INPUT_CSI_VPA: n = input_get(ictx, 0, 1, 1); if (n != -1) - screen_write_cursormove(sctx, -1, n - 1); + screen_write_cursormove(sctx, -1, n - 1, 1); break; case INPUT_CSI_DECSCUSR: n = input_get(ictx, 0, 0, 0); @@ -1572,12 +1593,12 @@ input_csi_dispatch_rm_private(struct input_ctx *ictx) screen_write_mode_clear(sctx, MODE_KCURSOR); break; case 3: /* DECCOLM */ - screen_write_cursormove(sctx, 0, 0); + screen_write_cursormove(sctx, 0, 0, 1); screen_write_clearscreen(sctx, ictx->cell.cell.bg); break; case 6: /* DECOM */ screen_write_mode_clear(sctx, MODE_ORIGIN); - screen_write_cursormove(sctx, 0, 0); + screen_write_cursormove(sctx, 0, 0, 1); break; case 7: /* DECAWM */ screen_write_mode_clear(sctx, MODE_WRAP); @@ -1660,12 +1681,12 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx) screen_write_mode_set(sctx, MODE_KCURSOR); break; case 3: /* DECCOLM */ - screen_write_cursormove(sctx, 0, 0); + screen_write_cursormove(sctx, 0, 0, 1); screen_write_clearscreen(sctx, ictx->cell.cell.bg); break; case 6: /* DECOM */ screen_write_mode_set(sctx, MODE_ORIGIN); - screen_write_cursormove(sctx, 0, 0); + screen_write_cursormove(sctx, 0, 0, 1); break; case 7: /* DECAWM */ screen_write_mode_set(sctx, MODE_WRAP); diff --git a/mode-tree.c b/mode-tree.c index eb18bdf7..112969ea 100644 --- a/mode-tree.c +++ b/mode-tree.c @@ -530,7 +530,7 @@ mode_tree_draw(struct mode_tree_data *mtd) line = &mtd->line_list[i]; mti = line->item; - screen_write_cursormove(&ctx, 0, i - mtd->offset); + screen_write_cursormove(&ctx, 0, i - mtd->offset, 0); if (i < 10) snprintf(key, sizeof key, "(%c) ", '0' + i); @@ -605,13 +605,13 @@ mode_tree_draw(struct mode_tree_data *mtd) line = &mtd->line_list[mtd->current]; mti = line->item; - screen_write_cursormove(&ctx, 0, h); + screen_write_cursormove(&ctx, 0, h, 0); screen_write_box(&ctx, w, sy - h); xasprintf(&text, " %s (sort: %s)", mti->name, mtd->sort_list[mtd->sort_type]); if (w - 2 >= strlen(text)) { - screen_write_cursormove(&ctx, 1, h); + screen_write_cursormove(&ctx, 1, h, 0); screen_write_puts(&ctx, &gc0, "%s", text); if (mtd->no_matches) @@ -633,7 +633,7 @@ mode_tree_draw(struct mode_tree_data *mtd) box_y = sy - h - 2; if (box_x != 0 && box_y != 0) { - screen_write_cursormove(&ctx, 2, h + 1); + screen_write_cursormove(&ctx, 2, h + 1, 0); mtd->drawcb(mtd->modedata, mti->itemdata, &ctx, box_x, box_y); } diff --git a/screen-redraw.c b/screen-redraw.c index 167389b4..0c537630 100644 --- a/screen-redraw.c +++ b/screen-redraw.c @@ -300,7 +300,7 @@ screen_redraw_make_pane_status(struct client *c, struct window *w, screen_resize(&wp->status_screen, outlen, 1, 0); screen_write_start(&ctx, NULL, &wp->status_screen); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); screen_write_clearline(&ctx, 8); screen_write_cnputs(&ctx, outlen, &gc, "%s", out); screen_write_stop(&ctx); diff --git a/screen-write.c b/screen-write.c index c9cba2bd..9153ad27 100644 --- a/screen-write.c +++ b/screen-write.c @@ -1034,11 +1034,12 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg) /* Move cursor to px,py. */ void -screen_write_cursormove(struct screen_write_ctx *ctx, int px, int py) +screen_write_cursormove(struct screen_write_ctx *ctx, int px, int py, + int origin) { struct screen *s = ctx->s; - if (py != -1 && (s->mode & MODE_ORIGIN)) { + if (origin && py != -1 && (s->mode & MODE_ORIGIN)) { if ((u_int)py > s->rlower - s->rupper) py = s->rlower; else diff --git a/server-fn.c b/server-fn.c index 5655346d..f947d8ff 100644 --- a/server-fn.c +++ b/server-fn.c @@ -320,7 +320,7 @@ server_destroy_pane(struct window_pane *wp, int notify) screen_write_start(&ctx, wp, &wp->base); screen_write_scrollregion(&ctx, 0, screen_size_y(ctx.s) - 1); - screen_write_cursormove(&ctx, 0, screen_size_y(ctx.s) - 1); + screen_write_cursormove(&ctx, 0, screen_size_y(ctx.s) - 1, 0); screen_write_linefeed(&ctx, 1, 8); memcpy(&gc, &grid_default_cell, sizeof gc); diff --git a/status.c b/status.c index 2e2f5731..4da72866 100644 --- a/status.c +++ b/status.c @@ -465,7 +465,7 @@ draw: screen_write_start(&ctx, NULL, &c->status.status); /* Draw the left string and arrow. */ - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); if (llen != 0) screen_write_cnputs(&ctx, llen, &lgc, "%s", left); if (larrow != 0) { @@ -477,13 +477,13 @@ draw: /* Draw the right string and arrow. */ if (rarrow != 0) { - screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, 0); + screen_write_cursormove(&ctx, c->tty.sx - rlen - 1, 0, 0); memcpy(&gc, &stdgc, sizeof gc); if (rarrow == -1) gc.attr ^= GRID_ATTR_REVERSE; screen_write_putc(&ctx, &gc, '>'); } else - screen_write_cursormove(&ctx, c->tty.sx - rlen, 0); + screen_write_cursormove(&ctx, c->tty.sx - rlen, 0, 0); if (rlen != 0) screen_write_cnputs(&ctx, rlen, &rgc, "%s", right); @@ -507,7 +507,7 @@ draw: /* Copy the window list. */ c->status.window_list_offset = -wloffset + wlstart; - screen_write_cursormove(&ctx, wloffset, 0); + screen_write_cursormove(&ctx, wloffset, 0, 0); screen_write_fast_copy(&ctx, &window_list, wlstart, 0, wlwidth, 1); screen_free(&window_list); @@ -677,10 +677,10 @@ status_message_redraw(struct client *c) style_apply(&gc, s->options, "message-style"); screen_write_start(&ctx, NULL, &c->status.status); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); for (offset = 0; offset < lines * c->tty.sx; offset++) screen_write_putc(&ctx, &gc, ' '); - screen_write_cursormove(&ctx, 0, lines - 1); + screen_write_cursormove(&ctx, 0, lines - 1, 0); screen_write_nputs(&ctx, len, &gc, "%s", c->message_string); screen_write_stop(&ctx); @@ -839,12 +839,12 @@ status_prompt_redraw(struct client *c) start = c->tty.sx; screen_write_start(&ctx, NULL, &c->status.status); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); for (offset = 0; offset < lines * c->tty.sx; offset++) screen_write_putc(&ctx, &gc, ' '); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); screen_write_nputs(&ctx, start, &gc, "%s", c->prompt_string); - screen_write_cursormove(&ctx, start, 0); + screen_write_cursormove(&ctx, start, 0, 0); left = c->tty.sx - start; if (left == 0) diff --git a/tmux.h b/tmux.h index 6a94524c..c25f80b4 100644 --- a/tmux.h +++ b/tmux.h @@ -2100,7 +2100,7 @@ void screen_write_deleteline(struct screen_write_ctx *, u_int, u_int); void screen_write_clearline(struct screen_write_ctx *, u_int); void screen_write_clearendofline(struct screen_write_ctx *, u_int); void screen_write_clearstartofline(struct screen_write_ctx *, u_int); -void screen_write_cursormove(struct screen_write_ctx *, int, int); +void screen_write_cursormove(struct screen_write_ctx *, int, int, int); void screen_write_reverseindex(struct screen_write_ctx *, u_int); void screen_write_scrollregion(struct screen_write_ctx *, u_int, u_int); void screen_write_linefeed(struct screen_write_ctx *, int, u_int); diff --git a/window-buffer.c b/window-buffer.c index e1008e6b..7c918c70 100644 --- a/window-buffer.c +++ b/window-buffer.c @@ -226,7 +226,7 @@ window_buffer_draw(__unused void *modedata, void *itemdata, line[at] = '\0'; if (*line != '\0') { - screen_write_cursormove(ctx, cx, cy + i); + screen_write_cursormove(ctx, cx, cy + i, 0); screen_write_puts(ctx, &grid_default_cell, "%s", line); } diff --git a/window-client.c b/window-client.c index f0c81cf0..f86d8676 100644 --- a/window-client.c +++ b/window-client.c @@ -225,10 +225,10 @@ window_client_draw(__unused void *modedata, void *itemdata, screen_write_preview(ctx, &wp->base, sx, sy - 3); - screen_write_cursormove(ctx, cx, cy + sy - 2); + screen_write_cursormove(ctx, cx, cy + sy - 2, 0); screen_write_hline(ctx, sx, 0, 0); - screen_write_cursormove(ctx, cx, cy + sy - 1); + screen_write_cursormove(ctx, cx, cy + sy - 1, 0); if (c->status.old_status != NULL) screen_write_fast_copy(ctx, c->status.old_status, 0, 0, sx, 1); else diff --git a/window-clock.c b/window-clock.c index f98d7923..45d4d47b 100644 --- a/window-clock.c +++ b/window-clock.c @@ -238,7 +238,7 @@ window_clock_draw_screen(struct window_mode_entry *wme) if (screen_size_x(s) >= strlen(tim) && screen_size_y(s) != 0) { x = (screen_size_x(s) / 2) - (strlen(tim) / 2); y = screen_size_y(s) / 2; - screen_write_cursormove(&ctx, x, y); + screen_write_cursormove(&ctx, x, y, 0); memcpy(&gc, &grid_default_cell, sizeof gc); gc.flags |= GRID_FLAG_NOPALETTE; @@ -274,7 +274,7 @@ window_clock_draw_screen(struct window_mode_entry *wme) for (j = 0; j < 5; j++) { for (i = 0; i < 5; i++) { - screen_write_cursormove(&ctx, x + i, y + j); + screen_write_cursormove(&ctx, x + i, y + j, 0); if (window_clock_table[idx][j][i]) screen_write_putc(&ctx, &gc, ' '); } diff --git a/window-copy.c b/window-copy.c index 223741d1..062d687f 100644 --- a/window-copy.c +++ b/window-copy.c @@ -273,7 +273,7 @@ window_copy_init(struct window_mode_entry *wme, screen_write_start(&ctx, NULL, &data->screen); for (i = 0; i < screen_size_y(&data->screen); i++) window_copy_write_line(wme, &ctx, i); - screen_write_cursormove(&ctx, data->cx, data->cy); + screen_write_cursormove(&ctx, data->cx, data->cy, 0); screen_write_stop(&ctx); return (&data->screen); @@ -1373,13 +1373,13 @@ window_copy_write_line(struct window_mode_entry *wme, } if (size > screen_size_x(s)) size = screen_size_x(s); - screen_write_cursormove(ctx, screen_size_x(s) - size, 0); + screen_write_cursormove(ctx, screen_size_x(s) - size, 0, 0); screen_write_puts(ctx, &gc, "%s", hdr); } else size = 0; if (size < screen_size_x(s)) { - screen_write_cursormove(ctx, 0, py); + screen_write_cursormove(ctx, 0, py, 0); screen_write_copy(ctx, data->backing, 0, (screen_hsize(data->backing) - data->oy) + py, screen_size_x(s) - size, 1, data->searchmark, &gc); @@ -1387,7 +1387,7 @@ window_copy_write_line(struct window_mode_entry *wme, if (py == data->cy && data->cx == screen_size_x(s)) { memcpy(&gc, &grid_default_cell, sizeof gc); - screen_write_cursormove(ctx, screen_size_x(s) - 1, py); + screen_write_cursormove(ctx, screen_size_x(s) - 1, py, 0); screen_write_putc(ctx, &gc, '$'); } } @@ -1430,7 +1430,7 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny) screen_write_start(&ctx, wp, NULL); for (i = py; i < py + ny; i++) window_copy_write_line(wme, &ctx, i); - screen_write_cursormove(&ctx, data->cx, data->cy); + screen_write_cursormove(&ctx, data->cx, data->cy, 0); screen_write_stop(&ctx); } @@ -1482,7 +1482,7 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy) window_copy_redraw_lines(wme, data->cy, 1); else { screen_write_start(&ctx, wp, NULL); - screen_write_cursormove(&ctx, data->cx, data->cy); + screen_write_cursormove(&ctx, data->cx, data->cy, 0); screen_write_stop(&ctx); } } @@ -2475,7 +2475,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny) window_copy_update_selection(wme, 0); screen_write_start(&ctx, wp, NULL); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); screen_write_deleteline(&ctx, ny, 8); window_copy_write_lines(wme, &ctx, screen_size_y(s) - ny, ny); window_copy_write_line(wme, &ctx, 0); @@ -2485,7 +2485,7 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny) window_copy_write_line(wme, &ctx, screen_size_y(s) - 2); if (s->sel != NULL && screen_size_y(s) > ny) window_copy_write_line(wme, &ctx, screen_size_y(s) - ny - 1); - screen_write_cursormove(&ctx, data->cx, data->cy); + screen_write_cursormove(&ctx, data->cx, data->cy, 0); screen_write_stop(&ctx); } @@ -2509,14 +2509,14 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny) window_copy_update_selection(wme, 0); screen_write_start(&ctx, wp, NULL); - screen_write_cursormove(&ctx, 0, 0); + screen_write_cursormove(&ctx, 0, 0, 0); screen_write_insertline(&ctx, ny, 8); window_copy_write_lines(wme, &ctx, 0, ny); if (s->sel != NULL && screen_size_y(s) > ny) window_copy_write_line(wme, &ctx, ny); else if (ny == 1) /* nuke position */ window_copy_write_line(wme, &ctx, 1); - screen_write_cursormove(&ctx, data->cx, data->cy); + screen_write_cursormove(&ctx, data->cx, data->cy, 0); screen_write_stop(&ctx); } diff --git a/window-tree.c b/window-tree.c index 56bd2b07..46b28eae 100644 --- a/window-tree.c +++ b/window-tree.c @@ -476,10 +476,10 @@ window_tree_draw_label(struct screen_write_ctx *ctx, u_int px, u_int py, oy = (sy + 1) / 2; if (ox > 1 && ox + len < sx - 1 && sy >= 3) { - screen_write_cursormove(ctx, px + ox - 1, py + oy - 1); + screen_write_cursormove(ctx, px + ox - 1, py + oy - 1, 0); screen_write_box(ctx, len + 2, 3); } - screen_write_cursormove(ctx, px + ox, py + oy); + screen_write_cursormove(ctx, px + ox, py + oy, 0); screen_write_puts(ctx, gc, "%s", label); } @@ -554,17 +554,17 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, if (left) { data->left = cx + 2; - screen_write_cursormove(ctx, cx + 2, cy); + screen_write_cursormove(ctx, cx + 2, cy, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, cx, cy + sy / 2); + screen_write_cursormove(ctx, cx, cy + sy / 2, 0); screen_write_puts(ctx, &grid_default_cell, "<"); } else data->left = -1; if (right) { data->right = cx + sx - 3; - screen_write_cursormove(ctx, cx + sx - 3, cy); + screen_write_cursormove(ctx, cx + sx - 3, cy, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); + screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0); screen_write_puts(ctx, &grid_default_cell, ">"); } else data->right = -1; @@ -597,7 +597,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, else width = each - 1; - screen_write_cursormove(ctx, cx + offset, cy); + screen_write_cursormove(ctx, cx + offset, cy, 0); screen_write_preview(ctx, &w->active->base, width, sy); xasprintf(&label, " %u:%s ", wl->idx, w->name); @@ -608,7 +608,7 @@ window_tree_draw_session(struct window_tree_modedata *data, struct session *s, free(label); if (loop != end - 1) { - screen_write_cursormove(ctx, cx + offset + width, cy); + screen_write_cursormove(ctx, cx + offset + width, cy, 0); screen_write_vline(ctx, sy, 0, 0); } loop++; @@ -687,17 +687,17 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, if (left) { data->left = cx + 2; - screen_write_cursormove(ctx, cx + 2, cy); + screen_write_cursormove(ctx, cx + 2, cy, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, cx, cy + sy / 2); + screen_write_cursormove(ctx, cx, cy + sy / 2, 0); screen_write_puts(ctx, &grid_default_cell, "<"); } else data->left = -1; if (right) { data->right = cx + sx - 3; - screen_write_cursormove(ctx, cx + sx - 3, cy); + screen_write_cursormove(ctx, cx + sx - 3, cy, 0); screen_write_vline(ctx, sy, 0, 0); - screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2); + screen_write_cursormove(ctx, cx + sx - 1, cy + sy / 2, 0); screen_write_puts(ctx, &grid_default_cell, ">"); } else data->right = -1; @@ -729,7 +729,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, else width = each - 1; - screen_write_cursormove(ctx, cx + offset, cy); + screen_write_cursormove(ctx, cx + offset, cy, 0); screen_write_preview(ctx, &wp->base, width, sy); if (window_pane_index(wp, &pane_idx) != 0) @@ -740,7 +740,7 @@ window_tree_draw_window(struct window_tree_modedata *data, struct session *s, free(label); if (loop != end - 1) { - screen_write_cursormove(ctx, cx + offset + width, cy); + screen_write_cursormove(ctx, cx + offset + width, cy, 0); screen_write_vline(ctx, sy, 0, 0); } loop++; -- cgit v1.2.3