rebuild geeqie
[oi-userland.git] / components / x11 / libXaw4 / src / Xaw3_1Clock.c
blobb64bc8e4438757d1af7d10d557e4698a6014dd40
1 #ifndef lint
2 static char Xrcsid[] = "$XConsortium: Clock.c,v 1.50 89/12/06 15:23:24 kit Exp $";
3 #endif /* lint */
6 /***********************************************************
7 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
8 and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
10 All Rights Reserved
12 Permission to use, copy, modify, and distribute this software and its
13 documentation for any purpose and without fee is hereby granted,
14 provided that the above copyright notice appear in all copies and that
15 both that copyright notice and this permission notice appear in
16 supporting documentation, and that the names of Digital or MIT not be
17 used in advertising or publicity pertaining to distribution of the
18 software without specific, written prior permission.
20 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
21 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
22 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
23 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
25 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
26 SOFTWARE.
28 ******************************************************************/
30 #include <time.h>
32 #include <X11/Xlib.h>
33 #include <X11/StringDefs.h>
34 #include <X11/IntrinsicP.h>
35 #include <./Xaw3_1XawInit.h>
36 #include <./Xaw3_1ClockP.h>
38 extern long time();
39 static void clock_tic(), DrawHand(), DrawSecond(), SetSeg(), DrawClockFace();
40 static void erase_hands();
41 static round();
43 /* Private Definitions */
45 #define VERTICES_IN_HANDS 6 /* to draw triangle */
46 #define PI 3.14159265358979
47 #define TWOPI (2. * PI)
49 #define SECOND_HAND_FRACT 90
50 #define MINUTE_HAND_FRACT 70
51 #define HOUR_HAND_FRACT 40
52 #define HAND_WIDTH_FRACT 7
53 #define SECOND_WIDTH_FRACT 5
54 #define SECOND_HAND_TIME 30
56 #define ANALOG_SIZE_DEFAULT 164
58 #define max(a, b) ((a) > (b) ? (a) : (b))
59 #define min(a, b) ((a) < (b) ? (a) : (b))
60 #define abs(a) ((a) < 0 ? -(a) : (a))
63 /* Initialization of defaults */
65 #define offset(field) XtOffset(ClockWidget,clock.field)
66 #define goffset(field) XtOffset(Widget,core.field)
68 static XtResource resources[] = {
69 {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
70 goffset(width), XtRImmediate, (caddr_t) 0},
71 {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
72 goffset(height), XtRImmediate, (caddr_t) 0},
73 {XtNbackground, XtCBackground, XtRPixel, sizeof(Pixel),
74 goffset(background_pixel), XtRString, "XtdefaultBackground"},
75 {XtNupdate, XtCInterval, XtRInt, sizeof(int),
76 offset(update), XtRImmediate, (caddr_t) 60 },
77 {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
78 offset(fgpixel), XtRString, "XtdefaultForeground"},
79 {XtNhand, XtCForeground, XtRPixel, sizeof(Pixel),
80 offset(Hdpixel), XtRString, "XtdefaultForeground"},
81 {XtNhighlight, XtCForeground, XtRPixel, sizeof(Pixel),
82 offset(Hipixel), XtRString, "XtdefaultForeground"},
83 {XtNanalog, XtCBoolean, XtRBoolean, sizeof(Boolean),
84 offset(analog), XtRImmediate, (caddr_t) TRUE},
85 {XtNchime, XtCBoolean, XtRBoolean, sizeof(Boolean),
86 offset(chime), XtRImmediate, (caddr_t) FALSE },
87 {XtNpadding, XtCMargin, XtRInt, sizeof(int),
88 offset(padding), XtRImmediate, (caddr_t) 8},
89 {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
90 offset(font), XtRString, "fixed"},
91 {XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
92 offset (reverse_video), XtRImmediate, (caddr_t) FALSE},
93 {XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof (int),
94 offset (backing_store), XtRString, "default"},
97 #undef offset
98 #undef goffset
100 static void ClassInitialize();
101 static void Initialize(), Realize(), Destroy(), Resize(), Redisplay();
102 static Boolean SetValues();
104 ClockClassRec clockClassRec = {
105 { /* core fields */
106 /* superclass */ &widgetClassRec,
107 /* class_name */ "Clock",
108 /* widget_size */ sizeof(ClockRec),
109 /* class_initialize */ ClassInitialize,
110 /* class_part_initialize */ NULL,
111 /* class_inited */ FALSE,
112 /* initialize */ Initialize,
113 /* initialize_hook */ NULL,
114 /* realize */ Realize,
115 /* actions */ NULL,
116 /* num_actions */ 0,
117 /* resources */ resources,
118 /* resource_count */ XtNumber(resources),
119 /* xrm_class */ NULL,
120 /* compress_motion */ TRUE,
121 /* compress_exposure */ TRUE,
122 /* compress_enterleave */ TRUE,
123 /* visible_interest */ FALSE,
124 /* destroy */ Destroy,
125 /* resize */ Resize,
126 /* expose */ Redisplay,
127 /* set_values */ SetValues,
128 /* set_values_hook */ NULL,
129 /* set_values_almost */ XtInheritSetValuesAlmost,
130 /* get_values_hook */ NULL,
131 /* accept_focus */ NULL,
132 /* version */ XtVersion,
133 /* callback_private */ NULL,
134 /* tm_table */ NULL,
135 /* query_geometry */ XtInheritQueryGeometry,
136 /* display_accelerator */ XtInheritDisplayAccelerator,
137 /* extension */ NULL
141 WidgetClass clockWidgetClass = (WidgetClass) &clockClassRec;
143 /****************************************************************
145 * Private Procedures
147 ****************************************************************/
149 static void ClassInitialize()
151 XawInitializeWidgetSet();
152 XtAddConverter( XtRString, XtRBackingStore, XmuCvtStringToBackingStore,
153 NULL, 0 );
156 /* ARGSUSED */
157 static void Initialize (request, new)
158 Widget request, new;
160 ClockWidget w = (ClockWidget)new;
161 XtGCMask valuemask;
162 XGCValues myXGCV;
163 int min_height, min_width;
165 valuemask = GCForeground | GCBackground | GCFont | GCLineWidth;
166 if (w->clock.font != NULL)
167 myXGCV.font = w->clock.font->fid;
168 else
169 valuemask &= ~GCFont; /* use server default font */
171 min_width = min_height = ANALOG_SIZE_DEFAULT;
172 if(!w->clock.analog) {
173 char *str;
174 struct tm tm;
175 long time_value;
176 (void) time(&time_value);
177 tm = *localtime(&time_value);
178 str = asctime(&tm);
179 if (w->clock.font == NULL)
180 w->clock.font = XQueryFont( XtDisplay(w),
181 XGContextFromGC(
182 DefaultGCOfScreen(XtScreen(w))) );
183 min_width = XTextWidth(w->clock.font, str, strlen(str)) +
184 2 * w->clock.padding;
185 min_height = w->clock.font->ascent +
186 w->clock.font->descent + 2 * w->clock.padding;
188 if (w->core.width == 0)
189 w->core.width = min_width;
190 if (w->core.height == 0)
191 w->core.height = min_height;
193 myXGCV.foreground = w->clock.fgpixel;
194 myXGCV.background = w->core.background_pixel;
195 if (w->clock.font != NULL)
196 myXGCV.font = w->clock.font->fid;
197 else
198 valuemask &= ~GCFont; /* use server default font */
199 myXGCV.line_width = 0;
200 w->clock.myGC = XtGetGC((Widget)w, valuemask, &myXGCV);
202 valuemask = GCForeground | GCLineWidth ;
203 myXGCV.foreground = w->core.background_pixel;
204 w->clock.EraseGC = XtGetGC((Widget)w, valuemask, &myXGCV);
206 myXGCV.foreground = w->clock.Hipixel;
207 w->clock.HighGC = XtGetGC((Widget)w, valuemask, &myXGCV);
209 valuemask = GCForeground;
210 myXGCV.foreground = w->clock.Hdpixel;
211 w->clock.HandGC = XtGetGC((Widget)w, valuemask, &myXGCV);
213 if (w->clock.update <= 0)
214 w->clock.update = 60; /* make invalid update's use a default */
215 w->clock.show_second_hand = (w->clock.update <= SECOND_HAND_TIME);
216 w->clock.numseg = 0;
217 w->clock.interval_id = 0;
220 static void Realize (gw, valueMask, attrs)
221 Widget gw;
222 XtValueMask *valueMask;
223 XSetWindowAttributes *attrs;
225 ClockWidget w = (ClockWidget) gw;
226 #ifdef notdef
227 *valueMask |= CWBitGravity;
228 attrs->bit_gravity = ForgetGravity;
229 #endif
230 switch (w->clock.backing_store) {
231 case Always:
232 case NotUseful:
233 case WhenMapped:
234 *valueMask |=CWBackingStore;
235 attrs->backing_store = w->clock.backing_store;
236 break;
238 XtCreateWindow( gw, InputOutput, (Visual *)CopyFromParent,
239 *valueMask, attrs);
240 Resize(gw);
243 static void Destroy (gw)
244 Widget gw;
246 ClockWidget w = (ClockWidget) gw;
247 if (w->clock.interval_id) XtRemoveTimeOut (w->clock.interval_id);
248 XtDestroyGC (w->clock.myGC);
249 XtDestroyGC (w->clock.HighGC);
250 XtDestroyGC (w->clock.HandGC);
251 XtDestroyGC (w->clock.EraseGC);
254 static void Resize (gw)
255 Widget gw;
257 ClockWidget w = (ClockWidget) gw;
258 /* don't do this computation if window hasn't been realized yet. */
259 if (XtIsRealized(gw) && w->clock.analog) {
260 /* need signed value since Dimension is unsigned */
261 int radius = ((int) min(w->core.width, w->core.height) - (int) (2 * w->clock.padding)) / 2;
262 w->clock.radius = (Dimension) max (radius, 1);
264 w->clock.second_hand_length = ((SECOND_HAND_FRACT * w->clock.radius) / 100);
265 w->clock.minute_hand_length = ((MINUTE_HAND_FRACT * w->clock.radius) / 100);
266 w->clock.hour_hand_length = ((HOUR_HAND_FRACT * w->clock.radius) / 100);
267 w->clock.hand_width = ((HAND_WIDTH_FRACT * w->clock.radius) / 100);
268 w->clock.second_hand_width = ((SECOND_WIDTH_FRACT * w->clock.radius) / 100);
270 w->clock.centerX = w->core.width / 2;
271 w->clock.centerY = w->core.height / 2;
275 /* ARGSUSED */
276 static void Redisplay (gw, event, region)
277 Widget gw;
278 XEvent *event; /* unused */
279 Region region; /* unused */
281 ClockWidget w = (ClockWidget) gw;
282 if (w->clock.analog) {
283 if (w->clock.numseg != 0)
284 erase_hands (w, (struct tm *) 0);
285 DrawClockFace(w);
286 } else {
287 w->clock.prev_time_string[0] = '\0';
289 clock_tic((caddr_t)w, (XtIntervalId)0);
292 /* ARGSUSED */
293 static void clock_tic(client_data, id)
294 caddr_t client_data;
295 XtIntervalId *id;
297 ClockWidget w = (ClockWidget)client_data;
298 struct tm tm;
299 long time_value;
300 char *time_ptr;
301 register Display *dpy = XtDisplay(w);
302 register Window win = XtWindow(w);
304 if (id || !w->clock.interval_id)
305 w->clock.interval_id =
306 XtAppAddTimeOut( XtWidgetToApplicationContext( (Widget) w),
307 w->clock.update*1000,
308 (XtTimerCallbackProc)clock_tic, (caddr_t)w );
309 (void) time(&time_value);
310 tm = *localtime(&time_value);
312 * Beep on the half hour; double-beep on the hour.
314 if (w->clock.chime == TRUE) {
315 if (w->clock.beeped && (tm.tm_min != 30) &&
316 (tm.tm_min != 0))
317 w->clock.beeped = FALSE;
318 if (((tm.tm_min == 30) || (tm.tm_min == 0))
319 && (!w->clock.beeped)) {
320 w->clock.beeped = TRUE;
321 XBell(dpy, 50);
322 if (tm.tm_min == 0)
323 XBell(dpy, 50);
326 if( w->clock.analog == FALSE ) {
327 int clear_from;
328 int i, len, prev_len;
330 time_ptr = asctime(&tm);
331 len = strlen (time_ptr);
332 if (time_ptr[len - 1] == '\n') time_ptr[--len] = '\0';
333 prev_len = strlen (w->clock.prev_time_string);
334 for (i = 0; ((i < len) && (i < prev_len) &&
335 (w->clock.prev_time_string[i] == time_ptr[i])); i++);
336 strcpy (w->clock.prev_time_string+i, time_ptr+i);
338 XDrawImageString (dpy, win, w->clock.myGC,
339 (2+w->clock.padding +
340 XTextWidth (w->clock.font, time_ptr, i)),
341 2+w->clock.font->ascent+w->clock.padding,
342 time_ptr + i, len - i);
344 * Clear any left over bits
346 clear_from = XTextWidth (w->clock.font, time_ptr, len)
347 + 2 + w->clock.padding;
348 if (clear_from < w->core.width)
349 XFillRectangle (dpy, win, w->clock.EraseGC,
350 clear_from, 0, w->core.width - clear_from, w->core.height);
351 } else {
353 * The second (or minute) hand is sec (or min)
354 * sixtieths around the clock face. The hour hand is
355 * (hour + min/60) twelfths of the way around the
356 * clock-face. The derivation is left as an excercise
357 * for the reader.
361 * 12 hour clock.
363 if(tm.tm_hour > 12)
364 tm.tm_hour -= 12;
366 erase_hands (w, &tm);
368 if (w->clock.numseg == 0 ||
369 tm.tm_min != w->clock.otm.tm_min ||
370 tm.tm_hour != w->clock.otm.tm_hour) {
371 w->clock.segbuffptr = w->clock.segbuff;
372 w->clock.numseg = 0;
374 * Calculate the hour hand, fill it in with its
375 * color and then outline it. Next, do the same
376 * with the minute hand. This is a cheap hidden
377 * line algorithm.
379 DrawHand(w,
380 w->clock.minute_hand_length, w->clock.hand_width,
381 ((double) tm.tm_min)/60.0
383 if(w->clock.Hdpixel != w->core.background_pixel)
384 XFillPolygon( dpy,
385 win, w->clock.HandGC,
386 w->clock.segbuff, VERTICES_IN_HANDS,
387 Convex, CoordModeOrigin
389 XDrawLines( dpy,
390 win, w->clock.HighGC,
391 w->clock.segbuff, VERTICES_IN_HANDS,
392 CoordModeOrigin);
393 w->clock.hour = w->clock.segbuffptr;
394 DrawHand(w,
395 w->clock.hour_hand_length, w->clock.hand_width,
396 ((((double)tm.tm_hour) +
397 (((double)tm.tm_min)/60.0)) / 12.0)
399 if(w->clock.Hdpixel != w->core.background_pixel) {
400 XFillPolygon(dpy,
401 win, w->clock.HandGC,
402 w->clock.hour,
403 VERTICES_IN_HANDS,
404 Convex, CoordModeOrigin
407 XDrawLines( dpy,
408 win, w->clock.HighGC,
409 w->clock.hour, VERTICES_IN_HANDS,
410 CoordModeOrigin );
412 w->clock.sec = w->clock.segbuffptr;
414 if (w->clock.show_second_hand == TRUE) {
415 w->clock.segbuffptr = w->clock.sec;
416 DrawSecond(w,
417 w->clock.second_hand_length - 2,
418 w->clock.second_hand_width,
419 w->clock.minute_hand_length + 2,
420 ((double) tm.tm_sec)/60.0
422 if(w->clock.Hdpixel != w->core.background_pixel)
423 XFillPolygon( dpy,
424 win, w->clock.HandGC,
425 w->clock.sec,
426 VERTICES_IN_HANDS -2,
427 Convex, CoordModeOrigin
429 XDrawLines( dpy,
430 win, w->clock.HighGC,
431 w->clock.sec,
432 VERTICES_IN_HANDS-1,
433 CoordModeOrigin
437 w->clock.otm = tm;
441 static void erase_hands (w, tm)
442 ClockWidget w;
443 struct tm *tm;
446 * Erase old hands.
448 if(w->clock.numseg > 0) {
449 Display *dpy;
450 Window win;
452 dpy = XtDisplay (w);
453 win = XtWindow (w);
454 if (w->clock.show_second_hand == TRUE) {
455 XDrawLines(dpy, win,
456 w->clock.EraseGC,
457 w->clock.sec,
458 VERTICES_IN_HANDS-1,
459 CoordModeOrigin);
460 if(w->clock.Hdpixel != w->core.background_pixel) {
461 XFillPolygon(dpy,
462 win, w->clock.EraseGC,
463 w->clock.sec,
464 VERTICES_IN_HANDS-2,
465 Convex, CoordModeOrigin
469 if(!tm || tm->tm_min != w->clock.otm.tm_min ||
470 tm->tm_hour != w->clock.otm.tm_hour)
472 XDrawLines( dpy, win,
473 w->clock.EraseGC,
474 w->clock.segbuff,
475 VERTICES_IN_HANDS,
476 CoordModeOrigin);
477 XDrawLines( dpy, win,
478 w->clock.EraseGC,
479 w->clock.hour,
480 VERTICES_IN_HANDS,
481 CoordModeOrigin);
482 if(w->clock.Hdpixel != w->core.background_pixel) {
483 XFillPolygon( dpy, win,
484 w->clock.EraseGC,
485 w->clock.segbuff, VERTICES_IN_HANDS,
486 Convex, CoordModeOrigin);
487 XFillPolygon( dpy, win,
488 w->clock.EraseGC,
489 w->clock.hour,
490 VERTICES_IN_HANDS,
491 Convex, CoordModeOrigin);
498 * DrawLine - Draws a line.
500 * blank_length is the distance from the center which the line begins.
501 * length is the maximum length of the hand.
502 * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
503 * how far around the circle (clockwise) from high noon.
504 ***** Note: in this routine, fraction_of_a_circle is actually the minute
505 ***** tic we are drawing, 0 through 59. This is due to a Solaris 2.0
506 ***** compiler bug I was not able to work around any other way. C'est la vie.
509 * The blank_length feature is because I wanted to draw tick-marks around the
510 * circle (for seconds). The obvious means of drawing lines from the center
511 * to the perimeter, then erasing all but the outside most pixels doesn't
512 * work because of round-off error (sigh).
514 static void DrawLine(w, blank_length, length, fraction_of_a_circle)
515 ClockWidget w;
516 Dimension blank_length;
517 Dimension length;
518 int fraction_of_a_circle;
520 double dblank_length = (double)blank_length, dlength = (double)length;
521 double angle, cosangle, sinangle;
522 double cos();
523 double sin();
524 int cx = w->clock.centerX, cy = w->clock.centerY, x1, y1, x2, y2;
527 * A full circle is 2 PI radians.
528 * Angles are measured from 12 o'clock, clockwise increasing.
529 * Since in X, +x is to the right and +y is downward:
531 * x = x0 + r * sin(theta)
532 * y = y0 - r * cos(theta)
535 angle = TWOPI * (double) fraction_of_a_circle / 60. ;
536 cosangle = cos(angle);
537 sinangle = sin(angle);
539 /* break this out so that stupid compilers can cope */
540 x1 = cx + (int)(dblank_length * sinangle);
541 y1 = cy - (int)(dblank_length * cosangle);
542 x2 = cx + (int)(dlength * sinangle);
543 y2 = cy - (int)(dlength * cosangle);
544 SetSeg(w, x1, y1, x2, y2);
548 * DrawHand - Draws a hand.
550 * length is the maximum length of the hand.
551 * width is the half-width of the hand.
552 * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
553 * how far around the circle (clockwise) from high noon.
556 static void DrawHand(w, length, width, fraction_of_a_circle)
557 ClockWidget w;
558 Dimension length, width;
559 double fraction_of_a_circle;
562 register double angle, cosangle, sinangle;
563 register double ws, wc;
564 Position x, y, x1, y1, x2, y2;
565 double cos();
566 double sin();
569 * A full circle is 2 PI radians.
570 * Angles are measured from 12 o'clock, clockwise increasing.
571 * Since in X, +x is to the right and +y is downward:
573 * x = x0 + r * sin(theta)
574 * y = y0 - r * cos(theta)
577 angle = TWOPI * fraction_of_a_circle;
578 cosangle = cos(angle);
579 sinangle = sin(angle);
581 * Order of points when drawing the hand.
583 * 1,4
584 * / \
585 * / \
586 * / \
587 * 2 ------- 3
589 wc = width * cosangle;
590 ws = width * sinangle;
591 SetSeg(w,
592 x = w->clock.centerX + round(length * sinangle),
593 y = w->clock.centerY - round(length * cosangle),
594 x1 = w->clock.centerX - round(ws + wc),
595 y1 = w->clock.centerY + round(wc - ws)); /* 1 ---- 2 */
596 /* 2 */
597 SetSeg(w, x1, y1,
598 x2 = w->clock.centerX - round(ws - wc),
599 y2 = w->clock.centerY + round(wc + ws)); /* 2 ----- 3 */
601 SetSeg(w, x2, y2, x, y); /* 3 ----- 1(4) */
605 * DrawSecond - Draws the second hand (diamond).
607 * length is the maximum length of the hand.
608 * width is the half-width of the hand.
609 * offset is direct distance from center to tail end.
610 * Fraction_of_a_circle is a fraction between 0 and 1 (inclusive) indicating
611 * how far around the circle (clockwise) from high noon.
614 static void DrawSecond(w, length, width, offset, fraction_of_a_circle)
615 ClockWidget w;
616 Dimension length, width, offset;
617 double fraction_of_a_circle;
620 register double angle, cosangle, sinangle;
621 register double ms, mc, ws, wc;
622 register int mid;
623 Position x, y;
624 double cos();
625 double sin();
628 * A full circle is 2 PI radians.
629 * Angles are measured from 12 o'clock, clockwise increasing.
630 * Since in X, +x is to the right and +y is downward:
632 * x = x0 + r * sin(theta)
633 * y = y0 - r * cos(theta)
636 angle = TWOPI * fraction_of_a_circle;
637 cosangle = cos(angle);
638 sinangle = sin(angle);
640 * Order of points when drawing the hand.
642 * 1,5
643 * / \
644 * / \
645 * / \
646 * 2< >4
647 * \ /
648 * \ /
649 * \ /
650 * - 3
653 * offset
656 * - + center
659 mid = (length + offset) / 2;
660 mc = mid * cosangle;
661 ms = mid * sinangle;
662 wc = width * cosangle;
663 ws = width * sinangle;
664 /*1 ---- 2 */
665 SetSeg(w,
666 x = w->clock.centerX + round(length * sinangle),
667 y = w->clock.centerY - round(length * cosangle),
668 w->clock.centerX + round(ms - wc),
669 w->clock.centerY - round(mc + ws) );
670 SetSeg(w, w->clock.centerX + round(offset *sinangle),
671 w->clock.centerY - round(offset * cosangle), /* 2-----3 */
672 w->clock.centerX + round(ms + wc),
673 w->clock.centerY - round(mc - ws));
674 w->clock.segbuffptr->x = x;
675 w->clock.segbuffptr++->y = y;
676 w->clock.numseg ++;
679 static void SetSeg(w, x1, y1, x2, y2)
680 ClockWidget w;
681 int x1, y1, x2, y2;
683 w->clock.segbuffptr->x = x1;
684 w->clock.segbuffptr++->y = y1;
685 w->clock.segbuffptr->x = x2;
686 w->clock.segbuffptr++->y = y2;
687 w->clock.numseg += 2;
691 * Draw the clock face (every fifth tick-mark is longer
692 * than the others).
694 static void DrawClockFace(w)
695 ClockWidget w;
697 register int i;
698 register int delta = (w->clock.radius - w->clock.second_hand_length) / 3;
700 w->clock.segbuffptr = w->clock.segbuff;
701 w->clock.numseg = 0;
702 for (i = 0; i < 60; i++)
703 DrawLine(w, ( (i % 5) == 0 ?
704 w->clock.second_hand_length :
705 (w->clock.radius - delta) ),
706 w->clock.radius, i );
707 /* Changed last argument to DrawLine from i/60. to i due
708 * to compiler bug. Updated DrawLine function to reflect this.
712 * Go ahead and draw it.
714 XDrawSegments(XtDisplay(w), XtWindow(w),
715 w->clock.myGC, (XSegment *) &(w->clock.segbuff[0]),
716 w->clock.numseg/2);
718 w->clock.segbuffptr = w->clock.segbuff;
719 w->clock.numseg = 0;
722 static int round(x)
723 double x;
725 return(x >= 0.0 ? (int)(x + .5) : (int)(x - .5));
728 /* ARGSUSED */
729 static Boolean SetValues (gcurrent, grequest, gnew)
730 Widget gcurrent, grequest, gnew;
732 ClockWidget current = (ClockWidget) gcurrent;
733 ClockWidget new = (ClockWidget) gnew;
734 Boolean redisplay = FALSE;
735 XtGCMask valuemask;
736 XGCValues myXGCV;
738 /* first check for changes to clock-specific resources. We'll accept all
739 the changes, but may need to do some computations first. */
741 if (new->clock.update != current->clock.update) {
742 if (current->clock.interval_id)
743 XtRemoveTimeOut (current->clock.interval_id);
744 if (XtIsRealized((Widget)new))
745 new->clock.interval_id = XtAppAddTimeOut(
746 XtWidgetToApplicationContext(gnew),
747 new->clock.update*1000,
748 (XtTimerCallbackProc)clock_tic,
749 (caddr_t)gnew);
751 new->clock.show_second_hand =(new->clock.update <= SECOND_HAND_TIME);
754 if (new->clock.padding != current->clock.padding)
755 redisplay = TRUE;
757 if (new->clock.analog != current->clock.analog)
758 redisplay = TRUE;
760 if (new->clock.font != current->clock.font)
761 redisplay = TRUE;
763 if ((new->clock.fgpixel != current->clock.fgpixel)
764 || (new->core.background_pixel != current->core.background_pixel)) {
765 valuemask = GCForeground | GCBackground | GCFont | GCLineWidth;
766 myXGCV.foreground = new->clock.fgpixel;
767 myXGCV.background = new->core.background_pixel;
768 myXGCV.font = new->clock.font->fid;
769 myXGCV.line_width = 0;
770 XtDestroyGC (current->clock.myGC);
771 new->clock.myGC = XtGetGC(gcurrent, valuemask, &myXGCV);
772 redisplay = TRUE;
775 if (new->clock.Hipixel != current->clock.Hipixel) {
776 valuemask = GCForeground | GCLineWidth;
777 myXGCV.foreground = new->clock.fgpixel;
778 myXGCV.font = new->clock.font->fid;
779 myXGCV.line_width = 0;
780 XtDestroyGC (current->clock.HighGC);
781 new->clock.HighGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV);
782 redisplay = TRUE;
785 if (new->clock.Hdpixel != current->clock.Hdpixel) {
786 valuemask = GCForeground;
787 myXGCV.foreground = new->clock.fgpixel;
788 XtDestroyGC (current->clock.HandGC);
789 new->clock.HandGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV);
790 redisplay = TRUE;
793 if (new->core.background_pixel != current->core.background_pixel) {
794 valuemask = GCForeground | GCLineWidth;
795 myXGCV.foreground = new->core.background_pixel;
796 myXGCV.line_width = 0;
797 XtDestroyGC (current->clock.EraseGC);
798 new->clock.EraseGC = XtGetGC((Widget)gcurrent, valuemask, &myXGCV);
799 redisplay = TRUE;
802 return (redisplay);