#include #include #include #include #include #include enum{ Mevt = 0, Mrsz, Timer, }; Alt alts[] = { {nil, nil, CHANRCV}, /* mouse event */ {nil, nil, CHANRCV}, /* resizec */ {nil, nil, CHANRCV}, /* timer */ CHANEND, }; Image *hrhand, *minhand; Image *dots, *back; Channel *tchan; Point circlept(Point c, int r, int degrees) { double rad; rad = (double) degrees * PI/180.0; c.x += cos(rad)*r; c.y -= sin(rad)*r; return c; } void redraw(Image *screen) { static int tm, ntm; static Rectangle r; static Point c; static int rad; int i; int anghr, angmin; static Tm tms; static Tm ntms; ntm = time(0); if(ntm == tm && eqrect(screen->r, r)) return; ntms = *localtime(ntm); anghr = 90-(ntms.hour*5 + ntms.min/10)*6; angmin = 90-ntms.min*6; tm = ntm; tms = ntms; r = screen->r; c = divpt(addpt(r.min, r.max), 2); rad = Dx(r) < Dy(r) ? Dx(r) : Dy(r); rad /= 2; rad -= 8; draw(screen, screen->r, back, nil, ZP); for(i=0; i<12; i++) fillellipse(screen, circlept(c, rad, i*(360/12)), 2, 2, dots, ZP); line(screen, c, circlept(c, (rad*3)/4, angmin), 0, 0, 1, minhand, ZP); line(screen, c, circlept(c, rad/2, anghr), 0, 0, 1, hrhand, ZP); flushimage(display, 1); } void timerproc(void *v) { threadsetname("timerproc"); for(;;){ threadsleep(30*1000); nbsendul(tchan, 0); } } void threadmain(int i, char** c) { Mouse m; Mousectl *mousectl; Menu menu; char *mstr[] = {"exit", 0}; tchan = chancreate(sizeof(ulong), 0); threadcreate(timerproc, nil, 8192); initdraw(0,0,"clock"); back = allocimagemix(display, DPalebluegreen, DWhite); hrhand = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DDarkblue); minhand = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DPaleblue); dots = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DBlue); redraw(screen); menu.item = mstr; menu.lasthit = 0; mousectl = initmouse(nil, screen); if(mousectl == nil){ fprint(2, "clock: can't initialize mouse: %r\n"); threadexitsall("mouse"); } alts[Mevt].c = mousectl->c; alts[Mevt].v = &mousectl->m; alts[Mrsz].c = mousectl->resizec; alts[Mrsz].v = nil; alts[Timer].c = tchan; alts[Timer].v = nil; for(;;) { switch(alt(alts)){ case Mevt: m = mousectl->m; if(m.buttons & 4) { if(menuhit(3, mousectl, &menu, nil) == 0) threadexitsall(0); } break; case Mrsz: if(getwindow(display, Refnone) < 0) { fprint(2,"can't reattach to window"); threadexitsall("getwindow"); } redraw(screen); break; case Timer: redraw(screen); break; } } }