Sean CaronCode style cleanupa0eeef48 years agoHistory
169 lines · 5.0 KB · C
RawDownload
/*  * 9clock.c: a basic graphical clock for plan 9  * sean caron (scaron@umich.edu)*/ /*  * The paradigm here is that we must always include u.h  * first and libc.h second, and anything else after that.*/ #include <u.h>#include <libc.h>#include <draw.h>#include <cursor.h>#include <event.h> int main(void);void eresized(int new); int main(void) {    Point center, minend, hrend, o_minend, o_hrend;    Tm *thetime;    int xdim, ydim, fd;    double mintheta, hrtheta;    char *buttons[] = { "quit", 0 };    Menu menu = { buttons };    Mouse m;    Event e;    ulong timer, evtype;     initdraw(nil, nil, "9clock");     /*     * initialize event handler for mouse events only. we     * must call this subsequent to initdraw().    */    einit(Emouse);     /* we need to call this resize handler at least once */    eresized(0);     /*     * we need to set up this timer event because when you use     * the event() system call, it basically blocks until some sort     * of event occurs. we use the timer event in lieu of a real     * event occurring or else the clock would not update until     * the user moved the mouse or clicked a button.    */    timer = etimer(0,10);     /*     * initdraw() sets up some global variables,     *     * Display *display     * Image *screen     * Screen *_screen     * Font *font     *     * ZP is a constant point (0,0).    */     /* resize the current window. */    fd = open("/dev/wctl", OWRITE);    fprint(fd, "resize -dx 200 -dy 200");    close(fd);     getwindow(display, Refnone);     /* initialize some variables. */    xdim = (screen->r.max.x - screen->r.min.x) / 2;    ydim = (screen->r.max.y - screen->r.min.y) / 2;     center.x = screen->r.min.x + xdim;    center.y = screen->r.min.y + ydim;     /* main program loop */    while (1) {        evtype = event(&e);         /* look for mouse events */        if (evtype == Emouse) {            m = e.mouse;             /* if left mouse button is clicked, show the menu */            if (m.buttons == 4) {                /* quit */                if (emenuhit(3, &m, &menu) == 0) {                    closedisplay(display);		    exits(0);                }            }        }         /* use the faux timer event to update the clock if there is no real input */        else if (event(&e) == timer) {            /* draw outline of clock face. */            ellipse(screen, center, xdim, ydim, 2, display->black, center);             thetime = localtime(time(nil));             /* correct 24 hour system time to 12 hour clock. */            if (thetime->hour > 12) {                thetime->hour = thetime->hour - 12;            }             /*             * 6 degrees = 0.104718 rads per minute on the clock face.             * 30 degrees = 0.523590 rads per hour on the clock face.             *             * we subtract the value from PI/2 to correct between standard             * form and clock form.            */             mintheta = (PI/2.0) - (0.104718 * (double)thetime->min);            hrtheta = (PI/2.0) - (0.523590 * (double)thetime->hour);             /*             * calculate the endpoints for the minute and hour hands.             * we resize the window to be square so xdim and ydim are actually the same.             * we scale down the hour hand to make it shorter than the minute hand.            */             minend.x = center.x + (double)xdim*cos(mintheta);            minend.y = center.y - (double)ydim*sin(mintheta);             hrend.x = center.x + (double)xdim*cos(hrtheta);            hrend.y = center.y - (double)ydim*sin(hrtheta);             /*             * if the time has changed since the last time we looped, get rid of the stale minute or             * hour hands.            */            if ((o_minend.x != minend.x) || (o_minend.y != minend.y)) {                line(screen, center, o_minend, Endsquare, Endarrow, 1, display->white, center);            }             if ((o_hrend.x != hrend.x) || (o_hrend.y != hrend.y)) {                line(screen, center, o_hrend, Endsquare, Endarrow, 2, display->white, center);            }             /* draw the current minute and hour hands. */            line(screen, center, minend, Endsquare, Endarrow, 1, display->black, center);            line(screen, center, hrend, Endsquare, Endarrow, 2, display->black, center);             /* save the minute and hour hand coordinates for comparison the next time around. */            o_minend = minend;            o_hrend = hrend;             /* let some other processes get a word in edgewise. */            sleep(1);             /*             * the draw (2) manpage suggests that this is not required, but the graphics will not             * show up unless we use it.            */            flushimage(display,1);        }    }} /*  * by convention we must declare an eresized() function to  * handle the window resizing event.*/ void eresized(int new) {    /* just refresh the window for now. */    getwindow(display, Refnone);}