Annotation of 43BSD/contrib/X/xclock/xclock.c, revision 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.