forked from enlightenment/terminology
Rewrite reflow on resize
Summary: simplify code (treat every resize as a single case) and fill the lines from the bottom up Reviewers: billiob Differential Revision: https://phab.enlightenment.org/D355
This commit is contained in:
parent
fae338a84f
commit
d0c6c1d457
|
@ -605,695 +605,210 @@ termpty_line_length(const Termcell *cells, ssize_t nb_cells)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define OLD_SCREEN(_X, _Y) \
|
||||
old_screen[_X + (((_Y + old_circular_offset) % old_h) * old_w)]
|
||||
|
||||
static void
|
||||
_termpty_horizontally_expand(Termpty *ty, int old_w, int old_h,
|
||||
Termcell *old_screen)
|
||||
static int
|
||||
termpty_line_find_top(Termpty *ty, int y_end)
|
||||
{
|
||||
int i,
|
||||
new_back_pos = 0,
|
||||
old_y,
|
||||
old_x,
|
||||
old_circular_offset = ty->circular_offset,
|
||||
x = 0,
|
||||
y = 0;
|
||||
Termsave **new_back, *new_ts = NULL;
|
||||
Eina_Bool rewrapping = EINA_FALSE;
|
||||
|
||||
if ((!ty->backmax) || (!ty->back)) goto expand_screen;
|
||||
|
||||
new_back = calloc(sizeof(Termsave *), ty->backmax);
|
||||
if (!new_back) return;
|
||||
|
||||
termpty_save_freeze();
|
||||
for (i = 0; i < ty->backmax; i++)
|
||||
{
|
||||
int y_start = y_end;
|
||||
Termsave *ts;
|
||||
|
||||
if (ty->backscroll_num == ty->backmax - 1)
|
||||
ts = termpty_save_extract(ty->back[(ty->backpos + i) % ty->backmax]);
|
||||
while (y_start > 0)
|
||||
{
|
||||
if (TERMPTY_SCREEN(ty, ty->w - 1, y_start - 1).att.autowrapped)
|
||||
y_start--;
|
||||
else
|
||||
ts = termpty_save_extract(ty->back[i]);
|
||||
if (!ts) break;
|
||||
|
||||
if (!ts->w)
|
||||
{
|
||||
if (rewrapping)
|
||||
{
|
||||
rewrapping = EINA_FALSE;
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 0;
|
||||
return y_start;
|
||||
}
|
||||
else
|
||||
new_back[new_back_pos++] = ts;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rewrapping)
|
||||
{
|
||||
int remaining_width = ty->w - new_ts->w;
|
||||
int len = ts->w;
|
||||
Termcell *cells = ts->cell;
|
||||
|
||||
if (new_ts->w)
|
||||
{
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 0;
|
||||
}
|
||||
if (ts->w >= remaining_width)
|
||||
{
|
||||
termpty_cell_copy(ty, cells, new_ts->cell + new_ts->w,
|
||||
remaining_width);
|
||||
new_ts->w = ty->w;
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 1;
|
||||
len -= remaining_width;
|
||||
cells += remaining_width;
|
||||
|
||||
new_ts = termpty_save_new(ty->w);
|
||||
new_ts->w = 0;
|
||||
new_back[new_back_pos++] = new_ts;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
termpty_cell_copy(ty, cells, new_ts->cell + new_ts->w, len);
|
||||
new_ts->w += len;
|
||||
}
|
||||
|
||||
rewrapping = ts->cell[ts->w - 1].att.autowrapped;
|
||||
if (!rewrapping) new_ts = NULL;
|
||||
termpty_save_free(ts);
|
||||
}
|
||||
else
|
||||
while (-y_start < ty->backscroll_num)
|
||||
{
|
||||
ts = termpty_save_extract(ty->back[(y_start + ty->backpos - 1 +
|
||||
ty->backmax) % ty->backmax]);
|
||||
ty->back[(y_start + ty->backpos - 1 + ty->backmax) % ty->backmax] = ts;
|
||||
if (ts->cell[ts->w - 1].att.autowrapped)
|
||||
{
|
||||
rewrapping = EINA_TRUE;
|
||||
new_ts = termpty_save_new(ty->w);
|
||||
new_ts->w = ts->w;
|
||||
termpty_cell_copy(ty, ts->cell, new_ts->cell, ts->w);
|
||||
new_ts->cell[ts->w - 1].att.autowrapped = 0;
|
||||
new_back[new_back_pos++] = new_ts;
|
||||
termpty_save_free(ts);
|
||||
}
|
||||
y_start--;
|
||||
else
|
||||
new_back[new_back_pos++] = ts;
|
||||
return y_start;
|
||||
}
|
||||
}
|
||||
|
||||
if (new_back_pos >= ty->backmax)
|
||||
{
|
||||
ty->backscroll_num = ty->backmax - 1;
|
||||
ty->backpos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ty->backscroll_num = new_back_pos;
|
||||
ty->backpos = new_back_pos;
|
||||
}
|
||||
|
||||
free(ty->back);
|
||||
ty->back = new_back;
|
||||
|
||||
expand_screen:
|
||||
|
||||
if (ty->altbuf)
|
||||
{
|
||||
termpty_save_thaw();
|
||||
return;
|
||||
}
|
||||
|
||||
ty->circular_offset = 0;
|
||||
/* TODO double-width :) */
|
||||
for (old_y = 0; old_y < old_h; old_y++)
|
||||
{
|
||||
ssize_t cur_line_length;
|
||||
|
||||
cur_line_length = termpty_line_length(&OLD_SCREEN(0, old_y), old_w);
|
||||
if (rewrapping)
|
||||
{
|
||||
if (new_ts)
|
||||
{
|
||||
ssize_t remaining_width = ty->w - new_ts->w;
|
||||
ssize_t len = MIN(cur_line_length, remaining_width);
|
||||
Termcell *cells = &OLD_SCREEN(0, old_y);
|
||||
|
||||
termpty_cell_copy(ty, cells, new_ts->cell + new_ts->w, len);
|
||||
new_ts->w += len;
|
||||
cells += len;
|
||||
if (cur_line_length > remaining_width)
|
||||
{
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 1;
|
||||
new_ts = NULL;
|
||||
len = cur_line_length - remaining_width;
|
||||
termpty_cell_copy(ty, cells, ty->screen + (y * ty->w),
|
||||
len);
|
||||
x += len;
|
||||
}
|
||||
|
||||
rewrapping = OLD_SCREEN(old_w - 1, old_y).att.autowrapped;
|
||||
if (!rewrapping)
|
||||
{
|
||||
new_ts = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int remaining_width = ty->w - x,
|
||||
len = cur_line_length;
|
||||
|
||||
old_x = 0;
|
||||
if (cur_line_length >= remaining_width)
|
||||
{
|
||||
termpty_cell_copy(ty,
|
||||
&OLD_SCREEN(0, old_y),
|
||||
ty->screen + (y * ty->w) + x,
|
||||
remaining_width);
|
||||
TERMPTY_SCREEN(ty, ty->w - 1, y).att.autowrapped = 1;
|
||||
y++;
|
||||
x = 0;
|
||||
old_x = remaining_width;
|
||||
len -= remaining_width;
|
||||
}
|
||||
if (len)
|
||||
{
|
||||
termpty_cell_copy(ty,
|
||||
&OLD_SCREEN(old_x, old_y),
|
||||
ty->screen + (y * ty->w) + x,
|
||||
len);
|
||||
x += len;
|
||||
TERMPTY_SCREEN(ty, x - 1, y).att.autowrapped = 0;
|
||||
}
|
||||
rewrapping = OLD_SCREEN(old_w - 1, old_y).att.autowrapped;
|
||||
if (!rewrapping) y++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
termpty_cell_copy(ty,
|
||||
&OLD_SCREEN(0, old_y),
|
||||
ty->screen + (y * ty->w),
|
||||
cur_line_length);
|
||||
if (OLD_SCREEN(old_w - 1, old_y).att.autowrapped)
|
||||
{
|
||||
rewrapping = EINA_TRUE;
|
||||
TERMPTY_SCREEN(ty, old_w - 1, old_y).att.autowrapped = 0;
|
||||
x = cur_line_length;
|
||||
}
|
||||
else y++;
|
||||
}
|
||||
}
|
||||
if (y < old_h)
|
||||
{
|
||||
ty->state.cy -= old_h - y;
|
||||
if (ty->state.cy < 0) ty->state.cy = 0;
|
||||
}
|
||||
termpty_save_thaw();
|
||||
return y_start;
|
||||
}
|
||||
|
||||
static void
|
||||
_termpty_vertically_expand(Termpty *ty, int old_w, int old_h,
|
||||
Termcell *old_screen)
|
||||
static int
|
||||
termpty_line_rewrap(Termpty *ty, int y_start, int y_end,
|
||||
Termcell *screen2, Termsave **back2,
|
||||
int w2, int h2, int y2_end)
|
||||
{
|
||||
int from_history = 0, y;
|
||||
int x, x2, y, y2, y2_start;
|
||||
int len, len_last, len_remaining, copy_width, ts2_width;
|
||||
Termsave *ts, *ts2;
|
||||
Termcell *line, *line2;
|
||||
|
||||
if (ty->altbuf) return;
|
||||
|
||||
termpty_save_freeze();
|
||||
|
||||
if (ty->backmax > 0)
|
||||
from_history = MIN(ty->h - old_h, ty->backscroll_num);
|
||||
if (old_screen)
|
||||
if (y_end >= 0)
|
||||
{
|
||||
int old_circular_offset = ty->circular_offset;
|
||||
|
||||
ty->circular_offset = 0;
|
||||
|
||||
for (y = 0; y < old_h; y++)
|
||||
{
|
||||
Termcell *c1, *c2;
|
||||
|
||||
c1 = &(OLD_SCREEN(0, y));
|
||||
c2 = &(TERMPTY_SCREEN(ty, 0, y));
|
||||
termpty_cell_copy(ty, c1, c2, old_w);
|
||||
}
|
||||
}
|
||||
|
||||
if ((from_history <= 0) || (!ty->back))
|
||||
{
|
||||
termpty_save_thaw();
|
||||
return;
|
||||
}
|
||||
|
||||
/* display content from backlog */
|
||||
for (y = from_history - 1; y >= 0; y--)
|
||||
{
|
||||
Termsave *ts;
|
||||
Termcell *src, *dst;
|
||||
|
||||
ty->backpos--;
|
||||
if (ty->backpos < 0)
|
||||
ty->backpos = ty->backscroll_num - 1;
|
||||
ts = termpty_save_extract(ty->back[ty->backpos]);
|
||||
|
||||
src = ts->cell;
|
||||
dst = &(TERMPTY_SCREEN(ty, 0, ty->h - from_history + y));
|
||||
termpty_cell_copy(ty, src, dst, ts->w);
|
||||
|
||||
termpty_save_free(ts);
|
||||
ty->back[ty->backpos] = NULL;
|
||||
ty->backscroll_num--;
|
||||
}
|
||||
|
||||
ty->circular_offset = (ty->circular_offset + ty->h - from_history) % ty->h;
|
||||
|
||||
ty->state.cy += from_history;
|
||||
termpty_save_thaw();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_termpty_vertically_shrink(Termpty *ty, int old_w, int old_h,
|
||||
Termcell *old_screen)
|
||||
{
|
||||
int to_history,
|
||||
real_h = old_h,
|
||||
old_circular_offset,
|
||||
y;
|
||||
Termcell *src, *dst;
|
||||
|
||||
if (ty->altbuf) return;
|
||||
|
||||
termpty_save_freeze();
|
||||
|
||||
old_circular_offset = ty->circular_offset;
|
||||
for (y = old_h - 1; y >= 0; y--)
|
||||
{
|
||||
ssize_t screen_length = termpty_line_length(&OLD_SCREEN(0, y), old_w);
|
||||
|
||||
if (screen_length) break;
|
||||
else real_h--;
|
||||
}
|
||||
|
||||
to_history = real_h - ty->h;
|
||||
if (to_history > 0)
|
||||
{
|
||||
for (y = 0; y < to_history; y++)
|
||||
{
|
||||
termpty_text_save_top(ty, &(OLD_SCREEN(0, y)), old_w);
|
||||
}
|
||||
ty->state.cy -= to_history;
|
||||
if (ty->state.cy < 0) ty->state.cy = 0;
|
||||
}
|
||||
|
||||
if (old_w == ty->w)
|
||||
{
|
||||
if (to_history < 0)
|
||||
to_history = 0;
|
||||
ty->circular_offset = 0;
|
||||
for (y = 0; y < ty->h; y++)
|
||||
{
|
||||
src = &(OLD_SCREEN(0, y + to_history));
|
||||
dst = &(TERMPTY_SCREEN(ty, 0, y));
|
||||
termpty_cell_copy(ty, src, dst, old_w);
|
||||
}
|
||||
len_last = termpty_line_length(&TERMPTY_SCREEN(ty, 0, y_end), ty->w);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* in place */
|
||||
int len, pos, offset;
|
||||
|
||||
if ((to_history <= 0) || (ty->circular_offset == 0))
|
||||
{
|
||||
termpty_save_thaw();
|
||||
return;
|
||||
ts = termpty_save_extract(ty->back[(y_end + ty->backpos +
|
||||
ty->backmax) % ty->backmax]);
|
||||
ty->back[(y_end + ty->backpos + ty->backmax) % ty->backmax] = ts;
|
||||
len_last = ts->w;
|
||||
}
|
||||
|
||||
ty->circular_offset = (ty->circular_offset + to_history) % old_h;
|
||||
len = real_h - to_history;
|
||||
pos = (len + ty->circular_offset) % old_h;
|
||||
offset = len - pos;
|
||||
|
||||
/* 2 times */
|
||||
if (offset > 0)
|
||||
len_remaining = len_last + (y_end - y_start) * ty->w;
|
||||
y2_start = y2_end;
|
||||
if (len_remaining)
|
||||
{
|
||||
for (y = pos - 1; y >= 0; y--)
|
||||
{
|
||||
src = &(old_screen[y * old_w]);
|
||||
dst = &(old_screen[(y + offset) * old_w]);
|
||||
termpty_cell_copy(ty, src, dst, old_w);
|
||||
}
|
||||
}
|
||||
else
|
||||
offset = len;
|
||||
|
||||
for (y = 0; y < offset; y++)
|
||||
{
|
||||
src = &(old_screen[(ty->circular_offset + y) * old_w]);
|
||||
dst = &(old_screen[y * old_w]);
|
||||
termpty_cell_copy(ty, src, dst, old_w);
|
||||
}
|
||||
ty->circular_offset = 0;
|
||||
|
||||
len = ty->h - len;
|
||||
if (len)
|
||||
termpty_cell_fill(ty, NULL,
|
||||
&old_screen[(old_h - len) * old_w],
|
||||
len * old_w);
|
||||
}
|
||||
termpty_save_thaw();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_termpty_horizontally_shrink(Termpty *ty, int old_w, int old_h,
|
||||
Termcell *old_screen)
|
||||
{
|
||||
int i,
|
||||
new_back_pos = 0,
|
||||
new_back_scroll_num = 0,
|
||||
old_y,
|
||||
old_x,
|
||||
screen_height_used,
|
||||
old_circular_offset = ty->circular_offset,
|
||||
x = 0,
|
||||
y = 0;
|
||||
ssize_t *screen_lengths;
|
||||
Termsave **new_back,
|
||||
*new_ts = NULL,
|
||||
*old_ts = NULL;
|
||||
Termcell *old_cells = NULL;
|
||||
Eina_Bool rewrapping = EINA_FALSE,
|
||||
done = EINA_FALSE,
|
||||
cy_pushed_back = EINA_FALSE;
|
||||
|
||||
termpty_save_freeze();
|
||||
|
||||
if (!ty->backmax || !ty->back)
|
||||
goto shrink_screen;
|
||||
|
||||
new_back = calloc(sizeof(Termsave*), ty->backmax);
|
||||
|
||||
for (i = 0; i < ty->backmax; i++)
|
||||
{
|
||||
Termsave *ts;
|
||||
Termcell *cells;
|
||||
int remaining_width;
|
||||
|
||||
if (ty->backscroll_num == ty->backmax - 1)
|
||||
ts = termpty_save_extract(ty->back[(ty->backpos + i) % ty->backmax]);
|
||||
else
|
||||
ts = termpty_save_extract(ty->back[i]);
|
||||
if (!ts)
|
||||
break;
|
||||
|
||||
#define PUSH_BACK_TS(_ts) do { \
|
||||
if (new_back[new_back_pos]) \
|
||||
termpty_save_free(new_back[new_back_pos]); \
|
||||
new_back[new_back_pos++] = _ts; \
|
||||
new_back_scroll_num++; \
|
||||
if (new_back_pos >= ty->backmax) \
|
||||
new_back_pos = 0; \
|
||||
} while(0)
|
||||
|
||||
if (!ts->w)
|
||||
{
|
||||
if (rewrapping)
|
||||
{
|
||||
rewrapping = EINA_FALSE;
|
||||
new_ts = termpty_save_new(old_ts->w);
|
||||
termpty_cell_copy(ty, old_cells, new_ts->cell, old_ts->w);
|
||||
PUSH_BACK_TS(new_ts);
|
||||
termpty_save_free(old_ts);
|
||||
old_ts = NULL;
|
||||
termpty_save_free(ts);
|
||||
}
|
||||
else
|
||||
PUSH_BACK_TS(ts);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!old_ts && ts->w <= ty->w)
|
||||
{
|
||||
PUSH_BACK_TS(ts);
|
||||
continue;
|
||||
}
|
||||
|
||||
cells = ts->cell;
|
||||
|
||||
if (old_ts)
|
||||
{
|
||||
int len = MIN(old_ts->w + ts->w, ty->w);
|
||||
|
||||
new_ts = termpty_save_new(len);
|
||||
termpty_cell_copy(ty, old_cells, new_ts->cell, old_ts->w);
|
||||
|
||||
remaining_width = len - old_ts->w;
|
||||
|
||||
termpty_cell_copy(ty, cells, new_ts->cell + old_ts->w,
|
||||
remaining_width);
|
||||
|
||||
rewrapping = ts->cell[ts->w - 1].att.autowrapped;
|
||||
cells += remaining_width;
|
||||
ts->w -= remaining_width;
|
||||
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped =
|
||||
rewrapping || ts->w > 0;
|
||||
|
||||
termpty_save_free(old_ts);
|
||||
old_ts = NULL;
|
||||
|
||||
PUSH_BACK_TS(new_ts);
|
||||
}
|
||||
|
||||
while (ts->w >= ty->w)
|
||||
{
|
||||
new_ts = termpty_save_new(ty->w);
|
||||
termpty_cell_copy(ty, cells, new_ts->cell, ty->w);
|
||||
rewrapping = ts->cell[ts->w - 1].att.autowrapped;
|
||||
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 1;
|
||||
if (!rewrapping && ty->w == ts->w)
|
||||
new_ts->cell[new_ts->w - 1].att.autowrapped = 0;
|
||||
|
||||
cells += ty->w;
|
||||
ts->w -= ty->w;
|
||||
|
||||
PUSH_BACK_TS(new_ts);
|
||||
}
|
||||
|
||||
if (!ts->w)
|
||||
{
|
||||
old_cells = 0;
|
||||
termpty_save_free(old_ts);
|
||||
old_ts = NULL;
|
||||
rewrapping = EINA_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rewrapping)
|
||||
{
|
||||
old_cells = cells;
|
||||
old_ts = ts;
|
||||
y2_start -= (len_remaining + w2 - 1) / w2 - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ts = termpty_save_new(ts->w);
|
||||
termpty_cell_copy(ty, cells, new_ts->cell, ts->w);
|
||||
PUSH_BACK_TS(new_ts);
|
||||
termpty_save_free(ts);
|
||||
if (y2_start < 0)
|
||||
back2[y2_start + ty->backmax] = termpty_save_new(0);
|
||||
return y2_start;
|
||||
}
|
||||
}
|
||||
#undef PUSH_BACK_TS
|
||||
|
||||
ty->backpos = new_back_pos;
|
||||
ty->backscroll_num = new_back_scroll_num;
|
||||
if (ty->backscroll_num >= ty->backmax)
|
||||
ty->backscroll_num = ty->backmax - 1;
|
||||
free(ty->back);
|
||||
ty->back = new_back;
|
||||
|
||||
shrink_screen:
|
||||
|
||||
if (ty->altbuf)
|
||||
if (-y2_start > ty->backmax)
|
||||
{
|
||||
termpty_save_thaw();
|
||||
return;
|
||||
}
|
||||
|
||||
ty->circular_offset = 0;
|
||||
|
||||
/* TODO double-width :) */
|
||||
x = 0;
|
||||
y = 0;
|
||||
|
||||
if (old_ts)
|
||||
{
|
||||
termpty_cell_copy(ty, old_cells, ty->screen, old_ts->w);
|
||||
x = old_ts->w;
|
||||
if (!rewrapping) y++;
|
||||
termpty_save_free(old_ts);
|
||||
old_ts = NULL;
|
||||
old_cells = NULL;
|
||||
}
|
||||
screen_height_used = old_h;
|
||||
screen_lengths = malloc(sizeof(ssize_t) * old_h);
|
||||
for (old_y = old_h - 1; old_y >= 0; old_y--)
|
||||
{
|
||||
screen_lengths[old_y] = termpty_line_length(&OLD_SCREEN(0, old_y), old_w);
|
||||
|
||||
if (!screen_lengths[old_y] && done != EINA_TRUE)
|
||||
screen_height_used--;
|
||||
else
|
||||
done = EINA_TRUE;
|
||||
}
|
||||
|
||||
for (old_y = 0; old_y < screen_height_used; old_y++)
|
||||
{
|
||||
ssize_t cur_line_length;
|
||||
int remaining_width, len;
|
||||
|
||||
cur_line_length = screen_lengths[old_y];
|
||||
|
||||
if (old_y == ty->state.cy)
|
||||
ty->state.cy = y;
|
||||
|
||||
old_x = 0;
|
||||
do
|
||||
{
|
||||
Eina_Bool need_new_line = EINA_FALSE;
|
||||
|
||||
remaining_width = ty->w - x;
|
||||
len = MIN(remaining_width, cur_line_length);
|
||||
termpty_cell_copy(ty,
|
||||
&OLD_SCREEN(old_x, old_y),
|
||||
&TERMPTY_SCREEN(ty, x, y),
|
||||
len);
|
||||
x += len;
|
||||
old_x += len;
|
||||
cur_line_length -= len;
|
||||
if (cur_line_length > 0)
|
||||
{
|
||||
TERMPTY_SCREEN(ty, x - 1, y).att.autowrapped = 1;
|
||||
need_new_line = EINA_TRUE;
|
||||
y_start += ((-y2_start - ty->backmax) * w2) / ty->w;
|
||||
x = ((-y2_start - ty->backmax) * w2) % ty->w;
|
||||
len_remaining -= (-y2_start - ty->backmax) * w2;
|
||||
y2_start = -ty->backmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
Termcell *cell = &TERMPTY_SCREEN(ty, x - 1, y);
|
||||
if (cell->att.autowrapped)
|
||||
{
|
||||
if (x >= ty->w)
|
||||
need_new_line = EINA_TRUE;
|
||||
else
|
||||
{
|
||||
cell->att.autowrapped = 0;
|
||||
need_new_line = EINA_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (old_y < old_h - 1)
|
||||
need_new_line = EINA_TRUE;
|
||||
}
|
||||
}
|
||||
if (need_new_line)
|
||||
{
|
||||
x = 0;
|
||||
if (y >= ty->h - 1)
|
||||
{
|
||||
Termcell *cells;
|
||||
|
||||
ty->circular_offset++;
|
||||
if (ty->circular_offset >= ty->h)
|
||||
ty->circular_offset = 0;
|
||||
cells = &TERMPTY_SCREEN(ty, 0, y);
|
||||
len = termpty_line_length(cells, ty->w);
|
||||
termpty_text_save_top(ty, cells, len);
|
||||
termpty_cell_fill(ty, NULL, cells, len);
|
||||
if (ty->state.cy == old_y || cy_pushed_back)
|
||||
{
|
||||
cy_pushed_back = EINA_TRUE;
|
||||
ty->state.cy--;
|
||||
}
|
||||
y = y_start;
|
||||
x2 = 0;
|
||||
y2 = y2_start;
|
||||
|
||||
while (y <= y_end)
|
||||
{
|
||||
if (y >= 0)
|
||||
{
|
||||
line = &TERMPTY_SCREEN(ty, 0, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts = termpty_save_extract(ty->back[(y + ty->backpos +
|
||||
ty->backmax) % ty->backmax]);
|
||||
ty->back[(y + ty->backpos + ty->backmax) % ty->backmax] = ts;
|
||||
line = ts->cell;
|
||||
}
|
||||
if (y == y_end)
|
||||
len = len_last;
|
||||
else
|
||||
len = ty->w;
|
||||
line[len - 1].att.autowrapped = 0;
|
||||
while (x < len)
|
||||
{
|
||||
copy_width = MIN(len - x, w2 - x2);
|
||||
if (x2 == 0)
|
||||
{
|
||||
if (y2 >= 0)
|
||||
{
|
||||
line2 = screen2 + (y2 * w2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts2_width = MIN(len_remaining, w2);
|
||||
ts2 = termpty_save_new(ts2_width);
|
||||
line2 = ts2->cell;
|
||||
back2[y2 + ty->backmax] = ts2;
|
||||
}
|
||||
}
|
||||
termpty_cell_copy(ty, line + x, line2 + x2, copy_width);
|
||||
x += copy_width;
|
||||
x2 += copy_width;
|
||||
len_remaining -= copy_width;
|
||||
if ((x2 == w2) && (y2 != y2_end))
|
||||
{
|
||||
line2[x2 - 1].att.autowrapped = 1;
|
||||
x2 = 0;
|
||||
y2++;
|
||||
}
|
||||
}
|
||||
x = 0;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
while (cur_line_length > 0);
|
||||
}
|
||||
if (ty->state.cy >= ty->h) ty->state.cy = ty->h - 1;
|
||||
else if (ty->state.cy < 0) ty->state.cy = 0;
|
||||
|
||||
termpty_save_thaw();
|
||||
|
||||
free(screen_lengths);
|
||||
|
||||
termpty_save_thaw();
|
||||
return y2_start;
|
||||
}
|
||||
#undef OLD_SCREEN
|
||||
|
||||
|
||||
void
|
||||
termpty_resize(Termpty *ty, int w, int h)
|
||||
termpty_resize(Termpty *ty, int new_w, int new_h)
|
||||
{
|
||||
Termcell *olds, *olds2;
|
||||
int oldw, oldh;
|
||||
Termcell *new_screen;
|
||||
Termsave **new_back;
|
||||
int y_start, y_end, new_y_start, new_y_end;
|
||||
int i;
|
||||
|
||||
if ((ty->w == w) && (ty->h == h)) return;
|
||||
if ((ty->w == new_w) && (ty->h == new_h)) return;
|
||||
if ((new_w == new_h) && (new_w == 1)) return;
|
||||
|
||||
if (w == h && h == 1) // fuck off
|
||||
return;
|
||||
termpty_save_freeze();
|
||||
|
||||
olds = ty->screen;
|
||||
olds2 = ty->screen2;
|
||||
oldw = ty->w;
|
||||
oldh = ty->h;
|
||||
if (ty->altbuf)
|
||||
{
|
||||
termpty_screen_swap(ty);
|
||||
ty->altbuf = 1;
|
||||
}
|
||||
|
||||
ty->w = w;
|
||||
ty->h = h;
|
||||
ty->state.had_cr = 0;
|
||||
|
||||
ty->screen = calloc(1, sizeof(Termcell) * ty->w * ty->h);
|
||||
new_screen = calloc(1, sizeof(Termcell) * new_w * new_h);
|
||||
if (!ty->screen)
|
||||
{
|
||||
ty->screen2 = NULL;
|
||||
ERR("memerr");
|
||||
}
|
||||
ty->screen2 = calloc(1, sizeof(Termcell) * ty->w * ty->h);
|
||||
free(ty->screen2);
|
||||
ty->screen2 = calloc(1, sizeof(Termcell) * new_w * new_h);
|
||||
if (!ty->screen2)
|
||||
{
|
||||
ERR("memerr");
|
||||
}
|
||||
new_back = calloc(sizeof(Termsave *), ty->backmax);
|
||||
|
||||
/* Shrink vertically, in place, if needed */
|
||||
if (ty->h < oldh)
|
||||
y_end = ty->state.cy;
|
||||
y_start = termpty_line_find_top(ty, ty->state.cy);
|
||||
new_y_start = new_h - 1 - (y_end - y_start);
|
||||
new_y_end = new_y_start - 1;
|
||||
y_end = y_start - 1;
|
||||
if (new_y_end < 0)
|
||||
new_y_end = -1;
|
||||
while ((y_end >= -ty->backscroll_num) && (new_y_end >= -ty->backmax))
|
||||
{
|
||||
_termpty_vertically_shrink(ty, oldw, oldh, olds);
|
||||
oldh = ty->h;
|
||||
y_start = termpty_line_find_top(ty, y_end);
|
||||
new_y_start = termpty_line_rewrap(ty, y_start, y_end, new_screen,
|
||||
new_back, new_w, new_h, new_y_end);
|
||||
y_end = y_start - 1;
|
||||
new_y_end = new_y_start - 1;
|
||||
}
|
||||
|
||||
if (oldw != ty->w)
|
||||
free(ty->screen);
|
||||
for (i = 1; i <= ty->backscroll_num; i++)
|
||||
termpty_save_free(ty->back[(ty->backpos - i + ty->backmax) % ty->backmax]);
|
||||
free(ty->back);
|
||||
|
||||
ty->w = new_w;
|
||||
ty->h = new_h;
|
||||
ty->state.cy = MIN((new_h - 1) - new_y_start, new_h - 1);
|
||||
ty->circular_offset = MAX(new_y_start, 0);
|
||||
ty->backpos = 0;
|
||||
ty->backscroll_num = MAX(-new_y_start, 0);
|
||||
ty->state.had_cr = 0;
|
||||
ty->screen = new_screen;
|
||||
ty->back = new_back;
|
||||
|
||||
if (ty->altbuf)
|
||||
{
|
||||
if (ty->w > oldw)
|
||||
_termpty_horizontally_expand(ty, oldw, oldh, olds);
|
||||
else
|
||||
_termpty_horizontally_shrink(ty, oldw, oldh, olds);
|
||||
|
||||
free(olds); olds = NULL;
|
||||
free(olds2); olds2 = NULL;
|
||||
termpty_screen_swap(ty);
|
||||
ty->altbuf = 1;
|
||||
}
|
||||
|
||||
if (ty->h > oldh)
|
||||
_termpty_vertically_expand(ty, oldw, oldh, olds);
|
||||
|
||||
free(olds);
|
||||
free(olds2);
|
||||
|
||||
_limit_coord(ty, &(ty->state));
|
||||
_limit_coord(ty, &(ty->swap));
|
||||
_limit_coord(ty, &(ty->save));
|
||||
|
||||
_pty_size(ty);
|
||||
|
||||
termpty_save_thaw();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1484,31 +999,25 @@ termpty_cell_copy(Termpty *ty, Termcell *src, Termcell *dst, int n)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_swap_line(Termpty *ty, Termcell *cells, Termcell *cells2)
|
||||
{
|
||||
int x;
|
||||
Termcell c;
|
||||
|
||||
for (x = 0; x < ty->w; x++)
|
||||
{
|
||||
c = cells[x];
|
||||
cells[x] = cells2[x];
|
||||
cells2[x] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
termpty_screen_swap(Termpty *ty)
|
||||
{
|
||||
int y;
|
||||
Termcell *tmp_screen;
|
||||
Termstate tmp_state;
|
||||
int tmp_circular_offset;
|
||||
|
||||
tmp_screen = ty->screen;
|
||||
ty->screen = ty->screen2;
|
||||
ty->screen2 = tmp_screen;
|
||||
|
||||
tmp_state = ty->state;
|
||||
ty->state = ty->swap;
|
||||
ty->swap = tmp_state;
|
||||
|
||||
tmp_circular_offset = ty->circular_offset;
|
||||
ty->circular_offset = ty->circular_offset2;
|
||||
ty->circular_offset2 = tmp_circular_offset;
|
||||
|
||||
for (y = 0; y < ty->h; y++)
|
||||
{
|
||||
_swap_line(ty,
|
||||
&(TERMPTY_SCREEN(ty, 0, y)),
|
||||
&ty->screen2[y * ty->w]);
|
||||
}
|
||||
ty->altbuf = !ty->altbuf;
|
||||
|
||||
if (ty->cb.cancel_sel.func)
|
||||
|
|
|
@ -123,6 +123,7 @@ struct _Termpty
|
|||
int w, h;
|
||||
int fd, slavefd;
|
||||
int circular_offset;
|
||||
int circular_offset2;
|
||||
int backmax, backpos;
|
||||
int backscroll_num;
|
||||
struct {
|
||||
|
|
|
@ -835,20 +835,12 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
|
|||
handled = 1;
|
||||
DBG("DDD: switch buf");
|
||||
if (ty->altbuf)
|
||||
{
|
||||
// if we are looking at alt buf now,
|
||||
// clear main buf before we swap it back
|
||||
// into the screen2 save (so save is
|
||||
// clear)
|
||||
_termpty_clear_all(ty);
|
||||
// _termpty_cursor_copy(&(ty->swap), &(ty->state));
|
||||
ty->state = ty->swap;
|
||||
}
|
||||
else
|
||||
{
|
||||
// _termpty_cursor_copy(&(ty->state), &(ty->swap));
|
||||
ty->swap = ty->state;
|
||||
}
|
||||
|
||||
// swap screen content now
|
||||
termpty_screen_swap(ty);
|
||||
break;
|
||||
|
|
|
@ -55,7 +55,7 @@ termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max)
|
|||
ty->backpos++;
|
||||
if (ty->backpos >= ty->backmax) ty->backpos = 0;
|
||||
ty->backscroll_num++;
|
||||
if (ty->backscroll_num >= ty->backmax) ty->backscroll_num = ty->backmax - 1;
|
||||
if (ty->backscroll_num >= ty->backmax) ty->backscroll_num = ty->backmax;
|
||||
termpty_save_thaw();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue