1 /****************************************************************************
2 * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
4 * Permission is hereby granted, free of charge, to any person obtaining a *
5 * copy of this software and associated documentation files (the *
6 * "Software"), to deal in the Software without restriction, including *
7 * without limitation the rights to use, copy, modify, merge, publish, *
8 * distribute, distribute with modifications, sublicense, and/or sell *
9 * copies of the Software, and to permit persons to whom the Software is *
10 * furnished to do so, subject to the following conditions: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23 * Except as contained in this notice, the name(s) of the above copyright *
24 * holders shall not be used in advertising or otherwise to promote the *
25 * sale, use or other dealings in this Software without prior written *
27 ****************************************************************************/
29 * Grand digital clock for curses compatible terminals
30 * Usage: gdc [-s] [n] -- run for n seconds (default infinity)
33 * modified 10-18-89 for curses (jrl)
34 * 10-18-89 added signal handling
36 * $Id: gdc.c,v 1.34 2010/11/13 21:01:23 tom Exp $
39 #include <test.priv.h>
52 static short disp
[11] =
54 075557, 011111, 071747, 071717, 055711,
55 074717, 074757, 071111, 075757, 075717, 002020
57 static long older
[6], next
[6], newer
[6], mask
;
59 static int sigtermed
= 0;
60 static bool redirected
= FALSE
;
61 static bool hascolor
= FALSE
;
66 signal(signo
, sighndl
);
70 ExitProgram(EXIT_FAILURE
);
75 drawbox(bool scrolling
)
77 chtype bottom
[XLENGTH
+ 1];
81 (void) attrset(COLOR_PAIR(PAIR_FRAMES
));
83 MvAddCh(YBASE
- 1, XBASE
- 1, ACS_ULCORNER
);
84 hline(ACS_HLINE
, XLENGTH
);
85 MvAddCh(YBASE
- 1, XBASE
+ XLENGTH
, ACS_URCORNER
);
87 MvAddCh(YBASE
+ YDEPTH
, XBASE
- 1, ACS_LLCORNER
);
88 if ((mvinchnstr(YBASE
+ YDEPTH
, XBASE
, bottom
, XLENGTH
)) != ERR
) {
89 for (n
= 0; n
< XLENGTH
; n
++) {
91 bottom
[n
] &= ~A_COLOR
;
92 bottom
[n
] = ACS_HLINE
| (bottom
[n
] & (A_ATTRIBUTES
| A_COLOR
));
94 (void) mvaddchnstr(YBASE
+ YDEPTH
, XBASE
, bottom
, XLENGTH
);
96 MvAddCh(YBASE
+ YDEPTH
, XBASE
+ XLENGTH
, ACS_LRCORNER
);
98 move(YBASE
, XBASE
- 1);
99 vline(ACS_VLINE
, YDEPTH
);
101 move(YBASE
, XBASE
+ XLENGTH
);
102 vline(ACS_VLINE
, YDEPTH
);
105 (void) attrset(COLOR_PAIR(PAIR_OTHERS
));
113 attron(COLOR_PAIR(PAIR_DIGITS
));
119 attron(COLOR_PAIR(PAIR_OTHERS
));
132 for (i
= 0; i
< 5; i
++) {
133 next
[i
] |= ((disp
[t
] >> ((4 - i
) * 3)) & 07) << n
;
134 mask
|= (next
[i
] ^ older
[i
]) & m
;
143 static const char *msg
[] =
145 "Usage: gdc [options] [count]"
148 ," -n redirect input to /dev/null"
149 ," -s scroll each number into place, rather than flipping"
151 ,"If you specify a count, gdc runs for that number of seconds"
154 for (j
= 0; j
< SIZEOF(msg
); j
++)
155 fprintf(stderr
, "%s\n", msg
[j
]);
156 ExitProgram(EXIT_FAILURE
);
160 main(int argc
, char *argv
[])
171 setlocale(LC_ALL
, "");
175 while ((k
= getopt(argc
, argv
, "sn")) != -1) {
181 ifp
= fopen("/dev/null", "r");
189 count
= atoi(argv
[optind
++]);
196 char *name
= getenv("TERM");
198 || newterm(name
, ofp
, ifp
) == 0) {
199 fprintf(stderr
, "cannot open terminal\n");
200 ExitProgram(EXIT_FAILURE
);
211 hascolor
= has_colors();
214 short bg
= COLOR_BLACK
;
216 #if HAVE_USE_DEFAULT_COLORS
217 if (use_default_colors() == OK
)
220 init_pair(PAIR_DIGITS
, COLOR_BLACK
, COLOR_RED
);
221 init_pair(PAIR_OTHERS
, COLOR_RED
, bg
);
222 init_pair(PAIR_FRAMES
, COLOR_WHITE
, bg
);
223 (void) attrset(COLOR_PAIR(PAIR_OTHERS
));
227 for (j
= 0; j
< 5; j
++)
228 older
[j
] = newer
[j
] = next
[j
] = 0;
237 tm
= localtime(&now
);
240 set(tm
->tm_sec
% 10, 0);
241 set(tm
->tm_sec
/ 10, 4);
242 set(tm
->tm_min
% 10, 10);
243 set(tm
->tm_min
/ 10, 14);
244 set(tm
->tm_hour
% 10, 20);
245 set(tm
->tm_hour
/ 10, 24);
249 for (k
= 0; k
< 6; k
++) {
251 for (i
= 0; i
< 5; i
++)
252 newer
[i
] = (newer
[i
] & ~mask
) | (newer
[i
+ 1] & mask
);
253 newer
[5] = (newer
[5] & ~mask
) | (next
[k
] & mask
);
255 newer
[k
] = (newer
[k
] & ~mask
) | (next
[k
] & mask
);
257 for (s
= 1; s
>= 0; s
--) {
259 for (i
= 0; i
< 6; i
++) {
260 if ((a
= (newer
[i
] ^ older
[i
]) & (s
? newer
: older
)[i
])
262 for (j
= 0, t
= 1 << 26; t
; t
>>= 1, j
++) {
264 if (!(a
& (t
<< 1))) {
265 move(YBASE
+ i
, XBASE
+ 2 * j
);
280 * If we're scrolling, space out the refreshes to fake
281 * movement. That's 7 frames, or 6 intervals, which would
282 * be 166 msec if we spread it out over a second. It looks
283 * better (but will work on a slow terminal, e.g., less
284 * than 9600bd) to squeeze that into a half-second, and use
285 * half of 170 msec to ensure that the program doesn't eat
286 * a lot of time when asking what time it is, at the top of
287 * this loop -T.Dickey
295 /* this depends on the detailed format of ctime(3) */
296 (void) strcpy(buf
, ctime(&now
));
297 (void) strcpy(buf
+ 10, buf
+ 19);
298 MvAddStr(16, 30, buf
);
305 * If we're not scrolling, wait 1000 msec (1 sec). Use napms() rather
306 * than sleep() because the latter does odd things on some systems,
307 * e.g., suspending output as well.
315 * This is a safe way to check if we're interrupted - making the signal
316 * handler set a flag that we can check. Since we're running
317 * nodelay(), the wgetch() call returns immediately, and in particular
318 * will return an error if interrupted. This works only if we can
319 * read from the input, of course.
321 switch (wgetch(stdscr
)) {
326 nodelay(stdscr
, FALSE
);
329 nodelay(stdscr
, TRUE
);
340 fprintf(stderr
, "gdc terminated by signal %d\n", sigtermed
);
341 ExitProgram(EXIT_FAILURE
);
350 ExitProgram(EXIT_SUCCESS
);