[net.micro.amiga] menu bar clock + memory monitor

mwm@eris.berkeley.edu (Mike Meyer) (09/28/86)

This is an improved version of my menu bar clock. Enhancements are:

	1) Display #k of CHIP and FAST memory free.
	2) Update display MUCH more frequently so those are more usefull.
	3) Seconds added to clock (since we're interrupting so often).
	4) Raise priority to 20 so that it's *really* correct.


	<mike

/*
 * clock - a dumb, digital clock in the upper right-hand corner. Designed
 *	to be small, not flexible!
 *
 * Copyright (c) 1986, Mike Meyer
 *
 * Permission is hereby granted to distribute this program for any purposes
 * whatsoever, so long as this notice, including the above copyright, is
 * included with the distribution. Unlike other people, I don't care if you
 * make money off of this, so long as I get credit for having written it.
 */

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <devices/timer.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>

#include <stdio.h>

#define INTUITION_REV	1
/*
 * Things to tweak:
 *	WIN_WIDTH - the width of the window output screen. Should be 369.
 *	WAIT_TIME - how long to wait between updates. Also the maximum
 *		mis-time you can get.  Finally, it's the longest period of
 *		time you have to put up with the clock broken. Measured in
 *		micro-seconds.
 */
#define	WIN_WIDTH	369
#define WAIT_TIME	250000

static struct NewWindow	New_Window = {
	(590 - WIN_WIDTH), 0,	/* Upper right, out of the way */
	WIN_WIDTH, 10,		/* Just big enough for the time */
	-1, -1,			/* Default pens */
	CLOSEWINDOW,		/* All we care about is closing */
	WINDOWCLOSE		/* Borderless, fairly standard window */
	| WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH,
	(struct Gadget *) NULL,
	(struct Image *) NULL,
	"",			/* Empty title */
	(struct Screen *) NULL,
	(struct BitMap *) NULL,
	0, 0, 0, 0,		/* no change sizes, doesn't matter */
	WBENCHSCREEN		/* Of course! */
	} ;

static char	Date_Buffer[40] ;	/* Now you know where the time goes! */

static struct IntuiText	Date_Text = {
	1, 0,				/* Use the standard pen colors */
	JAM2,				/* Use both of them */
	0, 0,				/* in the upper left-hand corner */
	(struct TextAttr *) NULL,	/* Use default text */
	Date_Buffer,			/* Buffer for time */
	(struct IntuiText *) NULL	/* All of text */
	} ;

struct IntuitionBase	*IntuitionBase ;

/*
 * Some things that need to be shared with done.
 */
static struct Window		*Window = NULL ;
static struct timerequest	Time_Req ;
static struct MsgPort		*Timer_Port = NULL, *CreatePort() ;
#ifdef	DEBUG
static short			cli = FALSE ;
#endif

#ifdef	DEBUG
main(argc, argv) int argc; char *argv; {
#else
_main() {
#endif
	register short		hours, minutes ;
	register short		chip_free, fast_free ;
	struct DateStamp	now ;
	struct IntuiMessage	*Msg, *GetMsg() ;
	struct Task		*FindTask() ;
	ULONG			AvailMem() ;

#ifdef	DEBUG
	if (argc) cli = TRUE ;
#endif
	if ((IntuitionBase = (struct IntuitionBase *)
	    OpenLibrary("intuition.library", INTUITION_REV)) == NULL)
		done(20, "Can't open Intuition library") ;

	if ((Timer_Port = CreatePort("Timer Port", 0)) == NULL)
		done(20, "Can't create timer port") ;

	if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Time_Req, 0) != NULL)
		done(20, "Can't open timer device") ;
	Time_Req . tr_node . io_Message . mn_ReplyPort = Timer_Port ;
	Time_Req . tr_node . io_Command = TR_ADDREQUEST ;
	Time_Req . tr_node . io_Flags = 0 ;
	Time_Req . tr_node . io_Error = 0 ;

	if ((Window = (struct Window *) OpenWindow(&New_Window)) == NULL)
		done(20, "Can't open window") ;
	
	/* Nudge me up to high priority */
	(void) SetTaskPri(FindTask((char *) 0), 20) ;

	for (;;) {
		DateStamp(&now) ;
		chip_free = AvailMem(MEMF_CHIP) >> 10;
		fast_free = AvailMem(MEMF_FAST) >> 10;
		hours = now . ds_Minute / 60 ;
		minutes = now . ds_Minute % 60 ;
		/* Oh, this hurts. But stdio, here we come.... */
		sprintf(Date_Buffer, " Chip:%3d  Fast:%4d  Time:%2d:%02d:%02d ",
					chip_free, fast_free, hours, minutes ,
					now . ds_Tick / TICKS_PER_SECOND) ;

		PrintIText(Window -> RPort, &Date_Text, 28, 1) ;

		Time_Req . tr_time . tv_secs = 0 ;
		Time_Req . tr_time . tv_micro = WAIT_TIME ;
		SendIO((char *) &Time_Req . tr_node) ;
		Wait(1 << Window -> UserPort -> mp_SigBit
		   | 1 << Timer_Port -> mp_SigBit) ;

		while (Msg = GetMsg(Window -> UserPort)) {
			if (Msg -> Class == CLOSEWINDOW) {
				ReplyMsg(Msg) ;
				done(0, "exit") ;
				}
			ReplyMsg(Msg) ;
			}

		(void) GetMsg(Timer_Port) ;
		}
	/* NOTREACHED */
	}
/*
 * done - just clean up that which is open, and then leave.
 */
done(how, why) int how; char *why; {

	AbortIO((char *) &Time_Req . tr_node) ;
	if (Window) CloseWindow(Window) ;
	if (Time_Req . tr_node . io_Message . mn_ReplyPort)
		CloseDevice(&Time_Req) ;
	if (Timer_Port) DeletePort(Timer_Port) ;
	if (IntuitionBase) CloseLibrary(IntuitionBase) ;
#ifdef	DEBUG
	if (cli) printf("clock: %s\n", why) ;
#endif

	OpenWorkBench() ;			/* As requested */
	exit(how) ;
	}