mirror of https://github.com/tmux/tmux.git
Merge topcat001/tmux/sixel.
parent
6794facc82
commit
4c92acf6ff
|
@ -154,7 +154,6 @@ dist_tmux_SOURCES = \
|
||||||
hyperlinks.c \
|
hyperlinks.c \
|
||||||
input-keys.c \
|
input-keys.c \
|
||||||
input.c \
|
input.c \
|
||||||
image.c \
|
|
||||||
job.c \
|
job.c \
|
||||||
key-bindings.c \
|
key-bindings.c \
|
||||||
key-string.c \
|
key-string.c \
|
||||||
|
@ -181,7 +180,6 @@ dist_tmux_SOURCES = \
|
||||||
server-fn.c \
|
server-fn.c \
|
||||||
server.c \
|
server.c \
|
||||||
session.c \
|
session.c \
|
||||||
sixel.c \
|
|
||||||
spawn.c \
|
spawn.c \
|
||||||
status.c \
|
status.c \
|
||||||
style.c \
|
style.c \
|
||||||
|
@ -220,6 +218,12 @@ if HAVE_UTF8PROC
|
||||||
nodist_tmux_SOURCES += compat/utf8proc.c
|
nodist_tmux_SOURCES += compat/utf8proc.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Enable sixel support.
|
||||||
|
if ENABLE_SIXEL
|
||||||
|
dist_tmux_SOURCES += image.c
|
||||||
|
dist_tmux_SOURCES += image-sixel.c
|
||||||
|
endif
|
||||||
|
|
||||||
if NEED_FUZZING
|
if NEED_FUZZING
|
||||||
check_PROGRAMS = fuzz/input-fuzzer
|
check_PROGRAMS = fuzz/input-fuzzer
|
||||||
fuzz_input_fuzzer_LDFLAGS = $(FUZZING_LIBS)
|
fuzz_input_fuzzer_LDFLAGS = $(FUZZING_LIBS)
|
||||||
|
|
10
configure.ac
10
configure.ac
|
@ -449,6 +449,16 @@ if test "x$enable_cgroups" = xyes; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Enable sixel support.
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
sixel,
|
||||||
|
AS_HELP_STRING(--enable-sixel, enable sixel images)
|
||||||
|
)
|
||||||
|
if test "x$enable_sixel" = xyes; then
|
||||||
|
AC_DEFINE(ENABLE_SIXEL)
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(ENABLE_SIXEL, [test "x$enable_sixel" = xyes])
|
||||||
|
|
||||||
# Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well.
|
# Check for b64_ntop. If we have b64_ntop, we assume b64_pton as well.
|
||||||
AC_MSG_CHECKING(for b64_ntop)
|
AC_MSG_CHECKING(for b64_ntop)
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
|
|
@ -126,7 +126,7 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
|
||||||
{
|
{
|
||||||
const char *last;
|
const char *last;
|
||||||
char *endptr;
|
char *endptr;
|
||||||
u_int d, x, y;
|
u_int x, y;
|
||||||
|
|
||||||
last = cp;
|
last = cp;
|
||||||
while (last != end) {
|
while (last != end) {
|
||||||
|
@ -134,10 +134,10 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
|
||||||
break;
|
break;
|
||||||
last++;
|
last++;
|
||||||
}
|
}
|
||||||
d = strtoul(cp, &endptr, 10);
|
strtoul(cp, &endptr, 10);
|
||||||
if (endptr == last || *endptr != ';')
|
if (endptr == last || *endptr != ';')
|
||||||
return (last);
|
return (last);
|
||||||
d = strtoul(endptr + 1, &endptr, 10);
|
strtoul(endptr + 1, &endptr, 10);
|
||||||
if (endptr == last || *endptr != ';')
|
if (endptr == last || *endptr != ';')
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
|
@ -442,7 +442,7 @@ sixel_print_repeat(char **buf, size_t *len, size_t *used, u_int count, char ch)
|
||||||
char *
|
char *
|
||||||
sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size)
|
sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size)
|
||||||
{
|
{
|
||||||
char *buf, tmp[64], *contains, data, last;
|
char *buf, tmp[64], *contains, data, last = 0;
|
||||||
size_t len, used = 0, tmplen;
|
size_t len, used = 0, tmplen;
|
||||||
u_int *colours, ncolours, i, c, x, y, count;
|
u_int *colours, ncolours, i, c, x, y, count;
|
||||||
struct sixel_line *sl;
|
struct sixel_line *sl;
|
9
image.c
9
image.c
|
@ -34,6 +34,8 @@ image_free(struct image *im)
|
||||||
all_images_count--;
|
all_images_count--;
|
||||||
|
|
||||||
TAILQ_REMOVE(&s->images, im, entry);
|
TAILQ_REMOVE(&s->images, im, entry);
|
||||||
|
sixel_free(im->data);
|
||||||
|
free(im->fallback);
|
||||||
free(im);
|
free(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ image_free_all(struct screen *s)
|
||||||
return (redraw);
|
return (redraw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
struct image*
|
||||||
image_store(struct screen *s, struct sixel_image *si)
|
image_store(struct screen *s, struct sixel_image *si)
|
||||||
{
|
{
|
||||||
struct image *im;
|
struct image *im;
|
||||||
|
@ -61,11 +63,16 @@ image_store(struct screen *s, struct sixel_image *si)
|
||||||
im->py = s->cy;
|
im->py = s->cy;
|
||||||
sixel_size_in_cells(si, &im->sx, &im->sy);
|
sixel_size_in_cells(si, &im->sx, &im->sy);
|
||||||
|
|
||||||
|
/* XXX Fallback mode: This can be abstracted further. */
|
||||||
|
xasprintf(&im->fallback, "Sixel image (%ux%u)\n", im->sx, im->sy);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&s->images, im, entry);
|
TAILQ_INSERT_TAIL(&s->images, im, entry);
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&all_images, im, all_entry);
|
TAILQ_INSERT_TAIL(&all_images, im, all_entry);
|
||||||
if (++all_images_count == 10/*XXX*/)
|
if (++all_images_count == 10/*XXX*/)
|
||||||
image_free(TAILQ_FIRST(&all_images));
|
image_free(TAILQ_FIRST(&all_images));
|
||||||
|
|
||||||
|
return (im);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
13
input.c
13
input.c
|
@ -1442,7 +1442,11 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||||
case -1:
|
case -1:
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
input_reply(ictx, "\033[?1;2;4c");
|
||||||
|
#else
|
||||||
input_reply(ictx, "\033[?1;2c");
|
input_reply(ictx, "\033[?1;2c");
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
||||||
|
@ -2237,19 +2241,22 @@ input_dcs_dispatch(struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
struct window_pane *wp = ictx->wp;
|
struct window_pane *wp = ictx->wp;
|
||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
struct window *w = wp->window;
|
|
||||||
u_char *buf = ictx->input_buf;
|
u_char *buf = ictx->input_buf;
|
||||||
size_t len = ictx->input_len;
|
size_t len = ictx->input_len;
|
||||||
const char prefix[] = "tmux;";
|
const char prefix[] = "tmux;";
|
||||||
const u_int prefixlen = (sizeof prefix) - 1;
|
const u_int prefixlen = (sizeof prefix) - 1;
|
||||||
struct sixel_image *si;
|
|
||||||
long long allow_passthrough = 0;
|
long long allow_passthrough = 0;
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
struct window *w = wp->window;
|
||||||
|
struct sixel_image *si;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
if (ictx->flags & INPUT_DISCARD)
|
if (ictx->flags & INPUT_DISCARD)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (buf[0] == 'q') {
|
if (buf[0] == 'q') {
|
||||||
si = sixel_parse(buf, len, w->xpixel, w->ypixel);
|
si = sixel_parse(buf, len, w->xpixel, w->ypixel);
|
||||||
if (si != NULL) {
|
if (si != NULL) {
|
||||||
|
@ -2257,6 +2264,7 @@ input_dcs_dispatch(struct input_ctx *ictx)
|
||||||
screen_write_sixelimage(sctx, si, ictx->cell.cell.bg);
|
screen_write_sixelimage(sctx, si, ictx->cell.cell.bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
allow_passthrough = options_get_number(wp->options, "allow-passthrough");
|
allow_passthrough = options_get_number(wp->options, "allow-passthrough");
|
||||||
if (!allow_passthrough)
|
if (!allow_passthrough)
|
||||||
|
@ -2267,6 +2275,7 @@ input_dcs_dispatch(struct input_ctx *ictx)
|
||||||
screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen,
|
screen_write_rawstring(sctx, buf + prefixlen, len - prefixlen,
|
||||||
allow_passthrough == 2);
|
allow_passthrough == 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -856,5 +856,8 @@ screen_redraw_draw_pane(struct screen_redraw_ctx *ctx, struct window_pane *wp)
|
||||||
tty_default_colours(&defaults, wp);
|
tty_default_colours(&defaults, wp);
|
||||||
tty_draw_line(tty, s, i, j, width, x, y, &defaults, palette);
|
tty_draw_line(tty, s, i, j, width, x, y, &defaults, palette);
|
||||||
}
|
}
|
||||||
tty_draw_images(tty, wp, s);
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
tty_draw_images(c, wp, s);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -990,8 +990,10 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
|
||||||
memcpy(&gc, &grid_default_cell, sizeof gc);
|
memcpy(&gc, &grid_default_cell, sizeof gc);
|
||||||
utf8_set(&gc.data, 'E');
|
utf8_set(&gc.data, 'E');
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_free_all(s) && ctx->wp != NULL)
|
if (image_free_all(s) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (yy = 0; yy < screen_size_y(s); yy++) {
|
for (yy = 0; yy < screen_size_y(s); yy++) {
|
||||||
for (xx = 0; xx < screen_size_x(s); xx++)
|
for (xx = 0; xx < screen_size_x(s); xx++)
|
||||||
|
@ -1027,8 +1029,10 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
||||||
if (s->cx > screen_size_x(s) - 1)
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1058,8 +1062,10 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
||||||
if (s->cx > screen_size_x(s) - 1)
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1089,8 +1095,10 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
|
||||||
if (s->cx > screen_size_x(s) - 1)
|
if (s->cx > screen_size_x(s) - 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1109,13 +1117,18 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid *gd = s->grid;
|
struct grid *gd = s->grid;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
u_int sy = screen_size_y(s);
|
u_int sy = screen_size_y(s);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
ny = 1;
|
ny = 1;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s->cy < s->rupper || s->cy > s->rlower) {
|
if (s->cy < s->rupper || s->cy > s->rlower) {
|
||||||
if (ny > screen_size_y(s) - s->cy)
|
if (ny > screen_size_y(s) - s->cy)
|
||||||
|
@ -1165,8 +1178,10 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
|
||||||
if (ny == 0)
|
if (ny == 0)
|
||||||
ny = 1;
|
ny = 1;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s->cy < s->rupper || s->cy > s->rlower) {
|
if (s->cy < s->rupper || s->cy > s->rlower) {
|
||||||
if (ny > sy - s->cy)
|
if (ny > sy - s->cy)
|
||||||
|
@ -1216,8 +1231,10 @@ screen_write_clearline(struct screen_write_ctx *ctx, u_int bg)
|
||||||
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
|
if (gl->cellsize == 0 && COLOUR_DEFAULT(bg))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
||||||
|
|
||||||
|
@ -1248,8 +1265,10 @@ screen_write_clearendofline(struct screen_write_ctx *ctx, u_int bg)
|
||||||
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && COLOUR_DEFAULT(bg)))
|
if (s->cx > sx - 1 || (s->cx >= gl->cellsize && COLOUR_DEFAULT(bg)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
|
grid_view_clear(s->grid, s->cx, s->cy, sx - s->cx, 1, bg);
|
||||||
|
|
||||||
|
@ -1278,8 +1297,10 @@ screen_write_clearstartofline(struct screen_write_ctx *ctx, u_int bg)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s->cx > sx - 1)
|
if (s->cx > sx - 1)
|
||||||
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
grid_view_clear(s->grid, 0, s->cy, sx, 1, bg);
|
||||||
|
@ -1328,8 +1349,10 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_free_all(s) && ctx->wp != NULL)
|
if (image_free_all(s) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s->cy == s->rupper) {
|
if (s->cy == s->rupper) {
|
||||||
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
|
||||||
|
@ -1374,7 +1397,7 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped, u_int bg)
|
||||||
struct screen *s = ctx->s;
|
struct screen *s = ctx->s;
|
||||||
struct grid *gd = s->grid;
|
struct grid *gd = s->grid;
|
||||||
struct grid_line *gl;
|
struct grid_line *gl;
|
||||||
int redraw;
|
int redraw = 0;
|
||||||
u_int rupper = s->rupper, rlower = s->rlower;
|
u_int rupper = s->rupper, rlower = s->rlower;
|
||||||
|
|
||||||
gl = grid_get_line(gd, gd->hsize + s->cy);
|
gl = grid_get_line(gd, gd->hsize + s->cy);
|
||||||
|
@ -1390,10 +1413,12 @@ screen_write_linefeed(struct screen_write_ctx *ctx, int wrapped, u_int bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->cy == s->rlower) {
|
if (s->cy == s->rlower) {
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (rlower == screen_size_y(s) - 1)
|
if (rlower == screen_size_y(s) - 1)
|
||||||
redraw = image_scroll_up(s, 1);
|
redraw = image_scroll_up(s, 1);
|
||||||
else
|
else
|
||||||
redraw = image_check_line(s, rupper, rlower - rupper);
|
redraw = image_check_line(s, rupper, rlower - rupper);
|
||||||
|
#endif
|
||||||
if (redraw && ctx->wp != NULL)
|
if (redraw && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
||||||
|
@ -1421,8 +1446,10 @@ screen_write_scrollup(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
||||||
ctx->bg = bg;
|
ctx->bg = bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_scroll_up(s, lines) && ctx->wp != NULL)
|
if (image_scroll_up(s, lines) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < lines; i++) {
|
for (i = 0; i < lines; i++) {
|
||||||
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_up(gd, s->rupper, s->rlower, bg);
|
||||||
|
@ -1448,8 +1475,10 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
|
||||||
else if (lines > s->rlower - s->rupper + 1)
|
else if (lines > s->rlower - s->rupper + 1)
|
||||||
lines = s->rlower - s->rupper + 1;
|
lines = s->rlower - s->rupper + 1;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_free_all(s) && ctx->wp != NULL)
|
if (image_free_all(s) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < lines; i++)
|
for (i = 0; i < lines; i++)
|
||||||
grid_view_scroll_region_down(gd, s->rupper, s->rlower, bg);
|
grid_view_scroll_region_down(gd, s->rupper, s->rlower, bg);
|
||||||
|
@ -1475,8 +1504,10 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
if (image_check_line(s, s->cy, sy - s->cy) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
screen_write_initctx(ctx, &ttyctx, 1);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1507,8 +1538,10 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
u_int sx = screen_size_x(s);
|
u_int sx = screen_size_x(s);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_line(s, 0, s->cy - 1) && ctx->wp != NULL)
|
if (image_check_line(s, 0, s->cy - 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
screen_write_initctx(ctx, &ttyctx, 1);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1533,8 +1566,10 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_free_all(s) && ctx->wp != NULL)
|
if (image_free_all(s) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 1);
|
screen_write_initctx(ctx, &ttyctx, 1);
|
||||||
ttyctx.bg = bg;
|
ttyctx.bg = bg;
|
||||||
|
@ -1804,8 +1839,10 @@ screen_write_collect_end(struct screen_write_ctx *ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
if (image_check_area(s, s->cx, s->cy, ci->used, 1) && ctx->wp != NULL)
|
if (image_check_area(s, s->cx, s->cy, ci->used, 1) && ctx->wp != NULL)
|
||||||
ctx->wp->flags |= PANE_REDRAW;
|
ctx->wp->flags |= PANE_REDRAW;
|
||||||
|
#endif
|
||||||
|
|
||||||
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, cl->data + ci->x,
|
grid_view_set_cells(s->grid, s->cx, s->cy, &ci->gc, cl->data + ci->x,
|
||||||
ci->used);
|
ci->used);
|
||||||
|
@ -2194,6 +2231,7 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
|
||||||
tty_write(tty_cmd_rawstring, &ttyctx);
|
tty_write(tty_cmd_rawstring, &ttyctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
/* Write a SIXEL image. */
|
/* Write a SIXEL image. */
|
||||||
void
|
void
|
||||||
screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
|
screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
|
||||||
|
@ -2239,15 +2277,14 @@ screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
|
||||||
}
|
}
|
||||||
screen_write_collect_flush(ctx, 0, __func__);
|
screen_write_collect_flush(ctx, 0, __func__);
|
||||||
|
|
||||||
image_store(s, si);
|
|
||||||
|
|
||||||
screen_write_initctx(ctx, &ttyctx, 0);
|
screen_write_initctx(ctx, &ttyctx, 0);
|
||||||
ttyctx.ptr = si;
|
ttyctx.ptr = image_store(s, si);
|
||||||
|
|
||||||
tty_write(tty_cmd_sixelimage, &ttyctx);
|
tty_write(tty_cmd_sixelimage, &ttyctx);
|
||||||
|
|
||||||
screen_write_cursormove(ctx, 0, cy + y, 0);
|
screen_write_cursormove(ctx, 0, cy + y, 0);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Turn alternate screen on. */
|
/* Turn alternate screen on. */
|
||||||
void
|
void
|
||||||
|
|
12
screen.c
12
screen.c
|
@ -88,7 +88,10 @@ screen_init(struct screen *s, u_int sx, u_int sy, u_int hlimit)
|
||||||
s->tabs = NULL;
|
s->tabs = NULL;
|
||||||
s->sel = NULL;
|
s->sel = NULL;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
TAILQ_INIT(&s->images);
|
TAILQ_INIT(&s->images);
|
||||||
|
#endif
|
||||||
|
|
||||||
s->write_list = NULL;
|
s->write_list = NULL;
|
||||||
s->hyperlinks = NULL;
|
s->hyperlinks = NULL;
|
||||||
|
|
||||||
|
@ -120,7 +123,11 @@ screen_reinit(struct screen *s)
|
||||||
|
|
||||||
screen_clear_selection(s);
|
screen_clear_selection(s);
|
||||||
screen_free_titles(s);
|
screen_free_titles(s);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
image_free_all(s);
|
image_free_all(s);
|
||||||
|
#endif
|
||||||
|
|
||||||
screen_reset_hyperlinks(s);
|
screen_reset_hyperlinks(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +160,10 @@ screen_free(struct screen *s)
|
||||||
if (s->hyperlinks != NULL)
|
if (s->hyperlinks != NULL)
|
||||||
hyperlinks_free(s->hyperlinks);
|
hyperlinks_free(s->hyperlinks);
|
||||||
screen_free_titles(s);
|
screen_free_titles(s);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
image_free_all(s);
|
image_free_all(s);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset tabs to default, eight spaces apart. */
|
/* Reset tabs to default, eight spaces apart. */
|
||||||
|
@ -298,7 +308,9 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
||||||
screen_resize_y(s, sy, eat_empty, &cy);
|
screen_resize_y(s, sy, eat_empty, &cy);
|
||||||
|
|
||||||
if (reflow) {
|
if (reflow) {
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
image_free_all(s);
|
image_free_all(s);
|
||||||
|
#endif
|
||||||
screen_reflow(s, sx, &cx, &cy, cursor);
|
screen_reflow(s, sx, &cx, &cy, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
tmux.1
2
tmux.1
|
@ -21,7 +21,7 @@
|
||||||
.Nm tmux
|
.Nm tmux
|
||||||
.Nd terminal multiplexer
|
.Nd terminal multiplexer
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm tmux
|
.Nm
|
||||||
.Bk -words
|
.Bk -words
|
||||||
.Op Fl 2CDlNuVv
|
.Op Fl 2CDlNuVv
|
||||||
.Op Fl c Ar shell-command
|
.Op Fl c Ar shell-command
|
||||||
|
|
31
tmux.h
31
tmux.h
|
@ -64,7 +64,11 @@ struct screen_write_citem;
|
||||||
struct screen_write_cline;
|
struct screen_write_cline;
|
||||||
struct screen_write_ctx;
|
struct screen_write_ctx;
|
||||||
struct session;
|
struct session;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
struct sixel_image;
|
struct sixel_image;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct tty_ctx;
|
struct tty_ctx;
|
||||||
struct tty_code;
|
struct tty_code;
|
||||||
struct tty_key;
|
struct tty_key;
|
||||||
|
@ -833,10 +837,12 @@ struct style {
|
||||||
enum style_default_type default_type;
|
enum style_default_type default_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
/* Image. */
|
/* Image. */
|
||||||
struct image {
|
struct image {
|
||||||
struct screen *s;
|
struct screen *s;
|
||||||
struct sixel_image *data;
|
struct sixel_image *data;
|
||||||
|
char *fallback;
|
||||||
|
|
||||||
u_int px;
|
u_int px;
|
||||||
u_int py;
|
u_int py;
|
||||||
|
@ -847,6 +853,7 @@ struct image {
|
||||||
TAILQ_ENTRY (image) entry;
|
TAILQ_ENTRY (image) entry;
|
||||||
};
|
};
|
||||||
TAILQ_HEAD(images, image);
|
TAILQ_HEAD(images, image);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Cursor style. */
|
/* Cursor style. */
|
||||||
enum screen_cursor_style {
|
enum screen_cursor_style {
|
||||||
|
@ -888,7 +895,10 @@ struct screen {
|
||||||
|
|
||||||
bitstr_t *tabs;
|
bitstr_t *tabs;
|
||||||
struct screen_sel *sel;
|
struct screen_sel *sel;
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
struct images images;
|
struct images images;
|
||||||
|
#endif
|
||||||
|
|
||||||
struct screen_write_cline *write_list;
|
struct screen_write_cline *write_list;
|
||||||
|
|
||||||
|
@ -1390,6 +1400,7 @@ struct tty {
|
||||||
|
|
||||||
u_int sx;
|
u_int sx;
|
||||||
u_int sy;
|
u_int sy;
|
||||||
|
/* Cell size in pixels. */
|
||||||
u_int xpixel;
|
u_int xpixel;
|
||||||
u_int ypixel;
|
u_int ypixel;
|
||||||
|
|
||||||
|
@ -1398,6 +1409,8 @@ struct tty {
|
||||||
enum screen_cursor_style cstyle;
|
enum screen_cursor_style cstyle;
|
||||||
int ccolour;
|
int ccolour;
|
||||||
|
|
||||||
|
/* Properties of the area being drawn on. */
|
||||||
|
/* When true, the drawing area is bigger than the terminal. */
|
||||||
int oflag;
|
int oflag;
|
||||||
u_int oox;
|
u_int oox;
|
||||||
u_int ooy;
|
u_int ooy;
|
||||||
|
@ -2341,7 +2354,11 @@ void tty_set_path(struct tty *, const char *);
|
||||||
void tty_update_mode(struct tty *, int, struct screen *);
|
void tty_update_mode(struct tty *, int, struct screen *);
|
||||||
void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
|
void tty_draw_line(struct tty *, struct screen *, u_int, u_int, u_int,
|
||||||
u_int, u_int, const struct grid_cell *, struct colour_palette *);
|
u_int, u_int, const struct grid_cell *, struct colour_palette *);
|
||||||
void tty_draw_images(struct tty *, struct window_pane *, struct screen *);
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
void tty_draw_images(struct client *, struct window_pane *, struct screen *);
|
||||||
|
#endif
|
||||||
|
|
||||||
void tty_sync_start(struct tty *);
|
void tty_sync_start(struct tty *);
|
||||||
void tty_sync_end(struct tty *);
|
void tty_sync_end(struct tty *);
|
||||||
int tty_open(struct tty *, char **);
|
int tty_open(struct tty *, char **);
|
||||||
|
@ -2372,7 +2389,11 @@ void tty_cmd_scrolldown(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_reverseindex(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_setselection(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
void tty_cmd_rawstring(struct tty *, const struct tty_ctx *);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
void tty_cmd_sixelimage(struct tty *, const struct tty_ctx *);
|
void tty_cmd_sixelimage(struct tty *, const struct tty_ctx *);
|
||||||
|
#endif
|
||||||
|
|
||||||
void tty_cmd_syncstart(struct tty *, const struct tty_ctx *);
|
void tty_cmd_syncstart(struct tty *, const struct tty_ctx *);
|
||||||
void tty_default_colours(struct grid_cell *, struct window_pane *);
|
void tty_default_colours(struct grid_cell *, struct window_pane *);
|
||||||
|
|
||||||
|
@ -2955,8 +2976,10 @@ void screen_write_setselection(struct screen_write_ctx *, const char *,
|
||||||
u_char *, u_int);
|
u_char *, u_int);
|
||||||
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int,
|
void screen_write_rawstring(struct screen_write_ctx *, u_char *, u_int,
|
||||||
int);
|
int);
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
void screen_write_sixelimage(struct screen_write_ctx *,
|
void screen_write_sixelimage(struct screen_write_ctx *,
|
||||||
struct sixel_image *, u_int);
|
struct sixel_image *, u_int);
|
||||||
|
#endif
|
||||||
void screen_write_alternateon(struct screen_write_ctx *,
|
void screen_write_alternateon(struct screen_write_ctx *,
|
||||||
struct grid_cell *, int);
|
struct grid_cell *, int);
|
||||||
void screen_write_alternateoff(struct screen_write_ctx *,
|
void screen_write_alternateoff(struct screen_write_ctx *,
|
||||||
|
@ -3370,14 +3393,15 @@ struct window_pane *spawn_pane(struct spawn_context *, char **);
|
||||||
/* regsub.c */
|
/* regsub.c */
|
||||||
char *regsub(const char *, const char *, const char *, int);
|
char *regsub(const char *, const char *, const char *, int);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
/* image.c */
|
/* image.c */
|
||||||
int image_free_all(struct screen *);
|
int image_free_all(struct screen *);
|
||||||
void image_store(struct screen *, struct sixel_image *);
|
struct image *image_store(struct screen *, struct sixel_image *);
|
||||||
int image_check_line(struct screen *, u_int, u_int);
|
int image_check_line(struct screen *, u_int, u_int);
|
||||||
int image_check_area(struct screen *, u_int, u_int, u_int, u_int);
|
int image_check_area(struct screen *, u_int, u_int, u_int, u_int);
|
||||||
int image_scroll_up(struct screen *, u_int);
|
int image_scroll_up(struct screen *, u_int);
|
||||||
|
|
||||||
/* sixel.c */
|
/* image-sixel.c */
|
||||||
struct sixel_image *sixel_parse(const char *, size_t, u_int, u_int);
|
struct sixel_image *sixel_parse(const char *, size_t, u_int, u_int);
|
||||||
void sixel_free(struct sixel_image *);
|
void sixel_free(struct sixel_image *);
|
||||||
void sixel_log(struct sixel_image *);
|
void sixel_log(struct sixel_image *);
|
||||||
|
@ -3387,6 +3411,7 @@ struct sixel_image *sixel_scale(struct sixel_image *, u_int, u_int, u_int,
|
||||||
char *sixel_print(struct sixel_image *, struct sixel_image *,
|
char *sixel_print(struct sixel_image *, struct sixel_image *,
|
||||||
size_t *);
|
size_t *);
|
||||||
struct screen *sixel_to_screen(struct sixel_image *);
|
struct screen *sixel_to_screen(struct sixel_image *);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* server-acl.c */
|
/* server-acl.c */
|
||||||
void server_acl_init(void);
|
void server_acl_init(void);
|
||||||
|
|
|
@ -1260,13 +1260,6 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//XXX primary DA
|
|
||||||
// for (i = 1; i < n; i++) {
|
|
||||||
// log_debug("%s: DA feature: %d", c->name, p[i]);
|
|
||||||
// if (p[i] == 4)
|
|
||||||
// flags |= TERM_SIXEL;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle primary device attributes input. Returns 0 for success, -1 for
|
* Handle primary device attributes input. Returns 0 for success, -1 for
|
||||||
* failure, 1 for partial.
|
* failure, 1 for partial.
|
||||||
|
|
102
tty.c
102
tty.c
|
@ -72,6 +72,11 @@ 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,
|
static void tty_check_overlay_range(struct tty *, u_int, u_int, u_int,
|
||||||
struct overlay_ranges *);
|
struct overlay_ranges *);
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
static void tty_write_one(void (*)(struct tty *, const struct tty_ctx *),
|
||||||
|
struct client *, struct tty_ctx *);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define tty_use_margin(tty) \
|
#define tty_use_margin(tty) \
|
||||||
(tty->term->flags & TERM_DECSLRM)
|
(tty->term->flags & TERM_DECSLRM)
|
||||||
#define tty_full_width(tty, ctx) \
|
#define tty_full_width(tty, ctx) \
|
||||||
|
@ -483,6 +488,11 @@ tty_update_features(struct tty *tty)
|
||||||
if (tty->term->flags & TERM_VT100LIKE)
|
if (tty->term->flags & TERM_VT100LIKE)
|
||||||
tty_puts(tty, "\033[?7727h");
|
tty_puts(tty, "\033[?7727h");
|
||||||
|
|
||||||
|
/* tty features might have changed since the first draw during attach.
|
||||||
|
* For example, this happens when DA responses are received.
|
||||||
|
*/
|
||||||
|
c->flags |= CLIENT_REDRAWWINDOW;
|
||||||
|
|
||||||
tty_invalidate(tty);
|
tty_invalidate(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1576,37 +1586,57 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||||
tty_update_mode(tty, tty->mode, s);
|
tty_update_mode(tty, tty->mode, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
#ifdef ENABLE_SIXEL
|
||||||
tty_draw_images(struct tty *tty, struct window_pane *wp, struct screen *s)
|
/* Update context for client. */
|
||||||
|
static int
|
||||||
|
tty_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = ttyctx->arg;
|
||||||
|
|
||||||
|
if (c->session->curw->window != wp->window)
|
||||||
|
return (0);
|
||||||
|
if (wp->layout_cell == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Set the properties relevant to the current client. */
|
||||||
|
ttyctx->bigger = tty_window_offset(&c->tty, &ttyctx->wox, &ttyctx->woy,
|
||||||
|
&ttyctx->wsx, &ttyctx->wsy);
|
||||||
|
|
||||||
|
ttyctx->yoff = ttyctx->ryoff = wp->yoff;
|
||||||
|
if (status_at_line(c) == 0)
|
||||||
|
ttyctx->yoff += status_line_size(c);
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tty_draw_images(struct client *c, struct window_pane *wp, struct screen *s)
|
||||||
{
|
{
|
||||||
#if 0 /* XXX */
|
|
||||||
struct client *c = tty->client;
|
|
||||||
struct image *im;
|
struct image *im;
|
||||||
struct tty_ctx ttyctx;
|
struct tty_ctx ttyctx;
|
||||||
|
|
||||||
TAILQ_FOREACH(im, &s->images, entry) {
|
TAILQ_FOREACH(im, &s->images, entry) {
|
||||||
memset(&ttyctx, 0, sizeof ttyctx);
|
memset(&ttyctx, 0, sizeof ttyctx);
|
||||||
|
|
||||||
|
/* Set the client independent properties. */
|
||||||
ttyctx.ocx = im->px;
|
ttyctx.ocx = im->px;
|
||||||
ttyctx.ocy = im->py;
|
ttyctx.ocy = im->py;
|
||||||
|
|
||||||
ttyctx.orlower = s->rlower;
|
ttyctx.orlower = s->rlower;
|
||||||
ttyctx.orupper = s->rupper;
|
ttyctx.orupper = s->rupper;
|
||||||
|
|
||||||
ttyctx.bigger = tty_window_offset(&c->tty, &ttyctx.ox,
|
ttyctx.xoff = ttyctx.rxoff = wp->xoff;
|
||||||
&ttyctx.oy, &ttyctx.sx, &ttyctx.sy);
|
ttyctx.sx = wp->sx;
|
||||||
|
ttyctx.sy = wp->sy;
|
||||||
|
|
||||||
ttyctx.xoff = wp->xoff;
|
ttyctx.ptr = im;
|
||||||
ttyctx.yoff = wp->yoff;
|
ttyctx.arg = wp;
|
||||||
|
ttyctx.set_client_cb = tty_set_client_cb;
|
||||||
if (status_at_line(c) == 0)
|
ttyctx.allow_invisible_panes = 1;
|
||||||
ttyctx.yoff += status_line_size(c);
|
tty_write_one(tty_cmd_sixelimage, c, &ttyctx);
|
||||||
|
|
||||||
ttyctx.ptr = im->data;
|
|
||||||
tty_cmd_sixelimage(tty, &ttyctx);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_sync_start(struct tty *tty)
|
tty_sync_start(struct tty *tty)
|
||||||
|
@ -1681,6 +1711,19 @@ tty_write(void (*cmdfn)(struct tty *, const struct tty_ctx *),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
|
/* Only write to the incoming tty instead of every client. */
|
||||||
|
static void
|
||||||
|
tty_write_one(void (*cmdfn)(struct tty *, const struct tty_ctx *),
|
||||||
|
struct client *c, struct tty_ctx *ctx)
|
||||||
|
{
|
||||||
|
if (ctx->set_client_cb == NULL)
|
||||||
|
return;
|
||||||
|
if ((ctx->set_client_cb(ctx, c)) == 1)
|
||||||
|
cmdfn(&c->tty, ctx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_insertcharacter(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
|
@ -2182,21 +2225,24 @@ tty_cmd_rawstring(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
tty_invalidate(tty);
|
tty_invalidate(tty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SIXEL
|
||||||
void
|
void
|
||||||
tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
{
|
{
|
||||||
struct sixel_image *si = ctx->ptr;
|
struct image *im = ctx->ptr;
|
||||||
|
struct sixel_image *si = im->data;
|
||||||
struct sixel_image *new;
|
struct sixel_image *new;
|
||||||
char *data;
|
char *data;
|
||||||
size_t size;
|
size_t size;
|
||||||
u_int cx = ctx->ocx, cy = ctx->ocy, sx, sy;
|
u_int cx = ctx->ocx, cy = ctx->ocy, sx, sy;
|
||||||
u_int i, j, x, y, rx, ry;
|
u_int i, j, x, y, rx, ry;
|
||||||
|
int fallback = 0;
|
||||||
|
|
||||||
if ((~tty->term->flags & TERM_SIXEL) &&
|
if ((~tty->term->flags & TERM_SIXEL) &&
|
||||||
!tty_term_has(tty->term, TTYC_SXL))
|
!tty_term_has(tty->term, TTYC_SXL))
|
||||||
return;
|
fallback = 1;
|
||||||
if (tty->xpixel == 0 || tty->ypixel == 0)
|
if (tty->xpixel == 0 || tty->ypixel == 0)
|
||||||
return;
|
fallback = 1;
|
||||||
|
|
||||||
sixel_size_in_cells(si, &sx, &sy);
|
sixel_size_in_cells(si, &sx, &sy);
|
||||||
log_debug("%s: image is %ux%u", __func__, sx, sy);
|
log_debug("%s: image is %ux%u", __func__, sx, sy);
|
||||||
|
@ -2204,11 +2250,16 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
return;
|
return;
|
||||||
log_debug("%s: clamping to %u,%u-%u,%u", __func__, i, j, rx, ry);
|
log_debug("%s: clamping to %u,%u-%u,%u", __func__, i, j, rx, ry);
|
||||||
|
|
||||||
new = sixel_scale(si, tty->xpixel, tty->ypixel, i, j, rx, ry, 0);
|
if (fallback == 1) {
|
||||||
if (new == NULL)
|
data = xstrdup(im->fallback);
|
||||||
return;
|
size = strlen(data);
|
||||||
|
} else {
|
||||||
|
new = sixel_scale(si, tty->xpixel, tty->ypixel, i, j, rx, ry, 0);
|
||||||
|
if (new == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
data = sixel_print(new, si, &size);
|
data = sixel_print(new, si, &size);
|
||||||
|
}
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
log_debug("%s: %zu bytes: %s", __func__, size, data);
|
log_debug("%s: %zu bytes: %s", __func__, size, data);
|
||||||
tty_region_off(tty);
|
tty_region_off(tty);
|
||||||
|
@ -2220,8 +2271,11 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
tty_invalidate(tty);
|
tty_invalidate(tty);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
sixel_free(new);
|
|
||||||
|
if (fallback == 0)
|
||||||
|
sixel_free(new);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx)
|
tty_cmd_syncstart(struct tty *tty, const struct tty_ctx *ctx)
|
||||||
|
|
Loading…
Reference in New Issue