diff options
author | cperciva <cperciva@FreeBSD.org> | 2015-10-02 10:08:11 +0000 |
---|---|---|
committer | cperciva <cperciva@FreeBSD.org> | 2015-10-02 10:08:11 +0000 |
commit | 8cc71b38c27f2be8ba4c227078a51c63847a89de (patch) | |
tree | 0bbcb3f392def57bae56978c0da09362f7d6b426 /usr.bin/grdc | |
parent | 0c2e89c50542aa374d776ce0787b4a06e0de1be2 (diff) | |
download | FreeBSD-src-8cc71b38c27f2be8ba4c227078a51c63847a89de.zip FreeBSD-src-8cc71b38c27f2be8ba4c227078a51c63847a89de.tar.gz |
Final step of eliminating the "games" distribution: Merge src/games
(or what's left of it, at least) into src/usr.bin.
This change will not be MFCed.
Discussed at: EuroBSDCon 2014
Committed from: EuroBSDCon 2015
Diffstat (limited to 'usr.bin/grdc')
-rw-r--r-- | usr.bin/grdc/Makefile | 8 | ||||
-rw-r--r-- | usr.bin/grdc/Makefile.depend | 19 | ||||
-rw-r--r-- | usr.bin/grdc/grdc.6 | 33 | ||||
-rw-r--r-- | usr.bin/grdc/grdc.c | 273 |
4 files changed, 333 insertions, 0 deletions
diff --git a/usr.bin/grdc/Makefile b/usr.bin/grdc/Makefile new file mode 100644 index 0000000..73d395a --- /dev/null +++ b/usr.bin/grdc/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= grdc +MAN= grdc.6 +DPADD= ${LIBNCURSESW} +LDADD= -lncursesw + +.include <bsd.prog.mk> diff --git a/usr.bin/grdc/Makefile.depend b/usr.bin/grdc/Makefile.depend new file mode 100644 index 0000000..59bc828 --- /dev/null +++ b/usr.bin/grdc/Makefile.depend @@ -0,0 +1,19 @@ +# $FreeBSD$ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + gnu/lib/libgcc \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/ncurses/ncursesw \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.bin/grdc/grdc.6 b/usr.bin/grdc/grdc.6 new file mode 100644 index 0000000..5226a6b --- /dev/null +++ b/usr.bin/grdc/grdc.6 @@ -0,0 +1,33 @@ +.\" $FreeBSD$ +.Dd September 25, 2001 +.Dt GRDC 6 +.Os +.Sh NAME +.Nm grdc +.Nd grand digital clock (curses) +.Sh SYNOPSIS +.Nm +.Op Fl st +.Op Ar n +.Sh DESCRIPTION +.Nm +runs a digital clock made of reverse-video blanks on a curses +compatible VDU screen. +With an optional numeric argument +.Ar n +it stops after +.Ar n +seconds (default never). +The optional +.Fl s +flag makes digits scroll as they change. +The optional +.Fl t +flag tells grdc to output the time in a 12-hour format. +In this curses mode implementation, +the scrolling option has trouble keeping up. +.Sh AUTHORS +.An -nosplit +.An Amos Shapir , +modified for curses by +.An John Lupien . diff --git a/usr.bin/grdc/grdc.c b/usr.bin/grdc/grdc.c new file mode 100644 index 0000000..04cc00b --- /dev/null +++ b/usr.bin/grdc/grdc.c @@ -0,0 +1,273 @@ +/* + * Grand digital clock for curses compatible terminals + * Usage: grdc [-st] [n] -- run for n seconds (default infinity) + * Flags: -s: scroll + * -t: output time in 12-hour format + * + * + * modified 10-18-89 for curses (jrl) + * 10-18-89 added signal handling + * + * modified 03-25-03 for 12 hour option + * - Samy Al Bahra <samy@kerneled.com> + * + * $FreeBSD$ + */ + +#include <err.h> +#include <ncurses.h> +#include <signal.h> +#include <stdlib.h> +#include <time.h> +#include <unistd.h> + +#define YBASE 10 +#define XBASE 10 +#define XLENGTH 58 +#define YDEPTH 7 + +static struct timespec now; +static struct tm *tm; + +static short disp[11] = { + 075557, 011111, 071747, 071717, 055711, + 074717, 074757, 071111, 075757, 075717, 002020 +}; +static long old[6], next[6], new[6], mask; + +static volatile sig_atomic_t sigtermed; + +static int hascolor = 0; + +static void set(int, int); +static void standt(int); +static void movto(int, int); +static void sighndl(int); +static void usage(void); + +static void +sighndl(int signo) +{ + + sigtermed = signo; +} + +int +main(int argc, char *argv[]) +{ + struct timespec delay; + time_t prev_sec; + long t, a; + int i, j, s, k; + int n; + int ch; + int scrol; + int t12; + + t12 = scrol = 0; + + while ((ch = getopt(argc, argv, "ts")) != -1) + switch (ch) { + case 's': + scrol = 1; + break; + case 't': + t12 = 1; + break; + case '?': + default: + usage(); + /* NOTREACHED */ + } + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + /* NOTREACHED */ + } + + if (argc > 0) { + n = atoi(*argv) + 1; + if (n < 1) { + warnx("number of seconds is out of range"); + usage(); + /* NOTREACHED */ + } + } else + n = 0; + + initscr(); + + signal(SIGINT,sighndl); + signal(SIGTERM,sighndl); + signal(SIGHUP,sighndl); + + cbreak(); + noecho(); + curs_set(0); + + hascolor = has_colors(); + + if(hascolor) { + start_color(); + init_pair(1, COLOR_BLACK, COLOR_RED); + init_pair(2, COLOR_RED, COLOR_BLACK); + init_pair(3, COLOR_WHITE, COLOR_BLACK); + attrset(COLOR_PAIR(2)); + } + + clear(); + refresh(); + + if(hascolor) { + attrset(COLOR_PAIR(3)); + + mvaddch(YBASE - 2, XBASE - 3, ACS_ULCORNER); + hline(ACS_HLINE, XLENGTH); + mvaddch(YBASE - 2, XBASE - 2 + XLENGTH, ACS_URCORNER); + + mvaddch(YBASE + YDEPTH - 1, XBASE - 3, ACS_LLCORNER); + hline(ACS_HLINE, XLENGTH); + mvaddch(YBASE + YDEPTH - 1, XBASE - 2 + XLENGTH, ACS_LRCORNER); + + move(YBASE - 1, XBASE - 3); + vline(ACS_VLINE, YDEPTH); + + move(YBASE - 1, XBASE - 2 + XLENGTH); + vline(ACS_VLINE, YDEPTH); + + attrset(COLOR_PAIR(2)); + } + clock_gettime(CLOCK_REALTIME_FAST, &now); + prev_sec = now.tv_sec; + do { + mask = 0; + tm = localtime(&now.tv_sec); + set(tm->tm_sec%10, 0); + set(tm->tm_sec/10, 4); + set(tm->tm_min%10, 10); + set(tm->tm_min/10, 14); + + if (t12) { + if (tm->tm_hour < 12) { + if (tm->tm_hour == 0) + tm->tm_hour = 12; + mvaddstr(YBASE + 5, XBASE + 52, "AM"); + } else { + if (tm->tm_hour > 12) + tm->tm_hour -= 12; + mvaddstr(YBASE + 5, XBASE + 52, "PM"); + } + } + + set(tm->tm_hour%10, 20); + set(tm->tm_hour/10, 24); + set(10, 7); + set(10, 17); + for(k=0; k<6; k++) { + if(scrol) { + for(i=0; i<5; i++) + new[i] = (new[i]&~mask) | (new[i+1]&mask); + new[5] = (new[5]&~mask) | (next[k]&mask); + } else + new[k] = (new[k]&~mask) | (next[k]&mask); + next[k] = 0; + for(s=1; s>=0; s--) { + standt(s); + for(i=0; i<6; i++) { + if((a = (new[i]^old[i])&(s ? new : old)[i]) != 0) { + for(j=0,t=1<<26; t; t>>=1,j++) { + if(a&t) { + if(!(a&(t<<1))) { + movto(YBASE + i, XBASE + 2*j); + } + addstr(" "); + } + } + } + if(!s) { + old[i] = new[i]; + } + } + if(!s) { + refresh(); + } + } + } + movto(6, 0); + refresh(); + clock_gettime(CLOCK_REALTIME_FAST, &now); + if (now.tv_sec == prev_sec) { + if (delay.tv_nsec > 0) { + delay.tv_sec = 0; + delay.tv_nsec = 1000000000 - now.tv_nsec; + } else { + delay.tv_sec = 1; + delay.tv_nsec = 0; + } + nanosleep(&delay, NULL); + clock_gettime(CLOCK_REALTIME_FAST, &now); + } + n -= now.tv_sec - prev_sec; + prev_sec = now.tv_sec; + if (sigtermed) { + standend(); + clear(); + refresh(); + endwin(); + errx(1, "terminated by signal %d", (int)sigtermed); + } + } while (n); + standend(); + clear(); + refresh(); + endwin(); + return(0); +} + +static void +set(int t, int n) +{ + int i, m; + + m = 7<<n; + for(i=0; i<5; i++) { + next[i] |= ((disp[t]>>(4-i)*3)&07)<<n; + mask |= (next[i]^old[i])&m; + } + if(mask&m) + mask |= m; +} + +static void +standt(int on) +{ + if (on) { + if(hascolor) { + attron(COLOR_PAIR(1)); + } else { + attron(A_STANDOUT); + } + } else { + if(hascolor) { + attron(COLOR_PAIR(2)); + } else { + attroff(A_STANDOUT); + } + } +} + +static void +movto(int line, int col) +{ + move(line, col); +} + +static void +usage(void) +{ + + (void)fprintf(stderr, "usage: grdc [-st] [n]\n"); + exit(1); +} |