initial faces (John Cummings)
This commit is contained in:
parent
663ddde9d0
commit
b330c942b4
7 changed files with 1909 additions and 0 deletions
783
src/cmd/faces/main.c
Normal file
783
src/cmd/faces/main.c
Normal file
|
|
@ -0,0 +1,783 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <draw.h>
|
||||
#include <plumb.h>
|
||||
#include <regexp.h>
|
||||
//jpc #include <event.h> /* for support routines only */
|
||||
#include <bio.h>
|
||||
#include <thread.h>
|
||||
#include <mouse.h>
|
||||
#include <cursor.h>
|
||||
#include <9pclient.h>
|
||||
#include "faces.h"
|
||||
|
||||
int history = 0; /* use old interface, showing history of mailbox rather than current state */
|
||||
int initload = 0; /* initialize program with contents of mail box */
|
||||
|
||||
enum
|
||||
{
|
||||
Facesep = 6, /* must be even to avoid damaging background stipple */
|
||||
Infolines = 9,
|
||||
|
||||
HhmmTime = 18*60*60, /* max age of face to display hh:mm time */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Mainp,
|
||||
Timep,
|
||||
Mousep,
|
||||
NPROC
|
||||
};
|
||||
|
||||
int pids[NPROC];
|
||||
char *procnames[] = {
|
||||
"main",
|
||||
"time",
|
||||
"mouse"
|
||||
};
|
||||
|
||||
Rectangle leftright = {0, 0, 20, 15};
|
||||
|
||||
uchar leftdata[] = {
|
||||
0x00, 0x80, 0x00, 0x01, 0x80, 0x00, 0x03, 0x80,
|
||||
0x00, 0x07, 0x80, 0x00, 0x0f, 0x00, 0x00, 0x1f,
|
||||
0xff, 0xf0, 0x3f, 0xff, 0xf0, 0xff, 0xff, 0xf0,
|
||||
0x3f, 0xff, 0xf0, 0x1f, 0xff, 0xf0, 0x0f, 0x00,
|
||||
0x00, 0x07, 0x80, 0x00, 0x03, 0x80, 0x00, 0x01,
|
||||
0x80, 0x00, 0x00, 0x80, 0x00
|
||||
};
|
||||
|
||||
uchar rightdata[] = {
|
||||
0x00, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x1c,
|
||||
0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0xff,
|
||||
0xff, 0x80, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xf0,
|
||||
0xff, 0xff, 0xc0, 0xff, 0xff, 0x80, 0x00, 0x0f,
|
||||
0x00, 0x00, 0x1e, 0x00, 0x00, 0x1c, 0x00, 0x00,
|
||||
0x18, 0x00, 0x00, 0x10, 0x00
|
||||
};
|
||||
|
||||
CFsys *upasfs;
|
||||
Mousectl *mousectl;
|
||||
Image *blue; /* full arrow */
|
||||
Image *bgrnd; /* pale blue background color */
|
||||
Image *left; /* left-pointing arrow mask */
|
||||
Image *right; /* right-pointing arrow mask */
|
||||
Font *tinyfont;
|
||||
Font *mediumfont;
|
||||
Font *datefont;
|
||||
int first, last; /* first and last visible face; last is first invisible */
|
||||
int nfaces;
|
||||
int mousefd;
|
||||
int nacross;
|
||||
int ndown;
|
||||
|
||||
char date[64];
|
||||
Face **faces;
|
||||
char *maildir = "/mail/fs/mbox";
|
||||
ulong now;
|
||||
|
||||
Point datep = { 8, 6 };
|
||||
Point facep = { 8, 6+0+4 }; /* 0 updated to datefont->height in init() */
|
||||
Point enddate; /* where date ends on display; used to place arrows */
|
||||
Rectangle leftr; /* location of left arrow on display */
|
||||
Rectangle rightr; /* location of right arrow on display */
|
||||
void updatetimes(void);
|
||||
|
||||
void
|
||||
setdate(void)
|
||||
{
|
||||
now = time(nil);
|
||||
strcpy(date, ctime(now));
|
||||
date[4+4+3+5] = '\0'; /* change from Thu Jul 22 14:28:43 EDT 1999\n to Thu Jul 22 14:28 */
|
||||
}
|
||||
|
||||
void
|
||||
init(void)
|
||||
{
|
||||
#if 0
|
||||
mousefd = open("/dev/mouse", OREAD);
|
||||
if(mousefd < 0){
|
||||
fprint(2, "faces: can't open mouse: %r\n");
|
||||
threadexitsall("mouse");
|
||||
}
|
||||
#endif
|
||||
upasfs = nsmount("upasfs",nil);
|
||||
mousectl = initmouse(nil,screen);
|
||||
initplumb();
|
||||
|
||||
/* make background color */
|
||||
bgrnd = allocimagemix(display, DPalebluegreen, DWhite);
|
||||
blue = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x008888FF); /* blue-green */
|
||||
left = allocimage(display, leftright, GREY1, 0, DWhite);
|
||||
right = allocimage(display, leftright, GREY1, 0, DWhite);
|
||||
if(bgrnd==nil || blue==nil || left==nil || right==nil){
|
||||
fprint(2, "faces: can't create images: %r\n");
|
||||
threadexitsall("image");
|
||||
}
|
||||
|
||||
loadimage(left, leftright, leftdata, sizeof leftdata);
|
||||
loadimage(right, leftright, rightdata, sizeof rightdata);
|
||||
|
||||
/* initialize little fonts */
|
||||
tinyfont = openfont(display, "/lib/font/bit/misc/ascii.5x7.font");
|
||||
if(tinyfont == nil)
|
||||
tinyfont = font;
|
||||
mediumfont = openfont(display, "/lib/font/bit/pelm/latin1.8.font");
|
||||
if(mediumfont == nil)
|
||||
mediumfont = font;
|
||||
datefont = font;
|
||||
|
||||
facep.y += datefont->height;
|
||||
if(datefont->height & 1) /* stipple parity */
|
||||
facep.y++;
|
||||
faces = nil;
|
||||
}
|
||||
|
||||
void
|
||||
drawtime(void)
|
||||
{
|
||||
Rectangle r;
|
||||
|
||||
r.min = addpt(screen->r.min, datep);
|
||||
if(eqpt(enddate, ZP)){
|
||||
enddate = r.min;
|
||||
enddate.x += stringwidth(datefont, "Wed May 30 22:54"); /* nice wide string */
|
||||
enddate.x += Facesep; /* for safety */
|
||||
}
|
||||
r.max.x = enddate.x;
|
||||
r.max.y = enddate.y+datefont->height;
|
||||
draw(screen, r, bgrnd, nil, ZP);
|
||||
string(screen, r.min, display->black, ZP, datefont, date);
|
||||
}
|
||||
|
||||
void
|
||||
timeproc(void *dummy)
|
||||
{
|
||||
for(;;){
|
||||
lockdisplay(display);
|
||||
drawtime();
|
||||
updatetimes();
|
||||
flushimage(display, 1);
|
||||
unlockdisplay(display);
|
||||
sleep(60000);
|
||||
setdate();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
alreadyseen(char *digest)
|
||||
{
|
||||
int i;
|
||||
Face *f;
|
||||
|
||||
if(!digest)
|
||||
return 0;
|
||||
|
||||
/* can do accurate check */
|
||||
for(i=0; i<nfaces; i++){
|
||||
f = faces[i];
|
||||
if(f->str[Sdigest]!=nil && strcmp(digest, f->str[Sdigest])==0)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
torune(Rune *r, char *s, int nr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<nr-1 && *s!='\0'; i++)
|
||||
s += chartorune(r+i, s);
|
||||
r[i] = L'\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
center(Font *f, Point p, char *s, Image *color)
|
||||
{
|
||||
int i, n, dx;
|
||||
Rune rbuf[32];
|
||||
char sbuf[32*UTFmax+1];
|
||||
|
||||
dx = stringwidth(f, s);
|
||||
if(dx > Facesize){
|
||||
n = torune(rbuf, s, nelem(rbuf));
|
||||
for(i=0; i<n; i++){
|
||||
dx = runestringnwidth(f, rbuf, i+1);
|
||||
if(dx > Facesize)
|
||||
break;
|
||||
}
|
||||
sprint(sbuf, "%.*S", i, rbuf);
|
||||
s = sbuf;
|
||||
dx = stringwidth(f, s);
|
||||
}
|
||||
p.x += (Facesize-dx)/2;
|
||||
string(screen, p, color, ZP, f, s);
|
||||
}
|
||||
|
||||
Rectangle
|
||||
facerect(int index) /* index is geometric; 0 is always upper left face */
|
||||
{
|
||||
Rectangle r;
|
||||
int x, y;
|
||||
|
||||
x = index % nacross;
|
||||
y = index / nacross;
|
||||
r.min = addpt(screen->r.min, facep);
|
||||
r.min.x += x*(Facesize+Facesep);
|
||||
r.min.y += y*(Facesize+Facesep+2*mediumfont->height);
|
||||
r.max = addpt(r.min, Pt(Facesize, Facesize));
|
||||
r.max.y += 2*mediumfont->height;
|
||||
/* simple fix to avoid drawing off screen, allowing customers to use position */
|
||||
if(index<0 || index>=nacross*ndown)
|
||||
r.max.x = r.min.x;
|
||||
return r;
|
||||
}
|
||||
|
||||
static char *mon = "JanFebMarAprMayJunJulAugSepOctNovDec";
|
||||
char*
|
||||
facetime(Face *f, int *recent)
|
||||
{
|
||||
static char buf[30];
|
||||
|
||||
if((long)(now - f->time) > HhmmTime){
|
||||
*recent = 0;
|
||||
sprint(buf, "%.3s %2d", mon+3*f->tm.mon, f->tm.mday);
|
||||
return buf;
|
||||
}else{
|
||||
*recent = 1;
|
||||
sprint(buf, "%02d:%02d", f->tm.hour, f->tm.min);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drawface(Face *f, int i)
|
||||
{
|
||||
char *tstr;
|
||||
Rectangle r;
|
||||
Point p;
|
||||
|
||||
if(f == nil)
|
||||
return;
|
||||
if(i<first || i>=last)
|
||||
return;
|
||||
r = facerect(i-first);
|
||||
draw(screen, r, bgrnd, nil, ZP);
|
||||
draw(screen, r, f->bit, f->mask, ZP);
|
||||
r.min.y += Facesize;
|
||||
center(mediumfont, r.min, f->str[Suser], display->black);
|
||||
r.min.y += mediumfont->height;
|
||||
tstr = facetime(f, &f->recent);
|
||||
center(mediumfont, r.min, tstr, display->black);
|
||||
if(f->unknown){
|
||||
r.min.y -= mediumfont->height + tinyfont->height + 2;
|
||||
for(p.x=-1; p.x<=1; p.x++)
|
||||
for(p.y=-1; p.y<=1; p.y++)
|
||||
center(tinyfont, addpt(r.min, p), f->str[Sdomain], display->white);
|
||||
center(tinyfont, r.min, f->str[Sdomain], display->black);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
updatetimes(void)
|
||||
{
|
||||
int i;
|
||||
Face *f;
|
||||
|
||||
for(i=0; i<nfaces; i++){
|
||||
f = faces[i];
|
||||
if(f == nil)
|
||||
continue;
|
||||
if(((long)(now - f->time) <= HhmmTime) != f->recent)
|
||||
drawface(f, i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setlast(void)
|
||||
{
|
||||
last = first+nacross*ndown;
|
||||
if(last > nfaces)
|
||||
last = nfaces;
|
||||
}
|
||||
|
||||
void
|
||||
drawarrows(void)
|
||||
{
|
||||
Point p;
|
||||
|
||||
p = enddate;
|
||||
p.x += Facesep;
|
||||
if(p.x & 1)
|
||||
p.x++; /* align background texture */
|
||||
leftr = rectaddpt(leftright, p);
|
||||
p.x += Dx(leftright) + Facesep;
|
||||
rightr = rectaddpt(leftright, p);
|
||||
draw(screen, leftr, first>0? blue : bgrnd, left, leftright.min);
|
||||
draw(screen, rightr, last<nfaces? blue : bgrnd, right, leftright.min);
|
||||
}
|
||||
|
||||
void
|
||||
addface(Face *f) /* always adds at 0 */
|
||||
{
|
||||
Face **ofaces;
|
||||
Rectangle r0, r1, r;
|
||||
int y, nx, ny;
|
||||
|
||||
if(f == nil)
|
||||
return;
|
||||
lockdisplay(display);
|
||||
if(first != 0){
|
||||
first = 0;
|
||||
resized();
|
||||
}
|
||||
findbit(f);
|
||||
|
||||
nx = nacross;
|
||||
ny = (nfaces+(nx-1)) / nx;
|
||||
|
||||
for(y=ny; y>=0; y--){
|
||||
/* move them along */
|
||||
r0 = facerect(y*nx+0);
|
||||
r1 = facerect(y*nx+1);
|
||||
r = r1;
|
||||
r.max.x = r.min.x + (nx - 1)*(Facesize+Facesep);
|
||||
draw(screen, r, screen, nil, r0.min);
|
||||
/* copy one down from row above */
|
||||
if(y != 0){
|
||||
r = facerect((y-1)*nx+nx-1);
|
||||
draw(screen, r0, screen, nil, r.min);
|
||||
}
|
||||
}
|
||||
|
||||
ofaces = faces;
|
||||
faces = emalloc((nfaces+1)*sizeof(Face*));
|
||||
memmove(faces+1, ofaces, nfaces*(sizeof(Face*)));
|
||||
free(ofaces);
|
||||
nfaces++;
|
||||
setlast();
|
||||
drawarrows();
|
||||
faces[0] = f;
|
||||
drawface(f, 0);
|
||||
flushimage(display, 1);
|
||||
unlockdisplay(display);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
loadmboxfaces(char *maildir)
|
||||
{
|
||||
int dirfd;
|
||||
Dir *d;
|
||||
int i, n;
|
||||
|
||||
dirfd = open(maildir, OREAD);
|
||||
if(dirfd >= 0){
|
||||
chdir(maildir);
|
||||
while((n = dirread(dirfd, &d)) > 0){
|
||||
for(i=0; i<n; i++)
|
||||
addface(dirface(maildir, d[i].name));
|
||||
free(d);
|
||||
}
|
||||
close(dirfd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
loadmboxfaces(char *maildir)
|
||||
{
|
||||
CFid *dirfd;
|
||||
Dir *d;
|
||||
int i, n;
|
||||
|
||||
dirfd = fsopen(upasfs,maildir, OREAD);
|
||||
if(dirfd != nil){
|
||||
//jpc chdir(maildir);
|
||||
while((n = fsdirread(dirfd, &d)) > 0){
|
||||
for(i=0; i<n; i++) {
|
||||
addface(dirface(maildir, d[i].name));
|
||||
}
|
||||
free(d);
|
||||
}
|
||||
fsclose(dirfd);
|
||||
}
|
||||
else {
|
||||
error("cannot open %s: %r",maildir);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
freeface(Face *f)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(f->file!=nil && f->bit!=f->file->image)
|
||||
freeimage(f->bit);
|
||||
freefacefile(f->file);
|
||||
for(i=0; i<Nstring; i++)
|
||||
free(f->str[i]);
|
||||
free(f);
|
||||
}
|
||||
|
||||
void
|
||||
delface(int j)
|
||||
{
|
||||
Rectangle r0, r1, r;
|
||||
int nx, ny, x, y;
|
||||
|
||||
if(j < first)
|
||||
first--;
|
||||
else if(j < last){
|
||||
nx = nacross;
|
||||
ny = (nfaces+(nx-1)) / nx;
|
||||
x = (j-first)%nx;
|
||||
for(y=(j-first)/nx; y<ny; y++){
|
||||
if(x != nx-1){
|
||||
/* move them along */
|
||||
r0 = facerect(y*nx+x);
|
||||
r1 = facerect(y*nx+x+1);
|
||||
r = r0;
|
||||
r.max.x = r.min.x + (nx - x - 1)*(Facesize+Facesep);
|
||||
draw(screen, r, screen, nil, r1.min);
|
||||
}
|
||||
if(y != ny-1){
|
||||
/* copy one up from row below */
|
||||
r = facerect((y+1)*nx);
|
||||
draw(screen, facerect(y*nx+nx-1), screen, nil, r.min);
|
||||
}
|
||||
x = 0;
|
||||
}
|
||||
if(last < nfaces) /* first off-screen becomes visible */
|
||||
drawface(faces[last], last-1);
|
||||
else{
|
||||
/* clear final spot */
|
||||
r = facerect(last-first-1);
|
||||
draw(screen, r, bgrnd, nil, r.min);
|
||||
}
|
||||
}
|
||||
freeface(faces[j]);
|
||||
memmove(faces+j, faces+j+1, (nfaces-(j+1))*sizeof(Face*));
|
||||
nfaces--;
|
||||
setlast();
|
||||
drawarrows();
|
||||
}
|
||||
|
||||
void
|
||||
dodelete(int i)
|
||||
{
|
||||
Face *f;
|
||||
|
||||
f = faces[i];
|
||||
if(history){
|
||||
free(f->str[Sshow]);
|
||||
f->str[Sshow] = estrdup("");
|
||||
}else{
|
||||
delface(i);
|
||||
flushimage(display, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
delete(char *s, char *digest)
|
||||
{
|
||||
int i;
|
||||
Face *f;
|
||||
|
||||
lockdisplay(display);
|
||||
for(i=0; i<nfaces; i++){
|
||||
f = faces[i];
|
||||
if(digest != nil){
|
||||
if(f->str[Sdigest]!=nil && strcmp(digest, f->str[Sdigest]) == 0){
|
||||
dodelete(i);
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
if(f->str[Sshow] && strcmp(s, f->str[Sshow]) == 0){
|
||||
dodelete(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unlockdisplay(display);
|
||||
}
|
||||
|
||||
void
|
||||
faceproc(void)
|
||||
{
|
||||
for(;;)
|
||||
addface(nextface());
|
||||
}
|
||||
|
||||
void
|
||||
resized(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
nacross = (Dx(screen->r)-2*facep.x+Facesep)/(Facesize+Facesep);
|
||||
for(ndown=1; rectinrect(facerect(ndown*nacross), screen->r); ndown++)
|
||||
;
|
||||
setlast();
|
||||
draw(screen, screen->r, bgrnd, nil, ZP);
|
||||
enddate = ZP;
|
||||
drawtime();
|
||||
for(i=0; i<nfaces; i++)
|
||||
drawface(faces[i], i);
|
||||
drawarrows();
|
||||
flushimage(display, 1);
|
||||
}
|
||||
|
||||
void
|
||||
eresized(int new)
|
||||
{
|
||||
lockdisplay(display);
|
||||
if(new && getwindow(display, Refnone) < 0) {
|
||||
fprint(2, "can't reattach to window\n");
|
||||
killall("reattach");
|
||||
}
|
||||
resized();
|
||||
unlockdisplay(display);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
getmouse(Mouse *m)
|
||||
{
|
||||
int n;
|
||||
static int eof;
|
||||
char buf[128];
|
||||
|
||||
if(eof)
|
||||
return 0;
|
||||
for(;;){
|
||||
n = read(mousefd, buf, sizeof(buf));
|
||||
if(n <= 0){
|
||||
/* so callers needn't check return value every time */
|
||||
eof = 1;
|
||||
m->buttons = 0;
|
||||
return 0;
|
||||
}
|
||||
//jpc n = eatomouse(m, buf, n);
|
||||
if(n > 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
int
|
||||
getmouse(Mouse *m)
|
||||
{
|
||||
static int eof;
|
||||
|
||||
if(eof)
|
||||
return 0;
|
||||
if( readmouse(mousectl) < 0 ) {
|
||||
eof = 1;
|
||||
m->buttons = 0;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
*m = mousectl->m;
|
||||
/* m->buttons = mousectl->m.buttons;
|
||||
m->xy.x = mousectl->m.xy.x;
|
||||
m->xy.y = mousectl->m.xy.y;
|
||||
m->msec = mousectl->m.msec; */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
Clicksize = 3, /* pixels */
|
||||
};
|
||||
|
||||
int
|
||||
scroll(int but, Point p)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = 0;
|
||||
lockdisplay(display);
|
||||
if(ptinrect(p, leftr) && first>0){
|
||||
if(but == 2)
|
||||
delta = -first;
|
||||
else{
|
||||
delta = nacross;
|
||||
if(delta > first)
|
||||
delta = first;
|
||||
delta = -delta;
|
||||
}
|
||||
}else if(ptinrect(p, rightr) && last<nfaces){
|
||||
if(but == 2)
|
||||
delta = (nfaces-nacross*ndown) - first;
|
||||
else{
|
||||
delta = nacross;
|
||||
if(delta > nfaces-last)
|
||||
delta = nfaces-last;
|
||||
}
|
||||
}
|
||||
first += delta;
|
||||
last += delta;
|
||||
unlockdisplay(display);
|
||||
if(delta)
|
||||
eresized(0);
|
||||
return delta;
|
||||
}
|
||||
|
||||
void
|
||||
click(int button, Mouse *m)
|
||||
{
|
||||
Point p;
|
||||
int i;
|
||||
|
||||
p = m->xy;
|
||||
while(m->buttons == (1<<(button-1)))
|
||||
getmouse(m);
|
||||
if(m->buttons)
|
||||
return;
|
||||
if(abs(p.x-m->xy.x)>Clicksize || abs(p.y-m->xy.y)>Clicksize)
|
||||
return;
|
||||
switch(button){
|
||||
case 1:
|
||||
if(scroll(1, p))
|
||||
break;
|
||||
if(history){
|
||||
/* click clears display */
|
||||
lockdisplay(display);
|
||||
for(i=0; i<nfaces; i++)
|
||||
freeface(faces[i]);
|
||||
free(faces);
|
||||
faces=nil;
|
||||
nfaces = 0;
|
||||
unlockdisplay(display);
|
||||
eresized(0);
|
||||
return;
|
||||
}else{
|
||||
for(i=first; i<last; i++) /* clear vwhois faces */
|
||||
if(ptinrect(p, facerect(i-first))
|
||||
&& strstr(faces[i]->str[Sshow], "/XXXvwhois")){
|
||||
delface(i);
|
||||
flushimage(display, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
scroll(2, p);
|
||||
break;
|
||||
case 3:
|
||||
scroll(3, p);
|
||||
lockdisplay(display);
|
||||
for(i=first; i<last; i++)
|
||||
if(ptinrect(p, facerect(i-first))){
|
||||
showmail(faces[i]);
|
||||
break;
|
||||
}
|
||||
unlockdisplay(display);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mouseproc(void *dummy)
|
||||
{
|
||||
Mouse mouse;
|
||||
|
||||
while(getmouse(&mouse)){
|
||||
if(mouse.buttons == 1)
|
||||
click(1, &mouse);
|
||||
else if(mouse.buttons == 2)
|
||||
click(2, &mouse);
|
||||
else if(mouse.buttons == 4)
|
||||
click(3, &mouse);
|
||||
|
||||
while(mouse.buttons)
|
||||
getmouse(&mouse);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
killall(char *s)
|
||||
{
|
||||
int i, pid;
|
||||
|
||||
pid = getpid();
|
||||
for(i=0; i<NPROC; i++)
|
||||
if(pids[i] && pids[i]!=pid)
|
||||
postnote(PNPROC, pids[i], "kill");
|
||||
threadexitsall(s);
|
||||
}
|
||||
|
||||
void
|
||||
startproc(void (*f)(void), int index)
|
||||
{
|
||||
int pid;
|
||||
|
||||
switch(pid = rfork(RFPROC|RFNOWAIT)){ //jpc removed |RFMEM
|
||||
case -1:
|
||||
fprint(2, "faces: fork failed: %r\n");
|
||||
killall("fork failed");
|
||||
case 0:
|
||||
f();
|
||||
fprint(2, "faces: %s process exits\n", procnames[index]);
|
||||
if(index >= 0)
|
||||
killall("process died");
|
||||
threadexitsall(nil);
|
||||
}
|
||||
if(index >= 0)
|
||||
pids[index] = pid;
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: faces [-hi] [-m maildir] -W winsize\n");
|
||||
threadexitsall("usage");
|
||||
}
|
||||
|
||||
void
|
||||
threadmain(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'h':
|
||||
history++;
|
||||
break;
|
||||
case 'i':
|
||||
initload++;
|
||||
break;
|
||||
case 'm':
|
||||
addmaildir(EARGF(usage()));
|
||||
maildir = nil;
|
||||
break;
|
||||
case 'W':
|
||||
winsize = EARGF(usage());
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
if(initdraw(nil, nil, "faces") < 0){
|
||||
fprint(2, "faces: initdraw failed: %r\n");
|
||||
threadexitsall("initdraw");
|
||||
}
|
||||
if(maildir)
|
||||
addmaildir(maildir);
|
||||
init();
|
||||
unlockdisplay(display); /* initdraw leaves it locked */
|
||||
display->locking = 1; /* tell library we're using the display lock */
|
||||
setdate();
|
||||
eresized(0);
|
||||
|
||||
pids[Mainp] = getpid();
|
||||
pids[Timep] = proccreate(timeproc, nil, 16000);
|
||||
pids[Mousep] = proccreate(mouseproc, nil, 16000);
|
||||
if(initload)
|
||||
for(i = 0; i < nmaildirs; i++)
|
||||
loadmboxfaces(maildirs[i]);
|
||||
faceproc();
|
||||
fprint(2, "faces: %s process exits\n", procnames[Mainp]);
|
||||
killall(nil);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue