🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.micro.atari16
Article #531

ST Calendar Desk Accessory (SOURCE)

#531
From: Jim Tittsler
Date: Thu, 24 Apr 1986 19:19
547 lines
13886 bytes
Here is a shar file containing the source for a simple "sort of
perpetual" calendar desk accessory.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	cal.c string.c
echo x cal.c
sed 's/^X//' > cal.c << 'xEOF'
X/*
X * cal.c -- simple TOS desktop calendar accessory
X *
X *	provides a "perpetual" (well, really 1980-2009) calendar page display
X *	uses vertical scroll bar:  arrows move by month, shaded area by year
X *
X *	link68 cal.68k=accstart,cal,string,osbind,vdibind,aesbind
X *	relmod cal
X *	ren cal.prg cal.acc (must be DESKN.ACC in early TOS)
X *
X *	- a further experiment into the realm of writing a desk accessory
X *	This was a personal experiment to learn more about desk accessories.
X *	It may be freely distributed, on an "as-is" basis.  Comments and
X *	suggestions are welcome.  This is NOT an official, supported,
X *	Atari product.  
X *	Jim Tittsler, Atari Corp.
X *
X *	15Oct85	jwt	v0.01	hacked from WATCH accessory
X *	17Jan86	jwt	v0.02	set first displayed page at OPEN time,
X *				  not init time
X *				added Day of Week string
X *	21Jan86	jwt	v0.03	use reverse video to highlight current date
X *	30Jan86	jwt	v0.04	reduce height & width of highlight in high res
X *	18Apr86	jwt	v0.05	"reopen" at same place as last close
X *	24Apr86	jwt	v1.00	distribute
X */
X
Xstatic char id[] = "@(#)CAL.ACC V1.00  jwt@atari";
X
X/* #define	DEBUG 1		*/
X/* #define	DDEVICE 2	*/
X#define	REVHIGHLIGHT 1
X
X#include "obdefs.h"
X#include "define.h"
X#include "gemdefs.h"
X#include "osbind.h"
X
X#define WI_KIND		(MOVER|CLOSER|NAME|UPARROW|DNARROW|VSLIDE)
X
X#define NO_WINDOW (-1)
X
X#define	AR_UPPG		0
X#define	AR_DNPG		1
X#define	AR_UPLN		2
X#define	AR_DNLN		3
X
X#define	STRINGWIDTH	22
X#define	BLANKSTRING	"                      "
X#define	CALLINES	8
X#define	DAYOFWEEKSTRING	" Sn  M Tu  W Th  F Sa "
X#define LENDOWS		STRINGWIDTH
X
X#define	YEAROFFSET	1980
X#define	BASEYEAR	1980
X#define	CALLEN		30
X#define	LASTYEAR	(BASEYEAR+CALLEN-1)
X
X#define MIN_WIDTH  (STRINGWIDTH*gl_wchar)
X#define MIN_HEIGHT (CALLINES*gl_hchar+1)
X
X#define	INIT_X		100
X#define	INIT_Y		50
X#define	INIT_WIDTH	MIN_WIDTH
X#define	INIT_HEIGHT	MIN_HEIGHT
X
Xextern int	gl_apid;
X
Xint	year,month,day;
Xint	curyr,curmo,curday;
X
Xint	initx = INIT_X;
Xint	inity = INIT_Y;
X
Xint	lastdate = -1;	/* last DOS date */
Xint	washighlighted;
Xint	hires;		/* 1 if in high resolution */
Xchar	dtoabuf[10];
Xchar	calstring[CALLINES][(STRINGWIDTH+1)];
Xchar	*months[]= {"January", "February", "March", "April",
X		"May", "June", "July", "August",
X		"September", "October", "November", "December"};
Xint	daypermon[]= {31, 28, 31, 30,
X		31, 30, 31, 31,
X		30, 31, 30, 31};
X
Xint	gl_hchar;
Xint	gl_wchar;
Xint	gl_wbox;
Xint	gl_hbox;	/* system sizes */
X
Xint	menu_id ;	/* our menu id */
X
Xint 	phys_handle;	/* physical workstation handle */
Xint 	handle;		/* virtual workstation handle */
Xint	wi_handle;	/* window handle */
Xint	top_window;	/* handle of topped window */
X
Xint	xwork,ywork,hwork,wwork;	/* work area */
X
Xint	msgbuff[8];	/* event message buffer */
Xint	keycode;	/* keycode returned by event-keyboard */
Xint	mx,my;		/* mouse x and y pos. */
Xint	ret;		/* dummy return variable */
X
Xint	hidden;		/* current state of cursor */
X
Xint	contrl[12];
Xint	intin[128];
Xint	ptsin[128];
Xint	intout[128];
Xint	ptsout[128];	/* storage wasted for idiotic bindings */
X
Xint work_in[11];	/* Input to GSX parameter array */
Xint work_out[57];	/* Output from GSX parameter array */
Xint pxyarray[10];	/* input point array */
X
X/*page*/
Xchar *dtoa( i, fwidth ) register int i,fwidth; {
Xregister char *ptr,*lptr;
Xregister int cnt;
Xchar tbuf[6];
X
X	ptr = dtoabuf;
X
X	if (i < 0) {
X		*ptr++ = '-';
X		--fwidth;
X		i = -i;
X	}
X
X	lptr = tbuf;
X	cnt = 0;
X
X	do {
X		*lptr++ = (i % 10)+0x30;
X		++cnt;
X	} while ( (i /= 10) && (cnt<fwidth) );
X
X	if (i)	/* did we exceed the field width? */
X		for(cnt=0; cnt<fwidth; ++cnt) *ptr++ = '*';
X	else {
X		for(i=0; i<(fwidth-cnt); ++i) *ptr++ = ' ';
X		while(cnt--) *ptr++ = *--lptr;
X	}
X
X	*ptr='\0';	/* null terminate the string */
X
X	return dtoabuf;
X}
X
X/*page*/
Xhide_mouse()
X{
X	if(! hidden){
X		graf_mouse(M_OFF,0x0L);
X		hidden=TRUE;
X	}
X}
X
Xshow_mouse()
X{
X	if(hidden){
X		graf_mouse(M_ON,0x0L);
X		hidden=FALSE;
X	}
X}
X
Xopen_vwork() {
Xint i;
X	for(i=0;i<10;work_in[i++]=1);
X	work_in[10]=2;		/* use device coordinates */
X	handle=phys_handle;
X	v_opnvwk(work_in,&handle,work_out);
X}
X
Xset_clip(x,y,w,h) int x,y,w,h; {
Xint clip[4];
X	clip[0]=x;
X	clip[1]=y;
X	clip[2]=x+w-1;
X	clip[3]=y+h-1;
X	vs_clip(handle,1,clip);
X}
X
Xopen_window() {
Xint xbord,ybord,wbord,hbord;
X
X	wind_calc(WC_BORDER,WI_KIND,	/* WC_BORDER */
X		initx,inity,INIT_WIDTH,INIT_HEIGHT,
X		&xbord, &ybord, &wbord, &hbord);
X	wi_handle=wind_create(WI_KIND,xbord,ybord,
X		wbord,hbord);
X	wind_set(wi_handle, WF_NAME," CALENDAR ",0,0);
X	wind_set(wi_handle, WF_VSLSIZE, -1, 0, 0, 0);
X	wind_set(wi_handle, WF_VSLIDE,
X		(int)((1000L*((year-BASEYEAR)*12L+month))/(CALLEN*12)),0,0,0);
X	graf_growbox(0,0,gl_wbox,gl_hbox,
X		xbord,ybord,wbord,hbord);
X	wind_open(wi_handle,xbord,ybord,
X		wbord,hbord);
X	wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
X}
X
Xdo_redraw(complete,xc,yc,wc,hc)
Xint complete;
Xint xc,yc,wc,hc;
X{
XGRECT t1,t2;
X
X	hide_mouse();
X	wind_update(TRUE);
X	t2.g_x=xc;
X	t2.g_y=yc;
X	t2.g_w=wc;
X	t2.g_h=hc;
X	wind_get(wi_handle,WF_FIRSTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
X	while (t1.g_w && t1.g_h) {
X	  if (rc_intersect(&t2,&t1)) {
X	    set_clip(t1.g_x,t1.g_y,t1.g_w,t1.g_h);
X	    draw_calendar(complete);
X	  }
X	  wind_get(wi_handle,WF_NEXTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
X	}
X	wind_update(FALSE);
X	show_mouse();
X}
X
X/*page*/
Xmain() {
Xlong ikbdtime;
X
X	appl_init();
X	phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
X	gl_hchar++;
X	menu_id=menu_register(gl_apid,"  Calendar");
X
X	/* use the ikbd's version of time if it looks valid */
X	/* i.e., month is nonzero */
X	if((ikbdtime = Gettime()) &0x01E00000L) {
X		Tsetdate((int)(ikbdtime>>16));
X		Tsettime((int)(ikbdtime&0xFFFFL));
X	}
X	wi_handle=NO_WINDOW;
X	hidden=FALSE;
X
X	hires = (Getrez() == 2);	/* hires = 1 if in high res */
X	multi();
X}
X
X/*page*/
Xmulti()
X{
Xint event;
X#ifdef DEBUG
Xint idebug;
X#endif
X
X      while (TRUE) {
X	event = evnt_multi(MU_MESAG | MU_KEYBD | MU_TIMER,
X			1,1,0,
X			0,0,0,0,0,
X			0,0,0,0,0,
X			msgbuff,10000,0,&mx,&my,&ret,&ret,&keycode,&ret);
X
X	if((lastdate != Tgetdate()) && (wi_handle != NO_WINDOW)){
X		lastdate = Tgetdate();
X		curday = lastdate & 0x1F;
X		curmo = (lastdate >> 5) & 0xF;
X		curyr = (lastdate >> 9)+YEAROFFSET;
X		if(((year==curyr)&&(month==curmo)) || washighlighted)
X			do_redraw(FALSE,xwork,ywork,wwork,hwork);
X	}
X
X	wind_update(TRUE);
X	wind_get(wi_handle,WF_TOP,&top_window,&ret,&ret,&ret);
X
X	if (event & MU_MESAG) {
X#ifdef DEBUG
X	  putsaux("Message: ");
X	  for (idebug=0; idebug<8; ++idebug) {
X		putdaux(msgbuff[idebug]);
X		putcaux(' ');
X	  }
X	  putcaux(0x0D); putcaux(0x0A);
X#endif
X
X	  switch (msgbuff[0]) {
X
X	  case WM_REDRAW:
X	    if (msgbuff[3] == wi_handle)
X	      do_redraw(TRUE,msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
X	    break;
X
X	  case WM_NEWTOP:
X	  case WM_TOPPED:
X	    if (msgbuff[3] == wi_handle){
X	      wind_set(wi_handle,WF_TOP,0,0,0,0);}
X	    break;
X
X	  case AC_CLOSE:
X	    if((msgbuff[3] == menu_id)&&(wi_handle != NO_WINDOW)){
X	      v_clsvwk(handle);
X	      wi_handle = NO_WINDOW;
X	    }
X	    break;
X
X	  case WM_CLOSED:
X	    if(msgbuff[3] == wi_handle){
X	      wind_close(wi_handle);
X	      graf_shrinkbox(0,0,gl_wbox,gl_hbox,xwork,ywork,wwork,hwork);
X	      wind_delete(wi_handle);
X	      v_clsvwk(handle);
X	      wi_handle = NO_WINDOW;
X	    }
X	    break;
X
X	  case WM_MOVED:
X	    if(msgbuff[3] == wi_handle){
X		wind_set(wi_handle,WF_CURRXYWH,
X			msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
X		wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
X		initx = xwork;  inity = ywork;
X	    }
X	    break;
X
X	  case AC_OPEN:
X	    if (msgbuff[4] == menu_id){
X	      if(wi_handle == NO_WINDOW){
X
X		if (lastdate != Tgetdate()){
X		  lastdate = Tgetdate();
X		  curday = day = lastdate & 0x1F;
X		  curmo = month = (lastdate >> 5) & 0xF;
X		  curyr = year = (lastdate >> 9)+YEAROFFSET;
X		  makecalpage(year, month, day);
X		}
X		open_vwork();
X	        open_window();
X	      }
X	      else	/* if already opened, for user convenience */
X	        wind_set(wi_handle,WF_TOP,0,0,0,0);
X	    }
X	    break;
X
X	  case WM_ARROWED:
X	    switch(msgbuff[4]){
X		case AR_UPLN:  if(--month) break;
X				month=12;
X				if(--year<BASEYEAR) {
X					year = BASEYEAR;
X					month = 1;
X				}
X				break;
X		case AR_UPPG:  if(--year<BASEYEAR) year = BASEYEAR; break;
X		case AR_DNLN:  if(++month<13) break;
X				month=1;
X				if(++year>LASTYEAR) {
X					year = LASTYEAR;
X					month = 12;
X				}
X				break;
X		case AR_DNPG:  if(++year>LASTYEAR) year = LASTYEAR; break;
X	    } /* switch(msgbuff[4]) */
X	    makecalpage(year,month,-1);
X	    do_redraw(FALSE,xwork,ywork,wwork,hwork);
X	    wind_set(wi_handle, WF_VSLIDE,
X		(int)((1000L*((year-BASEYEAR)*12L+month))/(CALLEN*12)),0,0,0);
X	    break;
X
X	  case WM_VSLID:
X	    wind_set(wi_handle, WF_VSLIDE, msgbuff[4], 0, 0, 0);
X	    month = (int)(((long)msgbuff[4]*(CALLEN*12-1))/1000L);
X	    year = (month/12)+BASEYEAR;
X	    month = (month % 12)+1;
X	    makecalpage(year,month,-1);
X	    do_redraw(FALSE,xwork,ywork,wwork,hwork);
X	    break;
X
X	  } /* switch (msgbuff[0]) */
X	}
X
X	wind_update(FALSE);
X
X      } /* while (TRUE) */
X
X}
X
Xdraw_calendar(complete) int complete; {
Xint temp[4];
Xint i;
X
X	if (complete || washighlighted){
X		vsf_interior(handle,1);		/* solid */
X		vsf_color(handle,0);
X		temp[0]=xwork;
X		temp[1]=ywork;
X		temp[2]=xwork+wwork-1;
X		temp[3]=ywork+hwork-1;
X		v_bar(handle,temp);		/* blank the interior */
X	}
X
X	vst_color(handle, 1);
X
X	for(i=0; i<CALLINES; ++i)
X		v_gtext(handle, xwork, ywork+(i+1)*gl_hchar-1,
X			calstring[i]);
X
X	if((year==curyr)&&(month==curmo)){
X		i = dow(curyr,curmo,1)+curday-1;
X#ifdef REVHIGHLIGHT
X		vsf_color(handle,1);
X		temp[0]=xwork+((i%7)*3+1)*gl_wchar-2;
X		temp[1]=ywork+((i/7)+2)*gl_hchar+1+hires;
X		temp[2]=temp[0]+2*gl_wchar+3-hires;
X		temp[3]=temp[1]+gl_hchar-1-hires;
X		v_bar(handle,temp);
X		vst_color(handle, 0);
X		vswr_mode(handle, 2);
X#else /* not REVHIGHLIGHT */
X		vst_color(handle, 3);
X#endif /* REVHIGHLIGHT */
X		v_gtext(handle,xwork+((i%7)*3+1)*gl_wchar,
X			ywork+((i/7)+3)*gl_hchar-1,
X			dtoa(curday,2));
X#ifdef REVHIGHLIGHT
X		vswr_mode(handle, 1);
X#endif /* REVHIGHLIGHT */
X		washighlighted = 1;
X	} else	washighlighted = 0;
X}
X
X/*page*/
X/*
X * dow -- find the day of the week
X *	for a given yr,mon,day between Mar1900 and Dec2099
X */
Xint dow(yr, mon, day) int yr, mon, day; {
X	register int d,i;
X
X	/* find day of week of jan1 of the year of interest */
X	d = (yr+((yr+3)/4)+5) % 7;
X
X	/* find day of week for first of month */
X	for(i=1; i<mon; ++i) d += daypermon[i-1];
X
X	/* and for the given day */
X	d += day-1;
X
X	return d % 7;
X}
X
Xmakecalpage(yr, mon, day) int yr, mon, day; {
X	register int i,monlen,xpos;
X
X	daypermon[1] = (yr%4) ? 28 : 29;
X
X	--mon;	/* create index into months array */
X
X	for(i=0; i<CALLINES; ++i)
X		strcpy(calstring[i], BLANKSTRING);
X
X	monlen = strlen(months[mon]);
X
X	xpos = (STRINGWIDTH/2) - (monlen+5)/2;
X
X	strncpy(&calstring[0][xpos],months[mon],monlen);
X	strncpy(&calstring[0][xpos+monlen+1],dtoa(year,4),4);
X
X	strncpy(calstring[1], DAYOFWEEKSTRING, LENDOWS);
X
X	xpos = dow(yr, mon+1, 1);
X	for(i=1; i<=daypermon[mon]; ++i,++xpos)
X		strncpy(&calstring[xpos/7+2][3*(xpos%7)+1],
X			dtoa(i,2),2);
X}
X
X/*page*/
X#ifdef DEBUG
Xputsaux( s ) char *s; {
Xchar c;
X
X	while(c = *s++) putcaux(c);
X}
X
Xputdaux( i ) int i; {
X	int pot, leading, d;
X
X	if (i < 0) {
X		putcaux('-');
X		i = -i;
X	}
X
X	leading = 0;
X	for(pot = 10000; pot >= 1; pot /= 10) {
X		d = i/pot; i -= d*pot;
X		if (d || leading || (pot == 1)) {
X			putcaux(d+0x30);
X			leading = 1;
X		} else putcaux(' ');
X	}
X}
X
Xputcaux( c ) char c; {
X	Bconout(DDEVICE, c);
X}
X#endif
xEOF
echo x string.c
sed 's/^X//' > string.c << 'xEOF'
Xstrcpy(s1,s2) register char *s1,*s2; {
X
X	while (*s1++ = *s2++);
X
X}
X
Xstrncpy(s1, s2, n) register char *s1,*s2; register int n; {
X	register char c;
X
X	while((c = *s2++) && n--) *s1++ = c;
X
X	while(n--) *s1++ = '\0';	/* NULL fill */
X}
X
Xint strlen(s1) register char *s1; {
X	register int length;
X
X	length = 0;
X
X	while(*s1++) ++length;
X
X	return length;
X}
xEOF
----
Jim Tittsler, Atari Corp  lll-crg!vecpyr!atari!jwt
Technical Details
Message-ID: <210@atari.UUcp>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!allegra!princeton!orsvax1!pyrnj!caip!topaz!lll-crg!lll-lcc!vecpyr!atari!jwt

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!burl!ulysses!allegra!princeton!orsvax1!pyrnj!caip!topaz!lll-crg!lll-lcc!vecpyr!atari!jwt
From: jwt@atari.UUcp (Jim Tittsler)
Newsgroups: net.micro.atari16
Subject: ST Calendar Desk Accessory (SOURCE)
Message-ID: <210@atari.UUcp>
Date: Thu, 24-Apr-86 15:19:24 EDT
Article-I.D.: atari.210
Posted: Thu Apr 24 15:19:24 1986
Date-Received: Sun, 27-Apr-86 06:32:48 EDT
Organization: Atari Corp., Sunnyvale, CA
Lines: 547
Keywords: ST Accessory