version 1.405, 2021/10/06 10:33:12 |
version 1.406, 2021/10/11 13:27:50 |
|
|
static void tty_default_attributes(struct tty *, const struct grid_cell *, |
static void tty_default_attributes(struct tty *, const struct grid_cell *, |
struct colour_palette *, u_int); |
struct colour_palette *, u_int); |
static int tty_check_overlay(struct tty *, u_int, u_int); |
static int tty_check_overlay(struct tty *, u_int, u_int); |
|
static void tty_check_overlay_range(struct tty *, u_int, u_int, u_int, |
|
struct overlay_ranges *); |
|
|
#define tty_use_margin(tty) \ |
#define tty_use_margin(tty) \ |
(tty->term->flags & TERM_DECSLRM) |
(tty->term->flags & TERM_DECSLRM) |
|
|
tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, |
tty_clear_line(struct tty *tty, const struct grid_cell *defaults, u_int py, |
u_int px, u_int nx, u_int bg) |
u_int px, u_int nx, u_int bg) |
{ |
{ |
struct client *c = tty->client; |
struct client *c = tty->client; |
u_int i; |
struct overlay_ranges r; |
|
u_int i; |
|
|
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); |
log_debug("%s: %s, %u at %u,%u", __func__, c->name, nx, px, py); |
|
|
|
|
* Couldn't use an escape sequence, use spaces. Clear only the visible |
* Couldn't use an escape sequence, use spaces. Clear only the visible |
* bit if there is an overlay. |
* bit if there is an overlay. |
*/ |
*/ |
for (i = 0; i < nx; i++) { |
tty_check_overlay_range(tty, px, py, nx, &r); |
if (!tty_check_overlay(tty, px + i, py)) |
for (i = 0; i < OVERLAY_MAX_RANGES; i++) { |
break; |
if (r.nx[i] == 0) |
|
continue; |
|
tty_cursor(tty, r.px[i], py); |
|
tty_repeat_space(tty, r.nx[i]); |
} |
} |
tty_cursor(tty, px, py); |
|
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. */ |
/* Clear a line, adjusting to visible part of pane. */ |
|
|
return (&new); |
return (&new); |
} |
} |
|
|
|
/* |
|
* Check if a single character is obstructed by the overlay and return a |
|
* boolean. |
|
*/ |
static int |
static int |
tty_check_overlay(struct tty *tty, u_int px, u_int py) |
tty_check_overlay(struct tty *tty, u_int px, u_int py) |
{ |
{ |
|
struct overlay_ranges r; |
|
|
|
/* |
|
* A unit width range will always return nx[2] == 0 from a check, even |
|
* with multiple overlays, so it's sufficient to check just the first |
|
* two entries. |
|
*/ |
|
tty_check_overlay_range(tty, px, py, 1, &r); |
|
if (r.nx[0] + r.nx[1] == 0) |
|
return (0); |
|
return (1); |
|
} |
|
|
|
/* Return parts of the input range which are visible. */ |
|
static void |
|
tty_check_overlay_range(struct tty *tty, u_int px, u_int py, u_int nx, |
|
struct overlay_ranges *r) |
|
{ |
struct client *c = tty->client; |
struct client *c = tty->client; |
|
|
if (c->overlay_check == NULL) |
if (c->overlay_check == NULL) { |
return (1); |
r->px[0] = px; |
return (c->overlay_check(c, c->overlay_data, px, py)); |
r->nx[0] = nx; |
|
r->px[1] = 0; |
|
r->nx[1] = 0; |
|
r->px[2] = 0; |
|
r->nx[2] = 0; |
|
return; |
|
} |
|
|
|
c->overlay_check(c, c->overlay_data, px, py, nx, r); |
} |
} |
|
|
void |
void |
|
|
const struct grid_cell *gcp; |
const struct grid_cell *gcp; |
struct grid_line *gl; |
struct grid_line *gl; |
struct client *c = tty->client; |
struct client *c = tty->client; |
u_int i, j, ux, sx, width, hidden; |
struct overlay_ranges r; |
|
u_int i, j, ux, sx, width, hidden, eux, nxx; |
|
u_int cellsize; |
int flags, cleared = 0, wrapped = 0; |
int flags, cleared = 0, wrapped = 0; |
char buf[512]; |
char buf[512]; |
size_t len; |
size_t len; |
u_int cellsize; |
|
|
|
log_debug("%s: px=%u py=%u nx=%u atx=%u aty=%u", __func__, |
log_debug("%s: px=%u py=%u nx=%u atx=%u aty=%u", __func__, |
px, py, nx, atx, aty); |
px, py, nx, atx, aty); |
|
|
else |
else |
memcpy(&last, gcp, sizeof last); |
memcpy(&last, gcp, sizeof last); |
|
|
|
tty_check_overlay_range(tty, atx + ux, aty, gcp->data.width, |
|
&r); |
hidden = 0; |
hidden = 0; |
for (j = 0; j < gcp->data.width; j++) { |
for (j = 0; j < OVERLAY_MAX_RANGES; j++) |
if (!tty_check_overlay(tty, atx + ux + j, aty)) |
hidden += r.nx[j]; |
hidden++; |
hidden = gcp->data.width - hidden; |
} |
|
if (hidden != 0 && hidden == gcp->data.width) { |
if (hidden != 0 && hidden == gcp->data.width) { |
if (~gcp->flags & GRID_FLAG_PADDING) |
if (~gcp->flags & GRID_FLAG_PADDING) |
ux += gcp->data.width; |
ux += gcp->data.width; |
} else if (hidden != 0 || ux + gcp->data.width > nx) { |
} else if (hidden != 0 || ux + gcp->data.width > nx) { |
if (~gcp->flags & GRID_FLAG_PADDING) { |
if (~gcp->flags & GRID_FLAG_PADDING) { |
tty_attributes(tty, &last, defaults, palette); |
tty_attributes(tty, &last, defaults, palette); |
tty_cursor(tty, atx + ux, aty); |
for (j = 0; j < OVERLAY_MAX_RANGES; j++) { |
for (j = 0; j < gcp->data.width; j++) { |
if (r.nx[j] == 0) |
if (ux > nx) |
continue; |
break; |
/* Effective width drawn so far. */ |
if (tty_check_overlay(tty, atx + ux, |
eux = r.px[j] - atx; |
aty)) |
if (eux < nx) { |
tty_putc(tty, ' '); |
tty_cursor(tty, r.px[j], aty); |
else { |
nxx = nx - eux; |
tty_cursor(tty, atx + ux + 1, |
if (r.nx[j] > nxx) |
aty); |
r.nx[j] = nxx; |
|
tty_repeat_space(tty, r.nx[j]); |
|
ux = eux + r.nx[j]; |
} |
} |
ux++; |
|
} |
} |
} |
} |
} else if (gcp->attr & GRID_ATTR_CHARSET) { |
} else if (gcp->attr & GRID_ATTR_CHARSET) { |
|
|
{ |
{ |
const struct grid_cell *gcp = ctx->cell; |
const struct grid_cell *gcp = ctx->cell; |
struct screen *s = ctx->s; |
struct screen *s = ctx->s; |
u_int i, px, py; |
struct overlay_ranges r; |
|
u_int px, py, i, vis = 0; |
|
|
px = ctx->xoff + ctx->ocx - ctx->wox; |
px = ctx->xoff + ctx->ocx - ctx->wox; |
py = ctx->yoff + ctx->ocy - ctx->woy; |
py = ctx->yoff + ctx->ocy - ctx->woy; |
|
|
|
|
/* Handle partially obstructed wide characters. */ |
/* Handle partially obstructed wide characters. */ |
if (gcp->data.width > 1) { |
if (gcp->data.width > 1) { |
for (i = 0; i < gcp->data.width; i++) { |
tty_check_overlay_range(tty, px, py, gcp->data.width, &r); |
if (!tty_check_overlay(tty, px + i, py)) { |
for (i = 0; i < OVERLAY_MAX_RANGES; i++) |
tty_draw_line(tty, s, s->cx, s->cy, |
vis += r.nx[i]; |
|
if (vis < gcp->data.width) { |
|
tty_draw_line(tty, s, s->cx, s->cy, |
gcp->data.width, px, py, &ctx->defaults, |
gcp->data.width, px, py, &ctx->defaults, |
ctx->palette); |
ctx->palette); |
return; |
return; |
} |
|
} |
} |
} |
} |
|
|
|
|
void |
void |
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) |
tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx) |
{ |
{ |
u_int i, hide = 0; |
struct overlay_ranges r; |
|
u_int i, px; |
|
|
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) |
if (!tty_is_visible(tty, ctx, ctx->ocx, ctx->ocy, ctx->num, 1)) |
return; |
return; |
|
|
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); |
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy); |
|
|
tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette); |
tty_attributes(tty, ctx->cell, &ctx->defaults, ctx->palette); |
for (i = 0; i < ctx->num; i++) { |
px = tty->cx; |
if (!tty_check_overlay(tty, tty->cx + i, tty->cy)) |
tty_check_overlay_range(tty, px, tty->cy, ctx->num, &r); |
break; |
for (i = 0; i < OVERLAY_MAX_RANGES; i++) { |
|
if (r.nx[i] == 0) |
|
continue; |
|
tty_cursor(tty, r.px[i], tty->cy); |
|
tty_putn(tty, (char *)ctx->ptr + r.px[i] - px, r.nx[i], |
|
r.nx[i]); |
} |
} |
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 |
void |