mirror of
https://github.com/tmux/tmux.git
synced 2026-10-15 07:44:24 +00:00
Images and copy mode.
This commit is contained in:
47
image-grid.c
47
image-grid.c
@@ -374,6 +374,53 @@ image_grid_duplicate_lines(struct grid *dst, u_int dy, struct grid *src,
|
|||||||
free(maps);
|
free(maps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy clipped image spans between grid areas. */
|
||||||
|
void
|
||||||
|
image_grid_copy_area(struct grid *dst, u_int dx, u_int dy, struct grid *src,
|
||||||
|
u_int px, u_int py, u_int sx, u_int sy)
|
||||||
|
{
|
||||||
|
struct image_copy_map *maps = NULL;
|
||||||
|
struct image_placement *plmt;
|
||||||
|
struct image_line *src_line, *dst_line;
|
||||||
|
struct image_span *span;
|
||||||
|
u_int nmaps = 0, row, start, end, span_end;
|
||||||
|
|
||||||
|
if (dst == src || sx == 0 || sy == 0)
|
||||||
|
return;
|
||||||
|
if (dy >= dst->hsize + dst->sy || py >= src->hsize + src->sy)
|
||||||
|
return;
|
||||||
|
if (sy > dst->hsize + dst->sy - dy)
|
||||||
|
sy = dst->hsize + dst->sy - dy;
|
||||||
|
if (sy > src->hsize + src->sy - py)
|
||||||
|
sy = src->hsize + src->sy - py;
|
||||||
|
end = px + sx;
|
||||||
|
if (end < px)
|
||||||
|
end = UINT_MAX;
|
||||||
|
|
||||||
|
for (row = 0; row < sy; row++) {
|
||||||
|
src_line = src->linedata[py + row].images;
|
||||||
|
if (src_line == NULL)
|
||||||
|
continue;
|
||||||
|
dst_line = NULL;
|
||||||
|
TAILQ_FOREACH(span, &src_line->spans, line_entry) {
|
||||||
|
span_end = span->x + span->sx;
|
||||||
|
start = (span->x > px ? span->x : px);
|
||||||
|
if (start >= end || span_end <= px)
|
||||||
|
continue;
|
||||||
|
if (span_end > end)
|
||||||
|
span_end = end;
|
||||||
|
if (dst_line == NULL)
|
||||||
|
dst_line = image_line_get(&dst->linedata[dy + row]);
|
||||||
|
plmt = image_copy_placement(dst, span->placement, &maps,
|
||||||
|
&nmaps);
|
||||||
|
image_span_add(dst_line, plmt, dx + start - px,
|
||||||
|
span_end - start, span->source_x + start - span->x,
|
||||||
|
span->source_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(maps);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check whether a grid line has any image spans. */
|
/* Check whether a grid line has any image spans. */
|
||||||
int
|
int
|
||||||
image_grid_line_has_images(struct grid_line *gl)
|
image_grid_line_has_images(struct grid_line *gl)
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ void image_grid_move_cells(struct grid *, u_int, u_int, u_int,
|
|||||||
u_int);
|
u_int);
|
||||||
void image_grid_duplicate_lines(struct grid *, u_int, struct grid *,
|
void image_grid_duplicate_lines(struct grid *, u_int, struct grid *,
|
||||||
u_int, u_int);
|
u_int, u_int);
|
||||||
|
void image_grid_copy_area(struct grid *, u_int, u_int, struct grid *,
|
||||||
|
u_int, u_int, u_int, u_int);
|
||||||
int image_grid_line_has_images(struct grid_line *);
|
int image_grid_line_has_images(struct grid_line *);
|
||||||
int image_grid_area_has_images(struct grid *, u_int, u_int, u_int,
|
int image_grid_area_has_images(struct grid *, u_int, u_int, u_int,
|
||||||
u_int);
|
u_int);
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ static void window_copy_write_line(struct window_mode_entry *,
|
|||||||
struct screen_write_ctx *, u_int);
|
struct screen_write_ctx *, u_int);
|
||||||
static void window_copy_write_lines(struct window_mode_entry *,
|
static void window_copy_write_lines(struct window_mode_entry *,
|
||||||
struct screen_write_ctx *, u_int, u_int);
|
struct screen_write_ctx *, u_int, u_int);
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
static void window_copy_update_image_refresh(struct window_copy_mode_data *);
|
||||||
|
static int window_copy_visible_has_images(struct window_copy_mode_data *);
|
||||||
|
#endif
|
||||||
static char *window_copy_match_at_cursor(struct window_copy_mode_data *);
|
static char *window_copy_match_at_cursor(struct window_copy_mode_data *);
|
||||||
static void window_copy_scroll_to(struct window_mode_entry *, u_int, u_int,
|
static void window_copy_scroll_to(struct window_mode_entry *, u_int, u_int,
|
||||||
int);
|
int);
|
||||||
@@ -293,6 +297,12 @@ struct window_copy_mode_data {
|
|||||||
|
|
||||||
u_int oy; /* number of lines scrolled up */
|
u_int oy; /* number of lines scrolled up */
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
u_int image_base; /* where images were last drawn for */
|
||||||
|
int image_base_set;
|
||||||
|
int image_refresh;
|
||||||
|
#endif
|
||||||
|
|
||||||
u_int selx; /* beginning of selection */
|
u_int selx; /* beginning of selection */
|
||||||
u_int sely;
|
u_int sely;
|
||||||
|
|
||||||
@@ -656,6 +666,9 @@ window_copy_init(struct window_mode_entry *wme,
|
|||||||
data->my = screen_hsize(data->backing) + data->cy - data->oy;
|
data->my = screen_hsize(data->backing) + data->cy - data->oy;
|
||||||
data->showmark = 0;
|
data->showmark = 0;
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
window_copy_update_image_refresh(data);
|
||||||
|
#endif
|
||||||
screen_write_start(&ctx, &data->screen);
|
screen_write_start(&ctx, &data->screen);
|
||||||
for (i = 0; i < screen_size_y(&data->screen); i++)
|
for (i = 0; i < screen_size_y(&data->screen); i++)
|
||||||
window_copy_write_line(wme, &ctx, i);
|
window_copy_write_line(wme, &ctx, i);
|
||||||
@@ -1227,6 +1240,9 @@ window_copy_size_changed(struct window_mode_entry *wme)
|
|||||||
window_copy_clear_marks(wme);
|
window_copy_clear_marks(wme);
|
||||||
data->searchindex = searchindex;
|
data->searchindex = searchindex;
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
window_copy_update_image_refresh(data);
|
||||||
|
#endif
|
||||||
screen_write_start(&ctx, s);
|
screen_write_start(&ctx, s);
|
||||||
window_copy_write_lines(wme, &ctx, 0, screen_size_y(s));
|
window_copy_write_lines(wme, &ctx, 0, screen_size_y(s));
|
||||||
screen_write_stop(&ctx);
|
screen_write_stop(&ctx);
|
||||||
@@ -5576,6 +5592,16 @@ window_copy_write_one(struct window_mode_entry *wme,
|
|||||||
for (fx = 0; fx < nx; fx++) {
|
for (fx = 0; fx < nx; fx++) {
|
||||||
grid_get_cell(gd, fx, fy, &gc);
|
grid_get_cell(gd, fx, fy, &gc);
|
||||||
if (fx + gc.data.width <= nx) {
|
if (fx + gc.data.width <= nx) {
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
if (image_grid_area_has_images(gd, fx, fy,
|
||||||
|
gc.data.width, 1)) {
|
||||||
|
grid_view_set_cell(ctx->s->grid, px + fx, py,
|
||||||
|
&gc);
|
||||||
|
screen_write_cursormove(ctx,
|
||||||
|
px + fx + gc.data.width, py, 0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
window_copy_update_style(wme, fx, fy, &gc, mgc, cgc,
|
window_copy_update_style(wme, fx, fy, &gc, mgc, cgc,
|
||||||
mkgc, clgc);
|
mkgc, clgc);
|
||||||
if (gc.flags & GRID_FLAG_PADDING) {
|
if (gc.flags & GRID_FLAG_PADDING) {
|
||||||
@@ -5824,6 +5850,14 @@ window_copy_write_line(struct window_mode_entry *wme,
|
|||||||
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
|
window_copy_write_one(wme, ctx, width, py, hsize - data->oy + py,
|
||||||
content_sx, &mgc, &cgc, &mkgc, &clgc);
|
content_sx, &mgc, &cgc, &mkgc, &clgc);
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
image_grid_free_line(s->grid, &s->grid->linedata[s->grid->hsize + py]);
|
||||||
|
image_grid_copy_area(s->grid, width, s->grid->hsize + py,
|
||||||
|
data->backing->grid, 0, hsize - data->oy + py, content_sx, 1);
|
||||||
|
if (data->image_refresh)
|
||||||
|
image_redraw_area(ctx, width, py, content_sx, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
if (py == 0 && s->rupper < s->rlower && !data->hide_position) {
|
||||||
value = options_get_string(oo, "copy-mode-position-format");
|
value = options_get_string(oo, "copy-mode-position-format");
|
||||||
if (*value != '\0') {
|
if (*value != '\0') {
|
||||||
@@ -5874,6 +5908,34 @@ window_copy_redraw_selection(struct window_mode_entry *wme, u_int old_y)
|
|||||||
window_copy_redraw_lines(wme, start, end - start + 1);
|
window_copy_redraw_lines(wme, start, end - start + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
/* Refresh images when the visible range of history changes. */
|
||||||
|
static void
|
||||||
|
window_copy_update_image_refresh(struct window_copy_mode_data *data)
|
||||||
|
{
|
||||||
|
u_int base = screen_hsize(data->backing) - data->oy;
|
||||||
|
|
||||||
|
if (!data->image_base_set || base != data->image_base)
|
||||||
|
data->image_refresh = 1;
|
||||||
|
else
|
||||||
|
data->image_refresh = 0;
|
||||||
|
data->image_base = base;
|
||||||
|
data->image_base_set = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether visible history contains images. */
|
||||||
|
static int
|
||||||
|
window_copy_visible_has_images(struct window_copy_mode_data *data)
|
||||||
|
{
|
||||||
|
struct grid *gd = data->backing->grid;
|
||||||
|
struct screen *s = &data->screen;
|
||||||
|
u_int sx = screen_size_x(s), sy = screen_size_y(s);
|
||||||
|
u_int hsize = screen_hsize(data->backing);
|
||||||
|
|
||||||
|
return (image_grid_area_has_images(gd, 0, hsize - data->oy, sx, sy));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
||||||
{
|
{
|
||||||
@@ -5883,6 +5945,10 @@ window_copy_redraw_lines(struct window_mode_entry *wme, u_int py, u_int ny)
|
|||||||
struct screen_write_ctx ctx;
|
struct screen_write_ctx ctx;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
window_copy_update_image_refresh(data);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (window_copy_line_number_width(wme) != 0) {
|
if (window_copy_line_number_width(wme) != 0) {
|
||||||
screen_write_start(&ctx, &data->screen);
|
screen_write_start(&ctx, &data->screen);
|
||||||
for (i = py; i < py + ny; i++)
|
for (i = py; i < py + ny; i++)
|
||||||
@@ -7373,6 +7439,13 @@ window_copy_scroll_up(struct window_mode_entry *wme, u_int ny)
|
|||||||
window_copy_redraw_screen(wme);
|
window_copy_redraw_screen(wme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
if (window_copy_visible_has_images(data)) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window_copy_update_image_refresh(data);
|
||||||
|
#endif
|
||||||
if (window_copy_line_numbers_active(wme)) {
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
if (window_copy_line_number_mode(wme) !=
|
if (window_copy_line_number_mode(wme) !=
|
||||||
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||||
@@ -7444,6 +7517,13 @@ window_copy_scroll_down(struct window_mode_entry *wme, u_int ny)
|
|||||||
window_copy_redraw_screen(wme);
|
window_copy_redraw_screen(wme);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef ENABLE_IMAGES
|
||||||
|
if (window_copy_visible_has_images(data)) {
|
||||||
|
window_copy_redraw_screen(wme);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window_copy_update_image_refresh(data);
|
||||||
|
#endif
|
||||||
if (window_copy_line_numbers_active(wme)) {
|
if (window_copy_line_numbers_active(wme)) {
|
||||||
if (window_copy_line_number_mode(wme) !=
|
if (window_copy_line_number_mode(wme) !=
|
||||||
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
WINDOW_COPY_LINE_NUMBERS_ABSOLUTE) {
|
||||||
|
|||||||
Reference in New Issue
Block a user