|
|
1.1 ! root 1: #ifndef lint ! 2: static char rcsid[] = "$Header: Clock.c,v 1.18 87/09/13 22:45:21 newman Exp $"; ! 3: #endif lint ! 4: ! 5: /* ! 6: * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. ! 7: * ! 8: * All Rights Reserved ! 9: * ! 10: * Permission to use, copy, modify, and distribute this software and its ! 11: * documentation for any purpose and without fee is hereby granted, ! 12: * provided that the above copyright notice appear in all copies and that ! 13: * both that copyright notice and this permission notice appear in ! 14: * supporting documentation, and that the name of Digital Equipment ! 15: * Corporation not be used in advertising or publicity pertaining to ! 16: * distribution of the software without specific, written prior permission. ! 17: * ! 18: * ! 19: * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 20: * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 21: * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 22: * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 23: * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 24: * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 25: * SOFTWARE. ! 26: */ ! 27: #include <sys/time.h> ! 28: ! 29: #include "Xlib.h" ! 30: #include "Xutil.h" ! 31: #include "Intrinsic.h" ! 32: #include "Clock.h" ! 33: #include "ClockP.h" ! 34: #include "Atoms.h" ! 35: ! 36: extern long time(); ! 37: static void clock_tic(), DrawHand(), DrawSecond(), SetSeg(), DrawClockFace(); ! 38: ! 39: /* Private Definitions */ ! 40: ! 41: #define VERTICES_IN_HANDS 6 /* to draw triangle */ ! 42: #define PI 3.14159265358979 ! 43: #define TWOPI (2. * PI) ! 44: ! 45: #define SECOND_HAND_FRACT 90 ! 46: #define MINUTE_HAND_FRACT 70 ! 47: #define HOUR_HAND_FRACT 40 ! 48: #define HAND_WIDTH_FRACT 7 ! 49: #define SECOND_WIDTH_FRACT 5 ! 50: #define SECOND_HAND_TIME 30 ! 51: ! 52: #define max(a, b) ((a) > (b) ? (a) : (b)) ! 53: #define min(a, b) ((a) < (b) ? (a) : (b)) ! 54: #define abs(a) ((a) < 0 ? -(a) : (a)) ! 55: ! 56: ! 57: /* Initialization of defaults */ ! 58: ! 59: #define offset(field) XtOffset(ClockWidget,clock.field) ! 60: #define goffset(field) XtOffset(Widget,core.field) ! 61: ! 62: static XtResource resources[] = { ! 63: {XtNwidth, XtCWidth, XrmRInt, sizeof(int), ! 64: goffset(width), XrmRString, "164"}, ! 65: {XtNheight, XtCHeight, XrmRInt, sizeof(int), ! 66: goffset(height), XrmRString, "164"}, ! 67: {XtNupdate, XtCInterval, XrmRInt, sizeof(int), ! 68: offset(update), XrmRString, "60" }, ! 69: {XtNforeground, XtCForeground, XrmRPixel, sizeof(Pixel), ! 70: offset(fgpixel), XrmRString, "Black"}, ! 71: {XtNhand, XtCForeground, XrmRPixel, sizeof(Pixel), ! 72: offset(Hdpixel), XrmRString, "Black"}, ! 73: {XtNhigh, XtCForeground, XrmRPixel, sizeof(Pixel), ! 74: offset(Hipixel), XrmRString, "Black"}, ! 75: {XtNanalog, XtCBoolean, XrmRBoolean, sizeof(Boolean), ! 76: offset(analog), XrmRString, "TRUE"}, ! 77: {XtNchime, XtCBoolean, XrmRBoolean, sizeof(Boolean), ! 78: offset(chime), XrmRString, "FALSE" }, ! 79: {XtNpadding, XtCMargin, XrmRInt, sizeof(int), ! 80: offset(padding), XrmRString, "8"}, ! 81: {XtNfont, XtCFont, XrmRFontStruct, sizeof(XFontStruct *), ! 82: offset(font), XrmRString, "6x10"}, ! 83: }; ! 84: ! 85: #undef offset ! 86: #undef goffset ! 87: ! 88: static void Initialize(), Realize(), Destroy(), Resize(), Redisplay(); ! 89: static Boolean SetValues(); ! 90: ! 91: ClockClassRec clockClassRec = { ! 92: { /* core fields */ ! 93: /* superclass */ &widgetClassRec, ! 94: /* class_name */ "Clock", ! 95: /* size */ sizeof(ClockRec), ! 96: /* class_initialize */ NULL, ! 97: /* class_inited */ FALSE, ! 98: /* initialize */ Initialize, ! 99: /* realize */ Realize, ! 100: /* actions */ NULL, ! 101: /* num_actions */ 0, ! 102: /* resources */ resources, ! 103: /* resource_count*/ XtNumber(resources), ! 104: /* xrm_class */ NULL, ! 105: /* compress_motion */ TRUE, ! 106: /* compress_exposure */TRUE, ! 107: /* visible_interest */ FALSE, ! 108: /* destroy */ Destroy, ! 109: /* resize */ Resize, ! 110: /* expose */ Redisplay, ! 111: /* set_values */ SetValues, ! 112: /* accept_focus */ NULL, ! 113: } ! 114: }; ! 115: ! 116: WidgetClass clockWidgetClass = (WidgetClass) &clockClassRec; ! 117: ! 118: /**************************************************************** ! 119: * ! 120: * Private Procedures ! 121: * ! 122: ****************************************************************/ ! 123: ! 124: ! 125: static void EventHandler(gw, closure, event) ! 126: Widget gw; ! 127: char *closure; ! 128: XEvent *event; ! 129: { ! 130: if (event->type == ClientMessage && event->xclient.message_type == XtTimerExpired) ! 131: clock_tic((ClockWidget)gw); ! 132: } ! 133: ! 134: static void Initialize (request, new) ! 135: Widget request, new; ! 136: { ! 137: ClockWidget w = (ClockWidget)new; ! 138: XtGCMask valuemask; ! 139: XGCValues myXGCV; ! 140: ! 141: if(!w->clock.analog) { ! 142: char *str; ! 143: struct tm tm, *localtime(); ! 144: long time_value; ! 145: int min_height, min_width; ! 146: (void) time(&time_value); ! 147: tm = *localtime(&time_value); ! 148: str = asctime(&tm); ! 149: min_width = XTextWidth(w->clock.font, str, strlen(str)) + ! 150: 2 * w->clock.padding; ! 151: min_height = w->clock.font->ascent + ! 152: w->clock.font->descent + 2 * w->clock.padding; ! 153: if (w->core.width < min_width) w->core.width = min_width; ! 154: if (w->core.height < min_height) w->core.width = min_height; ! 155: } ! 156: valuemask = GCForeground | GCBackground | GCFont | GCLineWidth; ! 157: myXGCV.foreground = w->clock.fgpixel; ! 158: myXGCV.background = w->core.background_pixel; ! 159: myXGCV.font = w->clock.font->fid; ! 160: myXGCV.line_width = 0; ! 161: w->clock.myGC = XtGetGC(w, valuemask, &myXGCV); ! 162: ! 163: valuemask = GCForeground | GCLineWidth ; ! 164: myXGCV.foreground = w->core.background_pixel; ! 165: w->clock.EraseGC = XtGetGC(w, valuemask, &myXGCV); ! 166: ! 167: myXGCV.foreground = w->clock.Hipixel; ! 168: w->clock.HighGC = XtGetGC(w, valuemask, &myXGCV); ! 169: ! 170: valuemask = GCForeground; ! 171: myXGCV.foreground = w->clock.Hdpixel; ! 172: w->clock.HandGC = XtGetGC(w, valuemask, &myXGCV); ! 173: ! 174: XtAddEventHandler (w, 0, TRUE, EventHandler, NULL); ! 175: ! 176: w->clock.interval_id = XtAddTimeOut(w, w->clock.update*1000); ! 177: w->clock.show_second_hand = (w->clock.update <= SECOND_HAND_TIME); ! 178: } ! 179: ! 180: static void Realize (gw, valueMask, attrs) ! 181: Widget gw; ! 182: XtValueMask valueMask; ! 183: XSetWindowAttributes *attrs; ! 184: { ! 185: valueMask |= CWBitGravity; ! 186: attrs->bit_gravity = ForgetGravity; ! 187: gw->core.window = XCreateWindow (XtDisplay(gw), ! 188: gw->core.parent->core.window, ! 189: gw->core.x, gw->core.y, ! 190: gw->core.width, gw->core.height, ! 191: gw->core.border_width, ! 192: gw->core.depth, InputOutput, ! 193: /* visualID */ CopyFromParent, ! 194: valueMask, attrs); ! 195: Resize(gw); ! 196: } ! 197: ! 198: static void Destroy (gw) ! 199: Widget gw; ! 200: { ! 201: ClockWidget w = (ClockWidget) gw; ! 202: XtRemoveTimeOut (w->clock.interval_id); ! 203: XtDestroyGC (w->clock.myGC); ! 204: XtDestroyGC (w->clock.HighGC); ! 205: XtDestroyGC (w->clock.HandGC); ! 206: XtDestroyGC (w->clock.EraseGC); ! 207: } ! 208: ! 209: static void Resize (gw) ! 210: Widget gw; ! 211: { ! 212: ClockWidget w = (ClockWidget) gw; ! 213: /* don't do this computation if window hasn't been realized yet. */ ! 214: if (XtIsRealized(gw) && w->clock.analog) { ! 215: w->clock.radius = (min(w->core.width, w->core.height)-(2 * w->clock.padding)) / 2; ! 216: w->clock.second_hand_length = ((SECOND_HAND_FRACT * w->clock.radius) / 100); ! 217: w->clock.minute_hand_length = ((MINUTE_HAND_FRACT * w->clock.radius) / 100); ! 218: w->clock.hour_hand_length = ((HOUR_HAND_FRACT * w->clock.radius) / 100); ! 219: w->clock.hand_width = ((HAND_WIDTH_FRACT * w->clock.radius) / 100); ! 220: w->clock.second_hand_width = ((SECOND_WIDTH_FRACT * w->clock.radius) / 100); ! 221: w->clock.centerX = w->core.width / 2; ! 222: w->clock.centerY = w->core.height / 2; ! 223: } ! 224: } ! 225: ! 226: static void Redisplay (gw) ! 227: Widget gw; ! 228: { ! 229: ClockWidget w = (ClockWidget) gw; ! 230: if (w->clock.analog) ! 231: DrawClockFace(w); ! 232: clock_tic(w); ! 233: } ! 234: ! 235: ! 236: static void clock_tic(w) ! 237: ClockWidget w; ! 238: { ! 239: ! 240: struct tm *localtime(); ! 241: struct tm tm; ! 242: long time_value; ! 243: char time_string[28]; ! 244: char *time_ptr = time_string; ! 245: register Display *dpy = XtDisplay(w); ! 246: register Window win = XtWindow(w); ! 247: ! 248: (void) time(&time_value); ! 249: tm = *localtime(&time_value); ! 250: /* ! 251: * Beep on the half hour; double-beep on the hour. ! 252: */ ! 253: if (w->clock.chime == TRUE) { ! 254: if (w->clock.beeped && (tm.tm_min != 30) && ! 255: (tm.tm_min != 0)) ! 256: w->clock.beeped = FALSE; ! 257: if (((tm.tm_min == 30) || (tm.tm_min == 0)) ! 258: && (!w->clock.beeped)) { ! 259: w->clock.beeped = TRUE; ! 260: XBell(dpy, 50); ! 261: if (tm.tm_min == 0) ! 262: XBell(dpy, 50); ! 263: } ! 264: } ! 265: if( w->clock.analog == FALSE ) { ! 266: time_ptr = asctime(&tm); ! 267: time_ptr[strlen(time_ptr) - 1] = 0; ! 268: XDrawImageString (dpy, win, w->clock.myGC, ! 269: 2+w->clock.padding, 2+w->clock.font->ascent+w->clock.padding, ! 270: time_ptr, strlen(time_ptr)); ! 271: } else { ! 272: /* ! 273: * The second (or minute) hand is sec (or min) ! 274: * sixtieths around the clock face. The hour hand is ! 275: * (hour + min/60) twelfths of the way around the ! 276: * clock-face. The derivation is left as an excercise ! 277: * for the reader. ! 278: */ ! 279: ! 280: /* ! 281: * 12 hour clock. ! 282: */ ! 283: if(tm.tm_hour > 12) ! 284: tm.tm_hour -= 12; ! 285: ! 286: /* ! 287: * Erase old hands. ! 288: */ ! 289: if(w->clock.numseg > 0) { ! 290: if (w->clock.show_second_hand == TRUE) { ! 291: XDrawLines(dpy, win, ! 292: w->clock.EraseGC, ! 293: w->clock.sec, ! 294: VERTICES_IN_HANDS-1, ! 295: CoordModeOrigin); ! 296: if(w->clock.Hdpixel != w->core.background_pixel) { ! 297: XFillPolygon(dpy, ! 298: win, w->clock.EraseGC, ! 299: w->clock.sec, ! 300: VERTICES_IN_HANDS-2, ! 301: Convex, CoordModeOrigin ! 302: ); ! 303: } ! 304: } ! 305: if( tm.tm_min != w->clock.otm.tm_min || ! 306: tm.tm_hour != w->clock.otm.tm_hour ) { ! 307: XDrawLines( dpy, ! 308: win, ! 309: w->clock.EraseGC, ! 310: w->clock.segbuff, ! 311: VERTICES_IN_HANDS, ! 312: CoordModeOrigin); ! 313: XDrawLines( dpy, ! 314: win, ! 315: w->clock.EraseGC, ! 316: w->clock.hour, ! 317: VERTICES_IN_HANDS, ! 318: CoordModeOrigin); ! 319: if(w->clock.Hdpixel != w->core.background_pixel) { ! 320: XFillPolygon( dpy, ! 321: win, w->clock.EraseGC, ! 322: w->clock.segbuff, VERTICES_IN_HANDS, ! 323: Convex, CoordModeOrigin ! 324: ); ! 325: XFillPolygon(dpy, ! 326: win, w->clock.EraseGC, ! 327: w->clock.hour, ! 328: VERTICES_IN_HANDS, ! 329: Convex, CoordModeOrigin ! 330: ); ! 331: } ! 332: } ! 333: } ! 334: ! 335: if (w->clock.numseg == 0 || ! 336: tm.tm_min != w->clock.otm.tm_min || ! 337: tm.tm_hour != w->clock.otm.tm_hour) { ! 338: w->clock.segbuffptr = w->clock.segbuff; ! 339: w->clock.numseg = 0; ! 340: /* ! 341: * Calculate the hour hand, fill it in with its ! 342: * color and then outline it. Next, do the same ! 343: * with the minute hand. This is a cheap hidden ! 344: * line algorithm. ! 345: */ ! 346: DrawHand(w, ! 347: w->clock.minute_hand_length, w->clock.hand_width, ! 348: ((double) tm.tm_min)/60.0 ! 349: ); ! 350: if(w->clock.Hdpixel != w->core.background_pixel) ! 351: XFillPolygon( dpy, ! 352: win, w->clock.HandGC, ! 353: w->clock.segbuff, VERTICES_IN_HANDS, ! 354: Convex, CoordModeOrigin ! 355: ); ! 356: XDrawLines( dpy, ! 357: win, w->clock.HighGC, ! 358: w->clock.segbuff, VERTICES_IN_HANDS, ! 359: CoordModeOrigin); ! 360: w->clock.hour = w->clock.segbuffptr; ! 361: DrawHand(w, ! 362: w->clock.hour_hand_length, w->clock.hand_width, ! 363: ((((double)tm.tm_hour) + ! 364: (((double)tm.tm_min)/60.0)) / 12.0) ! 365: ); ! 366: if(w->clock.Hdpixel != w->core.background_pixel) { ! 367: XFillPolygon(dpy, ! 368: win, w->clock.HandGC, ! 369: w->clock.hour, ! 370: VERTICES_IN_HANDS, ! 371: Convex, CoordModeOrigin ! 372: ); ! 373: } ! 374: XDrawLines( dpy, ! 375: win, w->clock.HighGC, ! 376: w->clock.hour, VERTICES_IN_HANDS, ! 377: CoordModeOrigin ); ! 378: ! 379: w->clock.sec = w->clock.segbuffptr; ! 380: } ! 381: if (w->clock.show_second_hand == TRUE) { ! 382: w->clock.segbuffptr = w->clock.sec; ! 383: DrawSecond(w, ! 384: w->clock.second_hand_length - 2, ! 385: w->clock.second_hand_width, ! 386: w->clock.minute_hand_length + 2, ! 387: ((double) tm.tm_sec)/60.0 ! 388: ); ! 389: if(w->clock.Hdpixel != w->core.background_pixel) ! 390: XFillPolygon( dpy, ! 391: win, w->clock.HandGC, ! 392: w->clock.sec, ! 393: VERTICES_IN_HANDS -2, ! 394: Convex, CoordModeOrigin ! 395: ); ! 396: XDrawLines( dpy, ! 397: win, w->clock.HighGC, ! 398: w->clock.sec, ! 399: VERTICES_IN_HANDS-1, ! 400: CoordModeOrigin ! 401: ); ! 402: ! 403: } ! 404: w->clock.otm = tm; ! 405: ! 406: } ! 407: } ! 408: ! 409: /* ! 410: * DrawLine - Draws a line. ! 411: * ! 412: * blank_length is the distance from the center which the line begins. ! 413: * length is the maximum length of the hand. ! 414: * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating ! 415: * how far around the circle (clockwise) from high noon. ! 416: * ! 417: * The blank_length feature is because I wanted to draw tick-marks around the ! 418: * circle (for seconds). The obvious means of drawing lines from the center ! 419: * to the perimeter, then erasing all but the outside most pixels doesn't ! 420: * work because of round-off error (sigh). ! 421: */ ! 422: static void DrawLine(w, blank_length, length, fraction_of_a_circle) ! 423: ClockWidget w; ! 424: Dimension blank_length; ! 425: Dimension length; ! 426: double fraction_of_a_circle; ! 427: { ! 428: register double angle, cosangle, sinangle; ! 429: double cos(); ! 430: double sin(); ! 431: ! 432: /* ! 433: * A full circle is 2 PI radians. ! 434: * Angles are measured from 12 o'clock, clockwise increasing. ! 435: * Since in X, +x is to the right and +y is downward: ! 436: * ! 437: * x = x0 + r * sin(theta) ! 438: * y = y0 - r * cos(theta) ! 439: * ! 440: */ ! 441: angle = TWOPI * fraction_of_a_circle; ! 442: cosangle = cos(angle); ! 443: sinangle = sin(angle); ! 444: ! 445: SetSeg(w, ! 446: w->clock.centerX + (int)(blank_length * sinangle), ! 447: w->clock.centerY - (int)(blank_length * cosangle), ! 448: w->clock.centerX + (int)(length * sinangle), ! 449: w->clock.centerY - (int)(length * cosangle)); ! 450: } ! 451: ! 452: /* ! 453: * DrawHand - Draws a hand. ! 454: * ! 455: * length is the maximum length of the hand. ! 456: * width is the half-width of the hand. ! 457: * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating ! 458: * how far around the circle (clockwise) from high noon. ! 459: * ! 460: */ ! 461: static void DrawHand(w, length, width, fraction_of_a_circle) ! 462: ClockWidget w; ! 463: Dimension length, width; ! 464: double fraction_of_a_circle; ! 465: { ! 466: ! 467: register double angle, cosangle, sinangle; ! 468: register double ws, wc; ! 469: Position x, y, x1, y1, x2, y2; ! 470: double cos(); ! 471: double sin(); ! 472: ! 473: /* ! 474: * A full circle is 2 PI radians. ! 475: * Angles are measured from 12 o'clock, clockwise increasing. ! 476: * Since in X, +x is to the right and +y is downward: ! 477: * ! 478: * x = x0 + r * sin(theta) ! 479: * y = y0 - r * cos(theta) ! 480: * ! 481: */ ! 482: angle = TWOPI * fraction_of_a_circle; ! 483: cosangle = cos(angle); ! 484: sinangle = sin(angle); ! 485: /* ! 486: * Order of points when drawing the hand. ! 487: * ! 488: * 1,4 ! 489: * / \ ! 490: * / \ ! 491: * / \ ! 492: * 2 ------- 3 ! 493: */ ! 494: wc = width * cosangle; ! 495: ws = width * sinangle; ! 496: SetSeg(w, ! 497: x = w->clock.centerX + round(length * sinangle), ! 498: y = w->clock.centerY - round(length * cosangle), ! 499: x1 = w->clock.centerX - round(ws + wc), ! 500: y1 = w->clock.centerY + round(wc - ws)); /* 1 ---- 2 */ ! 501: /* 2 */ ! 502: SetSeg(w, x1, y1, ! 503: x2 = w->clock.centerX - round(ws - wc), ! 504: y2 = w->clock.centerY + round(wc + ws)); /* 2 ----- 3 */ ! 505: ! 506: SetSeg(w, x2, y2, x, y); /* 3 ----- 1(4) */ ! 507: } ! 508: ! 509: /* ! 510: * DrawSecond - Draws the second hand (diamond). ! 511: * ! 512: * length is the maximum length of the hand. ! 513: * width is the half-width of the hand. ! 514: * offset is direct distance from center to tail end. ! 515: * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating ! 516: * how far around the circle (clockwise) from high noon. ! 517: * ! 518: */ ! 519: static void DrawSecond(w, length, width, offset, fraction_of_a_circle) ! 520: ClockWidget w; ! 521: Dimension length, width, offset; ! 522: double fraction_of_a_circle; ! 523: { ! 524: ! 525: register double angle, cosangle, sinangle; ! 526: register double ms, mc, ws, wc; ! 527: register int mid; ! 528: Position x, y; ! 529: double cos(); ! 530: double sin(); ! 531: ! 532: /* ! 533: * A full circle is 2 PI radians. ! 534: * Angles are measured from 12 o'clock, clockwise increasing. ! 535: * Since in X, +x is to the right and +y is downward: ! 536: * ! 537: * x = x0 + r * sin(theta) ! 538: * y = y0 - r * cos(theta) ! 539: * ! 540: */ ! 541: angle = TWOPI * fraction_of_a_circle; ! 542: cosangle = cos(angle); ! 543: sinangle = sin(angle); ! 544: /* ! 545: * Order of points when drawing the hand. ! 546: * ! 547: * 1,5 ! 548: * / \ ! 549: * / \ ! 550: * / \ ! 551: * 2< >4 ! 552: * \ / ! 553: * \ / ! 554: * \ / ! 555: * - 3 ! 556: * | ! 557: * | ! 558: * offset ! 559: * | ! 560: * | ! 561: * - + center ! 562: */ ! 563: ! 564: mid = (length + offset) / 2; ! 565: mc = mid * cosangle; ! 566: ms = mid * sinangle; ! 567: wc = width * cosangle; ! 568: ws = width * sinangle; ! 569: /*1 ---- 2 */ ! 570: SetSeg(w, ! 571: x = w->clock.centerX + round(length * sinangle), ! 572: y = w->clock.centerY - round(length * cosangle), ! 573: w->clock.centerX + round(ms - wc), ! 574: w->clock.centerY - round(mc + ws) ); ! 575: SetSeg(w, w->clock.centerX + round(offset *sinangle), ! 576: w->clock.centerY - round(offset * cosangle), /* 2-----3 */ ! 577: w->clock.centerX + round(ms + wc), ! 578: w->clock.centerY - round(mc - ws)); ! 579: w->clock.segbuffptr->x = x; ! 580: w->clock.segbuffptr++->y = y; ! 581: w->clock.numseg ++; ! 582: } ! 583: ! 584: static void SetSeg(w, x1, y1, x2, y2) ! 585: ClockWidget w; ! 586: int x1, y1, x2, y2; ! 587: { ! 588: w->clock.segbuffptr->x = x1; ! 589: w->clock.segbuffptr++->y = y1; ! 590: w->clock.segbuffptr->x = x2; ! 591: w->clock.segbuffptr++->y = y2; ! 592: w->clock.numseg += 2; ! 593: } ! 594: ! 595: /* ! 596: * Draw the clock face (every fifth tick-mark is longer ! 597: * than the others). ! 598: */ ! 599: static void DrawClockFace(w) ! 600: ClockWidget w; ! 601: { ! 602: register int i; ! 603: register int delta = (w->clock.radius - w->clock.second_hand_length) / 3; ! 604: ! 605: w->clock.segbuffptr = w->clock.segbuff; ! 606: w->clock.numseg = 0; ! 607: for (i = 0; i < 60; i++) ! 608: DrawLine(w, (i % 5) == 0 ? w->clock.second_hand_length : (w->clock.radius - delta), ! 609: w->clock.radius, ((double) i)/60.); ! 610: /* ! 611: * Go ahead and draw it. ! 612: */ ! 613: XDrawSegments(XtDisplay(w), XtWindow(w), ! 614: w->clock.myGC, (XSegment *) &(w->clock.segbuff[0]), ! 615: w->clock.numseg/2); ! 616: ! 617: w->clock.segbuffptr = w->clock.segbuff; ! 618: w->clock.numseg = 0; ! 619: } ! 620: ! 621: static int round(x) ! 622: double x; ! 623: { ! 624: return(x >= 0.0 ? (int)(x + .5) : (int)(x - .5)); ! 625: } ! 626: ! 627: static Boolean SetValues (gcurrent, grequest, gnew, last) ! 628: Widget gcurrent, grequest, gnew; ! 629: Boolean last; ! 630: { ! 631: ClockWidget current = (ClockWidget) gcurrent; ! 632: ClockWidget new = (ClockWidget) gnew; ! 633: Boolean redisplay = FALSE; ! 634: XtGCMask valuemask; ! 635: XGCValues myXGCV; ! 636: ! 637: /* first check for changes to clock-specific resources. We'll accept all ! 638: the changes, but may need to do some computations first. */ ! 639: ! 640: if (new->clock.update != current->clock.update) { ! 641: XtRemoveTimeOut (current->clock.interval_id); ! 642: new->clock.interval_id = XtAddTimeOut(gcurrent, new->clock.update*1000); ! 643: new->clock.show_second_hand = (new->clock.update <= SECOND_HAND_TIME); ! 644: } ! 645: ! 646: if (new->clock.analog != current->clock.analog) ! 647: redisplay = TRUE; ! 648: ! 649: if (new->clock.padding != current->clock.padding) { ! 650: Resize(gnew); ! 651: redisplay = TRUE; ! 652: } ! 653: ! 654: if (new->clock.font != current->clock.font) ! 655: redisplay = TRUE; ! 656: ! 657: if ((new->clock.fgpixel != current->clock.fgpixel) ! 658: || (new->core.background_pixel != current->core.background_pixel)) { ! 659: valuemask = GCForeground | GCBackground | GCFont | GCLineWidth; ! 660: myXGCV.foreground = new->clock.fgpixel; ! 661: myXGCV.background = new->core.background_pixel; ! 662: myXGCV.font = new->clock.font->fid; ! 663: myXGCV.line_width = 0; ! 664: XtDestroyGC (current->clock.myGC); ! 665: new->clock.myGC = XtGetGC(gcurrent, valuemask, &myXGCV); ! 666: redisplay = TRUE; ! 667: } ! 668: ! 669: if (new->clock.Hipixel != current->clock.Hipixel) { ! 670: valuemask = GCForeground | GCLineWidth; ! 671: myXGCV.foreground = new->clock.fgpixel; ! 672: myXGCV.font = new->clock.font->fid; ! 673: myXGCV.line_width = 0; ! 674: XtDestroyGC (current->clock.HighGC); ! 675: new->clock.HighGC = XtGetGC(gcurrent, valuemask, &myXGCV); ! 676: redisplay = TRUE; ! 677: } ! 678: ! 679: if (new->clock.Hdpixel != current->clock.Hdpixel) { ! 680: valuemask = GCForeground; ! 681: myXGCV.foreground = new->clock.fgpixel; ! 682: XtDestroyGC (current->clock.HandGC); ! 683: new->clock.HandGC = XtGetGC(gcurrent, valuemask, &myXGCV); ! 684: redisplay = TRUE; ! 685: } ! 686: ! 687: if (new->core.background_pixel != current->core.background_pixel) { ! 688: valuemask = GCForeground | GCLineWidth; ! 689: myXGCV.foreground = new->core.background_pixel; ! 690: myXGCV.line_width = 0; ! 691: XtDestroyGC (current->clock.EraseGC); ! 692: new->clock.EraseGC = XtGetGC(gcurrent, valuemask, &myXGCV); ! 693: redisplay = TRUE; ! 694: } ! 695: ! 696: if ((new->core.x != current->core.x) ! 697: || (new->core.y != current->core.y) ! 698: || (new->core.width != current->core.width) ! 699: || (new->core.height != current->core.height) ! 700: || (new->core.border_width != current->core.border_width)) ! 701: /* need to make geometry request */; ! 702: ! 703: return (redisplay); ! 704: ! 705: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.