From: Ali Gholami Rudi Date: Fri, 18 May 2012 09:47:48 +0000 (+0430) Subject: term: support scrolling history X-Git-Url: https://repo.or.cz/w/fbpad.git/commitdiff_plain/b33117b2bbf300ecfc5a0279e86579effa056627 term: support scrolling history This is based on an older patch on the bold branch which was suggested and tested by: Sara Fauzia . --- diff --git a/README b/README index b363e14..9e3e9ef 100644 --- a/README +++ b/README @@ -22,6 +22,8 @@ m-s create a text screenshot (SCRSHOT) m-y redraw terminal c-m-l lock the screen; use PASS to unlock c-m-q quit fbpad +m-, scroll up +m-. scroll down ============== ======================================= Fbpad can be instructed to execute a single program: the program and diff --git a/fbpad.c b/fbpad.c index 7ae8f55..447101d 100644 --- a/fbpad.c +++ b/fbpad.c @@ -21,7 +21,7 @@ #include "draw.h" #define CTRLKEY(x) ((x) - 96) -#define BADPOLLFLAGS (POLLHUP | POLLERR | POLLNVAL) +#define POLLFLAGS (POLLIN | POLLHUP | POLLERR | POLLNVAL) #define NTAGS (sizeof(tags) - 1) #define NTERMS (NTAGS * 2) #define TERMOPEN(i) (terms[i].fd) @@ -38,6 +38,7 @@ static int locked; static char pass[1024]; static int passlen; static int cmdmode; /* execute a command and exit */ +static int histpos; /* scrolling history */ static int readchar(void) { @@ -61,6 +62,8 @@ static void term_switch(int oidx, int nidx, int show, int save, int load) if (show && load && TERMOPEN(nidx) && TERMSNAP(nidx)) flags = scr_load(&terms[nidx]) ? TERM_REDRAW : TERM_VISIBLE; term_load(&terms[nidx], flags); + if (show && load) + histpos = 0; } static void showterm(int n) @@ -191,6 +194,14 @@ static void directkey(void) locked = 1; passlen = 0; return; + case ',': + histpos = MIN(NHIST, histpos + pad_rows() / 2); + term_hist(histpos); + return; + case '.': + histpos = MAX(0, histpos - pad_rows() / 2); + term_hist(histpos); + return; default: if (strchr(tags, c)) { showtag(strchr(tags, c) - tags); @@ -200,6 +211,7 @@ static void directkey(void) term_send(ESC); } } + histpos = 0; if (c != -1 && mainterm()) term_send(c); } @@ -233,15 +245,17 @@ static int poll_all(void) } if (poll(ufds, n, 1000) < 1) return 0; - if (ufds[0].revents & BADPOLLFLAGS) + if (ufds[0].revents & (POLLFLAGS & ~POLLIN)) return 1; if (ufds[0].revents & POLLIN) directkey(); for (i = 1; i < n; i++) { + if (!(ufds[i].revents & POLLFLAGS)) + continue; temp_switch(term_idx[i]); - if (ufds[i].revents & POLLIN) + if (ufds[i].revents & POLLIN) { term_read(); - if (ufds[i].revents & BADPOLLFLAGS) { + } else { scr_free(&terms[term_idx[i]]); term_end(); if (cmdmode) diff --git a/fbpad.h b/fbpad.h index 0900777..57fd6d8 100644 --- a/fbpad.h +++ b/fbpad.h @@ -2,10 +2,13 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define LEN(a) (sizeof(a) / sizeof((a)[0])) #define ESC 27 /* escape code */ -#define MAXCHARS (1 << 15) /* maximum characters on screen */ -#define MAXDOTS (1 << 10) /* maximum pixels in glyphs */ +#define NCOLS 256 /* maximum number of screen columns */ +#define NROWS 128 /* maximum number of screen rows */ +#define NDOTS 1024 /* maximum pixels in glyphs */ +#define NHIST 32 /* scrolling history lines */ /* isdw.c */ #define DWCHAR 0x40000000u /* 2nd half of a fullwidth char */ @@ -25,9 +28,10 @@ struct term_state { }; struct term { - int screen[MAXCHARS]; - char fgs[MAXCHARS]; - char bgs[MAXCHARS]; + int screen[NROWS * NCOLS]; + int hist[NHIST * NCOLS]; + char fgs[NROWS * NCOLS]; + char bgs[NROWS * NCOLS]; struct term_state cur, sav; int fd; int pid; @@ -42,6 +46,7 @@ void term_send(int c); void term_exec(char **args); void term_end(void); void term_screenshot(void); +void term_hist(int pos); /* pad.c */ #define FN_I 0x10 diff --git a/isdw.c b/isdw.c index daf1e64..5abaa24 100644 --- a/isdw.c +++ b/isdw.c @@ -1,7 +1,5 @@ #include "fbpad.h" -#define LEN(a) (sizeof(a) / sizeof((a)[0])) - static int dwchars[][2] = { {0x1100, 0x115f}, {0x11a3, 0x11a7}, {0x11fa, 0x11ff}, {0x2329, 0x232a}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, diff --git a/pad.c b/pad.c index 2d306c1..89d952d 100644 --- a/pad.c +++ b/pad.c @@ -70,7 +70,7 @@ static unsigned color2fb(int c) return FB_VAL(CR(cd[c]), CG(cd[c]), CB(cd[c])); } -static fbval_t cache[NCACHE][MAXDOTS]; +static fbval_t cache[NCACHE][NDOTS]; static struct glyph { int c; short fg, bg; @@ -112,7 +112,7 @@ static void bmp2fb(fbval_t *d, char *s, int fg, int bg, int nr, int nc) static fbval_t *ch2fb(int fn, int c, short fg, short bg) { - char bits[MAXDOTS]; + char bits[NDOTS]; fbval_t *fbbits; if (c < 0 || (c < 128 && (!isprint(c) || isspace(c)))) return NULL; diff --git a/term.c b/term.c index a36a315..b266c10 100644 --- a/term.c +++ b/term.c @@ -316,6 +316,7 @@ void term_exec(char **args) fcntl(term->fd, F_SETFD, fcntl(term->fd, F_GETFD) | FD_CLOEXEC); fcntl(term->fd, F_SETFL, fcntl(term->fd, F_GETFL) | O_NONBLOCK); term_reset(); + memset(term->hist, 0, sizeof(term->hist)); } static void misc_save(struct term_state *state) @@ -430,9 +431,44 @@ static void blank_rows(int sr, int er) draw_cursor(1); } +static void scrl_rows(int nr) +{ + int nc = nr * pad_cols(); + memmove(term->hist, term->hist + nc, + (LEN(term->hist) - nc) * sizeof(term->hist[0])); + memcpy(term->hist + LEN(term->hist) - nc, term->screen, + nc * sizeof(term->hist[0])); +} + +void term_hist(int scrl) +{ + int i, j; + int *_scr; + char *_fgs, *_bgs; + lazy_start(); + memset(dirty, 1, sizeof(dirty)); + for (i = 0; i < pad_rows(); i++) { + int off = (i - scrl) * pad_cols(); + if (i < scrl) { + _scr = term->hist + LEN(term->hist) + off; + _fgs = NULL; + _bgs = NULL; + } else { + _scr = term->screen + off; + _fgs = term->fgs + off; + _bgs = term->bgs + off; + } + for (j = 0; j < pad_cols(); j++) + pad_put(_scr[j], i, j, _fgs ? _fgs[j] : BGCOLOR, + _bgs ? _bgs[j] : FGCOLOR); + } +} + static void scroll_screen(int sr, int nr, int n) { draw_cursor(0); + if (sr + n == 0) + scrl_rows(sr); screen_move(OFFSET(sr + n, 0), OFFSET(sr, 0), nr * pad_cols()); if (n > 0) empty_rows(sr, sr + n);