mirror of
https://github.com/rkd77/elinks.git
synced 2025-06-30 22:19:29 -04:00
[kitty] Try to decode kitty escape sequences
This commit is contained in:
parent
f2872b3711
commit
8f02de86e8
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -21,6 +21,7 @@ struct k_image {
|
||||
int width;
|
||||
int height;
|
||||
int id;
|
||||
int ID;
|
||||
int number;
|
||||
int x;
|
||||
int y;
|
||||
|
46
src/terminal/map.cpp
Normal file
46
src/terminal/map.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "terminal/map.h"
|
||||
#include <map>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static std::map<unsigned int, unsigned int> map_ID;
|
||||
static std::map<unsigned int, unsigned int> reverse_map_ID;
|
||||
|
||||
// -1 not found
|
||||
int
|
||||
get_id_from_ID(unsigned int ID)
|
||||
{
|
||||
auto search = map_ID.find(ID);
|
||||
|
||||
if (search == map_ID.end()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return search->second;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
set_id_ID(unsigned int id, unsigned int ID)
|
||||
{
|
||||
map_ID[ID] = id;
|
||||
reverse_map_ID[id] = ID;
|
||||
}
|
||||
|
||||
void
|
||||
remove_id(unsigned int id)
|
||||
{
|
||||
auto search = reverse_map_ID.find(id);
|
||||
|
||||
if (search == reverse_map_ID.end()) {
|
||||
return;
|
||||
}
|
||||
unsigned int ID = search->second;
|
||||
reverse_map_ID.erase(search);
|
||||
|
||||
auto search2 = map_ID.find(ID);
|
||||
|
||||
if (search2 != map_ID.end()) {
|
||||
map_ID.erase(search2);
|
||||
}
|
||||
}
|
16
src/terminal/map.h
Normal file
16
src/terminal/map.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef EL__TERMINAL_MAP_H
|
||||
#define EL__TERMINAL_MAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int get_id_from_ID(unsigned int ID);
|
||||
void set_id_ID(unsigned int id, unsigned int ID);
|
||||
void remove_id(unsigned int id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EL__TERMINAL_MAP_H */
|
@ -1,5 +1,5 @@
|
||||
if conf_data.get('CONFIG_KITTY')
|
||||
srcs += files('kitty.c')
|
||||
srcs += files('kitty.c', 'map.cpp')
|
||||
endif
|
||||
if conf_data.get('CONFIG_MOUSE')
|
||||
srcs += files('mouse.c')
|
||||
|
@ -480,7 +480,7 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active)
|
||||
|
||||
if (!found) {
|
||||
for (;cx < data[im.cy].length; cx++) {
|
||||
if (im.id == data[im.cy].ch.chars[cx].number) {
|
||||
if (im.number == data[im.cy].ch.chars[cx].number) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user