xref: /openbsd/games/grdc/grdc.c (revision 07ea8d15)
1 /*	$OpenBSD: grdc.c,v 1.2 1996/12/19 22:21:30 deraadt Exp $	*/
2 /*
3  * Grand digital clock for curses compatible terminals
4  * Usage: grdc [-s] [n]   -- run for n seconds (default infinity)
5  * Flags: -s: scroll
6  *
7  * modified 10-18-89 for curses (jrl)
8  * 10-18-89 added signal handling
9  */
10 
11 #include <time.h>
12 #include <signal.h>
13 #include <curses.h>
14 #include <stdlib.h>
15 #ifndef NONPOSIX
16 #include <unistd.h>
17 #endif
18 
19 #define YBASE	10
20 #define XBASE	10
21 #define XLENGTH 58
22 #define YDEPTH  7
23 
24 /* it won't be */
25 long now; /* yeah! */
26 struct tm *tm;
27 
28 short disp[11] = {
29 	075557, 011111, 071747, 071717, 055711,
30 	074717, 074757, 071111, 075757, 075717, 002020
31 };
32 long old[6], next[6], new[6], mask;
33 char scrol;
34 
35 int sigtermed=0;
36 
37 int hascolor = 0;
38 
39 void set(int, int);
40 void standt(int);
41 void movto(int, int);
42 
43 void sighndl(signo)
44 int signo;
45 {
46 	sigtermed=signo;
47 }
48 
49 int
50 main(argc, argv)
51 int argc;
52 char **argv;
53 {
54 long t, a;
55 int i, j, s, k;
56 int n = 0;
57 
58 	initscr();
59 
60 	setgid(getgid());
61 
62 	signal(SIGINT,sighndl);
63 	signal(SIGTERM,sighndl);
64 	signal(SIGHUP,sighndl);
65 
66 	cbreak();
67 	noecho();
68 
69 	hascolor = has_colors();
70 
71 	if(hascolor) {
72 		start_color();
73 		init_pair(1, COLOR_BLACK, COLOR_RED);
74 		init_pair(2, COLOR_RED, COLOR_BLACK);
75 		init_pair(3, COLOR_WHITE, COLOR_BLACK);
76 		attrset(COLOR_PAIR(2));
77 	}
78 
79 	clear();
80 	refresh();
81 	while(--argc > 0) {
82 		if(**++argv == '-')
83 			scrol = 1;
84 		else
85 			n = atoi(*argv);
86 	}
87 
88 	if(hascolor) {
89 		attrset(COLOR_PAIR(3));
90 
91 		mvaddch(YBASE - 2,  XBASE - 3, ACS_ULCORNER);
92 		hline(ACS_HLINE, XLENGTH);
93 		mvaddch(YBASE - 2,  XBASE - 2 + XLENGTH, ACS_URCORNER);
94 
95 		mvaddch(YBASE + YDEPTH - 1,  XBASE - 3, ACS_LLCORNER);
96 		hline(ACS_HLINE, XLENGTH);
97 		mvaddch(YBASE + YDEPTH - 1,  XBASE - 2 + XLENGTH, ACS_LRCORNER);
98 
99 		move(YBASE - 1,  XBASE - 3);
100 		vline(ACS_VLINE, YDEPTH);
101 
102 		move(YBASE - 1,  XBASE - 2 + XLENGTH);
103 		vline(ACS_VLINE, YDEPTH);
104 
105 		attrset(COLOR_PAIR(2));
106 	}
107 	do {
108 		mask = 0;
109 		time(&now);
110 		tm = localtime(&now);
111 		set(tm->tm_sec%10, 0);
112 		set(tm->tm_sec/10, 4);
113 		set(tm->tm_min%10, 10);
114 		set(tm->tm_min/10, 14);
115 		set(tm->tm_hour%10, 20);
116 		set(tm->tm_hour/10, 24);
117 		set(10, 7);
118 		set(10, 17);
119 		for(k=0; k<6; k++) {
120 			if(scrol) {
121 				for(i=0; i<5; i++)
122 					new[i] = (new[i]&~mask) | (new[i+1]&mask);
123 				new[5] = (new[5]&~mask) | (next[k]&mask);
124 			} else
125 				new[k] = (new[k]&~mask) | (next[k]&mask);
126 			next[k] = 0;
127 			for(s=1; s>=0; s--) {
128 				standt(s);
129 				for(i=0; i<6; i++) {
130 					if((a = (new[i]^old[i])&(s ? new : old)[i]) != 0) {
131 						for(j=0,t=1<<26; t; t>>=1,j++) {
132 							if(a&t) {
133 								if(!(a&(t<<1))) {
134 									movto(YBASE + i, XBASE + 2*j);
135 								}
136 								addstr("  ");
137 							}
138 						}
139 					}
140 					if(!s) {
141 						old[i] = new[i];
142 					}
143 				}
144 				if(!s) {
145 					refresh();
146 				}
147 			}
148 		}
149 		movto(6, 0);
150 		refresh();
151 		sleep(1);
152 		if (sigtermed) {
153 			standend();
154 			clear();
155 			refresh();
156 			endwin();
157 			fprintf(stderr, "grdc terminated by signal %d\n", sigtermed);
158 			exit(1);
159 		}
160 	} while(--n);
161 	standend();
162 	clear();
163 	refresh();
164 	endwin();
165 	return(0);
166 }
167 
168 void
169 set(int t, int n)
170 {
171 int i, m;
172 
173 	m = 7<<n;
174 	for(i=0; i<5; i++) {
175 		next[i] |= ((disp[t]>>(4-i)*3)&07)<<n;
176 		mask |= (next[i]^old[i])&m;
177 	}
178 	if(mask&m)
179 		mask |= m;
180 }
181 
182 void
183 standt(int on)
184 {
185 	if (on) {
186 		if(hascolor) {
187 			attron(COLOR_PAIR(1));
188 		} else {
189 			attron(A_STANDOUT);
190 		}
191 	} else {
192 		if(hascolor) {
193 			attron(COLOR_PAIR(2));
194 		} else {
195 			attroff(A_STANDOUT);
196 		}
197 	}
198 }
199 
200 void
201 movto(int line, int col)
202 {
203 	move(line, col);
204 }
205 
206