Skip to content

Instantly share code, notes, and snippets.

@sileht
Last active December 5, 2022 23:12
Show Gist options
  • Save sileht/8759089d5620da763bb456a0ae82e4d0 to your computer and use it in GitHub Desktop.
Save sileht/8759089d5620da763bb456a0ae82e4d0 to your computer and use it in GitHub Desktop.
sixel support for tmux-2.5-2\~bpo9+1
commit b4a5392a631ca08893c7b5653756bc1aa21db71b
Author: Mehdi Abaakouk <sileht@sileht.net>
Committer: Mehdi Abaakouk <sileht@sileht.net>
Date: Fri Oct 6 10:16:01 2017 (43 seconds ago)
sixel patch
Updated from https://github.com/saitoha/tmux-SIXEL
for debian strech
To enable, add to your tmux.conf: set -ga terminal-overrides ',xterm*:smglr=\E7\E[?69h\E[%i%p1%d;%p2%ds\E8:mgc=\E7\E[?69l\E8'
diff --git a/input.c b/input.c
index 22dd1ee..c11ab7e 100644
--- a/input.c
+++ b/input.c
@@ -1845,6 +1845,7 @@ input_dcs_dispatch(struct input_ctx *ictx)
{
const char prefix[] = "tmux;";
const u_int prefix_len = (sizeof prefix) - 1;
+ u_char *p;
if (ictx->flags & INPUT_DISCARD)
return (0);
@@ -1858,6 +1859,15 @@ input_dcs_dispatch(struct input_ctx *ictx)
ictx->input_buf + prefix_len, ictx->input_len - prefix_len);
}
+ for (p = ictx->input_buf; p != ictx->input_buf + ictx->input_len; p++) {
+ if ((*p >= 0 && *p <= 9) || *p == ';')
+ continue;
+ if (*p != 'q')
+ break;
+ screen_write_sixel(&ictx->ctx,
+ ictx->input_buf, ictx->input_len);
+ }
+
return (0);
}
diff --git a/screen-write.c b/screen-write.c
index 0a63e1b..fc183e0 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -1417,6 +1417,18 @@ screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len)
}
/* Write unmodified string. */
+void
+screen_write_sixel(struct screen_write_ctx *ctx, u_char *str, u_int len)
+{
+ struct tty_ctx ttyctx;
+
+ screen_write_initctx(ctx, &ttyctx);
+ ttyctx.ptr = str;
+ ttyctx.num = len;
+
+ tty_write(tty_cmd_write_sixel, &ttyctx);
+}
+
void
screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len)
{
diff --git a/tmux.h b/tmux.h
index 40bc99f..70a6f40 100644
--- a/tmux.h
+++ b/tmux.h
@@ -384,6 +384,7 @@ enum tty_code_code {
TTYC_KUP5,
TTYC_KUP6,
TTYC_KUP7,
+ TTYC_MGC, /* clear_margins, MC */
TTYC_MS, /* modify xterm(1) selection */
TTYC_OP, /* orig_pair, op */
TTYC_REV, /* enter_reverse_mode, mr */
@@ -398,6 +399,7 @@ enum tty_code_code {
TTYC_SITM, /* enter_italics_mode, it */
TTYC_SMACS, /* enter_alt_charset_mode, as */
TTYC_SMCUP, /* enter_ca_mode, ti */
+ TTYC_SMGLR, /* set_lr_margin, ML */
TTYC_SMKX, /* keypad_xmit, ks */
TTYC_SMSO, /* enter_standout_mode, so */
TTYC_SMUL, /* enter_underline_mode, us */
@@ -1041,6 +1043,8 @@ struct tty {
u_int cx;
u_int cy;
+ u_int pixel_x;
+ u_int pixel_y;
u_int cstyle;
char *ccolour;
@@ -1681,6 +1685,7 @@ void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
void tty_cmd_scrollup(struct tty *, const struct tty_ctx *);
void tty_cmd_reverseindex(struct tty *, const struct tty_ctx *);
void tty_cmd_setselection(struct tty *, const struct tty_ctx *);
+void tty_cmd_write_sixel(struct tty *, const struct tty_ctx *);
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
/* tty-term.c */
@@ -2020,6 +2025,7 @@ void screen_write_collect_add(struct screen_write_ctx *,
const struct grid_cell *);
void screen_write_cell(struct screen_write_ctx *, const struct grid_cell *);
void screen_write_setselection(struct screen_write_ctx *, u_char *, u_int);
+void screen_write_sixel(struct screen_write_ctx *, u_char *, u_int);
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int);
/* screen-redraw.c */
diff --git a/tty-term.c b/tty-term.c
index b8a25de..926d59e 100644
--- a/tty-term.c
+++ b/tty-term.c
@@ -215,6 +215,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_KNXT4] = { TTYCODE_STRING, "kNXT4" },
[TTYC_KNXT5] = { TTYCODE_STRING, "kNXT5" },
[TTYC_KNXT6] = { TTYCODE_STRING, "kNXT6" },
+ [TTYC_MGC] = { TTYCODE_STRING, "mgc" },
[TTYC_KNXT7] = { TTYCODE_STRING, "kNXT7" },
[TTYC_KPP] = { TTYCODE_STRING, "kpp" },
[TTYC_KPRV2] = { TTYCODE_STRING, "kPRV" },
@@ -229,6 +230,7 @@ static const struct tty_term_code_entry tty_term_codes[] = {
[TTYC_KRIT5] = { TTYCODE_STRING, "kRIT5" },
[TTYC_KRIT6] = { TTYCODE_STRING, "kRIT6" },
[TTYC_KRIT7] = { TTYCODE_STRING, "kRIT7" },
+ [TTYC_SMGLR] = { TTYCODE_STRING, "smglr" },
[TTYC_KUP2] = { TTYCODE_STRING, "kUP" },
[TTYC_KUP3] = { TTYCODE_STRING, "kUP3" },
[TTYC_KUP4] = { TTYCODE_STRING, "kUP4" },
diff --git a/tty.c b/tty.c
index 1c39fce..55e4c1c 100644
--- a/tty.c
+++ b/tty.c
@@ -129,6 +129,8 @@ tty_resize(struct tty *tty)
struct winsize ws;
u_int sx, sy;
+ memset(&ws, 0, sizeof(ws));
+
if (ioctl(tty->fd, TIOCGWINSZ, &ws) != -1) {
sx = ws.ws_col;
if (sx == 0)
@@ -136,6 +138,8 @@ tty_resize(struct tty *tty)
sy = ws.ws_row;
if (sy == 0)
sy = 24;
+ tty->pixel_x = ws.ws_xpixel;
+ tty->pixel_y = ws.ws_ypixel;
} else {
sx = 80;
sy = 24;
@@ -975,8 +979,10 @@ tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
- tty_fake_bce(tty, ctx->wp, ctx->bg) ||
+ struct screen *s = ctx->wp->screen;
+
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) &&
+ tty_fake_bce(tty, ctx->wp, ctx->bg)) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_IL1)) {
tty_redraw_region(tty, ctx);
@@ -985,18 +991,28 @@ tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx)
tty_default_attributes(tty, ctx->wp, ctx->bg);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode2(tty, TTYC_SMGLR,
+ ctx->xoff, ctx->xoff + screen_size_x(s) - 1);
+
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_off(tty);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num);
tty->cx = tty->cy = UINT_MAX;
+
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode(tty, TTYC_MGC);
}
void
tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
{
- if (!tty_pane_full_width(tty, ctx) ||
+ struct screen *s = ctx->wp->screen;
+
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) &&
+ !tty_pane_full_width(tty, ctx)) ||
tty_fake_bce(tty, ctx->wp, ctx->bg) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_DL1)) {
@@ -1006,12 +1022,18 @@ tty_cmd_deleteline(struct tty *tty, const struct tty_ctx *ctx)
tty_default_attributes(tty, ctx->wp, ctx->bg);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode2(tty, TTYC_SMGLR,
+ ctx->xoff, ctx->xoff + screen_size_x(s) - 1);
+
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_off(tty);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num);
tty->cx = tty->cy = UINT_MAX;
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode(tty, TTYC_MGC);
}
void
@@ -1073,10 +1095,13 @@ tty_cmd_clearstartofline(struct tty *tty, const struct tty_ctx *ctx)
void
tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
{
+ struct screen *s = ctx->wp->screen;
+
if (ctx->ocy != ctx->orupper)
return;
- if (!tty_pane_full_width(tty, ctx) ||
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) &&
+ !tty_pane_full_width(tty, ctx)) ||
tty_fake_bce(tty, ctx->wp, 8) ||
!tty_term_has(tty->term, TTYC_CSR) ||
!tty_term_has(tty->term, TTYC_RI)) {
@@ -1086,10 +1111,17 @@ tty_cmd_reverseindex(struct tty *tty, const struct tty_ctx *ctx)
tty_attributes(tty, &grid_default_cell, ctx->wp);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode2(tty, TTYC_SMGLR,
+ ctx->xoff, ctx->xoff + screen_size_x(s) - 1);
+
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_off(tty);
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode(tty, TTYC_MGC);
+
tty_putcode(tty, TTYC_RI);
}
@@ -1097,19 +1129,26 @@ void
tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
+ struct screen *s = wp->screen;
if (ctx->ocy != ctx->orlower)
return;
- if ((!tty_pane_full_width(tty, ctx) && !tty_use_margin(tty)) ||
- tty_fake_bce(tty, wp, 8) ||
- !tty_term_has(tty->term, TTYC_CSR)) {
- tty_redraw_region(tty, ctx);
- return;
- }
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) &&
+ !tty_pane_full_width(tty, ctx) &&
+ !tty_use_margin(tty)) ||
+ tty_fake_bce(tty, wp, 8) ||
+ !tty_term_has(tty->term, TTYC_CSR)) {
+ tty_redraw_region(tty, ctx);
+ return;
+ }
tty_attributes(tty, &grid_default_cell, wp);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode2(tty, TTYC_SMGLR,
+ ctx->xoff, ctx->xoff + screen_size_x(s) - 1);
+
tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
tty_margin_pane(tty, ctx);
@@ -1124,6 +1163,9 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx)
tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
tty_putc(tty, '\n');
+
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode(tty, TTYC_MGC);
}
void
@@ -1338,6 +1380,38 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx)
free(buf);
}
+void
+tty_cmd_write_sixel(struct tty *tty, const struct tty_ctx *ctx)
+{
+ u_char *str = ctx->ptr;
+ u_char *start = str;
+ u_char *end = str + ctx->num;
+ u_char *p = str;
+ int pixel_y = 6;
+ struct screen *s = ctx->wp->screen;
+
+ if (s != NULL && tty->pixel_y > 0) {
+ tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode2(tty, TTYC_SMGLR, ctx->xoff,
+ ctx->xoff + screen_size_x(s) - 1);
+ tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
+ bufferevent_write(ctx->wp->event, "\033P", 2);
+ bufferevent_write(ctx->wp->event, str, ctx->num);
+ bufferevent_write(ctx->wp->event, "\033\\", 2);
+ if (!tty_pane_full_width(tty, ctx))
+ tty_putcode(tty, TTYC_MGC);
+ tty_region_pane(tty, ctx, ctx->orupper, ctx->orlower);
+ tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy);
+ for (p = start; p != end; ++p)
+ if (*p == '-')
+ pixel_y += 6;
+ s->cy += (pixel_y - 1) * tty->sy / tty->pixel_y + 1;
+ if (s->cy > screen_size_y(s) - 1)
+ s->cy = screen_size_y(s) - 1;
+ }
+}
+
void
tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
{
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment