forked from enlightenment/terminology
terminology: use a circular buffer for the screen.
SVN revision: 83012
This commit is contained in:
parent
de8b44d645
commit
61576f1496
|
@ -255,6 +255,8 @@ termpty_new(const char *cmd, Eina_Bool login_shell, const char *cd, int w, int h
|
||||||
ty->screen2 = calloc(1, sizeof(Termcell) * ty->w * ty->h);
|
ty->screen2 = calloc(1, sizeof(Termcell) * ty->w * ty->h);
|
||||||
if (!ty->screen2) goto err;
|
if (!ty->screen2) goto err;
|
||||||
|
|
||||||
|
ty->circular_offset = 0;
|
||||||
|
|
||||||
ty->fd = posix_openpt(O_RDWR | O_NOCTTY);
|
ty->fd = posix_openpt(O_RDWR | O_NOCTTY);
|
||||||
if (ty->fd < 0) goto err;
|
if (ty->fd < 0) goto err;
|
||||||
if (grantpt(ty->fd) != 0) goto err;
|
if (grantpt(ty->fd) != 0) goto err;
|
||||||
|
@ -442,7 +444,7 @@ termpty_cellrow_get(Termpty *ty, int y, int *wret)
|
||||||
{
|
{
|
||||||
if (y >= ty->h) return NULL;
|
if (y >= ty->h) return NULL;
|
||||||
*wret = ty->w;
|
*wret = ty->w;
|
||||||
return &(ty->screen[y * ty->w]);
|
return &(TERMPTY_SCREEN(ty, 0, y));
|
||||||
}
|
}
|
||||||
if (y < -ty->backmax) return NULL;
|
if (y < -ty->backmax) return NULL;
|
||||||
ts = ty->back[(ty->backmax + ty->backpos + y) % ty->backmax];
|
ts = ty->back[(ty->backmax + ty->backpos + y) % ty->backmax];
|
||||||
|
@ -495,12 +497,13 @@ termpty_resize(Termpty *ty, int w, int h)
|
||||||
if (ww > oldw) ww = oldw;
|
if (ww > oldw) ww = oldw;
|
||||||
if (hh > oldh) hh = oldh;
|
if (hh > oldh) hh = oldh;
|
||||||
|
|
||||||
|
// FIXME: handle pointer copy here
|
||||||
for (y = 0; y < hh; y++)
|
for (y = 0; y < hh; y++)
|
||||||
{
|
{
|
||||||
Termcell *c1, *c2;
|
Termcell *c1, *c2;
|
||||||
|
|
||||||
c1 = &(olds[y * oldw]);
|
c1 = &(olds[y * oldw]);
|
||||||
c2 = &(ty->screen[y * ty->w]);
|
c2 = &(TERMPTY_SCREEN(ty, 0, y));
|
||||||
_termpty_text_copy(ty, c1, c2, ww);
|
_termpty_text_copy(ty, c1, c2, ww);
|
||||||
|
|
||||||
c1 = &(olds2[y * oldw]);
|
c1 = &(olds2[y * oldw]);
|
||||||
|
@ -508,6 +511,7 @@ termpty_resize(Termpty *ty, int w, int h)
|
||||||
_termpty_text_copy(ty, c1, c2, ww);
|
_termpty_text_copy(ty, c1, c2, ww);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty->circular_offset = 0;
|
||||||
free(olds);
|
free(olds);
|
||||||
free(olds2);
|
free(olds2);
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ struct _Termpty
|
||||||
const char *cur_cmd;
|
const char *cur_cmd;
|
||||||
Termcell *screen, *screen2;
|
Termcell *screen, *screen2;
|
||||||
Termsave **back;
|
Termsave **back;
|
||||||
|
int circular_offset;
|
||||||
int backmax, backpos;
|
int backmax, backpos;
|
||||||
int backscroll_num;
|
int backscroll_num;
|
||||||
int *buf;
|
int *buf;
|
||||||
|
@ -141,3 +142,6 @@ void termpty_backscroll_set(Termpty *ty, int size);
|
||||||
pid_t termpty_pid_get(const Termpty *ty);
|
pid_t termpty_pid_get(const Termpty *ty);
|
||||||
|
|
||||||
extern int _termpty_log_dom;
|
extern int _termpty_log_dom;
|
||||||
|
|
||||||
|
#define TERMPTY_SCREEN(Tpty, X, Y) \
|
||||||
|
Tpty->screen[X + (((Y + Tpty->circular_offset) % Tpty->h) * Tpty->w)]
|
||||||
|
|
|
@ -456,7 +456,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
|
||||||
int x, lim;
|
int x, lim;
|
||||||
|
|
||||||
if (arg < 1) arg = 1;
|
if (arg < 1) arg = 1;
|
||||||
cells = &(ty->screen[ty->state.cy * ty->w]);
|
cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy));
|
||||||
lim = ty->w - arg;
|
lim = ty->w - arg;
|
||||||
for (x = ty->state.cx; x < (ty->w); x++)
|
for (x = ty->state.cx; x < (ty->w); x++)
|
||||||
{
|
{
|
||||||
|
@ -705,8 +705,8 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
|
||||||
{
|
{
|
||||||
Termcell t;
|
Termcell t;
|
||||||
|
|
||||||
t = ty->screen[i];
|
t = ty->screen[(i + ty->circular_offset) % ty->h];
|
||||||
ty->screen[i] = ty->screen2[i];
|
ty->screen[(i + ty->circular_offset) % ty->h] = ty->screen2[i];
|
||||||
ty->screen2[i] = t;
|
ty->screen2[i] = t;
|
||||||
}
|
}
|
||||||
ty->altbuf = !ty->altbuf;
|
ty->altbuf = !ty->altbuf;
|
||||||
|
@ -846,7 +846,7 @@ _handle_esc_csi(Termpty *ty, const Eina_Unicode *c, Eina_Unicode *ce)
|
||||||
size = ty->w * cy + cx + 1;
|
size = ty->w * cy + cx + 1;
|
||||||
for (idx = size - 1; idx >= 0; idx--)
|
for (idx = size - 1; idx >= 0; idx--)
|
||||||
{
|
{
|
||||||
if (ty->screen[cx + (cy * ty->w)].att.tab) arg--;
|
if (TERMPTY_SCREEN(ty, cx, cy).att.tab) arg--;
|
||||||
cx--;
|
cx--;
|
||||||
if (cx < 0)
|
if (cx < 0)
|
||||||
{
|
{
|
||||||
|
@ -1211,7 +1211,7 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce)
|
||||||
return 1;
|
return 1;
|
||||||
case 0x09: // HT '\t' (horizontal tab)
|
case 0x09: // HT '\t' (horizontal tab)
|
||||||
DBG("->HT");
|
DBG("->HT");
|
||||||
ty->screen[ty->state.cx + (ty->state.cy * ty->w)].att.tab = 1;
|
TERMPTY_SCREEN(ty, ty->state.cx, ty->state.cy).att.tab = 1;
|
||||||
ty->state.wrapnext = 0;
|
ty->state.wrapnext = 0;
|
||||||
ty->state.cx += 8;
|
ty->state.cx += 8;
|
||||||
ty->state.cx = (ty->state.cx / 8) * 8;
|
ty->state.cx = (ty->state.cx / 8) * 8;
|
||||||
|
@ -1224,7 +1224,7 @@ _termpty_handle_seq(Termpty *ty, Eina_Unicode *c, Eina_Unicode *ce)
|
||||||
case 0x0c: // FF '\f' (form feed)
|
case 0x0c: // FF '\f' (form feed)
|
||||||
DBG("->LF");
|
DBG("->LF");
|
||||||
if (ty->state.had_cr)
|
if (ty->state.had_cr)
|
||||||
ty->screen[ty->state.had_cr_x + (ty->state.had_cr_y * ty->w)].att.newline = 1;
|
TERMPTY_SCREEN(ty, ty->state.had_cr_x, ty->state.had_cr_y).att.newline = 1;
|
||||||
ty->state.wrapnext = 0;
|
ty->state.wrapnext = 0;
|
||||||
if (ty->state.crlf) ty->state.cx = 0;
|
if (ty->state.crlf) ty->state.cx = 0;
|
||||||
ty->state.cy++;
|
ty->state.cy++;
|
||||||
|
|
|
@ -50,7 +50,7 @@ _text_save_top(Termpty *ty)
|
||||||
if (ty->backmax <= 0) return;
|
if (ty->backmax <= 0) return;
|
||||||
ts = malloc(sizeof(Termsave) + ((ty->w - 1) * sizeof(Termcell)));
|
ts = malloc(sizeof(Termsave) + ((ty->w - 1) * sizeof(Termcell)));
|
||||||
ts->w = ty->w;
|
ts->w = ty->w;
|
||||||
_termpty_text_copy(ty, ty->screen, ts->cell, ty->w);
|
_termpty_text_copy(ty, &(TERMPTY_SCREEN(ty, 0, 0)), ts->cell, ty->w);
|
||||||
if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax);
|
if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax);
|
||||||
if (ty->back[ty->backpos]) free(ty->back[ty->backpos]);
|
if (ty->back[ty->backpos]) free(ty->back[ty->backpos]);
|
||||||
ty->back[ty->backpos] = ts;
|
ty->back[ty->backpos] = ts;
|
||||||
|
@ -69,8 +69,8 @@ _termpty_text_copy(Termpty *ty __UNUSED__, Termcell *cells, Termcell *dest, int
|
||||||
void
|
void
|
||||||
_termpty_text_scroll(Termpty *ty)
|
_termpty_text_scroll(Termpty *ty)
|
||||||
{
|
{
|
||||||
Termcell *cells = NULL, *cells2;
|
Termcell /* *cells = NULL, */ *cells2;
|
||||||
int y, start_y = 0, end_y = ty->h - 1;
|
int start_y = 0, end_y = ty->h - 1;
|
||||||
|
|
||||||
if (ty->state.scroll_y2 != 0)
|
if (ty->state.scroll_y2 != 0)
|
||||||
{
|
{
|
||||||
|
@ -89,21 +89,20 @@ _termpty_text_scroll(Termpty *ty)
|
||||||
ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
|
ty->cb.cancel_sel.func(ty->cb.cancel_sel.data);
|
||||||
}
|
}
|
||||||
DBG("... scroll!!!!! [%i->%i]", start_y, end_y);
|
DBG("... scroll!!!!! [%i->%i]", start_y, end_y);
|
||||||
cells2 = &(ty->screen[end_y * ty->w]);
|
// screen is a circular buffer now
|
||||||
for (y = start_y; y < end_y; y++)
|
ty->circular_offset++;
|
||||||
{
|
if (ty->circular_offset >= ty->h)
|
||||||
cells = &(ty->screen[y * ty->w]);
|
ty->circular_offset = 0;
|
||||||
cells2 = &(ty->screen[(y + 1) * ty->w]);
|
|
||||||
_termpty_text_copy(ty, cells2, cells, ty->w);
|
cells2 = &(TERMPTY_SCREEN(ty, 0, end_y));
|
||||||
}
|
|
||||||
_text_clear(ty, cells2, ty->w, ' ', EINA_TRUE);
|
_text_clear(ty, cells2, ty->w, ' ', EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_termpty_text_scroll_rev(Termpty *ty)
|
_termpty_text_scroll_rev(Termpty *ty)
|
||||||
{
|
{
|
||||||
Termcell *cells, *cells2 = NULL;
|
Termcell *cells/* , *cells2 = NULL */;
|
||||||
int y, start_y = 0, end_y = ty->h - 1;
|
int start_y = 0, end_y = ty->h - 1;
|
||||||
|
|
||||||
if (ty->state.scroll_y2 != 0)
|
if (ty->state.scroll_y2 != 0)
|
||||||
{
|
{
|
||||||
|
@ -111,13 +110,12 @@ _termpty_text_scroll_rev(Termpty *ty)
|
||||||
end_y = ty->state.scroll_y2 - 1;
|
end_y = ty->state.scroll_y2 - 1;
|
||||||
}
|
}
|
||||||
DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
|
DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y);
|
||||||
cells = &(ty->screen[end_y * ty->w]);
|
// screen is a circular buffer now
|
||||||
for (y = end_y; y > start_y; y--)
|
ty->circular_offset--;
|
||||||
{
|
if (ty->circular_offset < 0)
|
||||||
cells = &(ty->screen[(y - 1) * ty->w]);
|
ty->circular_offset = ty->h - 1;
|
||||||
cells2 = &(ty->screen[y * ty->w]);
|
|
||||||
_termpty_text_copy(ty, cells, cells2, ty->w);
|
cells = &(TERMPTY_SCREEN(ty, 0, end_y));
|
||||||
}
|
|
||||||
_text_clear(ty, cells, ty->w, ' ', EINA_TRUE);
|
_text_clear(ty, cells, ty->w, ' ', EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +151,7 @@ _termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
|
||||||
Termcell *cells;
|
Termcell *cells;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
cells = &(ty->screen[ty->state.cy * ty->w]);
|
cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy));
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
Eina_Unicode g;
|
Eina_Unicode g;
|
||||||
|
@ -165,7 +163,7 @@ _termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len)
|
||||||
ty->state.cx = 0;
|
ty->state.cx = 0;
|
||||||
ty->state.cy++;
|
ty->state.cy++;
|
||||||
_termpty_text_scroll_test(ty);
|
_termpty_text_scroll_test(ty);
|
||||||
cells = &(ty->screen[ty->state.cy * ty->w]);
|
cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy));
|
||||||
}
|
}
|
||||||
if (ty->state.insert)
|
if (ty->state.insert)
|
||||||
{
|
{
|
||||||
|
@ -235,7 +233,7 @@ _termpty_clear_line(Termpty *ty, Termpty_Clear mode, int limit)
|
||||||
Termcell *cells;
|
Termcell *cells;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
cells = &(ty->screen[ty->state.cy * ty->w]);
|
cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy));
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case TERMPTY_CLR_END:
|
case TERMPTY_CLR_END:
|
||||||
|
@ -260,24 +258,42 @@ _termpty_clear_screen(Termpty *ty, Termpty_Clear mode)
|
||||||
{
|
{
|
||||||
Termcell *cells;
|
Termcell *cells;
|
||||||
|
|
||||||
cells = ty->screen;
|
// FIXME: Handle clear with the new layout
|
||||||
|
cells = &(TERMPTY_SCREEN(ty, 0, 0));
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case TERMPTY_CLR_END:
|
case TERMPTY_CLR_END:
|
||||||
_termpty_clear_line(ty, mode, ty->w);
|
_termpty_clear_line(ty, mode, ty->w);
|
||||||
if (ty->state.cy < (ty->h - 1))
|
if (ty->state.cy < (ty->h - 1))
|
||||||
{
|
{
|
||||||
cells = &(ty->screen[(ty->state.cy + 1) * ty->w]);
|
cells = &(TERMPTY_SCREEN(ty, 0, (ty->state.cy + 1)));
|
||||||
_text_clear(ty, cells, ty->w * (ty->h - ty->state.cy - 1), 0, EINA_TRUE);
|
_text_clear(ty, cells, ty->w * (ty->h - ty->state.cy - 1), 0, EINA_TRUE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TERMPTY_CLR_BEGIN:
|
case TERMPTY_CLR_BEGIN:
|
||||||
if (ty->state.cy > 0)
|
if (ty->state.cy > 0)
|
||||||
_text_clear(ty, cells, ty->w * ty->state.cy, 0, EINA_TRUE);
|
{
|
||||||
|
// First clear from circular > height, then from 0 to circular
|
||||||
|
int y = ty->state.cy + ty->circular_offset;
|
||||||
|
|
||||||
|
if (y < ty->h)
|
||||||
|
{
|
||||||
|
_text_clear(ty, cells, ty->w * ty->state.cy, 0, EINA_TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int yt = y % ty->w;
|
||||||
|
int yb = ty->h - ty->circular_offset;
|
||||||
|
|
||||||
|
_text_clear(ty, cells, ty->w * yb, 0, EINA_TRUE);
|
||||||
|
_text_clear(ty, ty->screen, ty->w * yt, 0, EINA_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
_termpty_clear_line(ty, mode, ty->w);
|
_termpty_clear_line(ty, mode, ty->w);
|
||||||
break;
|
break;
|
||||||
case TERMPTY_CLR_ALL:
|
case TERMPTY_CLR_ALL:
|
||||||
_text_clear(ty, cells, ty->w * ty->h, 0, EINA_TRUE);
|
ty->circular_offset = 0;
|
||||||
|
_text_clear(ty, ty->screen, ty->w * ty->h, 0, EINA_TRUE);
|
||||||
ty->state.scroll_y2 = 0;
|
ty->state.scroll_y2 = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue