Annotation of 43BSD/contrib/X/xclock/xclock.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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