Annotation of 43BSDTahoe/new/X/xclock/xclock.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)xclock.c   1.2 10/16/86";
                      3: #endif
                      4: 
                      5: #include <X/mit-copyright.h>
                      6: 
                      7: /* Copyright 1985 Massachusetts Institute of Technology */
                      8: 
                      9: /*
                     10:  * xclock.c MIT Project Athena, X Window system clock.
                     11:  *
                     12:  *  This program provides the user with a small
                     13:  * window contining a digital clock with day and date.
                     14:  * Parameters are variable from the command line.
                     15:  *
                     16:  *  Author:    Tony Della Fera, DEC
                     17:  *             September, 1984
                     18:  * Hacked up by a cast of thousands....
                     19:  */
                     20: 
                     21: #include <stdio.h>
                     22: #include <math.h>
                     23: #include <sys/time.h>
                     24: #include <X/Xlib.h>
                     25: 
                     26: #define PI                     3.141592
                     27: 
                     28: #define SEG_BUFF_SIZE          128
                     29: 
                     30: #define SECOND_HAND_FRACT      90
                     31: #define MINUTE_HAND_FRACT      70
                     32: #define HOUR_HAND_FRACT                40
                     33: #define SECOND_HAND_TIME       30
                     34: 
                     35: #define DEF_UPDATE             60
                     36: 
                     37: #define DEF_BORDER             2
                     38: #define DEF_VECTOR_HEIGHT      1
                     39: #define DEF_VECTOR_WIDTH       1
                     40: 
                     41: #define DEF_DIGITAL_PADDING    10
                     42: #define DEF_DIGITAL_FONT       "6x10"
                     43: #define DEF_ANALOG_PADDING     8
                     44: #define DEF_ANALOG_WIDTH       164
                     45: #define DEF_ANALOG_HEIGHT      164
                     46: 
                     47: #define DEF_BORDER_COLOR       BlackPixel
                     48: #define DEF_HIGH_COLOR         BlackPixel
                     49: #define DEF_FRGRND_COLOR       BlackPixel
                     50: #define DEF_BKGRND_COLOR       WhitePixel
                     51: 
                     52: #define UNINIT                 -1
                     53: #define FAILURE                        0
                     54: 
                     55: #define max(a, b) ((a) > (b) ? (a) : (b))
                     56: #define min(a, b) ((a) < (b) ? (a) : (b))
                     57: #define abs(a) ((a) < 0 ? -(a) : (a))
                     58: 
                     59: typedef enum _bool {FALSE, TRUE} Bool;
                     60: 
                     61: Bool XClockDebug = FALSE;
                     62: Bool AnalogClock = FALSE;
                     63: Bool ShowSecondHand = FALSE;
                     64: Bool Reverse = FALSE;
                     65: 
                     66: int CenterX = 0;
                     67: int CenterY = 0;
                     68: int NumSegs = 0;
                     69: 
                     70: int FrgrndColor;
                     71: int BkgrndColor;
                     72: int BorderColor;
                     73: int HighColor;
                     74: 
                     75: Vertex SegBuff[SEG_BUFF_SIZE];
                     76: Vertex *SegBuffPtr;
                     77: 
                     78: Window ClockWindow;
                     79: 
                     80: main(argc, argv)
                     81:        int argc;
                     82:        char **argv;
                     83: {
                     84:     char time_string[26];
                     85:     register char *time_ptr = time_string;
                     86: #ifdef DEBUG
                     87:     register Bool debug = XClockDebug;
                     88: #endif
                     89:     register int i;
                     90:     register int radius;
                     91:     register int padding = UNINIT; /* UNINIT = parameter uninitialized. */
                     92:     int border = UNINIT;       /* UNINIT = parameter uninitialized. */
                     93:     int update = UNINIT;       /* UNINIT = parameter uninitialized. */
                     94:     int win_width = UNINIT;    /* UNINIT = parameter uninitialized. */
                     95:     int win_height = UNINIT;   /* UNINIT = parameter uninitialized. */
                     96:     int second_hand_length;
                     97:     int minute_hand_length;
                     98:     int hour_hand_length;
                     99:     int readfds = 0;
                    100:     int maxfds = 0;
                    101:     int string_width;
                    102:     int status;
                    103:     Bool even_update = FALSE;
                    104: 
                    105:     long time_value;
                    106: 
                    107:     char *index();
                    108:     char *ctime(), asctim();
                    109:     char *strind;
                    110:     char *fn = DEF_DIGITAL_FONT;
                    111:     char *fore_color = NULL;
                    112:     char *back_color = NULL;
                    113:     char *high_color = NULL;
                    114:     char *brdr_color = NULL;
                    115:     char *geom = NULL;
                    116:     char *display = NULL;
                    117:     int rvflag = 0;
                    118: 
                    119:     Color cdef;
                    120: 
                    121:     struct tm *localtime();
                    122:     struct timeval timeout;
                    123:     struct tm tm; 
                    124:     struct tm otm;
                    125: 
                    126:     Font font;
                    127:     FontInfo font_info; 
                    128:     XEvent event;
                    129:     char *def_val;
                    130: 
                    131:     def_val = XGetDefault(argv[0], "BorderWidth");
                    132:     if (def_val != NULL) border = atoi(def_val);
                    133: 
                    134:     def_val = XGetDefault(argv[0], "BodyFont");
                    135:     if (def_val != NULL) fn = def_val;
                    136: 
                    137:     fore_color = XGetDefault(argv[0], "Foreground");
                    138:     back_color = XGetDefault(argv[0], "Background");
                    139:     high_color = XGetDefault(argv[0], "Highlight");
                    140:     brdr_color = XGetDefault(argv[0], "Border");
                    141: 
                    142:     def_val = XGetDefault(argv[0], "ReverseVideo");
                    143:     if(def_val != NULL && strcmp(def_val, "on") == 0) rvflag++;
                    144: 
                    145:     def_val = XGetDefault(argv[0], "InternalBorder");
                    146:     if (def_val != NULL) padding = atoi(def_val);
                    147:        
                    148:     if ((def_val = XGetDefault(argv[0], "Mode")) != NULL) {
                    149:        if (strcmp(def_val, "analog") == 0) AnalogClock = TRUE;
                    150:        if (strcmp(def_val, "digital") == 0) AnalogClock = FALSE;
                    151:        if (strcmp(def_val, "Analog") == 0) AnalogClock = TRUE;
                    152:        if (strcmp(def_val, "Digital") == 0) AnalogClock = FALSE;
                    153:     }
                    154: 
                    155:     def_val = XGetDefault(argv[0],"Update");
                    156:     if (def_val != NULL) update = atoi(def_val);
                    157: 
                    158:     geom = XGetDefault(argv[0], "Geometry");
                    159: 
                    160:     for (i = 1; i < argc; i++) {
                    161:        if (argv [i] [0] == '=') {
                    162:            geom = argv[i];
                    163:            continue;
                    164:        }
                    165:        strind = index(argv[i], ':');
                    166:        if(strind != NULL) {
                    167:            display = argv[i];
                    168:            continue;
                    169:        }
                    170:        strind = index(argv [i], '-');
                    171:        if (strind == NULL) Syntax(argv[0]);
                    172:        if (strcmp(argv [i], "-a") == 0 ||
                    173:            strcmp(argv [i], "-analog") == 0) {
                    174:            AnalogClock = TRUE;
                    175:            continue;
                    176:        }
                    177:        if (strcmp(argv [i], "-d") == 0 ||
                    178:            strcmp(argv [i], "-digital") == 0) {
                    179:            AnalogClock = FALSE;
                    180:            continue;
                    181:        }
                    182:        if (strcmp(argv [i], "-bw") == 0 ||
                    183:            strcmp(argv [i], "-border") == 0) {
                    184:            if (++i >= argc) Syntax(argv[0]);
                    185:            border = atoi(argv [i]);
                    186:            continue;
                    187:        }
                    188: #ifdef DEBUG
                    189:        if (strcmp(argv [i], "-debug") == 0) {
                    190:            XClockDebug = TRUE;
                    191:            debug = TRUE;
                    192:            continue;
                    193:        }
                    194: #endif
                    195:        if (strcmp(argv [i], "-fn") == 0 ||
                    196:            strcmp(argv [i], "-font") == 0) {
                    197:            if (++i >= argc) Syntax(argv[0]);
                    198:            fn = argv [i];
                    199:            continue;
                    200:        }
                    201:        if (strcmp(argv [i], "-fg") == 0 ||
                    202:            strcmp(argv [i], "-foreground") == 0) {
                    203:            if (++i >= argc) Syntax(argv[0]);
                    204:            fore_color = argv [i];
                    205:            continue;
                    206:        }
                    207:        if (strcmp(argv [i], "-bg") == 0 ||
                    208:            strcmp(argv [i], "-background") == 0) {
                    209:            if (++i >= argc) Syntax(argv[0]);
                    210:            back_color = argv [i];
                    211:            continue;
                    212:        }
                    213:        if (strcmp(argv [i], "-hl") == 0 ||
                    214:            strcmp(argv [i], "-highlight") == 0) {
                    215:            if (++i >= argc) Syntax(argv[0]);
                    216:            high_color = argv [i];
                    217:            continue;
                    218:        }
                    219:        if (strcmp(argv [i], "-bd") == 0 ||
                    220:            strcmp(argv [i], "-bordercolor") == 0) {
                    221:            if (++i >= argc) Syntax(argv[0]);
                    222:            brdr_color = argv [i];
                    223:            continue;
                    224:        }
                    225:        if (strcmp(argv [i], "-help") == 0) {
                    226:            Syntax(argv[0]);
                    227:        }
                    228:        if (strcmp(argv [i], "-p") == 0 ||
                    229:            strcmp(argv [i], "-padding") == 0) {
                    230:            if (++i >= argc) Syntax(argv[0]);
                    231:            padding = atoi(argv [i]);
                    232:            continue;
                    233:        }
                    234:        if (strcmp(argv [i], "-rv") == 0 ||
                    235:            strcmp(argv [i], "-reverse") == 0) {
                    236:            rvflag++;
                    237:            continue;
                    238:        }
                    239:        if (strcmp(argv [i], "-u") == 0 ||
                    240:            strcmp(argv [i], "-update") == 0) {
                    241:            if (++i >= argc) Syntax(argv[0]);
                    242:            update = atoi(argv [i]);
                    243:            continue;
                    244:        }
                    245:        Syntax(argv[0]);
                    246:     }
                    247: 
                    248:     /*
                    249:      * Open up the display.
                    250:      */
                    251:     if (XOpenDisplay(display) == NULL) {
                    252:        XClockError("Error while trying to open display");
                    253:     }
                    254:     if (rvflag) Reverse = TRUE;
                    255: 
                    256:     /*
                    257:      * Set up colors and pixmaps.
                    258:      */
                    259:     if (brdr_color != NULL) {
                    260:        if (DisplayCells() > 2) {
                    261:            if (
                    262:                XParseColor(brdr_color, &cdef) &&
                    263:                XGetHardwareColor(&cdef)
                    264:                ) BorderColor = cdef.pixel;
                    265:            else BorderColor = DEF_BORDER_COLOR;
                    266:        }
                    267:        else if (strcmp(brdr_color, "black") == 0)
                    268:            BorderColor = BlackPixel;
                    269:        else if (strcmp(brdr_color, "white") == 0)
                    270:            BorderColor = WhitePixel;
                    271:        else BorderColor = DEF_BORDER_COLOR;
                    272:     }
                    273:     else BorderColor = DEF_BORDER_COLOR;
                    274: 
                    275:     if (fore_color != NULL) {
                    276:        if (DisplayCells() > 2) {
                    277:            if (
                    278:                XParseColor(fore_color, &cdef) &&
                    279:                XGetHardwareColor(&cdef)
                    280:                ) FrgrndColor = cdef.pixel;
                    281:            else FrgrndColor = DEF_FRGRND_COLOR;
                    282:        }
                    283:        else if (strcmp(fore_color, "black") == 0)
                    284:            FrgrndColor = BlackPixel;
                    285:        else if (strcmp(fore_color, "white") == 0)
                    286:            FrgrndColor = WhitePixel;
                    287:        else FrgrndColor = DEF_FRGRND_COLOR;
                    288:     }
                    289:     else FrgrndColor = DEF_FRGRND_COLOR;
                    290: 
                    291:     if (back_color != NULL) {
                    292:        if (DisplayCells() > 2) {
                    293:            if (
                    294:                XParseColor(back_color, &cdef) &&
                    295:                XGetHardwareColor(&cdef)
                    296:                ) BkgrndColor = cdef.pixel;
                    297:            else BkgrndColor = DEF_BKGRND_COLOR;
                    298:        }
                    299:        else if (strcmp(back_color, "black") == 0)
                    300:            BkgrndColor = BlackPixel;
                    301:        else if (strcmp(back_color, "white") == 0)
                    302:            BkgrndColor = WhitePixel;
                    303:        else BkgrndColor = DEF_BKGRND_COLOR;
                    304:     }
                    305:     else BkgrndColor = DEF_BKGRND_COLOR;
                    306: 
                    307:     if ((high_color != NULL) && AnalogClock) {
                    308:        if (DisplayCells() > 2) {
                    309:            if (
                    310:                XParseColor(high_color, &cdef) &&
                    311:                XGetHardwareColor(&cdef)
                    312:                ) HighColor = cdef.pixel;
                    313:            else HighColor = DEF_HIGH_COLOR;
                    314:        }
                    315:        else if (strcmp(high_color, "black") == 0)
                    316:            HighColor = BlackPixel;
                    317:        else if (strcmp(high_color, "white") == 0)
                    318:            HighColor = WhitePixel;
                    319:        else HighColor = DEF_HIGH_COLOR;
                    320:     }
                    321:     else HighColor = DEF_HIGH_COLOR;
                    322:        
                    323:     if (Reverse) {
                    324:        HighColor = BorderColor = BkgrndColor;
                    325:        BkgrndColor = FrgrndColor;
                    326:        FrgrndColor = HighColor;
                    327:     }
                    328: 
                    329:     /*
                    330:      * Set up analog and digital specific defaults.
                    331:      */
                    332:     if (AnalogClock == TRUE) {
                    333:        /*
                    334:         * Set analog defaults.
                    335:         */
                    336:        if (padding == UNINIT) padding = DEF_ANALOG_PADDING;
                    337:        if (update == UNINIT) update = DEF_UPDATE;
                    338:        if (update <= SECOND_HAND_TIME) ShowSecondHand = TRUE;
                    339:        /*
                    340:         * Initialize the segment buffer and segment buffer pointer.
                    341:         */
                    342:        SegBuffPtr = SegBuff;
                    343: 
                    344:        /*
                    345:         * Initialize the number of "segments" in the buffer; each
                    346:         * segment is one Vertex or 3 shorts, an x value, a y value
                    347:         * and the flags as passed to XDraw.
                    348:         */
                    349:        NumSegs = 0;
                    350:     } 
                    351:     else {
                    352:        /* 
                    353:         * Set digital defaults.
                    354:         */
                    355: 
                    356:        if (padding == UNINIT) padding = DEF_DIGITAL_PADDING;
                    357:        if (update == UNINIT) update = DEF_UPDATE;
                    358: 
                    359:        /*
                    360:         * Get font dependent information and determine window
                    361:         * size from a test string.
                    362:         */
                    363:        time(&time_value);
                    364:        time_ptr = ctime(&time_value);
                    365:        time_ptr[strlen(time_ptr) - 1] = 0;
                    366: 
                    367:        font = XGetFont(fn);
                    368:        if (font == FAILURE) XClockError("Can't get font");
                    369: 
                    370:        status = XQueryFont(font, &font_info);
                    371:        if (status == FAILURE) XClockError("Can't query font");
                    372: 
                    373:        string_width = XQueryWidth (time_ptr, font);
                    374:        
                    375:     }
                    376:        
                    377: 
                    378:     /* 
                    379:      * Now set analog and digital independent defaults.
                    380:      */
                    381:     if (border == UNINIT) border = DEF_BORDER;
                    382:     if (update > 1 && ((60 / update) * update == 60)) even_update = TRUE;
                    383: 
                    384:     /*
                    385:      * Open the main window.
                    386:      */
                    387: {
                    388:     int min_width, min_height;
                    389:     char default_geom[20];
                    390:     OpaqueFrame frame;
                    391:     if (AnalogClock) {
                    392:        min_width = DEF_ANALOG_WIDTH/3;
                    393:        min_height = DEF_ANALOG_HEIGHT/3;
                    394:        sprintf (default_geom,
                    395:                 "%dx%d-0-0", DEF_ANALOG_WIDTH, DEF_ANALOG_HEIGHT);
                    396:     }
                    397:     else {
                    398:        min_width = string_width + (2 * padding);
                    399:        min_height = font_info.height + (2 * padding);
                    400:        sprintf (default_geom, "%dx%d-0-0", min_width, min_height);
                    401:     }
                    402:     frame.bdrwidth = border;
                    403:     frame.border = XMakeTile (BorderColor);
                    404:     frame.background = XMakeTile (BkgrndColor);
                    405:     ClockWindow = XCreate (
                    406:                           AnalogClock ? "Analog XClock" : "Digital XClock",
                    407:                           argv[0],
                    408:                           geom,
                    409:                           default_geom,
                    410:                           &frame,
                    411:                           min_width,
                    412:                           min_height);
                    413:     if (ClockWindow == FAILURE)
                    414:        XClockError("Can't open clock window");
                    415: }
                    416: 
                    417:     /*
                    418:      * Select window exposure events to see if the contents of
                    419:      * the window have been erased or altered.  Select unmap events so
                    420:      * we can stop output when iconified.
                    421:      */
                    422:     XSelectInput(ClockWindow, ExposeWindow|UnmapWindow);
                    423: 
                    424:     /*
                    425:      * Map clock window to screen.
                    426:      */
                    427:     XMapWindow(ClockWindow);
                    428: 
                    429:     /*
                    430:      * Initialize the select system call's maximum file
                    431:      * descriptor number to be one more than the file descriptor
                    432:      * number of the X connection.
                    433:      */
                    434:     maxfds = dpyno() + 1;
                    435: 
                    436:     /*
                    437:      * Initialize the select timeout structure.
                    438:      */
                    439:     timeout.tv_sec = update;
                    440:     timeout.tv_usec = 0;
                    441: 
                    442:     /*
                    443:      * Initialize the old-time structure.
                    444:      */
                    445:     otm = *localtime(&time_value);
                    446: 
                    447:     /*
                    448:      * Synchronize X before proceeding.
                    449:      */
                    450:     XSync(FALSE);
                    451: 
                    452:     /*
                    453:      * Main clock loop.
                    454:      */
                    455:     while (TRUE) {
                    456:        time(&time_value);
                    457:        tm = *localtime(&time_value);
                    458:        if (even_update) {
                    459:            /* Truncate to update interval, get new timeout */
                    460:            timeout.tv_sec = update - tm.tm_sec;
                    461:            tm.tm_sec = (tm.tm_sec / update) * update;
                    462:            timeout.tv_sec += tm.tm_sec;
                    463:        }
                    464:        if (AnalogClock == FALSE) {     
                    465:            /* 
                    466:             * See if there are any events pending that
                    467:             * arn't supposed to be there.
                    468:             */
                    469:            if (XPending() != 0) {
                    470:                /*
                    471:                 * There is an event pending so we must
                    472:                 * check to see if it is an ExposeWindow
                    473:                 * event, if it is anything else somthing
                    474:                 * went wrong!
                    475:                 */
                    476:                XNextEvent(&event);
                    477:                if (event.type == UnmapWindow) {
                    478:                    XPeekEvent(&event);
                    479:                    continue;
                    480:                }
                    481:                if (event.type != ExposeWindow) {
                    482:                    XClockError("Unexpected X_Event (digital mode)");
                    483:                }
                    484:            }
                    485:            time_ptr = asctime(&tm);
                    486:            time_ptr[strlen(time_ptr) - 1] = 0;
                    487:            XTextPad (
                    488:                      ClockWindow,
                    489:                      padding, padding, 
                    490:                      time_ptr, strlen(time_ptr),
                    491:                      font, 0, 0, 
                    492:                      FrgrndColor, BkgrndColor,
                    493:                      GXcopy, AllPlanes
                    494:                      );
                    495:        }
                    496:        else {
                    497:            /* 
                    498:             * Look for an X_Event associated with xclock.
                    499:             */
                    500:            if (XPending() != 0) {
                    501:                /*
                    502:                 * There is an event pending so we must
                    503:                 * check to see if it is an ExposeWindow
                    504:                 * event, if it is anything else, somthing
                    505:                 * went wrong!
                    506:                 */
                    507:                XNextEvent(&event);
                    508:                if (event.type == UnmapWindow) {
                    509:                    XPeekEvent(&event);
                    510:                    continue;
                    511:                }
                    512:                if (event.type == ExposeWindow) {
                    513:                    /*
                    514:                     * Ok, we have a window exposure event,
                    515:                     * refresh the clock face.  Check to
                    516:                     * see if the window has changed size.
                    517:                     */
                    518:                    XExposeWindowEvent *exp_event = (XExposeWindowEvent *)&event;
                    519:                    if ((exp_event->width != win_width) ||
                    520:                        (exp_event->height != win_height)) {
                    521:                        win_width = exp_event->width;
                    522:                        win_height = exp_event->height;
                    523:                        radius = (min(win_width, win_height) -(2 * padding)) / 2;
                    524:                        second_hand_length = 
                    525:                        ((SECOND_HAND_FRACT *
                    526:                          radius)
                    527:                         / 100);
                    528:                        minute_hand_length =
                    529:                        ((MINUTE_HAND_FRACT *
                    530:                          radius) / 100);
                    531:                        hour_hand_length =
                    532:                        ((HOUR_HAND_FRACT *
                    533:                          radius) / 100);
                    534:                        CenterX = win_width / 2;
                    535:                        CenterY = win_height / 2;
                    536:                    }
                    537:                    DrawClockFace(second_hand_length,
                    538:                                  radius);
                    539:                }
                    540:                else {
                    541:                    /*
                    542:                     * We should never get here!
                    543:                     */
                    544:                    XClockError("Unexpected X_Event (analog mode)");
                    545:                }
                    546:            }
                    547:            /*
                    548:             * The second (or minute) hand is sec (or min) 
                    549:             * sixtieths around the clock face. The hour hand is
                    550:             * (hour + min/60) twelfths of the way around the
                    551:             * clock-face.  The derivation is left as an excercise
                    552:             * for the reader.
                    553:             */
                    554: 
                    555:            /*
                    556:             * Erase old hands.
                    557:             */
                    558:            if (ShowSecondHand == TRUE) {
                    559:                DrawHand(1, second_hand_length,
                    560:                         ((double) otm.tm_sec)/60.0);
                    561:            }
                    562:            DrawHand(1, minute_hand_length,
                    563:                     ((double) otm.tm_min)/60.0);
                    564:            DrawHand(1, hour_hand_length,
                    565:                     (((double)otm.tm_hour) + 
                    566:                      (((double)otm.tm_min)/60.0))/12.0);
                    567:            Sync(BkgrndColor);
                    568: 
                    569:            /*
                    570:             * 12 hour clock.
                    571:             */
                    572:            if(tm.tm_hour > 12)
                    573:                tm.tm_hour -= 12;
                    574: 
                    575:            /*
                    576:             * Draw new hands.
                    577:             */
                    578:            if (ShowSecondHand == TRUE) {
                    579:                DrawHand(1, second_hand_length,
                    580:                         ((double) tm.tm_sec)/60.0);
                    581:            }
                    582:            DrawHand(1, minute_hand_length,
                    583:                     ((double) tm.tm_min)/60.0);
                    584:            DrawHand(1, hour_hand_length,
                    585:                     (((double) tm.tm_hour) + 
                    586:                      (((double) tm.tm_min)/60.0))/12.0);
                    587:            Sync(HighColor);
                    588: 
                    589:            /*
                    590:             * Make the new time now be the old time.
                    591:             */
                    592:            otm = tm;
                    593:        }
                    594:        XFlush ();
                    595: 
                    596:        /*
                    597:         * Use the select system call on the file descriptor in
                    598:         * the display structure to determine if there is work
                    599:         * to be done.  If not block untill timeout.  Remember to
                    600:         * reset the file descriptor before each select.
                    601:         */
                    602:        readfds = 1 << dpyno();
                    603:        if (select(maxfds, &readfds, NULL, NULL, &timeout) == -1)
                    604:            XClockError("Error in select on display file descriptor");
                    605:     }
                    606: }
                    607: 
                    608: 
                    609: /*
                    610:  * DrawHand - Draws (or erases) a hand.  Fraction_of_a_circle is a
                    611:  * fraction between 0 and 1 (inclusive) indicating how far around the
                    612:  * circle (clockwise) high noon.
                    613:  *
                    614:  * Blank_length is the distance from the center which the hand begins
                    615:  * (logically 0, but I have the feature, I might as well use it).
                    616:  * length is the maximum length of the hand.
                    617:  *
                    618:  * The blank_length feature is because I wanted to draw tick-marks around the
                    619:  * circle (for seconds).  The obvious means of drawing lines from the center
                    620:  * to the perimeter, then erasing all but the outside most pixels doesn't
                    621:  * work because of round-off error (sigh).
                    622:  */
                    623: DrawHand(blank_length, length, fraction_of_a_circle)
                    624:        int blank_length;
                    625:        int length;
                    626:        double fraction_of_a_circle;
                    627: {
                    628: 
                    629:        double cos();
                    630:        double sin();
                    631:        double angle;
                    632: 
                    633:        /*
                    634:         *  A full circle is 2 PI radians.
                    635:         *  Angles are measured from 6 o'clock, not noon (or so it seems).
                    636:         *  Thus, when fraction_of_a_circle is 0, we want angle to be PI,
                    637:         *  and when fraction_of_a_circle is 1, we want angle to be 3 PI.
                    638:         *
                    639:         *  Also, angles increase counter-clockwise, not clockwise, so we
                    640:         *  throw in a factor of -1 so our clock doesn't run backwards.
                    641:         */
                    642:        angle = (-2 * PI * fraction_of_a_circle) + PI;
                    643: 
                    644:        /*
                    645:         * Add the move instruction to the segment buffer and increment
                    646:         * the "next" pointer.
                    647:         */
                    648:        SegBuffPtr->x = CenterX + (int)((float)blank_length * sin(angle));
                    649:        SegBuffPtr->y = CenterY + (int)((float)blank_length * cos(angle));
                    650:        SegBuffPtr->flags = VertexDontDraw;
                    651:        SegBuffPtr++;
                    652:        NumSegs++;
                    653: 
                    654:        /*
                    655:         * Add the new point to the buffer and increment the "next" pointer.
                    656:         */
                    657:        SegBuffPtr->x = CenterX + (int)((float)length * sin(angle));
                    658:        SegBuffPtr->y = CenterY + (int)((float)length * cos(angle));
                    659:        SegBuffPtr->flags = VertexDrawLastPoint;
                    660:        SegBuffPtr++;
                    661:        NumSegs++;
                    662: }
                    663: 
                    664: 
                    665: /*
                    666:  *  Draw the clock face (every fifth tick-mark is longer
                    667:  *  than the others).
                    668:  */
                    669: DrawClockFace(second_hand, radius)
                    670:        int second_hand;
                    671:        int radius;
                    672: {
                    673:        register Bool debug = XClockDebug;
                    674:        register int i;
                    675:        register int delta = (radius - second_hand) / 3;
                    676:        
                    677:        XClear(ClockWindow);
                    678:        for (i = 0; i < 60; i++) {
                    679:                if ((i % 5) == 0) {
                    680:                        DrawHand(second_hand, radius, ((double) i)/60.);
                    681:                }
                    682:                else {
                    683:                        DrawHand((radius - delta), radius, ((double) i)/60.);
                    684:                }
                    685:        }
                    686:        /*
                    687:         * Flush the buffer to the VS100.
                    688:         */
                    689:        Sync(FrgrndColor);
                    690: }
                    691: 
                    692: 
                    693: /*
                    694:  * This routine synchronizes the segment buffer contents with the
                    695:  * VS100 screen.  In effect, it flushes the buffer contents to the
                    696:  * screen.
                    697:  */
                    698: Sync(color)
                    699:        int color;              /* X drawing color. */
                    700: {
                    701:        register Bool debug = XClockDebug;
                    702:        
                    703:        /*
                    704:         * Call the X draw curve routine.
                    705:         */
                    706:        XDraw(
                    707:                ClockWindow,
                    708:                SegBuff, NumSegs,
                    709:                DEF_VECTOR_WIDTH, DEF_VECTOR_HEIGHT,
                    710:                color, GXcopy, AllPlanes
                    711:        );
                    712: 
                    713:        /*
                    714:         * Reset the segment buffer pointer and the segment counter.
                    715:         */
                    716:        SegBuffPtr = SegBuff;
                    717:        NumSegs = 0;
                    718: }
                    719: 
                    720: 
                    721: 
                    722: /*
                    723:  * Report the syntax for calling xclock.
                    724:  */
                    725: Syntax(call)
                    726:        char *call;
                    727: {
                    728:        printf ("Usage: %s [-analog] [-bw <pixels>] [-digital]\n", call);
                    729:        printf ("       [-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>]\n");
                    730:        printf ("       [-fn <font_name>] [-help] [-padding <pixels>]\n");
                    731:        printf ("       [-rv] [-update <seconds>] [[<host>]:[<vs>]]\n");
                    732:        printf ("       [=[<width>][x<height>][<+-><xoff>[<+-><yoff>]]]\n\n");
                    733:        printf ("Default: %s -digital -bw %d -font %s -padding %d -update %d =-0-0\n\n",
                    734:                call, DEF_BORDER, DEF_DIGITAL_FONT, DEF_DIGITAL_PADDING, DEF_UPDATE);
                    735:        printf ("Default: %s -analog -bw %d -padding %d -update %d =%dx%d-0-0\n\n",
                    736:                call, DEF_BORDER, DEF_DIGITAL_PADDING, DEF_UPDATE,
                    737:                DEF_ANALOG_WIDTH, DEF_ANALOG_HEIGHT);
                    738:        printf ("Notes: The order in which switches are specified is not significant.\n");
                    739:        printf ("       In analog mode the second hand only appears for update times\n");
                    740:        printf ("       less than or equal to %d seconds.\n", SECOND_HAND_TIME);
                    741:        exit(0);
                    742: }
                    743: 
                    744: 
                    745: /*
                    746:  * XClockError - Fatal xclock error.
                    747:  */
                    748: XClockError (identifier)
                    749:        char *identifier;
                    750: {
                    751:        register Bool debug = XClockDebug;
                    752: 
                    753:        if (debug) printf("XClockError: Fatal xclock error encountered.\n");
                    754:        perror("xclock");
                    755:        fprintf(stderr, "xclock: %s\n", identifier);
                    756:        
                    757:        exit(1);
                    758: }
                    759: 
                    760: /*
                    761:  * End of xclock.c
                    762:  */

unix.superglobalmegacorp.com

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