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);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LIBSIXEL
|
||||
init_list(document->images);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMBINE
|
||||
document->comb_x = -1;
|
||||
document->comb_y = -1;
|
||||
|
@ -21,6 +21,7 @@ struct ecmascript_timeout;
|
||||
struct el_form_control;
|
||||
struct frame_desc;
|
||||
struct frameset_desc;
|
||||
struct image;
|
||||
struct module;
|
||||
struct screen_char;
|
||||
|
||||
@ -305,6 +306,9 @@ struct document {
|
||||
|
||||
struct el_box clipboard_box;
|
||||
enum clipboard_status clipboard_status;
|
||||
#ifdef CONFIG_LIBSIXEL
|
||||
LIST_OF(struct image) images;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define document_has_frames(document_) ((document_) && (document_)->frame_desc)
|
||||
|
@ -5,6 +5,7 @@
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -25,6 +26,7 @@
|
||||
#include "protocol/uri.h"
|
||||
#include "terminal/color.h"
|
||||
#include "terminal/draw.h"
|
||||
#include "terminal/sixel.h"
|
||||
#include "util/color.h"
|
||||
#include "util/error.h"
|
||||
#include "util/memory.h"
|
||||
@ -639,10 +641,45 @@ add_document_line(struct plain_renderer *renderer,
|
||||
if (template_->attr)
|
||||
template_->attr |= pos->attr;
|
||||
} else if (line_char == 27) {
|
||||
#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,
|
||||
doc_opts->color_mode, &was_reversed);
|
||||
*template_ = saved_renderer_template;
|
||||
}
|
||||
} else {
|
||||
int added_chars = 0;
|
||||
|
||||
@ -700,6 +737,7 @@ add_document_line(struct plain_renderer *renderer,
|
||||
next:
|
||||
line_pos += charlen;
|
||||
cells += cell;
|
||||
zero:
|
||||
}
|
||||
mem_free(line);
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
if conf_data.get('CONFIG_MOUSE')
|
||||
srcs += files('mouse.c')
|
||||
endif
|
||||
if conf_data.get('CONFIG_LIBSIXEL')
|
||||
srcs += files('sixel.c')
|
||||
endif
|
||||
if conf_data.get('CONFIG_TERMINFO')
|
||||
srcs += files('terminfo.c')
|
||||
endif
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "terminal/hardio.h"
|
||||
#include "terminal/kbd.h"
|
||||
#include "terminal/screen.h"
|
||||
#include "terminal/sixel.h"
|
||||
#include "terminal/terminal.h"
|
||||
#ifdef CONFIG_TERMINFO
|
||||
#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
|
||||
* @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)
|
||||
{
|
||||
#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
|
||||
* be updated using the last screen. */
|
||||
void
|
||||
@ -1453,6 +1456,9 @@ redraw_screen(struct terminal *term)
|
||||
|
||||
copy_screen_chars(screen->last_image, screen->image, term->width * term->height);
|
||||
screen->was_dirty = 0;
|
||||
#ifdef CONFIG_LIBSIXEL
|
||||
try_to_draw_images(term);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8,6 +8,7 @@ extern "C" {
|
||||
struct bitfield;
|
||||
struct module;
|
||||
struct screen_char;
|
||||
struct string;
|
||||
struct terminal;
|
||||
|
||||
/** The terminal's screen manages */
|
||||
@ -50,6 +51,8 @@ void erase_screen(struct terminal *term);
|
||||
/** Meeep! */
|
||||
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;
|
||||
|
||||
#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/kbd.h"
|
||||
#include "terminal/screen.h"
|
||||
#include "terminal/sixel.h"
|
||||
#include "terminal/terminal.h"
|
||||
#ifdef CONFIG_TERMINFO
|
||||
#include "terminal/terminfo.h"
|
||||
@ -117,6 +118,9 @@ init_term(int fdin, int fdout)
|
||||
#endif
|
||||
init_list(term->windows);
|
||||
|
||||
#ifdef CONFIG_LIBSIXEL
|
||||
init_list(term->images);
|
||||
#endif
|
||||
term->fdin = fdin;
|
||||
term->fdout = fdout;
|
||||
term->master = (term->fdout == get_output_handle());
|
||||
@ -184,6 +188,11 @@ destroy_terminal(struct terminal *term)
|
||||
while (!list_empty(term->windows))
|
||||
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->title);
|
||||
if (term->screen) done_screen(term->screen);
|
||||
|
@ -172,6 +172,10 @@ struct terminal {
|
||||
void *textarea_data;
|
||||
|
||||
struct term_event_mouse prev_mouse_event;
|
||||
|
||||
#ifdef CONFIG_LIBSIXEL
|
||||
LIST_OF(struct image) images;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define do_not_ignore_next_mouse_event(term) \
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@ -29,6 +30,7 @@
|
||||
#include "session/location.h"
|
||||
#include "session/session.h"
|
||||
#include "terminal/draw.h"
|
||||
#include "terminal/sixel.h"
|
||||
#include "terminal/tab.h"
|
||||
#include "terminal/terminal.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)
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user