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 WMTIME_VERSION "1.2"
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];
121 for (i
=1; i
<argc
; i
++) {
127 if (strcmp(arg
+1, "display")
128 && strcmp(arg
+1, "digital") && strcmp(arg
+1, "d")) {
132 if (!strcmp(arg
+1, "digital") || !(strcmp(arg
+1, "d")))
136 if (strcmp(arg
+1, "geometry")) {
142 if (strcmp(arg
+1, "noseconds") && strcmp(arg
+1, "n")) {
154 strcpy(locale
, argv
[i
+1]);
165 if (setlocale(LC_ALL
, locale
) == NULL
)
167 "warning: locale '%s' not recognized; defaulting to '%s'.",
168 locale
, setlocale(LC_ALL
, NULL
));
171 wmtime_routine(argc
, argv
);
180 char langbuf
[10], outbuf
[10];
184 size_t insize
, outsize
;
186 icd
= iconv_open("ASCII//TRANSLIT", nl_langinfo(CODESET
));
190 for (i
= 0; i
< 7; i
++) {
191 strncpy(langbuf
, nl_langinfo(ABDAY_1
+ i
), 10);
192 insize
= outsize
= 10;
196 ret
= iconv(icd
, &inp
, &insize
, &outp
, &outsize
);
197 } while (outsize
> 0 && ret
> 0);
198 if (strstr(outbuf
,"?") != NULL
) return;
199 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 2;
201 day_of_week
[i
][outsize
] = toupper(*outp
);
203 for (i
= 0; i
< 12; i
++) {
204 strncpy(langbuf
, nl_langinfo(ABMON_1
+ i
), 10);
205 insize
= outsize
= 10;
209 ret
= iconv(icd
, &inp
, &insize
, &outp
, &outsize
);
210 } while (outsize
> 0 && ret
> 0);
211 if (strstr(outbuf
,"?") != NULL
) return;
212 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 3;
214 mon_of_year
[i
][outsize
] = toupper(*outp
);
220 /*******************************************************************************\
222 \*******************************************************************************/
224 char *left_action
= NULL
;
225 char *right_action
= NULL
;
226 char *middle_action
= NULL
;
228 void DrawTime(int, int, int);
229 void DrawWijzer(int, int, int);
230 void DrawDate(int, int, int);
232 void wmtime_routine(int argc
, char **argv
) {
234 rckeys wmtime_keys
[] = {
235 { "left", &left_action
},
236 { "right", &right_action
},
237 { "middle", &middle_action
},
245 struct tm
*time_struct
;
250 char *conffile
= NULL
;
252 /* Scan through ~/.wmtimerc for the mouse button actions. */
253 if (default_left_action
) left_action
= strdup(default_left_action
);
254 if (default_middle_action
) middle_action
= strdup(default_middle_action
);
255 if (default_right_action
) right_action
= strdup(default_right_action
);
257 /* Scan through the .rc files */
258 if (asprintf(&conffile
, "/etc/wmtimerc") >= 0) {
259 parse_rcfile(conffile
, wmtime_keys
);
263 if (asprintf(&conffile
, "%s/.wmtimerc", getenv("HOME")) >= 0) {
264 parse_rcfile(conffile
, wmtime_keys
);
268 if (asprintf(&conffile
, "/etc/wmtimerc.fixed") >= 0) {
269 parse_rcfile(conffile
, wmtime_keys
);
273 openXwindow(argc
, argv
, wmtime_master_xpm
, wmtime_mask_bits
, 128, 64);
275 /* Mask out the right parts of the clock */
276 copyXPMArea(0, 0, 128, 64, 0, 98); /* Draw the borders */
277 copyXPMArea(0, 0, 64, 64, 64, 0); /* Draw the clock face */
278 copyXPMArea(64, 98, 64, 64, 0, 0); /* Draw the LCD background */
281 /* add mouse region */
282 AddMouseRegion(0, 5, 48, 58, 60);
283 AddMouseRegion(1, 5, 5, 58, 46);
288 time_struct
= localtime(&curtime
);
293 waitpid(0, NULL
, WNOHANG
);
295 time_struct
= localtime(&curtime
);
298 if (curtime
>= starttime
) {
300 /* Now to update the seconds */
302 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
304 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
308 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
310 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
316 while (XPending(display
)) {
317 XNextEvent(display
, &Event
);
318 switch (Event
.type
) {
323 XCloseDisplay(display
);
327 but_stat
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
330 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
331 if (but_stat
== i
&& but_stat
>= 0) {
337 copyXPMArea(64, 98, 64, 64, 0, 0);
338 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
339 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
341 copyXPMArea(0, 98, 64, 64, 0, 0);
342 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
343 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
348 switch (Event
.xbutton
.button
) {
351 execCommand(left_action
);
355 execCommand(middle_action
);
359 execCommand(right_action
);
368 /* Sleep 0.3 seconds */
373 /*******************************************************************************\
375 \*******************************************************************************/
377 void DrawTime(int hr
, int min
, int sec
) {
378 const int time_size
= 16;
379 char time
[time_size
];
387 snprintf(time
, time_size
, "%02d:%02d ", hr
, min
);
391 snprintf(time
, time_size
, "%02d:%02d:%02d ", hr
, min
, sec
);
395 for (i
=0; i
< numfields
; i
++) {
396 for (j
=0; j
<2; j
++) {
397 copyXPMArea((*p
-'0')*7 + 1, 84, 8, 13, k
, 18);
402 copyXPMArea(71, 84, 5, 13, k
, 18);
409 /*******************************************************************************\
411 \*******************************************************************************/
413 void DrawDate(int wkday
, int dom
, int month
) {
414 const int date_size
= 16;
415 char date
[date_size
];
421 snprintf(date
, date_size
,
422 "%.2s%02d%.3s ", day_of_week
[wkday
], dom
, mon_of_year
[month
]);
425 for (i
=0; i
<2; i
++) {
427 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
429 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
434 for (i
=0; i
<2; i
++) {
435 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
439 copyXPMArea(61, 64, 4, 9, k
, 49);
441 for (i
=0; i
<3; i
++) {
443 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
445 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
451 /*******************************************************************************\
453 \*******************************************************************************/
455 void DrawWijzer(int hr
, int min
, int sec
) {
468 copyXPMArea(5+64, 5, 54, 40, 5, 5);
470 /**********************************************************************/
471 psi
= hr
* (M_PI
/ 6.0);
472 psi
+= min
* (M_PI
/ 360);
474 dx
= floor(sin(psi
) * 22 * 0.7 + 0.5);
475 dy
= floor(-cos(psi
) * 16 * 0.7 + 0.5);
477 // dx, dy is het punt waar we naar toe moeten.
478 // Zoek alle punten die ECHT op de lijn liggen:
482 if (dx
< 0) ddx
= -1;
483 if (dy
< 0) ddy
= -1;
488 if (abs(dx
) > abs(dy
)) {
493 for (i
=0; i
<abs(dx
); i
++) {
494 // laat de kleur afhangen van de adder.
495 // adder loopt van abs(dx) tot 0
497 k
= 12 - adder
/ (abs(dx
) / 12.0);
498 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
500 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
503 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
519 for (i
=0; i
<abs(dy
); i
++) {
520 k
= 12 - adder
/ (abs(dy
) / 12.0);
521 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
523 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
526 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
537 /**********************************************************************/
538 psi
= min
* (M_PI
/ 30.0);
539 psi
+= sec
* (M_PI
/ 1800);
541 dx
= floor(sin(psi
) * 22 * 0.55 + 0.5);
542 dy
= floor(-cos(psi
) * 16 * 0.55 + 0.5);
544 // dx, dy is het punt waar we naar toe moeten.
545 // Zoek alle punten die ECHT op de lijn liggen:
552 if (dx
< 0) ddx
= -1;
553 if (dy
< 0) ddy
= -1;
558 if (abs(dx
) > abs(dy
)) {
563 for (i
=0; i
<abs(dx
); i
++) {
564 // laat de kleur afhangen van de adder.
565 // adder loopt van abs(dx) tot 0
567 k
= 12 - adder
/ (abs(dx
) / 12.0);
568 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
570 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
573 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
589 for (i
=0; i
<abs(dy
); i
++) {
590 k
= 12 - adder
/ (abs(dy
) / 12.0);
591 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
593 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
596 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
607 /**********************************************************************/
609 return; /* Skip drawing the seconds. */
611 psi
= sec
* (M_PI
/ 30.0);
613 dx
= floor(sin(psi
) * 22 * 0.9 + 0.5);
614 dy
= floor(-cos(psi
) * 16 * 0.9 + 0.5);
616 // dx, dy is het punt waar we naar toe moeten.
617 // Zoek alle punten die ECHT op de lijn liggen:
621 if (dx
< 0) ddx
= -1;
622 if (dy
< 0) ddy
= -1;
624 if (dx
== 0) ddx
= 0;
625 if (dy
== 0) ddy
= 0;
631 if (abs(dx
) > abs(dy
)) {
636 for (i
=0; i
<abs(dx
); i
++) {
637 // laat de kleur afhangen van de adder.
638 // adder loopt van abs(dx) tot 0
640 k
= 12 - adder
/ (abs(dx
) / 12.0);
641 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24 - ddy
);
644 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
660 for (i
=0; i
<abs(dy
); i
++) {
661 k
= 12 - adder
/ (abs(dy
) / 12.0);
662 copyXPMArea(79+k
, 70, 1, 1, x
+ 31 - ddx
, y
+ 24);
665 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
678 /*******************************************************************************\
680 \*******************************************************************************/
682 void usage(char *name
) {
683 printf("Usage: %s [OPTION]...\n", name
);
684 printf("WindowMaker dockapp that displays the time and date.\n");
686 printf(" -d, -digital display the digital clock\n");
687 printf(" -display DISPLAY contact the DISPLAY X server\n");
688 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
689 printf(" -n, -noseconds disables the second hand\n");
690 printf(" -l LOCALE set locale to LOCALE\n");
691 printf(" -h display this help and exit\n");
692 printf(" -v output version information and exit\n");
695 /*******************************************************************************\
697 \*******************************************************************************/
699 void printversion(void) {
700 printf("WMTime version %s\n", WMTIME_VERSION
);
703 /* vim: sw=4 ts=4 columns=82