mirror of
https://github.com/tmux/tmux.git
synced 2026-03-07 00:05:33 +00:00
Feedback from nicm
This commit is contained in:
@@ -469,9 +469,8 @@ AC_ARG_ENABLE(
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
sixel,
|
||||
AS_HELP_STRING(--enable-sixel, deprecated; use --enable-sixel-images),
|
||||
AS_HELP_STRING(--enable-sixel support),
|
||||
[
|
||||
AC_MSG_WARN([--enable-sixel is deprecated; use --enable-sixel-images])
|
||||
enable_sixel_images="$enableval"
|
||||
]
|
||||
)
|
||||
|
||||
11
format.c
11
format.c
@@ -2566,16 +2566,13 @@ format_cb_image_support(__unused struct format_tree *ft)
|
||||
{
|
||||
#if defined(ENABLE_SIXEL_IMAGES) && defined(ENABLE_KITTY_IMAGES)
|
||||
return (xstrdup("kitty,sixel"));
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_SIXEL_IMAGES
|
||||
#elif defined(ENABLE_SIXEL_IMAGES)
|
||||
return (xstrdup("sixel"));
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
#elif defined(ENABLE_KITTY_IMAGES)
|
||||
return (xstrdup("kitty"));
|
||||
#endif
|
||||
#else
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Callback for active_window_index. */
|
||||
|
||||
@@ -23,6 +23,41 @@
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* kitty_image stores the raw decoded pixel data and metadata from a kitty
|
||||
* graphics protocol APC sequence. It is used to re-emit the sequence to the
|
||||
* outer terminal on redraw.
|
||||
*/
|
||||
struct kitty_image {
|
||||
/* Control-data fields parsed from the APC sequence. */
|
||||
char action; /* a=: 'T'=transmit+display, 't', 'p', 'd' */
|
||||
u_int format; /* f=: 32=RGBA, 24=RGB, 100=PNG */
|
||||
char medium; /* t=: 'd'=direct, 'f'=file, 't'=tmp, 's'=shm */
|
||||
u_int pixel_w; /* s=: source image pixel width */
|
||||
u_int pixel_h; /* v=: source image pixel height */
|
||||
u_int cols; /* c=: display columns (0=auto) */
|
||||
u_int rows; /* r=: display rows (0=auto) */
|
||||
u_int image_id; /* i=: image id (0=unassigned) */
|
||||
u_int image_num; /* I=: image number */
|
||||
u_int placement_id; /* p=: placement id */
|
||||
u_int more; /* m=: 1=more chunks coming, 0=last */
|
||||
u_int quiet; /* q=: suppress responses */
|
||||
int z_index; /* z=: z-index */
|
||||
char compression; /* o=: 'z'=zlib, 0=none */
|
||||
char delete_what; /* d=: delete target (used with a=d) */
|
||||
|
||||
/* Cell size at the time of parsing (from the owning window). */
|
||||
u_int xpixel;
|
||||
u_int ypixel;
|
||||
|
||||
/* Original base64-encoded payload (concatenated across all chunks). */
|
||||
char *encoded;
|
||||
size_t encodedlen;
|
||||
|
||||
char *ctrl;
|
||||
size_t ctrllen;
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse control-data key=value pairs from a kitty APC sequence.
|
||||
* Format: key=value,key=value,...
|
||||
@@ -190,6 +225,52 @@ kitty_free(struct kitty_image *ki)
|
||||
free(ki);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the size in cells of a kitty image. If cols/rows are 0 (auto),
|
||||
* calculate from pixel dimensions. Returns size via sx/sy pointers.
|
||||
*/
|
||||
void
|
||||
kitty_size_in_cells(struct kitty_image *ki, u_int *sx, u_int *sy)
|
||||
{
|
||||
*sx = ki->cols;
|
||||
*sy = ki->rows;
|
||||
|
||||
/*
|
||||
* If cols/rows are 0, they mean "auto" - calculate from
|
||||
* pixel dimensions.
|
||||
*/
|
||||
if (*sx == 0 && ki->pixel_w > 0 && ki->xpixel > 0) {
|
||||
*sx = (ki->pixel_w + ki->xpixel - 1) / ki->xpixel;
|
||||
}
|
||||
if (*sy == 0 && ki->pixel_h > 0 && ki->ypixel > 0) {
|
||||
*sy = (ki->pixel_h + ki->ypixel - 1) / ki->ypixel;
|
||||
}
|
||||
|
||||
/* If still 0, use a reasonable default */
|
||||
if (*sx == 0)
|
||||
*sx = 10;
|
||||
if (*sy == 0)
|
||||
*sy = 10;
|
||||
}
|
||||
|
||||
char
|
||||
kitty_get_action(struct kitty_image *ki)
|
||||
{
|
||||
return (ki->action);
|
||||
}
|
||||
|
||||
u_int
|
||||
kitty_get_image_id(struct kitty_image *ki)
|
||||
{
|
||||
return (ki->image_id);
|
||||
}
|
||||
|
||||
u_int
|
||||
kitty_get_rows(struct kitty_image *ki)
|
||||
{
|
||||
return (ki->rows);
|
||||
}
|
||||
|
||||
/*
|
||||
* Serialize a kitty_image back into an APC escape sequence for transmission
|
||||
* to the terminal. This recreates the original command that was parsed.
|
||||
@@ -238,9 +319,7 @@ kitty_delete_all(size_t *outlen)
|
||||
{
|
||||
char *out;
|
||||
|
||||
*outlen = 3 + 7 + 2;
|
||||
out = xmalloc(*outlen + 1);
|
||||
memcpy(out, "\033_Ga=d,d=a\033\\", *outlen);
|
||||
out[*outlen] = '\0';
|
||||
out = xstrdup("\033_Ga=d,d=a\033\\");
|
||||
*outlen = strlen(out);
|
||||
return (out);
|
||||
}
|
||||
|
||||
33
image.c
33
image.c
@@ -176,33 +176,7 @@ image_store(struct screen *s, enum image_type type, void *data)
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
case IMAGE_KITTY:
|
||||
im->data.kitty = data;
|
||||
|
||||
/* Kitty images have size info in the structure */
|
||||
im->sx = im->data.kitty->cols;
|
||||
im->sy = im->data.kitty->rows;
|
||||
|
||||
/*
|
||||
* If cols/rows are 0, they mean "auto" - calculate from
|
||||
* pixel dimensions. The terminal will figure out the actual
|
||||
* size, but we need a reasonable estimate for our cache.
|
||||
*/
|
||||
if (im->sx == 0 && im->data.kitty->pixel_w > 0 &&
|
||||
im->data.kitty->xpixel > 0) {
|
||||
im->sx = (im->data.kitty->pixel_w +
|
||||
im->data.kitty->xpixel - 1) /
|
||||
im->data.kitty->xpixel;
|
||||
}
|
||||
if (im->sy == 0 && im->data.kitty->pixel_h > 0 &&
|
||||
im->data.kitty->ypixel > 0) {
|
||||
im->sy = (im->data.kitty->pixel_h +
|
||||
im->data.kitty->ypixel - 1) / im->data.kitty->ypixel;
|
||||
}
|
||||
|
||||
/* If still 0, use a reasonable default */
|
||||
if (im->sx == 0)
|
||||
im->sx = 10;
|
||||
if (im->sy == 0)
|
||||
im->sy = 10;
|
||||
kitty_size_in_cells(im->data.kitty, &im->sx, &im->sy);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -288,7 +262,7 @@ image_scroll_up(struct screen *s, u_int lines)
|
||||
case IMAGE_SIXEL:
|
||||
sx = im->sx;
|
||||
sy = (im->py + im->sy) - lines;
|
||||
image_log(im, __func__, "3 sixel, lines=%u, sy=%u",
|
||||
image_log(im, __func__, "sixel, lines=%u, sy=%u",
|
||||
lines, sy);
|
||||
|
||||
new = sixel_scale(im->data.sixel, 0, 0, 0, im->sy - sy,
|
||||
@@ -311,10 +285,7 @@ image_scroll_up(struct screen *s, u_int lines)
|
||||
* owns the placement. Just adjust position and let
|
||||
* the terminal handle clipping.
|
||||
*/
|
||||
image_log(im, __func__,
|
||||
"3 kitty, lines=%u (no rescale)", lines);
|
||||
im->py = 0;
|
||||
/* Height remains the same - terminal will clip */
|
||||
redraw = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
158
input.c
158
input.c
@@ -181,6 +181,7 @@ static void input_ground(struct input_ctx *);
|
||||
static void input_enter_dcs(struct input_ctx *);
|
||||
static void input_enter_osc(struct input_ctx *);
|
||||
static void input_exit_osc(struct input_ctx *);
|
||||
static int input_da1_has_sixel(struct input_ctx *);
|
||||
static void input_enter_apc(struct input_ctx *);
|
||||
static void input_exit_apc(struct input_ctx *);
|
||||
static void input_enter_rename(struct input_ctx *);
|
||||
@@ -1561,31 +1562,11 @@ input_csi_dispatch(struct input_ctx *ictx)
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
{
|
||||
/*
|
||||
* Report sixel support only if outer terminal supports it.
|
||||
* This ensures applications choose the right protocol.
|
||||
*/
|
||||
int has_sixel = 0;
|
||||
#ifdef ENABLE_SIXEL_IMAGES
|
||||
if (ictx->wp != NULL) {
|
||||
struct client *c;
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->session != NULL &&
|
||||
c->session->curw->window == ictx->wp->window &&
|
||||
(c->tty.term->flags & TERM_SIXEL)) {
|
||||
has_sixel = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (has_sixel)
|
||||
if (input_da1_has_sixel(ictx))
|
||||
input_reply(ictx, 1, "\033[?1;2;4c");
|
||||
else
|
||||
input_reply(ictx, 1, "\033[?1;2c");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_debug("%s: unknown '%c'", __func__, ictx->ch);
|
||||
break;
|
||||
@@ -2740,16 +2721,85 @@ input_enter_apc(struct input_ctx *ictx)
|
||||
ictx->flags &= ~INPUT_LAST;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if any client viewing this pane has an outer terminal that supports
|
||||
* sixel, so we can report it in the DA1 response.
|
||||
*/
|
||||
static int
|
||||
input_da1_has_sixel(__unused struct input_ctx *ictx)
|
||||
{
|
||||
#ifdef ENABLE_SIXEL_IMAGES
|
||||
struct window_pane *wp = ictx->wp;
|
||||
struct client *c;
|
||||
|
||||
if (wp == NULL)
|
||||
return (0);
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->session == NULL)
|
||||
continue;
|
||||
if (c->session->curw->window != wp->window)
|
||||
continue;
|
||||
if (c->tty.term->flags & TERM_SIXEL)
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
/* Handle a kitty graphics APC sequence. */
|
||||
static void
|
||||
input_apc_kitty_image(struct input_ctx *ictx)
|
||||
{
|
||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||
struct window_pane *wp = ictx->wp;
|
||||
struct window *w;
|
||||
struct kitty_image *ki;
|
||||
|
||||
if (wp == NULL)
|
||||
return;
|
||||
|
||||
w = wp->window;
|
||||
ki = kitty_parse(ictx->input_buf + 1, ictx->input_len - 1,
|
||||
w->xpixel, w->ypixel);
|
||||
if (ki == NULL)
|
||||
return;
|
||||
|
||||
/* Handle query commands. */
|
||||
if (kitty_get_action(ki) == 'q') {
|
||||
if (kitty_get_image_id(ki) != 0)
|
||||
input_reply(ictx, 0, "\033_Gi=%u;OK\033\\",
|
||||
kitty_get_image_id(ki));
|
||||
else
|
||||
input_reply(ictx, 0, "\033_Ga=q;OK\033\\");
|
||||
kitty_free(ki);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store image placements and trigger a redraw. */
|
||||
if (kitty_get_action(ki) == 'T' || kitty_get_action(ki) == 't' ||
|
||||
kitty_get_action(ki) == 'p') {
|
||||
screen_write_kittyimage(sctx, ki);
|
||||
} else {
|
||||
/* For other actions (delete, etc.), pass through. */
|
||||
char *apc;
|
||||
size_t apclen;
|
||||
|
||||
apclen = xasprintf(&apc, "\033_%s\033\\", ictx->input_buf);
|
||||
tty_kitty_passthrough(wp, apc, apclen, sctx->s->cx,
|
||||
sctx->s->cy);
|
||||
free(apc);
|
||||
kitty_free(ki);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* APC terminator (ST) received. */
|
||||
static void
|
||||
input_exit_apc(struct input_ctx *ictx)
|
||||
{
|
||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||
struct window_pane *wp = ictx->wp;
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
struct kitty_image *ki;
|
||||
struct window *w;
|
||||
#endif
|
||||
|
||||
if (ictx->flags & INPUT_DISCARD)
|
||||
return;
|
||||
@@ -2757,64 +2807,10 @@ input_exit_apc(struct input_ctx *ictx)
|
||||
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
if (ictx->input_len >= 1 && ictx->input_buf[0] == 'G') {
|
||||
if (wp == NULL)
|
||||
return;
|
||||
|
||||
w = wp->window;
|
||||
/*
|
||||
* Intercept only a=q (query) to reply OK ourselves.
|
||||
* Everything else — including a=T (transmit+display),
|
||||
* a=d (delete), a=p (place), multi-chunk sequences —
|
||||
* passes through verbatim to the outer terminal.
|
||||
* The outer terminal manages all image placement and
|
||||
* scrolling; tmux must not interfere.
|
||||
*/
|
||||
ki = kitty_parse(ictx->input_buf + 1,
|
||||
ictx->input_len - 1, w->xpixel, w->ypixel);
|
||||
if (ki == NULL)
|
||||
return;
|
||||
|
||||
/* Handle query commands */
|
||||
if (ki->action == 'q') {
|
||||
if (ki->image_id != 0)
|
||||
input_reply(ictx, 0,
|
||||
"\033_Gi=%u;OK\033\\",
|
||||
ki->image_id);
|
||||
else
|
||||
input_reply(ictx, 0,
|
||||
"\033_Ga=q;OK\033\\");
|
||||
kitty_free(ki);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the image and trigger a redraw.
|
||||
* Similar to sixel, we cache the image and let the
|
||||
* redraw mechanism handle sending it to terminals.
|
||||
*/
|
||||
if (ki->action == 'T' || ki->action == 't' || ki->action == 'p') {
|
||||
screen_write_kittyimage(sctx, ki);
|
||||
} else {
|
||||
/* For other actions (delete, etc.), pass through */
|
||||
char *apc;
|
||||
size_t apclen;
|
||||
|
||||
apclen = 2 + ictx->input_len + 2;
|
||||
apc = xmalloc(apclen + 1);
|
||||
apc[0] = '\033';
|
||||
apc[1] = '_';
|
||||
memcpy(apc + 2, ictx->input_buf, ictx->input_len);
|
||||
apc[2 + ictx->input_len] = '\033';
|
||||
apc[2 + ictx->input_len + 1] = '\\';
|
||||
apc[apclen] = '\0';
|
||||
tty_kitty_passthrough(wp, apc, apclen,
|
||||
sctx->s->cx, sctx->s->cy);
|
||||
free(apc);
|
||||
kitty_free(ki);
|
||||
}
|
||||
input_apc_kitty_image(ictx);
|
||||
return;
|
||||
}
|
||||
#endif /* ENABLE_KITTY_IMAGES */
|
||||
#endif
|
||||
|
||||
if (wp != NULL &&
|
||||
options_get_number(wp->options, "allow-set-title") &&
|
||||
|
||||
@@ -2469,10 +2469,10 @@ screen_write_kittyimage(struct screen_write_ctx *ctx, struct kitty_image *ki)
|
||||
if (ki == NULL)
|
||||
return;
|
||||
|
||||
/* Store the image in the cache */
|
||||
/* Store the image in the cache. */
|
||||
im = image_store(s, IMAGE_KITTY, ki);
|
||||
|
||||
/* Trigger a tty write to send to all terminals */
|
||||
/* Trigger a tty write to send to all terminals. */
|
||||
if (im != NULL && ctx->wp != NULL) {
|
||||
screen_write_collect_flush(ctx, 0, __func__);
|
||||
screen_write_initctx(ctx, &ttyctx, 0);
|
||||
@@ -2484,9 +2484,9 @@ screen_write_kittyimage(struct screen_write_ctx *ctx, struct kitty_image *ki)
|
||||
tty_write(tty_cmd_kittyimage, &ttyctx);
|
||||
}
|
||||
|
||||
/* Move cursor past the image */
|
||||
if (ki->rows > 0)
|
||||
screen_write_cursormove(ctx, 0, s->cy + ki->rows, 0);
|
||||
/* Move cursor past the image. */
|
||||
if (kitty_get_rows(ki) > 0)
|
||||
screen_write_cursormove(ctx, 0, s->cy + kitty_get_rows(ki), 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
45
tmux.h
45
tmux.h
@@ -623,7 +623,6 @@ enum tty_code_code {
|
||||
TTYC_SMULX,
|
||||
TTYC_SMXX,
|
||||
TTYC_SXL,
|
||||
TTYC_KTY,
|
||||
TTYC_SS,
|
||||
TTYC_SWD,
|
||||
TTYC_SYNC,
|
||||
@@ -947,7 +946,9 @@ struct image {
|
||||
enum image_type type;
|
||||
struct screen *s;
|
||||
union {
|
||||
#ifdef ENABLE_SIXEL_IMAGES
|
||||
struct sixel_image *sixel;
|
||||
#endif
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
struct kitty_image *kitty;
|
||||
#endif
|
||||
@@ -965,44 +966,6 @@ struct image {
|
||||
TAILQ_HEAD(images, image);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_KITTY_IMAGES
|
||||
/*
|
||||
* kitty_image stores the raw decoded pixel data and metadata from a kitty
|
||||
* graphics protocol APC sequence. It is used to re-emit the sequence to the
|
||||
* outer terminal on redraw.
|
||||
*/
|
||||
struct kitty_image {
|
||||
/* Control-data fields parsed from the APC sequence. */
|
||||
char action; /* a=: 'T'=transmit+display, 't', 'p', 'd', ... */
|
||||
u_int format; /* f=: 32=RGBA, 24=RGB, 100=PNG */
|
||||
char medium; /* t=: 'd'=direct, 'f'=file, 't'=tmp, 's'=shm */
|
||||
u_int pixel_w; /* s=: source image pixel width */
|
||||
u_int pixel_h; /* v=: source image pixel height */
|
||||
u_int cols; /* c=: display columns (0=auto) */
|
||||
u_int rows; /* r=: display rows (0=auto) */
|
||||
u_int image_id; /* i=: image id (0=unassigned) */
|
||||
u_int image_num; /* I=: image number */
|
||||
u_int placement_id; /* p=: placement id */
|
||||
u_int more; /* m=: 1=more chunks coming, 0=last */
|
||||
u_int quiet; /* q=: suppress responses */
|
||||
int z_index; /* z=: z-index */
|
||||
char compression; /* o=: 'z'=zlib, 0=none */
|
||||
char delete_what; /* d=: delete target (used with a=d) */
|
||||
|
||||
/* Cell size at the time of parsing (from the owning window). */
|
||||
u_int xpixel;
|
||||
u_int ypixel;
|
||||
|
||||
/* Original base64-encoded payload (concatenated across all chunks). */
|
||||
char *encoded;
|
||||
size_t encodedlen;
|
||||
|
||||
char *ctrl;
|
||||
size_t ctrllen;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* Cursor style. */
|
||||
enum screen_cursor_style {
|
||||
SCREEN_CURSOR_DEFAULT,
|
||||
@@ -3832,6 +3795,10 @@ struct screen *sixel_to_screen(struct sixel_image *);
|
||||
/* image-kitty.c */
|
||||
struct kitty_image *kitty_parse(const u_char *, size_t, u_int, u_int);
|
||||
void kitty_free(struct kitty_image *);
|
||||
void kitty_size_in_cells(struct kitty_image *, u_int *, u_int *);
|
||||
char kitty_get_action(struct kitty_image *);
|
||||
u_int kitty_get_image_id(struct kitty_image *);
|
||||
u_int kitty_get_rows(struct kitty_image *);
|
||||
char *kitty_print(struct kitty_image *, size_t *);
|
||||
char *kitty_delete_all(size_t *);
|
||||
#endif
|
||||
|
||||
BIN
tools/image.kitty
Normal file
BIN
tools/image.kitty
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 172 KiB |
17
tty-keys.c
17
tty-keys.c
@@ -1836,6 +1836,7 @@ tty_keys_kitty_graphics(struct tty *tty, const char *buf, size_t len,
|
||||
{
|
||||
struct client *c = tty->client;
|
||||
int *features = &c->term_features;
|
||||
const char *semi;
|
||||
size_t i;
|
||||
char tmp[256];
|
||||
|
||||
@@ -1878,15 +1879,13 @@ tty_keys_kitty_graphics(struct tty *tty, const char *buf, size_t len,
|
||||
* Check if the message (after the semicolon) starts with "OK".
|
||||
* The format is: i=31;OK or i=31;ENOSYS:...
|
||||
*/
|
||||
{
|
||||
const char *semi = strchr(tmp, ';');
|
||||
if (semi != NULL && strncmp(semi + 1, "OK", 2) == 0) {
|
||||
log_debug("%s: kitty graphics supported", c->name);
|
||||
tty_add_features(features, "kitty", ",");
|
||||
tty_update_features(tty);
|
||||
} else {
|
||||
log_debug("%s: kitty graphics not supported", c->name);
|
||||
}
|
||||
semi = strchr(tmp, ';');
|
||||
if (semi != NULL && strncmp(semi + 1, "OK", 2) == 0) {
|
||||
log_debug("%s: kitty graphics supported", c->name);
|
||||
tty_add_features(features, "kitty", ",");
|
||||
tty_update_features(tty);
|
||||
} else {
|
||||
log_debug("%s: kitty graphics not supported", c->name);
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
@@ -270,7 +270,6 @@ static const struct tty_term_code_entry tty_term_codes[] = {
|
||||
[TTYC_SETULC1] = { TTYCODE_STRING, "Setulc1" },
|
||||
[TTYC_SE] = { TTYCODE_STRING, "Se" },
|
||||
[TTYC_SXL] = { TTYCODE_FLAG, "Sxl" },
|
||||
[TTYC_KTY] = { TTYCODE_FLAG, "Kty" },
|
||||
[TTYC_SGR0] = { TTYCODE_STRING, "sgr0" },
|
||||
[TTYC_SITM] = { TTYCODE_STRING, "sitm" },
|
||||
[TTYC_SMACS] = { TTYCODE_STRING, "smacs" },
|
||||
|
||||
29
tty.c
29
tty.c
@@ -2180,48 +2180,35 @@ tty_cmd_sixelimage(struct tty *tty, const struct tty_ctx *ctx)
|
||||
static int
|
||||
tty_has_kitty(struct tty *tty)
|
||||
{
|
||||
return ((tty->term->flags & TERM_KITTY) ||
|
||||
tty_term_has(tty->term, TTYC_KTY));
|
||||
return (tty->term->flags & TERM_KITTY);
|
||||
}
|
||||
|
||||
void
|
||||
tty_cmd_kittyimage(struct tty *tty, const struct tty_ctx *ctx)
|
||||
{
|
||||
struct image *im = ctx->ptr;
|
||||
struct kitty_image *ki;
|
||||
char *data;
|
||||
size_t size;
|
||||
u_int cx = ctx->ocx, cy = ctx->ocy;
|
||||
int fallback = 0;
|
||||
|
||||
log_debug("%s: called, im=%p", __func__, im);
|
||||
|
||||
if (im == NULL) {
|
||||
log_debug("%s: NULL image pointer", __func__);
|
||||
if (im == NULL || im->data.kitty == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
ki = im->data.kitty;
|
||||
log_debug("%s: ki=%p, type=%d", __func__, ki, im->type);
|
||||
|
||||
if (ki == NULL) {
|
||||
log_debug("%s: NULL kitty_image pointer", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if this terminal supports kitty graphics */
|
||||
/* Check if this terminal supports kitty graphics. */
|
||||
if (!tty_has_kitty(tty))
|
||||
fallback = 1;
|
||||
|
||||
log_debug("%s: image at %u,%u (fallback=%d)", __func__, cx, cy, fallback);
|
||||
log_debug("%s: image at %u,%u (fallback=%d)", __func__, cx, cy,
|
||||
fallback);
|
||||
|
||||
if (fallback == 1) {
|
||||
/* Use text fallback for non-kitty terminals */
|
||||
/* Use text fallback for non-kitty terminals. */
|
||||
data = xstrdup(im->fallback);
|
||||
size = strlen(data);
|
||||
} else {
|
||||
/* Re-serialize the kitty image command */
|
||||
data = kitty_print(ki, &size);
|
||||
/* Re-serialize the kitty image command. */
|
||||
data = kitty_print(im->data.kitty, &size);
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
|
||||
Reference in New Issue
Block a user