]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - games/grdc/grdc.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / games / grdc / grdc.c
1 /*
2  * Grand digital clock for curses compatible terminals
3  * Usage: grdc [-st] [n]   -- run for n seconds (default infinity)
4  * Flags: -s: scroll
5  *        -t: output time in 12-hour format
6  *
7  *
8  * modified 10-18-89 for curses (jrl)
9  * 10-18-89 added signal handling
10  *
11  * modified 03-25-03 for 12 hour option
12  *     - Samy Al Bahra <samy@kerneled.com>
13  *
14  * $FreeBSD$
15  */
16
17 #include <err.h>
18 #include <time.h>
19 #include <signal.h>
20 #include <ncurses.h>
21 #include <stdlib.h>
22 #ifndef NONPOSIX
23 #include <unistd.h>
24 #endif
25
26 #define YBASE   10
27 #define XBASE   10
28 #define XLENGTH 58
29 #define YDEPTH  7
30
31 /* it won't be */
32 time_t now; /* yeah! */
33 struct tm *tm;
34
35 short disp[11] = {
36         075557, 011111, 071747, 071717, 055711,
37         074717, 074757, 071111, 075757, 075717, 002020
38 };
39 long old[6], next[6], new[6], mask;
40
41 volatile sig_atomic_t sigtermed;
42
43 int hascolor = 0;
44
45 void set(int, int);
46 void standt(int);
47 void movto(int, int);
48 void sighndl(int);
49 void usage(void);
50
51 void sighndl(signo)
52 int signo;
53 {
54         sigtermed=signo;
55 }
56
57 int
58 main(argc, argv)
59 int argc;
60 char **argv;
61 {
62 long t, a;
63 int i, j, s, k;
64 int n;
65 int ch;
66 int scrol;
67 int t12;
68
69         t12 = scrol = 0;
70
71         while ((ch = getopt(argc, argv, "ts")) != -1)
72         switch (ch) {
73         case 's':
74                 scrol = 1;
75                 break;
76         case 't':
77                 t12 = 1;
78                 break;
79         case '?':
80         default:
81                 usage();
82                 /* NOTREACHED */
83         }
84         argc -= optind;
85         argv += optind;
86
87         if (argc > 1) {
88                 usage();
89                 /* NOTREACHED */
90         }
91
92         if (argc > 0)
93                 n = atoi(*argv);
94         else
95                 n = 0;
96
97         initscr();
98
99         signal(SIGINT,sighndl);
100         signal(SIGTERM,sighndl);
101         signal(SIGHUP,sighndl);
102
103         cbreak();
104         noecho();
105         curs_set(0);
106
107         hascolor = has_colors();
108
109         if(hascolor) {
110                 start_color();
111                 init_pair(1, COLOR_BLACK, COLOR_RED);
112                 init_pair(2, COLOR_RED, COLOR_BLACK);
113                 init_pair(3, COLOR_WHITE, COLOR_BLACK);
114                 attrset(COLOR_PAIR(2));
115         }
116
117         clear();
118         refresh();
119
120         if(hascolor) {
121                 attrset(COLOR_PAIR(3));
122
123                 mvaddch(YBASE - 2,  XBASE - 3, ACS_ULCORNER);
124                 hline(ACS_HLINE, XLENGTH);
125                 mvaddch(YBASE - 2,  XBASE - 2 + XLENGTH, ACS_URCORNER);
126
127                 mvaddch(YBASE + YDEPTH - 1,  XBASE - 3, ACS_LLCORNER);
128                 hline(ACS_HLINE, XLENGTH);
129                 mvaddch(YBASE + YDEPTH - 1,  XBASE - 2 + XLENGTH, ACS_LRCORNER);
130
131                 move(YBASE - 1,  XBASE - 3);
132                 vline(ACS_VLINE, YDEPTH);
133
134                 move(YBASE - 1,  XBASE - 2 + XLENGTH);
135                 vline(ACS_VLINE, YDEPTH);
136
137                 attrset(COLOR_PAIR(2));
138         }
139         do {
140                 mask = 0;
141                 time(&now);
142                 tm = localtime(&now);
143                 set(tm->tm_sec%10, 0);
144                 set(tm->tm_sec/10, 4);
145                 set(tm->tm_min%10, 10);
146                 set(tm->tm_min/10, 14);
147
148                 if (t12) {
149                         if (tm->tm_hour > 12) {
150                                 tm->tm_hour -= 12;
151                                 mvaddstr(YBASE + 5, XBASE + 52, "PM");
152                         } else {
153                                 if (tm->tm_hour == 0)
154                                         tm->tm_hour = 12;
155
156                                 mvaddstr(YBASE + 5, XBASE + 52, "AM");
157                         }
158                 }
159
160                 set(tm->tm_hour%10, 20);
161                 set(tm->tm_hour/10, 24);
162                 set(10, 7);
163                 set(10, 17);
164                 for(k=0; k<6; k++) {
165                         if(scrol) {
166                                 for(i=0; i<5; i++)
167                                         new[i] = (new[i]&~mask) | (new[i+1]&mask);
168                                 new[5] = (new[5]&~mask) | (next[k]&mask);
169                         } else
170                                 new[k] = (new[k]&~mask) | (next[k]&mask);
171                         next[k] = 0;
172                         for(s=1; s>=0; s--) {
173                                 standt(s);
174                                 for(i=0; i<6; i++) {
175                                         if((a = (new[i]^old[i])&(s ? new : old)[i]) != 0) {
176                                                 for(j=0,t=1<<26; t; t>>=1,j++) {
177                                                         if(a&t) {
178                                                                 if(!(a&(t<<1))) {
179                                                                         movto(YBASE + i, XBASE + 2*j);
180                                                                 }
181                                                                 addstr("  ");
182                                                         }
183                                                 }
184                                         }
185                                         if(!s) {
186                                                 old[i] = new[i];
187                                         }
188                                 }
189                                 if(!s) {
190                                         refresh();
191                                 }
192                         }
193                 }
194                 movto(6, 0);
195                 refresh();
196                 sleep(1);
197                 if (sigtermed) {
198                         standend();
199                         clear();
200                         refresh();
201                         endwin();
202                         errx(1, "terminated by signal %d", (int)sigtermed);
203                 }
204         } while(--n);
205         standend();
206         clear();
207         refresh();
208         endwin();
209         return(0);
210 }
211
212 void
213 set(int t, int n)
214 {
215 int i, m;
216
217         m = 7<<n;
218         for(i=0; i<5; i++) {
219                 next[i] |= ((disp[t]>>(4-i)*3)&07)<<n;
220                 mask |= (next[i]^old[i])&m;
221         }
222         if(mask&m)
223                 mask |= m;
224 }
225
226 void
227 standt(int on)
228 {
229         if (on) {
230                 if(hascolor) {
231                         attron(COLOR_PAIR(1));
232                 } else {
233                         attron(A_STANDOUT);
234                 }
235         } else {
236                 if(hascolor) {
237                         attron(COLOR_PAIR(2));
238                 } else {
239                         attroff(A_STANDOUT);
240                 }
241         }
242 }
243
244 void
245 movto(int line, int col)
246 {
247         move(line, col);
248 }
249
250 void
251 usage(void)
252 {
253
254         (void)fprintf(stderr, "usage: grdc [-st] [n]\n");
255         exit(1);
256 }