1 | /* |
---|
2 | * $Id: AClock.c,v 1.2 1999-01-22 23:16:45 ghudson Exp $ |
---|
3 | * |
---|
4 | * Copyright 1990, 1991 by the Massachusetts Institute of Technology. |
---|
5 | * |
---|
6 | * For copying and distribution information, please see the file |
---|
7 | * <mit-copyright.h>. |
---|
8 | * |
---|
9 | */ |
---|
10 | |
---|
11 | #if (!defined(lint)) && (!defined(SABER)) |
---|
12 | static char *rcsid = |
---|
13 | "$Id: AClock.c,v 1.2 1999-01-22 23:16:45 ghudson Exp $"; |
---|
14 | #endif |
---|
15 | |
---|
16 | #include "mit-copyright.h" |
---|
17 | #include <stdio.h> |
---|
18 | #include <X11/Xos.h> /* needed for <time.h> or <sys/time.h> */ |
---|
19 | #include <math.h> |
---|
20 | #include "Jets.h" |
---|
21 | #include "AClock.h" |
---|
22 | |
---|
23 | #ifdef SHAPE |
---|
24 | #include <X11/extensions/shape.h> |
---|
25 | #endif |
---|
26 | |
---|
27 | #include "sintable.h" |
---|
28 | |
---|
29 | extern int DEBUG; |
---|
30 | |
---|
31 | #define offset(field) XjOffset(AClockJet,field) |
---|
32 | |
---|
33 | static XjResource resources[] = { |
---|
34 | { XjNx, XjCX, XjRInt, sizeof(int), |
---|
35 | offset(core.x), XjRString, XjInheritValue }, |
---|
36 | { XjNy, XjCY, XjRInt, sizeof(int), |
---|
37 | offset(core.y), XjRString, XjInheritValue }, |
---|
38 | { XjNwidth, XjCWidth, XjRInt, sizeof(int), |
---|
39 | offset(core.width), XjRString, XjInheritValue }, |
---|
40 | { XjNheight, XjCHeight, XjRInt, sizeof(int), |
---|
41 | offset(core.height), XjRString, XjInheritValue }, |
---|
42 | { XjNpadding, XjCPadding, XjRInt, sizeof(int), |
---|
43 | offset(aClock.padding), XjRString, "7" }, |
---|
44 | { XjNminorTick, XjCTick, XjRInt, sizeof(int), |
---|
45 | offset(aClock.minorTick), XjRString, "1" }, |
---|
46 | { XjNmajorTick, XjCTick, XjRInt, sizeof(int), |
---|
47 | offset(aClock.majorTick), XjRString, "5" }, |
---|
48 | { XjNminorStart, XjCTick, XjRInt, sizeof(int), |
---|
49 | offset(aClock.minorStart), XjRString, "97" }, |
---|
50 | { XjNminorEnd, XjCTick, XjRInt, sizeof(int), |
---|
51 | offset(aClock.minorEnd), XjRString, "99" }, |
---|
52 | { XjNmajorStart, XjCTick, XjRInt, sizeof(int), |
---|
53 | offset(aClock.majorStart), XjRString, "90" }, |
---|
54 | { XjNmajorEnd, XjCTick, XjRInt, sizeof(int), |
---|
55 | offset(aClock.majorEnd), XjRString, "100" }, |
---|
56 | { XjNsecondStart, XjCHand, XjRInt, sizeof(int), |
---|
57 | offset(aClock.secondStart), XjRString, "73" }, |
---|
58 | { XjNsecondEnd, XjCHand, XjRInt, sizeof(int), |
---|
59 | offset(aClock.secondEnd), XjRString, "88" }, |
---|
60 | { XjNsecondArc, XjCArc, XjRInt, sizeof(int), |
---|
61 | offset(aClock.secondArc), XjRString, "6" }, |
---|
62 | { XjNminuteStart, XjCHand, XjRInt, sizeof(int), |
---|
63 | offset(aClock.minuteStart), XjRString, "71" }, |
---|
64 | { XjNminuteEnd, XjCHand, XjRInt, sizeof(int), |
---|
65 | offset(aClock.minuteEnd), XjRString, "-10" }, |
---|
66 | { XjNminuteArc, XjCArc, XjRInt, sizeof(int), |
---|
67 | offset(aClock.minuteArc), XjRString, "100" }, |
---|
68 | { XjNhourStart, XjCHand, XjRInt, sizeof(int), |
---|
69 | offset(aClock.hourStart), XjRString, "45" }, |
---|
70 | { XjNhourEnd, XjCHand, XjRInt, sizeof(int), |
---|
71 | offset(aClock.hourEnd), XjRString, "-10" }, |
---|
72 | { XjNhourArc, XjCArc, XjRInt, sizeof(int), |
---|
73 | offset(aClock.hourArc), XjRString, "100" }, |
---|
74 | { XjNforeground, XjCForeground, XjRColor, sizeof(int), |
---|
75 | offset(aClock.foreground), XjRString, XjDefaultForeground }, |
---|
76 | { XjNbackground, XjCBackground, XjRColor, sizeof(int), |
---|
77 | offset(aClock.background), XjRString, XjDefaultBackground }, |
---|
78 | { XjNhands, XjCForeground, XjRColor, sizeof(int), |
---|
79 | offset(aClock.hands), XjRString, XjDefaultForeground }, |
---|
80 | { XjNhighlight, XjCForeground, XjRColor, sizeof(int), |
---|
81 | offset(aClock.highlight), XjRString, XjDefaultForeground }, |
---|
82 | { XjNreverseVideo, XjCReverseVideo, XjRBoolean, sizeof(Boolean), |
---|
83 | offset(aClock.reverseVideo), XjRBoolean, (caddr_t) False }, |
---|
84 | { XjNupdate, XjCInterval, XjRInt, sizeof(int), |
---|
85 | offset(aClock.update), XjRString, "1" }, |
---|
86 | { XjNkeepRound, XjCKeepRound, XjRBoolean, sizeof(Boolean), |
---|
87 | offset(aClock.keepRound), XjRBoolean, (caddr_t) False }, |
---|
88 | #ifdef SHAPE |
---|
89 | { XjNround, XjCRound, XjRBoolean, sizeof(Boolean), |
---|
90 | offset(aClock.round), XjRBoolean, (caddr_t) False }, |
---|
91 | #endif |
---|
92 | }; |
---|
93 | |
---|
94 | #undef offset |
---|
95 | |
---|
96 | static void wakeup(), expose(), realize(), querySize(), move(), |
---|
97 | resize(), initialize(), destroy(); |
---|
98 | |
---|
99 | AClockClassRec aClockClassRec = { |
---|
100 | { |
---|
101 | /* class name */ "AnalogClock", |
---|
102 | /* jet size */ sizeof(AClockRec), |
---|
103 | /* classInitialize */ NULL, |
---|
104 | /* classInitialized? */ 1, |
---|
105 | /* initialize */ initialize, |
---|
106 | /* prerealize */ NULL, |
---|
107 | /* realize */ realize, |
---|
108 | /* event */ NULL, |
---|
109 | /* expose */ expose, |
---|
110 | /* querySize */ querySize, |
---|
111 | /* move */ move, |
---|
112 | /* resize */ resize, |
---|
113 | /* destroy */ destroy, |
---|
114 | /* resources */ resources, |
---|
115 | /* number of 'em */ XjNumber(resources) |
---|
116 | } |
---|
117 | }; |
---|
118 | |
---|
119 | JetClass aClockJetClass = (JetClass)&aClockClassRec; |
---|
120 | |
---|
121 | |
---|
122 | static void initialize(me) |
---|
123 | AClockJet me; |
---|
124 | { |
---|
125 | #ifdef SHAPE |
---|
126 | int shape_event_base, shape_error_base; |
---|
127 | |
---|
128 | if (me->aClock.round && !XShapeQueryExtension (XjDisplay(me), |
---|
129 | &shape_event_base, |
---|
130 | &shape_error_base)) |
---|
131 | me->aClock.round = False; |
---|
132 | |
---|
133 | me->aClock.mask = 0; |
---|
134 | #endif |
---|
135 | |
---|
136 | me->aClock.realized = 0; |
---|
137 | } |
---|
138 | |
---|
139 | static int intsin(angle) |
---|
140 | int angle; |
---|
141 | { |
---|
142 | int quadr; /* used to be quad; conflicts with Ultrix. grrrr. */ |
---|
143 | |
---|
144 | if (angle >= 0) |
---|
145 | { |
---|
146 | quadr = (angle%CIRCLE) / ANGLES; |
---|
147 | angle = angle%ANGLES; |
---|
148 | } |
---|
149 | else |
---|
150 | { |
---|
151 | quadr = (3 - ((-angle)%CIRCLE) / ANGLES); |
---|
152 | angle = ANGLES - ((-angle)%ANGLES); |
---|
153 | } |
---|
154 | |
---|
155 | switch(quadr) |
---|
156 | { |
---|
157 | case 0: |
---|
158 | return sinTable[angle]; |
---|
159 | case 1: |
---|
160 | return sinTable[(ANGLES - 1) - angle]; |
---|
161 | case 2: |
---|
162 | return -sinTable[angle]; |
---|
163 | case 3: |
---|
164 | return -sinTable[(ANGLES - 1 ) - angle]; |
---|
165 | default: |
---|
166 | fprintf(stdout, "sin broken (%d)\n", angle); |
---|
167 | XjExit(-1); |
---|
168 | } |
---|
169 | return 0; /* just to make saber happy... look up 2 lines... */ |
---|
170 | } |
---|
171 | |
---|
172 | #define intcos(angle) intsin(angle + ANGLES) |
---|
173 | |
---|
174 | /* |
---|
175 | * Things are currently broken screenwise. |
---|
176 | * It will be fun to fix later. :) |
---|
177 | */ |
---|
178 | static void realize(me) |
---|
179 | AClockJet me; |
---|
180 | { |
---|
181 | unsigned long valuemask; |
---|
182 | XGCValues values; |
---|
183 | Pixmap tmp; |
---|
184 | |
---|
185 | me->aClock.realized = 1; |
---|
186 | |
---|
187 | if (me->aClock.reverseVideo) |
---|
188 | { |
---|
189 | int temp; |
---|
190 | |
---|
191 | temp = me->aClock.foreground; |
---|
192 | if (me->aClock.hands == me->aClock.foreground) |
---|
193 | me->aClock.hands = me->aClock.background; |
---|
194 | if (me->aClock.highlight == me->aClock.foreground) |
---|
195 | me->aClock.highlight = me->aClock.background; |
---|
196 | me->aClock.foreground = me->aClock.background; |
---|
197 | me->aClock.background = temp; |
---|
198 | } |
---|
199 | |
---|
200 | valuemask = ( GCForeground | GCBackground |
---|
201 | | GCFunction | GCGraphicsExposures ); |
---|
202 | values.graphics_exposures = False; |
---|
203 | values.function = GXcopy; |
---|
204 | values.background = me->aClock.background; |
---|
205 | |
---|
206 | #ifdef SHAPE |
---|
207 | tmp = XjCreatePixmap (XjDisplay(me), XjWindow(me), 1, 1, 1); |
---|
208 | values.foreground = 0; |
---|
209 | me->aClock.eraseGC = XjCreateGC(XjDisplay(me), tmp, valuemask, &values); |
---|
210 | values.foreground = 1; |
---|
211 | me->aClock.setGC = XjCreateGC(XjDisplay(me), tmp, valuemask, &values); |
---|
212 | XjFreePixmap(XjDisplay(me), tmp); |
---|
213 | #endif |
---|
214 | |
---|
215 | values.foreground = me->aClock.foreground; |
---|
216 | me->aClock.handsGC = me->aClock.highlightGC = me->aClock.foregroundGC |
---|
217 | = XjCreateGC(me->core.display, |
---|
218 | me->core.window, |
---|
219 | valuemask, |
---|
220 | &values); |
---|
221 | |
---|
222 | if (me->aClock.hands != me->aClock.foreground) |
---|
223 | { |
---|
224 | values.foreground = me->aClock.hands; |
---|
225 | me->aClock.handsGC = XjCreateGC(me->core.display, |
---|
226 | me->core.window, |
---|
227 | valuemask, |
---|
228 | &values); |
---|
229 | } |
---|
230 | |
---|
231 | if (me->aClock.highlight != me->aClock.foreground) |
---|
232 | { |
---|
233 | values.foreground = me->aClock.highlight; |
---|
234 | me->aClock.highlightGC = XjCreateGC(me->core.display, |
---|
235 | me->core.window, |
---|
236 | valuemask, |
---|
237 | &values); |
---|
238 | } |
---|
239 | |
---|
240 | values.foreground = me->aClock.background; |
---|
241 | me->aClock.backgroundGC = XjCreateGC(me->core.display, |
---|
242 | me->core.window, |
---|
243 | valuemask, |
---|
244 | &values); |
---|
245 | |
---|
246 | me->aClock.h = me->aClock.m = me->aClock.s = -1; |
---|
247 | me->aClock.timerid = XjAddWakeup(wakeup, me, 1000 * me->aClock.update); |
---|
248 | |
---|
249 | #ifdef SHAPE |
---|
250 | if (me->aClock.round) |
---|
251 | { |
---|
252 | XjSize size; |
---|
253 | |
---|
254 | size.width = me->core.width; |
---|
255 | size.height = me->core.height; |
---|
256 | resize(me, &size); |
---|
257 | } |
---|
258 | #endif /* SHAPE */ |
---|
259 | } |
---|
260 | |
---|
261 | static void querySize(me, size) |
---|
262 | AClockJet me; |
---|
263 | XjSize *size; |
---|
264 | { |
---|
265 | size->width = 50; |
---|
266 | size->height = 50; |
---|
267 | } |
---|
268 | |
---|
269 | static void move(me, x, y) |
---|
270 | AClockJet me; |
---|
271 | int x, y; |
---|
272 | { |
---|
273 | if (DEBUG) |
---|
274 | printf ("MV(aClock) '%s' x=%d,y=%d\n", me->core.name, x, y); |
---|
275 | |
---|
276 | me->core.x = x; |
---|
277 | me->core.y = y; |
---|
278 | me->aClock.centerx = me->core.width / 2 + me->core.x; |
---|
279 | me->aClock.centery = me->core.height / 2 + me->core.y; |
---|
280 | } |
---|
281 | |
---|
282 | static void resize(me, size) |
---|
283 | AClockJet me; |
---|
284 | XjSize *size; |
---|
285 | { |
---|
286 | int width, height; |
---|
287 | |
---|
288 | if (DEBUG) |
---|
289 | printf ("RS(aClock) '%s' w=%d,h=%d\n", me->core.name, |
---|
290 | size->width, size->height); |
---|
291 | |
---|
292 | if (me->aClock.keepRound) |
---|
293 | width = height = MIN(size->width, size->height); |
---|
294 | else |
---|
295 | { |
---|
296 | width = size->width; |
---|
297 | height = size->height; |
---|
298 | } |
---|
299 | |
---|
300 | me->aClock.centerx = size->width / 2 + me->core.x; |
---|
301 | me->aClock.centery = size->height / 2 + me->core.y; |
---|
302 | me->aClock.xradius = width / 2 + me->core.x - me->aClock.padding; |
---|
303 | me->aClock.yradius = height / 2 + me->core.y - me->aClock.padding; |
---|
304 | |
---|
305 | if (me->aClock.realized == 1) |
---|
306 | { |
---|
307 | XFillRectangle(me->core.display, me->core.window, |
---|
308 | me->aClock.backgroundGC, |
---|
309 | me->core.x, me->core.y, |
---|
310 | me->core.width, me->core.height); |
---|
311 | #ifdef SHAPE |
---|
312 | if (me->aClock.round) |
---|
313 | { |
---|
314 | Jet parent; |
---|
315 | int x, y, bw = 0; |
---|
316 | |
---|
317 | /* |
---|
318 | * allocate a pixmap to draw shapes in |
---|
319 | */ |
---|
320 | if (me->aClock.mask) |
---|
321 | XjFreePixmap(XjDisplay(me), me->aClock.mask); |
---|
322 | |
---|
323 | me->aClock.mask = XjCreatePixmap (XjDisplay(me), XjWindow(me), |
---|
324 | size->width, size->height, 1); |
---|
325 | |
---|
326 | /* erase the pixmap */ |
---|
327 | XFillRectangle (XjDisplay(me), me->aClock.mask, me->aClock.eraseGC, |
---|
328 | 0, 0, size->width, size->height); |
---|
329 | |
---|
330 | /* |
---|
331 | * draw the bounding shape. Doing this first |
---|
332 | * eliminates extra exposure events. |
---|
333 | */ |
---|
334 | |
---|
335 | x = me->aClock.centerx - width/2 - me->core.x; |
---|
336 | y = me->aClock.centery - height/2 - me->core.y; |
---|
337 | |
---|
338 | XFillArc (XjDisplay(me), me->aClock.mask, |
---|
339 | me->aClock.setGC, x, y, width, height, |
---|
340 | 0, 360 * 64); |
---|
341 | XShapeCombineMask (XjDisplay(me), XjWindow(me), ShapeBounding, |
---|
342 | 0, 0, me->aClock.mask, ShapeSet); |
---|
343 | |
---|
344 | /* |
---|
345 | * Find the highest enclosing widget (a window) to get borderwidth. |
---|
346 | */ |
---|
347 | for (parent = (Jet) me; XjParent(parent) && !bw; |
---|
348 | parent = XjParent(parent)) |
---|
349 | if (!strcmp(parent->core.classRec->core_class.className, "Window")) |
---|
350 | bw = parent->core.borderWidth; |
---|
351 | |
---|
352 | /* erase the pixmap */ |
---|
353 | XFillRectangle (XjDisplay (me), me->aClock.mask, me->aClock.eraseGC, |
---|
354 | 0, 0, size->width, size->height); |
---|
355 | |
---|
356 | /* |
---|
357 | * draw the clip shape |
---|
358 | */ |
---|
359 | |
---|
360 | XFillArc (XjDisplay(me), me->aClock.mask, |
---|
361 | me->aClock.setGC, x + bw, y + bw, |
---|
362 | width - 2 * bw, height - 2 * bw, |
---|
363 | 0, 360 * 64); |
---|
364 | XShapeCombineMask(XjDisplay(me), XjWindow(me), ShapeClip, |
---|
365 | 0, 0, me->aClock.mask, ShapeSet); |
---|
366 | } |
---|
367 | #endif /* SHAPE */ |
---|
368 | } |
---|
369 | |
---|
370 | me->core.width = size->width; /* These sizes must be set AFTER */ |
---|
371 | me->core.height = size->height; /* the FillRectangle above... */ |
---|
372 | } |
---|
373 | |
---|
374 | |
---|
375 | |
---|
376 | static void drawHand(me, drawable, gc_fill, gc_hilite, angle, start, end, arc) |
---|
377 | AClockJet me; |
---|
378 | Drawable drawable; |
---|
379 | GC gc_fill, gc_hilite; |
---|
380 | int angle; |
---|
381 | int start, end, arc; |
---|
382 | { |
---|
383 | int offset = arc * CIRCLE / (360 * 2); |
---|
384 | |
---|
385 | XPoint p[4]; |
---|
386 | |
---|
387 | p[0].x = (end * me->aClock.xradius / 100) * intsin(angle - offset) / |
---|
388 | SCALE + me->aClock.centerx; |
---|
389 | p[0].y = (-(end * me->aClock.yradius / 100) * intcos(angle - offset) / |
---|
390 | SCALE) + me->aClock.centery; |
---|
391 | p[1].x = (start * me->aClock.xradius / 100) * intsin(angle) / |
---|
392 | SCALE + me->aClock.centerx; |
---|
393 | p[1].y = (-(start * me->aClock.yradius / 100) * intcos(angle) / |
---|
394 | SCALE) + me->aClock.centery; |
---|
395 | p[2].x = (end * me->aClock.xradius / 100) * intsin(angle + offset) / |
---|
396 | SCALE + me->aClock.centerx; |
---|
397 | p[2].y = (-(end * me->aClock.yradius / 100) * intcos(angle + offset) / |
---|
398 | SCALE) + me->aClock.centery; |
---|
399 | p[3] = p[0]; |
---|
400 | |
---|
401 | XFillPolygon(me->core.display, drawable, |
---|
402 | gc_fill, p, 3, Convex, CoordModeOrigin); |
---|
403 | |
---|
404 | XDrawLines(me->core.display, drawable, |
---|
405 | gc_hilite, p, 4, CoordModeOrigin); |
---|
406 | } |
---|
407 | |
---|
408 | |
---|
409 | static void drawSecond(me, drawable, gc_fill, gc_hilite, angle) |
---|
410 | AClockJet me; |
---|
411 | Drawable drawable; |
---|
412 | GC gc_fill, gc_hilite; |
---|
413 | int angle; |
---|
414 | { |
---|
415 | int offset = me->aClock.secondArc * CIRCLE / (360 * 2); |
---|
416 | int ssx = me->aClock.secondStart * me->aClock.xradius / 100; |
---|
417 | int ssy = me->aClock.secondStart * me->aClock.yradius / 100; |
---|
418 | int sex = me->aClock.secondEnd * me->aClock.xradius / 100; |
---|
419 | int sey = me->aClock.secondEnd * me->aClock.yradius / 100; |
---|
420 | int mx = (ssx + sex) / 2; |
---|
421 | int my = (ssy + sey) / 2; |
---|
422 | |
---|
423 | XPoint p[5]; |
---|
424 | |
---|
425 | p[0].x = intsin(angle) * ssx / SCALE + me->aClock.centerx; |
---|
426 | p[0].y = -(intcos(angle) * ssy / SCALE) + me->aClock.centery; |
---|
427 | p[2].x = intsin(angle) * sex / SCALE + me->aClock.centerx; |
---|
428 | p[2].y = -(intcos(angle) * sey / SCALE) + me->aClock.centery; |
---|
429 | |
---|
430 | p[1].x = intsin(angle - offset) * mx / SCALE + me->aClock.centerx; |
---|
431 | p[1].y = -(intcos(angle - offset) * my / SCALE) + me->aClock.centery; |
---|
432 | p[3].x = intsin(angle + offset) * mx / SCALE + me->aClock.centerx; |
---|
433 | p[3].y = -(intcos(angle + offset) * my / SCALE) + me->aClock.centery; |
---|
434 | p[4] = p[0]; |
---|
435 | |
---|
436 | XFillPolygon(me->core.display, drawable, |
---|
437 | gc_fill, p, 4, Convex, CoordModeOrigin); |
---|
438 | |
---|
439 | XDrawLines(me->core.display, drawable, |
---|
440 | gc_hilite, p, 5, CoordModeOrigin); |
---|
441 | } |
---|
442 | |
---|
443 | |
---|
444 | static int update(me, expose) |
---|
445 | AClockJet me; |
---|
446 | int expose; |
---|
447 | { |
---|
448 | struct timeval now; |
---|
449 | struct tm *t; |
---|
450 | int oh = me->aClock.h, om = me->aClock.m, os = me->aClock.s; |
---|
451 | int h, m, s; |
---|
452 | |
---|
453 | gettimeofday(&now, NULL); |
---|
454 | t = localtime((time_t *) &now.tv_sec); |
---|
455 | |
---|
456 | h = t->tm_hour%12; |
---|
457 | m = t->tm_min; |
---|
458 | s = t->tm_sec; |
---|
459 | |
---|
460 | if ((s != os || expose) && (me->aClock.update < 31)) |
---|
461 | { |
---|
462 | if (s != os) |
---|
463 | drawSecond(me, me->core.window, |
---|
464 | me->aClock.backgroundGC, me->aClock.backgroundGC, |
---|
465 | os * CIRCLE / 60); |
---|
466 | |
---|
467 | drawSecond(me, me->core.window, |
---|
468 | me->aClock.handsGC, me->aClock.highlightGC, |
---|
469 | s * CIRCLE / 60); |
---|
470 | } |
---|
471 | |
---|
472 | if (m != om || expose) |
---|
473 | { |
---|
474 | if (m != om) |
---|
475 | { |
---|
476 | drawHand(me, me->core.window, |
---|
477 | me->aClock.backgroundGC, me->aClock.backgroundGC, |
---|
478 | om * CIRCLE / 60, |
---|
479 | me->aClock.minuteStart, me->aClock.minuteEnd, |
---|
480 | me->aClock.minuteArc); |
---|
481 | |
---|
482 | drawHand(me, me->core.window, |
---|
483 | me->aClock.backgroundGC, me->aClock.backgroundGC, |
---|
484 | (60 * oh + om) * CIRCLE / 720, |
---|
485 | me->aClock.hourStart, me->aClock.hourEnd, |
---|
486 | me->aClock.hourArc); |
---|
487 | } |
---|
488 | |
---|
489 | drawHand(me, me->core.window, |
---|
490 | me->aClock.handsGC, me->aClock.highlightGC, |
---|
491 | m * CIRCLE / 60, |
---|
492 | me->aClock.minuteStart, me->aClock.minuteEnd, |
---|
493 | me->aClock.minuteArc); |
---|
494 | |
---|
495 | drawHand(me, me->core.window, |
---|
496 | me->aClock.handsGC, me->aClock.highlightGC, |
---|
497 | (60 * h + m) * CIRCLE / 720, |
---|
498 | me->aClock.hourStart, me->aClock.hourEnd, |
---|
499 | me->aClock.hourArc); |
---|
500 | } |
---|
501 | |
---|
502 | me->aClock.h = h; me->aClock.m = m; me->aClock.s = s; |
---|
503 | |
---|
504 | /* if (me->aClock.update > 1) */ |
---|
505 | return(1000 * me->aClock.update); |
---|
506 | |
---|
507 | /* return(1000 - (now.tv_usec / 1000)); */ |
---|
508 | } |
---|
509 | |
---|
510 | static void drawTicks(me) |
---|
511 | AClockJet me; |
---|
512 | { |
---|
513 | int ticks; |
---|
514 | int start, end; |
---|
515 | int x1, y1, x2, y2; |
---|
516 | |
---|
517 | for (ticks = 0; ticks < 60; ticks++) |
---|
518 | { |
---|
519 | |
---|
520 | if (me->aClock.majorTick != 0 |
---|
521 | && ticks % me->aClock.majorTick == 0) |
---|
522 | { |
---|
523 | start = me->aClock.majorStart; |
---|
524 | end = me->aClock.majorEnd; |
---|
525 | } |
---|
526 | else if (me->aClock.minorTick != 0 |
---|
527 | && ticks % me->aClock.minorTick == 0) |
---|
528 | { |
---|
529 | start = me->aClock.minorStart; |
---|
530 | end = me->aClock.minorEnd; |
---|
531 | } |
---|
532 | else continue; |
---|
533 | |
---|
534 | x1 = me->aClock.centerx + |
---|
535 | (me->aClock.xradius * start) / 100 |
---|
536 | * intsin(ticks * CIRCLE / 60) / SCALE; |
---|
537 | |
---|
538 | y1 = me->aClock.centery + |
---|
539 | (me->aClock.yradius * start) / 100 |
---|
540 | * -(intcos(ticks * CIRCLE / 60)) / SCALE; |
---|
541 | |
---|
542 | x2 = me->aClock.centerx + |
---|
543 | (me->aClock.xradius * end) / 100 |
---|
544 | * intsin(ticks * CIRCLE / 60) / SCALE; |
---|
545 | |
---|
546 | y2 = me->aClock.centery + |
---|
547 | (me->aClock.yradius * end) / 100 |
---|
548 | * -(intcos(ticks * CIRCLE / 60)) / SCALE; |
---|
549 | |
---|
550 | XDrawLine(me->core.display, |
---|
551 | me->core.window, |
---|
552 | me->aClock.foregroundGC, |
---|
553 | x1, y1, x2, y2); |
---|
554 | } |
---|
555 | } |
---|
556 | |
---|
557 | static void wakeup(me, id) |
---|
558 | AClockJet me; |
---|
559 | int id; |
---|
560 | { |
---|
561 | me->aClock.timerid = XjAddWakeup(wakeup, me, update(me, 0)); |
---|
562 | } |
---|
563 | |
---|
564 | static void expose(me, event) |
---|
565 | AClockJet me; |
---|
566 | XEvent *event; |
---|
567 | { |
---|
568 | drawTicks(me); |
---|
569 | (void) update(me, 1); |
---|
570 | } |
---|
571 | |
---|
572 | static void destroy(me) |
---|
573 | AClockJet me; |
---|
574 | { |
---|
575 | XjFreeGC(me->core.display, me->aClock.backgroundGC); |
---|
576 | XjFreeGC(me->core.display, me->aClock.foregroundGC); |
---|
577 | |
---|
578 | (void)XjRemoveWakeup(me->aClock.timerid); |
---|
579 | } |
---|