Created
July 14, 2015 16:21
-
-
Save saitoha/ad59c1c4be095accaf4e to your computer and use it in GitHub Desktop.
tmux: SIXEL integration (for mlterm / RLogin, not works on XTerm)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/input.c b/input.c | |
index d1ff17f..33fad13 100644 | |
--- a/input.c | |
+++ b/input.c | |
@@ -1805,6 +1805,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); | |
@@ -1818,6 +1819,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 e38c9f5..7a756c7 100644 | |
--- a/screen-write.c | |
+++ b/screen-write.c | |
@@ -1096,6 +1096,18 @@ screen_write_setselection(struct screen_write_ctx *ctx, u_char *str, u_int len) | |
} | |
void | |
+screen_write_sixel(struct screen_write_ctx *ctx, u_char *str, u_int len) | |
+{ | |
+ struct tty_ctx ttyctx; | |
+ | |
+ screen_write_initctx(ctx, &ttyctx, 0); | |
+ 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) | |
{ | |
struct tty_ctx ttyctx; | |
diff --git a/tmux.h b/tmux.h | |
index f0fef0d..6363f35 100644 | |
--- a/tmux.h | |
+++ b/tmux.h | |
@@ -368,6 +368,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 */ | |
@@ -382,6 +383,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 */ | |
@@ -1127,6 +1129,8 @@ struct tty { | |
u_int cx; | |
u_int cy; | |
+ u_int pixel_x; | |
+ u_int pixel_y; | |
u_int cstyle; | |
char *ccolour; | |
@@ -1641,6 +1645,7 @@ void tty_cmd_linefeed(struct tty *, const struct tty_ctx *); | |
void tty_cmd_utf8character(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 *); | |
void tty_bell(struct tty *); | |
@@ -2070,6 +2075,7 @@ void screen_write_clearscreen(struct screen_write_ctx *); | |
void screen_write_clearhistory(struct screen_write_ctx *); | |
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 d177c19..13cd982 100644 | |
--- a/tty-term.c | |
+++ b/tty-term.c | |
@@ -215,6 +215,7 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = { | |
{ TTYC_KUP5, TTYCODE_STRING, "kUP5" }, | |
{ TTYC_KUP6, TTYCODE_STRING, "kUP6" }, | |
{ TTYC_KUP7, TTYCODE_STRING, "kUP7" }, | |
+ { TTYC_MGC, TTYCODE_STRING, "mgc" }, | |
{ TTYC_MS, TTYCODE_STRING, "Ms" }, | |
{ TTYC_OP, TTYCODE_STRING, "op" }, | |
{ TTYC_REV, TTYCODE_STRING, "rev" }, | |
@@ -229,6 +230,7 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = { | |
{ TTYC_SITM, TTYCODE_STRING, "sitm" }, | |
{ TTYC_SMACS, TTYCODE_STRING, "smacs" }, | |
{ TTYC_SMCUP, TTYCODE_STRING, "smcup" }, | |
+ { TTYC_SMGLR, TTYCODE_STRING, "smglr" }, | |
{ TTYC_SMKX, TTYCODE_STRING, "smkx" }, | |
{ TTYC_SMSO, TTYCODE_STRING, "smso" }, | |
{ TTYC_SMUL, TTYCODE_STRING, "smul" }, | |
diff --git a/tty.c b/tty.c | |
index 63380c2..8176499 100644 | |
--- a/tty.c | |
+++ b/tty.c | |
@@ -90,6 +90,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) | |
@@ -97,6 +99,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; | |
@@ -831,7 +835,11 @@ 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) || | |
+ 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) || | |
!tty_term_has(tty->term, TTYC_CSR) || | |
!tty_term_has(tty->term, TTYC_IL1)) { | |
tty_redraw_region(tty, ctx); | |
@@ -840,16 +848,25 @@ tty_cmd_insertline(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_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); | |
tty_emulate_repeat(tty, TTYC_IL, TTYC_IL1, ctx->num); | |
+ 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) || tty_fake_bce(tty, ctx->wp) || | |
+ 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) || | |
!tty_term_has(tty->term, TTYC_CSR) || | |
!tty_term_has(tty->term, TTYC_DL1)) { | |
tty_redraw_region(tty, ctx); | |
@@ -858,10 +875,15 @@ tty_cmd_deleteline(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_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); | |
tty_emulate_repeat(tty, TTYC_DL, TTYC_DL1, ctx->num); | |
+ if (!tty_pane_full_width(tty, ctx)) | |
+ tty_putcode(tty, TTYC_MGC); | |
} | |
void | |
@@ -916,10 +938,14 @@ 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) || tty_fake_bce(tty, ctx->wp) || | |
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) && | |
+ !tty_pane_full_width(tty, ctx)) || | |
+ tty_fake_bce(tty, ctx->wp) || | |
!tty_term_has(tty->term, TTYC_CSR) || | |
!tty_term_has(tty->term, TTYC_RI)) { | |
tty_redraw_region(tty, ctx); | |
@@ -928,21 +954,29 @@ 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_cursor_pane(tty, ctx, ctx->ocx, ctx->orupper); | |
tty_putcode(tty, TTYC_RI); | |
+ if (!tty_pane_full_width(tty, ctx)) | |
+ tty_putcode(tty, TTYC_MGC); | |
} | |
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_fake_bce(tty, wp) || | |
+ if ((!tty_term_has(tty->term, TTYC_SMGLR) && | |
+ !tty_pane_full_width(tty, ctx)) || | |
+ tty_fake_bce(tty, ctx->wp) || | |
!tty_term_has(tty->term, TTYC_CSR)) { | |
if (tty_large_region(tty, ctx)) | |
wp->flags |= PANE_REDRAW; | |
@@ -961,10 +995,15 @@ tty_cmd_linefeed(struct tty *tty, const struct tty_ctx *ctx) | |
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_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 | |
@@ -1145,6 +1184,38 @@ tty_cmd_setselection(struct tty *tty, const struct tty_ctx *ctx) | |
} | |
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(tty->event, "\033P", 2); | |
+ bufferevent_write(tty->event, str, ctx->num); | |
+ bufferevent_write(tty->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) | |
{ | |
u_int i; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
set -ga terminal-overrides ',xterm*:smglr=\E7\E[?69h\E[%i%p1%d;%p2%ds\E8:mgc=\E7\E[?69l\E8' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@HalosGhost It reproduced for me.
The reason is that the
master
branch of yaft does not return terminal pixel size overTIOCGWINSZ
.yaft
develop
branch seemes to do it.uobikiemukot/yaft@9bb83c1#diff-8c689842501e39ed6229d6ec73103c42R121
You should use the
develop
branch or apply it.https://gist.github.com/saitoha/2c662697f972170150ab
Even if you do above solution, it won't works with tmux's vertical split feature, because yaft does not supports DECLRMM/DECSLRM.