/* DClock.c ***************************************************************** * * DClock -------- A Dumb Clock utility, my idea of how a clock * should really be like. * * Author -------- Olaf 'Olsen' Barthel, MXM * Brabeckstrasse 35 * D-3000 Hannover 71 * * Federal Republic of Germany * * This program truly is in the PUBLIC DOMAIN. Written on a cold * and damp September evening, hoping the next morning would be * better. * * Compiled using Aztec C 5.0b, CygnusEd Professional 2 & ARexx. * ***************************************************************************/ /* ARP help messages. */ char *CLI_Template = "Q=Quit/S,I=Info/S,V=Version/S,S=Quiet/S,R=Refresh/S,C=Readclock/S,Beep/K,Click/K,\ Speech/K,Hour/K,Seconds/K,SetEnv/K,Tea=Countdown/K,Sound/K,Textcolour/K,Backcolour/K,\ Clickvolume/K,Priority/K,Page/K,Alarm/K,Alarmtime/K"; char *CLI_Help = "\nUsage: \33[1mDClock\33[0m [Quit] [Info] [Version] [Quiet] [Refresh] [Readclock]\ \n [Beep On|Off] [Click On|Off] [Speech On|Off]\ \n [Hour On|Off] [Seconds On|Off] [SetEnv On|Off]\ \n [Countdown/Tea #|Off] [Sound \"Name\"|Off]\ \n [Textcolour #] [Backcolour #]\ \n [Clickvolume 0..64] [Priority -128..127] [Page 0..4]\ \n [Alarm On|Off|Show] [Alarmtime HH:MM:SS]\n"; /* Where to find the different arguments (quite a lot). */ #define ARG_QUIT 1 #define ARG_INFO 2 #define ARG_VERSION 3 #define ARG_QUIET 4 #define ARG_REFRESH 5 #define ARG_READCLOCK 6 #define ARG_BEEP 7 #define ARG_CLICK 8 #define ARG_SPEECH 9 #define ARG_HOUR 10 #define ARG_SECONDS 11 #define ARG_SETENV 12 #define ARG_COUNTDOWN 13 #define ARG_SOUND 14 #define ARG_TEXTCOLOUR 15 #define ARG_BACKCOLOUR 16 #define ARG_CLICKVOLUME 17 #define ARG_PRIORITY 18 #define ARG_PAGE 19 #define ARG_ALARM 20 #define ARG_ALARMTIME 21 /* Pop-up requester support structure. */ struct PopSupport { ULONG ps_Flags; LONG ps_TimeOut; }; /* Pop-up requester support flags. */ #define PS_CENTER 0x00000001 /* Center window on screen. */ #define PS_TIMEOUT 0x00000002 /* Wait for timeout. */ #define PS_DONTMOVE 0x00000004 /* Don't move the pointer. */ #define PS_BEEP 0x00000008 /* Beep on startup. */ #define PS_STAYACTIVE 0x00000010 /* Keep the window activated. */ /* Prototypes. */ LONG Chk_Abort(VOID); VOID _wb_parse(VOID); LONG MovePointer(struct Screen *mp_Screen, LONG mp_X, LONG mp_Y); LONG WriteConsole(struct Window *wc_Window, UBYTE *wc_String); VOID CalcDimensions(UBYTE *cd_String, LONG *cd_Width, LONG *cd_Height, LONG cd_MaxWidth); VOID EraseGadget(struct RastPort *RPort, struct Gadget *Gadget); LONG PopRequest(struct Window *pr_ParentWindow, UBYTE *pr_TitleText, UBYTE *pr_BodyText, UBYTE *pr_PosText, UBYTE *pr_NegText, LONG pr_Default, struct PopSupport *pr_ExtraInfo); VOID ProcessIcon(VOID); LONG FindChunk(ULONG ChunkName,BPTR FileHandle); LONG LoadChimeSound(char *Name); VOID main(int argc,char **argv); /* For Workbench startability we need access to the icon info. */ struct Library *IconBase; BOOL FromWorkbench = FALSE; /* Some more libraries... */ extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern struct ExecBase *SysBase; /* Main communication structure. */ struct DSeg *DSeg; /* Stubs, don't need these. */ LONG Chk_Abort(VOID) { return(0); } VOID _wb_parse(VOID) {} /* Our current version tag. */ const char *VersionTag = "$VER: DClock 1.29 (15 Sep 1990)\n\r"; /* MovePointer(mp_Screen,mp_X,mp_Y) : * * Moves the mouse pointer to a given position * on a screen. */ LONG MovePointer(struct Screen *mp_Screen,LONG mp_X,LONG mp_Y) { static struct InputEvent mp_StaticEvent = { NULL, IECLASS_POINTERPOS, 0, IECODE_NOBUTTON, 0,0,0,0 }; struct MsgPort *mp_InputPort; struct IOStdReq *mp_InputRequest; struct InputEvent *mp_FakeEvent; LONG mp_Success = FALSE; if(mp_InputPort = (struct MsgPort *)CreatePort(NULL,0)) { if(mp_InputRequest = (struct IOStdReq *)CreateStdIO(mp_InputPort)) { if(!OpenDevice("input.device",0,(struct IORequest *)mp_InputRequest,0)) { if(mp_FakeEvent = (struct InputEvent *)AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC)) { CopyMem(&mp_StaticEvent,mp_FakeEvent,sizeof(struct InputEvent)); mp_InputRequest -> io_Command = IND_WRITEEVENT; mp_InputRequest -> io_Flags = 0; mp_InputRequest -> io_Length = sizeof(struct InputEvent); mp_InputRequest -> io_Data = (APTR)mp_FakeEvent; mp_FakeEvent -> ie_X = mp_X; mp_FakeEvent -> ie_Y = mp_Y; if(!(mp_Screen -> ViewPort . Modes & HIRES)) mp_FakeEvent -> ie_X *= 2; if(!(mp_Screen -> ViewPort . Modes & LACE)) mp_FakeEvent -> ie_Y *= 2; mp_FakeEvent -> ie_Y += (2 * mp_Screen -> TopEdge); DoIO((struct IORequest *)mp_InputRequest); mp_Success = TRUE; FreeMem(mp_FakeEvent,sizeof(struct InputEvent)); } CloseDevice((struct IORequest *)mp_InputRequest); } DeleteStdIO(mp_InputRequest); } DeletePort(mp_InputPort); } return(mp_Success); } /* WriteConsole(wc_Window,wc_String) : * * Writes a string to a window (via console.device). */ LONG WriteConsole(struct Window *wc_Window,UBYTE *wc_String) { struct IOStdReq *wc_ConWrite; struct MsgPort *wc_ConPort; LONG wc_Success = FALSE; if(wc_ConPort = (struct MsgPort *)CreatePort(NULL,0)) { if(wc_ConWrite = (struct IOStdReq *)CreateStdIO(wc_ConPort)) { wc_ConWrite -> io_Data = (APTR)wc_Window; wc_ConWrite -> io_Length= sizeof(struct Window); if(!OpenDevice("console.device",0,(struct IORequest *)wc_ConWrite,0)) { wc_ConWrite -> io_Command = CMD_WRITE; wc_ConWrite -> io_Data = (APTR)"\2330 p"; wc_ConWrite -> io_Length = -1; DoIO((struct IORequest *)wc_ConWrite); wc_ConWrite -> io_Data = (APTR)wc_String; wc_ConWrite -> io_Length = -1; DoIO((struct IORequest *)wc_ConWrite); wc_Success = TRUE; CloseDevice((struct IORequest *)wc_ConWrite); } DeleteStdIO(wc_ConWrite); } DeletePort(wc_ConPort); } return(wc_Success); } /* CalcDimensions(cd_String,cd_Width,cd_Height,cd_MaxWidth) : * * Calculates the width and height of a formatted * string block. */ VOID CalcDimensions(UBYTE *cd_String,LONG *cd_Width,LONG *cd_Height,LONG cd_MaxWidth) { LONG i,cd_InLine = 0,cd_NumLines = 0; *cd_Width = *cd_Height = 0; for(i = 0 ; i < strlen(cd_String) ; i++) { if(cd_String[i] == '\n' || cd_InLine == cd_MaxWidth) { if(cd_InLine > *cd_Width) *cd_Width = cd_InLine; cd_NumLines++; cd_InLine = 0; continue; } if(cd_String[i] == '\33') { while(cd_String[i] != 'm' && cd_String[i] != 'w' && i < strlen(cd_String)) i++; if(i >= strlen(cd_String)) i = strlen(cd_String) - 1; continue; } if(cd_String[i] < ' ') continue; cd_InLine++; } *cd_Height = cd_NumLines; if(cd_InLine > *cd_Width) *cd_Width = cd_InLine; } /* EraseGadget(RPort,Gadget) : * * Clears the background of a gadget. */ VOID EraseGadget(struct RastPort *RPort,struct Gadget *Gadget) { SetAPen(RPort,2); SetDrMd(RPort,JAM1); RectFill(RPort,Gadget -> LeftEdge,Gadget -> TopEdge,Gadget -> LeftEdge + Gadget -> Width - 1,Gadget -> TopEdge + Gadget -> Height - 1); SetAPen(RPort,1); } /* PopRequest(pr_ParentWindow,pr_TitleText,pr_BodyText,pr_PosText,pr_NegText,pr_Default,pr_ExtraInfo) : * * Creates a pop-up requester, note: this function is reentrant, * just like all functions above. */ LONG PopRequest(struct Window *pr_ParentWindow,UBYTE *pr_TitleText,UBYTE *pr_BodyText,UBYTE *pr_PosText,UBYTE *pr_NegText,LONG pr_Default,struct PopSupport *pr_ExtraInfo) { static struct NewWindow pr_StaticNewWindow = { 0,0, 0,1, 0,1, VANILLAKEY | MOUSEBUTTONS | GADGETUP | CLOSEWINDOW, RMBTRAP | WINDOWDRAG | WINDOWDEPTH, (struct Gadget *)NULL, (struct Image *)NULL, (STRPTR)NULL, (struct Screen *)NULL, (struct BitMap *)NULL, 0,0, 0,0, WBENCHSCREEN }; static struct Gadget pr_StaticGadget = { (struct Gadget *)NULL, 0,0, 0,0, GADGHBOX, RELVERIFY | GADGIMMEDIATE, BOOLGADGET, (APTR)NULL, (APTR)NULL, (struct IntuiText *)NULL, NULL, (APTR)NULL, 0, (APTR)NULL }; static struct TextAttr pr_TextAttr = { (UBYTE *)"topaz.font", 8, FS_NORMAL, FPF_ROMFONT }; struct NewWindow *pr_NewWindow; struct Window *pr_Window; struct IntuiMessage *pr_IMsg; struct Gadget *pr_PosGadget = NULL,*pr_NegGadget = NULL,*pr_TempGadget; struct Screen pr_Screen,*pr_FirstScreen; struct TextFont *pr_TextFont; LONG pr_Width,pr_Height; LONG pr_Result = FALSE; LONG pr_TickCount = 0; ULONG pr_IntuiLock; if(!pr_BodyText) return(pr_Result); if(!(pr_NewWindow = (struct NewWindow *)AllocMem(sizeof(struct NewWindow),MEMF_PUBLIC))) return(pr_Result); CopyMem(&pr_StaticNewWindow,pr_NewWindow,sizeof(struct NewWindow)); pr_IntuiLock = LockIBase(NULL); pr_FirstScreen = IntuitionBase -> FirstScreen; UnlockIBase(pr_IntuiLock); if(pr_ParentWindow) { pr_NewWindow -> Type = CUSTOMSCREEN; pr_NewWindow -> Screen = pr_ParentWindow -> WScreen; } else OpenWorkBench(); if(!GetScreenData(&pr_Screen,sizeof(struct Screen),pr_NewWindow -> Type,pr_NewWindow -> Screen)) { FreeMem(pr_NewWindow,sizeof(struct NewWindow)); return(pr_Result); } CalcDimensions(pr_BodyText,&pr_Width,&pr_Height,(pr_Screen . Width - 6) / 8); if(pr_Height > (pr_Screen . Height - 15 - 13) / 8) { FreeMem(pr_NewWindow,sizeof(struct NewWindow)); return(pr_Result); } pr_NewWindow -> Width = pr_Width * 8 + 6 + 4; pr_NewWindow -> Height = pr_Height * 8 + 15 + 19 + 2; if(pr_TitleText) pr_NewWindow -> Title = pr_TitleText; else pr_NewWindow -> Title = (UBYTE *)"System Request"; if(!pr_PosText && !pr_NegText) pr_NegText = (UBYTE *)"Okay"; if(pr_PosText) { if(!(pr_PosGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC))) { FreeMem(pr_NewWindow,sizeof(struct NewWindow)); return(pr_Result); } CopyMem(&pr_StaticGadget,pr_PosGadget,sizeof(struct Gadget)); pr_PosGadget -> Width = 8 * strlen(pr_PosText) + 4; pr_PosGadget -> Height = 8 + 2; pr_PosGadget -> LeftEdge= 3 + 2 + 3; pr_PosGadget -> TopEdge = pr_NewWindow -> Height - 13 - 1; } if(pr_NegText) { if(!(pr_NegGadget = (struct Gadget *)AllocMem(sizeof(struct Gadget),MEMF_PUBLIC))) { FreeMem(pr_NewWindow,sizeof(struct NewWindow)); if(pr_PosGadget) FreeMem(pr_PosGadget,sizeof(struct Gadget)); return(pr_Result); } CopyMem(&pr_StaticGadget,pr_NegGadget,sizeof(struct Gadget)); pr_NegGadget -> Width = 8 * strlen(pr_NegText) + 4; pr_NegGadget -> Height = 8 + 2; pr_Width = pr_NegGadget -> Width + 6 + 4 + 6; if(pr_PosGadget) pr_Width += (pr_PosGadget -> Width + 12); if(pr_NewWindow -> Width < pr_Width) pr_NewWindow -> Width = pr_Width; pr_NegGadget -> LeftEdge= pr_NewWindow -> Width - pr_NegGadget -> Width - 3 - 2 - 3; pr_NegGadget -> TopEdge = pr_NewWindow -> Height - 13 - 1; pr_NegGadget -> GadgetID= 1; } if(!pr_NegGadget && pr_NewWindow -> Width < pr_PosGadget -> Width + 6 + 4 + 6) pr_NewWindow -> Width = pr_PosGadget -> Width + 6 + 4 + 6; if(pr_Default && !pr_PosGadget) pr_Default = FALSE; if(!pr_Default && !pr_NegGadget) pr_Default = TRUE; if(pr_Default) pr_TempGadget = pr_PosGadget; else pr_TempGadget = pr_NegGadget; pr_NewWindow -> LeftEdge= pr_Screen . MouseX - (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2); pr_NewWindow -> TopEdge = pr_Screen . MouseY - (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2); while(pr_NewWindow -> LeftEdge < 0) pr_NewWindow -> LeftEdge++; while(pr_NewWindow -> TopEdge < 0) pr_NewWindow -> TopEdge++; while(pr_NewWindow -> LeftEdge + pr_NewWindow -> Width >= pr_Screen . Width) pr_NewWindow -> LeftEdge--; while(pr_NewWindow -> TopEdge + pr_NewWindow -> Height >= pr_Screen . Height) pr_NewWindow -> TopEdge--; if(!(pr_TextFont = (struct TextFont *)OpenFont(&pr_TextAttr))) { if(pr_PosGadget) FreeMem(pr_PosGadget,sizeof(struct Gadget)); if(pr_NegGadget) FreeMem(pr_NegGadget,sizeof(struct Gadget)); FreeMem(pr_NewWindow,sizeof(struct NewWindow)); return(pr_Result); } if(pr_ExtraInfo) { if(pr_ExtraInfo -> ps_Flags & PS_CENTER) { pr_NewWindow -> LeftEdge = (pr_Screen . Width - pr_NewWindow -> Width) / 2; pr_NewWindow -> TopEdge = (pr_Screen . Height - pr_NewWindow -> Height) / 2; } if(pr_ExtraInfo -> ps_Flags & PS_TIMEOUT) pr_NewWindow -> IDCMPFlags |= INTUITICKS; if(pr_ExtraInfo -> ps_Flags & PS_STAYACTIVE) pr_NewWindow -> IDCMPFlags |= INACTIVEWINDOW; } if(!(pr_Window = (struct Window *)OpenWindow(pr_NewWindow))) { CloseFont(pr_TextFont); if(pr_PosGadget) FreeMem(pr_PosGadget,sizeof(struct Gadget)); if(pr_NegGadget) FreeMem(pr_NegGadget,sizeof(struct Gadget)); FreeMem(pr_NewWindow,sizeof(struct NewWindow)); return(pr_Result); } SetFont(pr_Window -> RPort,pr_TextFont); WriteConsole(pr_Window,pr_BodyText); if(pr_PosGadget) { AddGadget(pr_Window,pr_PosGadget,1); EraseGadget(pr_Window -> RPort,pr_PosGadget); Move(pr_Window -> RPort,pr_PosGadget -> LeftEdge + 2,pr_PosGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline); Text(pr_Window -> RPort,pr_PosText,strlen(pr_PosText)); } if(pr_NegGadget) { AddGadget(pr_Window,pr_NegGadget,1); EraseGadget(pr_Window -> RPort,pr_NegGadget); Move(pr_Window -> RPort,pr_NegGadget -> LeftEdge + 2,pr_NegGadget -> TopEdge + 1 + pr_TextFont -> tf_Baseline); Text(pr_Window -> RPort,pr_NegText,strlen(pr_NegText)); } MoveScreen(pr_Window -> WScreen,0,- pr_Window -> WScreen -> TopEdge); ScreenToFront(pr_Window -> WScreen); ActivateWindow(pr_Window); if(pr_ExtraInfo && pr_ExtraInfo -> ps_Flags & PS_DONTMOVE) goto Skip1; MovePointer(pr_Window -> WScreen, pr_Window -> LeftEdge + (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2), pr_Window -> TopEdge + (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2)); Skip1: if(pr_ExtraInfo) { if(pr_ExtraInfo -> ps_Flags & PS_BEEP) DisplayBeep(pr_Window -> WScreen); if(pr_ExtraInfo -> ps_Flags & PS_TIMEOUT) pr_TickCount = pr_ExtraInfo -> ps_TimeOut * 10; } FOREVER { ULONG pr_Class,pr_Code,pr_Qualifier; struct Gadget *pr_Gadget; WaitPort(pr_Window -> UserPort); if(pr_IMsg = (struct IntuiMessage *)GetMsg(pr_Window -> UserPort)) { pr_Class = pr_IMsg -> Class; pr_Code = pr_IMsg -> Code; pr_Qualifier = pr_IMsg -> Qualifier; pr_Gadget = (struct Gadget *)pr_IMsg -> IAddress; ReplyMsg((struct Message *)pr_IMsg); if(pr_Class == INTUITICKS) { if(pr_TickCount) pr_TickCount--; else { pr_Result = pr_Default; break; } continue; } if(pr_Class == INACTIVEWINDOW) { MoveScreen(pr_Window -> WScreen,0,- pr_Window -> WScreen -> TopEdge); ScreenToFront(pr_Window -> WScreen); ActivateWindow(pr_Window); if(!(pr_ExtraInfo -> ps_Flags & PS_DONTMOVE)) { MovePointer(pr_Window -> WScreen, pr_Window -> LeftEdge + (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2), pr_Window -> TopEdge + (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2)); } if(pr_ExtraInfo -> ps_Flags & PS_BEEP) DisplayBeep(pr_Window -> WScreen); continue; } if(pr_Class == GADGETUP) { if(pr_Gadget -> GadgetID == 0) pr_Result = TRUE; break; } if(pr_Class == CLOSEWINDOW) break; if(pr_Class == VANILLAKEY) { pr_Code = Toupper(pr_Code); if((pr_Code == 'Y' || pr_Code == 'J' || pr_Code == 'V' || pr_Code == 'C' || pr_Code == 'R' || pr_Code == '\r') && pr_PosText) { pr_Result = TRUE; break; } if((pr_Code == 'N' || pr_Code == 'Q' || pr_Code == 'B' || pr_Code == '\33') && pr_NegText) break; continue; } if(pr_Class == MOUSEBUTTONS && pr_Code == MENUDOWN) { MovePointer(pr_Window -> WScreen, pr_Window -> LeftEdge+ (pr_TempGadget -> LeftEdge + pr_TempGadget -> Width / 2), pr_Window -> TopEdge + (pr_TempGadget -> TopEdge + pr_TempGadget -> Height / 2)); } } } CloseFont(pr_TextFont); if(pr_PosGadget) { RemoveGadget(pr_Window,pr_PosGadget); FreeMem(pr_PosGadget,sizeof(struct Gadget)); } if(pr_NegGadget) { RemoveGadget(pr_Window,pr_NegGadget); FreeMem(pr_NegGadget,sizeof(struct Gadget)); } FreeMem(pr_NewWindow,sizeof(struct NewWindow)); if(pr_FirstScreen != pr_Window -> WScreen) ScreenToBack(pr_Window -> WScreen); CloseWindow(pr_Window); return(pr_Result); } /* FindChunk(ChunkName,FileHandle): * * Tries to locate a an iff-chunk inside a file. */ LONG FindChunk(ULONG ChunkName,BPTR FileHandle) { LONG OldPosition; ULONG FormType = 0; /* The format of a typical IFF-chunk. */ struct { ULONG IFF_Type; ULONG IFF_Length; } Chunk; /* Remember initial file position. */ OldPosition = Seek(FileHandle,0,OFFSET_CURRENT); /* Try to find it. */ FOREVER { /* Read the first bytes. */ if(Read(FileHandle,&Chunk,sizeof(Chunk)) != sizeof(Chunk)) { Seek(FileHandle,OldPosition,OFFSET_BEGINNING); return(FALSE); } /* Is it a FORM-chunk? */ if(OldPosition == 0 && FormType == 0 && Chunk . IFF_Type == 'FORM') { Read(FileHandle,&FormType,sizeof(LONG)); /* Check the form type. */ if(FormType == ChunkName) return(TRUE); continue; } /* Is it the chunk type we want? */ if(Chunk . IFF_Type == ChunkName) return(TRUE); /* Skip chunk. */ Seek(FileHandle,Chunk . IFF_Length,OFFSET_CURRENT); } } /* LoadChimeSound(Name): * * Loads an IFF-8SVX-soundfile to be used as the hour * chime sound. */ LONG LoadChimeSound(char *Name) { BPTR SoundHandle; APTR SoundData; LONG SoundRate,SoundLength,SoundVolume; /* The format of the VoiceHeader chunk. */ struct { ULONG oneShotHiSamples, repeatHiSamples, samplesPerHiCycle; UWORD samplesPerSec; UBYTE ctOctave, sCompression; LONG volume; } VoiceHeader; /* No name? Reset to defaults. */ if(!Strcmp(Name,"OFF")) { ObtainSemaphore(DSeg -> SoundSemaphore); /* Free the memory. */ if(DSeg -> SoundLength && DSeg -> SoundData) FreeMem(DSeg -> SoundData,DSeg -> SoundLength); /* Mark sound slot as vacant. */ DSeg -> SoundLength = 0; DSeg -> SoundData = NULL; ReleaseSemaphore(DSeg -> SoundSemaphore); return(TRUE); } /* Open the file for reading. */ if(!(SoundHandle = Open(Name,MODE_OLDFILE))) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","No such sound file found!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m No such sound file found!"); return(FALSE); } /* Is it a sound file? */ if(!FindChunk('8SVX',SoundHandle)) { Close(SoundHandle); if(FromWorkbench) PopRequest(NULL,"DClock problem:","File is not an IFF-8SVX-file!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m File is not an IFF-8SVX-file!"); return(FALSE); } /* Look for the VoiceHeader. */ if(!FindChunk('VHDR',SoundHandle)) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","Didn't find VHDR chunk!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m Didn't find VHDR chunk!"); Close(SoundHandle); return(FALSE); } /* Read the header. */ if(Read(SoundHandle,&VoiceHeader,sizeof(VoiceHeader)) != sizeof(VoiceHeader)) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","Error while reading file!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m Error while reading file!"); Close(SoundHandle); return(FALSE); } /* Fill in the more important information. */ SoundLength = VoiceHeader . oneShotHiSamples + VoiceHeader . repeatHiSamples; SoundRate = ((GfxBase -> DisplayFlags & PAL) ? 3546895 : 3579545) / VoiceHeader . samplesPerSec; SoundVolume = (VoiceHeader . volume > 64 ? 64 : VoiceHeader . volume); /* Proceed with the body chunk. */ if(!FindChunk('BODY',SoundHandle)) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","Didn't find BODY chunk!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m Didn't find BODY chunk!"); Close(SoundHandle); return(FALSE); } /* Allocate space for the sound data. */ if(!(SoundData = (APTR)AllocMem(SoundLength,MEMF_PUBLIC | MEMF_CHIP))) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","Not enough memory for sound data!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m Not enough memory for sound data!"); Close(SoundHandle); return(FALSE); } /* Read the sound data. */ if(Read(SoundHandle,SoundData,SoundLength) != SoundLength) { if(FromWorkbench) PopRequest(NULL,"DClock problem:","Error while reading file!",NULL,"Continue?",FALSE,NULL); else Puts("\33[1mDClock:\33[0m Error while reading file!"); FreeMem(SoundData,SoundLength); Close(SoundHandle); return(FALSE); } /* Close the file. */ Close(SoundHandle); /* Lock access to sound data. */ ObtainSemaphore(DSeg -> SoundSemaphore); /* Free last sound. */ if(DSeg -> SoundLength && DSeg -> SoundData) FreeMem(DSeg -> SoundData,DSeg -> SoundLength); /* Fill in the data. */ DSeg -> SoundData = SoundData; DSeg -> SoundLength = SoundLength; DSeg -> SoundRate = SoundRate; DSeg -> SoundVolume = SoundVolume; /* Unlock it again. */ ReleaseSemaphore(DSeg -> SoundSemaphore); return(TRUE); } /* ProcessIcon(): * * To add startability from Workbench this function * checks for the approritate tooltype entries. */ VOID ProcessIcon() { struct DiskObject *DiskObject; extern struct WBStartup *WBenchMsg; char *Option; /* No need to continue? */ if(!DSeg || !FromWorkbench) { if(!DSeg && FromWorkbench) PopRequest(NULL,"DClock problem:","Can't find \33[1m\"DClock-Handler\"\33[0m!\nCheck L: and current directory.",NULL,"Continue?",FALSE,NULL); return; } /* Try to open the icon.library. */ if(!(IconBase = (struct Library *)OpenLibrary("icon.library",0))) { PopRequest(NULL,"DClock problem:","Unable to open \33[1micon.library\33[0m!",NULL,"Continue?",FALSE,NULL); return; } /* Can we read the icon file please? */ if(!(DiskObject = (struct DiskObject *)GetDiskObject(WBenchMsg -> sm_ArgList -> wa_Name))) { PopRequest(NULL,"DClock problem:","Couldn't read icon information file!",NULL,"Continue?",FALSE,NULL); CloseLibrary(IconBase); return; } /* Adjust Click volume? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"CLICKVOLUME")) { if(Atol(Option) > 64 || Atol(Option) < 0) PopRequest(NULL,"DClock problem:","Illegal value for click volume (must be between 0 and 64)!",NULL,"Continue?",FALSE,NULL); else DSeg -> ClickVolume = Atol(Option); } /* Adjust task priority? */ if((Option = FindToolType(DiskObject -> do_ToolTypes,"PRIORITY")) && DSeg -> Child) { if(Atol(Option) > 127 || Atol(Option) < -128) PopRequest(NULL,"DClock problem:","Illegal value for handler task priority (must be between -128 and 127)!",NULL,"Continue?",FALSE,NULL); else { DSeg -> Priority = Atol(Option); SetTaskPri(DSeg -> Child,DSeg -> Priority); } } /* Turn DisplayBeep() off? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"BEEP")) { if(!Strcmp(Option,"OFF")) DSeg -> Beep = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Beep = TRUE; else PopRequest(NULL,"DClock problem:","Beep settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Turn keyboard click off? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"CLICK")) { if(!Strcmp(Option,"OFF")) DSeg -> Click = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Click = TRUE; else PopRequest(NULL,"DClock problem:","Click settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Set text colour? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"TEXTCOLOUR")) DSeg -> TextColour = Atol(Option); /* Set background colour? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"BACKCOLOUR")) DSeg -> BackColour = Atol(Option); /* Turn alarm on? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"ALARM")) { if(!Strcmp(Option,"OFF")) DSeg -> Alarm = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Alarm = TRUE; else PopRequest(NULL,"DClock problem:","Alarm settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Set alarm time? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"ALARMTIME")) { char TimeBuff[3]; LONG TheTime; TimeBuff[2] = 0; TimeBuff[0] = Option[0]; TimeBuff[1] = Option[1]; TheTime = Atol(TimeBuff); if(TheTime >= 0 && TheTime <= 23) DSeg -> AlarmHour = TheTime; else PopRequest(NULL,"DClock problem:","Illegal value for alarm hour (must be between 0 and 23)!",NULL,"Continue?",FALSE,NULL); TimeBuff[0] = Option[3]; TimeBuff[1] = Option[4]; TheTime = Atol(TimeBuff); if(TheTime >= 0 && TheTime <= 59) DSeg -> AlarmMinute = TheTime; else PopRequest(NULL,"DClock problem:","Illegal value for alarm minute (must be between 0 and 59)!",NULL,"Continue?",FALSE,NULL); TimeBuff[0] = Option[6]; TimeBuff[1] = Option[7]; TheTime = Atol(TimeBuff); if(TheTime >= 0 && TheTime <= 59) DSeg -> AlarmSecond = TheTime; else PopRequest(NULL,"DClock problem:","Illegal value for alarm seconds (must be between 0 and 59)!",NULL,"Continue?",FALSE,NULL); } /* Set environment variables? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"SETENV")) { if(!Strcmp(Option,"OFF")) DSeg -> SetEnv = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> SetEnv = TRUE; else PopRequest(NULL,"DClock problem:","Environment settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Start countdown? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"COUNTDOWN")) { if(Atol(Option) > 0) DSeg -> Countdown = Atol(Option); else PopRequest(NULL,"DClock problem:","Countdown must be greater than 0!",NULL,"Continue?",FALSE,NULL); } /* Set hour chime? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"HOUR")) { if(!Strcmp(Option,"OFF")) DSeg -> Hour = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Hour = TRUE; else PopRequest(NULL,"DClock problem:","Hour settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Turn seconds off? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"SECONDS")) { if(!Strcmp(Option,"OFF")) DSeg -> Seconds = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Seconds = TRUE; else PopRequest(NULL,"DClock problem:","Second settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Load a chime sound? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"SOUND")) LoadChimeSound(Option); /* Show which page on startup? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"PAGE")) { if(Atol(Option) < 0 || Atol(Option) > 4 || (Atol(Option) == 4 && DSeg -> Countdown < 1)) PopRequest(NULL,"DClock problem:","Illegal value for page!",NULL,"Continue?",FALSE,NULL); else DSeg -> Page = Atol(Option); } /* Turn the speech off? */ if(Option = FindToolType(DiskObject -> do_ToolTypes,"SPEECH")) { if(!Strcmp(Option,"OFF")) DSeg -> Speech = FALSE; else { if(!Strcmp(Option,"ON")) DSeg -> Speech = TRUE; else PopRequest(NULL,"DClock problem:","Speech settings not understood (must be OFF or ON)!",NULL,"Continue?",FALSE,NULL); } } /* Read the system clock? */ if(FindToolType(DiskObject -> do_ToolTypes,"READCLOCK")) { if(!ReadClock()) PopRequest(NULL,"DClock problem:","Could not find battery backed up clock!",NULL,"Continue?",FALSE,NULL); } /* Free the rest... */ FreeDiskObject(DiskObject); CloseLibrary(IconBase); } /* main(argc,argv): * * That's where all the trouble starts. */ VOID main(int argc,char **argv) { BOOL Quiet = FALSE; struct Process *ThatsMe = (struct Process *)SysBase -> ThisTask; /* Init important pointers. */ if(!ThatsMe -> pr_CLI) FromWorkbench = TRUE; /* Are we already running? */ DSeg = (struct DSeg *)FindPort(PORTNAME); /* Restart? */ if(FromWorkbench && DSeg) { ProcessIcon(); exit(RETURN_OK); } /* Yeah... push it! */ if(FromWorkbench) goto PushIt; /* Be quiet? */ if(argv[ARG_QUIET]) Quiet = TRUE; /* No argument and DClock's already running? */ if(argc < 2 && DSeg) { Printf("Can't install \33[1mDClock\33[0m, handler process \33[33malready running\33[31m\7!\n"); exit(RETURN_OK); } /* Read the system clock? */ if(argv[ARG_READCLOCK]) { if(!ReadClock() && !Quiet) Puts("\33[1mDClock:\33[0m Could not find battery backed up clock."); } /* User wants information. */ if(argv[ARG_INFO]) { Printf("\n\33[1m\33[33mDClock\33[0m\33[31m - A \33[33mD\33[31mumb \33[33mClock\33[31m. Renders time and date\n"); Printf(" into the Workbench title bar. Place\n"); Printf(" \33[33mDClock-Handler\33[31m in L:, \33[33mDClock\33[31m somewhere\n"); Printf(" in C: or in SYS:. Type '\33[1m\33[33mDClock\33[31m\33[0m' to\n"); Printf(" install, '\33[1m\33[33mDClock quit\33[31m\33[0m' to remove.\n\n"); Printf(" \33[33mDClock\33[31m is \33[1mfree\33[0m and in the \33[33m\33[1mPUBLIC-DOMAIN\33[31m\33[0m!\n\n"); Printf("\33[1m\33[33mAuthor\33[31m\33[0m - Olaf Barthel, MXM\n"); Printf(" Brabeckstrasse 35\n"); Printf(" D-3000 Hannover 71\n\n"); Printf(" Federal Republic of Germany.\n\n"); exit(RETURN_OK); } /* Print current release version number. */ if(argv[ARG_VERSION]) { Printf("\33[1mDClock\33[0m version 1.%ld, created \33[33mSaturday, 15-Sep-90 23:18\33[31m.\n",DSeg ? DSeg -> Revision : REVISION); exit(RETURN_OK); } /* Terminate dumb clock? */ if(argv[ARG_QUIT]) { Printf("Removing \33[1m\33[33mDClock\33[31m\33[0m (DClock-Handler revision 1.%ld), ",DSeg ? DSeg -> Revision : -1); /* Segment not loaded. */ if(!DSeg) { Printf("failed!\7\n"); exit(RETURN_FAIL); } /* We are the caller. */ DSeg -> Father = (struct Task *)ThatsMe; /* Child still present? */ if(DSeg -> Child) { Signal(DSeg -> Child,SIGBREAKF_CTRL_D); Wait(SIGBREAKF_CTRL_D); } /* Remove port and associated data. */ RemPort(&DSeg -> Port); FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME)); if(DSeg -> SoundData && DSeg -> SoundLength) FreeMem(DSeg -> SoundData,DSeg -> SoundLength); FreeMem(DSeg -> SoundSemaphore,sizeof(struct SignalSemaphore)); if(DSeg -> Segment) UnLoadSeg(DSeg -> Segment); FreeMem(DSeg,DSeg -> SegSize); Printf("OK.\n"); exit(RETURN_OK); } /* Create global communication structure. */ PushIt: if(!DSeg) { if(DSeg = (struct DSeg *)AllocMem(sizeof(struct DSeg),MEMF_PUBLIC | MEMF_CLEAR)) { ULONG Micros; /* Dummy MessagePort. */ DSeg -> Port . mp_Flags = PA_IGNORE; DSeg -> Port . mp_Node . ln_Pri = 1; DSeg -> Port . mp_Node . ln_Type = NT_MSGPORT; DSeg -> Port . mp_Node . ln_Name = AllocMem(sizeof(PORTNAME),MEMF_PUBLIC); DSeg -> Child = NULL; DSeg -> Father = (struct Task *)ThatsMe; DSeg -> SoundSemaphore = (struct SignalSemaphore *)AllocMem(sizeof(struct SignalSemaphore),MEMF_PUBLIC | MEMF_CLEAR); if(!DSeg -> Port . mp_Node . ln_Name || !DSeg -> SoundSemaphore) goto Purge; /* For future expansion of this structure; * this will insure that any version of * DClock will be able to free the memory * occupied by the segment. */ DSeg -> SegSize = sizeof(struct DSeg); /* We'll wait for this signal to come from * the handler process. */ DSeg -> RingBack = SIGBREAKF_CTRL_E; /* Enable beep and disable click feature. */ DSeg -> Beep = TRUE; DSeg -> Click = FALSE; /* So we have valid time counter. */ CurrentTime(&DSeg -> LastSecs,&Micros); /* Click volume and handler priority. */ DSeg -> ClickVolume = 64; DSeg -> Priority = 5; /* Rendering colours. */ DSeg -> TextColour = 0; DSeg -> BackColour = 1; /* Set alarm default. */ DSeg -> Alarm = FALSE; DSeg -> AlarmHour = 12; DSeg -> AlarmMinute = 0; DSeg -> AlarmSecond = 0; /* Disable countdown & hour chime. */ DSeg -> Countdown = 0; DSeg -> Hour = FALSE; /* Seconds are by default enabled. */ DSeg -> Seconds = TRUE; /* Set environment variables. */ DSeg -> SetEnv = FALSE; /* Install the current revision number. */ DSeg -> Revision = REVISION; /* Init port. */ strcpy(DSeg -> Port . mp_Node . ln_Name,PORTNAME); if(!FromWorkbench) Printf("Installing \33[33m\33[1mDClock\33[0m\33[31m, "); /* Load the handler code. */ DSeg -> Segment = LoadSeg("DClock-Handler"); if(!DSeg -> Segment) DSeg -> Segment = LoadSeg("L:DClock-Handler"); if(!DSeg -> Segment) { if(!FromWorkbench) Printf("unable to find \33[33mL:DClock-Handler\33[31m\7!\n"); else PopRequest(NULL,"DClock problem:","Can't find \33[1m\"DClock-Handler\"\33[0m!\nCheck L: and current directory.",NULL,"Continue?",FALSE,NULL); Purge: if(DSeg) { if(DSeg -> Port . mp_Node . ln_Name) FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME)); if(DSeg -> SoundSemaphore) FreeMem(DSeg -> SoundSemaphore,sizeof(struct SignalSemaphore)); FreeMem(DSeg,DSeg -> SegSize); } } else { /* Install the port and start the handler. */ AddPort(&DSeg -> Port); CreateProc("DClock-Handler",DSeg -> Priority,DSeg -> Segment,4096); /* Wait for child task to ring back... */ Wait(SIGBREAKF_CTRL_E); if(!DSeg -> Child) { if(!FromWorkbench) Printf("\33[33mFAILED!\33[31m (care to retry?)\n"); else PopRequest(NULL,"DClock problem:","Handler process didn't reply startup-message.",NULL,"Continue?",FALSE,NULL); RemPort(&DSeg -> Port); FreeMem(DSeg -> Port . mp_Node . ln_Name,sizeof(PORTNAME)); if(DSeg -> Segment) UnLoadSeg(DSeg -> Segment); FreeMem(DSeg,DSeg -> SegSize); if(FromWorkbench) Delay(TICKS_PER_SECOND * 2); exit(RETURN_FAIL); } else { if(!FromWorkbench) Printf("\33[3mOkay. \33[0m\33[33mDClock v1.%ld\33[31m, by \33[4mMXM\33[0m. \33[1mPUBLIC DOMAIN\33[0m.\n",REVISION); else PopRequest(NULL,"DClock Message:","Handler process successfully installed!\n\n\33[33mDClock\33[31m (C) Copyright 1989, 1990 \33[3mby MXM.\33[0m \33[1mPUBLIC DOMAIN\33[0m.",NULL,"Continue?",FALSE,NULL); } } } } /* Deal with the icon... */ if(FromWorkbench) { ProcessIcon(); exit(RETURN_OK); } /* Change click volume. */ if(argv[ARG_CLICKVOLUME] && DSeg) { if(Atol(argv[ARG_CLICKVOLUME]) >= 0 && Atol(argv[ARG_CLICKVOLUME]) <= 64 ) { if(!Quiet) Printf("\33[1mDClock:\33[0m Click volume set to %ld.\n",DSeg -> ClickVolume = Atol(argv[ARG_CLICKVOLUME])); } else Puts(CLI_Help); } /* Change handler priority? */ if(argv[ARG_PRIORITY] && DSeg) { if(DSeg -> Child) { if(!Quiet) Printf("\33[1mDClock:\33[0m Handler priority set to %ld.\n",DSeg -> Priority = Atol(argv[ARG_PRIORITY])); SetTaskPri(DSeg -> Child,DSeg -> Priority); } else Puts("\33[1mDClock:\33[0m Unable to find handler task."); } /* Turn beeping on/off? */ if(argv[ARG_BEEP] && DSeg) { if(!Strcmp(argv[ARG_BEEP],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Beep disabled."); DSeg -> Beep = FALSE; } else { if(!Strcmp(argv[ARG_BEEP],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Beep enabled."); DSeg -> Beep = TRUE; } else Puts(CLI_Help); } } /* Turn clicking on/off? */ if(argv[ARG_CLICK]) { if(!Strcmp(argv[ARG_CLICK],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Click disabled."); DSeg -> Click = FALSE; } else { if(!Strcmp(argv[ARG_CLICK],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Click enabled."); DSeg -> Click = TRUE; } else Puts(CLI_Help); } } /* Select new front colour? */ if(argv[ARG_TEXTCOLOUR]) { DSeg -> TextColour = Atol(argv[ARG_TEXTCOLOUR]); if(!Quiet) Printf("\33[1mDClock:\33[0m Text colour set to %ld.\n",DSeg -> TextColour); } /* Select new background colour? */ if(argv[ARG_BACKCOLOUR]) { DSeg -> BackColour = Atol(argv[ARG_BACKCOLOUR]); if(!Quiet) Printf("\33[1mDClock:\33[0m Background colour set to %ld.\n",DSeg -> BackColour); } /* Set/check alarm status. */ if(argv[ARG_ALARM]) { if(!Strcmp(argv[ARG_ALARM],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Alarm disabled."); DSeg -> Alarm = FALSE; } else { if(!Strcmp(argv[ARG_ALARM],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Alarm enabled."); DSeg -> Alarm = TRUE; } else { if(!Strcmp(argv[ARG_ALARM],"SHOW")) Printf("\33[1mDClock:\33[0m Current alarm time is %02ld:%02ld:%02ld.\n",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond); else Puts(CLI_Help); } } } /* Adjust alarm time. */ if(argv[ARG_ALARMTIME]) { char TimeBuff[3]; LONG TheTime; TimeBuff[2] = 0; if(strlen(argv[ARG_ALARMTIME]) != 8) { Puts("\33[1mDClock:\33[0m Alarm time format = HH:MM:SS, example: 09:03:07."); exit(RETURN_ERROR); } TimeBuff[0] = argv[ARG_ALARMTIME][0]; TimeBuff[1] = argv[ARG_ALARMTIME][1]; TheTime = Atol(TimeBuff); if(TheTime < 0 || TheTime > 23) { Puts("\33[1mDClock:\33[0m Illegal time value, Hours must be within 0 ... 23."); exit(RETURN_ERROR); } DSeg -> AlarmHour = TheTime; TimeBuff[0] = argv[ARG_ALARMTIME][3]; TimeBuff[1] = argv[ARG_ALARMTIME][4]; TheTime = Atol(TimeBuff); if(TheTime < 0 || TheTime > 59) { Puts("\33[1mDClock:\33[0m Illegal time value, Minutes must be within 0 ... 59."); exit(RETURN_ERROR); } DSeg -> AlarmMinute = TheTime; TimeBuff[0] = argv[ARG_ALARMTIME][6]; TimeBuff[1] = argv[ARG_ALARMTIME][7]; TheTime = Atol(TimeBuff); if(TheTime < 0 || TheTime > 59) { Puts("\33[1mDClock:\33[0m Illegal time value, Seconds must be within 0 ... 59."); exit(RETURN_ERROR); } DSeg -> AlarmSecond = TheTime; if(!Quiet) Printf("\33[1mDClock:\33[0m Alarm time set to %02ld:%02ld:%02ld.\n",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond); } if(argv[ARG_REFRESH]) { if(CloseWorkBench()) OpenWorkBench(); if(!Quiet) Puts("\33[1mDClock:\33[0m Main window refreshed."); } /* Set environment variables? */ if(argv[ARG_SETENV]) { if(!Strcmp(argv[ARG_SETENV],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Environment variables disabled."); DSeg -> SetEnv = FALSE; } else { if(!Strcmp(argv[ARG_SETENV],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Environment variables enabled."); DSeg -> SetEnv = TRUE; } else Puts(CLI_Help); } } /* Set countdown timeout? */ if(argv[ARG_COUNTDOWN]) { if(Atol(argv[ARG_COUNTDOWN]) > 0) { DSeg -> Countdown = Atol(argv[ARG_COUNTDOWN]); if(!Quiet) Printf("\33[1mDClock:\33[0m Countdown set to %ld.\n",DSeg -> Countdown); } else Puts(CLI_Help); } /* Enable/disable the hour chime? */ if(argv[ARG_HOUR]) { if(!Strcmp(argv[ARG_HOUR],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Hour chime disabled."); DSeg -> Hour = FALSE; } else { if(!Strcmp(argv[ARG_HOUR],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Hour chime enabled."); DSeg -> Hour = TRUE; } else Puts(CLI_Help); } } /* Display seconds or not? */ if(argv[ARG_SECONDS]) { if(!Strcmp(argv[ARG_SECONDS],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Seconds disabled."); DSeg -> Seconds = FALSE; } else { if(!Strcmp(argv[ARG_SECONDS],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Seconds enabled."); DSeg -> Seconds = TRUE; } else Puts(CLI_Help); } } /* Load a sound file? */ if(argv[ARG_SOUND]) { if(LoadChimeSound(argv[ARG_SOUND])) { if(!Strcmp(argv[ARG_SOUND],"OFF") && !Quiet) Puts("\33[1mDClock:\33[0m Chime sound reset."); } } /* Show a special page on startup? */ if(argv[ARG_PAGE] && DSeg) { UBYTE Page = Atol(argv[ARG_PAGE]); if(Page >= 0 && Page <= 4 || (Page == 4 && DSeg -> Countdown > 0)) { if(!Quiet) Printf("\33[1mDClock:\33[0m Showing display page %ld.\n",DSeg -> Page = Page); } else Puts("\33[1mDClock:\33[0m Page value out of limits (must be 0-3/4)."); } /* Turn the speech on/off? */ if(argv[ARG_SPEECH]) { if(!Strcmp(argv[ARG_SPEECH],"OFF")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Speech now off."); DSeg -> Speech = FALSE; } else { if(!Strcmp(argv[ARG_SPEECH],"ON")) { if(!Quiet) Puts("\33[1mDClock:\33[0m Speech now on."); DSeg -> Speech = TRUE; } else Puts(CLI_Help); } } exit(RETURN_OK); }