home *** CD-ROM | disk | FTP | other *** search
- MODULE Helper;
-
- (*======================================================================*)
- (* Helper version v0.07 *)
- (*======================================================================*)
- (* Copyright © 1989 Mike Cargal, All Rights Reserved *)
- (*======================================================================*)
- (* Version: 0.07 Author : Mike Cargal *)
- (* Date : 20-Jun-89 Changes: Original *)
- (*======================================================================*)
- (* Link with RTA *)
- (*======================================================================*)
-
-
- FROM SYSTEM IMPORT ADR, STRPTR, LONGWORD, BYTE, ADDRESS, TSIZE,
- SHIFT, SHORT;
- FROM RunTime IMPORT WBMsg;
- FROM EasyIDCMP IMPORT ProcTable, ProcessEvents;
- FROM EasyMenus IMPORT AddMenu, AddItem, DisposeStrip, AddSub,
- StartStrip, currentStrip, stripFailed,
- nextSubWidth;
- FROM Intuition IMPORT WindowPtr, IntuiMessage, GadgetPtr,
- ActivateWindow, SetMenuStrip, IDCMPFlags,
- ClearMenuStrip, ITEMNUM, IDCMPFlagSet,
- ModifyIDCMP, Screen, ScreenPtr,
- RememberPtr, AllocRemember, FreeRemember;
- FROM DOS IMPORT Lock, UnLock, SharedLock, Write, Output,
- CurrentDir, FileLock, ParentDir, DupLock,
- InfoData, InfoDataPtr, Input;
- FROM DOSProcess IMPORT Process, ProcessPtr, StandardPacket,
- StandardPacketPtr, ActionDiskInfo;
- FROM ArpPortUtils IMPORT CreatePort, DeletePort;
- FROM ArpLoader IMPORT PCBFlags, PCBFlagSet, PCBPtr, PCB, ASyncRun,
- NewShell, nshInteractiveShell,
- nshInteractiveCLI, SpawnShell;
- FROM ArpPackets IMPORT SendPacket;
- FROM ArpProcess IMPORT FindCLI;
- FROM ArpMisc IMPORT CloseWindowSafely;
- FROM Interrupts IMPORT Forbid, Permit;
- FROM Libraries IMPORT OpenLibrary, CloseLibrary;
- FROM Workbench IMPORT DiskObject, DiskObjectPtr, StrArrayPtr,
- WBStartupPtr, WBStartup, WBArg;
- FROM Icon IMPORT GetDiskObject, FindToolType, IconBase, IconName,
- FreeDiskObject;
- FROM Memory IMPORT AllocMem, FreeMem, MemReqSet, MemReqs;
- FROM Strings IMPORT AppendSubStr, AssignStr, LengthStr,
- Equal, CompareCAPStr, LocateChar;
- FROM Tasks IMPORT FindTask, CurrentTask;
- FROM Devices IMPORT OpenDevice, CloseDevice;
- FROM IO IMPORT IOStdReq, IOStdReqPtr, DoIO, IOFlagSet;
- FROM IOUtils IMPORT CreateStdIO, DeleteStdIO;
- FROM Ports IMPORT MsgPortPtr, MsgPort;
- FROM InputEvents IMPORT InputEvent, IEQualifiers, IEQualifierSet,
- IEClass, InputEventPtr;
- FROM InputDevice IMPORT INDWriteEvent, InputDeviceName;
- FROM CmdLineUtils IMPORT argc, argv;
- FROM Conversions IMPORT ConvNumToStr, ConvStrToNum, Hex;
- FROM DoRawTbl IMPORT RawEnt, RawTbl, RawTblPtr, BuildRawTbl;
- FROM Gads IMPORT Gad, ChangeGads, InitGads, GadPtr,
- OpenHelperWindow, CloseHelperWindow,
- GetFile, HandleCloseWindow, DefConfig,
- LoadGads, SaveGads, SaveDefaults, Version;
- FROM IconifyUtils IMPORT StartIconify, Iconify, DisposeIconify;
- (*FROM TermOut IMPORT WriteString; *)
- (* IMPORT Debug; *)
-
- (*$O-,$R-*)
- CONST
- IconifyGadID = 100;
- VAR
- Gads : GadPtr;
- MyInputEvent : InputEvent;
- ParentProcess,
- MyProcess : ProcessPtr;
- CmdBuff : ARRAY [0..255] OF CHAR;
- MyStdIO : IOStdReqPtr;
- MyRawTbl : RawTblPtr;
- MyPort : MsgPortPtr;
- CLIWindow,
- wp : WindowPtr;
- MyDiskObj : DiskObjectPtr;
- FromWB : BOOLEAN;
- CLINum : INTEGER;
- MemRemem : RememberPtr;
- Remembering : BOOLEAN;
- ITopEdge,
- ILeftEdge,
- IWidth,
- IHeight : INTEGER;
- IconGad : GadgetPtr;
- Iconified : BOOLEAN;
-
- (*******************************************************************)
-
- PROCEDURE CLIWActive(wp : WindowPtr) : BOOLEAN;
-
- (*-------------------------------------------------------------\
- | |
- | This is a recursive routine which traverses to linked- |
- | list of windows for this Screen and returns TRUE or |
- | FALSE based up whether or not our CLI window is still |
- | open. |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- Result : BOOLEAN;
-
- BEGIN
-
- IF wp = CLIWindow THEN
- RETURN(TRUE)
- ELSE
- IF wp^.NextWindow = NIL THEN
- RETURN(FALSE)
- ELSE
- RETURN(CLIWActive(wp^.NextWindow))
- END;
- END;
-
- END CLIWActive;
-
- (*******************************************************************)
-
- PROCEDURE WriteCommand(Cmd : ARRAY OF CHAR);
-
- (*-------------------------------------------------------------\
- | |
- | Create input events for each character of the command |
- | and Write input device events for each of these to |
- | simulate them being typed on keyboard. |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- i : CARDINAL;
- dummy : LONGINT;
-
- BEGIN
-
- dummy := 0;
- FOR i := 0 TO LengthStr(Cmd)-1 DO
- MyInputEvent.ieCode := MyRawTbl^[CARDINAL(Cmd[i])].Cd;
- MyInputEvent.ieQualifier := MyRawTbl^[CARDINAL(Cmd[i])].Qual;
- IF dummy = 0 THEN
- dummy := DoIO(MyStdIO);
- END;
- END;
-
- END WriteCommand;
-
- (*******************************************************************)
-
- PROCEDURE HandleGadgetUp(VAR im : IntuiMessage;
- gp : GadgetPtr) : INTEGER;
-
- (*-------------------------------------------------------------\
- | |
- | Set our process current directory to the current |
- | directory of the CLI from which we were started (and |
- | are consequently attached to). |
- | |
- | Build command string associated with selected Helper |
- | button (appending file name from file requester if |
- | necessary). |
- | |
- | Write Command to input device. |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- FileName : STRPTR;
- i : CARDINAL;
-
- BEGIN
-
- IF FromWB THEN
- IF NOT CLIWActive(wp^.WScreen^.FirstWindow) THEN
- RETURN(1)
- END;
- END;
-
- IF gp^.GadgetID = IconifyGadID THEN
- Iconify(wp,Iconified,wp^.Width,ITopEdge,ILeftEdge,IWidth,IHeight);
- ActivateWindow(CLIWindow);
- RETURN(0);
- END;
-
- UnLock(CurrentDir(DupLock(ParentProcess^.prCurrentDir)));
- i := gp^.GadgetID;
- AssignStr(CmdBuff,Gads^[i].Command);
- IF Gads^[i].AppendFile THEN
- FileName := GetFile(ADR(Gads^[i].Command),ADR(""));
- IF LocateChar(FileName^," ",0) # -1 THEN
- AppendSubStr(CmdBuff,"\x22");
- END;
- AppendSubStr(CmdBuff,FileName^);
- IF LocateChar(FileName^," ",0) # -1 THEN
- AppendSubStr(CmdBuff,"\x22");
- END;
- END;
- AppendSubStr(CmdBuff,"\x0d");
- ActivateWindow(CLIWindow);
- WriteCommand(CmdBuff);
- RETURN(0);
-
- END HandleGadgetUp;
-
- (*******************************************************************)
-
- PROCEDURE HandleIntuiTicks(VAR im : IntuiMessage) : INTEGER;
-
- (*-------------------------------------------------------------\
- | |
- | This procedure will execute approximately 10 times each |
- | second as long as the Helper window is active. |
- | Of course, the Helper window is rarely active since |
- | Helper automatically reactivates the CLI window. |
- | However, by using this code, anything which activates |
- | the Helper window will cause Helper (if run from WB) |
- | to check to see if its CLI window is still open, and |
- | exit if the CLI window has been closed (Since there is |
- | nothing for Helper to do if it has no CLI). |
- | |
- \-------------------------------------------------------------*)
-
- BEGIN
-
- IF CLIWActive(wp^.WScreen^.FirstWindow) THEN
- RETURN(0)
- END;
- RETURN(1);
-
- END HandleIntuiTicks;
-
- (*******************************************************************)
-
- PROCEDURE HandleMenuPick(VAR im : IntuiMessage;
- item : CARDINAL ) : INTEGER;
-
- (*-------------------------------------------------------------\
- | |
- | Handle menu requests: |
- | Menuitem 0 - Load configuration. |
- | 1 - Change configuration. |
- | 2 - Save configuration file. |
- | 3 - Save default configuration file. |
- | 4 - exit helper by returning non 0 to |
- | EasyIDCMP. |
- | |
- \-------------------------------------------------------------*)
-
- BEGIN
- CASE ITEMNUM(item) OF
- 0 : LoadGads(wp)
- | 1 : ChangeGads(wp)
- | 2 : SaveGads(wp)
- | 3 : SaveDefaults(wp)
- | 4 : (* Do Nothing *)
- | 5 : RETURN(1);
- ELSE (* Do Nothing *)
- END;
- RETURN(0);
-
- END HandleMenuPick;
-
- (*******************************************************************)
-
- PROCEDURE AddMenus();
-
- (*-------------------------------------------------------------\
- | |
- | Build menu structures and attach to Helper window if |
- | successful. |
- | |
- \-------------------------------------------------------------*)
-
- BEGIN
-
- StartStrip;
-
- AddMenu("Project",145);;
- AddItem("Load", "L");
- AddItem("Change", "C");
- AddItem("Save", "S");
- AddItem("Save Defaults","D");
- AddItem("About...", 0C);
- nextSubWidth := 210;
- AddSub(" ",0C);
- AddSub(" Helper v0.06 ",0C);
- AddSub(" ",0C);
- AddSub(" © 1989 Mike Cargal ",0C);
- AddSub(" ",0C);
- AddSub(" Developed using M2Sprint ",0C);
- AddSub(" for the Amiga ",0C);
- AddSub(" M2S Inc., Dallas, Texas ",0C);
- AddSub(" ",0C);
- AddItem("Quit", "Q");
-
- IF NOT stripFailed THEN
- SetMenuStrip(wp,currentStrip);
- END;
-
- END AddMenus;
-
- (*******************************************************************)
-
- PROCEDURE Getwp(CLIProcess : ProcessPtr) : WindowPtr;
-
- (*-------------------------------------------------------------\
- | |
- | Get pointer to CLI window. By sending packet to Console |
- | handler for the parent task, we can get back the |
- | address of the window it opened for us. Since Helper |
- | should have been started from the CLI, this will be |
- | the window opened by the CLI's console handler. If |
- | Helper was not started from CLI, this packet should |
- | fail so we'll return NILL and Helper will not continue. |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- wp : WindowPtr;
- MyStandardPacket : StandardPacket;
- MyInfoDataPtr : InfoDataPtr;
- MyArgs : ARRAY [0..6] OF ADDRESS;
-
- BEGIN
-
-
- MyInfoDataPtr := AllocMem(TSIZE(InfoData),MemReqSet{MemClear});
- MyArgs[0] := SHIFT(MyInfoDataPtr,-2); (* PTR to BPTR *)
- IF BOOLEAN(SendPacket(ActionDiskInfo,
- ADR(MyArgs),
- MsgPortPtr(CLIProcess^.prConsoleTask))) THEN
- wp := WindowPtr(MyInfoDataPtr^.idVolumeNode)
- ELSE
- wp := NIL;
- END;
- FreeMem(MyInfoDataPtr,TSIZE(InfoData));
- RETURN(wp);
-
- END Getwp;
-
- (*******************************************************************)
-
- PROCEDURE OpenInputDevice() : BOOLEAN;
-
- (*-------------------------------------------------------------\
- | |
- | Open up Input Device to send input events to simulate |
- | keyboard input. |
- | |
- \-------------------------------------------------------------*)
-
- BEGIN
- MyPort := CreatePort(NIL,0);
- MyStdIO := CreateStdIO(MyPort);
- WITH MyStdIO^ DO
- ioCommand := INDWriteEvent;
- ioLength := TSIZE(InputEvent);
- ioData := ADR(MyInputEvent);
- END;
- WITH MyInputEvent DO
- ieNextEvent := NIL;
- ieClass := IEClassRawKey;
- ieSubClass := BYTE(0);
- ieQualifier := IEQualifierSet{};
- ieEventAddress := NIL;
- ieTimeStamp.tvSecs := 0;
- ieTimeStamp.tvMicro := 0;
- END;
- IF OpenDevice(ADR(InputDeviceName),0,MyStdIO,LONGBITSET{}) = 0 THEN
- RETURN(TRUE);
- END;
- RETURN(FALSE);
-
- END OpenInputDevice;
-
- (*******************************************************************)
-
- PROCEDURE StartCLI();
-
- VAR
- MyNewShell : NewShell;
- WindowSpec,
- StartUp,
- Shell,
- ConfigFile : STRPTR;
- MyWBStartupPtr : WBStartupPtr;
-
- BEGIN
-
- StartUp := NIL;
- Shell := NIL;
- WindowSpec := NIL;
- MyDiskObj := NIL;
-
- IconBase := OpenLibrary(ADR(IconName),0);
- IF IconBase # NIL THEN
- MyWBStartupPtr := WBStartupPtr(WBMsg);
- UnLock(CurrentDir(DupLock(MyWBStartupPtr^.smArgList^.waLock)));
- MyDiskObj := GetDiskObject(MyWBStartupPtr^.smArgList^.waName);
- IF MyDiskObj # NIL THEN
- WindowSpec := FindToolType(MyDiskObj^.doToolTypes,
- ADR("WINDOW"));
- StartUp := FindToolType(MyDiskObj^.doToolTypes,
- ADR("STARTUP"));
- ConfigFile := FindToolType(MyDiskObj^.doToolTypes,
- ADR("CONFIG"));
- Shell := FindToolType(MyDiskObj^.doToolTypes,
- ADR("SHELL"));
- IF ConfigFile # NIL THEN
- DefConfig := ConfigFile;
- END;
- END;
- CloseLibrary(IconBase);
- END;
-
- IF WindowSpec = NIL THEN
- WindowSpec := ADR("NewCON:0/20/640/200/Helper Shell");
- END;
-
- WITH MyNewShell DO
- nshStackSize := 4000;
- nshPri := BYTE(0);
- IF CompareCAPStr(Shell^,"YES") = Equal THEN
- nshControl := nshInteractiveShell;
- ELSE
- nshControl := nshInteractiveCLI;
- END;
- nshLogMsg := ADR("Welcome to Helper\n\x1b[33m© 1989 Mike Cargal\x1b[31m\n");
- nshInput := NIL;
- nshOutput := NIL;
- nshReserved[0] := 0;
- nshReserved[1] := 0;
- nshReserved[2] := 0;
- nshReserved[3] := 0;
- nshReserved[4] := 0;
- nshReserved[5] := 0;
- END;
-
- CLINum := SHORT(SpawnShell(WindowSpec,StartUp,ADR(MyNewShell)));
- IF CLINum > 0 THEN
- Forbid;
- ParentProcess := FindCLI(CLINum);
- Permit;
- ELSE
- ParentProcess := NIL;
- END;
-
- END StartCLI;
-
-
- (*******************************************************************)
-
- PROCEDURE DoHelper();
-
- (*-------------------------------------------------------------\
- | |
- | If all looks well, then open Helper window, etc. and BEGIN |
- | to wait for IDCMP events to let us know what to do |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- MyProcTable : ProcTable;
- dummy : INTEGER;
- MyIDCMP : IDCMPFlagSet;
-
- BEGIN
-
- IF ParentProcess # NIL THEN
- CLIWindow := Getwp(ParentProcess);
- IF CLIWindow # NIL THEN
- Gads := InitGads();
- IF OpenInputDevice() THEN
- wp := OpenHelperWindow();
- IF FromWB THEN
- MyIDCMP := wp^.IDCMPFlags;
- INCL(MyIDCMP,IntuiTicks);
- ModifyIDCMP(wp,MyIDCMP);
- END;
- IF wp # NIL THEN
- IF StartIconify(wp,IconifyGadID,IconGad) THEN END;
- Iconified := FALSE;
- MyRawTbl := BuildRawTbl();
- IF MyRawTbl # NIL THEN
- AddMenus;
- WITH MyProcTable DO
- WaitForEvent := TRUE;
- CloseWindow := HandleCloseWindow;
- GadgetUp := HandleGadgetUp;
- MenuPick := HandleMenuPick;
- IntuiTicks := HandleIntuiTicks;
- END;
- dummy := ProcessEvents(wp,MyProcTable);
- ClearMenuStrip(wp);
- DisposeStrip(currentStrip);
- DisposeIconify(wp,IconGad);
- CloseHelperWindow(wp);
- END;
- END;
- CloseDevice(MyStdIO);
- DeleteStdIO(MyStdIO);
- DeletePort(MyPort);
- END;
- END;
- END;
-
- END DoHelper;
-
-
- (*******************************************************************)
-
- PROCEDURE FirstTime();
-
- (*-------------------------------------------------------------\
- | |
- | If first time in (i.e. no arguments (this needs to be |
- | improved)), start up another Helper asynchronously |
- | passing the address of this process's Process structure |
- | so I can keep the current directories in synch. |
- | |
- | NOTE: currently this address acts as an argument so that |
- | I can tell the difference between helper running itself |
- | and Helper being run initially from the CLI. This is |
- | not very clean and I'm still looking for a better way |
- | to do this. |
- | |
- \-------------------------------------------------------------*)
-
- VAR
- MyPCB : PCB;
- result : LONGINT;
-
- BEGIN
- WITH MyPCB DO
- pcbStackSize := 4000;
- pcbPri := BYTE(0);
- pcbControl := PCBFlagSet{};
- pcbTrapCode := PROC(NIL);
- pcbInput := NIL;
- pcbOutput := NIL;
- pcbLoadedCode := NIL;
- pcbLastGasp := NIL;
- pcbWBProcess := NIL;
- END;
- IF ConvNumToStr(CmdBuff,LONGWORD(MyProcess),Hex,FALSE,8,"0") THEN
- AppendSubStr(CmdBuff,"\x0d");
- result := ASyncRun(argv[0](*"Helper"*),ADR(CmdBuff),ADR(MyPCB));
- IF result < LONGINT(0) THEN
- result := Write(Output(),ADR("Helper failed to start process\n"),31);
- END;
- END;
-
- END FirstTime;
-
- (*******************************************************************)
-
- PROCEDURE SecondTime();
-
- (*-------------------------------------------------------------\
- | |
- | If we had an argument then it should have been the address |
- | of the parent Process. If not then somethings not |
- | quite right so we'll get out of here. |
- | |
- | If all looks well, then open Helper window, etc. and BEGIN |
- | to wait for IDCMP events to let us know what to do |
- | |
- \-------------------------------------------------------------*)
-
- BEGIN
- IF ConvStrToNum(argv[1]^,LONGWORD(ParentProcess),Hex,FALSE) THEN
- DoHelper
- END;
- END SecondTime;
-
- (*******************************************************************)
-
- BEGIN
-
- (*-------------------------------------------------------------\
- | |
- | First time in MyProcess will be the ParentProcess we will |
- | pass to the second invocation of Helper. Second time |
- | it will be the Process structure for the started process. |
- | |
- | We can tell (theoretically) whether this is the first |
- | or second time by the presence of any arguments. |
- | |
- \-------------------------------------------------------------*)
-
- MyProcess := ProcessPtr(FindTask(CurrentTask));
- IF WBMsg # NIL THEN
- FromWB := TRUE;
- StartCLI;
- DoHelper;
- IF MyDiskObj # NIL THEN
- FreeDiskObject(MyDiskObj);
- END;
- ELSE
- IF argc = 1 THEN
- FirstTime
- ELSE
- SecondTime
- END;
- END;
-
- END Helper.
-