{ This program shows the use of gadgets in a window. Thus one } { menu, one auto requester, but lots of gadget types. } { For the sake of example, two mutual exclude gadgets } { (female/male) are shown that perform a function that might } { be better implemented as a toggle image, in a manner similar } { to that shown in the inflection Mode gadget. } { The toy consists of one program (speechtoy.pas), two modules } { (initspeech.pas and dospeech.pas) and an include file } { (speechtoy.inc). See the examples appendix for details of } { the commands necessary to build the speechtoy. } PROGRAM Speechtoy( output ); INCLUDE 'speechtoy.inc'; {$L- Turn off listing for the external routines include files } INCLUDE 'exec/io'; { For SendIO } INCLUDE 'exec/ports'; { For Get/ReplyMsg } INCLUDE 'exec/signals'; { For Alloc/FreeSignal, Wait } INCLUDE 'intuition/gadgets'; { For Add/Remove/RefreshGadgets } INCLUDE 'intuition/screens'; { For DisplayBeep } INCLUDE 'graphics/rastport'; { For Draw, Move, RectFill, SetAPen } {$L+} PROCEDURE Initialise; IMPORT; PROCEDURE MyCleanup( code : INTEGER ); IMPORT; PROCEDURE XOR( VAR a : WORD; b : WORD ); IMPORT; PROCEDURE MenuMessage( code : WORD; w : WindowPtrType ); IMPORT; PROCEDURE GadgetMessage( address : GadgetPtrType ); IMPORT; PROCEDURE DrawFace; IMPORT; PROCEDURE ProcessControlWindowMessage; VAR MIClass : INTEGER; { These three variables are used to } MICode : WORD; { save the message class, code and } MIAddress : IAddressType; { address before replying } MyIntuiMessage : IntuiMessagePtrType; { Message received from Intuition } BEGIN { Get and process the Intuition message } MyIntuiMessage := GetMsg( ControlWindow^.UserPort ); WHILE MyIntuiMessage <> NIL DO BEGIN { Get all the required information and give the message back } WITH MyIntuiMessage^ DO BEGIN MIClass := Class; MICode := Code; MIAddress := IAddress END; ReplyMsg( MyIntuiMessage ); { Note that this is done ASAP } { Now what does the user what done ? } CASE MIClass OF MENUPICK: { Process the menu message } MenuMessage( MICode, ControlWindow ); GADGETUP: { Process the gadget message } GadgetMessage( MIAddress.gadget ); CLOSEWINDOW: { Reply to any later messages then clean up } BEGIN MyIntuiMessage := GetMsg( ControlWindow^.UserPort ); WHILE MyIntuiMessage <> NIL DO BEGIN ReplyMsg( MyIntuiMessage ); MyIntuiMessage := GetMsg( ControlWindow^.UserPort ) END; MyCleanup( 100 ); END; OTHERWISE: ; { Unhandled message recieved } END; { case } MyIntuiMessage := GetMsg( ControlWindow^.UserPort ) END { while } END; { ProcessControlWindowMessage } PROCEDURE ProcessFaceWindowMessage; VAR MyIntuiMessage : IntuiMessagePtrType; { Message from Intuition } BEGIN { Get and process the Intuition message } MyIntuiMessage := GetMsg( FaceWindow^.UserPort ); WHILE MyIntuiMessage <> NIL DO BEGIN CASE MyIntuiMessage^.Class OF SIZEVERIFY: ; { Handled by intuition } NEWSIZE: DrawFace; { Don't reply until processed } OTHERWISE: ; { Unhandled message received } END; { case } ReplyMsg( MyIntuiMessage ); MyIntuiMessage := GetMsg( FaceWindow^.UserPort ) END { while } END; { ProcessFaceWindowMessage } PROCEDURE ProcessCompletedWrite; BEGIN WITH voice_io.message DO BEGIN { Was it Sucessful? Filter out the abort error } IF io_Error = -2 THEN io_Error := 0; IF io_Error <> 0 THEN { Narrator failed } BEGIN DisplayBeep( ControlWindow^.WScreen ); { Flash this screen } pos := RemoveGadget( ControlWindow, PhonStrGadget ); { Move the cursor to the error character and ensure that the cursor } { (error point) is shown in the gadget within 29 (number of chars } { shown) of the front } WITH PhonInfo^ DO BEGIN BufferPos := io_Actual - 1; IF io_Actual < 29 THEN DispPos := 0 ELSE IF (io_Length - io_Actual) < 29 THEN DispPos := io_Length - 29 ELSE DispPos := io_Actual - 15 END; pos := AddGadget( ControlWindow, PhonStrGadget, pos ); RefreshGadgets( PhonStrGadget, ControlWindow, NIL ); io_Error := 0 END; WITH FaceGadget^ DO XOR( Flags, GADGDISABLED ); WITH SpeakGadget^ DO XOR( Flags, GADGDISABLED ); END { with voice } END; { ProcessCompletedWrite } PROCEDURE ProcessCompletedRead; BEGIN WITH FaceWindow^ DO BEGIN { Could WaitBOVP( WScreen^.View_Port ); } SetAPen( RPort, WHTP ); RectFill( RPort, 0, EyesBottom, GZZWidth, GZZHeight ); WITH mouth_io DO BEGIN IF MouthWMult = 0 THEN LipWidth := width >> 1 ELSE LipWidth := width * MouthWMult; IF MouthHMult = 0 THEN LipHeight := height >> 1 ELSE LipHeight := height * MouthHMult END; SetAPen( RPort, REDP ); Move( RPort, XMouthCentre - LipWidth, YMouthCentre ); Draw( RPort, XMouthCentre, YMouthCentre - LipHeight ); Draw( RPort, XMouthCentre + LipWidth, YMouthCentre ); Draw( RPort, XMouthCentre, YMouthCentre + LipHeight ); Draw( RPort, XMouthCentre - LipWidth, YMouthCentre ); { The narrator will give an error when the write has completed and } { we've tried to read so we stop trying when that happens } IF mouth_io.voice.message.io_Error = 0 THEN SendIO( ADDR( mouth_io ) ) END { with } END; { ProcessCompletedRead } PROCEDURE ProcessSignals; VAR Signal, { Program tells Wait what to look at } Signals : INTEGER; { Wait tells program what to look at } BEGIN Signal := (1 << ControlWindow^.UserPort^.mp_SigBit) | (1 << voice_io.message.io_Message.mn_ReplyPort^.mp_SigBit) | (1 << mouth_io.voice.message.io_Message.mn_ReplyPort^.mp_SigBit); IF FaceWindow <> NIL THEN Signal := Signal | (1 << FaceWindow^.UserPort^.mp_SigBit); { Wait for a signal and process it. Note that Wait lets } { the rest of the system run whilst this program sleeps } Signals := Wait( Signal ); { Now check the Signals to see to what we owe the intrusion } { Have we received a signal from the control window ? } IF (Signals & (1 << ControlWindow^.UserPort^.mp_SigBit)) <> 0 THEN ProcessControlWindowMessage; { Have we received a signal from the face window ? } IF FaceWindow <> NIL THEN IF (Signals & (1 << FaceWindow^.UserPort^.mp_SigBit)) <> 0 THEN ProcessFaceWindowMessage; { Has a voice SendIO (Write) completed ? } WITH voice_io.message.io_Message.mn_ReplyPort^ DO IF (Signals & (1 << mp_SigBit)) <> 0 THEN ProcessCompletedWrite; { Has a mouth DoIO (Read) completed ? } WITH mouth_io.voice.message.io_Message.mn_ReplyPort^ DO IF (Signals & (1 << mp_SigBit)) <> 0 THEN ProcessCompletedRead END; { ProcessSignals } BEGIN Initialise; { Set up just about everything } { Now infinitely loop processing any messages received. The only way } { to exit from this loop is for the user to close the control window } WHILE TRUE DO ProcessSignals END. { Speechtoy }