2 Code based on wmppp/wmifs
6 This code was mainly put together by looking at the
10 A neat piece of equip, used to display the date
11 and time on the screen.
12 Comes with every AfterStep installation.
15 How do I create a not so solid window?
16 How do I open a window?
19 ------------------------------------------------------------
21 Author: Martijn Pieterse (pieterse@xs4all.nl)
23 This program is distributed under the GPL license.
24 (as were asclock and pppstats)
29 15/07/2008 (Paul Harris, harris.pc@gmail.com)
30 * Minor changes to correct build warnings
31 09/10/2003 (Simon Law, sfllaw@debian.org)
32 * Add -geometry support
33 * Add -noseconds support
34 * Make the digital clock fill the space provided
35 * Eliminated exploitable static buffers
36 17/05/1998 (Antoine Nulle, warp@xs4all.nl)
37 * Updated version number and some other minor stuff
38 16/05/1998 (Antoine Nulle, warp@xs4all.nl)
39 * Added Locale support, based on original diff supplied
40 by Alen Salamun (snowman@hal9000.medinet.si)
41 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
42 * Moved the hands one pixel down.
43 * Removed the RedrawWindow out of the main loop
44 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
45 * Removed a lot of code that was in the wmgeneral dir.
46 02/05/1998 (Antoine Nulle, warp@xs4all.nl)
47 * Updated master-xpm, hour dots where a bit 'off'
48 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
49 * Added anti-aliased hands
50 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
51 * Changed the hand lengths.. again! ;)
52 * Zombies were created, so added wait code
53 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
54 * Added digital/analog switching support
55 18/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
56 * Started this project.
57 * Copied the source from wmmon.
74 #include <sys/param.h>
75 #include <sys/types.h>
79 #include <X11/extensions/shape.h>
81 #include "../wmgeneral/wmgeneral.h"
82 #include "../wmgeneral/misc.h"
84 #include "wmtime-master.xpm"
85 #include "wmtime-mask.xbm"
91 const char* default_left_action
= NULL
;
92 const char* default_middle_action
= NULL
;
93 const char* default_right_action
= NULL
;
95 #define WMMON_VERSION "1.1"
97 /********************/
98 /* Global Variables */
99 /********************/
103 char day_of_week
[7][3] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
104 char mon_of_year
[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
108 void printversion(void);
110 void wmtime_routine(int, char **);
113 int main(int argc
, char *argv
[]) {
116 char *name
= argv
[0];
118 for (i
=1; i
<argc
; i
++) {
124 if (strcmp(arg
+1, "display")
125 && strcmp(arg
+1, "digital") && strcmp(arg
+1, "d")) {
129 if (!strcmp(arg
+1, "digital") || !(strcmp(arg
+1, "d")))
133 if (strcmp(arg
+1, "geometry")) {
139 if (strcmp(arg
+1, "noseconds") && strcmp(arg
+1, "n")) {
156 if (setlocale(LC_ALL
, "") != NULL
)
159 wmtime_routine(argc
, argv
);
168 char langbuf
[10], outbuf
[10];
172 size_t insize
, outsize
;
174 icd
= iconv_open("ASCII//TRANSLIT", nl_langinfo(CODESET
));
178 for (i
= 0; i
< 7; i
++) {
179 strncpy(langbuf
, nl_langinfo(ABDAY_1
+ i
), 10);
180 insize
= outsize
= 10;
184 ret
= iconv(icd
, &inp
, &insize
, &outp
, &outsize
);
185 } while (outsize
> 0 && ret
> 0);
186 if (strstr(outbuf
,"?") != NULL
) return;
187 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 2;
189 day_of_week
[i
][outsize
] = toupper(*outp
);
191 for (i
= 0; i
< 12; i
++) {
192 strncpy(langbuf
, nl_langinfo(ABMON_1
+ i
), 10);
193 insize
= outsize
= 10;
197 ret
= iconv(icd
, &inp
, &insize
, &outp
, &outsize
);
198 } while (outsize
> 0 && ret
> 0);
199 if (strstr(outbuf
,"?") != NULL
) return;
200 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 3;
202 mon_of_year
[i
][outsize
] = toupper(*outp
);
208 /*******************************************************************************\
210 \*******************************************************************************/
212 char *left_action
= NULL
;
213 char *right_action
= NULL
;
214 char *middle_action
= NULL
;
216 void DrawTime(int, int, int);
217 void DrawWijzer(int, int, int);
218 void DrawDate(int, int, int);
220 void wmtime_routine(int argc
, char **argv
) {
222 rckeys wmtime_keys
[] = {
223 { "left", &left_action
},
224 { "right", &right_action
},
225 { "middle", &middle_action
},
233 struct tm
*time_struct
;
238 char *conffile
= NULL
;
240 /* Scan through ~/.wmtimerc for the mouse button actions. */
241 if (default_left_action
) left_action
= strdup(default_left_action
);
242 if (default_middle_action
) middle_action
= strdup(default_middle_action
);
243 if (default_right_action
) right_action
= strdup(default_right_action
);
245 /* Scan through the .rc files */
246 if (asprintf(&conffile
, "/etc/wmtimerc") >= 0) {
247 parse_rcfile(conffile
, wmtime_keys
);
251 if (asprintf(&conffile
, "%s/.wmtimerc", getenv("HOME")) >= 0) {
252 parse_rcfile(conffile
, wmtime_keys
);
256 if (asprintf(&conffile
, "/etc/wmtimerc.fixed") >= 0) {
257 parse_rcfile(conffile
, wmtime_keys
);
261 openXwindow(argc
, argv
, wmtime_master_xpm
, wmtime_mask_bits
, 128, 64);
263 /* Mask out the right parts of the clock */
264 copyXPMArea(0, 0, 128, 64, 0, 98); /* Draw the borders */
265 copyXPMArea(0, 0, 64, 64, 64, 0); /* Draw the clock face */
266 copyXPMArea(64, 98, 64, 64, 0, 0); /* Draw the LCD background */
269 /* add mouse region */
270 AddMouseRegion(0, 5, 48, 58, 60);
271 AddMouseRegion(1, 5, 5, 58, 46);
276 time_struct
= localtime(&curtime
);
281 waitpid(0, NULL
, WNOHANG
);
283 time_struct
= localtime(&curtime
);
286 if (curtime
>= starttime
) {
288 /* Now to update the seconds */
290 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
292 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
296 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
298 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
304 while (XPending(display
)) {
305 XNextEvent(display
, &Event
);
306 switch (Event
.type
) {
311 XCloseDisplay(display
);
315 but_stat
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
318 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
319 if (but_stat
== i
&& but_stat
>= 0) {
325 copyXPMArea(64, 98, 64, 64, 0, 0);
326 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
327 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
329 copyXPMArea(0, 98, 64, 64, 0, 0);
330 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
331 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
336 switch (Event
.xbutton
.button
) {
339 execCommand(left_action
);
343 execCommand(middle_action
);
347 execCommand(right_action
);
356 /* Sleep 0.3 seconds */
361 /*******************************************************************************\
363 \*******************************************************************************/
365 void DrawTime(int hr
, int min
, int sec
) {
366 const int time_size
= 16;
367 char time
[time_size
];
375 snprintf(time
, time_size
, "%02d:%02d ", hr
, min
);
379 snprintf(time
, time_size
, "%02d:%02d:%02d ", hr
, min
, sec
);
383 for (i
=0; i
< numfields
; i
++) {
384 for (j
=0; j
<2; j
++) {
385 copyXPMArea((*p
-'0')*7 + 1, 84, 8, 13, k
, 18);
390 copyXPMArea(71, 84, 5, 13, k
, 18);
397 /*******************************************************************************\
399 \*******************************************************************************/
401 void DrawDate(int wkday
, int dom
, int month
) {
402 const int date_size
= 16;
403 char date
[date_size
];
409 snprintf(date
, date_size
,
410 "%.2s%02d%.3s ", day_of_week
[wkday
], dom
, mon_of_year
[month
]);
413 for (i
=0; i
<2; i
++) {
415 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
417 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
422 for (i
=0; i
<2; i
++) {
423 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
427 copyXPMArea(61, 64, 4, 9, k
, 49);
429 for (i
=0; i
<3; i
++) {
431 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
433 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
439 /*******************************************************************************\
441 \*******************************************************************************/
443 void DrawWijzer(int hr
, int min
, int sec
) {
456 copyXPMArea(5+64, 5, 54, 40, 5, 5);
458 /**********************************************************************/
459 psi
= hr
* (M_PI
/ 6.0);
460 psi
+= min
* (M_PI
/ 360);
462 dx
= floor(sin(psi
) * 22 * 0.7 + 0.5);
463 dy
= floor(-cos(psi
) * 16 * 0.7 + 0.5);
465 // dx, dy is het punt waar we naar toe moeten.
466 // Zoek alle punten die ECHT op de lijn liggen:
470 if (dx
< 0) ddx
= -1;
471 if (dy
< 0) ddy
= -1;
476 if (abs(dx
) > abs(dy
)) {
481 for (i
=0; i
<abs(dx
); i
++) {
482 // laat de kleur afhangen van de adder.
483 // adder loopt van abs(dx) tot 0
485 k
= 12 - adder
/ (abs(dx
) / 12.0);
486 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
488 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
491 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
507 for (i
=0; i
<abs(dy
); i
++) {
508 k
= 12 - adder
/ (abs(dy
) / 12.0);
509 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
511 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
514 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
525 /**********************************************************************/
526 psi
= min
* (M_PI
/ 30.0);
527 psi
+= sec
* (M_PI
/ 1800);
529 dx
= floor(sin(psi
) * 22 * 0.55 + 0.5);
530 dy
= floor(-cos(psi
) * 16 * 0.55 + 0.5);
532 // dx, dy is het punt waar we naar toe moeten.
533 // Zoek alle punten die ECHT op de lijn liggen:
540 if (dx
< 0) ddx
= -1;
541 if (dy
< 0) ddy
= -1;
546 if (abs(dx
) > abs(dy
)) {
551 for (i
=0; i
<abs(dx
); i
++) {
552 // laat de kleur afhangen van de adder.
553 // adder loopt van abs(dx) tot 0
555 k
= 12 - adder
/ (abs(dx
) / 12.0);
556 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
558 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
561 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
577 for (i
=0; i
<abs(dy
); i
++) {
578 k
= 12 - adder
/ (abs(dy
) / 12.0);
579 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
581 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
584 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
595 /**********************************************************************/
597 return; /* Skip drawing the seconds. */
599 psi
= sec
* (M_PI
/ 30.0);
601 dx
= floor(sin(psi
) * 22 * 0.9 + 0.5);
602 dy
= floor(-cos(psi
) * 16 * 0.9 + 0.5);
604 // dx, dy is het punt waar we naar toe moeten.
605 // Zoek alle punten die ECHT op de lijn liggen:
609 if (dx
< 0) ddx
= -1;
610 if (dy
< 0) ddy
= -1;
612 if (dx
== 0) ddx
= 0;
613 if (dy
== 0) ddy
= 0;
619 if (abs(dx
) > abs(dy
)) {
624 for (i
=0; i
<abs(dx
); i
++) {
625 // laat de kleur afhangen van de adder.
626 // adder loopt van abs(dx) tot 0
628 k
= 12 - adder
/ (abs(dx
) / 12.0);
629 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24 - ddy
);
632 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
648 for (i
=0; i
<abs(dy
); i
++) {
649 k
= 12 - adder
/ (abs(dy
) / 12.0);
650 copyXPMArea(79+k
, 70, 1, 1, x
+ 31 - ddx
, y
+ 24);
653 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
666 /*******************************************************************************\
668 \*******************************************************************************/
670 void usage(char *name
) {
671 printf("Usage: %s [OPTION]...\n", name
);
672 printf("WindowMaker dockapp that displays the time and date.\n");
674 printf(" -d, -digital display the digital clock\n");
675 printf(" -display DISPLAY contact the DISPLAY X server\n");
676 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
677 printf(" -n, -noseconds disables the second hand\n");
678 printf(" -h display this help and exit\n");
679 printf(" -v output version information and exit\n");
682 /*******************************************************************************\
684 \*******************************************************************************/
686 void printversion(void) {
687 printf("WMTime version %s\n", WMMON_VERSION
);
690 /* vim: sw=4 ts=4 columns=82