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