120 lines
3.6 KiB
Plaintext
120 lines
3.6 KiB
Plaintext
|
|
/* Internal representation of the screen */
|
|
typedef struct {
|
|
int row; /* nb row */
|
|
int col; /* nb col */
|
|
Line *line; /* screen */
|
|
Line *alt; /* alternate screen */
|
|
int *dirty; /* dirtyness of lines */
|
|
TCursor c; /* cursor */
|
|
int ocx; /* old cursor col */
|
|
int ocy; /* old cursor row */
|
|
int top; /* top scroll limit */
|
|
int bot; /* bottom scroll limit */
|
|
int mode; /* terminal mode flags */
|
|
int esc; /* escape state flags */
|
|
char trantbl[4]; /* charset table translation */
|
|
int charset; /* current charset */
|
|
int icharset; /* selected charset for sequence */
|
|
int *tabs;
|
|
Rune lastc; /* last printed char outside of sequence, 0 if control */
|
|
} Term;
|
|
|
|
|
|
--- st.c
|
|
+++ st.c
|
|
@@ -105,26 +99,6 @@ typedef struct {
|
|
int alt;
|
|
} Selection;
|
|
|
|
-/* Internal representation of the screen */
|
|
-typedef struct {
|
|
- int row; /* nb row */
|
|
- int col; /* nb col */
|
|
- Line *line; /* screen */
|
|
- Line *alt; /* alternate screen */
|
|
- int *dirty; /* dirtyness of lines */
|
|
- TCursor c; /* cursor */
|
|
- int ocx; /* old cursor col */
|
|
- int ocy; /* old cursor row */
|
|
- int top; /* top scroll limit */
|
|
- int bot; /* bottom scroll limit */
|
|
- int mode; /* terminal mode flags */
|
|
- int esc; /* escape state flags */
|
|
- char trantbl[4]; /* charset table translation */
|
|
- int charset; /* current charset */
|
|
- int icharset; /* selected charset for sequence */
|
|
- int *tabs;
|
|
-} Term;
|
|
-
|
|
/* CSI Escape sequence structs */
|
|
/* ESC '[' [[ [<priv>] <arg> [;]] <mode> [<mode>]] */
|
|
typedef struct {
|
|
@@ -1929,7 +1956,39 @@ strhandle(void)
|
|
xsettitle(strescseq.args[0]);
|
|
return;
|
|
case 'P': /* DCS -- Device Control String */
|
|
- term.mode |= ESC_DCS;
|
|
+ if (IS_SET(MODE_SIXEL)) {
|
|
+ term.mode &= ~MODE_SIXEL;
|
|
+ new_image = malloc(sizeof(ImageList));
|
|
+ memset(new_image, 0, sizeof(ImageList));
|
|
+ new_image->x = term.c.x;
|
|
+ new_image->y = term.c.y;
|
|
+ new_image->width = sixel_st.image.width;
|
|
+ new_image->height = sixel_st.image.height;
|
|
+ new_image->pixels = malloc(new_image->width * new_image->height * 4);
|
|
+ if (sixel_parser_finalize(&sixel_st, new_image->pixels) != 0) {
|
|
+ perror("sixel_parser_finalize() failed");
|
|
+ sixel_parser_deinit(&sixel_st);
|
|
+ return;
|
|
+ }
|
|
+ sixel_parser_deinit(&sixel_st);
|
|
+ if (term.images) {
|
|
+ ImageList *im;
|
|
+ for (im = term.images; im->next;)
|
|
+ im = im->next;
|
|
+ im->next = new_image;
|
|
+ new_image->prev = im;
|
|
+ } else {
|
|
+ term.images = new_image;
|
|
+ }
|
|
+ for (i = 0; i < (sixel_st.image.height + win.ch-1)/win.ch; ++i) {
|
|
+ int x;
|
|
+ tclearregion(term.c.x, term.c.y, term.c.x+(sixel_st.image.width+win.cw-1)/win.cw, term.c.y);
|
|
+ for (x = term.c.x; x < MIN(term.col, term.c.x+(sixel_st.image.width+win.cw-1)/win.cw); x++)
|
|
+ term.line[term.c.y][x].mode |= ATTR_SIXEL;
|
|
+ tnewline(1);
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
case '_': /* APC -- Application Program Command */
|
|
case '^': /* PM -- Privacy Message */
|
|
return;
|
|
@@ -2358,21 +2418,17 @@ tputc(Rune u)
|
|
if (u == '\a' || u == 030 || u == 032 || u == 033 ||
|
|
ISCONTROLC1(u)) {
|
|
term.esc &= ~(ESC_START|ESC_STR|ESC_DCS);
|
|
- if (IS_SET(MODE_SIXEL)) {
|
|
- /* TODO: render sixel */;
|
|
- term.mode &= ~MODE_SIXEL;
|
|
- return;
|
|
- }
|
|
term.esc |= ESC_STR_END;
|
|
goto check_control_code;
|
|
}
|
|
|
|
if (IS_SET(MODE_SIXEL)) {
|
|
- /* TODO: implement sixel mode */
|
|
+ if (sixel_parser_parse(&sixel_st, (unsigned char *)&u, 1) != 0)
|
|
+ perror("sixel_parser_parse() failed");
|
|
return;
|
|
}
|
|
- if (term.esc&ESC_DCS && strescseq.len == 0 && u == 'q')
|
|
- term.mode |= MODE_SIXEL;
|
|
+ if (term.esc & ESC_DCS)
|
|
+ goto check_control_code;
|
|
|
|
if (strescseq.len+len >= sizeof(strescseq.buf)-1) {
|
|
/*
|