wmauda: Fix installation dir
[dockapps.git] / wmCalClock-1.25 / Src / wmCalClock.c
blobfa9a2f7cce168edf1dc7f9ba81c1e4bfdc1a21cb
1 /*
3 * wmCalClock-1.25 (C) 1998, 1999 Mike Henderson (mghenderson@lanl.gov)
4 *
5 * - Its a Calendar Clock....
6 *
7 *
8 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program (see the file COPYING); if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA
26 * Changes:
28 * Version 1.25 - released July 2, 1999.
29 * Some optimization + ignores double click if no command set (patch from
30 * Robert Horn).
32 * Version 1.24 - released March 27, 1999.
33 * Added support for additional fonts for time field;
35 * -tekton for Tekton
36 * -arial for Arial (Helvetica) (this is the same font as usual)
37 * -luggerbug for LuggerBug
38 * -comicsans for ComicSans
39 * -jazz for JazzPoster
41 * Different width fonts get used depending on whether or not seconds
42 * are displayed.
44 * Version 1.23 - released March 20, 1999.
45 * Switched from wmgeneral.c stuff to xutils.c (a more stripped down version
46 * of wmgeneral).
47 * Centered Calendar text better.
48 * Added command line options and code to change colors of the time
49 * field digits and the background of the time field. So now you can
50 * get things like darkblue on light grey or very dark color on an LCD-ish
51 * colored background (e.g. wmCalClock -bc #6e9e69 -tc #001100)..
52 * Rewrote the command line parsing routine.
54 * Version 1.21 - released February 4, 1999.
55 * cosmetic for AfterStep users. removed spurious black line at RHS edge of mask.
57 * Version 1.20 - released January 14, 1999.
58 * Changed support for LowColor Pixmap. Now, check for Depth
59 * automatically. If its <= 8, then use LowColor.
62 * Version 1.11 - released January 8, 1999.
63 * Fixed bug in 12-hour mode. Now displays 12:xx:xx AM instead
64 * of 0:xx:xx AM.
67 * Version 1.10 - released January 7, 1999.
68 * Added support for LowColor Pixmap. (21 colors may still be a
69 * bit high, but the poor saps with 8-bit displays can at least run
70 * it now.)
72 * Version 1.02 - released January 7, 1999.
73 * Fixed bug in AM/PM determination...
75 * Version 1.01 - released January 3, 1999.
76 * Added "-S" option to inhibit drawing of seconds.
78 * Version 1.00 - released December 16, 1998.
87 /*
88 * Includes
90 #include <stdio.h>
91 #include <unistd.h>
92 #include <stdlib.h>
93 #include <string.h>
94 #include <time.h>
95 #include <X11/X.h>
96 #include <X11/xpm.h>
97 #include "xutils.h"
98 #include "wmCalClock_master.xpm"
99 #include "wmCalClock_master_LowColor.xpm"
100 #include "wmCalClock_mask.xbm"
105 * Delay between refreshes (in microseconds)
107 #define DELAY 10000L
108 #define WMCALCLOCK_VERSION "1.25"
114 void ParseCMDLine(int argc, char *argv[]);
115 void ButtonPressEvent(XButtonEvent *);
116 void print_usage();
121 int xsMonth[12] = { 150, 170, 190, 212, 233, 256, 276, 294, 317, 337, 357, 380 };
122 int xeMonth[12] = { 168, 188, 210, 231, 254, 275, 292, 314, 335, 355, 377, 398 };
123 int xdMonth[12];
124 int yMonth = 80;
125 int ydMonth = 13;
127 int xsDayOfWeek[7] = { 293, 150, 177, 201, 228, 253, 271 };
128 int xeDayOfWeek[7] = { 314, 175, 199, 226, 250, 269, 290 };
129 int xdDayOfWeek[7];
130 int yDayOfWeek = 95;
131 int ydDayOfWeek = 13;
134 * I think this is 28??-pixel high adobe-myriad-bold
136 int xsDayOfMonth[31] = { 118, 161, 205, 248, 291, 335, 378, 421, 465,
137 75, 118, 162, 205, 248, 292, 335, 378, 422, 465,
138 75, 118, 162, 205, 248, 292, 335, 378, 422, 465,
139 75, 118 };
141 * I think this is 16-pixel high adobe-myriad-bold?
143 int xeDayOfMonth[31] = { 147, 193, 236, 282, 324, 368, 411, 454, 498,
144 107, 146, 192, 235, 281, 323, 367, 410, 453, 497,
145 108, 147, 193, 236, 282, 324, 368, 411, 454, 498,
146 108, 147 };
147 int xeDayOfMonth2[31] = { 144, 190, 234, 278, 320, 365, 407, 451, 494,
148 103, 143, 189, 233, 277, 319, 364, 406, 450, 493,
149 104, 144, 190, 234, 278, 320, 365, 407, 451, 494,
150 104, 144 };
153 * I think this is 16-pixel high adobe-myriad-bold?
155 int yDayOfMonth[31] = { 5, 5, 5, 5, 5, 5, 5, 5, 5,
156 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
157 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
158 80, 80 };
159 int xdDayOfMonth[31];
160 int xdDayOfMonth2[31];
161 int ydDayOfMonth = 23;
167 * Luggerbug Font Narrow - 13 pixels high.
169 int xsDigits_Luggerbug13n[11] = { 75, 84, 92, 101, 110, 119, 127, 136, 143, 151, 159 };
170 int xeDigits_Luggerbug13n[11] = { 80, 89, 97, 106, 115, 123, 132, 139, 147, 156, 159 };
171 int xdDigits_Luggerbug13n[11];
172 int yDigits_Luggerbug13n = 150;
173 int ydDigits_Luggerbug13n = 13;
176 * Luggerbug Font - 13 pixels high.
178 int xsDigits_Luggerbug13[11] = { 75, 89, 103, 117, 131, 146, 159, 172, 184, 197, 208 };
179 int xeDigits_Luggerbug13[11] = { 83, 97, 110, 125, 139, 153, 166, 178, 191, 205, 209 };
180 int xdDigits_Luggerbug13[11];
181 int yDigits_Luggerbug13 = 136;
182 int ydDigits_Luggerbug13 = 13;
185 * ComicSans Font - 12 pixels high.
187 int xsDigits_ComicSans12n[11] = { 338, 349, 359, 370, 380, 390, 401, 411, 422, 432, 444 };
188 int xeDigits_ComicSans12n[11] = { 343, 353, 364, 374, 385, 396, 406, 417, 427, 438, 445 };
189 int xdDigits_ComicSans12n[11];
190 int yDigits_ComicSans12n = 123;
191 int ydDigits_ComicSans12n = 12;
194 * ComicSans Font - 11 pixels high.
196 int xsDigits_ComicSans11[11] = { 338, 353, 366, 380, 392, 407, 420, 434, 448, 461, 471 };
197 int xeDigits_ComicSans11[11] = { 345, 357, 372, 386, 400, 413, 427, 441, 454, 468, 473 };
198 int xdDigits_ComicSans11[11];
199 int yDigits_ComicSans11 = 111;
200 int ydDigits_ComicSans11 = 11;
203 * JazzPoster Font Narrow - 12 pixels high.
205 int xsDigits_JazzPoster12n[11] = { 211, 220, 226, 233, 241, 249, 256, 263, 271, 278, 286 };
206 int xeDigits_JazzPoster12n[11] = { 217, 223, 231, 238, 247, 253, 261, 268, 276, 284, 286 };
207 int xdDigits_JazzPoster12n[11];
208 int yDigits_JazzPoster12n = 122;
209 int ydDigits_JazzPoster12n = 12;
212 * JazzPoster Font - 12 pixels high.
214 int xsDigits_JazzPoster12[11] = { 211, 225, 234, 246, 258, 271, 282, 293, 305, 317, 328 };
215 int xeDigits_JazzPoster12[11] = { 221, 230, 243, 254, 268, 278, 290, 301, 314, 325, 329 };
216 int xdDigits_JazzPoster12[11];
217 int yDigits_JazzPoster12 = 109;
218 int ydDigits_JazzPoster12 = 12;
222 * Tekton Font - 12 pixels high Narrow (13 pixels high actually).
224 int xsDigits_Tekton12n[11] = { 75, 84, 90, 97, 105, 114, 122, 131, 138, 147, 156 };
225 int xeDigits_Tekton12n[11] = { 81, 86, 94, 103, 111, 119, 128, 135, 144, 152, 157 };
226 int xdDigits_Tekton12n[11];
227 int yDigits_Tekton12n = 122;
228 int ydDigits_Tekton12n = 13;
231 * Tekton Font - 12 pixels high.
233 int xsDigits_Tekton12[11] = { 75, 89, 98, 111, 124, 137, 150, 164, 176, 191, 205 };
234 int xeDigits_Tekton12[11] = { 84, 92, 105, 119, 132, 145, 159, 171, 185, 199, 206 };
235 int xdDigits_Tekton12[11];
236 int yDigits_Tekton12 = 108;
237 int ydDigits_Tekton12 = 12;
240 * Monotype-arial-bold-narrow - 10 pixels high.
242 int xsDigits_Arial10[11] = { 320, 326, 333, 339, 346, 352, 358, 364, 371, 377, 384 };
243 int xeDigits_Arial10[11] = { 325, 331, 338, 344, 351, 357, 363, 369, 376, 382, 385 };
244 int xdDigits_Arial10[11];
245 int yDigits_Arial10 = 95;
246 int ydDigits_Arial10 = 10;
249 int xsDigits[11];
250 int xeDigits[11];
251 int xdDigits[11];
252 int yDigits;
253 int ydDigits;
256 int xsAMPM[2] = { 390, 396 };
257 int xeAMPM[2] = { 394, 400 };
258 int xdAMPM[2];
259 int yAMPM = 95;
260 int ydAMPM = 6;
261 int Show24HourTime = 0;
262 int ShowGreenwichTime = 0;
263 int ShowSiderealTime = 0;
264 double Longitude;
265 int Flag = 0;
266 int Beep = 0;
267 int Volume = 100;
268 int ShowSeconds = 1;
269 int UseLowColorPixmap = 0;
270 int UseArial = 0;
271 int UseComicSans = 0;
272 int UseTekton = 0;
273 int UseLuggerbug = 0;
274 int UseJazzPoster = 0;
275 int GotFirstClick1, GotDoubleClick1;
276 int GotFirstClick2, GotDoubleClick2;
277 int GotFirstClick3, GotDoubleClick3;
278 int DblClkDelay;
279 int HasExecute = 0; /* controls perf optimization */
280 char ExecuteCommand[1024];
283 char TimeColor[30] = "#ffff00";
284 char BackgroundColor[30] = "#181818";
292 * main
294 int main(int argc, char *argv[]) {
297 struct tm *Time;
298 XEvent event;
299 int i, n, wid, extrady, extradx;
300 int Year, Month, DayOfWeek, DayOfMonth, OldDayOfMonth;
301 int Hours, Mins, Secs, OldSecs, digit, xoff, D[10], xsize;
302 long CurrentLocalTime;
303 double UT, TU, TU2, TU3, T0, gmst, jd(), hour24();
307 * Parse any command line arguments.
309 ParseCMDLine(argc, argv);
317 * Set the font
319 if (UseTekton && !ShowSeconds){
321 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_Tekton12[i];
322 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_Tekton12[i];
323 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_Tekton12[i];
324 yDigits = yDigits_Tekton12;
325 ydDigits = ydDigits_Tekton12;
326 extrady = -1;
327 extradx = 0;
329 } else if (UseTekton && ShowSeconds){
331 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_Tekton12n[i];
332 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_Tekton12n[i];
333 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_Tekton12n[i];
334 yDigits = yDigits_Tekton12n;
335 ydDigits = ydDigits_Tekton12n;
336 extrady = -2;
337 extradx = 1;
339 } else if (UseLuggerbug && !ShowSeconds){
341 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_Luggerbug13[i];
342 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_Luggerbug13[i];
343 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_Luggerbug13[i];
344 yDigits = yDigits_Luggerbug13;
345 ydDigits = ydDigits_Luggerbug13;
346 extrady = -2;
347 extradx = 1;
349 } else if (UseLuggerbug && ShowSeconds){
351 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_Luggerbug13n[i];
352 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_Luggerbug13n[i];
353 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_Luggerbug13n[i];
354 yDigits = yDigits_Luggerbug13n;
355 ydDigits = ydDigits_Luggerbug13n;
356 extrady = -2;
357 extradx = 1;
359 } else if (UseComicSans && !ShowSeconds){
361 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_ComicSans11[i];
362 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_ComicSans11[i];
363 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_ComicSans11[i];
364 yDigits = yDigits_ComicSans11;
365 ydDigits = ydDigits_ComicSans11;
366 extrady = -1;
367 extradx = 1;
369 } else if (UseComicSans && ShowSeconds){
371 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_ComicSans12n[i];
372 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_ComicSans12n[i];
373 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_ComicSans12n[i];
374 yDigits = yDigits_ComicSans12n;
375 ydDigits = ydDigits_ComicSans12n;
376 extrady = -1;
377 extradx = 1;
379 } else if (UseJazzPoster && !ShowSeconds){
381 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_JazzPoster12[i];
382 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_JazzPoster12[i];
383 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_JazzPoster12[i];
384 yDigits = yDigits_JazzPoster12;
385 ydDigits = ydDigits_JazzPoster12;
386 extrady = -1;
387 extradx = 0;
389 } else if (UseJazzPoster && ShowSeconds){
391 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_JazzPoster12n[i];
392 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_JazzPoster12n[i];
393 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_JazzPoster12n[i];
394 yDigits = yDigits_JazzPoster12n;
395 ydDigits = ydDigits_JazzPoster12n;
396 extrady = -1;
397 extradx = 1;
399 } else {
401 for (i=0; i<11; ++i) xsDigits[i] = xsDigits_Arial10[i];
402 for (i=0; i<11; ++i) xeDigits[i] = xeDigits_Arial10[i];
403 for (i=0; i<11; ++i) xdDigits[i] = xdDigits_Arial10[i];
404 yDigits = yDigits_Arial10;
405 ydDigits = ydDigits_Arial10;
406 extrady = 0;
407 extradx = 0;
413 * Compute widths of digits etc...
414 * Should hand-encode for efficiency, but its easier to do this for development...
416 for (i=0; i<12; ++i) xdMonth[i] = xeMonth[i] - xsMonth[i] + 1;
417 for (i=0; i<7; ++i) xdDayOfWeek[i] = xeDayOfWeek[i] - xsDayOfWeek[i] + 1;
418 for (i=0; i<31; ++i) xdDayOfMonth[i] = xeDayOfMonth[i] - xsDayOfMonth[i] + 1;
419 for (i=0; i<31; ++i) xdDayOfMonth2[i] = xeDayOfMonth2[i] - xsDayOfMonth[i] + 1;
420 for (i=0; i<11; ++i) xdDigits[i] = xeDigits[i] - xsDigits[i] + 1;
421 for (i=0; i<2; ++i) xdAMPM[i] = xeAMPM[i] - xsAMPM[i] + 1;
431 initXwindow(argc, argv);
432 if (DisplayDepth <= 8) UseLowColorPixmap = 1;
434 if (UseLowColorPixmap)
435 openXwindow(argc, argv, wmCalClock_master_LowColor, wmCalClock_mask_bits, wmCalClock_mask_width, wmCalClock_mask_height);
436 else
437 openXwindow(argc, argv, wmCalClock_master, wmCalClock_mask_bits, wmCalClock_mask_width, wmCalClock_mask_height);
445 * Loop until we die
447 n = 32000;
448 OldDayOfMonth = -1;
449 OldSecs = -1;
450 while(1) {
454 * Only process every 10th cycle of this loop. We run it faster
455 * to catch expose events, etc...
458 if ( HasExecute == 0 || n>10){
460 n = 0;
462 if (ShowGreenwichTime){
464 CurrentLocalTime = time(CurrentTime);
465 Time = gmtime(&CurrentLocalTime);
466 DayOfMonth = Time->tm_mday-1;
467 DayOfWeek = Time->tm_wday;
468 Month = Time->tm_mon;
469 Hours = Time->tm_hour;
470 Mins = Time->tm_min;
471 Secs = Time->tm_sec;
473 } else if (ShowSiderealTime){
475 Show24HourTime = 1;
476 CurrentLocalTime = time(CurrentTime);
477 Time = gmtime(&CurrentLocalTime);
478 DayOfMonth = Time->tm_mday-1;
479 DayOfWeek = Time->tm_wday;
480 Year = Time->tm_year + 1900; /* this is NOT a Y2K bug */
481 Month = Time->tm_mon;
482 Hours = Time->tm_hour;
483 Mins = Time->tm_min;
484 Secs = Time->tm_sec;
485 UT = (double)Hours + (double)Mins/60.0 + (double)Secs/3600.0;
488 * Compute Greenwich Mean Sidereal Time (gmst)
489 * The TU here is number of Julian centuries
490 * since 2000 January 1.5
491 * From the 1996 astronomical almanac
493 TU = (jd(Year, Month+1, DayOfMonth+1, 0.0) - 2451545.0)/36525.0;
494 TU2 = TU*TU;
495 TU3 = TU2*TU;
496 T0 = (6.0 + 41.0/60.0 + 50.54841/3600.0) + 8640184.812866/3600.0*TU
497 + 0.093104/3600.0*TU2 - 6.2e-6/3600.0*TU3;
498 gmst = hour24(hour24(T0) + UT*1.002737909 + Longitude/15.0);
499 Hours = (int)gmst;
500 gmst = (gmst - (double)Hours)*60.0;
501 Mins = (int)gmst;
502 gmst = (gmst - (double)Mins)*60.0;
503 Secs = (int)gmst;
505 } else {
507 CurrentLocalTime = time(CurrentTime);
508 Time = localtime(&CurrentLocalTime);
509 DayOfMonth = Time->tm_mday-1;
510 DayOfWeek = Time->tm_wday;
511 Month = Time->tm_mon;
512 Hours = Time->tm_hour;
513 Mins = Time->tm_min;
514 Secs = Time->tm_sec;
519 * Flag indicates AM (Flag=0) or PM (Flag=1)
521 if (!Show24HourTime){
522 Flag = (Hours >= 12) ? 1 : 0;
523 if (Hours == 0)
524 Hours = 12;
525 else
526 Hours = (Hours > 12) ? Hours-12 : Hours;
533 * Blank the HH:MM section....
535 xsize = 0;
536 /* dont show leading zeros */
537 if ((digit = Hours / 10) > 0){
538 D[0] = digit, xsize += (xdDigits[digit]+1);
539 } else{
540 D[0] = -1;
542 digit = Hours % 10, D[1] = digit, xsize += (xdDigits[digit]+1);
543 digit = 10, D[2] = digit, xsize += (xdDigits[digit]+1);
544 digit = Mins / 10, D[3] = digit, xsize += (xdDigits[digit]+1);
545 digit = Mins % 10, D[4] = digit, xsize += (xdDigits[digit]+1);
546 if (ShowSeconds){
547 digit = 10, D[5] = digit, xsize += (xdDigits[digit]+1);
548 digit = Secs / 10, D[6] = digit, xsize += (xdDigits[digit]+1);
549 digit = Secs % 10, D[7] = digit, xsize += (xdDigits[digit]);
551 xoff = ((Hours>9)&&(!Show24HourTime)&&(ShowSeconds)) ? 28 - xsize/2 : 31 - xsize/2;
552 copyXPMArea(5, 110, 54, 15, 5, 5);
556 * Draw Hours
559 /* dont show leading zeros */
560 if (D[0] > -1){
561 digit = D[0];
562 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
563 xoff += (xdDigits[digit]+1);
566 digit = D[1];
567 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
568 xoff += (xdDigits[digit]+1);
571 * Draw Colon
573 digit = 10;
574 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
575 xoff += (xdDigits[digit]+1);
578 * Draw Minutes
580 digit = D[3];
581 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
582 xoff += (xdDigits[digit]+1);
584 digit = D[4];
585 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
586 xoff += (xdDigits[digit]+1);
588 if (ShowSeconds){
591 * Draw Colon
593 digit = 10;
594 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
595 xoff += (xdDigits[digit]+1);
598 * Draw Seconds
600 digit = D[6];
601 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
602 xoff += (xdDigits[digit]+1);
604 digit = D[7];
605 copyXPMArea(xsDigits[digit], yDigits, xdDigits[digit], ydDigits, xoff+extradx, 7+extrady);
606 xoff += (xdDigits[digit]+3);
612 * Draw AM/PM indicator if we are using 12 Hour Clock.
613 * Dont show it if we are using 24 Hour Clock.
615 if (!Show24HourTime)
616 copyXPMArea(xsAMPM[Flag], yAMPM, xdAMPM[Flag], ydAMPM, 54, 5);
623 * Beep on the hour
625 if (Beep){
626 if ((Mins == 0)&&(Secs == 0)&&(OldSecs != Secs)) XBell(display, Volume);
627 OldSecs = Secs;
636 if (OldDayOfMonth != DayOfMonth){
640 * Blank the Calendar section....
642 copyXPMArea(5, 70, 54, 35, 5, 24);
646 * Draw Day of Week and Month
648 wid = xdDayOfWeek[DayOfWeek] + xdMonth[Month] + 1;
649 copyXPMArea(xsDayOfWeek[DayOfWeek], yDayOfWeek, xdDayOfWeek[DayOfWeek],
650 ydMonth, 33-wid/2, 64-24-4-12);
651 copyXPMArea(xsMonth[Month], yMonth, xdMonth[Month],
652 ydMonth, 33-wid/2+xdDayOfWeek[DayOfWeek]+1, 64-24-4-12);
657 * Draw Day of Month
659 copyXPMArea(xsDayOfMonth[DayOfMonth], yDayOfMonth[DayOfMonth], xdDayOfMonth[DayOfMonth], ydDayOfMonth, 32-xdDayOfMonth2[DayOfMonth]/2, 36);
665 OldDayOfMonth = DayOfMonth;
670 } else {
673 * Update the counter.
675 ++n;
684 * Double Click Delays
685 * Keep track of click events. If Delay too long, set GotFirstClick's to False.
687 if (DblClkDelay > 15) {
689 DblClkDelay = 0;
690 GotFirstClick1 = 0; GotDoubleClick1 = 0;
691 GotFirstClick2 = 0; GotDoubleClick2 = 0;
692 GotFirstClick3 = 0; GotDoubleClick3 = 0;
694 } else {
696 ++DblClkDelay;
704 * Process any pending X events.
706 while(XPending(display)){
707 XNextEvent(display, &event);
708 switch(event.type){
709 case Expose:
710 RedrawWindow();
711 break;
712 case ButtonPress:
713 ButtonPressEvent(&event.xbutton);
714 break;
715 case ButtonRelease:
716 break;
726 * Redraw and wait for next update
728 RedrawWindow();
729 if( HasExecute == 1) {
730 usleep(DELAY);
731 } else if( ShowSeconds == 1) {
732 usleep( 200000L);
733 } else {
734 usleep( 500000L);
752 * ParseCMDLine()
754 void ParseCMDLine(int argc, char *argv[]) {
756 int i;
758 for (i = 1; i < argc; i++) {
760 if (!strcmp(argv[i], "-display")){
762 ++i;
764 } else if (!strcmp(argv[i], "-jazz")){
766 UseJazzPoster = 1;
768 } else if (!strcmp(argv[i], "-arial")){
770 UseArial = 1;
772 } else if (!strcmp(argv[i], "-tekton")){
774 UseTekton = 1;
776 } else if (!strcmp(argv[i], "-luggerbug")){
778 UseLuggerbug = 1;
780 } else if (!strcmp(argv[i], "-comicsans")){
782 UseComicSans = 1;
784 } else if (!strcmp(argv[i], "-tc")){
786 if ((i+1 >= argc)||(argv[i+1][0] == '-')) {
787 fprintf(stderr, "wmCalClock: No color found\n");
788 print_usage();
789 exit(-1);
791 strcpy(TimeColor, argv[++i]);
793 } else if (!strcmp(argv[i], "-bc")){
795 if ((i+1 >= argc)||(argv[i+1][0] == '-')) {
796 fprintf(stderr, "wmCalClock: No color found\n");
797 print_usage();
798 exit(-1);
800 strcpy(BackgroundColor, argv[++i]);
802 } else if (!strcmp(argv[i], "-24")){
804 Show24HourTime = 1;
806 } else if (!strcmp(argv[i], "-b")){
808 if ((i+1 >= argc)||(argv[i+1][0] == '-')) {
809 fprintf(stderr, "wmCalClock: No volume given\n");
810 print_usage();
811 exit(-1);
813 Beep = 1;
814 Volume = atoi(argv[++i]);
816 } else if (!strcmp(argv[i], "-e")){
818 if ((i+1 >= argc)||(argv[i+1][0] == '-')) {
819 fprintf(stderr, "wmCalClock: No command given\n");
820 print_usage();
821 exit(-1);
823 strcpy(ExecuteCommand, argv[++i]);
824 HasExecute = 1;
826 } else if (!strcmp(argv[i], "-g")){
828 ShowGreenwichTime = 1;
830 } else if (!strcmp(argv[i], "-S")){
832 ShowSeconds = 0;
834 } else if (!strcmp(argv[i], "-s")){
836 ShowSiderealTime = 1;
837 Longitude = 0.0;
839 } else if (!strcmp(argv[i], "-L")){
841 if ((i+1 >= argc)||(argv[i+1][0] == '-')) {
842 fprintf(stderr, "wmCalClock: No longitude given\n");
843 print_usage();
844 exit(-1);
846 ShowSiderealTime = 1;
847 Longitude = atof(argv[++i]);
849 } else if (!strcmp(argv[i], "-l")){
851 UseLowColorPixmap = 1;
853 } else {
855 print_usage();
856 exit(1);
861 if (!ShowSeconds && !UseArial && !UseJazzPoster
862 && !UseComicSans && !UseLuggerbug) UseTekton = 1;
869 void print_usage(){
871 printf("\nwmCalClock version: %s\n", WMCALCLOCK_VERSION);
872 printf("\nusage: wmCalClock [-b <Volume>] [-tc <Color>] [-bc <Color>] [-e \"Command\"] [-S]\n");
873 printf(" [-24] [-g] [-s] [-l <longitude>] [-l] [-jazz] [-tekton] [-luggerbug]\n");
874 printf(" [-arial] [-comicsans] [-h]\n\n");
875 printf("\t-b <Volume>\tBeep on the hour. Volume is between -100 to 100.\n");
876 printf("\t-tekton\t\tUse the Tekton font for time field.\n");
877 printf("\t-arial\t\tUse the Arial-Narrow (i.e. Helvetica-Narrow) font for time field.\n");
878 printf("\t-jazz\t\tUse the JazzPoster font for time field.\n");
879 printf("\t-luggerbug\tUse the Luggerbug font for time field.\n");
880 printf("\t-comicsans\tUse the ComicSans font for time field.\n");
881 printf("\t-tc <Color>\tColor of the time digits (e.g. red or #ff8800).\n");
882 printf("\t-bc <Color>\tBackground color.\n");
883 printf("\t-e \"Command\"\tCommand to execute via double click of mouse button 1.\n");
884 printf("\t-S\t\tDo not show seconds.\n");
885 printf("\t-24\t\tShow 24-hour time. Default is 12 hour AM/PM Time.\n");
886 printf("\t-g\t\tShow Greenwich time.\n");
887 printf("\t-s\t\tShow Greenwich Mean Sidereal Time (GMST) in 24-hour format. \n");
888 printf("\t-L <Longitude>\tShow Local Sidereal Time (LST) in 24-hour format. \n");
889 printf("\t \t\tLongitude is in degrees (- for West + for East).\n");
890 printf("\t-l\t\tUse a low-color pixmap to conserve colors. On 8-bit displays the\n");
891 printf("\t \t\tlow color pixmap will always be used.\n");
892 printf("\t-h\t\tDisplay help screen.\n");
893 printf("\nExample: wmCalClock -b 100 -tc #001100 -bc #7e9e69 \n\n");
903 * Compute the Julian Day number for the given date.
904 * Julian Date is the number of days since noon of Jan 1 4713 B.C.
906 double jd(ny, nm, nd, UT)
907 int ny, nm, nd;
908 double UT;
910 double A, B, C, D, JD, day;
912 day = nd + UT/24.0;
915 if ((nm == 1) || (nm == 2)){
916 ny = ny - 1;
917 nm = nm + 12;
920 if (((double)ny+nm/12.0+day/365.25)>=(1582.0+10.0/12.0+15.0/365.25)){
921 A = ((int)(ny / 100.0));
922 B = 2.0 - A + (int)(A/4.0);
924 else{
925 B = 0.0;
928 if (ny < 0.0){
929 C = (int)((365.25*(double)ny) - 0.75);
931 else{
932 C = (int)(365.25*(double)ny);
935 D = (int)(30.6001*(double)(nm+1));
938 JD = B + C + D + day + 1720994.5;
939 return(JD);
943 double hour24(hour)
944 double hour;
946 int n;
948 if (hour < 0.0){
949 n = (int)(hour/24.0) - 1;
950 return(hour-n*24.0);
952 else if (hour > 24.0){
953 n = (int)(hour/24.0);
954 return(hour-n*24.0);
956 else{
957 return(hour);
968 * This routine handles button presses.
970 * Double click on
971 * Mouse Button 1: Execute the command defined in the -e command-line option.
972 * Mouse Button 2: No action assigned.
973 * Mouse Button 3: No action assigned.
977 void ButtonPressEvent(XButtonEvent *xev){
979 char Command[512];
982 if( HasExecute == 0) return; /* no command specified. Ignore clicks. */
983 DblClkDelay = 0;
984 if ((xev->button == Button1) && (xev->type == ButtonPress)){
985 if (GotFirstClick1) GotDoubleClick1 = 1;
986 else GotFirstClick1 = 1;
987 } else if ((xev->button == Button2) && (xev->type == ButtonPress)){
988 if (GotFirstClick2) GotDoubleClick2 = 1;
989 else GotFirstClick2 = 1;
990 } else if ((xev->button == Button3) && (xev->type == ButtonPress)){
991 if (GotFirstClick3) GotDoubleClick3 = 1;
992 else GotFirstClick3 = 1;
997 * We got a double click on Mouse Button1 (i.e. the left one)
999 if (GotDoubleClick1) {
1000 GotFirstClick1 = 0;
1001 GotDoubleClick1 = 0;
1002 sprintf(Command, "%s &", ExecuteCommand);
1003 system(Command);
1008 * We got a double click on Mouse Button2 (i.e. the left one)
1010 if (GotDoubleClick2) {
1011 GotFirstClick2 = 0;
1012 GotDoubleClick2 = 0;
1017 * We got a double click on Mouse Button3 (i.e. the left one)
1019 if (GotDoubleClick3) {
1020 GotFirstClick3 = 0;
1021 GotDoubleClick3 = 0;
1026 return;