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 xw = (im->width + document->options.cell_width - 1) / document->options.cell_width;
|
||||||
int y;
|
int y;
|
||||||
im->id = html_top->name - document->text.source;
|
im->number = html_top->name - document->text.source;
|
||||||
im->number = im_number;
|
im->ID = im_number;
|
||||||
|
|
||||||
for (y = 0; y < how_many; y++) {
|
for (y = 0; y < how_many; y++) {
|
||||||
int x;
|
int x;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
top_builddir=../..
|
top_builddir=../..
|
||||||
include $(top_builddir)/Makefile.config
|
include $(top_builddir)/Makefile.config
|
||||||
|
|
||||||
OBJS-$(CONFIG_KITTY) += kitty.o
|
OBJS-$(CONFIG_KITTY) += kitty.o map.obj
|
||||||
OBJS-$(CONFIG_MOUSE) += mouse.o
|
OBJS-$(CONFIG_MOUSE) += mouse.o
|
||||||
OBJS-$(CONFIG_LIBSIXEL) += sixel.o
|
OBJS-$(CONFIG_LIBSIXEL) += sixel.o
|
||||||
OBJS-$(CONFIG_TERMINFO) += terminfo.o
|
OBJS-$(CONFIG_TERMINFO) += terminfo.o
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
#include "terminal/hardio.h"
|
#include "terminal/hardio.h"
|
||||||
#include "terminal/itrm.h"
|
#include "terminal/itrm.h"
|
||||||
#include "terminal/kbd.h"
|
#include "terminal/kbd.h"
|
||||||
|
#ifdef CONFIG_KITTY
|
||||||
|
#include "terminal/map.h"
|
||||||
|
#endif
|
||||||
#include "terminal/mouse.h"
|
#include "terminal/mouse.h"
|
||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
@ -785,6 +788,74 @@ get_ui_double_esc(void)
|
|||||||
return ui_double_esc;
|
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
|
/** Decode a control sequence that begins with CSI (CONTROL SEQUENCE
|
||||||
* INTRODUCER) encoded as ESC [, and set @a *ev accordingly.
|
* INTRODUCER) encoded as ESC [, and set @a *ev accordingly.
|
||||||
* (ECMA-48 also allows 0x9B as a single-byte CSI, but we don't
|
* (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);
|
el = decode_terminal_escape_sequence(itrm, &ev);
|
||||||
} else if (itrm->in.queue.data[1] == 0x4F /* SS3 */) {
|
} else if (itrm->in.queue.data[1] == 0x4F /* SS3 */) {
|
||||||
el = decode_terminal_application_key(itrm, &ev);
|
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) {
|
} else if (itrm->in.queue.data[1] == ASCII_ESC) {
|
||||||
/* ESC ESC can be either Alt-Esc or the
|
/* ESC ESC can be either Alt-Esc or the
|
||||||
* beginning of e.g. ESC ESC 0x5B 0x41,
|
* beginning of e.g. ESC ESC 0x5B 0x41,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "osdep/osdep.h"
|
#include "osdep/osdep.h"
|
||||||
#include "terminal/hardio.h"
|
#include "terminal/hardio.h"
|
||||||
#include "terminal/kitty.h"
|
#include "terminal/kitty.h"
|
||||||
|
#include "terminal/map.h"
|
||||||
#include "terminal/screen.h"
|
#include "terminal/screen.h"
|
||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#include "util/base64.h"
|
#include "util/base64.h"
|
||||||
@ -91,7 +92,7 @@ try_to_draw_k_images(struct terminal *term)
|
|||||||
{
|
{
|
||||||
ELOG
|
ELOG
|
||||||
|
|
||||||
if (!term->kitty || !term->number_of_images) {
|
if (!term->kitty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct string text;
|
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);
|
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 m;
|
||||||
int left = im->pixels.length;
|
int left = im->pixels.length;
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
m = left >= 4000;
|
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_bytes_to_string(&text, im->pixels.source + sent, m ? 4000 : left);
|
||||||
add_to_string(&text, "\033\\");
|
add_to_string(&text, "\033\\");
|
||||||
if (!m) {
|
if (!m) {
|
||||||
@ -133,9 +136,9 @@ try_to_draw_k_images(struct terminal *term)
|
|||||||
sent += 4000;
|
sent += 4000;
|
||||||
left -= 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 (text.length) {
|
||||||
if (term->master) want_draw();
|
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->width = src->width;
|
||||||
dest->height = src->height;
|
dest->height = src->height;
|
||||||
|
|
||||||
dest->id = src->id;
|
dest->ID = src->ID;
|
||||||
dest->number = src->number;
|
dest->number = src->number;
|
||||||
dest->sent = src->sent;
|
dest->sent = src->sent;
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ struct k_image {
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int id;
|
int id;
|
||||||
|
int ID;
|
||||||
int number;
|
int number;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
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')
|
if conf_data.get('CONFIG_KITTY')
|
||||||
srcs += files('kitty.c')
|
srcs += files('kitty.c', 'map.cpp')
|
||||||
endif
|
endif
|
||||||
if conf_data.get('CONFIG_MOUSE')
|
if conf_data.get('CONFIG_MOUSE')
|
||||||
srcs += files('mouse.c')
|
srcs += files('mouse.c')
|
||||||
|
@ -480,7 +480,7 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active)
|
|||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
for (;cx < data[im.cy].length; cx++) {
|
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;
|
found = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user