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.
70 #include <sys/param.h>
71 #include <sys/types.h>
75 #include <X11/extensions/shape.h>
77 #include "../wmgeneral/wmgeneral.h"
78 #include "../wmgeneral/misc.h"
80 #include "wmtime-master.xpm"
81 #include "wmtime-mask.xbm"
87 const char* default_left_action
= NULL
;
88 const char* default_middle_action
= NULL
;
89 const char* default_right_action
= NULL
;
91 #define WMMON_VERSION "1.0b2"
93 /********************/
94 /* Global Variables */
95 /********************/
99 char day_of_week
[7][3] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
100 char mon_of_year
[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
104 void printversion(void);
106 void wmtime_routine(int, char **);
109 int main(int argc
, char *argv
[]) {
112 char *name
= argv
[0];
114 for (i
=1; i
<argc
; i
++) {
120 if (strcmp(arg
+1, "display")
121 && strcmp(arg
+1, "digital") && strcmp(arg
+1, "d")) {
125 if (!strcmp(arg
+1, "digital") || !(strcmp(arg
+1, "d")))
129 if (strcmp(arg
+1, "geometry")) {
135 if (strcmp(arg
+1, "noseconds") && strcmp(arg
+1, "n")) {
152 wmtime_routine(argc
, argv
);
162 const int line_size
= 5;
163 char line
[line_size
];
165 fp
=fopen("language","r");
167 /* Grab the days of the week */
169 fgets(line
, line_size
, fp
);
170 strncpy(day_of_week
[i
], line
, 2);
172 /* Grab the names of the months */
174 fgets(line
, line_size
, fp
);
175 strncpy(mon_of_year
[i
], line
, 3);
181 /*******************************************************************************\
183 \*******************************************************************************/
185 char *left_action
= NULL
;
186 char *right_action
= NULL
;
187 char *middle_action
= NULL
;
189 void DrawTime(int, int, int);
190 void DrawWijzer(int, int, int);
191 void DrawDate(int, int, int);
193 void wmtime_routine(int argc
, char **argv
) {
195 rckeys wmtime_keys
[] = {
196 { "left", &left_action
},
197 { "right", &right_action
},
198 { "middle", &middle_action
},
206 struct tm
*time_struct
;
207 struct tm old_time_struct
;
213 char *conffile
= NULL
;
215 /* Scan through ~/.wmtimerc for the mouse button actions. */
216 if (default_left_action
) left_action
= strdup(default_left_action
);
217 if (default_middle_action
) middle_action
= strdup(default_middle_action
);
218 if (default_right_action
) right_action
= strdup(default_right_action
);
220 /* Scan through the .rc files */
221 if (asprintf(&conffile
, "/etc/wmtimerc") >= 0) {
222 parse_rcfile(conffile
, wmtime_keys
);
226 if (asprintf(&conffile
, "%s/.wmtimerc", getenv("HOME")) >= 0) {
227 parse_rcfile(conffile
, wmtime_keys
);
231 if (asprintf(&conffile
, "/etc/wmtimerc.fixed") >= 0) {
232 parse_rcfile(conffile
, wmtime_keys
);
236 openXwindow(argc
, argv
, wmtime_master_xpm
, wmtime_mask_bits
, 128, 64);
238 /* Mask out the right parts of the clock */
239 copyXPMArea(0, 0, 128, 64, 0, 98); /* Draw the borders */
240 copyXPMArea(0, 0, 64, 64, 64, 0); /* Draw the clock face */
241 copyXPMArea(64, 98, 64, 64, 0, 0); /* Draw the LCD background */
244 /* add mouse region */
245 AddMouseRegion(0, 5, 48, 58, 60);
246 AddMouseRegion(1, 5, 5, 58, 46);
249 nexttime
= starttime
+ 1;
252 time_struct
= localtime(&curtime
);
257 waitpid(0, NULL
, WNOHANG
);
259 old_time_struct
= *time_struct
;
260 time_struct
= localtime(&curtime
);
263 if (curtime
>= starttime
) {
265 /* Now to update the seconds */
267 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
269 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
273 DrawTime(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
275 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
281 while (XPending(display
)) {
282 XNextEvent(display
, &Event
);
283 switch (Event
.type
) {
288 XCloseDisplay(display
);
292 but_stat
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
295 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
296 if (but_stat
== i
&& but_stat
>= 0) {
302 copyXPMArea(64, 98, 64, 64, 0, 0);
303 DrawTime(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
);
306 copyXPMArea(0, 98, 64, 64, 0, 0);
307 DrawWijzer(time_struct
->tm_hour
, time_struct
->tm_min
, time_struct
->tm_sec
);
308 DrawDate(time_struct
->tm_wday
, time_struct
->tm_mday
, time_struct
->tm_mon
);
313 switch (Event
.xbutton
.button
) {
316 execCommand(left_action
);
320 execCommand(middle_action
);
324 execCommand(right_action
);
333 /* Sleep 0.3 seconds */
338 /*******************************************************************************\
340 \*******************************************************************************/
342 void DrawTime(int hr
, int min
, int sec
) {
343 const int time_size
= 16;
344 char time
[time_size
];
351 snprintf(time
, time_size
, "%02d:%02d ", hr
, min
);
354 snprintf(time
, time_size
, "%02d:%02d:%02d ", hr
, min
, sec
);
357 for (i
=0; i
< 3; i
++) {
358 for (j
=0; j
<2; j
++) {
359 copyXPMArea((*p
-'0')*7 + 1, 84, 8, 13, k
, 18);
364 copyXPMArea(71, 84, 5, 13, k
, 18);
371 /*******************************************************************************\
373 \*******************************************************************************/
375 void DrawDate(int wkday
, int dom
, int month
) {
376 const int date_size
= 16;
377 char date
[date_size
];
383 snprintf(date
, date_size
,
384 "%.2s%02d%.3s ", day_of_week
[wkday
], dom
, mon_of_year
[month
]);
387 for (i
=0; i
<2; i
++) {
388 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
393 for (i
=0; i
<2; i
++) {
394 copyXPMArea((*p
-'0')*6, 64, 6, 9, k
, 49);
398 copyXPMArea(61, 64, 4, 9, k
, 49);
400 for (i
=0; i
<3; i
++) {
401 copyXPMArea((*p
-'A')*6, 74, 6, 9, k
, 49);
407 /*******************************************************************************\
409 \*******************************************************************************/
411 void DrawWijzer(int hr
, int min
, int sec
) {
424 copyXPMArea(5+64, 5, 54, 40, 5, 5);
426 /**********************************************************************/
427 psi
= hr
* (M_PI
/ 6.0);
428 psi
+= min
* (M_PI
/ 360);
430 dx
= floor(sin(psi
) * 22 * 0.7 + 0.5);
431 dy
= floor(-cos(psi
) * 16 * 0.7 + 0.5);
433 // dx, dy is het punt waar we naar toe moeten.
434 // Zoek alle punten die ECHT op de lijn liggen:
438 if (dx
< 0) ddx
= -1;
439 if (dy
< 0) ddy
= -1;
444 if (abs(dx
) > abs(dy
)) {
449 for (i
=0; i
<abs(dx
); i
++) {
450 // laat de kleur afhangen van de adder.
451 // adder loopt van abs(dx) tot 0
453 k
= 12 - adder
/ (abs(dx
) / 12.0);
454 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
456 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
459 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
475 for (i
=0; i
<abs(dy
); i
++) {
476 k
= 12 - adder
/ (abs(dy
) / 12.0);
477 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
479 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
482 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
493 /**********************************************************************/
494 psi
= min
* (M_PI
/ 30.0);
495 psi
+= sec
* (M_PI
/ 1800);
497 dx
= floor(sin(psi
) * 22 * 0.55 + 0.5);
498 dy
= floor(-cos(psi
) * 16 * 0.55 + 0.5);
500 // dx, dy is het punt waar we naar toe moeten.
501 // Zoek alle punten die ECHT op de lijn liggen:
508 if (dx
< 0) ddx
= -1;
509 if (dy
< 0) ddy
= -1;
514 if (abs(dx
) > abs(dy
)) {
519 for (i
=0; i
<abs(dx
); i
++) {
520 // laat de kleur afhangen van de adder.
521 // adder loopt van abs(dx) tot 0
523 k
= 12 - adder
/ (abs(dx
) / 12.0);
524 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 - ddy
);
526 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
529 copyXPMArea(79+k
, 67, 1, 1, x
+ 31, y
+ 24 + ddy
);
545 for (i
=0; i
<abs(dy
); i
++) {
546 k
= 12 - adder
/ (abs(dy
) / 12.0);
547 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 - ddx
, y
+ 24);
549 copyXPMArea(79, 67, 1, 1, x
+ 31, y
+ 24);
552 copyXPMArea(79+k
, 67, 1, 1, x
+ 31 + ddx
, y
+ 24);
563 /**********************************************************************/
565 return; /* Skip drawing the seconds. */
567 psi
= sec
* (M_PI
/ 30.0);
569 dx
= floor(sin(psi
) * 22 * 0.9 + 0.5);
570 dy
= floor(-cos(psi
) * 16 * 0.9 + 0.5);
572 // dx, dy is het punt waar we naar toe moeten.
573 // Zoek alle punten die ECHT op de lijn liggen:
577 if (dx
< 0) ddx
= -1;
578 if (dy
< 0) ddy
= -1;
580 if (dx
== 0) ddx
= 0;
581 if (dy
== 0) ddy
= 0;
587 if (abs(dx
) > abs(dy
)) {
592 for (i
=0; i
<abs(dx
); i
++) {
593 // laat de kleur afhangen van de adder.
594 // adder loopt van abs(dx) tot 0
596 k
= 12 - adder
/ (abs(dx
) / 12.0);
597 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24 - ddy
);
600 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
616 for (i
=0; i
<abs(dy
); i
++) {
617 k
= 12 - adder
/ (abs(dy
) / 12.0);
618 copyXPMArea(79+k
, 70, 1, 1, x
+ 31 - ddx
, y
+ 24);
621 copyXPMArea(79+k
, 70, 1, 1, x
+ 31, y
+ 24);
634 /*******************************************************************************\
636 \*******************************************************************************/
638 void usage(char *name
) {
639 printf("Usage: %s [OPTION]...\n", name
);
640 printf("WindowMaker dockapp that displays the time and date.\n");
642 printf(" -d, -digital display the digital clock\n");
643 printf(" -display DISPLAY contact the DISPLAY X server\n");
644 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
645 printf(" -n, -noseconds disables the second hand\n");
646 printf(" -h display this help and exit\n");
647 printf(" -v output version information and exit\n");
650 /*******************************************************************************\
652 \*******************************************************************************/
654 void printversion(void) {
655 printf("WMTime version %s\n", WMMON_VERSION
);
658 /* vim: sw=4 ts=4 columns=82