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
;
234 struct tm old_time_struct
;
240 char *conffile
= NULL
;
242 /* Scan through ~/.wmtimerc for the mouse button actions. */
243 if (default_left_action
) left_action
= strdup(default_left_action
);
244 if (default_middle_action
) middle_action
= strdup(default_middle_action
);
245 if (default_right_action
) right_action
= strdup(default_right_action
);
247 /* Scan through the .rc files */
248 if (asprintf(&conffile
, "/etc/wmtimerc") >= 0) {
249 parse_rcfile(conffile
, wmtime_keys
);
253 if (asprintf(&conffile
, "%s/.wmtimerc", getenv("HOME")) >= 0) {
254 parse_rcfile(conffile
, wmtime_keys
);
258 if (asprintf(&conffile
, "/etc/wmtimerc.fixed") >= 0) {
259 parse_rcfile(conffile
, wmtime_keys
);
263 openXwindow(argc
, argv
, wmtime_master_xpm
, wmtime_mask_bits
, 128, 64);
265 /* Mask out the right parts of the clock */
266 copyXPMArea(0, 0, 128, 64, 0, 98); /* Draw the borders */
267 copyXPMArea(0, 0, 64, 64, 64, 0); /* Draw the clock face */
268 copyXPMArea(64, 98, 64, 64, 0, 0); /* Draw the LCD background */
271 /* add mouse region */
272 AddMouseRegion(0, 5, 48, 58, 60);
273 AddMouseRegion(1, 5, 5, 58, 46);
276 nexttime
= starttime
+ 1;
279 time_struct
= localtime(&curtime
);
284 waitpid(0, NULL
, WNOHANG
);
286 old_time_struct
= *time_struct
;
287 time_struct
= localtime(&curtime
);
290 if (curtime
>= starttime
) {
292 /* Now to update the seconds */
294 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
296 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
300 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
302 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
308 while (XPending(display
)) {
309 XNextEvent(display
, &Event
);
310 switch (Event
.type
) {
315 XCloseDisplay(display
);
319 but_stat
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
322 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
323 if (but_stat
== i
&& but_stat
>= 0) {
329 copyXPMArea(64, 98, 64, 64, 0, 0);
330 DrawTime(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
);
333 copyXPMArea(0, 98, 64, 64, 0, 0);
334 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
335 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
340 switch (Event
.xbutton
.button
) {
343 execCommand(left_action
);
347 execCommand(middle_action
);
351 execCommand(right_action
);
360 /* Sleep 0.3 seconds */
365 /*******************************************************************************\
367 \*******************************************************************************/
369 void DrawTime(int hr
, int min
, int sec
) {
370 const int time_size
= 16;
371 char time
[time_size
];
379 snprintf(time
, time_size
, "%02d:%02d ", hr
, min
);
383 snprintf(time
, time_size
, "%02d:%02d:%02d ", hr
, min
, sec
);
387 for (i
=0; i
< numfields
; i
++) {
388 for (j
=0; j
<2; j
++) {
389 copyXPMArea((*p
-'0')*7 + 1, 84, 8, 13, k
, 18);
394 copyXPMArea(71, 84, 5, 13, k
, 18);
401 /*******************************************************************************\
403 \*******************************************************************************/
405 void DrawDate(int wkday
, int dom
, int month
) {
406 const int date_size
= 16;
407 char date
[date_size
];
413 snprintf(date
, date_size
,
414 "%.2s%02d%.3s ", day_of_week
[wkday
], dom
, mon_of_year
[month
]);
417 for (i
=0; i
<2; i
++) {
419 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
421 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
426 for (i
=0; i
<2; i
++) {
427 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
431 copyXPMArea(61, 64, 4, 9, k
, 49);
433 for (i
=0; i
<3; i
++) {
435 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
437 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
443 /*******************************************************************************\
445 \*******************************************************************************/
447 void DrawWijzer(int hr
, int min
, int sec
) {
460 copyXPMArea(5+64, 5, 54, 40, 5, 5);
462 /**********************************************************************/
463 psi
= hr
* (M_PI
/ 6.0);
464 psi
+= min
* (M_PI
/ 360);
466 dx
= floor(sin(psi
) * 22 * 0.7 + 0.5);
467 dy
= floor(-cos(psi
) * 16 * 0.7 + 0.5);
469 // dx, dy is het punt waar we naar toe moeten.
470 // Zoek alle punten die ECHT op de lijn liggen:
474 if (dx
< 0) ddx
= -1;
475 if (dy
< 0) ddy
= -1;
480 if (abs(dx
) > abs(dy
)) {
485 for (i
=0; i
<abs(dx
); i
++) {
486 // laat de kleur afhangen van de adder.
487 // adder loopt van abs(dx) tot 0
489 k
= 12 - adder
/ (abs(dx
) / 12.0);
490 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
492 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
495 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
511 for (i
=0; i
<abs(dy
); i
++) {
512 k
= 12 - adder
/ (abs(dy
) / 12.0);
513 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
515 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
518 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
529 /**********************************************************************/
530 psi
= min
* (M_PI
/ 30.0);
531 psi
+= sec
* (M_PI
/ 1800);
533 dx
= floor(sin(psi
) * 22 * 0.55 + 0.5);
534 dy
= floor(-cos(psi
) * 16 * 0.55 + 0.5);
536 // dx, dy is het punt waar we naar toe moeten.
537 // Zoek alle punten die ECHT op de lijn liggen:
544 if (dx
< 0) ddx
= -1;
545 if (dy
< 0) ddy
= -1;
550 if (abs(dx
) > abs(dy
)) {
555 for (i
=0; i
<abs(dx
); i
++) {
556 // laat de kleur afhangen van de adder.
557 // adder loopt van abs(dx) tot 0
559 k
= 12 - adder
/ (abs(dx
) / 12.0);
560 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
562 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
565 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
581 for (i
=0; i
<abs(dy
); i
++) {
582 k
= 12 - adder
/ (abs(dy
) / 12.0);
583 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
585 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
588 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
599 /**********************************************************************/
601 return; /* Skip drawing the seconds. */
603 psi
= sec
* (M_PI
/ 30.0);
605 dx
= floor(sin(psi
) * 22 * 0.9 + 0.5);
606 dy
= floor(-cos(psi
) * 16 * 0.9 + 0.5);
608 // dx, dy is het punt waar we naar toe moeten.
609 // Zoek alle punten die ECHT op de lijn liggen:
613 if (dx
< 0) ddx
= -1;
614 if (dy
< 0) ddy
= -1;
616 if (dx
== 0) ddx
= 0;
617 if (dy
== 0) ddy
= 0;
623 if (abs(dx
) > abs(dy
)) {
628 for (i
=0; i
<abs(dx
); i
++) {
629 // laat de kleur afhangen van de adder.
630 // adder loopt van abs(dx) tot 0
632 k
= 12 - adder
/ (abs(dx
) / 12.0);
633 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24 - ddy
);
636 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
652 for (i
=0; i
<abs(dy
); i
++) {
653 k
= 12 - adder
/ (abs(dy
) / 12.0);
654 copyXPMArea(79+k
, 70, 1, 1, x
+ 31 - ddx
, y
+ 24);
657 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
670 /*******************************************************************************\
672 \*******************************************************************************/
674 void usage(char *name
) {
675 printf("Usage: %s [OPTION]...\n", name
);
676 printf("WindowMaker dockapp that displays the time and date.\n");
678 printf(" -d, -digital display the digital clock\n");
679 printf(" -display DISPLAY contact the DISPLAY X server\n");
680 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
681 printf(" -n, -noseconds disables the second hand\n");
682 printf(" -h display this help and exit\n");
683 printf(" -v output version information and exit\n");
686 /*******************************************************************************\
688 \*******************************************************************************/
690 void printversion(void) {
691 printf("WMTime version %s\n", WMMON_VERSION
);
694 /* vim: sw=4 ts=4 columns=82