ref: 2e6cf1acf48e95d9408a6063074666af586bf35e
dir: /main.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <draw.h> #include <mouse.h> #include <keyboard.h> #include <thread.h> #include <plumb.h> #include "theme.h" #include "a.h" #include "kbd.h" enum { Padding = 4, }; enum { Emouse, Eresize, Ekeyboard, Eseemail, Eshowmesg, Eselmesg, }; enum { BACK, TEXT, BORD, NCOLS, }; Mousectl *mctl; Kbdctl *kctl; Channel *showc; Channel *selc; Channel *eventc; Mailbox *mboxes[16]; int nmboxes; Mailbox *mbox; static Image *cols[NCOLS]; Rectangle headr; Rectangle indexr; Rectangle pagerr; int collapsed = 0; void drawheader(void) { char buf[255] = {0}; Point p; draw(screen, headr, cols[BACK], nil, ZP); p = headr.min; p.x += Padding; p.y += Padding / 2; if(mbox->unseen > 0) snprint(buf, sizeof buf, "» %s [total:%d - new:%d]", mbox->name, mbox->count, mbox->unseen); else snprint(buf, sizeof buf, "» %s [total:%d]", mbox->name, mbox->count); string(screen, p, cols[TEXT], ZP, font, buf); line(screen, Pt(headr.min.x, headr.max.y), headr.max, 0, 0, 0, cols[BORD], ZP); } void redraw(void) { draw(screen, screen->r, cols[BACK], nil, ZP); drawheader(); indexdraw(); if(collapsed){ line(screen, Pt(indexr.min.x, indexr.max.y), indexr.max, 0, 0, 0, cols[BORD], ZP); pagerdraw(); } flushimage(display, 1); } void resize(void) { headr = screen->r; headr.max.y = headr.min.y+Padding+font->height; indexr = screen->r; indexr.min.y = headr.max.y + 1; indexr = indexresize(indexr, collapsed); if(collapsed){ pagerr = screen->r; pagerr.min.y = indexr.max.y + 1; pagerresize(pagerr); } redraw(); } void mouse(Mouse m) { indexmouse(m); pagermouse(m); } void key(Key k) { if(k.k == Kdel) threadexitsall(nil); else if(k.k == 'q'){ if(collapsed){ collapsed = 0; resize(); }else threadexitsall(nil); }else if(k.mods == Malt){ if(collapsed) pagerkey(k.k); }else indexkey(k.k); } void seemail(Mailevent e) { Mailbox *mb; char *s; int i; for(mb = nil, i = 0; i < nmboxes; i++){ if(strncmp(mboxes[i]->path, e.path, strlen(mboxes[i]->path))==0){ mb = mboxes[i]; break; } } if(mb==nil) return; s = e.path; switch(e.type){ case Enew: i = mboxadd(mb, s); if(mb==mbox){ indexadded(i); redraw(); } break; case Edelete: i = mboxdel(mb, s); if(mb==mbox){ indexremoved(i); redraw(); } break; case Emodify: i = mboxmod(mb, s); if(i >= 0 && mb==mbox) redraw(); break; } free(s); } void init(Channel *selc) { Theme *theme; Rectangle r; theme = loadtheme(); if(theme != nil){ cols[BACK] = theme->back; cols[TEXT] = theme->text; cols[BORD] = theme->title; }else{ r = Rect(0, 0, 1, 1); cols[BACK] = allocimage(display, r, screen->chan, 1, 0xFFFFFFFF); cols[TEXT] = allocimage(display, r, screen->chan, 1, 0x000000FF); cols[BORD] = allocimage(display, r, screen->chan, 1, DGreygreen); /* cols[BACK] = allocimage(display, r, screen->chan, 1, 0x282828FF); cols[TEXT] = allocimage(display, r, screen->chan, 1, 0xA89984FF); cols[BORD] = allocimage(display, r, screen->chan, 1, 0x98971AFF); */ } indexinit(mctl, showc, selc, theme); pagerinit(mctl, theme); } void switchmbox(int n) { if(mbox==mboxes[n]) return; mbox = mboxes[n]; indexswitch(mbox); } void plumbmsg(Message *m) { int fd; fd = plumbopen("send", OWRITE|OCEXEC); if(fd<0) return; plumbsendtext(fd, "mongrel", nil, nil, m->path); close(fd); } void showmsg(Message *m) { if(collapsed == 0){ collapsed = 1; resize(); } pagershow(m); if(mesgmarkseen(mbox, m)) redraw(); } void selchanged(Message *m) { if(collapsed == 0) return; showmsg(m); } void usage(void) { fprint(2, "usage: %s [-m maildir]\n", argv0); exits("usage"); } void threadmain(int argc, char *argv[]) { Mouse m; Key k; Mailevent e; Message *msg; Alt alts[] = { { nil, &m, CHANRCV }, { nil, nil, CHANRCV }, { nil, &k, CHANRCV }, { nil, &e, CHANRCV }, { nil, &msg, CHANRCV }, { nil, &msg, CHANRCV }, { nil, nil, CHANEND }, }; char *s; nmboxes = 0; ARGBEGIN{ case 'm': s = EARGF(usage()); mboxes[nmboxes++] = loadmbox(s); break; default: fprint(2, "unknown flag '%c'\n", ARGC()); usage(); }ARGEND if(nmboxes==0){ fprint(2, "no maildir specified\n"); usage(); } tmfmtinstall(); if(initdraw(nil, nil, "mongrel")<0) sysfatal("initdraw: %r"); display->locking = 0; if((mctl = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); if((kctl = initkbd()) == nil) sysfatal("initkbd: %r"); if((eventc = chancreate(sizeof(Mailevent), 0))==nil) sysfatal("chancreate: %r"); if((showc = chancreate(sizeof(Message*), 1))==nil) sysfatal("chancreate: %r"); if((selc = chancreate(sizeof(Message*), 1))==nil) sysfatal("chancreate: %r"); alts[0].c = mctl->c; alts[1].c = mctl->resizec; alts[2].c = kctl->c; alts[3].c = eventc; alts[4].c = showc; alts[5].c = selc; proccreate(seemailproc, eventc, 8192); init(selc); switchmbox(0); resize(); for(;;){ switch(alt(alts)){ case Emouse: mouse(m); break; case Eresize: if(getwindow(display, Refnone)<0) sysfatal("cannot reattach: %r"); resize(); break; case Ekeyboard: key(k); break; case Eseemail: seemail(e); break; case Eshowmesg: showmsg(msg); break; case Eselmesg: //plumbmsg(msg); selchanged(msg); break; } } }