ecef2bb1e1d1e876ac1d397e18184f981335ddd7
[ncurses.git] / test / gdc.c
1 /*
2  * Grand digital clock for curses compatible terminals
3  * Usage: gdc [-s] [n]   -- run for n seconds (default infinity)
4  * Flags: -s: scroll
5  *
6  * modified 10-18-89 for curses (jrl)
7  * 10-18-89 added signal handling
8  *
9  * $Id: gdc.c,v 1.10 1997/10/18 20:06:06 tom Exp $
10  */
11
12 #include <test.priv.h>
13
14 #include <time.h>
15 #include <signal.h>
16 #include <string.h>
17
18 #define YBASE   10
19 #define XBASE   10
20 #define XLENGTH 54
21 #define YDEPTH  5
22
23 /* it won't be */
24 static time_t now; /* yeah! */
25 static struct tm *tm;
26
27 static short disp[11] = {
28         075557, 011111, 071747, 071717, 055711,
29         074717, 074757, 071111, 075757, 075717, 002020
30 };
31 static long older[6], next[6], newer[6], mask;
32 static char scrol;
33
34 static int sigtermed = 0;
35
36 static int hascolor = 0;
37
38 static void set(int, int);
39 static void standt(int);
40 static void movto(int, int);
41
42 static
43 RETSIGTYPE sighndl(int signo)
44 {
45         signal(signo, sighndl);
46         sigtermed=signo;
47 }
48
49 static void
50 drawbox(void)
51 {
52         chtype bottom[XLENGTH+1];
53         int n;
54
55         if(hascolor)
56                 attrset(COLOR_PAIR(3));
57
58         mvaddch(YBASE - 1,  XBASE - 1, ACS_ULCORNER);
59         hline(ACS_HLINE, XLENGTH);
60         mvaddch(YBASE - 1,  XBASE + XLENGTH, ACS_URCORNER);
61
62         mvaddch(YBASE + YDEPTH,  XBASE - 1, ACS_LLCORNER);
63         mvinchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
64         for (n = 0; n < XLENGTH; n++)
65                 bottom[n] = ACS_HLINE | (bottom[n] & (A_ATTRIBUTES | A_COLOR));
66         mvaddchnstr(YBASE + YDEPTH, XBASE, bottom, XLENGTH);
67         mvaddch(YBASE + YDEPTH,  XBASE + XLENGTH, ACS_LRCORNER);
68
69         move(YBASE,  XBASE - 1);
70         vline(ACS_VLINE, YDEPTH);
71
72         move(YBASE,  XBASE + XLENGTH);
73         vline(ACS_VLINE, YDEPTH);
74
75         if(hascolor)
76                 attrset(COLOR_PAIR(2));
77 }
78
79 int
80 main(int argc, char *argv[])
81 {
82 long t, a;
83 int i, j, s, k;
84 int n = 0;
85
86         signal(SIGINT,sighndl);
87         signal(SIGTERM,sighndl);
88         signal(SIGKILL,sighndl);
89
90         initscr();
91         cbreak();
92         noecho();
93         nodelay(stdscr, 1);
94         curs_set(0);
95
96         hascolor = has_colors();
97
98         if(hascolor) {
99                 int bg = COLOR_BLACK;
100                 start_color();
101 #ifdef NCURSES_VERSION
102                 if (use_default_colors() == OK)
103                         bg = -1;
104 #endif
105                 init_pair(1, COLOR_BLACK, COLOR_RED);
106                 init_pair(2, COLOR_RED,   bg);
107                 init_pair(3, COLOR_WHITE, bg);
108                 attrset(COLOR_PAIR(2));
109         }
110
111         clear();
112         refresh();
113         while(--argc > 0) {
114                 if(**++argv == '-')
115                         scrol = 1;
116                 else
117                         n = atoi(*argv);
118         }
119
120         drawbox();
121         do {
122                 char    buf[30];
123
124                 mask = 0;
125                 time(&now);
126                 tm = localtime(&now);
127                 set(tm->tm_sec%10, 0);
128                 set(tm->tm_sec/10, 4);
129                 set(tm->tm_min%10, 10);
130                 set(tm->tm_min/10, 14);
131                 set(tm->tm_hour%10, 20);
132                 set(tm->tm_hour/10, 24);
133                 set(10, 7);
134                 set(10, 17);
135                 for(k=0; k<6; k++) {
136                         if(scrol) {
137                                 for(i=0; i<5; i++)
138                                         newer[i] = (newer[i]&~mask) | (newer[i+1]&mask);
139                                 newer[5] = (newer[5]&~mask) | (next[k]&mask);
140                         } else
141                                 newer[k] = (newer[k]&~mask) | (next[k]&mask);
142                         next[k] = 0;
143                         for(s=1; s>=0; s--) {
144                                 standt(s);
145                                 for(i=0; i<6; i++) {
146                                         if((a = (newer[i]^older[i])&(s ? newer : older)[i]) != 0) {
147                                                 for(j=0,t=1<<26; t; t>>=1,j++) {
148                                                         if(a&t) {
149                                                                 if(!(a&(t<<1))) {
150                                                                         movto(YBASE + i, XBASE + 2*j);
151                                                                 }
152                                                                 addstr("  ");
153                                                         }
154                                                 }
155                                         }
156                                         if(!s) {
157                                                 older[i] = newer[i];
158                                         }
159                                 }
160                                 if(!s) {
161                                         if (scrol)
162                                                 drawbox();
163                                         refresh();
164                                         if (scrol)
165                                                 napms(150);
166                                 }
167                         }
168                 }
169
170                 /* this depends on the detailed format of ctime(3) */
171                 (void) strcpy(buf, ctime(&now));
172                 (void) strcpy(buf + 10, buf + 19);
173                 mvaddstr(16, 30, buf);
174
175                 movto(6, 0);
176                 drawbox();
177                 refresh();
178                 sleep(1);
179                 while(wgetch(stdscr) != ERR)
180                         continue;
181                 if (sigtermed) {
182                         standend();
183                         clear();
184                         refresh();
185                         curs_set(1);
186                         endwin();
187                         fprintf(stderr, "gdc terminated by signal %d\n", sigtermed);
188                         return EXIT_FAILURE;
189                 }
190         } while(--n);
191         standend();
192         clear();
193         refresh();
194         curs_set(1);
195         endwin();
196         return EXIT_SUCCESS;
197 }
198
199 static void
200 set(int t, int n)
201 {
202 int i, m;
203
204         m = 7<<n;
205         for(i=0; i<5; i++) {
206                 next[i] |= ((disp[t]>>(4-i)*3)&07)<<n;
207                 mask |= (next[i]^older[i])&m;
208         }
209         if(mask&m)
210                 mask |= m;
211 }
212
213 static void
214 standt(int on)
215 {
216         if (on) {
217                 if(hascolor) {
218                         attron(COLOR_PAIR(1));
219                 } else {
220                         attron(A_STANDOUT);
221                 }
222         } else {
223                 if(hascolor) {
224                         attron(COLOR_PAIR(2));
225                 } else {
226                         attroff(A_STANDOUT);
227                 }
228         }
229 }
230
231 static void
232 movto(int line, int col)
233 {
234         move(line, col);
235 }