-/* $OpenBSD: tty.c,v 1.393 2021/06/10 07:59:31 nicm Exp $ */
+/* $OpenBSD: tty.c,v 1.394 2021/08/05 09:43:51 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
static void tty_default_attributes(struct tty *, const struct grid_cell *,
int *, u_int);
+static int tty_check_overlay(struct tty *, u_int, u_int);
#define tty_use_margin(tty) \
(tty->term->flags & TERM_DECSLRM)
u_int px, u_int nx, u_int bg)
{
struct client *c = tty->client;
+ u_int i;
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py);
return;
/* If genuine BCE is available, can try escape sequences. */
- if (!tty_fake_bce(tty, defaults, bg)) {
+ if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) {
/* Off the end of the line, use EL if available. */
if (px + nx >= tty->sx && tty_term_has(tty->term, TTYC_EL)) {
tty_cursor(tty, px, py);
}
}
- /* Couldn't use an escape sequence, use spaces. */
+ /*
+ * Couldn't use an escape sequence, use spaces. Clear only the visible
+ * bit if there is an overlay.
+ */
+ for (i = 0; i < nx; i++) {
+ if (!tty_check_overlay(tty, px + i, py))
+ break;
+ }
tty_cursor(tty, px, py);
- tty_repeat_space(tty, nx);
+ tty_repeat_space(tty, i);
+ for (; i < nx; i++) {
+ if (tty_check_overlay(tty, px + i, py))
+ break;
+ }
+ tty_cursor(tty, px + i, py);
+ tty_repeat_space(tty, nx - i);
}
/* Clear a line, adjusting to visible part of pane. */
return;
/* If genuine BCE is available, can try escape sequences. */
- if (!tty_fake_bce(tty, defaults, bg)) {
+ if (c->overlay_check == NULL && !tty_fake_bce(tty, defaults, bg)) {
/* Use ED if clearing off the bottom of the terminal. */
if (px == 0 &&
px + nx >= tty->sx &&
struct grid_cell gc, last;
const struct grid_cell *gcp;
struct grid_line *gl;
+ struct client *c = tty->client;
u_int i, j, ux, sx, width;
int flags, cleared = 0, wrapped = 0;
char buf[512];
atx == 0 &&
px + sx != nx &&
tty_term_has(tty->term, TTYC_EL1) &&
- !tty_fake_bce(tty, defaults, 8)) {
+ !tty_fake_bce(tty, defaults, 8) &&
+ c->overlay_check == NULL) {
tty_default_attributes(tty, defaults, palette, 8);
tty_cursor(tty, nx - 1, aty);
tty_putcode(tty, TTYC_EL1);
void
tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->bigger ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
(!tty_term_has(tty->term, TTYC_ICH) &&
- !tty_term_has(tty->term, TTYC_ICH1))) {
+ !tty_term_has(tty->term, TTYC_ICH1)) ||
+ c->overlay_check != NULL) {
tty_draw_pane(tty, ctx, ctx->ocy);
return;
}
void
tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->bigger ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
(!tty_term_has(tty->term, TTYC_DCH) &&
- !tty_term_has(tty->term, TTYC_DCH1))) {
+ !tty_term_has(tty->term, TTYC_DCH1)) ||
+ c->overlay_check != NULL) {
tty_draw_pane(tty, ctx, ctx->ocy);
return;
}
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->bigger ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->bigger ||
!tty_full_width(tty, ctx) ||
tty_fake_bce(tty, &ctx->defaults, ctx->bg) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->ocy != ctx->orupper)
return;
(!tty_term_has(tty->term, TTYC_RI) &&
!tty_term_has(tty->term, TTYC_RIN)) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct client *c = tty->client;
+
if (ctx->ocy != ctx->orlower)
return;
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
{
- u_int i;
+ struct client *c = tty->client;
+ u_int i;
if (ctx->bigger ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
tty_fake_bce(tty, &ctx->defaults, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
{
- u_int i;
+ u_int i;
+ struct client *c = tty->client;
if (ctx->bigger ||
(!tty_full_width(tty, ctx) && !tty_use_margin(tty)) ||
(!tty_term_has(tty->term, TTYC_RI) &&
!tty_term_has(tty->term, TTYC_RIN)) ||
ctx->sx == 1 ||
- ctx->sy == 1) {
+ ctx->sy == 1 ||
+ c->overlay_check != NULL) {
tty_redraw_region(tty, ctx);
return;
}
void
tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, 1, 1))
+ const struct grid_cell *gcp = ctx->cell;
+ struct screen *s = ctx->s;
+ u_int i, px, py;
+
+ px = ctx->xoff + ctx->ocx - ctx->wox;
+ py = ctx->yoff + ctx->ocy - ctx->woy;
+ if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, 1, 1) ||
+ (gcp->data.width == 1 && !tty_check_overlay(tty, px, py)))
return;
+ /* Handle partially obstructed wide characters. */
+ if (gcp->data.width > 1) {
+ for (i = 0; i < gcp->data.width; i++) {
+ if (!tty_check_overlay(tty, px + i, py)) {
+ tty_draw_line(tty, s, s->cx, s->cy,
+ gcp->data.width, px, py, &ctx->defaults,
+ ctx->palette);
+ return;
+ }
+ }
+ }
+
if (ctx->xoff + ctx->ocx - ctx->wox > tty->sx - 1 &&
ctx->ocy == ctx->orlower &&
tty_full_width(tty, ctx))
void
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
{
+ u_int i, hide = 0;
+
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1))
return;
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy);
tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette);
- tty_putn(tty, ctx->ptr, ctx->num, ctx->num);
+ for (i = 0; i < ctx->num; i++) {
+ if (!tty_check_overlay(tty, tty->cx + i, tty->cy))
+ break;
+ }
+ tty_putn(tty, ctx->ptr, i, i);
+ for (; i < ctx->num; i++) {
+ if (tty_check_overlay(tty, tty->cx + hide, tty->cy))
+ break;
+ hide++;
+ }
+ tty_cursor(tty, tty->cx + hide, tty->cy);
+ tty_putn(tty, (char *)ctx->ptr + i, ctx->num - i, ctx->num - i);
}
void