[net.sources] Vtclock program for your VT100

espo@bpa.UUCP (11/23/83)

	Here's a nifty little program(s) to display the date & time of
	day on the screen of your VT100 terminal on a real-time basis.


	Although I've written it for a VT100, I'm sure those of you who
	have different terminals could modify it.  The only thing that's
	required, is that the terminal has a cursor save function
	within it's command repertoire.

	The swc.c program included is use to switch the clock display
	on/off for those times when you don't want the display, but
	keeps the clock running until switched back on.


	Bob Esposito....bpa!espo

/*
****************************************************************************
**
**	program = vtclock.c
**
**	 author = R.J. Esposito
**
**	Vtclock provides a visual clock display every minute on
**	a real-time basis.  The display is visable in the lower
**	right-hand corner (row 24, col 56-80) of the screen.
**	Vtclock could be modified to perform on other video
**	terminals, provided they incorporate the cursor save
**	function within their command repertoire.
**
**	Vtclock should be called from the user's .profile for
**	conveinence, but could be called from the shell.
**	It should be run as a backround process, since cursor
**	saving is done prior to clock display.
**
**	An interface program 'swc.c' is used to switch the display
**	on/off depending on it's previous state.  Vtclock saves it's
**	pid in the user's home directory in '.clock_pid'.  Swc reads
**	this file to send the SIGUSR1 (16) signal to vtclock for
**	display switching.  This file is removed when vtclock dies
**	(SIGHUP).
**
**	NOTE:  Some strange things may occur when emacs is used in
**	       conjunction with vtclock.  It may be wise to turn off
**	       the display (swc) prior to entering emacs, and then
**	       turning it back on (swc) after completion.  If you're
**	       a die-hard (like me!) just use the ^L to re-draw the
**	       display.
**
****************************************************************************
*/

#include <stdio.h>
#include <time.h>
#include <sys/signal.h>

#define SCROLL	"\33[0;23r"	/* set the scroll region (0 to 23) */
#define WINDOW	"\33[0m\33[24;56f\33[7m                         \33[24;59f"
#define SAVE	"7"		/* save cursor = ESC7 */
				/* This MUST be typed-in from keyboard */
#define RESTORE	"\338"		/* restore cursor */
#define CLWIN	"\33[0m\33[24;56f                         "
#define ATT_OFF	"\33[0m"

struct tm *localtime(), *tp;

char *asctime();
char *getenv();
char *strcpy(), *strcat();
char pid_file[100];

long time(), tloc;
unsigned sleep();
int (*signal())();
int die(), on_off(), pm;
int is_on = 1;

FILE *fp;

main()
{
	unsigned sec_diff;

	setbuf(stdout, (char *)0);
	(void )strcpy(pid_file, getenv("HOME"));
	(void )strcat(pid_file, "/.clock_pid");

	if((fp=fopen(pid_file, "w")) == NULL) {
		(void )puts("can't open clocl_pid");
		exit(1);
	}

	(void )fprintf(fp, "%d\n", getpid());
	(void )fclose(fp);

	(void )signal(SIGHUP, die);
	tloc = time ((long *)0);
	tp = localtime(&tloc);

	fixtime(tp->tm_hour);

	(void )printf("%s%s%16.16s", SAVE, WINDOW, asctime(tp));
	if (pm)
		(void )fputs(" PM", stdout);
	else
		(void )fputs(" AM", stdout);

	(void )printf("%s%s%s", SCROLL, ATT_OFF, RESTORE);
	(void )signal(SIGUSR1, on_off);

	for (;;) {	/* forever loop until hung-up */

		tp = localtime(&tloc);
		sec_diff = 60 - tp->tm_sec;
		(void )sleep(sec_diff);
		tloc = time((long *)0);
		tp = localtime(&tloc);

		fixtime(tp->tm_hour);

		if (is_on) {
			if (tp->tm_min == 00)	/* hourly chime */
				(void )fputs("\7\7", stdout);

			(void )printf("%s%s%16.16s", SAVE, WINDOW, asctime(tp));
			if (pm)
				(void )fputs(" PM", stdout);
			else
				(void )fputs(" AM", stdout);

			(void )printf("%s%s%s", SCROLL, ATT_OFF, RESTORE);
		}
	}
}

die()	/* enter here when hung-up */
{

	(void )unlink(pid_file);
	exit(0);
}

on_off()	/* routine used by swc to switch display on/off */
{

	if (is_on) {
		is_on = 0;
		(void )printf("%s%s\33[0;24r%s", SAVE, CLWIN, RESTORE);
	} else 
		is_on = 1;
	(void )signal(SIGUSR1, on_off);
}

fixtime(hour)
int hour;
{

	switch(hour) {		/* correct for AM/PM */

		case 0:
			tp->tm_hour = 12;
			pm = 0;
			break;

		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
		case 6:
		case 7:
		case 8:
		case 9:
		case 10:
		case 11:
			pm = 0;
			break;

		case 12:
			pm = 1;
			break;

		case 13:
		case 14:
		case 15:
		case 16:
		case 17:
		case 18:
		case 19:
		case 20:
		case 21:
		case 22:
		case 23:
			tp->tm_hour -= 12;
			pm = 1;
			break;
	}
}



/*
****************************************************************************
**
**	program = swc.c
**
**	 author = R.J. Esposito
**
**	Swc is an interface to vtclock - it switches the display on/off
**	depending on it's previous state.
**
****************************************************************************
*/

#include <stdio.h>

FILE *fp;

char pid_file[100];
char *strcpy(), *strcat();
char *getenv();

main()
{
	char *pid;

	(void )strcpy(pid_file, getenv("HOME"));
	(void )strcat(pid_file, "/.clock_pid");

	if((fp=fopen(pid_file, "r")) == NULL)
		exit(1);;

	pid = fgets(pid_file, 100, fp);

	(void )kill (atoi(pid), 16);	/* send SIGUSR1 to vtclock */
	(void )fclose(fp);
}