mirror of
https://github.com/rkd77/elinks.git
synced 2025-02-02 15:09:23 -05:00
[sixel] Small progress.
You can see images. In ~/.mailcap: image/*; img2sixel %s; copiousoutput
This commit is contained in:
parent
ee29a8877b
commit
c0a140f4f3
@ -163,6 +163,10 @@ init_document(struct cache_entry *cached, struct document_options *options)
|
|||||||
init_list(document->timeouts);
|
init_list(document->timeouts);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
init_list(document->images);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_COMBINE
|
#ifdef CONFIG_COMBINE
|
||||||
document->comb_x = -1;
|
document->comb_x = -1;
|
||||||
document->comb_y = -1;
|
document->comb_y = -1;
|
||||||
|
@ -21,6 +21,7 @@ struct ecmascript_timeout;
|
|||||||
struct el_form_control;
|
struct el_form_control;
|
||||||
struct frame_desc;
|
struct frame_desc;
|
||||||
struct frameset_desc;
|
struct frameset_desc;
|
||||||
|
struct image;
|
||||||
struct module;
|
struct module;
|
||||||
struct screen_char;
|
struct screen_char;
|
||||||
|
|
||||||
@ -305,6 +306,9 @@ struct document {
|
|||||||
|
|
||||||
struct el_box clipboard_box;
|
struct el_box clipboard_box;
|
||||||
enum clipboard_status clipboard_status;
|
enum clipboard_status clipboard_status;
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
LIST_OF(struct image) images;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define document_has_frames(document_) ((document_) && (document_)->frame_desc)
|
#define document_has_frames(document_) ((document_) && (document_)->frame_desc)
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -25,6 +26,7 @@
|
|||||||
#include "protocol/uri.h"
|
#include "protocol/uri.h"
|
||||||
#include "terminal/color.h"
|
#include "terminal/color.h"
|
||||||
#include "terminal/draw.h"
|
#include "terminal/draw.h"
|
||||||
|
#include "terminal/sixel.h"
|
||||||
#include "util/color.h"
|
#include "util/color.h"
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
@ -560,7 +562,7 @@ add_document_line(struct plain_renderer *renderer,
|
|||||||
|
|
||||||
prev_char = line_pos > 0 ? line[line_pos - 1] : '\0';
|
prev_char = line_pos > 0 ? line[line_pos - 1] : '\0';
|
||||||
next_char = (line_pos + charlen < width) ?
|
next_char = (line_pos + charlen < width) ?
|
||||||
line[line_pos + charlen] : '\0';
|
line[line_pos + charlen] : '\0';
|
||||||
|
|
||||||
/* Do not expand tabs that precede back-spaces; this saves the
|
/* Do not expand tabs that precede back-spaces; this saves the
|
||||||
* back-space code some trouble. */
|
* back-space code some trouble. */
|
||||||
@ -639,10 +641,45 @@ add_document_line(struct plain_renderer *renderer,
|
|||||||
if (template_->attr)
|
if (template_->attr)
|
||||||
template_->attr |= pos->attr;
|
template_->attr |= pos->attr;
|
||||||
} else if (line_char == 27) {
|
} else if (line_char == 27) {
|
||||||
decode_esc_color(line, &line_pos, width,
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
if (line_pos + 1 < width && line[line_pos + 1] == 'P' && line_pos + 2 < width && line[line_pos + 2] == 'q') {
|
||||||
|
while (1) {
|
||||||
|
char *end = (char *)memchr(line + line_pos + 1, 27, width - line_pos - 1);
|
||||||
|
|
||||||
|
if (end == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (end[1] == '\\') {
|
||||||
|
struct string pixels;
|
||||||
|
|
||||||
|
if (!init_string(&pixels)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
add_bytes_to_string(&pixels, line + line_pos, end + 2 - line - line_pos);
|
||||||
|
int ile = add_image_to_document(document, &pixels, lineno) + 1;
|
||||||
|
|
||||||
|
realloc_line(document, pos - startpos, lineno);
|
||||||
|
|
||||||
|
for (int i = 0; i < ile; i++) {
|
||||||
|
realloc_line(document, 0, lineno + i);
|
||||||
|
}
|
||||||
|
renderer->lineno += ile;
|
||||||
|
lineno += ile;
|
||||||
|
line_pos = end + 2 - line;
|
||||||
|
startpos = pos = realloc_line(document, width, lineno);
|
||||||
|
goto zero;
|
||||||
|
} else {
|
||||||
|
line_pos = end - line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
decode_esc_color(line, &line_pos, width,
|
||||||
&saved_renderer_template,
|
&saved_renderer_template,
|
||||||
doc_opts->color_mode, &was_reversed);
|
doc_opts->color_mode, &was_reversed);
|
||||||
*template_ = saved_renderer_template;
|
*template_ = saved_renderer_template;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int added_chars = 0;
|
int added_chars = 0;
|
||||||
|
|
||||||
@ -700,6 +737,7 @@ add_document_line(struct plain_renderer *renderer,
|
|||||||
next:
|
next:
|
||||||
line_pos += charlen;
|
line_pos += charlen;
|
||||||
cells += cell;
|
cells += cell;
|
||||||
|
zero:
|
||||||
}
|
}
|
||||||
mem_free(line);
|
mem_free(line);
|
||||||
|
|
||||||
@ -749,11 +787,11 @@ add_document_lines(struct plain_renderer *renderer)
|
|||||||
int last_space = 0;
|
int last_space = 0;
|
||||||
int tab_spaces = 0;
|
int tab_spaces = 0;
|
||||||
int step = 0;
|
int step = 0;
|
||||||
int cells = 0;
|
int cells = 0;
|
||||||
|
|
||||||
/* End of line detection: We handle \r, \r\n and \n types. */
|
/* End of line detection: We handle \r, \r\n and \n types. */
|
||||||
for (width = 0; (width < length) &&
|
for (width = 0; (width < length) &&
|
||||||
(cells < renderer->max_width);) {
|
(cells < renderer->max_width);) {
|
||||||
if (source[width] == ASCII_CR)
|
if (source[width] == ASCII_CR)
|
||||||
step++;
|
step++;
|
||||||
if (source[width + step] == ASCII_LF)
|
if (source[width + step] == ASCII_LF)
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
if conf_data.get('CONFIG_MOUSE')
|
if conf_data.get('CONFIG_MOUSE')
|
||||||
srcs += files('mouse.c')
|
srcs += files('mouse.c')
|
||||||
endif
|
endif
|
||||||
|
if conf_data.get('CONFIG_LIBSIXEL')
|
||||||
|
srcs += files('sixel.c')
|
||||||
|
endif
|
||||||
if conf_data.get('CONFIG_TERMINFO')
|
if conf_data.get('CONFIG_TERMINFO')
|
||||||
srcs += files('terminfo.c')
|
srcs += files('terminfo.c')
|
||||||
endif
|
endif
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "terminal/hardio.h"
|
#include "terminal/hardio.h"
|
||||||
#include "terminal/kbd.h"
|
#include "terminal/kbd.h"
|
||||||
#include "terminal/screen.h"
|
#include "terminal/screen.h"
|
||||||
|
#include "terminal/sixel.h"
|
||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#ifdef CONFIG_TERMINFO
|
#ifdef CONFIG_TERMINFO
|
||||||
#include "terminal/terminfo.h"
|
#include "terminal/terminfo.h"
|
||||||
@ -675,7 +676,7 @@ done_screen_drivers(struct module *xxx)
|
|||||||
|
|
||||||
/** Adds the term code for positioning the cursor at @a x and @a y to
|
/** Adds the term code for positioning the cursor at @a x and @a y to
|
||||||
* @a string. The template term code is: "\033[<y>;<x>H" */
|
* @a string. The template term code is: "\033[<y>;<x>H" */
|
||||||
static inline struct string *
|
struct string *
|
||||||
add_cursor_move_to_string(struct string *screen, int y, int x)
|
add_cursor_move_to_string(struct string *screen, int y, int x)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_TERMINFO
|
#ifdef CONFIG_TERMINFO
|
||||||
@ -1372,6 +1373,8 @@ add_char_true(struct string *screen, struct screen_driver *driver,
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/*! Updating of the terminal screen is done by checking what needs to
|
/*! Updating of the terminal screen is done by checking what needs to
|
||||||
* be updated using the last screen. */
|
* be updated using the last screen. */
|
||||||
void
|
void
|
||||||
@ -1453,6 +1456,9 @@ redraw_screen(struct terminal *term)
|
|||||||
|
|
||||||
copy_screen_chars(screen->last_image, screen->image, term->width * term->height);
|
copy_screen_chars(screen->last_image, screen->image, term->width * term->height);
|
||||||
screen->was_dirty = 0;
|
screen->was_dirty = 0;
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
try_to_draw_images(term);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -8,6 +8,7 @@ extern "C" {
|
|||||||
struct bitfield;
|
struct bitfield;
|
||||||
struct module;
|
struct module;
|
||||||
struct screen_char;
|
struct screen_char;
|
||||||
|
struct string;
|
||||||
struct terminal;
|
struct terminal;
|
||||||
|
|
||||||
/** The terminal's screen manages */
|
/** The terminal's screen manages */
|
||||||
@ -50,6 +51,8 @@ void erase_screen(struct terminal *term);
|
|||||||
/** Meeep! */
|
/** Meeep! */
|
||||||
void beep_terminal(struct terminal *term);
|
void beep_terminal(struct terminal *term);
|
||||||
|
|
||||||
|
struct string *add_cursor_move_to_string(struct string *screen, int y, int x);
|
||||||
|
|
||||||
extern struct module terminal_screen_module;
|
extern struct module terminal_screen_module;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
110
src/terminal/sixel.c
Normal file
110
src/terminal/sixel.c
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/** Terminal sixel routines.
|
||||||
|
* @file */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sixel.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "osdep/osdep.h"
|
||||||
|
#include "terminal/hardio.h"
|
||||||
|
#include "terminal/screen.h"
|
||||||
|
#include "terminal/sixel.h"
|
||||||
|
#include "terminal/terminal.h"
|
||||||
|
|
||||||
|
/* encode settings object */
|
||||||
|
struct sixel_decoder {
|
||||||
|
unsigned int ref;
|
||||||
|
char *input;
|
||||||
|
char *output;
|
||||||
|
sixel_allocator_t *allocator;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
try_to_draw_images(struct terminal *term)
|
||||||
|
{
|
||||||
|
struct image *im;
|
||||||
|
|
||||||
|
foreach (im, term->images) {
|
||||||
|
struct string text;
|
||||||
|
|
||||||
|
if (!init_string(&text)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
add_cursor_move_to_string(&text, im->y + 1, im->x + 1);
|
||||||
|
add_string_to_string(&text, &im->sixel);
|
||||||
|
|
||||||
|
if (text.length) {
|
||||||
|
if (term->master) want_draw();
|
||||||
|
hard_write(term->fdout, text.source, text.length);
|
||||||
|
if (term->master) done_draw();
|
||||||
|
}
|
||||||
|
done_string(&text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
delete_image(struct image *im)
|
||||||
|
{
|
||||||
|
del_from_list(im);
|
||||||
|
done_string(&im->sixel);
|
||||||
|
mem_free(im);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
add_image_to_document(struct document *doc, struct string *pixels, int lineno)
|
||||||
|
{
|
||||||
|
struct image *im = mem_calloc(1, sizeof(*im));
|
||||||
|
|
||||||
|
if (!im) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sixel_decoder_t *decoder = NULL;
|
||||||
|
SIXELSTATUS status = sixel_decoder_new(&decoder, NULL);
|
||||||
|
|
||||||
|
if (status != SIXEL_OK) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *indexed_pixels = NULL;
|
||||||
|
unsigned char *palette = NULL;
|
||||||
|
int ncolors;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int ile = 0;
|
||||||
|
|
||||||
|
status = sixel_decode_raw(
|
||||||
|
(unsigned char *)pixels->source,
|
||||||
|
pixels->length,
|
||||||
|
&indexed_pixels,
|
||||||
|
&width,
|
||||||
|
&height,
|
||||||
|
&palette,
|
||||||
|
&ncolors,
|
||||||
|
decoder->allocator
|
||||||
|
);
|
||||||
|
|
||||||
|
if (SIXEL_FAILED(status)) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
im->y = lineno + 1;
|
||||||
|
im->x = 0;
|
||||||
|
im->width = width;
|
||||||
|
im->height = height;
|
||||||
|
*(&im->sixel) = *pixels;
|
||||||
|
ile = (height + 15) / 16;
|
||||||
|
add_to_list(doc->images, im);
|
||||||
|
end:
|
||||||
|
sixel_allocator_free(decoder->allocator, indexed_pixels);
|
||||||
|
sixel_allocator_free(decoder->allocator, palette);
|
||||||
|
sixel_decoder_unref(decoder);
|
||||||
|
|
||||||
|
return ile;
|
||||||
|
}
|
38
src/terminal/sixel.h
Normal file
38
src/terminal/sixel.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef EL__TERMINAL_SIXEL_H
|
||||||
|
#define EL__TERMINAL_SIXEL_H
|
||||||
|
|
||||||
|
#include "util/lists.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
struct document;
|
||||||
|
struct terminal;
|
||||||
|
|
||||||
|
struct image {
|
||||||
|
LIST_HEAD(struct image);
|
||||||
|
struct string sixel;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
void delete_image(struct image *im);
|
||||||
|
|
||||||
|
void try_to_draw_images(struct terminal *term);
|
||||||
|
|
||||||
|
/* return height of image in terminal rows */
|
||||||
|
int add_image_to_document(struct document *doc, struct string *pixels, int lineno);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EL__TERMINAL_SIXEL_H */
|
@ -35,6 +35,7 @@
|
|||||||
#include "terminal/hardio.h"
|
#include "terminal/hardio.h"
|
||||||
#include "terminal/kbd.h"
|
#include "terminal/kbd.h"
|
||||||
#include "terminal/screen.h"
|
#include "terminal/screen.h"
|
||||||
|
#include "terminal/sixel.h"
|
||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#ifdef CONFIG_TERMINFO
|
#ifdef CONFIG_TERMINFO
|
||||||
#include "terminal/terminfo.h"
|
#include "terminal/terminfo.h"
|
||||||
@ -117,6 +118,9 @@ init_term(int fdin, int fdout)
|
|||||||
#endif
|
#endif
|
||||||
init_list(term->windows);
|
init_list(term->windows);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
init_list(term->images);
|
||||||
|
#endif
|
||||||
term->fdin = fdin;
|
term->fdin = fdin;
|
||||||
term->fdout = fdout;
|
term->fdout = fdout;
|
||||||
term->master = (term->fdout == get_output_handle());
|
term->master = (term->fdout == get_output_handle());
|
||||||
@ -184,6 +188,11 @@ destroy_terminal(struct terminal *term)
|
|||||||
while (!list_empty(term->windows))
|
while (!list_empty(term->windows))
|
||||||
delete_window((struct window *)term->windows.next);
|
delete_window((struct window *)term->windows.next);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
while (!list_empty(term->images)) {
|
||||||
|
delete_image((struct image *)term->images.next);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* mem_free_if(term->cwd); */
|
/* mem_free_if(term->cwd); */
|
||||||
mem_free_if(term->title);
|
mem_free_if(term->title);
|
||||||
if (term->screen) done_screen(term->screen);
|
if (term->screen) done_screen(term->screen);
|
||||||
|
@ -172,6 +172,10 @@ struct terminal {
|
|||||||
void *textarea_data;
|
void *textarea_data;
|
||||||
|
|
||||||
struct term_event_mouse prev_mouse_event;
|
struct term_event_mouse prev_mouse_event;
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
LIST_OF(struct image) images;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define do_not_ignore_next_mouse_event(term) \
|
#define do_not_ignore_next_mouse_event(term) \
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include "session/location.h"
|
#include "session/location.h"
|
||||||
#include "session/session.h"
|
#include "session/session.h"
|
||||||
#include "terminal/draw.h"
|
#include "terminal/draw.h"
|
||||||
|
#include "terminal/sixel.h"
|
||||||
#include "terminal/tab.h"
|
#include "terminal/tab.h"
|
||||||
#include "terminal/terminal.h"
|
#include "terminal/terminal.h"
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
@ -458,6 +460,32 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active)
|
|||||||
if (vs->current_link == -1)
|
if (vs->current_link == -1)
|
||||||
vs->current_link = 0;
|
vs->current_link = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_LIBSIXEL
|
||||||
|
while (!list_empty(term->images)) {
|
||||||
|
delete_image((struct image *)term->images.next);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_empty(term->images)) {
|
||||||
|
struct image *im;
|
||||||
|
|
||||||
|
foreach (im, doc_view->document->images) {
|
||||||
|
if (im) {
|
||||||
|
struct image *im_copy = mem_calloc(1, sizeof(*im_copy));
|
||||||
|
|
||||||
|
if (im_copy) {
|
||||||
|
if (init_string(&im_copy->sixel)) {
|
||||||
|
add_string_to_string(&im_copy->sixel, &im->sixel);
|
||||||
|
im_copy->x = im->x;
|
||||||
|
im_copy->y = im->y;
|
||||||
|
im_copy->width = im->width;
|
||||||
|
im_copy->height = im->height;
|
||||||
|
add_to_list(term->images, im_copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user