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