aboutsummaryrefslogtreecommitdiff
path: root/tty.c
diff options
context:
space:
mode:
authorThomas Adam <thomas@xteddy.org>2022-06-30 16:37:18 +0100
committerThomas Adam <thomas@xteddy.org>2022-06-30 16:37:18 +0100
commit01c4919f5f86d7c120451ae642e722ea7d9651d7 (patch)
tree588d4883507ab85ad5e51181a548346da7c86c20 /tty.c
parentd8c527a5f9fc06ea15a7d04f3a54a9e49cebae62 (diff)
parentcdacc12ce305ad2f3e65e2a01328a988e3200b51 (diff)
downloadrtmux-01c4919f5f86d7c120451ae642e722ea7d9651d7.tar.gz
rtmux-01c4919f5f86d7c120451ae642e722ea7d9651d7.tar.bz2
rtmux-01c4919f5f86d7c120451ae642e722ea7d9651d7.zip
Merge branch 'obsd-master'
Diffstat (limited to 'tty.c')
-rw-r--r--tty.c114
1 files changed, 82 insertions, 32 deletions
diff --git a/tty.c b/tty.c
index 7e0a6a3e..78961e47 100644
--- a/tty.c
+++ b/tty.c
@@ -69,7 +69,7 @@ static void tty_emulate_repeat(struct tty *, enum tty_code_code,
static void tty_repeat_space(struct tty *, u_int);
static void tty_draw_pane(struct tty *, const struct tty_ctx *, u_int);
static void tty_default_attributes(struct tty *, const struct grid_cell *,
- struct colour_palette *, u_int);
+ struct colour_palette *, u_int, struct hyperlinks *);
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 *);
@@ -1455,7 +1455,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
tty_term_has(tty->term, TTYC_EL1) &&
!tty_fake_bce(tty, defaults, 8) &&
c->overlay_check == NULL) {
- tty_default_attributes(tty, defaults, palette, 8);
+ tty_default_attributes(tty, defaults, palette, 8,
+ s->hyperlinks);
tty_cursor(tty, nx - 1, aty);
tty_putcode(tty, TTYC_EL1);
cleared = 1;
@@ -1480,9 +1481,11 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
gcp->fg != last.fg ||
gcp->bg != last.bg ||
gcp->us != last.us ||
+ gcp->link != last.link ||
ux + width + gcp->data.width > nx ||
(sizeof buf) - len < gcp->data.size)) {
- tty_attributes(tty, &last, defaults, palette);
+ tty_attributes(tty, &last, defaults, palette,
+ s->hyperlinks);
if (last.flags & GRID_FLAG_CLEARED) {
log_debug("%s: %zu cleared", __func__, len);
tty_clear_line(tty, defaults, aty, atx + ux,
@@ -1515,7 +1518,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
ux += gcp->data.width;
} else if (hidden != 0 || ux + gcp->data.width > nx) {
if (~gcp->flags & GRID_FLAG_PADDING) {
- tty_attributes(tty, &last, defaults, palette);
+ tty_attributes(tty, &last, defaults, palette,
+ s->hyperlinks);
for (j = 0; j < OVERLAY_MAX_RANGES; j++) {
if (r.nx[j] == 0)
continue;
@@ -1532,7 +1536,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
}
}
} else if (gcp->attr & GRID_ATTR_CHARSET) {
- tty_attributes(tty, &last, defaults, palette);
+ tty_attributes(tty, &last, defaults, palette,
+ s->hyperlinks);
tty_cursor(tty, atx + ux, aty);
for (j = 0; j < gcp->data.size; j++)
tty_putc(tty, gcp->data.data[j]);
@@ -1544,7 +1549,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
}
}
if (len != 0 && ((~last.flags & GRID_FLAG_CLEARED) || last.bg != 8)) {
- tty_attributes(tty, &last, defaults, palette);
+ tty_attributes(tty, &last, defaults, palette, s->hyperlinks);
if (last.flags & GRID_FLAG_CLEARED) {
log_debug("%s: %zu cleared (end)", __func__, len);
tty_clear_line(tty, defaults, aty, atx + ux, width,
@@ -1560,7 +1565,8 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
if (!cleared && ux < nx) {
log_debug("%s: %u to end of line (%zu cleared)", __func__,
nx - ux, len);
- tty_default_attributes(tty, defaults, palette, 8);
+ tty_default_attributes(tty, defaults, palette, 8,
+ s->hyperlinks);
tty_clear_line(tty, defaults, aty, atx + ux, nx - ux, 8);
}
@@ -1646,7 +1652,8 @@ tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -1668,7 +1675,8 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
@@ -1678,7 +1686,8 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, ctx->num, ctx->bg);
}
@@ -1700,7 +1709,8 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_off(tty);
@@ -1727,7 +1737,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_off(tty);
@@ -1740,7 +1751,8 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->sx, ctx->bg);
}
@@ -1750,7 +1762,8 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
{
u_int nx = ctx->sx - ctx->ocx;
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_clear_pane_line(tty, ctx, ctx->ocy, ctx->ocx, nx, ctx->bg);
}
@@ -1758,7 +1771,8 @@ tty_cmd_clearendofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
{
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_clear_pane_line(tty, ctx, ctx->ocy, 0, ctx->ocx + 1, ctx->bg);
}
@@ -1784,7 +1798,8 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_pane(tty, ctx);
@@ -1815,7 +1830,8 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_pane(tty, ctx);
@@ -1855,7 +1871,8 @@ tty_cmd_scrollup(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_pane(tty, ctx);
@@ -1895,7 +1912,8 @@ tty_cmd_scrolldown(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_pane(tty, ctx);
@@ -1914,7 +1932,8 @@ tty_cmd_clearendofscreen(struct tty *tty, const struct tty_ctx *ctx)
{
u_int px, py, nx, ny;
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, 0, ctx->sy - 1);
tty_margin_off(tty);
@@ -1938,7 +1957,8 @@ tty_cmd_clearstartofscreen(struct tty *tty, const struct tty_ctx *ctx)
{
u_int px, py, nx, ny;
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, 0, ctx->sy - 1);
tty_margin_off(tty);
@@ -1962,7 +1982,8 @@ tty_cmd_clearscreen(struct tty *tty, const struct tty_ctx *ctx)
{
u_int px, py, nx, ny;
- tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg);
+ tty_default_attributes(tty, &ctx->defaults, ctx->palette, ctx->bg,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, 0, ctx->sy - 1);
tty_margin_off(tty);
@@ -1985,7 +2006,8 @@ tty_cmd_alignmenttest(struct tty *tty, const struct tty_ctx *ctx)
return;
}
- tty_attributes(tty, &grid_default_cell, &ctx->defaults, ctx->palette);
+ tty_attributes(tty, &grid_default_cell, &ctx->defaults, ctx->palette,
+ ctx->s->hyperlinks);
tty_region_pane(tty, ctx, 0, ctx->sy - 1);
tty_margin_off(tty);
@@ -2031,7 +2053,8 @@ tty_cmd_cell(struct tty *tty, const struct tty_ctx *ctx)
tty_margin_off(tty);
tty_cursor_pane_unless_wrap(tty, ctx, ctx->ocx, ctx->ocy);
- tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette);
+ tty_cell(tty, ctx->cell, &ctx->defaults, ctx->palette,
+ ctx->s->hyperlinks);
}
void
@@ -2062,7 +2085,7 @@ tty_cmd_cells(struct tty *tty, const struct tty_ctx *ctx)
tty_margin_off(tty);
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, ctx->s->hyperlinks);
/* Get tty position from pane position for overlay check. */
px = ctx->xoff + ctx->ocx - ctx->wox;
@@ -2136,7 +2159,8 @@ tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cell(struct tty *tty, const struct grid_cell *gc,
- const struct grid_cell *defaults, struct colour_palette *palette)
+ const struct grid_cell *defaults, struct colour_palette *palette,
+ struct hyperlinks *hl)
{
const struct grid_cell *gcp;
@@ -2152,11 +2176,11 @@ tty_cell(struct tty *tty, const struct grid_cell *gc,
/* Check the output codeset and apply attributes. */
gcp = tty_check_codeset(tty, gc);
- tty_attributes(tty, gcp, defaults, palette);
+ tty_attributes(tty, gcp, defaults, palette, hl);
/* If it is a single character, write with putc to handle ACS. */
if (gcp->data.size == 1) {
- tty_attributes(tty, gcp, defaults, palette);
+ tty_attributes(tty, gcp, defaults, palette, hl);
if (*gcp->data.data < 0x20 || *gcp->data.data == 0x7f)
return;
tty_putc(tty, *gcp->data.data);
@@ -2173,6 +2197,8 @@ tty_reset(struct tty *tty)
struct grid_cell *gc = &tty->cell;
if (!grid_cells_equal(gc, &grid_default_cell)) {
+ if (gc->link != 0)
+ tty_putcode_ptr2(tty, TTYC_HLS, "", "");
if ((gc->attr & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
tty_putcode(tty, TTYC_RMACS);
tty_putcode(tty, TTYC_SGR0);
@@ -2462,9 +2488,29 @@ out:
tty->cy = cy;
}
+static void
+tty_hyperlink(struct tty *tty, const struct grid_cell *gc,
+ struct hyperlinks *hl)
+{
+ const char *uri, *id;
+
+ if (gc->link == tty->cell.link)
+ return;
+ tty->cell.link = gc->link;
+
+ if (hl == NULL)
+ return;
+
+ if (gc->link == 0 || !hyperlinks_get(hl, gc->link, &uri, &id))
+ tty_putcode_ptr2(tty, TTYC_HLS, "", "");
+ else
+ tty_putcode_ptr2(tty, TTYC_HLS, id, uri);
+}
+
void
tty_attributes(struct tty *tty, const struct grid_cell *gc,
- const struct grid_cell *defaults, struct colour_palette *palette)
+ const struct grid_cell *defaults, struct colour_palette *palette,
+ struct hyperlinks *hl)
{
struct grid_cell *tc = &tty->cell, gc2;
int changed;
@@ -2482,7 +2528,8 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
if (gc2.attr == tty->last_cell.attr &&
gc2.fg == tty->last_cell.fg &&
gc2.bg == tty->last_cell.bg &&
- gc2.us == tty->last_cell.us)
+ gc2.us == tty->last_cell.us &&
+ gc2.link == tty->last_cell.link)
return;
/*
@@ -2559,6 +2606,9 @@ tty_attributes(struct tty *tty, const struct grid_cell *gc,
if ((changed & GRID_ATTR_CHARSET) && tty_acs_needed(tty))
tty_putcode(tty, TTYC_SMACS);
+ /* Set hyperlink if any. */
+ tty_hyperlink(tty, gc, hl);
+
memcpy(&tty->last_cell, &gc2, sizeof tty->last_cell);
}
@@ -2924,13 +2974,13 @@ tty_default_colours(struct grid_cell *gc, struct window_pane *wp)
static void
tty_default_attributes(struct tty *tty, const struct grid_cell *defaults,
- struct colour_palette *palette, u_int bg)
+ struct colour_palette *palette, u_int bg, struct hyperlinks *hl)
{
struct grid_cell gc;
memcpy(&gc, &grid_default_cell, sizeof gc);
gc.bg = bg;
- tty_attributes(tty, &gc, defaults, palette);
+ tty_attributes(tty, &gc, defaults, palette, hl);
}
static void