term: support scrolling history
authorAli Gholami Rudi <ali@rudi.ir>
Fri, 18 May 2012 09:47:48 +0000 (18 14:17 +0430)
committerAli Gholami Rudi <ali@rudi.ir>
Wed, 14 Aug 2013 15:37:31 +0000 (14 20:07 +0430)
This is based on an older patch on the bold branch which was
suggested and tested by: Sara Fauzia <sfauzia@fas.harvard.edu>.

README
fbpad.c
fbpad.h
isdw.c
pad.c
term.c

diff --git a/README b/README
index b363e14..9e3e9ef 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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 (file)
--- 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);