diff --git a/src/document/html/parser/link.c b/src/document/html/parser/link.c
index f25275b56..6afc6c4fa 100644
--- a/src/document/html/parser/link.c
+++ b/src/document/html/parser/link.c
@@ -320,8 +320,8 @@ html_img_kitty(struct html_context *html_context, char *a,
}
int xw = (im->width + document->options.cell_width - 1) / document->options.cell_width;
int y;
- im->id = html_top->name - document->text.source;
- im->number = im_number;
+ im->number = html_top->name - document->text.source;
+ im->ID = im_number;
for (y = 0; y < how_many; y++) {
int x;
diff --git a/src/terminal/Makefile b/src/terminal/Makefile
index faf4e9aa4..317c32172 100644
--- a/src/terminal/Makefile
+++ b/src/terminal/Makefile
@@ -1,7 +1,7 @@
top_builddir=../..
include $(top_builddir)/Makefile.config
-OBJS-$(CONFIG_KITTY) += kitty.o
+OBJS-$(CONFIG_KITTY) += kitty.o map.obj
OBJS-$(CONFIG_MOUSE) += mouse.o
OBJS-$(CONFIG_LIBSIXEL) += sixel.o
OBJS-$(CONFIG_TERMINFO) += terminfo.o
diff --git a/src/terminal/kbd.c b/src/terminal/kbd.c
index eb10e7381..c54b3d1ce 100644
--- a/src/terminal/kbd.c
+++ b/src/terminal/kbd.c
@@ -38,6 +38,9 @@
#include "terminal/hardio.h"
#include "terminal/itrm.h"
#include "terminal/kbd.h"
+#ifdef CONFIG_KITTY
+#include "terminal/map.h"
+#endif
#include "terminal/mouse.h"
#include "terminal/terminal.h"
#include "util/error.h"
@@ -785,6 +788,74 @@ get_ui_double_esc(void)
return ui_double_esc;
}
+#ifdef CONFIG_KITTY
+static int
+decode_kitty_escape_sequence(struct itrm *itrm)
+{
+ ELOG
+ int i = 3;
+ int was_esc = 0;
+
+ if (itrm->in.queue.len < 3) {
+ return -1;
+ }
+
+ if (itrm->in.queue.data[2] != 'G') {
+ return -1;
+ }
+
+ for (i = 3; i < itrm->in.queue.len; i++) {
+ if (itrm->in.queue.data[i] == ASCII_ESC) {
+ was_esc = i + 1;
+ break;
+ }
+ }
+ if (!was_esc) {
+ return -1;
+ }
+
+ if (was_esc >= itrm->in.queue.len || itrm->in.queue.data[was_esc] != '\\') {
+ return -1;
+ }
+ itrm->in.queue.data[was_esc] = '\0';
+ const char *data = (const char *)(itrm->in.queue.data + 3);
+ char *ok = strstr(data, "OK");
+ int id = -1;
+ int ID = -1;
+
+ if (ok) {
+ char *ieq = strstr(data, "i=");
+
+ if (ieq) {
+ id = atoi(ieq + 2);
+ }
+ char *Ieq = strstr(data, "I=");
+ if (Ieq) {
+ ID = atoi(Ieq + 2);
+ }
+ if (id >= 0 && ID >= 0) {
+ set_id_ID(id, ID);
+ }
+ } else {
+ char *enoent = strstr(data, "ENOENT");
+
+ if (enoent) {
+ char *ieq = strstr(data, "i=");
+
+ if (ieq) {
+ id = atoi(ieq + 2);
+ }
+ if (id >= 0) {
+ remove_id(id);
+ }
+ }
+ }
+ itrm->in.queue.data[was_esc] = '\\';
+
+ return was_esc + 1;
+}
+#endif
+
/** Decode a control sequence that begins with CSI (CONTROL SEQUENCE
* INTRODUCER) encoded as ESC [, and set @a *ev accordingly.
* (ECMA-48 also allows 0x9B as a single-byte CSI, but we don't
@@ -1163,6 +1234,10 @@ process_queue(struct itrm *itrm)
el = decode_terminal_escape_sequence(itrm, &ev);
} else if (itrm->in.queue.data[1] == 0x4F /* SS3 */) {
el = decode_terminal_application_key(itrm, &ev);
+#ifdef CONFIG_KITTY
+ } else if (itrm->in.queue.data[1] == '_') {
+ el = decode_kitty_escape_sequence(itrm);
+#endif
} else if (itrm->in.queue.data[1] == ASCII_ESC) {
/* ESC ESC can be either Alt-Esc or the
* beginning of e.g. ESC ESC 0x5B 0x41,
diff --git a/src/terminal/kitty.c b/src/terminal/kitty.c
index 4b2f1b333..ee625e420 100644
--- a/src/terminal/kitty.c
+++ b/src/terminal/kitty.c
@@ -16,6 +16,7 @@
#include "osdep/osdep.h"
#include "terminal/hardio.h"
#include "terminal/kitty.h"
+#include "terminal/map.h"
#include "terminal/screen.h"
#include "terminal/terminal.h"
#include "util/base64.h"
@@ -91,7 +92,7 @@ try_to_draw_k_images(struct terminal *term)
{
ELOG
- if (!term->kitty || !term->number_of_images) {
+ if (!term->kitty) {
return;
}
struct string text;
@@ -118,13 +119,15 @@ try_to_draw_k_images(struct terminal *term)
}
add_cursor_move_to_string(&text, im->cy + 1, im->cx + 1);
- if (!im->sent) {
+ int id = get_id_from_ID(im->ID);
+
+ if (id < 0) {
int m;
int left = im->pixels.length;
int sent = 0;
while (1) {
m = left >= 4000;
- add_format_to_string(&text, "\033_Gf=32,i=%d,s=%d,v=%d,m=%d,t=d,q=1;", im->number, im->width, im->height, m);
+ add_format_to_string(&text, "\033_Gf=32,I=%d,s=%d,v=%d,m=%d,t=d,a=T;", im->ID, im->width, im->height, m);
add_bytes_to_string(&text, im->pixels.source + sent, m ? 4000 : left);
add_to_string(&text, "\033\\");
if (!m) {
@@ -133,9 +136,9 @@ try_to_draw_k_images(struct terminal *term)
sent += 4000;
left -= 4000;
};
- im->sent = 1;
+ } else {
+ add_format_to_string(&text, "\033_Gi=%d,x=%d,y=%d,w=%d,h=%d,a=p,q=1\033\\", id, im->x, im->y, im->w, im->h);
}
- add_format_to_string(&text, "\033_Gi=%d,x=%d,y=%d,w=%d,h=%d,a=p,q=1\033\\", im->number, im->x, im->y, im->w, im->h);
if (text.length) {
if (term->master) want_draw();
@@ -194,7 +197,7 @@ copy_k_frame(struct k_image *src, struct el_box *box, int cell_width, int cell_h
dest->width = src->width;
dest->height = src->height;
- dest->id = src->id;
+ dest->ID = src->ID;
dest->number = src->number;
dest->sent = src->sent;
diff --git a/src/terminal/kitty.h b/src/terminal/kitty.h
index 965d86e07..f199c057a 100644
--- a/src/terminal/kitty.h
+++ b/src/terminal/kitty.h
@@ -21,6 +21,7 @@ struct k_image {
int width;
int height;
int id;
+ int ID;
int number;
int x;
int y;
diff --git a/src/terminal/map.cpp b/src/terminal/map.cpp
new file mode 100644
index 000000000..0ffa0cea1
--- /dev/null
+++ b/src/terminal/map.cpp
@@ -0,0 +1,46 @@
+#include "terminal/map.h"
+#include