Raise some WARNS in usr.bin.
[dragonfly.git] / contrib / ncurses-5.4 / test / gdc.c
blobc466f2fde2674d95849d355f4bd980da2913f581
1 /*
2 * Grand digital clock for curses compatible terminals
3 * Usage: gdc [-s] [n] -- run for n seconds (default infinity)
4 * Flags: -s: scroll
6 * modified 10-18-89 for curses (jrl)
7 * 10-18-89 added signal handling
9 * $Id: gdc.c,v 1.23 2002/08/10 19:20:14 tom Exp $
12 #include <time.h>
14 #include <test.priv.h>
16 #define YBASE 10
17 #define XBASE 10
18 #define XLENGTH 54
19 #define YDEPTH 5
21 static short disp[11] =
23 075557, 011111, 071747, 071717, 055711,
24 074717, 074757, 071111, 075757, 075717, 002020
26 static long older[6], next[6], newer[6], mask;
28 static int sigtermed = 0;
29 static bool redirected = FALSE;
30 static bool hascolor = FALSE;
32 static RETSIGTYPE
33 sighndl(int signo)
35 signal(signo, sighndl);
36 sigtermed = signo;
37 if (redirected) {
38 endwin();
39 ExitProgram(EXIT_FAILURE);
43 static void
44 drawbox(void)
46 chtype bottom[XLENGTH + 1];
47 int n;
49 if (hascolor)
50 attrset(COLOR_PAIR(3));
52 mvaddch(YBASE - 1, XBASE - 1, ACS_ULCORNER);
53 hline(ACS_HLINE, XLENGTH);
54 mvaddch(YBASE - 1, XBASE + XLENGTH, ACS_URCORNER);
56 mvaddch(YBASE + YDEPTH, XBASE - 1, ACS_LLCORNER);
57 mvinchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
58 for (n = 0; n < XLENGTH; n++)
59 bottom[n] = ACS_HLINE | (bottom[n] & (A_ATTRIBUTES | A_COLOR));
60 mvaddchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
61 mvaddch(YBASE + YDEPTH, XBASE + XLENGTH, ACS_LRCORNER);
63 move(YBASE, XBASE - 1);
64 vline(ACS_VLINE, YDEPTH);
66 move(YBASE, XBASE + XLENGTH);
67 vline(ACS_VLINE, YDEPTH);
69 if (hascolor)
70 attrset(COLOR_PAIR(2));
73 static void
74 standt(int on)
76 if (on) {
77 if (hascolor) {
78 attron(COLOR_PAIR(1));
79 } else {
80 attron(A_STANDOUT);
82 } else {
83 if (hascolor) {
84 attron(COLOR_PAIR(2));
85 } else {
86 attroff(A_STANDOUT);
91 static void
92 set(int t, int n)
94 int i, m;
96 m = 7 << n;
97 for (i = 0; i < 5; i++) {
98 next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n;
99 mask |= (next[i] ^ older[i]) & m;
101 if (mask & m)
102 mask |= m;
105 static void
106 usage(void)
108 static const char *msg[] =
110 "Usage: gdc [options] [count]"
112 ,"Options:"
113 ," -n redirect input to /dev/null"
114 ," -s scroll each number into place, rather than flipping"
116 ,"If you specify a count, gdc runs for that number of seconds"
118 unsigned j;
119 for (j = 0; j < SIZEOF(msg); j++)
120 fprintf(stderr, "%s\n", msg[j]);
121 ExitProgram(EXIT_FAILURE);
125 main(int argc, char *argv[])
127 time_t now;
128 struct tm *tm;
129 long t, a;
130 int i, j, s, k;
131 int count = 0;
132 FILE *ofp = stdout;
133 FILE *ifp = stdin;
134 bool scrol = FALSE;
136 setlocale(LC_ALL, "");
138 signal(SIGINT, sighndl);
139 signal(SIGTERM, sighndl);
141 while ((k = getopt(argc, argv, "sn")) != EOF) {
142 switch (k) {
143 case 's':
144 scrol = TRUE;
145 break;
146 case 'n':
147 ifp = fopen("/dev/null", "r");
148 redirected = TRUE;
149 break;
150 default:
151 usage();
154 if (optind < argc) {
155 count = atoi(argv[optind++]);
157 if (optind < argc)
158 usage();
160 if (redirected) {
161 char *name = getenv("TERM");
162 if (name == 0
163 || newterm(name, ofp, ifp) == 0) {
164 fprintf(stderr, "cannot open terminal\n");
165 ExitProgram(EXIT_FAILURE);
168 } else {
169 initscr();
171 cbreak();
172 noecho();
173 nodelay(stdscr, 1);
174 curs_set(0);
176 hascolor = has_colors();
178 if (hascolor) {
179 int bg = COLOR_BLACK;
180 start_color();
181 #if HAVE_USE_DEFAULT_COLORS
182 if (use_default_colors() == OK)
183 bg = -1;
184 #endif
185 init_pair(1, COLOR_BLACK, COLOR_RED);
186 init_pair(2, COLOR_RED, bg);
187 init_pair(3, COLOR_WHITE, bg);
188 attrset(COLOR_PAIR(2));
191 restart:
192 for (j = 0; j < 5; j++)
193 older[j] = newer[j] = next[j] = 0;
195 clear();
196 drawbox();
198 do {
199 char buf[30];
201 time(&now);
202 tm = localtime(&now);
204 mask = 0;
205 set(tm->tm_sec % 10, 0);
206 set(tm->tm_sec / 10, 4);
207 set(tm->tm_min % 10, 10);
208 set(tm->tm_min / 10, 14);
209 set(tm->tm_hour % 10, 20);
210 set(tm->tm_hour / 10, 24);
211 set(10, 7);
212 set(10, 17);
214 for (k = 0; k < 6; k++) {
215 if (scrol) {
216 for (i = 0; i < 5; i++)
217 newer[i] = (newer[i] & ~mask) | (newer[i + 1] & mask);
218 newer[5] = (newer[5] & ~mask) | (next[k] & mask);
219 } else
220 newer[k] = (newer[k] & ~mask) | (next[k] & mask);
221 next[k] = 0;
222 for (s = 1; s >= 0; s--) {
223 standt(s);
224 for (i = 0; i < 6; i++) {
225 if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i])
226 != 0) {
227 for (j = 0, t = 1 << 26; t; t >>= 1, j++) {
228 if (a & t) {
229 if (!(a & (t << 1))) {
230 move(YBASE + i, XBASE + 2 * j);
232 addstr(" ");
236 if (!s) {
237 older[i] = newer[i];
240 if (!s) {
241 if (scrol)
242 drawbox();
243 refresh();
245 * If we're scrolling, space out the refreshes to fake
246 * movement. That's 7 frames, or 6 intervals, which would
247 * be 166 msec if we spread it out over a second. It looks
248 * better (but will well on a slow terminal, e.g., less
249 * than 9600bd) to squeeze that into a half-second, and use
250 * half of 170 msec to ensure that the program doesn't eat
251 * a lot of time when asking what time it is, at the top of
252 * this loop -TD
254 if (scrol)
255 napms(85);
260 /* this depends on the detailed format of ctime(3) */
261 (void) strcpy(buf, ctime(&now));
262 (void) strcpy(buf + 10, buf + 19);
263 mvaddstr(16, 30, buf);
265 move(6, 0);
266 drawbox();
267 refresh();
270 * If we're not scrolling, wait 1000 msec (1 sec). Use napms() rather
271 * than sleep() because the latter does odd things on some systems,
272 * e.g., suspending output as well.
274 if (scrol)
275 napms(500);
276 else
277 napms(1000);
280 * This is a safe way to check if we're interrupted - making the signal
281 * handler set a flag that we can check. Since we're running
282 * nodelay(), the wgetch() call returns immediately, and in particular
283 * will return an error if interrupted. This works only if we can
284 * read from the input, of course.
286 switch (wgetch(stdscr)) {
287 case 'q':
288 count = 1;
289 break;
290 case 's':
291 nodelay(stdscr, FALSE);
292 break;
293 case ' ':
294 nodelay(stdscr, TRUE);
295 break;
296 #ifdef KEY_RESIZE
297 case KEY_RESIZE:
298 #endif
299 case '?':
300 goto restart;
301 case ERR:
302 if (sigtermed) {
303 standend();
304 endwin();
305 fprintf(stderr, "gdc terminated by signal %d\n", sigtermed);
306 ExitProgram(EXIT_FAILURE);
308 /* FALLTHRU */
309 default:
310 continue;
312 } while (--count);
313 standend();
314 endwin();
315 ExitProgram(EXIT_SUCCESS);