void termpty_text_save_top(Termpty *ty, Termcell *cells, ssize_t w_max) { Termsave *ts; ssize_t w; if (ty->backmax <= 0) return; termpty_save_freeze(); w = termpty_line_length(cells, w_max); ts = termpty_save_new(w); termpty_cell_copy(ty, cells, ts->cell, w); if (!ty->back) ty->back = calloc(1, sizeof(Termsave *) * ty->backmax); if (ty->back[ty->backpos]) { Termsave *ts2; ts2 = termpty_save_extract(ty->back[ty->backpos]); termpty_save_free(ts2); ty->back[ty->backpos] = NULL; } ty->back[ty->backpos] = ts; ty->backpos++; if (ty->backpos >= ty->backmax) ty->backpos = 0; ty->backscroll_num++; if (ty->backscroll_num >= ty->backmax) ty->backscroll_num = ty->backmax; termpty_save_thaw(); }
void _termpty_text_scroll(Termpty *ty, Eina_Bool clear) { Termcell *cells = NULL, *cells2; int y, start_y = 0, end_y = ty->h - 1; if (ty->state.scroll_y2 != 0) { start_y = ty->state.scroll_y1; end_y = ty->state.scroll_y2 - 1; } else if (!ty->altbuf) termpty_text_save_top(ty, &(TERMPTY_SCREEN(ty, 0, 0)), ty->w); termio_scroll(ty->obj, -1, start_y, end_y); DBG("... scroll!!!!! [%i->%i]", start_y, end_y); if (start_y == 0 && end_y == ty->h - 1) { // screen is a circular buffer now cells = &(ty->screen[ty->circular_offset * ty->w]); if (clear) _text_clear(ty, cells, ty->w, 0, EINA_TRUE); ty->circular_offset++; if (ty->circular_offset >= ty->h) ty->circular_offset = 0; } else { cells = &(TERMPTY_SCREEN(ty, 0, end_y)); for (y = start_y; y < end_y; y++) { cells = &(TERMPTY_SCREEN(ty, 0, (y + 1))); cells2 = &(TERMPTY_SCREEN(ty, 0, y)); termpty_cell_copy(ty, cells, cells2, ty->w); } if (clear) _text_clear(ty, cells, ty->w, 0, EINA_TRUE); } }
void _termpty_text_scroll_rev(Termpty *ty, Eina_Bool clear) { Termcell *cells, *cells2 = NULL; int y, start_y = 0, end_y = ty->h - 1; if (ty->state.scroll_y2 != 0) { start_y = ty->state.scroll_y1; end_y = ty->state.scroll_y2 - 1; } DBG("... scroll rev!!!!! [%i->%i]", start_y, end_y); termio_scroll(ty->obj, 1, start_y, end_y); if (start_y == 0 && end_y == ty->h - 1) { // screen is a circular buffer now ty->circular_offset--; if (ty->circular_offset < 0) ty->circular_offset = ty->h - 1; cells = &(ty->screen[ty->circular_offset * ty->w]); if (clear) _text_clear(ty, cells, ty->w, 0, EINA_TRUE); } else { cells = &(TERMPTY_SCREEN(ty, 0, end_y)); for (y = end_y; y > start_y; y--) { cells = &(TERMPTY_SCREEN(ty, 0, (y - 1))); cells2 = &(TERMPTY_SCREEN(ty, 0, y)); termpty_cell_copy(ty, cells, cells2, ty->w); } y = start_y; if (clear) _text_clear(ty, cells, ty->w, 0, EINA_TRUE); } }
void _termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len) { Termcell *cells; int i, j; termio_content_change(ty->obj, ty->state.cx, ty->state.cy, len); cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy)); for (i = 0; i < len; i++) { Eina_Unicode g; if (ty->state.wrapnext) { cells[ty->w - 1].att.autowrapped = 1; ty->state.wrapnext = 0; ty->state.cx = 0; ty->state.cy++; _termpty_text_scroll_test(ty, EINA_TRUE); cells = &(TERMPTY_SCREEN(ty, 0, ty->state.cy)); } if (ty->state.insert) { for (j = ty->w - 1; j > ty->state.cx; j--) termpty_cell_copy(ty, &(cells[j - 1]), &(cells[j]), 1); } g = _termpty_charset_trans(codepoints[i], ty->state.charsetch); termpty_cell_codepoint_att_fill(ty, g, ty->state.att, &(cells[ty->state.cx]), 1); #if defined(SUPPORT_DBLWIDTH) cells[ty->state.cx].att.dblwidth = _termpty_is_dblwidth_get(ty, g); if (EINA_UNLIKELY((cells[ty->state.cx].att.dblwidth) && (ty->state.cx < (ty->w - 1)))) { TERMPTY_FMTCLR(cells[ty->state.cx].att); termpty_cell_codepoint_att_fill(ty, 0, cells[ty->state.cx].att, &(cells[ty->state.cx + 1]), 1); } #endif if (ty->state.wrap) { unsigned char offset = 1; ty->state.wrapnext = 0; #if defined(SUPPORT_DBLWIDTH) if (EINA_UNLIKELY(cells[ty->state.cx].att.dblwidth)) offset = 2; #endif if (EINA_UNLIKELY(ty->state.cx >= (ty->w - offset))) ty->state.wrapnext = 1; else ty->state.cx += offset; } else { unsigned char offset = 1; ty->state.wrapnext = 0; #if defined(SUPPORT_DBLWIDTH) if (EINA_UNLIKELY(cells[ty->state.cx].att.dblwidth)) offset = 2; #endif ty->state.cx += offset; if (ty->state.cx > (ty->w - offset)) { ty->state.cx = ty->w - offset; return; } } } }
void termpty_text_append(Termpty *ty, const Eina_Unicode *codepoints, int len) { Termcell *cells; int i, j; termio_content_change(ty->obj, ty->cursor_state.cx, ty->cursor_state.cy, len); cells = &(TERMPTY_SCREEN(ty, 0, ty->cursor_state.cy)); for (i = 0; i < len; i++) { Eina_Unicode g; if (ty->termstate.wrapnext) { cells[ty->w - 1].att.autowrapped = 1; ty->termstate.wrapnext = 0; ty->cursor_state.cx = 0; ty->cursor_state.cy++; termpty_text_scroll_test(ty, EINA_TRUE); cells = &(TERMPTY_SCREEN(ty, 0, ty->cursor_state.cy)); } if (ty->termstate.insert) { for (j = ty->w - 1; j > ty->cursor_state.cx; j--) termpty_cell_copy(ty, &(cells[j - 1]), &(cells[j]), 1); } g = _termpty_charset_trans(codepoints[i], ty); /* Skip 0-width space */ if (EINA_UNLIKELY(g == 0x200b)) { continue; } if (EINA_UNLIKELY(g >= 0x300 && g <=0x36f)) { /* combining chars */ if (EINA_UNLIKELY(g == 0x336)) { ty->termstate.combining_strike = 1; } continue; } termpty_cell_codepoint_att_fill(ty, g, ty->termstate.att, &(cells[ty->cursor_state.cx]), 1); if (EINA_UNLIKELY(ty->termstate.combining_strike)) { ty->termstate.combining_strike = 0; cells[ty->cursor_state.cx].att.strike = 1; } cells[ty->cursor_state.cx].att.dblwidth = _termpty_is_dblwidth_get(ty, g); if (EINA_UNLIKELY((cells[ty->cursor_state.cx].att.dblwidth) && (ty->cursor_state.cx < (ty->w - 1)))) { TERMPTY_FMTCLR(cells[ty->cursor_state.cx].att); termpty_cell_codepoint_att_fill(ty, 0, cells[ty->cursor_state.cx].att, &(cells[ty->cursor_state.cx + 1]), 1); } if (ty->termstate.wrap) { unsigned char offset = 1; ty->termstate.wrapnext = 0; if (EINA_UNLIKELY(cells[ty->cursor_state.cx].att.dblwidth)) offset = 2; if (EINA_UNLIKELY(ty->cursor_state.cx >= (ty->w - offset))) ty->termstate.wrapnext = 1; else { ty->cursor_state.cx += offset; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); } } else { unsigned char offset = 1; ty->termstate.wrapnext = 0; if (EINA_UNLIKELY(cells[ty->cursor_state.cx].att.dblwidth)) offset = 2; ty->cursor_state.cx += offset; if (ty->cursor_state.cx > (ty->w - offset)) { ty->cursor_state.cx = ty->w - offset; TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); return; } TERMPTY_RESTRICT_FIELD(ty->cursor_state.cx, 0, ty->w); } } }