/* JPClock v1.2 - © 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. */ /* Big bug fixed - thanks to Torsten Lohr for reporting it! */ #include #include #include #include #include #include #include #include #include #include #include #include #include extern void bye(); /* 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[10], DateBuffer[10], AlarmBuffer[10]="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,10,0}; struct StringInfo DateStringInfo={ DateBuffer,NULL,0,10,0}; struct StringInfo AlarmStringInfo={ AlarmBuffer,NULL,0,10,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,6,2,NULL,(UBYTE *)"Next Screen",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|GADGETUP, WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH|NOCAREREFRESH|RMBTRAP, NULL,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, StayFront=0,Alarm=0,a,b,c,USA=0,Swap=0,j,x,y,AlarmSet=0, DTime=1,DDay=1,DDate=1,DFast=1,DChip=1,DTotal=1, class,code,oldx,oldy; char d[8],Date[9],Time[9],buf[15],ch; char *Day[7]={ "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; char *alarmstring; struct Gadget *Gad; /* was I run from CLI? */ if (argc>0) { /* 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 : Auto. swap to next 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); /* 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 have a look at our args */ 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) strcat(TextBuffer," "); if (DDay) strcat(TextBuffer," "); if (DDate) strcat(TextBuffer," "); if (DFast) strcat(TextBuffer," "); if (DChip) strcat(TextBuffer," "); if (DTotal) strcat(TextBuffer," "); /* now what was that alarm time ? */ if (AlarmSet) { a=0; b=0; c=0; sscanf(alarmstring,"-at%d:%d:%d",&a,&b,&c); sprintf(AlarmBuffer,"%02d:%02d:%02d",a,b,c); } /* find out how wide window needs to be */ IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0); ClockWindow.Screen=(struct Screen *) IntuitionBase->FirstScreen; ClockWindow.Width=(strlen(TextBuffer)*8)+80; if (ClockWindow.LeftEdge>(ClockWindow.Screen->Width)-ClockWindow.Width) ClockWindow.LeftEdge=ClockWindow.Screen->Width-ClockWindow.Width; if (ClockWindow.TopEdge>(ClockWindow.Screen->Height-10)) ClockWindow.TopEdge=ClockWindow.Screen->Height-10; if ((Window=(struct Window *) OpenWindow(&ClockWindow))==NULL) bye(); /* if default font is too big, use topaz 8 */ if (Window->IFont->tf_YSize>8) TextPrint.ITextFont=&TopazText; if ((TimerPort=(struct MsgPort *) CreatePort("Timer Port",0))==NULL) bye(); if (OpenDevice(TIMERNAME,UNIT_VBLANK,&TimeReq,0)!=NULL) 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) if (nextscreen()) sizeflag=0; /* de main loop */ FOREVER { 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); strcpy(buf,""); strcpy(TextBuffer,""); /* clear both buffers */ if (DTime) { strcat(TextBuffer," "); strcat(TextBuffer,Time); } if (DDay) { strcat(TextBuffer," "); strcat(TextBuffer,Day[(int)d[0]]); } if (DDate) { strcat(TextBuffer," "); strcat(TextBuffer,Date); } 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) ringalarm(); /* alarm time! */ /* wait for a message */ Wait (1<UserPort->mp_SigBit | 1<mp_SigBit); if (Msg=(struct IntuiMessage *) GetMsg(Window->UserPort)) { class=Msg->Class; code=Msg->Code; if (class==GADGETUP) { Gad=(struct Gadget *) Msg->IAddress; GadgetID=Gad->GadgetID; } ReplyMsg((struct Message *)Msg); switch (class) { case CLOSEWINDOW: /* bye de bye */ bye(); break; case MOUSEBUTTONS: if (code==MENUUP) { /* hit de right mouse button; resize */ if (sizeflag==0) { /* make it big */ ScreenHeight=Window->WScreen->Height; ScreenWidth=Window->WScreen->Width; oldx=Window->LeftEdge; oldy=Window->TopEdge; 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); AddGList(Window,&SwapScreensGadget,-1,6,NULL); RefreshGList(&SwapScreensGadget,Window,NULL,6); sizeflag=1; } else { /* make it small */ RemoveGList(Window,&SwapScreensGadget,6); SizeWindow(Window,-(504-ClockWindow.Width),-35); if (oldx+ClockWindow.Width>Window->WScreen->Width) oldx=Window->WScreen->Width-ClockWindow.Width; if (oldy+10>Window->WScreen->Height) oldy=Window->WScreen->Height-10; MoveWindow(Window,oldx-Window->LeftEdge,oldy-Window->TopEdge); sizeflag=0; } } break; case GADGETUP: /* a gadget! */ switch (GadgetID) { case SWAPSCREENS: /* go to next screen */ if (nextscreen()) 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; ch='\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 */ strcpy(TimeBuffer,""); RefreshGList(&TimeStringGadget,Window,NULL,1); break; } strcpy(TimeBuffer,""); RefreshGList(&TimeStringGadget,Window,NULL,1); 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) { strcpy(DateBuffer,""); RefreshGList(&DateStringGadget,Window,NULL,1); break; } strcpy(DateBuffer,""); RefreshGList(&DateStringGadget,Window,NULL,1); 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; ch='\0'; sscanf(AlarmBuffer,"%d:%d:%d",&a,&b,&c); sprintf(AlarmBuffer,"%02d:%02d:%02d",a,b,c); RefreshGList(&AlarmStringGadget,Window,NULL,1); break; } break; } } if (GetMsg(TimerPort)) { TimeReq.tr_time.tv_secs=0; TimeReq.tr_time.tv_micro=delay; SendIO((char *) &TimeReq.tr_node); } } } nextscreen() { struct Screen *scr; scr=Window->WScreen->NextScreen; if (!scr || scr->WidthHeight<45) return(FALSE); ScreenToBack(Window->WScreen); ScreenToFront(scr); ClockWindow.LeftEdge=Window->LeftEdge; ClockWindow.TopEdge=Window->TopEdge; ClockWindow.Screen=scr; if (ClockWindow.LeftEdge+ClockWindow.Width>scr->Width) ClockWindow.LeftEdge=scr->Width-ClockWindow.Width; if (ClockWindow.TopEdge+10>scr->Height) ClockWindow.TopEdge=scr->Height-10; RemoveGList(Window,&SwapScreensGadget,6); CloseWindow(Window); if (!(Window=(struct Window *) OpenWindow(&ClockWindow))) bye(); return(TRUE); } void bye() { /* outahere! */ GetMsg(TimerPort); 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); } ringalarm() { int i; for (i=0;i<10;i++) { DisplayBeep(NULL); beep(); Delay(5); } return(0); } UBYTE allocationMap[] = { 1, 8, 2, 4 }; beep() { struct IOAudio *audioIOB; struct MsgPort *replyPort; UBYTE *beepWave; replyPort=(struct MsgPort *) CreatePort(0,0); beepWave=(UBYTE *)AllocMem(10,MEMF_CHIP|MEMF_CLEAR); if (beepWave!=0) { beepWave[0]=100; audioIOB=(struct IOAudio *) CreateExtIO(replyPort,sizeof(struct IOAudio)); if (audioIOB!=NULL) { audioIOB->ioa_Request.io_Message.mn_Node.ln_Pri=85; audioIOB->ioa_Data=allocationMap; audioIOB->ioa_Length=sizeof(allocationMap); if (OpenDevice("audio.device",0,audioIOB,0)==0) { audioIOB->ioa_Request.io_Command=CMD_WRITE; audioIOB->ioa_Request.io_Flags=ADIOF_PERVOL; audioIOB->ioa_Data=beepWave; audioIOB->ioa_Length=10; audioIOB->ioa_Period=3579545/10000; audioIOB->ioa_Volume=64; BeginIO(audioIOB); Delay(50); CloseDevice(audioIOB); } DeleteExtIO(audioIOB); } FreeMem(beepWave,10); } DeletePort(replyPort); return(0); }