static void screen_scroll_down(struct tsm_screen *con, unsigned int num) { unsigned int i, j, max; if (!num) return; max = con->margin_bottom + 1 - con->margin_top; if (num > max) num = max; /* see screen_scroll_up() for an explanation */ if (num > 128) { screen_scroll_down(con, 128); return screen_scroll_down(con, num - 128); } struct line *cache[num]; for (i = 0; i < num; ++i) { cache[i] = con->lines[con->margin_bottom - i]; for (j = 0; j < con->size_x; ++j) cell_init(con, &cache[i]->cells[j]); } if (num < max) { memmove(&con->lines[con->margin_top + num], &con->lines[con->margin_top], (max - num) * sizeof(struct line*)); } memcpy(&con->lines[con->margin_top], cache, num * sizeof(struct line*)); }
SHL_EXPORT void tsm_screen_move_up(struct tsm_screen *con, unsigned int num, bool scroll) { unsigned int diff, size; if (!con || !num) return; screen_inc_age(con); if (con->cursor_y >= con->margin_top) size = con->margin_top; else size = 0; diff = con->cursor_y - size; if (num > diff) { num -= diff; if (scroll) screen_scroll_down(con, num); move_cursor(con, con->cursor_x, size); } else { move_cursor(con, con->cursor_x, con->cursor_y - num); } }
void tsm_screen_scroll_down(struct tsm_screen *con, unsigned int num) { if (!con || !num) return; screen_scroll_down(con, num); }
static void screen_page_down(Screen *s) { int i = 0; for (i = 0; i < lines(s); ++i) { screen_scroll_down(s); } }
static void screen_scroll_down(struct tsm_screen *con, unsigned int num) { unsigned int i, j, max; if (!num) return; /* TODO: more sophisticated ageing */ con->age = con->age_cnt; max = con->margin_bottom + 1 - con->margin_top; if (num > max) num = max; /* see screen_scroll_up() for an explanation */ if (num > 128) { screen_scroll_down(con, 128); return screen_scroll_down(con, num - 128); } struct line *cache[num]; for (i = 0; i < num; ++i) { cache[i] = con->lines[con->margin_bottom - i]; for (j = 0; j < con->size_x; ++j) screen_cell_init(con, &cache[i]->cells[j]); } if (num < max) { memmove(&con->lines[con->margin_top + num], &con->lines[con->margin_top], (max - num) * sizeof(struct line*)); } memcpy(&con->lines[con->margin_top], cache, num * sizeof(struct line*)); if (con->sel_active) { if (!con->sel_start.line && con->sel_start.y >= 0) con->sel_start.y += num; if (!con->sel_end.line && con->sel_end.y >= 0) con->sel_end.y += num; } }
SHL_EXPORT void tsm_screen_scroll_down(struct tsm_screen *con, unsigned int num) { if (!con || !num) return; screen_inc_age(con); screen_scroll_down(con, num); }
/* Read the key press using ncurses, and perform the requested action */ void ScreenHandleInput(Screen *s) { /* this is non-blocking */ int c = getch(); switch(c) { case KEY_UP: screen_scroll_up(s); break; case KEY_DOWN: screen_scroll_down(s); break; case KEY_LEFT: screen_scroll_left(s); break; case KEY_RIGHT: screen_scroll_right(s); break; case KEY_NPAGE: screen_page_down(s); break; case KEY_HOME: screen_home(s); break; case KEY_END: screen_end(s); break; case KEY_PPAGE: screen_page_up(s); break; case KEY_RESIZE: break; case 9: /* TAB */ screen_next_col(s); break; case 353: /* SHIFT+TAB */ screen_prev_col(s); break; case 'p': screen_toggle_pause(s); break; case ERR: break; default: break; } ScreenUpdate(s); }
void tsm_screen_move_up(struct tsm_screen *con, unsigned int num, bool scroll) { unsigned int diff, size; if (!con || !num) return; if (con->cursor_y >= con->margin_top) size = con->margin_top; else size = 0; diff = con->cursor_y - size; if (num > diff) { num -= diff; if (scroll) screen_scroll_down(con, num); con->cursor_y = size; } else { con->cursor_y -= num; } }