3 * wmCalClock-1.25 (C) 1998, 1999 Mike Henderson (mghenderson@lanl.gov)
5 * - Its a Calendar Clock....
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)
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
28 * Version 1.25 - released July 2, 1999.
29 * Some optimization + ignores double click if no command set (patch from
32 * Version 1.24 - released March 27, 1999.
33 * Added support for additional fonts for time field;
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
44 * Version 1.23 - released March 20, 1999.
45 * Switched from wmgeneral.c stuff to xutils.c (a more stripped down version
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
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
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.
97 #include <X11/XKBlib.h>
99 #include "wmCalClock_master.xpm"
100 #include "wmCalClock_master_LowColor.xpm"
101 #include "wmCalClock_mask.xbm"
106 * Delay between refreshes (in microseconds)
109 #define WMCALCLOCK_VERSION "1.25"
115 void ParseCMDLine(int argc
, char *argv
[]);
116 void ButtonPressEvent(XButtonEvent
*);
122 int xsMonth
[12] = { 150, 170, 190, 212, 233, 256, 276, 294, 317, 337, 357, 380 };
123 int xeMonth
[12] = { 168, 188, 210, 231, 254, 275, 292, 314, 335, 355, 377, 398 };
128 int xsDayOfWeek
[7] = { 293, 150, 177, 201, 228, 253, 271 };
129 int xeDayOfWeek
[7] = { 314, 175, 199, 226, 250, 269, 290 };
132 int ydDayOfWeek
= 13;
135 * I think this is 28??-pixel high adobe-myriad-bold
137 int xsDayOfMonth
[31] = { 118, 161, 205, 248, 291, 335, 378, 421, 465,
138 75, 118, 162, 205, 248, 292, 335, 378, 422, 465,
139 75, 118, 162, 205, 248, 292, 335, 378, 422, 465,
142 * I think this is 16-pixel high adobe-myriad-bold?
144 int xeDayOfMonth
[31] = { 147, 193, 236, 282, 324, 368, 411, 454, 498,
145 107, 146, 192, 235, 281, 323, 367, 410, 453, 497,
146 108, 147, 193, 236, 282, 324, 368, 411, 454, 498,
148 int xeDayOfMonth2
[31] = { 144, 190, 234, 278, 320, 365, 407, 451, 494,
149 103, 143, 189, 233, 277, 319, 364, 406, 450, 493,
150 104, 144, 190, 234, 278, 320, 365, 407, 451, 494,
154 * I think this is 16-pixel high adobe-myriad-bold?
156 int yDayOfMonth
[31] = { 5, 5, 5, 5, 5, 5, 5, 5, 5,
157 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
158 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
160 int xdDayOfMonth
[31];
161 int xdDayOfMonth2
[31];
162 int ydDayOfMonth
= 23;
168 * Luggerbug Font Narrow - 13 pixels high.
170 int xsDigits_Luggerbug13n
[11] = { 75, 84, 92, 101, 110, 119, 127, 136, 143, 151, 159 };
171 int xeDigits_Luggerbug13n
[11] = { 80, 89, 97, 106, 115, 123, 132, 139, 147, 156, 159 };
172 int xdDigits_Luggerbug13n
[11];
173 int yDigits_Luggerbug13n
= 150;
174 int ydDigits_Luggerbug13n
= 13;
177 * Luggerbug Font - 13 pixels high.
179 int xsDigits_Luggerbug13
[11] = { 75, 89, 103, 117, 131, 146, 159, 172, 184, 197, 208 };
180 int xeDigits_Luggerbug13
[11] = { 83, 97, 110, 125, 139, 153, 166, 178, 191, 205, 209 };
181 int xdDigits_Luggerbug13
[11];
182 int yDigits_Luggerbug13
= 136;
183 int ydDigits_Luggerbug13
= 13;
186 * ComicSans Font - 12 pixels high.
188 int xsDigits_ComicSans12n
[11] = { 338, 349, 359, 370, 380, 390, 401, 411, 422, 432, 444 };
189 int xeDigits_ComicSans12n
[11] = { 343, 353, 364, 374, 385, 396, 406, 417, 427, 438, 445 };
190 int xdDigits_ComicSans12n
[11];
191 int yDigits_ComicSans12n
= 123;
192 int ydDigits_ComicSans12n
= 12;
195 * ComicSans Font - 11 pixels high.
197 int xsDigits_ComicSans11
[11] = { 338, 353, 366, 380, 392, 407, 420, 434, 448, 461, 471 };
198 int xeDigits_ComicSans11
[11] = { 345, 357, 372, 386, 400, 413, 427, 441, 454, 468, 473 };
199 int xdDigits_ComicSans11
[11];
200 int yDigits_ComicSans11
= 111;
201 int ydDigits_ComicSans11
= 11;
204 * JazzPoster Font Narrow - 12 pixels high.
206 int xsDigits_JazzPoster12n
[11] = { 211, 220, 226, 233, 241, 249, 256, 263, 271, 278, 286 };
207 int xeDigits_JazzPoster12n
[11] = { 217, 223, 231, 238, 247, 253, 261, 268, 276, 284, 286 };
208 int xdDigits_JazzPoster12n
[11];
209 int yDigits_JazzPoster12n
= 122;
210 int ydDigits_JazzPoster12n
= 12;
213 * JazzPoster Font - 12 pixels high.
215 int xsDigits_JazzPoster12
[11] = { 211, 225, 234, 246, 258, 271, 282, 293, 305, 317, 328 };
216 int xeDigits_JazzPoster12
[11] = { 221, 230, 243, 254, 268, 278, 290, 301, 314, 325, 329 };
217 int xdDigits_JazzPoster12
[11];
218 int yDigits_JazzPoster12
= 109;
219 int ydDigits_JazzPoster12
= 12;
223 * Tekton Font - 12 pixels high Narrow (13 pixels high actually).
225 int xsDigits_Tekton12n
[11] = { 75, 84, 90, 97, 105, 114, 122, 131, 138, 147, 156 };
226 int xeDigits_Tekton12n
[11] = { 81, 86, 94, 103, 111, 119, 128, 135, 144, 152, 157 };
227 int xdDigits_Tekton12n
[11];
228 int yDigits_Tekton12n
= 122;
229 int ydDigits_Tekton12n
= 13;
232 * Tekton Font - 12 pixels high.
234 int xsDigits_Tekton12
[11] = { 75, 89, 98, 111, 124, 137, 150, 164, 176, 191, 205 };
235 int xeDigits_Tekton12
[11] = { 84, 92, 105, 119, 132, 145, 159, 171, 185, 199, 206 };
236 int xdDigits_Tekton12
[11];
237 int yDigits_Tekton12
= 108;
238 int ydDigits_Tekton12
= 12;
241 * Monotype-arial-bold-narrow - 10 pixels high.
243 int xsDigits_Arial10
[11] = { 320, 326, 333, 339, 346, 352, 358, 364, 371, 377, 384 };
244 int xeDigits_Arial10
[11] = { 325, 331, 338, 344, 351, 357, 363, 369, 376, 382, 385 };
245 int xdDigits_Arial10
[11];
246 int yDigits_Arial10
= 95;
247 int ydDigits_Arial10
= 10;
257 int xsAMPM
[2] = { 390, 396 };
258 int xeAMPM
[2] = { 394, 400 };
262 int Show24HourTime
= 0;
263 int ShowGreenwichTime
= 0;
264 int ShowSiderealTime
= 0;
270 int UseLowColorPixmap
= 0;
272 int UseComicSans
= 0;
274 int UseLuggerbug
= 0;
275 int UseJazzPoster
= 0;
276 int GotFirstClick1
, GotDoubleClick1
;
277 int GotFirstClick2
, GotDoubleClick2
;
278 int GotFirstClick3
, GotDoubleClick3
;
280 int HasExecute
= 0; /* controls perf optimization */
281 char ExecuteCommand
[1024];
284 char TimeColor
[30] = "#ffff00";
285 char BackgroundColor
[30] = "#181818";
288 float KbTransparency
= 0.25;
289 int EnableKbIndicator
= 0;
290 char KbImgNames
[1024];
291 int KbLoadedImgs
= 0;
292 int KbConfiguredGroups
= 0;
296 int LoadLayoutInfo(void);
305 int main(int argc
, char *argv
[]) {
310 int i
, n
, wid
, extrady
, extradx
;
311 int Year
, Month
, DayOfWeek
, DayOfMonth
, OldDayOfMonth
;
312 int Hours
, Mins
, Secs
, OldSecs
, digit
, xoff
, D
[10], xsize
;
313 long CurrentLocalTime
;
314 double UT
, TU
, TU2
, TU3
, T0
, gmst
, jd(), hour24();
318 * Parse any command line arguments.
320 ParseCMDLine(argc
, argv
);
330 if (UseTekton
&& !ShowSeconds
){
332 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_Tekton12
[i
];
333 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_Tekton12
[i
];
334 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_Tekton12
[i
];
335 yDigits
= yDigits_Tekton12
;
336 ydDigits
= ydDigits_Tekton12
;
340 } else if (UseTekton
&& ShowSeconds
){
342 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_Tekton12n
[i
];
343 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_Tekton12n
[i
];
344 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_Tekton12n
[i
];
345 yDigits
= yDigits_Tekton12n
;
346 ydDigits
= ydDigits_Tekton12n
;
350 } else if (UseLuggerbug
&& !ShowSeconds
){
352 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_Luggerbug13
[i
];
353 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_Luggerbug13
[i
];
354 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_Luggerbug13
[i
];
355 yDigits
= yDigits_Luggerbug13
;
356 ydDigits
= ydDigits_Luggerbug13
;
360 } else if (UseLuggerbug
&& ShowSeconds
){
362 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_Luggerbug13n
[i
];
363 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_Luggerbug13n
[i
];
364 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_Luggerbug13n
[i
];
365 yDigits
= yDigits_Luggerbug13n
;
366 ydDigits
= ydDigits_Luggerbug13n
;
370 } else if (UseComicSans
&& !ShowSeconds
){
372 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_ComicSans11
[i
];
373 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_ComicSans11
[i
];
374 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_ComicSans11
[i
];
375 yDigits
= yDigits_ComicSans11
;
376 ydDigits
= ydDigits_ComicSans11
;
380 } else if (UseComicSans
&& ShowSeconds
){
382 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_ComicSans12n
[i
];
383 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_ComicSans12n
[i
];
384 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_ComicSans12n
[i
];
385 yDigits
= yDigits_ComicSans12n
;
386 ydDigits
= ydDigits_ComicSans12n
;
390 } else if (UseJazzPoster
&& !ShowSeconds
){
392 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_JazzPoster12
[i
];
393 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_JazzPoster12
[i
];
394 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_JazzPoster12
[i
];
395 yDigits
= yDigits_JazzPoster12
;
396 ydDigits
= ydDigits_JazzPoster12
;
400 } else if (UseJazzPoster
&& ShowSeconds
){
402 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_JazzPoster12n
[i
];
403 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_JazzPoster12n
[i
];
404 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_JazzPoster12n
[i
];
405 yDigits
= yDigits_JazzPoster12n
;
406 ydDigits
= ydDigits_JazzPoster12n
;
412 for (i
=0; i
<11; ++i
) xsDigits
[i
] = xsDigits_Arial10
[i
];
413 for (i
=0; i
<11; ++i
) xeDigits
[i
] = xeDigits_Arial10
[i
];
414 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xdDigits_Arial10
[i
];
415 yDigits
= yDigits_Arial10
;
416 ydDigits
= ydDigits_Arial10
;
424 * Compute widths of digits etc...
425 * Should hand-encode for efficiency, but its easier to do this for development...
427 for (i
=0; i
<12; ++i
) xdMonth
[i
] = xeMonth
[i
] - xsMonth
[i
] + 1;
428 for (i
=0; i
<7; ++i
) xdDayOfWeek
[i
] = xeDayOfWeek
[i
] - xsDayOfWeek
[i
] + 1;
429 for (i
=0; i
<31; ++i
) xdDayOfMonth
[i
] = xeDayOfMonth
[i
] - xsDayOfMonth
[i
] + 1;
430 for (i
=0; i
<31; ++i
) xdDayOfMonth2
[i
] = xeDayOfMonth2
[i
] - xsDayOfMonth
[i
] + 1;
431 for (i
=0; i
<11; ++i
) xdDigits
[i
] = xeDigits
[i
] - xsDigits
[i
] + 1;
432 for (i
=0; i
<2; ++i
) xdAMPM
[i
] = xeAMPM
[i
] - xsAMPM
[i
] + 1;
442 initXwindow(argc
, argv
);
443 if (DisplayDepth
<= 8) UseLowColorPixmap
= 1;
445 if (UseLowColorPixmap
)
446 openXwindow(argc
, argv
, wmCalClock_master_LowColor
, wmCalClock_mask_bits
, wmCalClock_mask_width
, wmCalClock_mask_height
);
448 openXwindow(argc
, argv
, wmCalClock_master
, wmCalClock_mask_bits
, wmCalClock_mask_width
, wmCalClock_mask_height
);
451 /* if we should indicate keyboard layouts */
452 if (EnableKbIndicator
) {
453 int opcode_rtrn
, error_rtrn
, major
, minor
;
456 /* before initializing XKB extension we should check if server and
457 * client version are the same, but XkbLibraryVersion doesn't work */
458 if (XkbQueryExtension(display
, &opcode_rtrn
, &KbXkbEvent
, &error_rtrn
,
461 KbConfiguredGroups
= LoadLayoutInfo();
462 KbLoadedImgs
= LoadKbImg(KbImgNames
);
463 if ((KbLoadedImgs
!= KbConfiguredGroups
) || (!KbLoadedImgs
) || (!KbConfiguredGroups
)) {
464 fprintf(stderr
, "wmCalClock: Bad loaded images and configured keyboard groups numbers %d, %d.\n", KbLoadedImgs
, KbConfiguredGroups
);
465 EnableKbIndicator
= 0;
467 XkbSelectEventDetails(display
, XkbUseCoreKbd
, XkbStateNotify
,
468 XkbGroupStateMask
, XkbGroupStateMask
);
469 XkbGetState(display
, XkbUseCoreKbd
, &state
);
470 KbCurGrp
= state
.group
;
475 fprintf(stderr
, "wmCalClock: Incompatible client and server XKB extension version.\n");
476 EnableKbIndicator
= 0;
494 * Only process every 10th cycle of this loop. We run it faster
495 * to catch expose events, etc...
498 if ( HasExecute
== 0 || n
>10){
502 if (ShowGreenwichTime
){
504 CurrentLocalTime
= time(CurrentTime
);
505 Time
= gmtime(&CurrentLocalTime
);
506 DayOfMonth
= Time
->tm_mday
-1;
507 DayOfWeek
= Time
->tm_wday
;
508 Month
= Time
->tm_mon
;
509 Hours
= Time
->tm_hour
;
513 } else if (ShowSiderealTime
){
516 CurrentLocalTime
= time(CurrentTime
);
517 Time
= gmtime(&CurrentLocalTime
);
518 DayOfMonth
= Time
->tm_mday
-1;
519 DayOfWeek
= Time
->tm_wday
;
520 Year
= Time
->tm_year
+ 1900; /* this is NOT a Y2K bug */
521 Month
= Time
->tm_mon
;
522 Hours
= Time
->tm_hour
;
525 UT
= (double)Hours
+ (double)Mins
/60.0 + (double)Secs
/3600.0;
528 * Compute Greenwich Mean Sidereal Time (gmst)
529 * The TU here is number of Julian centuries
530 * since 2000 January 1.5
531 * From the 1996 astronomical almanac
533 TU
= (jd(Year
, Month
+1, DayOfMonth
+1, 0.0) - 2451545.0)/36525.0;
536 T0
= (6.0 + 41.0/60.0 + 50.54841/3600.0) + 8640184.812866/3600.0*TU
537 + 0.093104/3600.0*TU2
- 6.2e-6/3600.0*TU3
;
538 gmst
= hour24(hour24(T0
) + UT
*1.002737909 + Longitude
/15.0);
540 gmst
= (gmst
- (double)Hours
)*60.0;
542 gmst
= (gmst
- (double)Mins
)*60.0;
547 CurrentLocalTime
= time(CurrentTime
);
548 Time
= localtime(&CurrentLocalTime
);
549 DayOfMonth
= Time
->tm_mday
-1;
550 DayOfWeek
= Time
->tm_wday
;
551 Month
= Time
->tm_mon
;
552 Hours
= Time
->tm_hour
;
559 * Flag indicates AM (Flag=0) or PM (Flag=1)
561 if (!Show24HourTime
){
562 Flag
= (Hours
>= 12) ? 1 : 0;
566 Hours
= (Hours
> 12) ? Hours
-12 : Hours
;
573 * Blank the HH:MM section....
576 /* dont show leading zeros */
577 if ((digit
= Hours
/ 10) > 0){
578 D
[0] = digit
, xsize
+= (xdDigits
[digit
]+1);
582 digit
= Hours
% 10, D
[1] = digit
, xsize
+= (xdDigits
[digit
]+1);
583 digit
= 10, D
[2] = digit
, xsize
+= (xdDigits
[digit
]+1);
584 digit
= Mins
/ 10, D
[3] = digit
, xsize
+= (xdDigits
[digit
]+1);
585 digit
= Mins
% 10, D
[4] = digit
, xsize
+= (xdDigits
[digit
]+1);
587 digit
= 10, D
[5] = digit
, xsize
+= (xdDigits
[digit
]+1);
588 digit
= Secs
/ 10, D
[6] = digit
, xsize
+= (xdDigits
[digit
]+1);
589 digit
= Secs
% 10, D
[7] = digit
, xsize
+= (xdDigits
[digit
]);
591 xoff
= ((Hours
>9)&&(!Show24HourTime
)&&(ShowSeconds
)) ? 28 - xsize
/2 : 31 - xsize
/2;
592 copyXPMArea(5, 110, 54, 15, 5, 5);
599 /* dont show leading zeros */
602 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
603 xoff
+= (xdDigits
[digit
]+1);
607 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
608 xoff
+= (xdDigits
[digit
]+1);
614 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
615 xoff
+= (xdDigits
[digit
]+1);
621 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
622 xoff
+= (xdDigits
[digit
]+1);
625 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
626 xoff
+= (xdDigits
[digit
]+1);
634 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
635 xoff
+= (xdDigits
[digit
]+1);
641 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
642 xoff
+= (xdDigits
[digit
]+1);
645 copyXPMArea(xsDigits
[digit
], yDigits
, xdDigits
[digit
], ydDigits
, xoff
+extradx
, 7+extrady
);
646 xoff
+= (xdDigits
[digit
]+3);
652 * Draw AM/PM indicator if we are using 12 Hour Clock.
653 * Dont show it if we are using 24 Hour Clock.
656 copyXPMArea(xsAMPM
[Flag
], yAMPM
, xdAMPM
[Flag
], ydAMPM
, 54, 5);
666 if ((Mins
== 0)&&(Secs
== 0)&&(OldSecs
!= Secs
)) XBell(display
, Volume
);
676 if (OldDayOfMonth
!= DayOfMonth
){
680 * Blank the Calendar section....
682 copyXPMArea(5, 70, 54, 35, 5, 24);
686 * Draw Day of Week and Month
688 wid
= xdDayOfWeek
[DayOfWeek
] + xdMonth
[Month
] + 1;
689 copyXPMArea(xsDayOfWeek
[DayOfWeek
], yDayOfWeek
, xdDayOfWeek
[DayOfWeek
],
690 ydMonth
, 33-wid
/2, 64-24-4-12);
691 copyXPMArea(xsMonth
[Month
], yMonth
, xdMonth
[Month
],
692 ydMonth
, 33-wid
/2+xdDayOfWeek
[DayOfWeek
]+1, 64-24-4-12);
699 copyXPMArea(xsDayOfMonth
[DayOfMonth
], yDayOfMonth
[DayOfMonth
], xdDayOfMonth
[DayOfMonth
], ydDayOfMonth
, 32-xdDayOfMonth2
[DayOfMonth
]/2, 36);
701 if (EnableKbIndicator
) {
703 ShowGroupImage(KbCurGrp
);
710 OldDayOfMonth
= DayOfMonth
;
718 * Update the counter.
729 * Double Click Delays
730 * Keep track of click events. If Delay too long, set GotFirstClick's to False.
732 if (DblClkDelay
> 15) {
735 GotFirstClick1
= 0; GotDoubleClick1
= 0;
736 GotFirstClick2
= 0; GotDoubleClick2
= 0;
737 GotFirstClick3
= 0; GotDoubleClick3
= 0;
749 * Process any pending X events.
751 while(XPending(display
)) {
752 XNextEvent(display
, &xkbevent
.core
);
753 if ((EnableKbIndicator
) && (xkbevent
.type
== KbXkbEvent
)) {
754 /* printf("wmCalClock: event %d\n", xkbevent.any.xkb_type); */
755 if (xkbevent
.any
.xkb_type
== XkbStateNotify
) {
757 KbCurGrp
= xkbevent
.state
.group
;
758 /*printf("group change: %d\n", grp);*/
759 if ((KbCurGrp
>= 0) && (KbCurGrp
< KbConfiguredGroups
)) {
760 ShowGroupImage(KbCurGrp
);
762 fprintf(stderr
, "wmCalClock: disabling KB feature\n");
763 EnableKbIndicator
= 0;
768 switch(xkbevent
.core
.type
) {
773 ButtonPressEvent(&xkbevent
.core
.xbutton
);
787 * Redraw and wait for next update
790 if( HasExecute
== 1) {
792 } else if( ShowSeconds
== 1) {
815 void ParseCMDLine(int argc
, char *argv
[]) {
819 for (i
= 1; i
< argc
; i
++) {
821 if (!strcmp(argv
[i
], "-display")){
825 } else if (!strcmp(argv
[i
], "-jazz")){
829 } else if (!strcmp(argv
[i
], "-arial")){
833 } else if (!strcmp(argv
[i
], "-tekton")){
837 } else if (!strcmp(argv
[i
], "-luggerbug")){
841 } else if (!strcmp(argv
[i
], "-comicsans")){
845 } else if (!strcmp(argv
[i
], "-tc")){
847 if ((i
+1 >= argc
)||(argv
[i
+1][0] == '-')) {
848 fprintf(stderr
, "wmCalClock: No color found\n");
852 strcpy(TimeColor
, argv
[++i
]);
854 } else if (!strcmp(argv
[i
], "-bc")){
856 if ((i
+1 >= argc
)||(argv
[i
+1][0] == '-')) {
857 fprintf(stderr
, "wmCalClock: No color found\n");
861 strcpy(BackgroundColor
, argv
[++i
]);
863 } else if (!strcmp(argv
[i
], "-24")){
867 } else if (!strcmp(argv
[i
], "-b")){
869 if ((i
+1 >= argc
)||(argv
[i
+1][0] == '-')) {
870 fprintf(stderr
, "wmCalClock: No volume given\n");
875 Volume
= atoi(argv
[++i
]);
877 } else if (!strcmp(argv
[i
], "-e")){
879 if ((i
+1 >= argc
)||(argv
[i
+1][0] == '-')) {
880 fprintf(stderr
, "wmCalClock: No command given\n");
884 strcpy(ExecuteCommand
, argv
[++i
]);
887 } else if (!strcmp(argv
[i
], "-g")){
889 ShowGreenwichTime
= 1;
891 } else if (!strcmp(argv
[i
], "-S")){
895 } else if (!strcmp(argv
[i
], "-s")){
897 ShowSiderealTime
= 1;
900 } else if (!strcmp(argv
[i
], "-L")){
902 if ((i
+1 >= argc
)||(argv
[i
+1][0] == '-')) {
903 fprintf(stderr
, "wmCalClock: No longitude given\n");
907 ShowSiderealTime
= 1;
908 Longitude
= atof(argv
[++i
]);
910 } else if (!strcmp(argv
[i
], "-l")){
912 UseLowColorPixmap
= 1;
914 } else if (!strcmp(argv
[i
], "-kb")) {
916 if ((i
+ 1 >= argc
) || (argv
[i
+ 1][0] == '-')) {
917 fprintf(stderr
, "wmCalClock: No images given\n");
921 EnableKbIndicator
= 1;
922 strncpy(KbImgNames
, argv
[++i
], 1024);
924 } else if (!strcmp(argv
[i
], "-kbt")) {
926 if ((i
+ 1 >= argc
) || (argv
[i
+ 1][0] == '-')) {
927 fprintf(stderr
, "wmCalClock: No transparency given\n");
931 KbTransparency
= atof(argv
[++i
]);
932 if ((KbTransparency
> 1) || (KbTransparency
< 0)) {
933 fprintf(stderr
, "wmCalClock: Bad transparency given (not in 0.0 - 1.0)\n");
946 if (!ShowSeconds
&& !UseArial
&& !UseJazzPoster
947 && !UseComicSans
&& !UseLuggerbug
) UseTekton
= 1;
956 printf("\nwmCalClock version: %s\n", WMCALCLOCK_VERSION
);
957 printf("\nusage: wmCalClock [-b <Volume>] [-tc <Color>] [-bc <Color>] [-e \"Command\"] [-S]\n");
958 printf(" [-24] [-g] [-s] [-l <longitude>] [-l] [-jazz] [-tekton] [-luggerbug]\n");
959 printf(" [-arial] [-comicsans] [-h]\n\n");
960 printf("\t-b <Volume>\tBeep on the hour. Volume is between -100 to 100.\n");
961 printf("\t-tekton\t\tUse the Tekton font for time field.\n");
962 printf("\t-arial\t\tUse the Arial-Narrow (i.e. Helvetica-Narrow) font for time field.\n");
963 printf("\t-jazz\t\tUse the JazzPoster font for time field.\n");
964 printf("\t-luggerbug\tUse the Luggerbug font for time field.\n");
965 printf("\t-comicsans\tUse the ComicSans font for time field.\n");
966 printf("\t-tc <Color>\tColor of the time digits (e.g. red or #ff8800).\n");
967 printf("\t-bc <Color>\tBackground color.\n");
968 printf("\t-e \"Command\"\tCommand to execute via double click of mouse button 1.\n");
969 printf("\t-S\t\tDo not show seconds.\n");
970 printf("\t-24\t\tShow 24-hour time. Default is 12 hour AM/PM Time.\n");
971 printf("\t-g\t\tShow Greenwich time.\n");
972 printf("\t-s\t\tShow Greenwich Mean Sidereal Time (GMST) in 24-hour format. \n");
973 printf("\t-L <Longitude>\tShow Local Sidereal Time (LST) in 24-hour format. \n");
974 printf("\t \t\tLongitude is in degrees (- for West + for East).\n");
975 printf("\t-l\t\tUse a low-color pixmap to conserve colors. On 8-bit displays the\n");
976 printf("\t \t\tlow color pixmap will always be used.\n");
977 printf("\t-kb <Images>\tEnable keyboard layout indication.\n");
978 printf("\t \t\t<Images> = up to 4 filenames (e.g. \"us.xpm,cz.xpm\")\n");
979 printf("\t-kbt <Number>\tKeyboard image transparency 0.0 - 1.0 (default 0.25)\n");
980 printf("\t-h\t\tDisplay help screen.\n");
981 printf("\nExample: wmCalClock -b 100 -tc #001100 -bc #7e9e69 \n\n");
991 * Compute the Julian Day number for the given date.
992 * Julian Date is the number of days since noon of Jan 1 4713 B.C.
994 double jd(ny
, nm
, nd
, UT
)
998 double A
, B
, C
, D
, JD
, day
;
1003 if ((nm
== 1) || (nm
== 2)){
1008 if (((double)ny
+nm
/12.0+day
/365.25)>=(1582.0+10.0/12.0+15.0/365.25)){
1009 A
= ((int)(ny
/ 100.0));
1010 B
= 2.0 - A
+ (int)(A
/4.0);
1017 C
= (int)((365.25*(double)ny
) - 0.75);
1020 C
= (int)(365.25*(double)ny
);
1023 D
= (int)(30.6001*(double)(nm
+1));
1026 JD
= B
+ C
+ D
+ day
+ 1720994.5;
1037 n
= (int)(hour
/24.0) - 1;
1038 return(hour
-n
*24.0);
1040 else if (hour
> 24.0){
1041 n
= (int)(hour
/24.0);
1042 return(hour
-n
*24.0);
1056 * This routine handles button presses.
1059 * Mouse Button 1: Execute the command defined in the -e command-line option.
1060 * Mouse Button 2: No action assigned.
1061 * Mouse Button 3: No action assigned.
1065 void ButtonPressEvent(XButtonEvent
*xev
){
1070 if( HasExecute
== 0) return; /* no command specified. Ignore clicks. */
1072 if ((xev
->button
== Button1
) && (xev
->type
== ButtonPress
)){
1073 if (GotFirstClick1
) GotDoubleClick1
= 1;
1074 else GotFirstClick1
= 1;
1075 } else if ((xev
->button
== Button2
) && (xev
->type
== ButtonPress
)){
1076 if (GotFirstClick2
) GotDoubleClick2
= 1;
1077 else GotFirstClick2
= 1;
1078 } else if ((xev
->button
== Button3
) && (xev
->type
== ButtonPress
)){
1079 if (GotFirstClick3
) GotDoubleClick3
= 1;
1080 else GotFirstClick3
= 1;
1085 * We got a double click on Mouse Button1 (i.e. the left one)
1087 if (GotDoubleClick1
) {
1089 GotDoubleClick1
= 0;
1090 sprintf(Command
, "%s &", ExecuteCommand
);
1096 * We got a double click on Mouse Button2 (i.e. the left one)
1098 if (GotDoubleClick2
) {
1100 GotDoubleClick2
= 0;
1105 * We got a double click on Mouse Button3 (i.e. the left one)
1107 if (GotDoubleClick3
) {
1109 GotDoubleClick3
= 0;
1119 int LoadLayoutInfo(void) {
1120 int /* i, */ groups
;
1123 /* we should select only XkbControlsMask | XkbNamesMask, but we get
1125 if (!(kb_desc
= XkbGetKeyboard(display
, XkbAllComponentsMask
, XkbUseCoreKbd
))) {
1126 fprintf(stderr
, "wmCalClock: Could not allocate memory for keyboard description.\n");
1130 if (XkbGetControls(display
, XkbGroupsWrapMask
, kb_desc
) != Success
) {
1131 fprintf(stderr
, "wmCalClock: Could not get controls for keyboard.\n");
1136 groups
= kb_desc
->ctrls
->num_groups
;
1137 /* printf("You have configured %u keyboard groups.\n", groups);
1138 printf("Your keyboard have following groups:\n");
1139 for (i = 0; i < groups; i++) {
1140 printf("Group %d: %s\n", i, XGetAtomName(display, kb_desc->names->groups[i]));
1142 XkbFreeKeyboard(kb_desc
, 0, 1);