2 * Grand digital clock for curses compatible terminals
3 * Usage: grdc [-st] [n] -- run for n seconds (default infinity)
4 * grdc -c n -- countdown n seconds
5 * Flags: -c: Countdown timer mode
7 * -t: output time in 12-hour format
10 * modified 10-18-89 for curses (jrl)
11 * 10-18-89 added signal handling
12 * 02-18-02 added countdown timer mode
14 * modified 03-25-03 for 12 hour option
15 * - Samy Al Bahra <samy@kerneled.com>
30 static struct timespec now
;
32 static struct timespec end
;
34 static short disp
[11] = {
35 075557, 011111, 071747, 071717, 055711,
36 074717, 074757, 071111, 075757, 075717, 002020
38 static long old
[6], next
[6], new[6], mask
;
40 static volatile sig_atomic_t sigtermed
;
42 static int hascolor
= 0;
44 static void set(int, int);
45 static void standt(int);
46 static void movto(int, int);
47 static void sighndl(int);
48 static void usage(void) __dead2
;
58 main(int argc
, char *argv
[])
60 struct timespec delay
;
66 bool scrol
= false, t12
= false, timer
= false;
67 int hour
, minute
, second
;
69 while ((ch
= getopt(argc
, argv
, "cst")) != -1)
88 if ((argc
> 1) || (argc
== 0 && timer
)) {
96 warnx("number of seconds is out of range");
108 signal(SIGINT
,sighndl
);
109 signal(SIGTERM
,sighndl
);
110 signal(SIGHUP
,sighndl
);
116 hascolor
= has_colors();
120 init_pair(1, COLOR_BLACK
, COLOR_RED
);
121 init_pair(2, COLOR_RED
, COLOR_BLACK
);
122 init_pair(3, COLOR_WHITE
, COLOR_BLACK
);
123 attrset(COLOR_PAIR(2));
130 attrset(COLOR_PAIR(3));
132 mvaddch(YBASE
- 2, XBASE
- 3, ACS_ULCORNER
);
133 hline(ACS_HLINE
, XLENGTH
);
134 mvaddch(YBASE
- 2, XBASE
- 2 + XLENGTH
, ACS_URCORNER
);
136 mvaddch(YBASE
+ YDEPTH
- 1, XBASE
- 3, ACS_LLCORNER
);
137 hline(ACS_HLINE
, XLENGTH
);
138 mvaddch(YBASE
+ YDEPTH
- 1, XBASE
- 2 + XLENGTH
, ACS_LRCORNER
);
140 move(YBASE
- 1, XBASE
- 3);
141 vline(ACS_VLINE
, YDEPTH
);
143 move(YBASE
- 1, XBASE
- 2 + XLENGTH
);
144 vline(ACS_VLINE
, YDEPTH
);
146 attrset(COLOR_PAIR(2));
148 clock_gettime(CLOCK_REALTIME_FAST
, &now
);
149 prev_sec
= now
.tv_sec
;
157 tm
= localtime(&now
.tv_sec
);
159 if (tm
->tm_hour
< 12) {
160 if (tm
->tm_hour
== 0)
162 mvaddstr(YBASE
+ 5, XBASE
+ 52, "AM");
164 if (tm
->tm_hour
> 12)
166 mvaddstr(YBASE
+ 5, XBASE
+ 52, "PM");
173 n
= end
.tv_sec
- now
.tv_sec
;
176 hour
= (n
/ 3600) % 100;
177 minute
= (n
/ 60) % 60;
182 set(minute
% 10, 10);
183 set(minute
/ 10, 14);
191 new[i
] = (new[i
]&~mask
) | (new[i
+1]&mask
);
192 new[5] = (new[5]&~mask
) | (next
[k
]&mask
);
194 new[k
] = (new[k
]&~mask
) | (next
[k
]&mask
);
196 for(s
=1; s
>=0; s
--) {
199 if((a
= (new[i
]^old
[i
])&(s
? new : old
)[i
]) != 0) {
200 for(j
=0,t
=1<<26; t
; t
>>=1,j
++) {
203 movto(YBASE
+ i
, XBASE
+ 2*j
);
220 clock_gettime(CLOCK_REALTIME_FAST
, &now
);
221 if (now
.tv_sec
== prev_sec
) {
222 if (delay
.tv_nsec
> 0) {
224 delay
.tv_nsec
= 1000000000 - now
.tv_nsec
;
229 nanosleep(&delay
, NULL
);
230 clock_gettime(CLOCK_REALTIME_FAST
, &now
);
232 n
-= now
.tv_sec
- prev_sec
;
233 prev_sec
= now
.tv_sec
;
239 errx(1, "terminated by signal %d", (int)sigtermed
);
256 next
[i
] |= ((disp
[t
]>>(4-i
)*3)&07)<<n
;
257 mask
|= (next
[i
]^old
[i
])&m
;
268 attron(COLOR_PAIR(1));
274 attron(COLOR_PAIR(2));
282 movto(int line
, int col
)
291 (void)fprintf(stderr
, "usage: grdc [-st] [n]\n"