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.0b2"
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 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 2;
188 day_of_week
[i
][outsize
] = toupper(*outp
);
190 for (i
= 0; i
< 12; i
++) {
191 strncpy(langbuf
, nl_langinfo(ABMON_1
+ i
), 10);
192 insize
= outsize
= 10;
196 ret
= iconv(icd
, &inp
, &insize
, &outp
, &outsize
);
197 } while (outsize
> 0 && ret
> 0);
198 for (outp
= outbuf
, outsize
= 0; *outp
!= 0 && outsize
< 3;
200 mon_of_year
[i
][outsize
] = toupper(*outp
);
206 /*******************************************************************************\
208 \*******************************************************************************/
210 char *left_action
= NULL
;
211 char *right_action
= NULL
;
212 char *middle_action
= NULL
;
214 void DrawTime(int, int, int);
215 void DrawWijzer(int, int, int);
216 void DrawDate(int, int, int);
218 void wmtime_routine(int argc
, char **argv
) {
220 rckeys wmtime_keys
[] = {
221 { "left", &left_action
},
222 { "right", &right_action
},
223 { "middle", &middle_action
},
231 struct tm
*time_struct
;
232 struct tm old_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);
274 nexttime
= starttime
+ 1;
277 time_struct
= localtime(&curtime
);
282 waitpid(0, NULL
, WNOHANG
);
284 old_time_struct
= *time_struct
;
285 time_struct
= localtime(&curtime
);
288 if (curtime
>= starttime
) {
290 /* Now to update the seconds */
292 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
294 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
298 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
300 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
306 while (XPending(display
)) {
307 XNextEvent(display
, &Event
);
308 switch (Event
.type
) {
313 XCloseDisplay(display
);
317 but_stat
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
320 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
321 if (but_stat
== i
&& but_stat
>= 0) {
327 copyXPMArea(64, 98, 64, 64, 0, 0);
328 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
329 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
331 copyXPMArea(0, 98, 64, 64, 0, 0);
332 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
333 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
338 switch (Event
.xbutton
.button
) {
341 execCommand(left_action
);
345 execCommand(middle_action
);
349 execCommand(right_action
);
358 /* Sleep 0.3 seconds */
363 /*******************************************************************************\
365 \*******************************************************************************/
367 void DrawTime(int hr
, int min
, int sec
) {
368 const int time_size
= 16;
369 char time
[time_size
];
377 snprintf(time
, time_size
, "%02d:%02d ", hr
, min
);
381 snprintf(time
, time_size
, "%02d:%02d:%02d ", hr
, min
, sec
);
385 for (i
=0; i
< numfields
; i
++) {
386 for (j
=0; j
<2; j
++) {
387 copyXPMArea((*p
-'0')*7 + 1, 84, 8, 13, k
, 18);
392 copyXPMArea(71, 84, 5, 13, k
, 18);
399 /*******************************************************************************\
401 \*******************************************************************************/
403 void DrawDate(int wkday
, int dom
, int month
) {
404 const int date_size
= 16;
405 char date
[date_size
];
411 snprintf(date
, date_size
,
412 "%.2s%02d%.3s ", day_of_week
[wkday
], dom
, mon_of_year
[month
]);
415 for (i
=0; i
<2; i
++) {
416 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
421 for (i
=0; i
<2; i
++) {
422 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
426 copyXPMArea(61, 64, 4, 9, k
, 49);
428 for (i
=0; i
<3; i
++) {
429 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
435 /*******************************************************************************\
437 \*******************************************************************************/
439 void DrawWijzer(int hr
, int min
, int sec
) {
452 copyXPMArea(5+64, 5, 54, 40, 5, 5);
454 /**********************************************************************/
455 psi
= hr
* (M_PI
/ 6.0);
456 psi
+= min
* (M_PI
/ 360);
458 dx
= floor(sin(psi
) * 22 * 0.7 + 0.5);
459 dy
= floor(-cos(psi
) * 16 * 0.7 + 0.5);
461 // dx, dy is het punt waar we naar toe moeten.
462 // Zoek alle punten die ECHT op de lijn liggen:
466 if (dx
< 0) ddx
= -1;
467 if (dy
< 0) ddy
= -1;
472 if (abs(dx
) > abs(dy
)) {
477 for (i
=0; i
<abs(dx
); i
++) {
478 // laat de kleur afhangen van de adder.
479 // adder loopt van abs(dx) tot 0
481 k
= 12 - adder
/ (abs(dx
) / 12.0);
482 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
484 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
487 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
503 for (i
=0; i
<abs(dy
); i
++) {
504 k
= 12 - adder
/ (abs(dy
) / 12.0);
505 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
507 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
510 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
521 /**********************************************************************/
522 psi
= min
* (M_PI
/ 30.0);
523 psi
+= sec
* (M_PI
/ 1800);
525 dx
= floor(sin(psi
) * 22 * 0.55 + 0.5);
526 dy
= floor(-cos(psi
) * 16 * 0.55 + 0.5);
528 // dx, dy is het punt waar we naar toe moeten.
529 // Zoek alle punten die ECHT op de lijn liggen:
536 if (dx
< 0) ddx
= -1;
537 if (dy
< 0) ddy
= -1;
542 if (abs(dx
) > abs(dy
)) {
547 for (i
=0; i
<abs(dx
); i
++) {
548 // laat de kleur afhangen van de adder.
549 // adder loopt van abs(dx) tot 0
551 k
= 12 - adder
/ (abs(dx
) / 12.0);
552 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
554 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
557 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
573 for (i
=0; i
<abs(dy
); i
++) {
574 k
= 12 - adder
/ (abs(dy
) / 12.0);
575 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
577 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
580 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
591 /**********************************************************************/
593 return; /* Skip drawing the seconds. */
595 psi
= sec
* (M_PI
/ 30.0);
597 dx
= floor(sin(psi
) * 22 * 0.9 + 0.5);
598 dy
= floor(-cos(psi
) * 16 * 0.9 + 0.5);
600 // dx, dy is het punt waar we naar toe moeten.
601 // Zoek alle punten die ECHT op de lijn liggen:
605 if (dx
< 0) ddx
= -1;
606 if (dy
< 0) ddy
= -1;
608 if (dx
== 0) ddx
= 0;
609 if (dy
== 0) ddy
= 0;
615 if (abs(dx
) > abs(dy
)) {
620 for (i
=0; i
<abs(dx
); i
++) {
621 // laat de kleur afhangen van de adder.
622 // adder loopt van abs(dx) tot 0
624 k
= 12 - adder
/ (abs(dx
) / 12.0);
625 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24 - ddy
);
628 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
644 for (i
=0; i
<abs(dy
); i
++) {
645 k
= 12 - adder
/ (abs(dy
) / 12.0);
646 copyXPMArea(79+k
, 70, 1, 1, x
+ 31 - ddx
, y
+ 24);
649 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
662 /*******************************************************************************\
664 \*******************************************************************************/
666 void usage(char *name
) {
667 printf("Usage: %s [OPTION]...\n", name
);
668 printf("WindowMaker dockapp that displays the time and date.\n");
670 printf(" -d, -digital display the digital clock\n");
671 printf(" -display DISPLAY contact the DISPLAY X server\n");
672 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
673 printf(" -n, -noseconds disables the second hand\n");
674 printf(" -h display this help and exit\n");
675 printf(" -v output version information and exit\n");
678 /*******************************************************************************\
680 \*******************************************************************************/
682 void printversion(void) {
683 printf("WMTime version %s\n", WMMON_VERSION
);
686 /* vim: sw=4 ts=4 columns=82