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

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

unix.superglobalmegacorp.com

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