#include #include #include #include "dat.h" #define INSET 5 /* inset from screen.r to written area */ #define DATEX (INSET+5) /* coordinates of date string */ #define DATEY (INSET+1) #define XOFF (INSET+5) /* offset from corner to picture */ #define YOFF (INSET+20) #define FCWID (MAXX+5) /* width of face, incl. strings */ int FCHT; /* height of face, incl. strings */ Point dp; /* upper left corner of first picture */ Bitmap *b; SRC old, new; int aflag; /* start at end of logfile */ int sflag; /* collapse equal faces */ #define ALARM 15000 void alarmf(void *a, char *s) { USED(a); if(strcmp(s, "alarm") == 0) noted(NCONT); noted(NDFLT); } void main(int argc, char *argv[]) { int n, lastb; uchar buf[14]; char err[ERRLEN]; int fd; Event e; char *log; binit(0, 0, "seemail"); log = "/sys/log/mail"; ARGBEGIN{ case 's': sflag++; break; case 'a': aflag = 1; break; case 'f': log = ARGF(); break; default: error("usage: seemail [-a] [-s] [-fFILE]"); }ARGEND if(argc > 0) log = argv[0]; b = balloc(Rect(0, 0, MAXX, MAXY), 3); /* byte map */ srand(time(0)); start_trail(log); FCHT = (MAXY - 2 + 2*medifont->height); fd = open("/dev/mouse", OREAD); if(fd < 0) error("can't open /dev/mouse"); lastb = 0; notify(alarmf); alarm(ALARM); redraw(); for(;;){ alarm(ALARM); n = read(fd, buf, sizeof buf); alarm(0); if(n == sizeof buf){ if(lastb!=buf[1] && (buf[1]&0x81)) redraw(); lastb = e.mouse.buttons; }else{ errstr(err); if(strcmp(err, "interrupted") != 0) if(strcmp(err, "no error") != 0) error(err); /* else alarm timeout */ Date(0); trail(log); } } exits(0); } void error(char *s) { fprint(2, "seemail: %s\n", s); exits(s); } void redraw(void) { screen.r = bscreenrect(0); bitblt(&screen, screen.r.min, &screen, screen.r, 0); /* cls */ border(&screen, screen.r, 1, F); dp.x = screen.r.min.x + XOFF; dp.y = screen.r.min.y + YOFF; Same = First = 1; Date(1); } void showimage(SRC *From, int Shift) { int nfaceh_1, nfacew_1; /* # faces high and wide, minus 1 */ Rectangle sr; Point dp2; wrbitmap(b, 0, MAXY, &From->pix[0][0]); overwrite(b); if(Shift){ sr = screen.r; sr.min.x += XOFF; sr.min.y += YOFF; sr.max.x -= XOFF; sr.max.y -= YOFF; nfacew_1 = Dx(sr)/FCWID - 1; if(nfacew_1 < 0) nfacew_1 = 0; nfaceh_1 = Dy(sr)/FCHT - 1; if(nfaceh_1 < 0) nfaceh_1 = 0; sr.max.x = sr.min.x + nfacew_1*FCWID; sr.min.y += nfaceh_1*FCHT; sr.max.y = sr.min.y + FCHT; dp2.x = sr.min.x + FCWID; dp2.y = sr.min.y; do{ /* shift faces */ bitblt(&screen, dp2, &screen, sr, S); sr.max.y = sr.min.y; sr.min.y -= FCHT; if(dp2.y > dp.y){ Rectangle nr; nr = sr; nr.min.x += nfacew_1*FCWID; nr.max.x = nr.min.x+FCWID; dp2.x -= FCWID; bitblt(&screen, dp2, &screen, nr, S); dp2.x += FCWID; } dp2.y -= FCHT; }while(dp2.y >= dp.y); nomessage(); } bitblt(&screen, dp, b, b->r, S); /* add new face */ bflush(); } void nomessage(void) { Rectangle dr; dr.min.x = dp.x; dr.min.y = dp.y + MAXY; dr.max.x = dp.x + FCWID; dr.max.y = dp.y + FCHT; bitblt(&screen, dr.min, &screen, dr, 0); } void message(char *buf, char *tm) { itag(0, buf); itag(medifont->height - 2, tm); } void itag(int m, char *buf) { Point p; char *z; z = &buf[strlen(buf)-1]; while(strwidth(medifont,buf) > FCWID) *z-- = '\0'; p.x = dp.x + (FCWID-strwidth(medifont, buf))/2; p.y = dp.y + MAXY + m; string(&screen, p, medifont, buf, S|D); } void Date(int force) { static char last[32]; char *r, *q; Point p; q = ctime(time(0L)); if((r=strrchr(q, ':')) == 0){ print("bad date %s\n", q); return; } *r = '\0'; p.x = screen.r.min.x + DATEX; p.y = screen.r.min.y + DATEY; if(force || strcmp(q, last)!=0) string(&screen, p, font, q, S); strcpy(last, q); bflush(); }