wmclockmon: update change-log
[dockapps.git] / wmtime / wmtime.c
blob70f7cad1ed9ec98cb806d01d7c5bd6744e30436a
1 /* wmtime - Window Maker dockapp that displays the time and date
2 Copyright (C) 1997, 1998 Martijn Pieterse <pieterse@xs4all.nl>
3 Copyright (C) 1997, 1998 Antoine Nulle <warp@xs4all.nl>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 Code based on wmppp/wmifs
20 [Orig WMMON comments]
22 This code was mainly put together by looking at the
23 following programs:
25 asclock
26 A neat piece of equip, used to display the date
27 and time on the screen.
28 Comes with every AfterStep installation.
30 Source used:
31 How do I create a not so solid window?
32 How do I open a window?
33 How do I use pixmaps?
35 ------------------------------------------------------------
37 Author: Martijn Pieterse (pieterse@xs4all.nl)
39 This program is distributed under the GPL license.
40 (as were asclock and pppstats)
42 ----
43 Changes:
44 ----
45 15/07/2008 (Paul Harris, harris.pc@gmail.com)
46 * Minor changes to correct build warnings
47 09/10/2003 (Simon Law, sfllaw@debian.org)
48 * Add -geometry support
49 * Add -noseconds support
50 * Make the digital clock fill the space provided
51 * Eliminated exploitable static buffers
52 17/05/1998 (Antoine Nulle, warp@xs4all.nl)
53 * Updated version number and some other minor stuff
54 16/05/1998 (Antoine Nulle, warp@xs4all.nl)
55 * Added Locale support, based on original diff supplied
56 by Alen Salamun (snowman@hal9000.medinet.si)
57 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
58 * Moved the hands one pixel down.
59 * Removed the RedrawWindow out of the main loop
60 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
61 * Removed a lot of code that was in the wmgeneral dir.
62 02/05/1998 (Antoine Nulle, warp@xs4all.nl)
63 * Updated master-xpm, hour dots where a bit 'off'
64 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
65 * Added anti-aliased hands
66 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
67 * Changed the hand lengths.. again! ;)
68 * Zombies were created, so added wait code
69 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
70 * Added digital/analog switching support
71 18/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
72 * Started this project.
73 * Copied the source from wmmon.
76 #define _GNU_SOURCE
77 #include <X11/X.h> /* for ButtonPress, ButtonRelease, etc */
78 #include <X11/Xlib.h> /* for XEvent, XButtonEvent, etc */
79 #include <X11/xpm.h>
80 #include <ctype.h> /* for toupper */
81 #include <iconv.h> /* for iconv, iconv_close, etc */
82 #include <langinfo.h> /* for nl_langinfo, ABDAY_1, etc */
83 #include <locale.h> /* for NULL, setlocale, LC_ALL */
84 #include <math.h> /* for floor, cos, sin, M_PI */
85 #include <stddef.h> /* for size_t */
86 #include <stdio.h> /* for printf, asprintf, snprintf, etc */
87 #include <stdlib.h> /* for abs, free, exit, getenv */
88 #include <string.h> /* for strcmp, strdup, strncpy, etc */
89 #include <sys/wait.h> /* for waitpid, WNOHANG */
90 #include <time.h> /* for tm, time, localtime */
91 #include <unistd.h> /* for usleep */
92 #include "libdockapp/misc.h" /* for execCommand */
93 #include "libdockapp/wmgeneral.h" /* for copyXPMArea, RedrawWindow, etc */
94 #include "wmtime-mask.xbm" /* for wmtime_mask_bits */
95 #include "wmtime-master.xpm" /* for wmtime_master_xpm */
98 /***********/
99 /* Defines */
100 /***********/
102 const char* default_left_action = NULL;
103 const char* default_middle_action = NULL;
104 const char* default_right_action = NULL;
106 #define WMTIME_VERSION "1.4"
108 /********************/
109 /* Global Variables */
110 /********************/
112 int digital = 0;
113 int noseconds = 0;
114 char day_of_week[7][3] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" };
115 char mon_of_year[12][4] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
116 XpmIcon wmgen;
117 char color[256];
119 /* functions */
120 void usage(char *);
121 void printversion(void);
123 void wmtime_routine(int, char **);
124 void get_lang();
127 int main(int argc, char *argv[]) {
129 int i;
130 char *name = argv[0];
131 char locale[256];
133 locale[0] = 0;
134 color[0] = 0;
136 for (i=1; i<argc; i++) {
137 char *arg = argv[i];
139 if (*arg=='-') {
140 switch (arg[1]) {
141 case 'c' :
142 if (argc > i+1) {
143 strcpy(color, argv[i+1]);
144 i++;
146 break;
147 case 'd' :
148 if (strcmp(arg+1, "display")
149 && strcmp(arg+1, "digital") && strcmp(arg+1, "d")) {
150 usage(name);
151 return 1;
153 if (!strcmp(arg+1, "digital") || !(strcmp(arg+1, "d")))
154 digital = 1;
155 break;
156 case 'g' :
157 if (strcmp(arg+1, "geometry")) {
158 usage(name);
159 return 1;
161 break;
162 case 'n' :
163 if (strcmp(arg+1, "noseconds") && strcmp(arg+1, "n")) {
164 usage(name);
165 return 1;
166 } else {
167 noseconds = 1;
169 break;
170 case 'v' :
171 printversion();
172 return 0;
173 case 'l':
174 if (argc > i+1) {
175 strcpy(locale, argv[i+1]);
176 i++;
178 break;
179 default:
180 usage(name);
181 return 1;
186 if (setlocale(LC_ALL, locale) == NULL)
187 fprintf(stderr,
188 "warning: locale '%s' not recognized; defaulting to '%s'.",
189 locale, setlocale(LC_ALL, NULL));
190 get_lang();
192 wmtime_routine(argc, argv);
193 return 0;
196 /************/
197 /* get_lang */
198 /************/
199 void get_lang(void)
201 char langbuf[10], outbuf[10];
202 char *inp, *outp;
203 iconv_t icd;
204 int i, ret;
205 size_t insize, outsize;
207 icd = iconv_open("ASCII//TRANSLIT", nl_langinfo(CODESET));
208 if (icd == (iconv_t) -1) {
209 perror("wmtime: Error allocating charset conversion descriptor");
210 return;
213 for (i = 0; i < 7; i++) {
214 strncpy(langbuf, nl_langinfo(ABDAY_1 + i), 10);
215 insize = outsize = 10;
216 inp = langbuf;
217 outp = outbuf;
218 do {
219 ret = iconv(icd, &inp, &insize, &outp, &outsize);
220 } while (outsize > 0 && ret > 0);
221 if (strstr(outbuf,"?") != NULL) return;
222 for (outp = outbuf, outsize = 0; *outp != 0 && outsize < 2;
223 outp++, outsize++)
224 day_of_week[i][outsize] = toupper(*outp);
226 for (i = 0; i < 12; i++) {
227 strncpy(langbuf, nl_langinfo(ABMON_1 + i), 10);
228 insize = outsize = 10;
229 inp = langbuf;
230 outp = outbuf;
231 do {
232 ret = iconv(icd, &inp, &insize, &outp, &outsize);
233 } while (outsize > 0 && ret > 0);
234 if (strstr(outbuf,"?") != NULL) return;
235 for (outp = outbuf, outsize = 0; *outp != 0 && outsize < 3;
236 outp++, outsize++)
237 mon_of_year[i][outsize] = toupper(*outp);
240 iconv_close(icd);
243 Pixel scale_pixel(Pixel pixel, float scale)
245 int red, green, blue;
247 red = pixel / ( 1 << 16 );
248 green = pixel % (1 << 16) / (1 << 8);
249 blue = pixel % (1 << 8);
251 red *= scale;
252 green *= scale;
253 blue *= scale;
255 return red * (1 << 16) + green * (1 << 8) + blue;
258 /*******************************************************************************\
259 |* wmtime_routine *|
260 \*******************************************************************************/
262 char *left_action = NULL;
263 char *right_action = NULL;
264 char *middle_action = NULL;
266 void DrawTime(int, int, int);
267 void DrawWijzer(int, int, int);
268 void DrawDate(int, int, int);
270 void wmtime_routine(int argc, char **argv) {
272 rckeys wmtime_keys[] = {
273 { "left", &left_action },
274 { "right", &right_action },
275 { "middle", &middle_action },
276 { NULL, NULL }
279 int i;
280 XEvent Event;
281 int but_stat = -1;
283 struct tm *time_struct;
285 long starttime;
286 long curtime;
288 char *conffile = NULL;
290 /* Scan through ~/.wmtimerc for the mouse button actions. */
291 if (default_left_action) left_action = strdup(default_left_action);
292 if (default_middle_action) middle_action = strdup(default_middle_action);
293 if (default_right_action) right_action = strdup(default_right_action);
295 /* Scan through the .rc files */
296 if (asprintf(&conffile, "/etc/wmtimerc") >= 0) {
297 parse_rcfile(conffile, wmtime_keys);
298 free(conffile);
301 if (asprintf(&conffile, "%s/.wmtimerc", getenv("HOME")) >= 0) {
302 parse_rcfile(conffile, wmtime_keys);
303 free(conffile);
306 if (asprintf(&conffile, "/etc/wmtimerc.fixed") >= 0) {
307 parse_rcfile(conffile, wmtime_keys);
308 free(conffile);
311 /* set user-defined colors */
312 if (color[0] != 0) {
313 Window Root;
314 XColor col;
315 XWindowAttributes attributes;
316 int screen;
317 Pixel pixel;
318 #define NUMSYMBOLS 10
319 XpmColorSymbol user_color[NUMSYMBOLS] = {
320 {NULL, "#2081B2CAAEBA", 0}, /* O */
321 {NULL, "#000049244103", 0}, /* + */
322 {NULL, "#00007DF771C6", 0}, /* @ */
323 {NULL, "#18618A288617", 0}, /* # */
324 {NULL, "#18619A699658", 0}, /* ; */
325 {NULL, "#0820861779E7", 0}, /* : */
326 {NULL, "#000071C66185", 0}, /* > */
327 {NULL, "#000061855144", 0}, /* , */
328 {NULL, "#00004D344103", 0}, /* < */
329 {NULL, "#10407DF779E7", 0} /* 1 */
333 /* code based on GetColor() from wmgeneral.c */
334 /* we need a temporary display to parse the color */
335 display = XOpenDisplay(NULL);
336 screen = DefaultScreen(display);
337 Root = RootWindow(display, screen);
338 XGetWindowAttributes(display, Root, &attributes);
340 col.pixel = 0;
341 if (!XParseColor(display, attributes.colormap, color, &col)) {
342 fprintf(stderr, "wmtime: can't parse %s.\n", color);
343 goto draw_window;
344 } else if (!XAllocColor(display, attributes.colormap, &col)) {
345 fprintf(stderr, "wmtime: can't allocate %s.\n", color);
346 goto draw_window;
349 pixel = col.pixel;
351 /* replace colors from wmtime-master.xpm */
352 user_color[0].pixel = pixel;
353 user_color[1].pixel = scale_pixel(pixel, .4);
354 user_color[2].pixel = scale_pixel(pixel, .7);
355 user_color[3].pixel = scale_pixel(pixel, .8);
356 user_color[4].pixel = scale_pixel(pixel, .9);
357 user_color[5].pixel = scale_pixel(pixel, .8);
358 user_color[6].pixel = scale_pixel(pixel, .6);
359 user_color[7].pixel = scale_pixel(pixel, .5);
360 user_color[8].pixel = scale_pixel(pixel, .4);
361 user_color[9].pixel = scale_pixel(pixel, .7);
363 wmgen.attributes.valuemask |= XpmColorSymbols;
364 wmgen.attributes.numsymbols = NUMSYMBOLS;
365 wmgen.attributes.colorsymbols = user_color;
367 XCloseDisplay(display);
370 draw_window:
371 openXwindow(argc, argv, wmtime_master_xpm, (char*)wmtime_mask_bits, 128, 64);
373 /* Mask out the right parts of the clock */
374 copyXPMArea(0, 0, 128, 64, 0, 98); /* Draw the borders */
375 copyXPMArea(0, 0, 64, 64, 64, 0); /* Draw the clock face */
376 copyXPMArea(64, 98, 64, 64, 0, 0); /* Draw the LCD background */
377 setMaskXY(0, 0);
379 /* add mouse region */
380 AddMouseRegion(0, 5, 48, 58, 60);
381 AddMouseRegion(1, 5, 5, 58, 46);
383 starttime = time(0);
385 curtime = time(0);
386 time_struct = localtime(&curtime);
388 while (1) {
389 curtime = time(0);
391 waitpid(0, NULL, WNOHANG);
393 time_struct = localtime(&curtime);
396 if (curtime >= starttime) {
397 if (!digital) {
398 /* Now to update the seconds */
400 DrawWijzer(time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
402 DrawDate(time_struct->tm_wday, time_struct->tm_mday, time_struct->tm_mon);
404 } else {
406 DrawTime(time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
408 DrawDate(time_struct->tm_wday, time_struct->tm_mday, time_struct->tm_mon);
410 RedrawWindow();
414 while (XPending(display)) {
415 XNextEvent(display, &Event);
416 switch (Event.type) {
417 case Expose:
418 RedrawWindow();
419 break;
420 case DestroyNotify:
421 XCloseDisplay(display);
422 exit(0);
423 break;
424 case ButtonPress:
425 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
426 break;
427 case ButtonRelease:
428 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
429 if (but_stat == i && but_stat >= 0) {
430 switch (but_stat) {
431 case 0:
432 digital = 1-digital;
434 if (digital) {
435 copyXPMArea(64, 98, 64, 64, 0, 0);
436 DrawTime(time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
437 DrawDate(time_struct->tm_wday, time_struct->tm_mday, time_struct->tm_mon);
438 } else {
439 copyXPMArea(0, 98, 64, 64, 0, 0);
440 DrawWijzer(time_struct->tm_hour, time_struct->tm_min, time_struct->tm_sec);
441 DrawDate(time_struct->tm_wday, time_struct->tm_mday, time_struct->tm_mon);
443 RedrawWindow();
444 break;
445 case 1:
446 switch (Event.xbutton.button) {
447 case 1:
448 if (left_action)
449 execCommand(left_action);
450 break;
451 case 2:
452 if (middle_action)
453 execCommand(middle_action);
454 break;
455 case 3:
456 if (right_action)
457 execCommand(right_action);
458 break;
462 break;
466 /* Sleep 0.3 seconds */
467 usleep(300000L);
471 /*******************************************************************************\
472 |* DrawTime *|
473 \*******************************************************************************/
475 void DrawTime(int hr, int min, int sec) {
476 #define TIME_SIZE 16
477 char time[TIME_SIZE];
478 char *p = time;
479 int i,j,k=6;
480 int numfields;
482 /* 7x13 */
484 if (noseconds) {
485 snprintf(time, TIME_SIZE, "%02d:%02d ", hr, min);
486 numfields = 2;
488 else {
489 snprintf(time, TIME_SIZE, "%02d:%02d:%02d ", hr, min, sec);
490 numfields = 3;
493 for (i=0; i < numfields; i++) {
494 for (j=0; j<2; j++) {
495 copyXPMArea((*p-'0')*7 + 1, 84, 8, 13, k, 18);
496 k += 7;
497 p++;
499 if (*p == ':') {
500 copyXPMArea(71, 84, 5, 13, k, 18);
501 k += 4;
502 p++;
507 /*******************************************************************************\
508 |* DrawDate *|
509 \*******************************************************************************/
511 void DrawDate(int wkday, int dom, int month) {
512 #define DATE_SIZE 16
513 char date[DATE_SIZE];
514 char *p = date;
515 int i,k;
517 /* 7x13 */
519 snprintf(date, DATE_SIZE,
520 "%.2s%02d%.3s ", day_of_week[wkday], dom, mon_of_year[month]);
522 k = 5;
523 for (i=0; i<2; i++) {
524 if (*p < 'A')
525 copyXPMArea((*p-'0')*6, 64, 6, 9, k, 49);
526 else
527 copyXPMArea((*p-'A')*6, 74, 6, 9, k, 49);
528 k += 6;
529 p++;
531 k = 23;
532 for (i=0; i<2; i++) {
533 copyXPMArea((*p-'0')*6, 64, 6, 9, k, 49);
534 k += 6;
535 p++;
537 copyXPMArea(61, 64, 4, 9, k, 49);
538 k += 4;
539 for (i=0; i<3; i++) {
540 if (*p < 'A')
541 copyXPMArea((*p-'0')*6, 64, 6, 9, k, 49);
542 else
543 copyXPMArea((*p-'A')*6, 74, 6, 9, k, 49);
544 k += 6;
545 p++;
549 /*******************************************************************************\
550 |* DrawWijzer *|
551 \*******************************************************************************/
553 void DrawWijzer(int hr, int min, int sec) {
555 double psi;
556 int dx,dy;
557 int x,y;
558 int ddx,ddy;
559 int adder;
560 int k;
562 int i;
564 hr %= 12;
566 copyXPMArea(5+64, 5, 54, 40, 5, 5);
568 /**********************************************************************/
569 psi = hr * (M_PI / 6.0);
570 psi += min * (M_PI / 360);
572 dx = floor(sin(psi) * 22 * 0.7 + 0.5);
573 dy = floor(-cos(psi) * 16 * 0.7 + 0.5);
575 /* dx, dy is het punt waar we naar toe moeten.
576 * Zoek alle punten die ECHT op de lijn liggen: */
578 ddx = 1;
579 ddy = 1;
580 if (dx < 0) ddx = -1;
581 if (dy < 0) ddy = -1;
583 x = 0;
584 y = 0;
586 if (abs(dx) > abs(dy)) {
587 if (dy != 0)
588 adder = abs(dx) / 2;
589 else
590 adder = 0;
591 for (i=0; i<abs(dx); i++) {
592 /* laat de kleur afhangen van de adder.
593 * adder loopt van abs(dx) tot 0 */
595 k = 12 - adder / (abs(dx) / 12.0);
596 copyXPMArea(79+k, 67, 1, 1, x + 31, y + 24 - ddy);
598 copyXPMArea(79, 67, 1, 1, x + 31, y + 24);
600 k = 12-k;
601 copyXPMArea(79+k, 67, 1, 1, x + 31, y + 24 + ddy);
604 x += ddx;
606 adder -= abs(dy);
607 if (adder < 0) {
608 adder += abs(dx);
609 y += ddy;
612 } else {
613 if (dx != 0)
614 adder = abs(dy) / 2;
615 else
616 adder = 0;
617 for (i=0; i<abs(dy); i++) {
618 k = 12 - adder / (abs(dy) / 12.0);
619 copyXPMArea(79+k, 67, 1, 1, x + 31 - ddx, y + 24);
621 copyXPMArea(79, 67, 1, 1, x + 31, y + 24);
623 k = 12-k;
624 copyXPMArea(79+k, 67, 1, 1, x + 31 + ddx, y + 24);
626 y += ddy;
628 adder -= abs(dx);
629 if (adder < 0) {
630 adder += abs(dy);
631 x += ddx;
635 /**********************************************************************/
636 psi = min * (M_PI / 30.0);
637 psi += sec * (M_PI / 1800);
639 dx = floor(sin(psi) * 22 * 0.55 + 0.5);
640 dy = floor(-cos(psi) * 16 * 0.55 + 0.5);
642 /* dx, dy is het punt waar we naar toe moeten.
643 * Zoek alle punten die ECHT op de lijn liggen: */
645 dx += dx;
646 dy += dy;
648 ddx = 1;
649 ddy = 1;
650 if (dx < 0) ddx = -1;
651 if (dy < 0) ddy = -1;
653 x = 0;
654 y = 0;
656 if (abs(dx) > abs(dy)) {
657 if (dy != 0)
658 adder = abs(dx) / 2;
659 else
660 adder = 0;
661 for (i=0; i<abs(dx); i++) {
662 /* laat de kleur afhangen van de adder.
663 * adder loopt van abs(dx) tot 0 */
665 k = 12 - adder / (abs(dx) / 12.0);
666 copyXPMArea(79+k, 67, 1, 1, x + 31, y + 24 - ddy);
668 copyXPMArea(79, 67, 1, 1, x + 31, y + 24);
670 k = 12-k;
671 copyXPMArea(79+k, 67, 1, 1, x + 31, y + 24 + ddy);
674 x += ddx;
676 adder -= abs(dy);
677 if (adder < 0) {
678 adder += abs(dx);
679 y += ddy;
682 } else {
683 if (dx != 0)
684 adder = abs(dy) / 2;
685 else
686 adder = 0;
687 for (i=0; i<abs(dy); i++) {
688 k = 12 - adder / (abs(dy) / 12.0);
689 copyXPMArea(79+k, 67, 1, 1, x + 31 - ddx, y + 24);
691 copyXPMArea(79, 67, 1, 1, x + 31, y + 24);
693 k = 12-k;
694 copyXPMArea(79+k, 67, 1, 1, x + 31 + ddx, y + 24);
696 y += ddy;
698 adder -= abs(dx);
699 if (adder < 0) {
700 adder += abs(dy);
701 x += ddx;
705 /**********************************************************************/
706 if (noseconds)
707 return; /* Skip drawing the seconds. */
709 psi = sec * (M_PI / 30.0);
711 dx = floor(sin(psi) * 22 * 0.9 + 0.5);
712 dy = floor(-cos(psi) * 16 * 0.9 + 0.5);
714 /* dx, dy is het punt waar we naar toe moeten.
715 * Zoek alle punten die ECHT op de lijn liggen: */
717 ddx = 1;
718 ddy = 1;
719 if (dx < 0) ddx = -1;
720 if (dy < 0) ddy = -1;
722 if (dx == 0) ddx = 0;
723 if (dy == 0) ddy = 0;
725 x = 0;
726 y = 0;
729 if (abs(dx) > abs(dy)) {
730 if (dy != 0)
731 adder = abs(dx) / 2;
732 else
733 adder = 0;
734 for (i=0; i<abs(dx); i++) {
735 /* laat de kleur afhangen van de adder.
736 * adder loopt van abs(dx) tot 0 */
738 k = 12 - adder / (abs(dx) / 12.0);
739 copyXPMArea(79+k, 70, 1, 1, x + 31, y + 24 - ddy);
741 k = 12-k;
742 copyXPMArea(79+k, 70, 1, 1, x + 31, y + 24);
745 x += ddx;
747 adder -= abs(dy);
748 if (adder < 0) {
749 adder += abs(dx);
750 y += ddy;
753 } else {
754 if (dx != 0)
755 adder = abs(dy) / 2;
756 else
757 adder = 0;
758 for (i=0; i<abs(dy); i++) {
759 k = 12 - adder / (abs(dy) / 12.0);
760 copyXPMArea(79+k, 70, 1, 1, x + 31 - ddx, y + 24);
762 k = 12-k;
763 copyXPMArea(79+k, 70, 1, 1, x + 31, y + 24);
765 y += ddy;
767 adder -= abs(dx);
768 if (adder < 0) {
769 adder += abs(dy);
770 x += ddx;
776 /*******************************************************************************\
777 |* usage *|
778 \*******************************************************************************/
780 void usage(char *name) {
781 printf("Usage: %s [OPTION]...\n", name);
782 printf("WindowMaker dockapp that displays the time and date.\n");
783 printf("\n");
784 printf(" -d, -digital display the digital clock\n");
785 printf(" -display DISPLAY contact the DISPLAY X server\n");
786 printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
787 printf(" -n, -noseconds disables the second hand\n");
788 printf(" -l LOCALE set locale to LOCALE\n");
789 printf(" -h display this help and exit\n");
790 printf(" -v output version information and exit\n");
791 printf(" -c set color\n");
794 /*******************************************************************************\
795 |* printversion *|
796 \*******************************************************************************/
798 void printversion(void) {
799 printf("WMTime version %s\n", WMTIME_VERSION);
802 /* vim: sw=4 ts=4 columns=82