missing ncurses sources
[tomato.git] / release / src / router / libncurses / test / gdc.c
blobf3018cd8d331e8d4427425fda8e76c55441eb677
1 /****************************************************************************
2 * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. *
3 * *
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: *
11 * *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
14 * *
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. *
22 * *
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 *
26 * authorization. *
27 ****************************************************************************/
29 * Grand digital clock for curses compatible terminals
30 * Usage: gdc [-s] [n] -- run for n seconds (default infinity)
31 * Flags: -s: scroll
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>
41 #include <time.h>
43 #define YBASE 10
44 #define XBASE 10
45 #define XLENGTH 54
46 #define YDEPTH 5
48 #define PAIR_DIGITS 1
49 #define PAIR_OTHERS 2
50 #define PAIR_FRAMES 3
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;
63 static RETSIGTYPE
64 sighndl(int signo)
66 signal(signo, sighndl);
67 sigtermed = signo;
68 if (redirected) {
69 endwin();
70 ExitProgram(EXIT_FAILURE);
74 static void
75 drawbox(bool scrolling)
77 chtype bottom[XLENGTH + 1];
78 int n;
80 if (hascolor)
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++) {
90 if (!scrolling)
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);
104 if (hascolor)
105 (void) attrset(COLOR_PAIR(PAIR_OTHERS));
108 static void
109 standt(int on)
111 if (on) {
112 if (hascolor) {
113 attron(COLOR_PAIR(PAIR_DIGITS));
114 } else {
115 attron(A_STANDOUT);
117 } else {
118 if (hascolor) {
119 attron(COLOR_PAIR(PAIR_OTHERS));
120 } else {
121 attroff(A_STANDOUT);
126 static void
127 set(int t, int n)
129 int i, m;
131 m = 7 << n;
132 for (i = 0; i < 5; i++) {
133 next[i] |= ((disp[t] >> ((4 - i) * 3)) & 07) << n;
134 mask |= (next[i] ^ older[i]) & m;
136 if (mask & m)
137 mask |= m;
140 static void
141 usage(void)
143 static const char *msg[] =
145 "Usage: gdc [options] [count]"
147 ,"Options:"
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"
153 unsigned j;
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[])
162 time_t now;
163 struct tm *tm;
164 long t, a;
165 int i, j, s, k;
166 int count = 0;
167 FILE *ofp = stdout;
168 FILE *ifp = stdin;
169 bool scrol = FALSE;
171 setlocale(LC_ALL, "");
173 CATCHALL(sighndl);
175 while ((k = getopt(argc, argv, "sn")) != -1) {
176 switch (k) {
177 case 's':
178 scrol = TRUE;
179 break;
180 case 'n':
181 ifp = fopen("/dev/null", "r");
182 redirected = TRUE;
183 break;
184 default:
185 usage();
188 if (optind < argc) {
189 count = atoi(argv[optind++]);
190 assert(count >= 0);
192 if (optind < argc)
193 usage();
195 if (redirected) {
196 char *name = getenv("TERM");
197 if (name == 0
198 || newterm(name, ofp, ifp) == 0) {
199 fprintf(stderr, "cannot open terminal\n");
200 ExitProgram(EXIT_FAILURE);
203 } else {
204 initscr();
206 cbreak();
207 noecho();
208 nodelay(stdscr, 1);
209 curs_set(0);
211 hascolor = has_colors();
213 if (hascolor) {
214 short bg = COLOR_BLACK;
215 start_color();
216 #if HAVE_USE_DEFAULT_COLORS
217 if (use_default_colors() == OK)
218 bg = -1;
219 #endif
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));
226 restart:
227 for (j = 0; j < 5; j++)
228 older[j] = newer[j] = next[j] = 0;
230 clear();
231 drawbox(FALSE);
233 do {
234 char buf[30];
236 time(&now);
237 tm = localtime(&now);
239 mask = 0;
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);
246 set(10, 7);
247 set(10, 17);
249 for (k = 0; k < 6; k++) {
250 if (scrol) {
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);
254 } else
255 newer[k] = (newer[k] & ~mask) | (next[k] & mask);
256 next[k] = 0;
257 for (s = 1; s >= 0; s--) {
258 standt(s);
259 for (i = 0; i < 6; i++) {
260 if ((a = (newer[i] ^ older[i]) & (s ? newer : older)[i])
261 != 0) {
262 for (j = 0, t = 1 << 26; t; t >>= 1, j++) {
263 if (a & t) {
264 if (!(a & (t << 1))) {
265 move(YBASE + i, XBASE + 2 * j);
267 addstr(" ");
271 if (!s) {
272 older[i] = newer[i];
275 if (!s) {
276 if (scrol)
277 drawbox(TRUE);
278 refresh();
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
289 if (scrol)
290 napms(85);
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);
300 move(6, 0);
301 drawbox(FALSE);
302 refresh();
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.
309 if (scrol)
310 napms(500);
311 else
312 napms(1000);
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)) {
322 case 'q':
323 count = 1;
324 break;
325 case 's':
326 nodelay(stdscr, FALSE);
327 break;
328 case ' ':
329 nodelay(stdscr, TRUE);
330 break;
331 #ifdef KEY_RESIZE
332 case KEY_RESIZE:
333 #endif
334 case '?':
335 goto restart;
336 case ERR:
337 if (sigtermed) {
338 (void) standend();
339 endwin();
340 fprintf(stderr, "gdc terminated by signal %d\n", sigtermed);
341 ExitProgram(EXIT_FAILURE);
343 /* FALLTHRU */
344 default:
345 continue;
347 } while (--count);
348 (void) standend();
349 endwin();
350 ExitProgram(EXIT_SUCCESS);