/* JPClock - © Copyright 1989 by Jonathan Potter This is my first, fully functional program written under Lattice C v5.02 Anyone ever tried converting Manx code to Lattice? yuk... */ /* This program is Public Domain; do with it what you will, but if you choose to sell it, at least leave my name in it. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "JPClock.i" /* lsr info */ long _stack=4000; char *_procname="JPClock"; long _priority=0; long _BackGroundIO=1; extern BPTR _Backstdout; /* gadget ids */ #define SWAPSCREENS 1 #define STAYFRONT 2 #define ALARM 3 #define TIME 4 #define ALARMTIME 5 #define DATE 6 char TextBuffer[56]; char TimeBuffer[9], DateBuffer[9], AlarmBuffer[9]="00:00:00"; /* the font we'll use if default > 8 point */ struct TextAttr TopazText={ "topaz.font",8,0,0}; /* where all the text goes */ struct IntuiText TextPrint={ 1,0,JAM2,0,0,NULL,TextBuffer,NULL}; short SXYBorder[]={ -1,-1,72,-1,72,8,-1,8,-1,-1}; struct Border SBorder={ 0,0,3,0,JAM1,5,SXYBorder,NULL}; struct StringInfo TimeStringInfo={ TimeBuffer,NULL,0,9,0}; struct StringInfo DateStringInfo={ DateBuffer,NULL,0,9,0}; struct StringInfo AlarmStringInfo={ AlarmBuffer,NULL,0,9,0}; struct IntuiText TimeStringText={ 1,0,JAM2,-35,0,NULL,(UBYTE *)"TIME",NULL}; struct IntuiText AlarmStringText={ 1,0,JAM2,-43,0,NULL,(UBYTE *)"ALARM",NULL}; struct IntuiText DateStringText={ 1,0,JAM2,-35,0,NULL,(UBYTE *)"DATE",NULL}; struct Gadget TimeStringGadget={ NULL,123,15,72,8,GADGHCOMP,TOGGLESELECT|RELVERIFY,STRGADGET, (APTR)&SBorder,NULL,&TimeStringText,NULL,(APTR)&TimeStringInfo,TIME,NULL}; struct Gadget DateStringGadget={ &TimeStringGadget,238,15,72,8,GADGHCOMP,TOGGLESELECT|RELVERIFY,STRGADGET, (APTR)&SBorder,NULL,&DateStringText,NULL,(APTR)&DateStringInfo,DATE,NULL}; struct Gadget AlarmStringGadget={ &DateStringGadget,361,15,72,8,GADGHCOMP,TOGGLESELECT|RELVERIFY,STRGADGET, (APTR)&SBorder,NULL,&AlarmStringText,NULL,(APTR)&AlarmStringInfo,ALARMTIME,NULL}; short GXYBorder[]={ -1,-1,100,-1,100,11,-1,11,-1,-1}; struct Border GBorder={ 0,0,3,0,JAM1,5,GXYBorder,NULL}; struct IntuiText AlarmText={ 1,0,JAM2,14,2,NULL,(UBYTE *)"Alarm On",NULL}; struct Gadget AlarmGadget={ &AlarmStringGadget,325,30,100,11,GADGHCOMP,RELVERIFY|TOGGLESELECT,BOOLGADGET, (APTR)&GBorder,NULL,&AlarmText, NULL,NULL,ALARM,NULL}; struct IntuiText StayFrontText={ 1,0,JAM2,10,2,NULL,(UBYTE *)"Stay Front",NULL}; struct Gadget StayFrontGadget={ &AlarmGadget,215,30,100,11,GADGHCOMP,RELVERIFY|TOGGLESELECT,BOOLGADGET, (APTR)&GBorder,NULL,&StayFrontText, NULL,NULL,STAYFRONT,NULL}; struct IntuiText SwapScreensText={ 1,0,JAM2,2,2,NULL,(UBYTE *)"Swap Screens",NULL}; struct Gadget SwapScreensGadget={ &StayFrontGadget,105,30,100,11,GADGHCOMP,RELVERIFY,BOOLGADGET, (APTR)&GBorder,NULL,&SwapScreensText, NULL,NULL,SWAPSCREENS,NULL}; struct NewWindow ClockWindow={ 86,0,504,10,-1,-1,CLOSEWINDOW|MOUSEBUTTONS|NEWSIZE|GADGETUP|INACTIVEWINDOW, WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH|NOCAREREFRESH|RMBTRAP, &SwapScreensGadget,NULL,"",NULL,NULL,0,0,0,110,CUSTOMSCREEN}; struct IntuitionBase *IntuitionBase; struct IntuiMessage *Msg; struct Window *Window; struct timerequest TimeReq; struct MsgPort *TimerPort; void main(argc,argv) int argc; char *argv[]; { /* heaps of variables, aren't there ? */ register short Chip, Fast, Total; int dy, mn, yr, sizeflag=0, GadgetID, ScreenHeight, ScreenWidth, delay=1, al, StayFront=0, Alarm=0, a, b, c, USA=0, Swap=0, j, x, y, AlarmSet=0, AE, DTime=1, DDay=1, DDate=1, DFast=1, DChip=1, DTotal=1, TwelveHour=0, message; char d[8], Date[9], Time[9], buf[15], ch; char *Day[7]={ "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; struct Gadget *Gad; struct Screen *NextScreen; /* was I run from CLI? */ if (_Backstdout) { /* yup */ if ((strncmp(argv[1],"?",1))==0) { /* need some help */ Write(_Backstdout,"\n",-1); Write(_Backstdout,"\x9B;0;1;2mJPClock\x9B;0;1m © Copyright 1989 by \x9B;0;1;33;4mJonathan Potter\x9B;0;1m (08-293-2788)\x9B;0m\n",-1); Write(_Backstdout,"\n\x9B;0;33mThe ultimate Workbench clock!\x9B;0m\n\n",-1); Write(_Backstdout,"Usage : JPClock [FLAGS]\n\nFlags are:\n\n",-1); Write(_Backstdout," -a : Set Alarm on\n",-1); Write(_Backstdout," -atALARMTIME : Set Alarm time to ALARMTIME (HH:MM:SS or H:MM:SSC)\n",-1); Write(_Backstdout," -dSECONDS : Set Delay between updates to SECONDS seconds\n",-1); Write(_Backstdout," -f : Set Stay Front on\n",-1); Write(_Backstdout," -ot : Turn time display off\n",-1); Write(_Backstdout," -oy : Turn day display off\n",-1); Write(_Backstdout," -od : Turn date display off\n",-1); Write(_Backstdout," -of : Turn fast memory display off\n",-1); Write(_Backstdout," -oc : Turn chip memory display off\n",-1); Write(_Backstdout," -ol : Turn total memory display off\n",-1); Write(_Backstdout," -s : Swap to second screen\n",-1); Write(_Backstdout," -u : USA format; MM-DD-YY instead of DD-MM-YY\n",-1); Write(_Backstdout," -xX : Open window with x-coordinate X\n",-1); Write(_Backstdout," -yY : Open window with y-coordinate Y\n",-1); Write(_Backstdout," -12 : Set time to 12 hours format\n",-1); /* close our output channel */ Close(_Backstdout); /* and get outahere */ exit(0); } /* close output channel.. if we don't, the cli window can never close */ Close(_Backstdout); /* let's 'ave a bo peep at our args then */ for (dy=1;dy10) delay=10; delay*=1000000; /* can't have no display; if asked for, at least show time */ if (DTime==0 && DDay==0 && DDate==0 && DFast==0 && DChip==0 && DTotal==0) DTime=1; if (DTime) { sprintf(buf," "); strcat(TextBuffer,buf); } if (DDay) { sprintf(buf," "); strcat(TextBuffer,buf); } if (DDate) { sprintf(buf," "); strcat(TextBuffer,buf); } if (DFast) { sprintf(buf," "); strcat(TextBuffer,buf); } if (DChip) { sprintf(buf," "); strcat(TextBuffer,buf); } if (DTotal) { sprintf(buf," "); strcat(TextBuffer,buf); } /* now what was that alarm time ? */ if (AlarmSet) { a=0; b=0; c=0; if (TwelveHour) { sscanf(argv[AE],"-at%d:%d:%d%c",&a,&b,&c,&ch); sprintf(AlarmBuffer,"%1d:%02d:%02d%1c",a,b,c,toupper(ch)); } else { sscanf(argv[AE],"-at%d:%d:%d",&a,&b,&c); sprintf(AlarmBuffer,"%02d:%02d:%02d",a,b,c); } } /* find out how wide window needs to be */ ClockWindow.Width=(strlen(TextBuffer)*8)+80; if (ClockWindow.LeftEdge>640-ClockWindow.Width) ClockWindow.LeftEdge=640-ClockWindow.Width; IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0); ClockWindow.Screen=(struct Screen *) IntuitionBase->FirstScreen; if (ClockWindow.TopEdge>(ClockWindow.Screen->Height-10)) ClockWindow.TopEdge=ClockWindow.Screen->Height-10; if ((Window=(struct Window *) OpenWindow(&ClockWindow))==NULL) goto bye; /* if default font is too big, use topaz 8 */ if (Window->IFont->tf_YSize>8) TextPrint.ITextFont=&TopazText; if ((TimerPort=CreatePort("Timer Port",0))==NULL) goto bye; if (OpenDevice(TIMERNAME,UNIT_VBLANK,&TimeReq,0)!=NULL) goto bye; /* set up timer device request */ TimeReq.tr_node.io_Message.mn_ReplyPort=TimerPort; TimeReq.tr_node.io_Command=TR_ADDREQUEST; TimeReq.tr_node.io_Flags=0; TimeReq.tr_node.io_Error=0; TimeReq.tr_time.tv_secs=0; TimeReq.tr_time.tv_micro=delay; SendIO((char *) &TimeReq.tr_node); /* lets go to next screen */ if (Swap==1) { NextScreen=(struct Screen *) Window->WScreen->NextScreen; if (NextScreen==NULL || NextScreen->WidthHeight<45) NextScreen=(struct Screen *) Window->WScreen; ClockWindow.Screen=NextScreen; CloseWindow(Window); Window=(struct Window *) OpenWindow(&ClockWindow); ScreenToFront(NextScreen); } /* de main loop */ FOREVER { loop: if (StayFront==1) WindowToFront(Window); /* shove to front if asked for */ Chip=AvailMem(MEMF_CHIP)>>10; /* combien memory? */ Fast=AvailMem(MEMF_FAST)>>10; Total=Chip+Fast; getclk(d); /* neat lattice function */ stpdate(Date,3,&d[1]); stptime(Time,2,&d[4]); sscanf(Date,"%d-%d-%d",&mn,&dy,&yr); if (USA==0) sprintf(Date,"%02d-%02d-%02d",dy,mn,yr); /* backwards :-) */ else sprintf(Date,"%02d-%02d-%02d",mn,dy,yr); if (TwelveHour) { ch='A'; j=d[4]; if (j>12) { j=j-12; ch='P'; } sprintf(Time,"%1d:%02d:%02d%1c",j,d[5],d[6],ch); } sprintf(buf,""); /* clear both buffers */ sprintf(TextBuffer,""); if (DTime) { sprintf(buf," %s",Time); strcat(TextBuffer,buf); } if (DDay) { sprintf(buf," %s",Day[(int)d[0]]); strcat(TextBuffer,buf); } if (DDate) { sprintf(buf," %s",Date); strcat(TextBuffer,buf); } if (DFast) { sprintf(buf," FAST:%-4d",Fast); strcat(TextBuffer,buf); } if (DChip) { sprintf(buf," CHIP:%-4d",Chip); strcat(TextBuffer,buf); } if (DTotal) { sprintf(buf," TOTAL:%-4d",Total); strcat(TextBuffer,buf); } /* print it out! */ PrintIText(Window->RPort,&TextPrint,28,1); /* check for alarm if asked */ if (Alarm==1) { if ((strncmp(Time,AlarmBuffer,8))==0) { /* alarm time! */ for (al=0;al<10;al++) { DisplayBeep(NULL); Delay(1); } } } /* got an intuimessage */ if (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) goto gotone; /* wait for a message */ message=Wait (1<UserPort->mp_SigBit | 1<mp_SigBit); /* timer message? */ if (message&1<mp_SigBit) { (void) GetMsg(TimerPort); TimeReq.tr_time.tv_secs=0; TimeReq.tr_time.tv_micro=delay; SendIO(&TimeReq.tr_node); goto loop; } /* nup, it was intui */ Msg=(struct IntuiMessage *) GetMsg(Window->UserPort); gotone: ReplyMsg((struct Message *)Msg); switch (Msg->Class) { case CLOSEWINDOW: /* bye de bye */ goto bye; break; case MOUSEBUTTONS: if (Msg->Code!=MENUDOWN) break; /* hit de right mouse button; resize */ if (sizeflag==0) { /* make it big */ ScreenHeight=Window->WScreen->Height; ScreenWidth=Window->WScreen->Width; if (Window->TopEdge+45>ScreenHeight) MoveWindow(Window,0,-((Window->TopEdge)-(ScreenHeight-45))); if (Window->LeftEdge+504>ScreenWidth) MoveWindow(Window,-((Window->LeftEdge)-(ScreenWidth-504)),0); SizeWindow(Window,(504-ClockWindow.Width),35); sizeflag=1; WaitForNewSize(); /* stupid how you have to do this */ break; } else { /* make it small */ SizeWindow(Window,-(504-ClockWindow.Width),-35); sizeflag=0; WaitForNewSize(); } break; case GADGETUP: /* a gadget! */ Gad=(struct Gadget *) Msg->IAddress; GadgetID=Gad->GadgetID; switch (GadgetID) { case SWAPSCREENS: /* go to next screen */ NextScreen=(struct Screen *) Window->WScreen->NextScreen; /* if next screen can't fit us, don't */ if (NextScreen==NULL || NextScreen->WidthHeight<45) NextScreen=(struct Screen *) Window->WScreen; ClockWindow.Screen=NextScreen; CloseWindow(Window); Window=(struct Window *) OpenWindow(&ClockWindow); ScreenToFront(NextScreen); /* and bring new screen to front */ sizeflag=0; break; case STAYFRONT: /* toggle */ if (StayFront==0) StayFront=1; else StayFront=0; break; case ALARM: /* toggle */ if (Alarm==0) Alarm=1; else Alarm=0; break; case TIME: /* set the new time */ a=0; b=0; c=0; if ((sscanf(TimeBuffer,"%d:%d:%d",&a,&b,&c))!=3 && (sscanf(TimeBuffer,"%d:%d",&a,&b))!=2 && (sscanf(TimeBuffer,"%d",&a))!=1) { /* didn't work; not entered properly */ sprintf(TimeBuffer,""); RefreshGadgets(&TimeStringGadget,Window,NULL); break; } sprintf(TimeBuffer,""); RefreshGadgets(&TimeStringGadget,Window,NULL); d[4]=a; d[5]=b; d[6]=c; chgclk(d); /* another nifty lattice thingo */ break; case DATE: /* new date */ if (USA==0) { a=d[3]; b=d[2]; c=d[1]+80; } else { a=d[2]; b=d[3]; c=d[1]+80; } if ((sscanf(DateBuffer,"%d-%d-%d",&a,&b,&c))!=3 && (sscanf(DateBuffer,"%d-%d",&a,&b))!=2 && (sscanf(DateBuffer,"%d",&a))!=1) { sprintf(DateBuffer,""); RefreshGadgets(&DateStringGadget,Window,NULL); break; } sprintf(DateBuffer,""); RefreshGadgets(&DateStringGadget,Window,NULL); if (c<80) break; if (USA==0) { d[1]=c-80; d[2]=b; d[3]=a; } else { d[1]=c-80; d[2]=a; d[3]=b; } chgclk(d); break; case ALARMTIME: /* new al. time */ a=0; b=0; c=0; if (TwelveHour) { sscanf(AlarmBuffer,"%d:%d:%d%c",&a,&b,&c,&ch); ch=toupper(ch); sprintf(AlarmBuffer,"%1d:%02d:%02d%1c",a,b,c,ch); } else { sscanf(AlarmBuffer,"%d:%d:%d",&a,&b,&c); sprintf(AlarmBuffer,"%02d:%02d:%02d",a,b,c); } RefreshGadgets(&AlarmStringGadget,Window,NULL); break; default: break; } break; default: break; } } bye: /* outahere! */ if (TimeReq.tr_node.io_Message.mn_ReplyPort) CloseDevice(&TimeReq); if (TimerPort) DeletePort(TimerPort); if (Window) CloseWindow(Window); if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase); OpenWorkBench(); /* don't see how it could be closed, but.. */ exit(0); } WaitForNewSize() { while (TRUE) { WaitPort(Window->UserPort); Msg=(struct IntuiMessage *) GetMsg(Window->UserPort); if (Msg->Class==INACTIVEWINDOW) { ReplyMsg((struct Message *) Msg); return(0); } if (Msg->Class!=NEWSIZE) { ReplyMsg((struct Message *) Msg); continue; } ReplyMsg((struct Message *) Msg); break; } }