home *** CD-ROM | disk | FTP | other *** search
- /* DClock-Handler.c *********************************************************
- *
- * DClock-Handler.c ------ Dumb clock main handler routines,
- * display clock data, handle
- * DisplayBeep, etc.
- *
- * 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.0a, CygnusEd Professional 2 & ARexx.
- *
- ***************************************************************************/
-
- /* Signal flag aliases. */
-
- #define SIG_CLICK SIGBREAKF_CTRL_C
- #define SIG_CLOSE SIGBREAKF_CTRL_D
- #define SIG_TIMER SIGBREAKF_CTRL_E
- #define SIG_TOGGL SIGBREAKF_CTRL_F
- #define SIG_SHAKE SIGBREAKF_CTRL_D
- #define SIG_BENCH (1 << BenchSig)
- #define SIG_WINDO (1 << Window -> UserPort -> mp_SigBit)
- #define SIG_DISPL (1 << DisplaySig)
- #define SIG_SPEECH (1 << SpeechSig)
-
- /* Prototypes. */
-
- struct InputEvent * EventHandler(struct InputEvent *Event);
- VOID Click(VOID);
- VOID FlushSound(VOID);
- UBYTE InitSound(VOID);
- UBYTE InitHandler(VOID);
- VOID FlushHandler(VOID);
- VOID ModifiedCloseWBench(struct Screen *);
- VOID AudioBeep(VOID);
- VOID VideoBeep(struct Screen *Screen,BYTE Perform);
- VOID ModifiedDisplayBeep(struct Screen *Screen);
- VOID PrintIt(STRPTR TimeBuff);
- VOID Ring(LONG Tea);
- VOID ShowTime(UBYTE ReallyDoIt,UBYTE Force);
- ULONG MaxMemSize(ULONG MemType);
- struct Screen * FindTheBench(VOID);
- VOID ShutDown(LONG HandShake);
- LONG RangeRand(LONG);
- struct Process * CreateFuncProc(char *Name,LONG Priority,APTR InitCode,ULONG StackSize);
- UBYTE MaxFontWidth(VOID);
- VOID DeleteDummyRPort(VOID);
- BYTE CreateDummyRPort(VOID);
- VOID Format(VOID *,char *,...);
- LONG PlayChime(VOID);
- VOID StopChime(VOID);
- LONG FindChunk(ULONG ChunkName,BPTR FileHandle);
- LONG LoadChimeSound(char *Name);
-
- extern VOID NewDisplayBeep(VOID);
- extern VOID NewCloseWBench(VOID);
-
- /* The ARexx server routines. */
-
- STRPTR CheckDClockStatus(STRPTR);
- VOID RexxServer(VOID);
-
- /* Interrupt register saving functions. */
-
- VOID int_start(VOID);
- VOID int_end(VOID);
-
- /* System specific functions. */
-
- VOID setenv(char *,char *);
- LONG _main(VOID);
-
- /* The speech server. */
-
- VOID SpeechServer(VOID);
-
- /* The magic pragmas. */
-
- #pragma regcall(EventHandler(a0))
- #pragma regcall(ModifiedDisplayBeep(a0))
-
- /* Some global data. */
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- extern struct ExecBase *SysBase;
- struct Library *DiskfontBase;
- struct RexxHostBase *RexxHostBase;
- struct Window *Window;
- struct Process *HandlerProcess;
- struct Process *RexxProcess;
- struct MsgPort *RexxTaskPort;
- struct Process *SpeechProcess;
- struct DSeg *DSeg;
- BYTE NewKick = FALSE;
- BYTE Printed = FALSE;
- LONG BenchSig = -1;
- LONG DisplaySig = -1;
- LONG SpeechSig = -1;
-
- /* Our current version tag. */
-
- const char *VersionTag = "$VER: DClock-Handler 1.27 (26 Jul 1990)\n\r";
-
- /* Online time. */
-
- UBYTE OnlineHours = 0,OnlineMinutes = 0,OnlineSeconds = 0;
-
- /* The chime data. */
-
- struct IOAudio *ChimeAudioBlock;
- struct MsgPort *ChimeReplyPort;
- UBYTE *ChimeWaveMap;
-
- /* Our dummy RastPort. */
-
- struct BitMap *DummyMap;
- struct RastPort *DummyRPort;
- struct TextFont *DummyFont;
- BYTE DummyDepth;
-
- /* Static DClock window size and location. */
-
- LONG LeftEdge = 409,TopEdge = 1,Width = 176,Height = 8;
-
- /* Audio.device control structures. */
-
- struct MsgPort *AudioPort;
- struct IOAudio *Audio;
-
- /* Input.device control structures. */
-
- struct MsgPort *InputDevPort;
- struct IOStdReq *InputRequestBlock;
-
- /* The interrupt handler control. */
-
- struct Interrupt *InputHandler;
-
- /* Console.device control structures. */
-
- struct Device *ConsoleDevice;
- struct IOStdReq *ConStdReq;
- struct InputEvent *CopyEvent;
-
- /* The library offset pointers (old ones). */
-
- VOID *OldDisplayBeep;
- VOID *OldCloseWBench;
-
- /* External data. */
-
- extern ULONG SoundData[67];
- extern ULONG RingData[1831];
- extern USHORT ClockMap[456];
- extern struct TextAttr DefaultFont;
- extern struct IntuiText TimeString;
- extern struct NewWindow NewWindow;
- extern UBYTE AnyChannel[4];
- extern UBYTE SquareWave[4];
- extern struct Image ClockImage;
- extern struct Gadget ClockGadget[2];
- extern struct NewWindow NewClockWindow;
- extern struct IntuiText ClockTxt[4];
-
- /* EventHandler(Event) :
- *
- * This is the main interface to the handler
- * routine.
- */
-
- struct InputEvent *
- EventHandler(struct InputEvent *Event)
- {
- int_start();
-
- /* User wants to toggle text and memory mode. */
-
- if(Event -> ie_Class == IECLASS_RAWKEY && Event -> ie_Code == 0x5F && Event -> ie_Qualifier == RIGHT_AMIGA)
- {
- Event -> ie_Class = IECLASS_NULL;
-
- if(DSeg -> Child)
- Signal(DSeg -> Child,SIG_TOGGL);
- }
-
- /* User wants to know the time? */
-
- if(Event -> ie_Class == IECLASS_RAWKEY && Event -> ie_Code == 0x5F && Event -> ie_Qualifier == RIGHT_ALT)
- {
- Event -> ie_Class = IECLASS_NULL;
-
- if(DSeg -> Child)
- Signal(DSeg -> Child,SIG_SPEECH);
- }
-
- /* Modify the time display size? */
-
- if(Event -> ie_Class == IECLASS_RAWKEY && Event -> ie_Code == 0x46 && Event -> ie_Qualifier == RIGHT_AMIGA)
- {
- Event -> ie_Class = IECLASS_NULL;
-
- if(DSeg -> Child)
- Signal(DSeg -> Child,SIG_DISPL);
- }
-
- /* If we can use it, initialize the copyevent and signal
- * the main process to produce a click.
- */
-
- if(Event -> ie_Class == IECLASS_RAWKEY && !(Event -> ie_Code & IECODE_UP_PREFIX) && DSeg -> Click)
- {
- CopyEvent -> ie_Class = Event -> ie_Class;
- CopyEvent -> ie_Code = Event -> ie_Code;
- CopyEvent -> ie_Qualifier = Event -> ie_Qualifier;
-
- /* This is safe from interrupt code, or
- * at least should be.
- */
-
- if(DSeg -> Child)
- Signal(DSeg -> Child,SIG_CLICK);
- }
-
- /* I had a lot of trouble getting DClock-Handler to
- * work with timer.device. Well, the only thing
- * happening in time were system crashes, so I
- * decided to use the timer entries of the
- * InputEvent structures.
- */
-
- if(Event -> ie_TimeStamp . tv_secs != DSeg -> LastSecs)
- {
- DSeg -> LastSecs = Event -> ie_TimeStamp . tv_secs;
-
- if(DSeg -> Child)
- Signal(DSeg -> Child,SIG_TIMER);
-
- /* Each second we take a look at CIA B, port A
- * to find out if a carrier signal is currently
- * present at the serial port. Note that the port
- * bits are low-active.
- */
-
- if(!(ciab . ciapra & CIAF_COMCD))
- {
- /* Are we online? */
-
- if(!DSeg -> Online)
- {
- /* Reset counters. */
-
- OnlineHours = OnlineMinutes = OnlineSeconds = 0;
- DSeg -> Online = TRUE;
- }
-
- /* Increment time counter. */
-
- if(++OnlineSeconds == 60)
- {
- OnlineSeconds = 0;
-
- if(++OnlineMinutes == 60)
- {
- OnlineMinutes = 0;
-
- ++OnlineHours;
- }
- }
- }
- else
- DSeg -> Online = FALSE;
- }
-
- int_end();
-
- return(Event);
- }
-
- /* Click() :
- *
- * Produces the click (or what did you expect?).
- */
-
- VOID
- Click()
- {
- char PrimaryBuffer[11]; /* Rawkey conversion buffer. */
- SHORT i;
-
- /* Erase the buffer. */
-
- for(i = 0 ; i < 11 ; i++)
- PrimaryBuffer[i] = 0;
-
- /* Convert the input event according to the
- * current keymap settings.
- */
-
- RawKeyConvert(CopyEvent,PrimaryBuffer,10,NULL);
-
- /* If it didn't produce a sensible result,
- * don't click.
- */
-
- if(!PrimaryBuffer[0])
- return;
-
- Audio -> ioa_Volume = DSeg -> ClickVolume;
-
- /* Let it click. */
-
- Tick: if(CheckIO(Audio))
- BeginIO(Audio);
- }
-
- /* FlushSound() :
- *
- * Send the sound control data to NIL:
- */
-
- VOID
- FlushSound()
- {
- if(Audio)
- {
- /* Audio device still open? */
-
- if(Audio -> ioa_Request . io_Device)
- {
- if(!CheckIO(Audio))
- WaitIO(Audio);
-
- /* Free the channel(s). */
-
- CloseDevice(Audio);
- }
-
- /* Free the audio control block. */
-
- FreeMem(Audio,sizeof(struct IOAudio));
- }
-
- /* Delete the replyport. */
-
- if(AudioPort)
- DeletePort(AudioPort);
- }
-
- /* InitSound() :
- *
- * Sets up the audio control structures.
- */
-
- UBYTE
- InitSound()
- {
- if(!(Audio = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- if(!(AudioPort = (struct MsgPort *)CreatePort(NULL,0)))
- return(FALSE);
-
- /* Open the channel. */
-
- if(OpenDevice(AUDIONAME,0,Audio,0))
- return(FALSE);
-
- /* Try to allocate a vacant channel. */
-
- Audio -> ioa_Request . io_Command = ADCMD_ALLOCATE;
- Audio -> ioa_Request . io_Flags = ADIOF_NOWAIT;
- Audio -> ioa_Request . io_Message . mn_Node . ln_Pri = 100;
- Audio -> ioa_Request . io_Message . mn_ReplyPort = AudioPort;
- Audio -> ioa_Data = AnyChannel;
- Audio -> ioa_Length = 4;
-
- /* Try the allocation. */
-
- BeginIO(Audio);
-
- /* Did it return an error? */
-
- if(WaitIO(Audio))
- return(FALSE);
-
- /* Prepare it for the click. */
-
- Audio -> ioa_Request . io_Command = CMD_WRITE;
- Audio -> ioa_Request . io_Flags = ADIOF_PERVOL | ADIOF_NOWAIT;
- Audio -> ioa_Period = 180;
- Audio -> ioa_Volume = 0;
- Audio -> ioa_Length = 270;
- Audio -> ioa_Data = (UBYTE *)SoundData;
- Audio -> ioa_Cycles = 1;
-
- /* Click once. */
-
- BeginIO(Audio);
- WaitIO(Audio);
-
- return(TRUE);
- }
-
- /* InitHandler() :
- *
- * Open the console.device for keymap translation
- * and add the input.device handler.
- */
-
- UBYTE
- InitHandler()
- {
- if(!(ConStdReq = (struct IOStdReq *)AllocMem(sizeof(struct IOStdReq),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- if(OpenDevice("console.device",-1,ConStdReq,0))
- return(FALSE);
-
- if(!(InputDevPort = (struct MsgPort *)CreatePort(NULL,0)))
- return(FALSE);
-
- if(!(InputRequestBlock = (struct IOStdReq *)CreateStdIO(InputDevPort)))
- return(FALSE);
-
- if(OpenDevice("input.device",0,InputRequestBlock,0))
- return(FALSE);
-
- if(!(InputHandler = (struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- if(!(CopyEvent = (struct InputEvent *)AllocMem(sizeof(struct InputEvent),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- InputHandler -> is_Node . ln_Name = "DClock-Handler";
- InputHandler -> is_Node . ln_Pri = 51;
- InputHandler -> is_Code = (VOID *)EventHandler;
-
- InputRequestBlock -> io_Command = IND_ADDHANDLER;
- InputRequestBlock -> io_Data = (APTR)InputHandler;
-
- DoIO(InputRequestBlock);
-
- ConsoleDevice = ConStdReq -> io_Device;
-
- return(TRUE);
- }
-
- /* FlushHandler() :
- *
- * Closes the console.device and removes the
- * input.device handler from the chain.
- */
-
- VOID
- FlushHandler()
- {
- if(ConsoleDevice)
- CloseDevice(ConStdReq);
-
- if(InputRequestBlock)
- {
- if(InputRequestBlock -> io_Device)
- {
- InputRequestBlock -> io_Command = IND_REMHANDLER;
- InputRequestBlock -> io_Data = (APTR)InputHandler;
-
- DoIO(InputRequestBlock);
-
- CloseDevice(InputRequestBlock);
- }
-
- DeleteStdIO(InputRequestBlock);
- }
-
- if(ConStdReq)
- FreeMem(ConStdReq,sizeof(struct IOStdReq));
-
- if(CopyEvent)
- FreeMem(CopyEvent,sizeof(struct InputEvent));
-
- if(InputHandler)
- FreeMem(InputHandler,sizeof(struct Interrupt));
-
- if(InputDevPort)
- DeletePort(InputDevPort);
- }
-
- /* ModifiedCloseWBench():
- *
- * Tells DClock to close its window before the
- * Workbench screen gets closed.
- */
-
- VOID
- ModifiedCloseWBench()
- {
- if(Window)
- {
- struct Task *ThisTask = SysBase -> ThisTask;
- BYTE CurrentPri;
-
- /* Shut down... */
-
- Signal(DSeg -> Child,SIG_BENCH);
-
- /* Careful - rather rude window close check,
- * don't waste too much time in the loop.
- */
-
- CurrentPri = SetTaskPri(ThisTask,0);
-
- while(Window);
-
- SetTaskPri(ThisTask,CurrentPri);
- }
- }
-
- VOID
- AudioBeep()
- {
- struct IOAudio *AudioBlock;
- struct MsgPort *ReplyPort;
-
- /* Allocate some driver memory. */
-
- if(AudioBlock = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR))
- {
- /* Time for a replyport? */
-
- if(ReplyPort = (struct MsgPort *)CreatePort(NULL,0))
- {
- AudioBlock -> ioa_Request . io_Message . mn_ReplyPort = ReplyPort;
-
- if(!OpenDevice(AUDIONAME,0,AudioBlock,0))
- {
- /* Set up initial driver data. */
-
- AudioBlock -> ioa_Request . io_Command = ADCMD_ALLOCATE;
- AudioBlock -> ioa_Request . io_Message . mn_Node . ln_Pri = 90;
- AudioBlock -> ioa_Data = &AnyChannel[0];
- AudioBlock -> ioa_Length = 4;
-
- if(!DoIO(AudioBlock))
- {
- AudioBlock -> ioa_Request . io_Command = CMD_WRITE;
- AudioBlock -> ioa_Request . io_Flags = ADIOF_PERVOL;
- AudioBlock -> ioa_Period = 447;
- AudioBlock -> ioa_Volume = 64 / 2;
- AudioBlock -> ioa_Cycles = 150;
- AudioBlock -> ioa_Data = &SquareWave[0];
- AudioBlock -> ioa_Length = 4;
-
- /* Beeep! */
-
- BeginIO(AudioBlock);
- WaitIO(AudioBlock);
- }
-
- CloseDevice(AudioBlock);
- }
-
- DeletePort(ReplyPort);
- }
-
- FreeMem(AudioBlock,sizeof(struct IOAudio));
- }
- }
-
- /* VideoBeep(Screen,Perform):
- *
- * Handles the visual part of the DisplayBeep,
- * flashes a particular screen or restores its
- * original colour (well, hope so).
- */
-
- VOID
- VideoBeep(struct Screen *Screen,BYTE Perform)
- {
- UBYTE R,G,B;
-
- /* Beep this screen? */
-
- if(Perform)
- {
- /* Is it already beeping? */
-
- if(!(Screen -> Flags & BEEPING))
- {
- /* This one's beeping. */
-
- Screen -> Flags |= BEEPING;
-
- /* Don't forget this one. */
-
- Screen -> SaveColor0 = GetRGB4(Screen -> ViewPort . ColorMap,0);
-
- /* Reverse the colour. */
-
- R = ((Screen -> SaveColor0 >> 8) & 0xF) ^ 0xF;
- G = ((Screen -> SaveColor0 >> 4) & 0xF) ^ 0xF;
- B = ((Screen -> SaveColor0 ) & 0xF) ^ 0xF;
-
- /* Set it. */
-
- SetRGB4(&Screen -> ViewPort,0,R,G,B);
- }
- }
- else
- {
- /* Is this one beeping? */
-
- if(Screen -> Flags & BEEPING)
- {
- /* This one isn't beeping any longer. */
-
- Screen -> Flags &= ~BEEPING;
-
- /* Restore the saved colour. */
-
- R = ((Screen -> SaveColor0 >> 8) & 0xF);
- G = ((Screen -> SaveColor0 >> 4) & 0xF);
- B = ((Screen -> SaveColor0 ) & 0xF);
-
- SetRGB4(&Screen -> ViewPort,0,R,G,B);
- }
- }
- }
-
- /* ModifiedDisplayBeep(Screen):
- *
- * Magic replacement for usual DisplayBeep()
- * function.
- */
-
- VOID
- ModifiedDisplayBeep(struct Screen *Screen)
- {
- /* Flash a particular screen. */
-
- if(Screen)
- {
- VideoBeep(Screen,TRUE);
-
- if(DSeg -> Beep)
- AudioBeep();
-
- VideoBeep(Screen,FALSE);
- }
- else
- {
- /* Flash all screens. */
-
- ULONG IntuiLock;
-
- /* Where's the first one? Has anybody
- * used the LockIBase() function so
- * far (save me)?
- */
-
- IntuiLock = LockIBase(NULL);
-
- Screen = IntuitionBase -> FirstScreen;
-
- /* Walk through the screens flashing them all. */
-
- do
- VideoBeep(Screen,TRUE);
- while(Screen = Screen -> NextScreen);
-
- UnlockIBase(IntuiLock);
-
- /* Let it resound. */
-
- if(DSeg -> Beep)
- AudioBeep();
-
- /* Again: where's the first screen? */
-
- IntuiLock = LockIBase(NULL);
-
- Screen = IntuitionBase -> FirstScreen;
-
- do
- VideoBeep(Screen,FALSE);
- while(Screen = Screen -> NextScreen);
-
- UnlockIBase(IntuiLock);
- }
- }
-
- /* PrintIt(TimeBuff,CharOffset):
- *
- * Prints the formatted string into the Workbench title bar.
- */
-
- VOID
- PrintIt(STRPTR TimeBuff)
- {
- BYTE Length = strlen((char *)TimeBuff);
- BYTE Offset = Width - TextLength(DummyRPort,TimeBuff,Length);
-
- SetAPen(DummyRPort,DSeg -> TextColour);
- SetBPen(DummyRPort,DSeg -> BackColour);
-
- SetRast(DummyRPort,1);
-
- Move(DummyRPort,(Offset >= 0 ? Offset : 0),DummyRPort -> Font -> tf_Baseline);
- Text(DummyRPort,TimeBuff,Length);
- }
-
- /* Ring():
- *
- * This one rings the bell of the alarm clock.
- */
-
- VOID
- Ring(LONG Tea)
- {
- struct IOAudio *AudioBlock;
- struct MsgPort *ReplyPort;
-
- struct Screen PublicScreen;
- struct Screen *FirstOne;
- struct Window *ClockWindow;
- struct IntuiMessage *Massage;
-
- ULONG Class;
- USHORT Code;
- struct Gadget *ID;
-
- ULONG IntuiLock;
- struct View *ViewLord;
-
- SHORT DyOffset,PlusY;
- LONG TimeOut;
-
- /* Remember initial first screen. */
-
- IntuiLock = LockIBase(NULL);
- FirstOne = IntuitionBase -> FirstScreen;
- UnlockIBase(IntuiLock);
-
- /* Knockin' on heaven's door... */
-
- OpenWorkBench();
-
- /* Center the clock window. */
-
- GetScreenData(&PublicScreen,sizeof(struct Screen),WBENCHSCREEN,NULL);
-
- NewClockWindow . LeftEdge = (PublicScreen . Width - NewClockWindow . Width) / 2;
- NewClockWindow . TopEdge = (PublicScreen . Height - NewClockWindow . Height) / 2;
-
- /* Open it and paint the background. */
-
- if(!(ClockWindow = (struct Window *)OpenWindow(&NewClockWindow)))
- {
- DisplayBeep(NULL);
- goto Quit;
- }
-
- if(NewKick)
- SetAPen(ClockWindow -> RPort,2);
- else
- SetAPen(ClockWindow -> RPort,1);
-
- RectFill(ClockWindow -> RPort,2,1,ClockWindow -> Width - 3,ClockWindow -> Height - 2);
-
- RefreshGadgets(&ClockGadget[0],ClockWindow,NULL);
-
- /* Adjust the contents of the alarm time string. */
-
- if(Tea)
- Format(ClockTxt[3] . IText,"Alarm time » %2ld:%02ld:%02ld «",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond);
- else
- strcpy((char *)ClockTxt[3] . IText,"Countdown elapsed!");
-
- PrintIText(ClockWindow -> RPort,&ClockTxt[0],0,0);
-
- /* Allocate some driver memory. */
-
- if(AudioBlock = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR))
- {
- /* Time for a replyport? */
-
- if(ReplyPort = (struct MsgPort *)CreatePort(NULL,0))
- {
- /* Set up initial driver data. */
-
- AudioBlock -> ioa_Data = &AnyChannel[0];
- AudioBlock -> ioa_Length = 4;
- AudioBlock -> ioa_Request . io_Message . mn_ReplyPort = ReplyPort;
- AudioBlock -> ioa_Request . io_Message . mn_Node.ln_Pri = 80;
-
- /* Allocate the channels on the fly. */
-
- if(!OpenDevice(AUDIONAME,0,AudioBlock,0))
- {
- AudioBlock -> ioa_Request . io_Command = CMD_WRITE;
- AudioBlock -> ioa_Request . io_Flags = ADIOF_PERVOL;
- AudioBlock -> ioa_Period = 308;
- AudioBlock -> ioa_Volume = 64;
- AudioBlock -> ioa_Cycles = 1;
- AudioBlock -> ioa_Data = (UBYTE *)&RingData[0];
- AudioBlock -> ioa_Length = 7326;
-
- IntuiLock = LockIBase(NULL);
- ViewLord = &IntuitionBase -> ViewLord;
- UnlockIBase(IntuiLock);
-
- DyOffset = ViewLord -> DyOffset;
-
- /* Ring! */
-
- BeginIO(AudioBlock);
-
- WBenchToFront();
-
- TimeOut = 0;
-
- /* Ring until somebody clicked our window
- * or a timeout occurs.
- */
-
- FOREVER
- {
- /* Cycles already finished. */
-
- if(CheckIO(AudioBlock))
- BeginIO(AudioBlock);
-
- Class = Code = NULL;
-
- if(Massage = GetMsg(ClockWindow -> UserPort))
- {
- Class = Massage -> Class;
- Code = Massage -> Code;
- ID = (struct Gadget *)Massage -> IAddress;
-
- ReplyMsg(Massage);
-
- if((Class == GADGETUP && !ID -> GadgetID) || Class == VANILLAKEY)
- break;
- }
-
- PlusY = 1 - RangeRand(3);
-
- /* Make the view vibrate. */
-
- if(DyOffset + PlusY >= 0)
- ViewLord -> DyOffset = DyOffset + PlusY;
-
- RethinkDisplay();
-
- /* Wait a tick. */
-
- Delay(1);
-
- /* Now for the timeout... */
-
- if((TimeOut++) >= (TICKS_PER_SECOND * 30))
- break;
- }
-
- ViewLord -> DyOffset = DyOffset;
- RethinkDisplay();
-
- /* Still ringing? */
-
- if(!CheckIO(AudioBlock))
- WaitIO(AudioBlock);
-
- /* Tick! */
-
- CloseDevice(AudioBlock);
- }
-
- DeletePort(ReplyPort);
- }
-
- FreeMem(AudioBlock,sizeof(struct IOAudio));
- }
-
- /* Bring original first screen to the front again. */
-
- Quit: if(FirstOne != ClockWindow -> WScreen)
- ScreenToBack(ClockWindow -> WScreen);
-
- if(ClockWindow)
- CloseWindow(ClockWindow);
- }
-
- /* ShowTime(ReallyDoIt,Force):
- *
- * Yes, it's Showtime! This one compiles the date/timestring
- * and prints it.
- */
-
- VOID
- ShowTime(UBYTE ReallyDoIt,UBYTE Force)
- {
- UBYTE TempBuff[30];
-
- static char *Months[12] =
- {
- "Jan","Feb","Mar",
- "Apr","May","Jun",
- "Jul","Aug","Sep",
- "Oct","Nov","Dec"
- };
-
- static char *Days[7] =
- {
- "Sun", /* Note: these have to appear right in this order. */
- "Mon",
- "Tue",
- "Wed",
- "Thu",
- "Fri",
- "Sat"
- };
-
- static char *LongDays[7] =
- {
- "Sunday",
- "Monday",
- "Tuesday",
- "Wednesday",
- "Thursday",
- "Friday",
- "Saturday"
- };
-
- static char DateBuff[15],TimeBuff[10];
-
- static UBYTE LastState = 2;
-
- static SHORT MonthVectors[14] =
- {
- -1, -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
- };
-
- LONG JulianDate, Day0, Day1, Day2, Day3;
- LONG Year, Month, Day;
-
- struct DateStamp Date;
-
- DateStamp(&Date);
-
- JulianDate = Date . ds_Days + DDELTA;
-
- Year = (JulianDate / 146097) * 400;
-
- Day0 = Day1 = JulianDate %= 146097;
-
- Year += (JulianDate / 36524) * 100;
-
- Day2 = Day1 %= 36524;
-
- Year += (Day2 / 1461) * 4;
-
- Day3 = Day1 %= 1461;
-
- Year += Day3 / 365;
-
- Month = 1 + (Day1 %= 365);
-
- Day = Month % 30;
-
- Month /= 30;
-
- if((Day3 >= 59 && Day0 < 59) || (Day3 < 59 && (Day2 >= 59 || Day0 < 59)))
- Day1++;
-
- if(Day1 > MonthVectors[1 + Month])
- Month++;
-
- Day = Day1 - MonthVectors[Month];
-
- DSeg -> CurrentTime . Year = Year;
- DSeg -> CurrentTime . Month = Month;
- DSeg -> CurrentTime . Day = Day;
- DSeg -> CurrentTime . Weekday = Date . ds_Days % DAYS_PER_WEEK;
-
- DSeg -> CurrentTime . Hour = Date . ds_Minute / MINS_PER_HOUR;
- DSeg -> CurrentTime . Minute = Date . ds_Minute % MINS_PER_HOUR;
- DSeg -> CurrentTime . Second = Date . ds_Tick / TICS_PER_SEC;
-
- /* Did we need a change? */
-
- if(LastState != DSeg -> Seconds)
- {
- LastState = DSeg -> Seconds;
- Force = TRUE;
- }
-
- if(ReallyDoIt)
- {
- if(DSeg -> Seconds)
- {
- Format(TempBuff,"%s %02ld-%s-%02ld %02ld:%02ld:%02ld",
- Days[DSeg -> CurrentTime . Weekday],
- DSeg -> CurrentTime . Day,
- Months[DSeg -> CurrentTime . Month - 1],
- DSeg -> CurrentTime . Year % 100,
- DSeg -> CurrentTime . Hour,
- DSeg -> CurrentTime . Minute,
- DSeg -> CurrentTime . Second);
-
- PrintIt(TempBuff);
- }
- else
- {
- if(!(Date . ds_Tick / TICKS_PER_SECOND) || Force)
- {
- Format(TempBuff,"%s %02ld-%s-%02ld %02ld:%02ld",
- Days[DSeg -> CurrentTime . Weekday],
- DSeg -> CurrentTime . Day,
- Months[DSeg -> CurrentTime . Month - 1],
- DSeg -> CurrentTime . Year % 100,
- DSeg -> CurrentTime . Hour,
- DSeg -> CurrentTime . Minute);
-
- SetRast(DummyRPort,1);
-
- PrintIt(TempBuff);
- }
- }
- }
-
- if((!DSeg -> CurrentTime . Second || !Printed) && DSeg -> SetEnv)
- {
- Printed = TRUE;
-
- Format(DateBuff,"%02ld-%s-%02ld",Day,Months[DSeg -> CurrentTime . Month - 1],DSeg -> CurrentTime . Year % 100);
- Format(TimeBuff,"%02ld:%02ld",DSeg -> CurrentTime . Hour,DSeg -> CurrentTime . Minute);
-
- setenv("DAY",LongDays[DSeg -> CurrentTime . Weekday]);
- setenv("DATE",DateBuff);
- setenv("TIME",TimeBuff);
- }
- }
-
- /* MaxMemSize(MemType):
- *
- * Returns the length of memory block of a special
- * kind. Borrowed from Louis A. Mamakos' GfxMem 0.4.
- */
-
- ULONG
- MaxMemSize(ULONG MemType)
- {
- ULONG BlockSize = 0;
- struct MemHeader *MemHeader;
-
- Forbid();
-
- /* Walk through the memory lists adding the
- * amount of memory bound to them.
- */
-
- for(MemHeader = (struct MemHeader *)SysBase -> MemList . lh_Head ; MemHeader -> mh_Node . ln_Succ ; MemHeader = (struct MemHeader *)MemHeader -> mh_Node . ln_Succ)
- {
- if(MemHeader -> mh_Attributes & MemType)
- BlockSize += ((ULONG)MemHeader -> mh_Upper - (ULONG)MemHeader -> mh_Lower);
- }
-
- Permit();
-
- return(BlockSize);
- }
-
- /* FindTheBench():
- *
- * Tries to locate the Workbench screen in the linked list
- * of system screens. This is rather a rude method and should
- * be exercised only while Intuition is locked.
- *
- * This could be lot easier if using LockPubScreen().
- */
-
- struct Screen *
- FindTheBench()
- {
- struct Screen *WBench;
- ULONG IntuiLock = LockIBase(NULL);
-
- /* Start with the first one. */
-
- WBench = IntuitionBase -> FirstScreen;
-
- /* Scan the list... */
-
- do
- {
- /* The type we want? */
-
- if((WBench -> Flags & SCREENTYPE) == WBENCHSCREEN)
- {
- UnlockIBase(IntuiLock);
- return(WBench);
- }
- }
- while(WBench = WBench -> NextScreen);
-
- /* Failed! */
-
- UnlockIBase(IntuiLock);
-
- return(NULL);
- }
-
- /* PlayChime():
- *
- * Plays the hour chime.
- */
-
- LONG
- PlayChime()
- {
- LONG Rate = 1788,Length = 4,Cycles = 150,Volume = 64 / 2;
-
- if(ChimeReplyPort)
- return(FALSE);
-
- ObtainSemaphore(DSeg -> SoundSemaphore);
-
- if(DSeg -> SoundData && DSeg -> SoundLength)
- {
- ChimeWaveMap = (UBYTE *)DSeg -> SoundData;
- Length = DSeg -> SoundLength;
- Volume = DSeg -> SoundVolume;
- Rate = DSeg -> SoundRate;
- Cycles = 1;
- }
- else
- ChimeWaveMap = &SquareWave[0];
-
- /* Allocate some driver memory. */
-
- if(!(ChimeAudioBlock = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_CLEAR)))
- {
- ReleaseSemaphore(DSeg -> SoundSemaphore);
- return(FALSE);
- }
-
- /* Time for a replyport? */
-
- if(!(ChimeReplyPort = (struct MsgPort *)CreatePort(NULL,0)))
- {
- FreeMem(ChimeAudioBlock,sizeof(struct IOAudio));
-
- ChimeAudioBlock = NULL;
-
- ReleaseSemaphore(DSeg -> SoundSemaphore);
- return(FALSE);
- }
-
- /* Set up initial driver data. */
-
- ChimeAudioBlock -> ioa_Data = &AnyChannel[0];
- ChimeAudioBlock -> ioa_Length = 4;
- ChimeAudioBlock -> ioa_Request . io_Message . mn_ReplyPort = ChimeReplyPort;
- ChimeAudioBlock -> ioa_Request . io_Message . mn_Node . ln_Pri = 90;
-
- /* Allocate the channels on the fly. */
-
- if(OpenDevice(AUDIONAME,0,ChimeAudioBlock,0))
- {
- FreeMem(ChimeAudioBlock,sizeof(struct IOAudio));
- DeletePort(ChimeReplyPort);
-
- ChimeAudioBlock = NULL;
- ChimeReplyPort = NULL;
-
- ReleaseSemaphore(DSeg -> SoundSemaphore);
- return(FALSE);
- }
-
- ChimeAudioBlock -> ioa_Request . io_Command = CMD_WRITE;
- ChimeAudioBlock -> ioa_Request . io_Flags = ADIOF_PERVOL;
- ChimeAudioBlock -> ioa_Cycles = Cycles;
- ChimeAudioBlock -> ioa_Data = ChimeWaveMap;
- ChimeAudioBlock -> ioa_Length = Length;
-
- ChimeAudioBlock -> ioa_Period = Rate;
- ChimeAudioBlock -> ioa_Volume = Volume;
-
- BeginIO(ChimeAudioBlock);
- }
-
- /* StopChime():
- *
- * Stops the hour chime.
- */
-
- VOID
- StopChime()
- {
- if(ChimeAudioBlock)
- {
- if(ChimeAudioBlock -> ioa_Request . io_Device)
- {
- if(!CheckIO(ChimeAudioBlock))
- WaitIO(ChimeAudioBlock);
-
- CloseDevice(ChimeAudioBlock);
- }
-
- if(!DSeg -> SoundData || !DSeg -> SoundLength)
- {
- if(ChimeWaveMap != &SquareWave[0])
- FreeMem(ChimeWaveMap,4);
- }
-
- FreeMem(ChimeAudioBlock,sizeof(struct IOAudio));
- DeletePort(ChimeReplyPort);
-
- ChimeAudioBlock = NULL;
- ChimeReplyPort = NULL;
-
- ReleaseSemaphore(DSeg -> SoundSemaphore);
- }
- }
-
- /* FindChunk(ChunkName,FileHandle):
- *
- * Tries to locate 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(!RexxStrCmp(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)))
- return(FALSE);
-
- /* Is it a sound file? */
-
- if(!FindChunk('8SVX',SoundHandle))
- {
- Close(SoundHandle);
-
- return(FALSE);
- }
-
- /* Look for the VoiceHeader. */
-
- if(!FindChunk('VHDR',SoundHandle))
- {
- Close(SoundHandle);
- return(FALSE);
- }
-
- /* Read the header. */
-
- if(Read(SoundHandle,&VoiceHeader,sizeof(VoiceHeader)) != sizeof(VoiceHeader))
- {
- 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))
- {
- Close(SoundHandle);
- return(FALSE);
- }
-
- /* Allocate space for the sound data. */
-
- if(!(SoundData = (APTR)AllocMem(SoundLength,MEMF_PUBLIC | MEMF_CHIP)))
- {
- Close(SoundHandle);
- return(FALSE);
- }
-
- /* Read the sound data. */
-
- if(Read(SoundHandle,SoundData,SoundLength) != SoundLength)
- {
- 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);
- }
-
- /* CheckDClockStatus(Arg):
- *
- * Checks DClock option flags and returns them.
- */
-
- STRPTR
- CheckDClockStatus(STRPTR Arg)
- {
- /* Static result string. */
-
- STATIC UBYTE Response[200];
-
- /* Every option to be checked. */
-
- STATIC STRPTR Options[17] =
- {
- "BEEP",
- "CLICK",
- "CLICKVOLUME",
- "PRIORITY",
- "TEXTCOLOUR",
- "BACKCOLOUR",
- "ALARM",
- "ALARMTIME",
- "SETENV",
- "VERSION",
- "COUNTDOWN",
- "HOUR",
- "SECONDS",
- "SOUND",
- "PAGE",
- "SPEECH",
- "LINE"
- };
-
- /* A temporary string. */
-
- UBYTE TempString[20];
-
- LONG i,TheOption = -1;
-
- /* Clear the string. */
-
- Response[0] = 0;
-
- /* Check which option matches the argument.
- * If none matches we'll produce a string
- * filled with all options.
- */
-
- for(i = 0 ; i < 16 ; i++)
- {
- if(!RexxStrCmp(Arg,Options[i]))
- {
- TheOption = i;
- break;
- }
- }
-
- /* Is it BEEP? */
-
- if(TheOption == 0 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response,Options[0]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Beep ? "ON" : "OFF"));
- }
-
- /* Is it CLICK? */
-
- if(TheOption == 1 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[1]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Click ? "ON" : "OFF"));
- }
-
- /* Is it CLICKVOLUME? */
-
- if(TheOption == 2 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[2]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> ClickVolume,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it PRIORITY? */
-
- if(TheOption == 3 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[3]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> Priority,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it TEXTCOLOUR? */
-
- if(TheOption == 4 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[4]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> TextColour,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it BACKCOLOUR? */
-
- if(TheOption == 5 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[5]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> Priority,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it ALARM? */
-
- if(TheOption == 6 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[6]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Alarm ? "ON" : "OFF"));
- }
-
- /* Is it ALARMTIME? */
-
- if(TheOption == 7 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[7]);
- strcat(Response," ");
- }
-
- Format(TempString,"%02ld:%02ld:%02ld",DSeg -> AlarmHour,DSeg -> AlarmMinute,DSeg -> AlarmSecond);
-
- strcat(Response,TempString);
- }
-
- /* Is it SETENV? */
-
- if(TheOption == 8 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[8]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> SetEnv ? "ON" : "OFF"));
- }
-
- /* Is it VERSION? */
-
- if(TheOption == 9 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[9]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> Revision,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it COUNTDOWN? */
-
- if(TheOption == 10 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[10]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> Countdown,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it HOUR? */
-
- if(TheOption == 11 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[11]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Hour ? "ON" : "OFF"));
- }
-
- /* Is it SECONDS? */
-
- if(TheOption == 12 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[12]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Seconds ? "ON" : "OFF"));
- }
-
- /* Is it SOUND? */
-
- if(TheOption == 13 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[13]);
- strcat(Response," ");
- }
-
- strcat(Response,((DSeg -> SoundData && DSeg -> SoundLength) ? "ON" : "OFF"));
- }
-
- /* Is it PAGE? */
-
- if(TheOption == 14 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[14]);
- strcat(Response," ");
- }
-
- BuildValueString(DSeg -> Page,TempString);
-
- strcat(Response,TempString);
- }
-
- /* Is it SPEECH? */
-
- if(TheOption == 15 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[15]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Speech ? "ON" : "OFF"));
- }
-
- /* Is it LINE? */
-
- if(TheOption == 16 || TheOption == -1)
- {
- if(TheOption == -1)
- {
- strcat(Response," ");
- strcat(Response,Options[16]);
- strcat(Response," ");
- }
-
- strcat(Response,(DSeg -> Online ? "ON" : "OFF"));
- }
-
- /* Return the result of our 'questionnaire'. */
-
- return(Response);
- }
-
- /* RexxServer():
- *
- * Rexx server subtask (process), handles the rexx commands
- * asynchronously.
- */
-
- VOID
- RexxServer()
- {
- struct RexxMessage *RexxMsg; /* Rexx signal message. */
- ULONG SignalSet; /* Incoming signals. */
-
- STRPTR StringResult; /* Result string (error message). */
- LONG NumResult; /* Return code. */
-
- LONG ArgCount; /* String counter. */
-
- UBYTE Arg1[20],Arg2[20]; /* Both arguments. */
-
- /* Get the base register (hey Manx, where's
- * the __saveds equivalent?).
- */
-
- geta4();
-
- /* Create the communication port. */
-
- if(!(RexxTaskPort = (struct MsgPort *)CreatePort(NULL,0)))
- goto Quit;
-
- /* Synchronization. */
-
- Signal(HandlerProcess,SIG_SHAKE);
-
- /* Ad infinitum. */
-
- FOREVER
- {
- /* Wait for a signal. */
-
- SignalSet = Wait(SIG_CLOSE | (1 << RexxTaskPort -> mp_SigBit));
-
- /* A rexx message? */
-
- if(SignalSet & (1 << RexxTaskPort -> mp_SigBit))
- {
- /* Intercept all messages. */
-
- while(RexxMsg = GetMsg(RexxTaskPort))
- {
- ArgCount = 0;
-
- /* Get the command string. */
-
- StringResult = GetRexxCommand(RexxMsg);
-
- /* Get command and argument. */
-
- GetToken(StringResult,&ArgCount,Arg1,20);
- GetToken(StringResult,&ArgCount,Arg2,20);
-
- /* Zero default values. */
-
- StringResult = NULL;
- NumResult = 0;
-
- /* Adjust Click volume? */
-
- if(!RexxStrCmp(Arg1,"CLICKVOLUME"))
- {
- if(GetStringValue(Arg2) > 64 || GetStringValue(Arg2) < 0)
- NumResult = 10;
- else
- DSeg -> ClickVolume = GetStringValue(Arg2);
- }
-
- /* Adjust task priority? */
-
- if(!RexxStrCmp(Arg1,"PRIORITY"))
- {
- if(GetStringValue(Arg2) > 127 || GetStringValue(Arg2) < -128)
- NumResult = 10;
- else
- {
- DSeg -> Priority = GetStringValue(Arg2);
- SetTaskPri(DSeg -> Child,DSeg -> Priority);
- }
- }
-
- /* Turn DisplayBeep() off? */
-
- if(!RexxStrCmp(Arg1,"BEEP"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> Beep = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> Beep = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Turn keyboard click off? */
-
- if(!RexxStrCmp(Arg1,"CLICK"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> Click = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> Click = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Set text colour? */
-
- if(!RexxStrCmp(Arg1,"TEXTCOLOUR"))
- DSeg -> TextColour = GetStringValue(Arg2);
-
- /* Set background colour? */
-
- if(!RexxStrCmp(Arg1,"BACKCOLOUR"))
- DSeg -> BackColour = GetStringValue(Arg2);
-
- /* Turn alarm on? */
-
- if(!RexxStrCmp(Arg1,"ALARM"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> Alarm = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> Alarm = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Set alarm time? */
-
- if(!RexxStrCmp(Arg1,"ALARMTIME"))
- {
- char TimeBuff[3];
- LONG TheTime;
-
- TimeBuff[2] = 0;
-
- TimeBuff[0] = Arg2[0];
- TimeBuff[1] = Arg2[1];
-
- TheTime = GetStringValue(TimeBuff);
-
- if(TheTime >= 0 && TheTime <= 23)
- DSeg -> AlarmHour = TheTime;
- else
- NumResult = 10;
-
- TimeBuff[0] = Arg2[3];
- TimeBuff[1] = Arg2[4];
-
- TheTime = GetStringValue(TimeBuff);
-
- if(TheTime >= 0 && TheTime <= 59)
- DSeg -> AlarmMinute = TheTime;
- else
- NumResult = 10;
-
- TimeBuff[0] = Arg2[6];
- TimeBuff[1] = Arg2[7];
-
- TheTime = GetStringValue(TimeBuff);
-
- if(TheTime >= 0 && TheTime <= 59)
- DSeg -> AlarmSecond = TheTime;
- else
- NumResult = 10;
- }
-
- /* Set environment variables? */
-
- if(!RexxStrCmp(Arg1,"SETENV"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> SetEnv = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> SetEnv = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Set the countdown tea timer? */
-
- if(!RexxStrCmp(Arg1,"COUNTDOWN"))
- {
- if(GetStringValue(Arg2) > 0)
- DSeg -> Countdown = GetStringValue(Arg2);
- else
- NumResult = 10;
- }
-
- /* Refresh the display? */
-
- if(!RexxStrCmp(Arg1,"REFRESH"))
- {
- if(CloseWorkBench())
- OpenWorkBench();
- }
-
- /* Turn hour alarm on? */
-
- if(!RexxStrCmp(Arg1,"HOUR"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> Hour = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> Hour = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Turn keyboard click off? */
-
- if(!RexxStrCmp(Arg1,"SECONDS"))
- {
- if(!RexxStrCmp(Arg2,"OFF"))
- DSeg -> Seconds = FALSE;
- else
- {
- if(!RexxStrCmp(Arg2,"ON"))
- DSeg -> Seconds = TRUE;
- else
- NumResult = 10;
- }
- }
-
- /* Load a sound file? */
-
- if(!RexxStrCmp(Arg1,"SOUND"))
- {
- if(!LoadChimeSound(Arg2))
- NumResult = 10;
- }
-
- /* Get a DClock status. */
-
- if(!RexxStrCmp(Arg1,"STATUS"))
- StringResult = CheckDClockStatus(Arg2);
-
- /* Show a special page? */
-
- if(!RexxStrCmp(Arg1,"PAGE"))
- {
- if(GetStringValue(Arg2) > 4 || GetStringValue(Arg2) < 0 || (GetStringValue(Arg2) == 4 && DSeg -> Countdown < 1))
- NumResult = 10;
- else
- DSeg -> Page = GetStringValue(Arg2);
- }
-
- /* Tell the current time? */
-
- if(!RexxStrCmp(Arg1,"TELLTIME"))
- {
- if(!SpeechProcess)
- {
- Forbid();
-
- if(SpeechProcess = CreateFuncProc("DClock-Speech",5,SpeechServer,4000))
- Wait(SIG_SHAKE);
-
- Permit();
- }
-
- if(SpeechProcess)
- Signal(SpeechProcess,SIG_CLICK);
- }
-
- /* Read the clock chip? */
-
- if(!RexxStrCmp(Arg1,"READTIME"))
- {
- if(!ReadClock())
- NumResult = 10;
- }
-
- /* Reply the rexx command. */
-
- ReplyRexxCommand(RexxMsg,NumResult,0,StringResult);
- }
- }
-
- /* Remove the server task. */
-
- if(SignalSet & SIG_CLOSE)
- break;
- }
-
- /* Delete the port. */
-
- Quit: if(RexxTaskPort)
- DeletePort(RexxTaskPort);
-
- /* Hey, I'm done! */
-
- Signal(HandlerProcess,SIG_SHAKE);
- }
-
- /* SpeechServer():
- *
- * Asks the narrator device to tell the time.
- */
-
- VOID
- SpeechServer()
- {
- ULONG SignalSet; /* Signal mask. */
- struct MsgPort *NarratorPort; /* Narrator reply port. */
- struct narrator_rb *NarratorRequest; /* Narrator device link. */
-
- char WorkString[40]; /* Phoneme string. */
-
- /* Numbers above twenty. */
-
- static char *AboveTwenty[4] =
- {
- "TWEH4NTIY4",
- "THER4TIY4",
- "FOH4RTIY4",
- "FIH4FTIY4"
- };
-
- /* Numbers from zero to nineteen. */
-
- static char *SingleNumbers[20] =
- {
- "ZIY4ROW",
- "WAH4N",
- "TUW4",
- "THRIY4",
- "FOH4R",
- "FAY4V",
- "SIH4KKSZ",
- "SEH4VVEHN",
- "EY4T",
- "NAY4N",
- "TEH4N",
- "IY4LAEEHFAEEHN",
- "TWEH4LF",
- "THER4TIY4N",
- "FOH4RTIY4N",
- "FIH4FTIY4N",
- "SIH4KKSZTIY4N",
- "SEH4VVEHNTIY4N",
- "EY3TIY4N",
- "NAY4NTIY4N"
- };
-
- /* The two halves of the day. */
-
- static char *TimeOfDay[2] =
- {
- " EY5EH3M.",
- " BPIY5EH3M."
- };
-
- /* Get the data base register. */
-
- geta4();
-
- /* Allocate speech driver data. */
-
- if(NarratorPort = CreatePort(NULL,0))
- {
- if(NarratorRequest = (struct narrator_rb *)CreateExtIO(NarratorPort,sizeof(struct narrator_rb)))
- {
- /* Say which channels we need. */
-
- NarratorRequest -> ch_masks = &AnyChannel[0];
- NarratorRequest -> nm_masks = 4;
-
- /* This is a write request. */
-
- NarratorRequest -> message . io_Command = CMD_WRITE;
- NarratorRequest -> message . io_Data = (APTR)WorkString;
-
- /* Try to open the speech driver. */
-
- if(!OpenDevice("narrator.device",0,NarratorRequest,0))
- {
- /* Handshake with handler process. */
-
- Signal(HandlerProcess,SIG_SHAKE);
-
- FOREVER
- {
- /* Wait for signal. */
-
- SignalSet = Wait(SIG_CLOSE | SIG_CLICK);
-
- /* Are we to shut down? */
-
- if(SignalSet & SIG_CLOSE)
- break;
-
- /* Prevent time data from being changed. */
-
- Forbid();
-
- strcpy(WorkString,"IH4THZ ");
-
- /* Is the hour below twelve? */
-
- if(DSeg -> CurrentTime . Hour <= 12)
- strcat(WorkString,SingleNumbers[DSeg -> CurrentTime . Hour]);
-
- /* Is it above twelve? */
-
- if(DSeg -> CurrentTime . Hour > 12)
- strcat(WorkString,SingleNumbers[DSeg -> CurrentTime . Hour - 12]);
-
- strcat(WorkString," EH4KLAA4K ");
-
- /* Are the minutes above zero and below twenty? */
-
- if(DSeg -> CurrentTime . Minute < 20 && DSeg -> CurrentTime . Minute > 0)
- strcat(WorkString,SingleNumbers[DSeg -> CurrentTime . Minute]);
-
- /* Are the minutes above twenty? */
-
- if(DSeg -> CurrentTime . Minute >= 20)
- {
- /* Append the tenths first. */
-
- strcat(WorkString,AboveTwenty[DSeg -> CurrentTime . Minute / 10 - 2]);
-
- /* Add the minutes if any. */
-
- if(DSeg -> CurrentTime . Minute % 10)
- strcat(WorkString,SingleNumbers[DSeg -> CurrentTime . Minute % 10]);
- }
-
- /* Add a.m./p.m. */
-
- if(DSeg -> CurrentTime . Hour > 12)
- strcat(WorkString,TimeOfDay[1]);
- else
- {
- if(DSeg -> CurrentTime . Hour > 0 && DSeg -> CurrentTime . Hour < 12)
- strcat(WorkString,TimeOfDay[0]);
- }
-
- Permit();
-
- /* Remember the length (-1 doesn't work here for some reason). */
-
- NarratorRequest -> message . io_Length = strlen(WorkString);
-
- /* Say it and wait for it to terminate. */
-
- SendIO(NarratorRequest);
- WaitIO(NarratorRequest);
-
- GetMsg(NarratorPort);
- }
-
- /* Deallocate our resources and exit. */
-
- while(!CheckIO(NarratorRequest))
- {
- AbortIO(NarratorRequest);
- WaitIO(NarratorRequest);
-
- GetMsg(NarratorPort);
- }
-
- CloseDevice(NarratorRequest);
- }
-
- DeleteExtIO(NarratorRequest);
- }
-
- DeletePort(NarratorPort);
- }
-
- /* Lock & quit. */
-
- Forbid();
-
- SpeechProcess = NULL;
-
- Signal(HandlerProcess,SIG_SHAKE);
- }
-
- /* CreateFuncProc():
- *
- * Similar to CreateTask this routine will start a
- * 'C' function as a process. The technique used
- * by this nifty little piece of code was originally
- * conceived by Leo Schwab.
- */
-
- struct Process *
- CreateFuncProc(char *Name,LONG Priority,APTR InitCode,ULONG StackSize)
- {
- struct Process *ChildProc = NULL;
-
- struct
- {
- ULONG SegLength; /* Length of segment. */
- BPTR NextSeg; /* Pointer to next segment. */
-
- WORD FirstCode; /* First instruction (JMP). */
- APTR RealCode; /* Address of function. */
- } *FakeSeg;
-
- /* Allocate the segment. */
-
- if(FakeSeg = (struct FakeSeg *)AllocMem(sizeof(*FakeSeg),MEMF_PUBLIC | MEMF_CLEAR))
- {
- struct MsgPort *ChildPort;
-
- /* Fill in the data. */
-
- FakeSeg -> SegLength = sizeof(*FakeSeg);
- FakeSeg -> FirstCode = 0x4EF9; /* JMP EA */
- FakeSeg -> RealCode = InitCode; /* EA */
-
- /* Create the process. */
-
- if(ChildPort = (struct MsgPort *)CreateProc(Name,Priority,MKBADDR(&FakeSeg -> NextSeg),StackSize))
- ChildProc = (struct Process *)ChildPort -> mp_SigTask;
-
- Delay(TICKS_PER_SECOND / 2);
-
- /* Free the segment. */
-
- FreeMem(FakeSeg,sizeof(*FakeSeg));
- }
-
- /* Return the pointer to the process. */
-
- return(ChildProc);
- }
-
- /* CreateDummyRPort():
- *
- * Creates a hidden RastPort for time/graphics
- * rendering.
- */
-
- BYTE
- CreateDummyRPort()
- {
- struct TextAttr FontRequest;
- SHORT i;
-
- /* Allocate the BitMap. */
-
- if(!(DummyMap = (struct DummyMap *)AllocMem(sizeof(struct BitMap),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- /* How many bitplanes are there in the display? */
-
- DummyDepth = Window -> RPort -> BitMap -> Depth;
-
- /* Initialize the bitmap pointers. */
-
- InitBitMap(DummyMap,DummyDepth,Width,Height);
-
- /* Allocate the memory. */
-
- for(i = 0 ; i < DummyDepth ; i++)
- {
- if(!(DummyMap -> Planes[i] = AllocMem(Byte(Width) * Height,MEMF_CHIP)))
- return(FALSE);
- }
-
- /* Mangle the RastPort. */
-
- if(!(DummyRPort = (struct RastPort *)AllocMem(sizeof(struct RastPort),MEMF_PUBLIC | MEMF_CLEAR)))
- return(FALSE);
-
- /* Initialize the RastPort. */
-
- InitRastPort(DummyRPort);
-
- /* Link it to the BitMap. */
-
- DummyRPort -> BitMap = DummyMap;
-
- /* Clear the drawing area. */
-
- SetRast(DummyRPort,1);
-
- /* Copy the font attributes. */
-
- FontRequest . ta_Name = (STRPTR)Window -> IFont -> tf_Message . mn_Node . ln_Name;
- FontRequest . ta_YSize = Window -> IFont -> tf_YSize;
- FontRequest . ta_Style = Window -> IFont -> tf_Style;
- FontRequest . ta_Flags = Window -> IFont -> tf_Flags;
-
- /* Can we open the font (is it already in the system
- * list)?
- */
-
- if(!(DummyFont = (struct TextFont *)OpenFont(&FontRequest)))
- {
- /* It is probably a diskfont. */
-
- if(DiskfontBase = (struct Library *)OpenLibrary("diskfont.library",0))
- {
- if(!(DummyFont = (struct TextFont *)OpenDiskFont(&FontRequest)))
- return(FALSE);
- else
- CloseLibrary(DiskfontBase);
- }
- }
-
- /* Attach the font to the RastPort. */
-
- SetFont(DummyRPort,DummyFont);
-
- /* And set the drawing mode. */
-
- SetDrMd(DummyRPort,JAM2);
-
- return(TRUE);
- }
-
- /* DeleteDummyRPort():
- *
- * Removes the hidden RastPort from memory and get rid
- * of the font attached to it.
- */
-
- VOID
- DeleteDummyRPort()
- {
- SHORT i;
-
- if(DummyMap)
- {
- for(i = 0 ; i < DummyDepth ; i++)
- if(DummyMap -> Planes[i])
- FreeMem(DummyMap -> Planes[i],Byte(Width) * Height);
-
- FreeMem(DummyMap,sizeof(struct BitMap));
-
- DummyMap = NULL;
- }
-
- if(DummyRPort)
- {
- FreeMem(DummyRPort,sizeof(struct RastPort));
- DummyRPort = NULL;
- }
-
- if(DummyFont)
- {
- CloseFont(DummyFont);
- DummyFont = NULL;
- }
- }
-
- /* MaxFontWidth():
- *
- * Calculate the maximum width of the display by looking for
- * the widest letter.
- */
-
- UBYTE
- MaxFontWidth()
- {
- BYTE FontWidth = 0,TempWidth;
- char Shuttle[2];
- SHORT i;
-
- /* We cannot use a single character to check the width
- * of a letter, so we'll fake a string.
- */
-
- Shuttle[1] = 0;
-
- /* Check all letters. */
-
- for(i = 0 ; i < 256 ; i++)
- {
- Shuttle[0] = i;
-
- /* Is it wider than the last letter. */
-
- if((TempWidth = TextLength(Window -> RPort,Shuttle,1)) > FontWidth)
- FontWidth = TempWidth;
- }
-
- return(FontWidth);
- }
-
- /* ShutDown(HandShake):
- *
- * Closes DClock and waits for removal.
- */
-
- VOID
- ShutDown(LONG HandShake)
- {
- /* Restore system functions. */
-
- if(OldDisplayBeep)
- SetFunction((struct Library *)IntuitionBase,-0x60,OldDisplayBeep);
-
- if(OldCloseWBench)
- SetFunction((struct Library *)IntuitionBase,-0x4E,OldCloseWBench);
-
- FlushHandler();
- FlushSound();
-
- if(Window)
- {
- SetRast(DummyRPort,1);
-
- ClipBlit(DummyRPort,0,0,Window -> WScreen -> BarLayer -> rp,LeftEdge,1,Width,Height,0xC0);
-
- CloseWindow(Window);
- }
-
- DeleteDummyRPort();
-
- /* Return the special signals. */
-
- if(BenchSig != -1)
- FreeSignal(BenchSig);
-
- if(DisplaySig != 1)
- FreeSignal(DisplaySig);
-
- if(SpeechSig != 1)
- FreeSignal(SpeechSig);
-
- /* Free the Rexx host port. */
-
- if(DSeg -> RexxHost)
- DeleteRexxHost(DSeg -> RexxHost);
-
- if(RexxProcess)
- {
- Signal(RexxProcess,SIG_CLOSE);
-
- Wait(SIG_SHAKE);
- }
-
- if(SpeechProcess)
- {
- Signal(SpeechProcess,SIG_CLOSE);
-
- Wait(SIG_SHAKE);
- }
-
- if(RexxHostBase)
- CloseLibrary(RexxHostBase);
-
- if(IntuitionBase)
- CloseLibrary(IntuitionBase);
-
- if(GfxBase)
- CloseLibrary(GfxBase);
-
- /* Sneak out before someone can
- * UnLoadSeg() us.
- */
-
- Forbid();
-
- /* Goodbye father. */
-
- if(DSeg -> Father)
- Signal(DSeg -> Father,HandShake);
- }
-
- /* _main():
- *
- * Modified Aztec C startup-routine, no CLI parsing,
- * no Workbench parsing, absolutely nothing.
- */
-
- LONG
- _main()
- {
- volatile ULONG MemSize,MaxSize;
-
- ULONG SignalSet;
- UBYTE Force,Blink = FALSE,i,EmptyWidth,FullWidth;
-
- LONG RexxMask = 0;
-
- struct Screen *Workbench;
-
- HandlerProcess = (struct Process *)SysBase -> ThisTask;
-
- /* If somebody called us from CLI... */
-
- if(HandlerProcess -> pr_CLI)
- return(-1);
-
- /* Is the DSeg structure anywhere? */
-
- if(!(DSeg = (struct DSeg *)FindPort(PORTNAME)))
- {
- Forbid();
- Signal(DSeg -> Father,DSeg -> RingBack);
-
- return;
- }
-
- /* Check if it's below our current revision
- * number (probably doesn't support some
- * structure tags).
- */
-
- if(DSeg -> Revision < REVISION)
- {
- Forbid();
- Signal(DSeg -> Father,DSeg -> RingBack);
-
- return;
- }
-
- /* Open those libraries. */
-
- if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
- {
- Forbid();
- Signal(DSeg -> Father,DSeg -> RingBack);
-
- return;
- }
-
- if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Open RexxHostLibrary if possible. If the open
- * fails, it doesn't matter.
- */
-
- RexxHostBase = OpenLibrary("rexxhost.library",34);
-
- /* Try to find the Workbench screen. */
-
- if(!(Workbench = (struct Screen *)FindTheBench()))
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Open the backdrop window. */
-
- if(!(Window = (struct Window *)OpenWindow(&NewWindow)))
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Initialize the click sound data. */
-
- if(!InitSound())
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Install the handler code. */
-
- if(!InitHandler())
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- if((BenchSig = AllocSignal(-1)) == -1)
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- if((DisplaySig = AllocSignal(-1)) == -1)
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- if((SpeechSig = AllocSignal(-1)) == -1)
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Adjust the window left offset. */
-
- Width = MaxFontWidth() * 22;
- Height = Window -> IFont -> tf_YSize;
-
- LeftEdge = Workbench -> Width - 55 - Width;
-
- EmptyWidth = TextLength(Window -> RPort,"E",1);
- FullWidth = TextLength(Window -> RPort,"F",1);
-
- /* Create the dummy RastPort. */
-
- if(!CreateDummyRPort())
- {
- ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Check if we are running unter Kickstart 2.x. */
-
- if(SysBase -> LibNode . lib_Version >= 36)
- {
- USHORT TempCol;
-
- NewKick = TRUE;
-
- for(i = 0 ; i < 228 ; i++)
- {
- TempCol = ClockMap[i];
- ClockMap[i] = ClockMap[i + 228];
- ClockMap[i + 228] = TempCol;
- }
-
- for(i = 0 ; i < 3 ; i++)
- ClockTxt[i] . FrontPen = 1;
-
- LeftEdge = Workbench -> Width - 25 - Width;
- }
-
- /* Create the rexx server task. */
-
- if(RexxHostBase)
- {
- if(!(RexxProcess = (struct Process *)CreateFuncProc("DClock-Rexx",5,RexxServer,4000)))
- {
- Shut: ShutDown(DSeg -> RingBack);
-
- return;
- }
-
- /* Wait for handshake. */
-
- Wait(SIG_SHAKE);
-
- /* No port? Fail fast! */
-
- if(!RexxTaskPort)
- goto Shut;
- }
-
- /* Fill in the window and bring it to the front. */
-
- ShowTime(FALSE,TRUE);
-
- /* Patch system function. */
-
- OldDisplayBeep = SetFunction((struct Library *)IntuitionBase,-0x60,NewDisplayBeep);
- OldCloseWBench = SetFunction((struct Library *)IntuitionBase,-0x4E,NewCloseWBench);
-
- /* If RexxHostBase is around, add the rexx port. */
-
- if(RexxHostBase)
- {
- if(DSeg -> RexxHost = CreateRexxHost("DCLOCK"))
- RexxMask = (1 << DSeg -> RexxHost -> rh_Port . mp_SigBit);
- }
-
- /* Initialize the signal-semaphore. */
-
- InitSemaphore(DSeg -> SoundSemaphore);
-
- /* Now we are truly running. */
-
- DSeg -> Child = SysBase -> ThisTask;
-
- /* How much memory is there around in this
- * Amiga?
- */
-
- MaxSize = MaxMemSize(MEMF_CHIP) + MaxMemSize(MEMF_FAST);
-
- /* Tell father to finish. */
-
- Signal(DSeg -> Father,DSeg -> RingBack);
-
- DSeg -> Father = NULL;
-
- /* Go into infinite loop waiting for signals. */
-
- FOREVER
- {
- SignalSet = Wait(SIG_TIMER | SIG_CLOSE | SIG_CLICK | SIG_TOGGL | SIG_BENCH | SIG_WINDO | SIG_DISPL | SIG_SPEECH | RexxMask);
-
- /* Was it a Rexx call? */
-
- if((SignalSet & RexxMask) && RexxMask)
- {
- struct RexxMessage *RexxMsg;
-
- /* Capture the messages... */
-
- while(RexxMsg = GetMsg((struct MsgPort *)DSeg -> RexxHost))
- {
- /* Send them to the rexx server task. */
-
- if(GetRexxCommand(RexxMsg))
- PutMsg(RexxTaskPort,RexxMsg);
- else
- FreeRexxCommand(RexxMsg);
- }
- }
-
- /* Change the display mode? */
-
- if(SignalSet & SIG_TOGGL)
- {
- DSeg -> Page++;
-
- SetRast(DummyRPort,1);
-
- if(DSeg -> Page == 5)
- DSeg -> Page = 0;
-
- if(DSeg -> Countdown < 1 && DSeg -> Page == 4)
- DSeg -> Page = 0;
-
- Force = TRUE;
- }
-
- /* Are we to click? */
-
- if((SignalSet & SIG_CLICK) && DSeg -> Click)
- Click();
-
- /* Are we to shut down? */
-
- if(SignalSet & SIG_CLOSE)
- {
- if(ChimeAudioBlock)
- StopChime();
-
- ShutDown(SIG_CLOSE);
- return;
- }
-
- if(SignalSet & SIG_BENCH)
- {
- /* Close the window... */
-
- if(Window)
- {
- CloseWindow(Window);
- Window = NULL;
-
- DeleteDummyRPort();
-
- Delay(25);
-
- FOREVER
- {
- /* Wait for wakeup call... */
-
- if((SetSignal(NULL,NULL) & SIG_CLOSE) == SIG_CLOSE)
- {
- SetSignal(NULL,SIG_CLOSE);
-
- SignalSet = SIG_CLOSE;
- break;
- }
-
- if(Workbench = (struct Screen *)FindTheBench())
- {
- SignalSet = NULL;
- break;
- }
-
- Delay(25);
- }
- }
-
- /* Finish? */
-
- if(SignalSet & SIG_CLOSE)
- {
- if(ChimeAudioBlock)
- StopChime();
-
- ShutDown(SIG_CLOSE);
- return;
- }
-
- /* Open the window. */
-
- if(!(Window = (struct Window *)OpenWindow(&NewWindow)))
- {
- BeatIt: if(ChimeAudioBlock)
- StopChime();
-
- ShutDown(SIG_CLOSE);
- return;
- }
-
- Width = MaxFontWidth() * 22;
- Height = Window -> IFont -> tf_YSize;
-
- /* Re-adjust the Window offset. */
-
- if(NewKick)
- LeftEdge = Workbench -> Width - 25 - Width;
- else
- LeftEdge = Workbench -> Width - 55 - Width;
-
- EmptyWidth = TextLength(Window -> RPort,"E",1);
- FullWidth = TextLength(Window -> RPort,"F",1);
-
- /* Redraw the time if necessary. */
-
- Printed = FALSE;
-
- if(!CreateDummyRPort())
- goto BeatIt;
- }
-
- /* A window refresh call came in. */
-
- if(SignalSet & SIG_WINDO)
- {
- struct IntuiMessage *IMsg;
-
- /* Reply the Message (don't need it). */
-
- if(IMsg = GetMsg(Window -> UserPort))
- ReplyMsg(IMsg);
- }
-
- /* Give it a brief beep to indicate the hour? */
-
- if(DSeg -> Hour && !DSeg -> CurrentTime . Minute && !DSeg -> CurrentTime . Second)
- PlayChime();
-
- /* Check if chime has ended. */
-
- if(ChimeAudioBlock)
- {
- if(CheckIO(ChimeAudioBlock))
- StopChime();
- }
-
- /* Ready to ring the bell? */
-
- if(DSeg -> CurrentTime . Hour == DSeg -> AlarmHour &&
- DSeg -> CurrentTime . Minute == DSeg -> AlarmMinute &&
- DSeg -> CurrentTime . Second == DSeg -> AlarmSecond &&
- DSeg -> Alarm)
- Ring(TRUE);
-
- /* If needed, decrement the tea timer. */
-
- if(DSeg -> Countdown > 0)
- {
- if(!(--DSeg -> Countdown))
- Ring(FALSE);
- }
-
- /* Check the display signal before we
- * redraw it.
- */
-
- if(SignalSet & SIG_DISPL)
- {
- DSeg -> Seconds ^= TRUE;
-
- Force = TRUE;
- }
-
- /* We are to tell the time. */
-
- if(SignalSet & SIG_SPEECH)
- {
- /* Remove speech process if speech
- * has been turned off after it has
- * been run once.
- */
-
- if(!DSeg -> Speech)
- {
- if(SpeechProcess)
- {
- Signal(SpeechProcess,SIG_CLOSE);
-
- Wait(SIG_SHAKE);
- }
- }
- else
- {
- /* Try to create the speech process. */
-
- if(!SpeechProcess)
- {
- Forbid();
-
- if(SpeechProcess = CreateFuncProc("DClock-Speech",5,SpeechServer,4000))
- Wait(SIG_SHAKE);
-
- Permit();
- }
-
- /* Tell the time. */
-
- if(SpeechProcess)
- Signal(SpeechProcess,SIG_CLICK);
- }
- }
-
- /* Show time and date. */
-
- if(DSeg -> Page == 0)
- ShowTime(TRUE,Force);
- else
- ShowTime(FALSE,Force);
-
- Force = FALSE;
-
- /* Show memory display. */
-
- if(DSeg -> Page == 1)
- {
- LONG BarLength;
-
- /* For single bitplane Workbench
- * screen -> use fill pattern.
- */
-
- static USHORT Checkers[8]=
- {
- 0xAAAA,0x5555,
- 0xAAAA,0x5555,
- 0xAAAA,0x5555,
- 0xAAAA,0x5555
- };
-
- /* How much memory is still available? */
-
- MemSize = AvailMem(MEMF_CHIP) + AvailMem(MEMF_FAST);
-
- /* How LONG will the bar be? */
-
- BarLength = ((Width - (EmptyWidth + FullWidth)) * MemSize) / MaxSize;
-
- if(NewKick)
- {
- SetAPen(DummyRPort,2);
- SetBPen(DummyRPort,3);
- }
- else
- {
- SetAPen(DummyRPort,1);
- SetBPen(DummyRPort,2);
- }
-
- Move(DummyRPort,0,Window -> IFont -> tf_Baseline);
-
- Text(DummyRPort,"E",1);
-
- Move(DummyRPort,Width - FullWidth,Window -> IFont -> tf_Baseline);
-
- Text(DummyRPort,"F",1);
-
- /* Draw the full part. */
-
- if(Window -> RPort -> BitMap -> Depth < 2)
- SetAfPt(DummyRPort,&Checkers[0],1);
-
- if(NewKick)
- SetAPen(DummyRPort,2);
- else
- SetAPen(DummyRPort,3);
-
- RectFill(DummyRPort,EmptyWidth,0,Width - FullWidth - BarLength,Height - 1);
-
- if(Window -> RPort -> BitMap -> Depth < 2)
- SetAfPt(DummyRPort,NULL,0);
-
- /* Add the empty part. */
-
- if(NewKick)
- SetAPen(DummyRPort,3);
- else
- SetAPen(DummyRPort,2);
-
- RectFill(DummyRPort,Width - FullWidth - BarLength,0,Width - (FullWidth + 1),Height - 1);
- }
-
- /* Numeric memory display. */
-
- if(DSeg -> Page == 2)
- {
- UBYTE TempBuff[30];
-
- Format(TempBuff,"C: %07ld F: %07ld",AvailMem(MEMF_CHIP),AvailMem(MEMF_FAST));
- PrintIt(TempBuff);
- }
-
- /* Show online timer? */
-
- if(DSeg -> Page == 3)
- {
- UBYTE TempBuff[50];
-
- Format(TempBuff,"OFFLINE %02ld:%02ld:%02ld",OnlineHours,OnlineMinutes,OnlineSeconds);
-
- if(DSeg -> Online)
- {
- if(Blink ^= TRUE)
- {
- TempBuff[0] = ' ';
- TempBuff[1] = 'O';
- TempBuff[2] = 'N';
- }
- else
- {
- TempBuff[0] = ' ';
- TempBuff[1] = ' ';
- TempBuff[2] = ' ';
- }
- }
-
- PrintIt(TempBuff);
- }
-
- /* Show the countdown. */
-
- if(DSeg -> Page == 4)
- {
- UBYTE TempBuff[50];
-
- if(DSeg -> Countdown > 0)
- {
- Format(TempBuff,"Countdown %ld ",-DSeg -> Countdown);
- TempBuff[22] = 0;
-
- PrintIt(TempBuff);
- }
- else
- DSeg -> Page = 0;
- }
-
- /* Transfer the image portion. */
-
- ClipBlit(DummyRPort,0,0,Window -> WScreen -> BarLayer -> rp,LeftEdge,1,Width,Height,0xC0);
- }
- }
-