Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/Clock.c, revision 1.1

1.1     ! root        1: /* $Header: Clock.c,v 1.3 87/09/12 12:42:42 swick Exp $ */
        !             2: #ifndef lint
        !             3: static char *sccsid = "@(#)Clock.c     1.0     2/25/87";
        !             4: #endif lint
        !             5:  
        !             6: /*
        !             7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
        !             8:  * 
        !             9:  *                         All Rights Reserved
        !            10:  * 
        !            11:  * Permission to use, copy, modify, and distribute this software and its 
        !            12:  * documentation for any purpose and without fee is hereby granted, 
        !            13:  * provided that the above copyright notice appear in all copies and that
        !            14:  * both that copyright notice and this permission notice appear in 
        !            15:  * supporting documentation, and that the name of Digital Equipment
        !            16:  * Corporation not be used in advertising or publicity pertaining to
        !            17:  * distribution of the software without specific, written prior permission.  
        !            18:  * 
        !            19:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            20:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            21:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            22:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            23:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            24:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            25:  * SOFTWARE.
        !            26:  */
        !            27: 
        !            28: 
        !            29: #include <stdio.h>
        !            30: #include <strings.h>
        !            31: #include "Xlib.h"
        !            32: #include "Xutil.h"
        !            33: #include "Intrinsic.h"
        !            34: #include "Clock.h"
        !            35: #include "Atoms.h"
        !            36: #include <sys/time.h>
        !            37: #include <sys/file.h>
        !            38: #include <sys/param.h>
        !            39: #include <math.h>
        !            40: 
        !            41: extern long time();
        !            42:        
        !            43: /* Private Definitions */
        !            44: 
        !            45: 
        !            46: #define VERTICES_IN_HANDS      6       /* to draw triangle */
        !            47: #define PHI                    (PI / 16.)      /* half angle of hand tip */
        !            48: #define PI                     3.14159265358979
        !            49: #define PI4                    (PI / 4.)
        !            50: #define        SINPHI                  0.19509032201613
        !            51: #define TWOPI                  (2. * PI)
        !            52: 
        !            53: #define SEG_BUFF_SIZE          128
        !            54: 
        !            55: #define SECOND_HAND_FRACT      90
        !            56: #define MINUTE_HAND_FRACT      70
        !            57: #define HOUR_HAND_FRACT                40
        !            58: #define HAND_WIDTH_FRACT       7
        !            59: #define SECOND_WIDTH_FRACT     5
        !            60: #define SECOND_HAND_TIME       30
        !            61: 
        !            62: #define DEF_UPDATE             60
        !            63: 
        !            64: #define DEF_BORDER             2
        !            65: #define DEF_VECTOR_HEIGHT      1
        !            66: #define DEF_VECTOR_WIDTH       1
        !            67: 
        !            68: #define DEF_DIGITAL_PADDING    10
        !            69: #define DEF_DIGITAL_FONT       "6x10"
        !            70: #define DEF_ANALOG_PADDING     8
        !            71: #define DEF_ANALOG_WIDTH       164
        !            72: #define DEF_ANALOG_HEIGHT      164
        !            73: 
        !            74: #define UNINIT                 -1
        !            75: #define FAILURE                        0
        !            76: 
        !            77: #define max(a, b) ((a) > (b) ? (a) : (b))
        !            78: #define min(a, b) ((a) < (b) ? (a) : (b))
        !            79: #define abs(a) ((a) < 0 ? -(a) : (a))
        !            80: 
        !            81: 
        !            82: typedef struct WidgetDataRec {
        !            83:        Display *dpy;           /* widget display connection */
        !            84:         Window mywin;          /* widget window */
        !            85:         Dimension      brwidth;        /* border width in pixels */
        !            86:         Dimension      width, height;  /* width/height in pixels */
        !            87:         Position       x, y;
        !            88:         Pixel  fgpixel;        /* color index for text */
        !            89:         Pixel  bgpixel;        /* color index for background */
        !            90:         Pixel  Hipixel;        /* color index for Highlighting */
        !            91:         Pixel  Hdpixel;        /* color index for hands */
        !            92:         Pixel  brpixel;        /* pixel for border */
        !            93:         XFontStruct    *fontstruct;    /* font for text */
        !            94:         GC     myGC;           /* pointer to GraphicsContext */
        !            95:         GC     EraseGC;        /* eraser GC */
        !            96:         GC     HandGC;         /* Hand GC */
        !            97:         GC     HighGC;         /* Highlighting GC */
        !            98: /* start of graph stuff */
        !            99:         int    update;         /* update frequence */
        !           100:         Dimension radius;              /* radius factor */
        !           101:         int    chime;  
        !           102:         int    beeped;
        !           103:         int    analog;
        !           104:         int    show_second_hand;
        !           105:         Dimension second_hand_length;
        !           106:         Dimension minute_hand_length;
        !           107:         Dimension hour_hand_length;
        !           108:         Dimension hand_width;
        !           109:         Dimension second_hand_width;
        !           110:         Position centerX;
        !           111:         Position centerY;
        !           112:         int    numseg;
        !           113:         int    mapped;         /* is exposed */
        !           114:         int    padding;
        !           115:         XPoint segbuff[SEG_BUFF_SIZE];
        !           116:         XPoint *segbuffptr;
        !           117:         XPoint *hour, *sec;
        !           118:         struct tm  otm ;
        !           119:         caddr_t cookie;
        !           120:    } WidgetDataRec, *WidgetData;
        !           121: 
        !           122: 
        !           123: /* Private Data */
        !           124: 
        !           125: static WidgetDataRec globaldata;
        !           126: 
        !           127: /* !!! STATIC !!! */
        !           128: static int  initDone = 0;       /* initialization flag */
        !           129: 
        !           130: static XContext widgetContext;
        !           131: 
        !           132: /* bogus static's */
        !           133: static int def_brwidth = DEF_BORDER;
        !           134: static int def_width = 164;
        !           135: static int def_height = 164;
        !           136: static int def_x = 0;
        !           137: static int def_y = 0;
        !           138: static int def_update = DEF_UPDATE;
        !           139: static int def_analog = 1;
        !           140: static int def_chime = 0;
        !           141: static int def_padding = DEF_ANALOG_PADDING;
        !           142: 
        !           143: static Resource resourcelist[] = {
        !           144:     {XtNwindow, XtCWindow, XrmRWindow,
        !           145:        sizeof(Window), (caddr_t)&globaldata.mywin, (caddr_t)NULL},
        !           146:     {XtNborderWidth, XtCBorderWidth, XrmRInt,
        !           147:        sizeof(int), (caddr_t)&globaldata.brwidth, (caddr_t) &def_brwidth},
        !           148:     {XtNwidth, XtCWidth, XrmRInt,
        !           149:        sizeof(int), (caddr_t)&globaldata.width, (caddr_t) &def_width},
        !           150:     {XtNheight, XtCHeight, XrmRInt,
        !           151:        sizeof(int), (caddr_t)&globaldata.height, (caddr_t) &def_height },
        !           152:     {XtNx, XtCX, XrmRInt,
        !           153:        sizeof(int), (caddr_t)&globaldata.x, (caddr_t) &def_x },
        !           154:     {XtNy, XtCY, XrmRInt,
        !           155:        sizeof(int), (caddr_t)&globaldata.y, (caddr_t) &def_y },
        !           156:     {XtNupdate, XtCInterval, XrmRInt,
        !           157:        sizeof(int), (caddr_t)&globaldata.update, (caddr_t) &def_update },
        !           158:     {XtNchime, XtCChime, XrmRInt,
        !           159:        sizeof(int), (caddr_t)&globaldata.chime, (caddr_t) &def_chime },
        !           160:     {XtNhand, XtCColor, XrmRPixel,
        !           161:        sizeof(int), (caddr_t)&globaldata.Hdpixel, (caddr_t)&XtDefaultFGPixel},
        !           162:     {XtNhigh, XtCColor, XrmRPixel,
        !           163:        sizeof(int), (caddr_t)&globaldata.Hipixel, (caddr_t)&XtDefaultFGPixel},
        !           164:     {XtNforeground, XtCColor, XrmRPixel,
        !           165:        sizeof(int), (caddr_t)&globaldata.fgpixel, (caddr_t)&XtDefaultFGPixel},
        !           166:     {XtNbackground, XtCColor, XrmRPixel,
        !           167:        sizeof(int), (caddr_t)&globaldata.bgpixel, (caddr_t)&XtDefaultBGPixel},
        !           168:     {XtNpadding, XtCPadding, XrmRInt,
        !           169:        sizeof(int), (caddr_t)&globaldata.padding, (caddr_t) &def_padding },
        !           170:     {XtNborder, XtCColor, XrmRPixel,
        !           171:        sizeof(int),(caddr_t)&globaldata.brpixel, (caddr_t)&XtDefaultFGPixel}
        !           172: };
        !           173: 
        !           174: static Resource resourcelist1[] = {
        !           175:     {XtNfont, XtCFont, XrmRFontStruct,
        !           176:        sizeof(XFontStruct *), (caddr_t)&globaldata.fontstruct, (caddr_t)NULL},
        !           177:     {XtNanalog, XtCAnalog, XrmRInt,
        !           178:         sizeof(int), (caddr_t) &globaldata.analog, (caddr_t) &def_analog }
        !           179: };
        !           180: 
        !           181: /****************************************************************
        !           182:  *
        !           183:  * Private Procedures
        !           184:  *
        !           185:  ****************************************************************/
        !           186: 
        !           187: static void ClockInitialize (dpy)
        !           188:     Display    *dpy;
        !           189: {
        !           190:     if (initDone) return;
        !           191: 
        !           192:     widgetContext = XUniqueContext();
        !           193:     globaldata.fontstruct = XLoadQueryFont(dpy,"fixed");
        !           194: 
        !           195:     initDone = 1;
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * Given a display and window, get the widget data.
        !           200:  */
        !           201: 
        !           202: static WidgetData DataFromWindow(dpy, window)
        !           203: Display *dpy;
        !           204: Window window;
        !           205: {
        !           206:     WidgetData result;
        !           207:     if (XFindContext(dpy, window, widgetContext, (caddr_t *)&result))
        !           208:        return NULL;
        !           209:     return result;
        !           210: }
        !           211: 
        !           212: static void Destroy();
        !           213: 
        !           214: /*
        !           215:  *
        !           216:  * Generic widget event handler
        !           217:  *
        !           218:  */
        !           219: 
        !           220: static XtEventReturnCode EventHandler(event, eventdata)
        !           221: XEvent *event;
        !           222: caddr_t eventdata;
        !           223: {
        !           224:     WidgetData         data = (WidgetData ) eventdata;
        !           225:     void clock_tic();
        !           226: 
        !           227:     switch (event->type) {
        !           228:        case ConfigureNotify:
        !           229:            data->height = event->xconfigure.height;
        !           230:            data->width = event->xconfigure.width;
        !           231:            break;
        !           232: 
        !           233:        case DestroyNotify:
        !           234:                Destroy(data);
        !           235:            break;
        !           236:        
        !           237:        case ClientMessage:
        !           238:            if (((XClientMessageEvent *)event)->message_type == 
        !           239:                  (unsigned long) XtTimerExpired)
        !           240:                  clock_tic(data);
        !           241:            break;
        !           242:        
        !           243:         case Expose:
        !           244:            data->mapped = 1;
        !           245:            if( ((XExposeEvent *)event)->count == 0)
        !           246:              redisplay_clock(data);
        !           247:            break;
        !           248: 
        !           249:        case NoExpose:
        !           250:            data->mapped = 0;
        !           251:            break;
        !           252:     }
        !           253: 
        !           254:     return (XteventHandled);
        !           255: }
        !           256: 
        !           257: static redisplay_clock(data) 
        !           258: WidgetData     data;
        !           259: {
        !           260:     if(data->analog) {
        !           261:       data->radius = (min(data->width, data->height)-(2 * data->padding)) / 2;
        !           262:       data->second_hand_length = ((SECOND_HAND_FRACT * data->radius) / 100);
        !           263:       data->minute_hand_length = ((MINUTE_HAND_FRACT * data->radius) / 100);
        !           264:       data->hour_hand_length = ((HOUR_HAND_FRACT * data->radius) / 100);
        !           265:       data->hand_width = ((HAND_WIDTH_FRACT * data->radius) / 100);
        !           266:       data->second_hand_width = ((SECOND_WIDTH_FRACT * data->radius) / 100);
        !           267:       data->centerX = data->width / 2;
        !           268:       data->centerY = data->height / 2;
        !           269:       DrawClockFace(data, data->second_hand_length, data->radius);
        !           270:     }
        !           271:     clock_tic(data);
        !           272: }
        !           273: 
        !           274: /*
        !           275:  *
        !           276:  * Destroy the widget
        !           277:  *
        !           278:  */
        !           279: 
        !           280: static void Destroy(data)
        !           281: WidgetData data;
        !           282: {
        !           283: 
        !           284:     XtClearEventHandlers(data->dpy, data->mywin);
        !           285:     (void) XtClearTimeOut(data->mywin, data->cookie);
        !           286:     XtFree ((char *) data);
        !           287: }
        !           288: 
        !           289: /****************************************************************
        !           290:  *
        !           291:  * Public Procedures
        !           292:  *
        !           293:  ****************************************************************/
        !           294: 
        !           295: Window XtCreateClock(dpy, pw, arglist, argCount)
        !           296: Display *dpy;
        !           297: Window pw;                      /* parent window */
        !           298: ArgList arglist;
        !           299: int argCount;
        !           300: {
        !           301:     WidgetData data;
        !           302:     unsigned long eventmask;
        !           303:     GCMask             valuemask;
        !           304:     XrmNameList   names;
        !           305:     XrmClassList        classes;
        !           306:     XGCValues  myXGCV;
        !           307:     char *str;
        !           308:     struct tm tm, *localtime();
        !           309:     long time_value;
        !           310: 
        !           311:     if (!initDone)ClockInitialize (dpy);
        !           312: 
        !           313:     data = (WidgetData ) XtMalloc (sizeof (WidgetDataRec));
        !           314:     globaldata.dpy = dpy;
        !           315:  
        !           316:     /* Set Some Default Values */
        !           317:     XtGetResources(dpy, resourcelist1, XtNumber(resourcelist1), arglist,
        !           318:                   argCount, pw, "clock", "Clock", &names, &classes);
        !           319:     if(!globaldata.analog) {
        !           320:       (void) time(&time_value);
        !           321:       tm = *localtime(&time_value);
        !           322:       str = asctime(&tm);
        !           323:       def_width = XTextWidth( globaldata.fontstruct, str, strlen(str)) +
        !           324:        2 * 10;
        !           325:       def_height = globaldata.fontstruct->ascent +
        !           326:        globaldata.fontstruct->descent + 2 * 10;
        !           327:       def_padding = 10;
        !           328:     }
        !           329:     /* Set Default Values */
        !           330:     XtGetResources(dpy, resourcelist, XtNumber(resourcelist), arglist,
        !           331:                   argCount, pw, "clock", "Clock", &names, &classes);
        !           332:     if(!globaldata.analog && globaldata.padding != def_padding) {
        !           333:       def_width = XTextWidth( globaldata.fontstruct, str, strlen(str)) +
        !           334:        2 * globaldata.padding;
        !           335:       def_height = globaldata.fontstruct->ascent +
        !           336:        globaldata.fontstruct->descent + 2 * globaldata.padding;
        !           337:       XtGetResources(dpy, resourcelist, XtNumber(resourcelist), arglist,
        !           338:                     argCount, pw, "clock", "Clock", &names, &classes);
        !           339:     }
        !           340:     *data = globaldata;
        !           341:     valuemask = GCForeground | GCFont | GCBackground | GCLineWidth;
        !           342:     myXGCV.foreground = (*data).fgpixel;
        !           343:     myXGCV.font = (*data).fontstruct->fid;
        !           344:     myXGCV.background = data->bgpixel;
        !           345:     myXGCV.line_width = 0;
        !           346:     (*data).myGC = XtGetGC(dpy, (XContext) XtNclock, pw, valuemask, &myXGCV);
        !           347:     valuemask = GCForeground | GCLineWidth ;
        !           348:     myXGCV.foreground = (*data).bgpixel;
        !           349:     (*data).EraseGC = XtGetGC(dpy, (XContext) XtNclock, pw, valuemask, &myXGCV);
        !           350:     myXGCV.foreground = (*data).Hdpixel;
        !           351:     (*data).HandGC = XtGetGC(dpy, (XContext) XtNclock, pw, valuemask, &myXGCV);
        !           352:     valuemask = GCForeground | GCLineWidth ;
        !           353:     myXGCV.foreground = (*data).Hipixel;
        !           354:     (*data).HighGC = XtGetGC(dpy, (XContext) XtNclock, pw, valuemask, &myXGCV);
        !           355: 
        !           356:     if (data->mywin != NULL) {
        !           357:        XWindowAttributes wi;
        !           358:        /* set global data from window parameters */
        !           359:        if (! XGetWindowAttributes(data->dpy,data->mywin, &wi)) {
        !           360:            data->mywin = NULL;
        !           361:        } else {
        !           362:            data->brwidth = wi.border_width;
        !           363:            data->width = wi.width;
        !           364:            data->height = wi.height;
        !           365:        }
        !           366:     }
        !           367:     if (data->mywin == NULL) {
        !           368:        /* create the Clock window */
        !           369:          data->mywin = XCreateSimpleWindow(data->dpy, pw, data->x, data->y,
        !           370:                              data->width, data->height,
        !           371:                              data->brwidth, data->brpixel, data->bgpixel);
        !           372:     }
        !           373: 
        !           374:     XtSetNameAndClass(data->dpy, data->mywin, names, classes);
        !           375:     XrmFreeNameList(names);
        !           376:     XrmFreeClassList(classes);
        !           377: 
        !           378:     /* set handler for expose, resize, and message events */
        !           379: 
        !           380:     eventmask = ExposureMask+StructureNotifyMask;
        !           381:     XtSetEventHandler (
        !           382:        data->dpy, data->mywin,
        !           383:        (XtEventHandler)EventHandler, eventmask, (caddr_t)data);
        !           384: 
        !           385:     XtSetTimeOut(data->mywin, XtNclock, data->update*1000);
        !           386:     if (data->update <= SECOND_HAND_TIME)
        !           387:       data->show_second_hand = TRUE;
        !           388:     return (data->mywin);
        !           389: }
        !           390: 
        !           391: 
        !           392: static void clock_tic(data)
        !           393: WidgetData data;
        !           394: {
        !           395:     
        !           396:        struct tm *localtime();
        !           397:        struct tm tm; 
        !           398:        long    time_value;
        !           399:        char    time_string[28];
        !           400:        char    *time_ptr = time_string;
        !           401: 
        !           402:        (void) time(&time_value);
        !           403:        tm = *localtime(&time_value);
        !           404:        /*
        !           405:         * Beep on the half hour; double-beep on the hour.
        !           406:         */
        !           407:        if (data->chime == TRUE) {
        !           408:            if (data->beeped && (tm.tm_min != 30) &&
        !           409:                (tm.tm_min != 0))
        !           410:              data->beeped = 0;
        !           411:            if (((tm.tm_min == 30) || (tm.tm_min == 0)) 
        !           412:                && (!data->beeped)) {
        !           413:                data->beeped = 1;
        !           414:                XBell(data->dpy, 50);   
        !           415:                if (tm.tm_min == 0)
        !           416:                  XBell(data->dpy, 50);
        !           417:            }
        !           418:        }
        !           419:        if( data->analog == FALSE ) {
        !           420:            time_ptr = asctime(&tm);
        !           421:            time_ptr[strlen(time_ptr) - 1] = 0;
        !           422:            XDrawImageString(data->dpy, data->mywin, data->myGC,
        !           423:                             2+data->padding
        !           424:                             , 2+data->fontstruct->ascent+data->padding,
        !           425:                             time_ptr, strlen(time_ptr));
        !           426:        } else {
        !           427:                        /*
        !           428:                         * The second (or minute) hand is sec (or min) 
        !           429:                         * sixtieths around the clock face. The hour hand is
        !           430:                         * (hour + min/60) twelfths of the way around the
        !           431:                         * clock-face.  The derivation is left as an excercise
        !           432:                         * for the reader.
        !           433:                         */
        !           434: 
        !           435:                        /*
        !           436:                         * 12 hour clock.
        !           437:                         */
        !           438:                        if(tm.tm_hour > 12)
        !           439:                                tm.tm_hour -= 12;
        !           440: 
        !           441:                        /*
        !           442:                         * Erase old hands.
        !           443:                         */
        !           444:                        if(data->numseg > 0) {
        !           445:                            if (data->show_second_hand == TRUE) {
        !           446:                                XDrawLines(data->dpy, data->mywin,
        !           447:                                        data->EraseGC,
        !           448:                                        data->sec,
        !           449:                                        VERTICES_IN_HANDS-1,
        !           450:                                        CoordModeOrigin);
        !           451:                                if(data->Hdpixel != data->bgpixel) {
        !           452:                                    XFillPolygon(data->dpy,
        !           453:                                        data->mywin, data->EraseGC,
        !           454:                                        data->sec,
        !           455:                                        VERTICES_IN_HANDS-2,
        !           456:                                        Convex, CoordModeOrigin
        !           457:                                    );
        !           458:                                }
        !           459:                            }
        !           460:                            if( tm.tm_min != data->otm.tm_min ||
        !           461:                                tm.tm_hour != data->otm.tm_hour ) {
        !           462:                                XDrawLines( data->dpy,
        !           463:                                           data->mywin,
        !           464:                                           data->EraseGC,
        !           465:                                           data->segbuff,
        !           466:                                           VERTICES_IN_HANDS,
        !           467:                                           CoordModeOrigin);
        !           468:                                XDrawLines( data->dpy,
        !           469:                                           data->mywin,
        !           470:                                           data->EraseGC,
        !           471:                                           data->hour,
        !           472:                                           VERTICES_IN_HANDS,
        !           473:                                           CoordModeOrigin);
        !           474:                                if(data->Hdpixel != data->bgpixel) {
        !           475:                                    XFillPolygon( data->dpy,
        !           476:                                        data->mywin, data->EraseGC,
        !           477:                                        data->segbuff, VERTICES_IN_HANDS,
        !           478:                                        Convex, CoordModeOrigin
        !           479:                                    );
        !           480:                                    XFillPolygon(data->dpy,
        !           481:                                        data->mywin, data->EraseGC,
        !           482:                                        data->hour,
        !           483:                                        VERTICES_IN_HANDS,
        !           484:                                        Convex, CoordModeOrigin
        !           485:                                    );
        !           486:                                }
        !           487:                            }
        !           488:                    }
        !           489: 
        !           490:                    if (data->numseg == 0 ||
        !           491:                        tm.tm_min != data->otm.tm_min ||
        !           492:                        tm.tm_hour != data->otm.tm_hour) {
        !           493:                            data->segbuffptr = data->segbuff;
        !           494:                            data->numseg = 0;
        !           495:                            /*
        !           496:                             * Calculate the hour hand, fill it in with its
        !           497:                             * color and then outline it.  Next, do the same
        !           498:                             * with the minute hand.  This is a cheap hidden
        !           499:                             * line algorithm.
        !           500:                             */
        !           501:                            DrawHand(data,
        !           502:                                data->minute_hand_length, data->hand_width,
        !           503:                                ((double) tm.tm_min)/60.0
        !           504:                            );
        !           505:                            if(data->Hdpixel != data->bgpixel)
        !           506:                                XFillPolygon( data->dpy,
        !           507:                                    data->mywin, data->HandGC,
        !           508:                                    data->segbuff, VERTICES_IN_HANDS,
        !           509:                                    Convex, CoordModeOrigin
        !           510:                                );
        !           511:                            XDrawLines( data->dpy,
        !           512:                                data->mywin, data->HighGC,
        !           513:                                data->segbuff, VERTICES_IN_HANDS,
        !           514:                                       CoordModeOrigin);
        !           515:                            data->hour = data->segbuffptr;
        !           516:                            DrawHand(data, 
        !           517:                                data->hour_hand_length, data->hand_width,
        !           518:                                ((((double)tm.tm_hour) + 
        !           519:                                    (((double)tm.tm_min)/60.0)) / 12.0)
        !           520:                            );
        !           521:                            if(data->Hdpixel != data->bgpixel) {
        !           522:                              XFillPolygon( data->dpy,
        !           523:                                           data->mywin, data->HandGC,
        !           524:                                           data->hour,
        !           525:                                           VERTICES_IN_HANDS,
        !           526:                                           Convex, CoordModeOrigin
        !           527:                                           );
        !           528:                            }
        !           529:                            XDrawLines( data->dpy,
        !           530:                                       data->mywin, data->HighGC,
        !           531:                                       data->hour, VERTICES_IN_HANDS,
        !           532:                                       CoordModeOrigin );
        !           533: 
        !           534:                            data->sec = data->segbuffptr;
        !           535:                    }
        !           536:                    if (data->show_second_hand == TRUE) {
        !           537:                            data->segbuffptr = data->sec;
        !           538:                            DrawSecond(data,
        !           539:                                data->second_hand_length - 2, 
        !           540:                                data->second_hand_width,
        !           541:                                data->minute_hand_length + 2,
        !           542:                                ((double) tm.tm_sec)/60.0
        !           543:                            );
        !           544:                            if(data->Hdpixel != data->bgpixel)
        !           545:                                XFillPolygon( data->dpy,
        !           546:                                    data->mywin, data->HandGC,
        !           547:                                    data->sec,
        !           548:                                    VERTICES_IN_HANDS -2,
        !           549:                                    Convex, CoordModeOrigin
        !           550:                            );
        !           551:                            XDrawLines( data->dpy,
        !           552:                                       data->mywin, data->HighGC,
        !           553:                                       data->sec,
        !           554:                                       VERTICES_IN_HANDS-1,
        !           555:                                       CoordModeOrigin
        !           556:                                        );
        !           557:                            /*
        !           558:                             * keep the pointer from walking too far.
        !           559:                             */
        !           560:                            data->segbuffptr = data->sec;
        !           561:                            data->numseg = data->segbuffptr-data->segbuff;
        !           562:                        }
        !           563:                        data->otm = tm;
        !           564:                        
        !           565:                }
        !           566: }
        !           567:        
        !           568: /*
        !           569:  * DrawLine - Draws a line.
        !           570:  *
        !           571:  * blank_length is the distance from the center which the line begins.
        !           572:  * length is the maximum length of the hand.
        !           573:  * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
        !           574:  * how far around the circle (clockwise) from high noon.
        !           575:  *
        !           576:  * The blank_length feature is because I wanted to draw tick-marks around the
        !           577:  * circle (for seconds).  The obvious means of drawing lines from the center
        !           578:  * to the perimeter, then erasing all but the outside most pixels doesn't
        !           579:  * work because of round-off error (sigh).
        !           580:  */
        !           581: static DrawLine(data, blank_length, length, fraction_of_a_circle)
        !           582: WidgetData     data;
        !           583: Dimension blank_length;
        !           584: Dimension length;
        !           585: double fraction_of_a_circle;
        !           586: {
        !           587:        register double angle, cosangle, sinangle;
        !           588:        double cos();
        !           589:        double sin();
        !           590: 
        !           591:        /*
        !           592:         *  A full circle is 2 PI radians.
        !           593:         *  Angles are measured from 12 o'clock, clockwise increasing.
        !           594:         *  Since in X, +x is to the right and +y is downward:
        !           595:         *
        !           596:         *      x = x0 + r * sin(theta)
        !           597:         *      y = y0 - r * cos(theta)
        !           598:         *
        !           599:         */
        !           600:        angle = TWOPI * fraction_of_a_circle;
        !           601:        cosangle = cos(angle);
        !           602:        sinangle = sin(angle);
        !           603: 
        !           604:        SetSeg( data, 
        !           605:               data->centerX + (int)(blank_length * sinangle),
        !           606:               data->centerY - (int)(blank_length * cosangle),
        !           607:               data->centerX + (int)(length * sinangle),
        !           608:               data->centerY - (int)(length * cosangle));
        !           609: }
        !           610: 
        !           611: /*
        !           612:  * DrawHand - Draws a hand.
        !           613:  *
        !           614:  * length is the maximum length of the hand.
        !           615:  * width is the half-width of the hand.
        !           616:  * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
        !           617:  * how far around the circle (clockwise) from high noon.
        !           618:  *
        !           619:  */
        !           620: static DrawHand(data, length, width, fraction_of_a_circle)
        !           621: WidgetData     data;
        !           622: Dimension length, width;
        !           623: double fraction_of_a_circle;
        !           624: {
        !           625: 
        !           626:        register double angle, cosangle, sinangle;
        !           627:        register double ws, wc;
        !           628:        Position x, y, x1, y1, x2, y2;
        !           629:        double cos();
        !           630:        double sin();
        !           631: 
        !           632:        /*
        !           633:         *  A full circle is 2 PI radians.
        !           634:         *  Angles are measured from 12 o'clock, clockwise increasing.
        !           635:         *  Since in X, +x is to the right and +y is downward:
        !           636:         *
        !           637:         *      x = x0 + r * sin(theta)
        !           638:         *      y = y0 - r * cos(theta)
        !           639:         *
        !           640:         */
        !           641:        angle = TWOPI * fraction_of_a_circle;
        !           642:        cosangle = cos(angle);
        !           643:        sinangle = sin(angle);
        !           644:        /*
        !           645:         * Order of points when drawing the hand.
        !           646:         *
        !           647:         *              1,4
        !           648:         *              / \
        !           649:         *             /   \
        !           650:         *            /     \
        !           651:         *          2 ------- 3
        !           652:         */
        !           653:        wc = width * cosangle;
        !           654:        ws = width * sinangle;
        !           655:        SetSeg( data,
        !           656:               x = data->centerX + round(length * sinangle),
        !           657:               y = data->centerY - round(length * cosangle),
        !           658:               x1 = data->centerX - round(ws + wc), 
        !           659:               y1 = data->centerY + round(wc - ws));  /* 1 ---- 2 */
        !           660:        /* 2 */
        !           661:        SetSeg( data, x1, y1, 
        !           662:               x2 = data->centerX - round(ws - wc), 
        !           663:               y2 = data->centerY + round(wc + ws));  /* 2 ----- 3 */
        !           664: 
        !           665:        SetSeg( data, x2, y2, x, y);    /* 3 ----- 1(4) */
        !           666: }
        !           667: 
        !           668: /*
        !           669:  * DrawSecond - Draws the second hand (diamond).
        !           670:  *
        !           671:  * length is the maximum length of the hand.
        !           672:  * width is the half-width of the hand.
        !           673:  * offset is direct distance from center to tail end.
        !           674:  * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
        !           675:  * how far around the circle (clockwise) from high noon.
        !           676:  *
        !           677:  */
        !           678: static DrawSecond(data, length, width, offset, fraction_of_a_circle)
        !           679: WidgetData data;
        !           680: Dimension length, width, offset;
        !           681: double fraction_of_a_circle;
        !           682: {
        !           683: 
        !           684:        register double angle, cosangle, sinangle;
        !           685:        register double ms, mc, ws, wc;
        !           686:        register int mid;
        !           687:        Position x, y;
        !           688:        double cos();
        !           689:        double sin();
        !           690: 
        !           691:        /*
        !           692:         *  A full circle is 2 PI radians.
        !           693:         *  Angles are measured from 12 o'clock, clockwise increasing.
        !           694:         *  Since in X, +x is to the right and +y is downward:
        !           695:         *
        !           696:         *      x = x0 + r * sin(theta)
        !           697:         *      y = y0 - r * cos(theta)
        !           698:         *
        !           699:         */
        !           700:        angle = TWOPI * fraction_of_a_circle;
        !           701:        cosangle = cos(angle);
        !           702:        sinangle = sin(angle);
        !           703:        /*
        !           704:         * Order of points when drawing the hand.
        !           705:         *
        !           706:         *              1,5
        !           707:         *              / \
        !           708:         *             /   \
        !           709:         *            /     \
        !           710:         *          2<       >4
        !           711:         *            \     /
        !           712:         *             \   /
        !           713:         *              \ /
        !           714:         *      -        3
        !           715:         *      |
        !           716:         *      |
        !           717:         *   offset
        !           718:         *      |
        !           719:         *      |
        !           720:         *      -        + center
        !           721:         */
        !           722: 
        !           723:        mid = (length + offset) / 2;
        !           724:        mc = mid * cosangle;
        !           725:        ms = mid * sinangle;
        !           726:        wc = width * cosangle;
        !           727:        ws = width * sinangle;
        !           728:        /*1 ---- 2 */
        !           729:        SetSeg( data,
        !           730:               x = data->centerX + round(length * sinangle),
        !           731:               y = data->centerY - round(length * cosangle),
        !           732:               data->centerX + round(ms - wc),
        !           733:               data->centerY - round(mc + ws) );
        !           734:        SetSeg( data, data->centerX + round(offset *sinangle),
        !           735:               data->centerY - round(offset * cosangle), /* 2-----3 */
        !           736:               data->centerX + round(ms + wc), 
        !           737:               data->centerY - round(mc - ws));
        !           738:        data->segbuffptr->x = x;
        !           739:        data->segbuffptr++->y = y;
        !           740:        data->numseg ++;
        !           741: }
        !           742: 
        !           743: static SetSeg( data, x1, y1, x2, y2)
        !           744: WidgetData     data;
        !           745: int x1, y1, x2, y2;
        !           746: {
        !           747:        data->segbuffptr->x = x1;
        !           748:        data->segbuffptr++->y = y1;
        !           749:        data->segbuffptr->x = x2;
        !           750:        data->segbuffptr++->y = y2;
        !           751:        data->numseg += 2;
        !           752: }
        !           753: 
        !           754: /*
        !           755:  *  Draw the clock face (every fifth tick-mark is longer
        !           756:  *  than the others).
        !           757:  */
        !           758: static DrawClockFace(data, second_hand, radius)
        !           759: WidgetData data;
        !           760: Dimension second_hand;
        !           761: Dimension radius;
        !           762: {
        !           763:        register int i;
        !           764:        register int delta = (radius - second_hand) / 3;
        !           765:        
        !           766:        XClearWindow(data->dpy, data->mywin);
        !           767:        data->segbuffptr = data->segbuff;
        !           768:        data->numseg = 0;
        !           769:        for (i = 0; i < 60; i++)
        !           770:                DrawLine(data, (i % 5) == 0 ? second_hand : (radius - delta), radius,
        !           771:                 ((double) i)/60.);
        !           772:        /*
        !           773:         * Go ahead and draw it.
        !           774:         */
        !           775:        XDrawSegments(data->dpy, data->mywin, 
        !           776:                      data->myGC, (XSegment *) &(data->segbuff[0]),
        !           777:                      data->numseg/2);
        !           778:        
        !           779:        data->segbuffptr = data->segbuff;
        !           780:        data->numseg = 0;
        !           781: }
        !           782: 
        !           783: static round(x)
        !           784: double x;
        !           785: {
        !           786:        return(x >= 0 ? (int)(x + .5) : (int)(x - .5));
        !           787: }
        !           788: 
        !           789: 
        !           790: /*
        !           791:  *
        !           792:  * Get Attributes
        !           793:  *
        !           794:  */
        !           795: 
        !           796: void XtClockGetValues (dpy, window, arglist, argCount)
        !           797: Display *dpy;
        !           798: Window window;
        !           799: ArgList arglist;
        !           800: int argCount;
        !           801: {
        !           802:     WidgetData data;
        !           803:     data = DataFromWindow(dpy, window);
        !           804:     if (data == NULL) return;
        !           805:     globaldata = *data;
        !           806:     XtGetValues(resourcelist, XtNumber(resourcelist), arglist, argCount);
        !           807: }
        !           808: 
        !           809: /*
        !           810:  *
        !           811:  * Set Attributes
        !           812:  *
        !           813:  */
        !           814: 
        !           815: void XtClockSetValues (dpy, window, arglist, argCount)
        !           816: Display *dpy;
        !           817: Window window;
        !           818: ArgList arglist;
        !           819: int argCount;
        !           820: {
        !           821:       WidgetData data;
        !           822:       int redisplay = FALSE;
        !           823:       GCMask valuemask;
        !           824:       XGCValues        myXGCV;
        !           825:       
        !           826:       
        !           827:       data = DataFromWindow(dpy, window);
        !           828:       if (data == NULL) return;
        !           829:       globaldata = *data;
        !           830:       XtSetValues(resourcelist, XtNumber(resourcelist), arglist, argCount);
        !           831: 
        !           832:       if(globaldata.update != data->update) {
        !           833:            (void) XtClearTimeOut(data->mywin, data->cookie);
        !           834:            XtSetTimeOut(data->mywin, data->cookie, globaldata.update*1000);
        !           835:            data->update = globaldata.update;
        !           836:            if (data->update <= SECOND_HAND_TIME)
        !           837:                 data->show_second_hand = TRUE;
        !           838: 
        !           839:       }
        !           840:       if (globaldata.brpixel != data->brpixel) {
        !           841:        data->brpixel = globaldata.brpixel;
        !           842:        if (data->brwidth != 0)
        !           843:          XSetWindowBorder(data->dpy, data->mywin, data->brpixel);
        !           844:        redisplay = TRUE;
        !           845:       }
        !           846:       if ((globaldata.bgpixel != data->bgpixel) || 
        !           847:          (globaldata.fgpixel != data->fgpixel) ||
        !           848:          (globaldata.Hdpixel != data->Hdpixel) ||
        !           849:          (globaldata.Hipixel != data->Hipixel)) {
        !           850:          redisplay = TRUE;
        !           851:          if((globaldata.bgpixel != data->bgpixel) || 
        !           852:             (globaldata.fgpixel != data->fgpixel)) {
        !           853:                valuemask = GCForeground | GCFont | GCBackground | GCLineWidth;
        !           854:                myXGCV.foreground = (*data).fgpixel;
        !           855:                myXGCV.font = (*data).fontstruct->fid;
        !           856:                myXGCV.background = data->bgpixel;
        !           857:                data->myGC = XtGetGC(
        !           858:                        data->dpy, (XContext) XtNclock, data->mywin, valuemask, &myXGCV);
        !           859:          }
        !           860:          if (globaldata.bgpixel != data->bgpixel) {
        !           861:                valuemask = GCForeground | GCLineWidth;
        !           862:                myXGCV.foreground = (*data).bgpixel;
        !           863:                data->EraseGC = XtGetGC(
        !           864:                        data->dpy, (XContext) XtNclock, data->mywin, valuemask, &myXGCV);
        !           865:          }
        !           866:          if (globaldata.Hdpixel != data->Hdpixel) {
        !           867:                valuemask = GCForeground | GCLineWidth;
        !           868:                myXGCV.foreground = (*data).Hdpixel;
        !           869:                data->HandGC = XtGetGC(
        !           870:                        data->dpy, (XContext) XtNclock, data->mywin, valuemask, &myXGCV);
        !           871:          }
        !           872:          if (globaldata.Hipixel != data->Hipixel) {
        !           873:                 valuemask = GCForeground | GCLineWidth;
        !           874:                 myXGCV.foreground = (*data).Hipixel;
        !           875:                 data->HighGC = XtGetGC(
        !           876:                        data->dpy, (XContext) XtNclock, data->mywin, valuemask, &myXGCV);
        !           877:          }
        !           878:      }
        !           879:       *data = globaldata;
        !           880:       if(redisplay == TRUE) {
        !           881:        XClearWindow(data->dpy, data->mywin);
        !           882:        redisplay_clock(data);
        !           883:       }
        !           884: }
        !           885: 
        !           886: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.