home *** CD-ROM | disk | FTP | other *** search
- /*
- * ParM.c - Copyright © 1990 by S.R. & P.C.
- *
- * Created: 01 Jul 1990
- * Modified: 28 Jul 1991 18:25:29
- *
- * Make>> make
- */
-
- #include "ParMBase.h"
-
-
- #define COPYRIGHT "ParM V3.0 Copyright © 1990-91 by S.R. & P.C."
- #define DEFAULT_CONFIG_FILE "S:ParM.cfg"
-
- #define THE_END 0
- #define NO_WIN 10
-
- #define OPEN_ITEM 0
- #define UPDATE_ITEM 1
- #define STD_CFG_ITEM 2
- #define CMDMODE_ITEM 3
- #define COMMAND_ITEM 4
- #define CHDIR_ITEM 5
- #define QUIT_ITEM 6
-
- /* ParM modes */
- #define MODE_CLI 0 /* default mode */
- #define MODE_WINDOW 1
- #define MODE_MYMENU 2
-
-
- extern void CreateParMenu(short Color);
- extern void exit(int);
-
-
- /***** global variables *****/
-
- extern struct ExecBase *SysBase;
- extern struct ParMBase *ParMBase;
- extern struct Menu Menu1;
- extern struct MenuItem SubItem1;
- extern struct WBStartup *WBenchMsg;
-
-
- /***** local variables *****/
-
- static struct Process *ParMProcess;
- static struct Window *Win;
- static struct Menu *LastWBMenu, *TheMenu;
- static struct MsgPort SwapPort;
- static short FirstParMMenuNum; /* = 0 if not attached to WorkBench */
- static short ParMMode;
- static ULONG OldIDCMP, WinSignal;
- static BOOL PortTaken;
- static BOOL quit;
- static BYTE ParMenuColor = -1;
- static struct FileReq FileReq;
- static char Dir[REQ_DSIZE+1];
- static char File[REQ_FCHARS+1];
- static char Path[REQ_DSIZE+REQ_FCHARS+2];
- static struct ParMConfig ParMConfig;
- static BOOL DoNextSelect;
-
-
- struct ToolTypesArg {
- char *tta_Name;
- char tta_cli_equ;
- };
-
- static struct ToolTypesArg TTA_List[] = {
- {"STACKSIZE", 's'},
- {"LEFTEDGE", 'x'},
- {"TOPEDGE", 'y'},
- {"DETAILPEN", 'd'},
- {"BLOCKPEN", 'b'},
- {"MENUCOLOR", 'c'},
- {"CONFIGFILE", 'f'},
- {"NODRAGBAR", 'r'},
- {"DEPTHGADGETS",'g'},
- {"NOAUTOFRONT", 'a'},
- {"MYMENU", 'm'}
- };
-
- #define TTANUM 11 /* Number of ToolTypesArg in List */
-
-
- static struct NewWindow NWS = {
- 0, 0, /* window XY origin relative to TopLeft of screen */
- 39, 10, /* window width and height */
- 3, 2, /* detail and block pens */
- MENUPICK|RAWKEY|REFRESHWINDOW, /* IDCMP flags */
- WINDOWDRAG|SIMPLE_REFRESH, /* other window flags */
- NULL, /* first gadget in gadget list */
- NULL, /* custom CHECKMARK imagery */
- (UBYTE *)"ParM", /* window title */
- NULL, /* custom screen pointer */
- NULL, /* custom bitmap */
- 5, 5, /* minimum width and height */
- -1, -1, /* maximum width and height */
- WBENCHSCREEN /* destination screen type */
- };
-
-
- static struct Window *FindWorkBench(void)
- {
- struct Screen *WBS;
- struct Window *WBW = NULL;
- ULONG ilock;
-
- if (WBS = OpenWorkBench()) {
- ilock = LockIBase(0L); /* Just so's things don't change on us */
- WBW = WBS->FirstWindow;
- while (WBW) {
- /* Only main WB Window has NEWPREFS IDCMPFlag set, so find it */
- if ((WBW->Flags & WBENCHWINDOW) && (WBW->IDCMPFlags & NEWPREFS)) {
- TheMenu = WBW->MenuStrip;
- LastWBMenu = TheMenu->NextMenu->NextMenu;
- FirstParMMenuNum = 3;
- break;
- }
- WBW = WBW->NextWindow;
- }
- UnlockIBase(ilock);
- }
- return WBW;
- }
-
-
- void TakeMsgPort(void)
- {
- struct MsgPort *WinPort;
- struct List *myMsgList = &(SwapPort.mp_MsgList);
- struct List *winMsgList;
-
- SwapPort.mp_Node.ln_Type = NT_MSGPORT;
- SwapPort.mp_Flags = PA_SIGNAL;
- Forbid();
-
- /* get the info we need */
- WinPort = Win->UserPort;
- winMsgList = &(WinPort->mp_MsgList);
-
- /* setup our port */
- SwapPort.mp_SigBit = WinPort->mp_SigBit;
- SwapPort.mp_SigTask = WinPort->mp_SigTask;
-
- /* flip things around */
- WinPort->mp_SigTask = (struct Task *)ParMProcess;
- /* Prevent signal for being allocated later */
- WinSignal = AllocSignal(WinPort->mp_SigBit);
- myMsgList->lh_Head = (struct Node *) &winMsgList->lh_Tail;
- myMsgList->lh_TailPred = winMsgList->lh_TailPred;
- winMsgList->lh_TailPred = (struct Node *) &myMsgList->lh_Head;
- myMsgList->lh_TailPred->ln_Succ = (struct Node *) &myMsgList->lh_Tail;
-
- Permit();
-
- /* prevent deadlocks */
- SetTaskPri((struct Task *)ParMProcess, SwapPort.mp_SigTask->tc_Node.ln_Pri + 1);
- }
-
-
- /* Restore things the way they were before TakeMsgPort() */
-
- void DelMsgPort(void)
- {
- struct Message *Msg;
- struct List *myMsgList = &(SwapPort.mp_MsgList);
-
- Forbid();
- /* clean out our list */
- while (Msg = GetMsg(&SwapPort))
- PutMsg(&SwapPort, Msg);
- /* restore things */
- myMsgList->lh_Head->ln_Pred = myMsgList->lh_TailPred;
- myMsgList->lh_TailPred->ln_Succ = myMsgList->lh_Head;
- Win->UserPort->mp_SigTask = SwapPort.mp_SigTask;
- if (WinSignal)
- FreeSignal(WinSignal);
- Permit();
- }
-
-
- /* Configuration managing functions */
-
- static void InstallWBMenus(struct Menu *Menus)
- {
- long ilock;
-
- ilock = LockIBase(0);
- ClearMenuStrip(Win);
- if (Menus)
- CleanUp(TheMenu, 0, ParMConfig.ItemHeight);
- LastWBMenu->NextMenu = Menus;
- SetMenuStrip(Win, TheMenu);
- UnlockIBase(ilock);
- }
-
-
- static void ClearMenus(void)
- {
- if (ParMMode == MODE_MYMENU) {
- InstallWBMenus(NULL);
- Menu1.LeftEdge = LastWBMenu->LeftEdge + LastWBMenu->Width;
- }
- else
- ClearMenuStrip(Win);
- }
-
-
- void UpDateMenus(void)
- {
- ClearMenus();
- ParMConfig.MenuPen = ParMenuColor;
- if (!ParseMenus(&ParMConfig))
- FreeMenus(&ParMConfig);
- if (ParMMode == MODE_MYMENU)
- InstallWBMenus(&Menu1);
- else
- SetMenuStrip(Win, &Menu1);
- }
-
-
- static void OpenMenus(void)
- {
- char *yuck;
-
- FileReq.Title = "Open";
- strcpy(Dir, ParMConfig.CurCfg);
- strcpy(File, yuck = BaseName(Dir));
- *yuck = '\0'; /* cut off filename from fr_Dir */
- if (!FileRequester(&FileReq))
- return; /* quit if Open canceled */
- strcpy(ParMConfig.CurCfg, Path);
- UpDateMenus();
- }
-
-
- /* Print busy message in place of window title */
-
- static void Busy(BOOL status)
- {
- SetWindowTitles(Win, (status) ? "Busy" : "ParM", COPYRIGHT);
- }
-
-
- static void Usage(void)
- {
- Printf("%s\nUsage: ParM [-m] [-w] [-x#] [-y#] [-d#] [-b#] [-c#] [-r] [-g] [-a] [-o] [-s#] [-fConfigFile]\n", COPYRIGHT);
- exit(0);
- }
-
-
- /* Atcho, bonsoir... */
-
- void Bye(short err)
- {
- if (err == THE_END) {
- ClearMenus();
- FreeMenus(&ParMConfig);
- if (PortTaken)
- DelMsgPort();
- if (ParMMode == MODE_CLI)
- ModifyIDCMP(Win, OldIDCMP);
- else if (ParMMode == MODE_WINDOW)
- CloseWindowSafely(Win, NULL);
- }
- exit(err);
- }
-
-
- /* change parm current directory */
-
- static void ChangeDir(char *dir)
- {
- BPTR NewLock, OldLock;
-
- NewLock = Lock(dir, ACCESS_READ);
- if (NewLock != NULL) {
- OldLock = CurrentDir(NewLock);
- if (OldLock != NULL)
- UnLock(OldLock);
- }
- }
-
-
- static void DoExtMenu(USHORT MenuNum)
- {
- struct Extended_MenuItem *Item;
- struct Extended_WBStartup *EWBS;
-
- Item = (struct Extended_MenuItem *)ItemAddress(TheMenu, MenuNum);
- switch (Item->emi_Mode) {
- case TOK_ARUN:
- ARun(&ParMConfig, &Item->emi_RunInfo);
- break;
- case TOK_RUN:
- case TOK_SHELL:
- Run(&ParMConfig, &Item->emi_RunInfo, Item->emi_Mode);
- break;
- case TOK_WB:
- if (EWBS = MakeWBStartup(&ParMConfig, &Item->emi_RunInfo))
- WBRun(&ParMConfig, EWBS, Item->emi_RunInfo.ri_Pri);
- break;
- case TOK_CFG: /* new cfg */
- strcpy(ParMConfig.CurCfg, Item->emi_RunInfo.ri_Cmd);
- UpDateMenus();
- DoNextSelect = FALSE; /* Tell DoIntuiMsg not to execute next menu selection */
- }
- }
-
-
- static void parse_arg(char opt, char *args)
- {
- BPTR fh;
- long argl;
-
- argl = Atol(args);
- switch (opt) {
- case 'm':
- ParMMode = MODE_MYMENU;
- break;
- case 'w':
- ParMMode = MODE_WINDOW;
- break;
- case 's':
- if (argl >= 4000) ParMConfig.DefaultStack = argl;
- break;
- case 'x':
- NWS.LeftEdge = argl;
- ParMMode = MODE_WINDOW;
- break;
- case 'y':
- NWS.TopEdge = argl;
- ParMMode = MODE_WINDOW;
- break;
- case 'd':
- NWS.DetailPen = argl;
- ParMMode = MODE_WINDOW;
- break;
- case 'b':
- NWS.BlockPen = argl;
- ParMMode = MODE_WINDOW;
- break;
- case 'c':
- ParMenuColor = argl;
- break;
- case 'f':
- strcpy(ParMConfig.CurCfg, args);
- break;
- case 'r': /* no drag bar */
- ParMMode = MODE_WINDOW;
- NWS.Flags &= ~WINDOWDRAG;
- break;
- case 'g': /* depth gadgets */
- ParMMode = MODE_WINDOW;
- NWS.Flags |= WINDOWDEPTH;
- NWS.Width += 51;
- break;
- case 'a':
- ParMMode = MODE_WINDOW;
- NWS.Flags |= NOCAREREFRESH;
- break;
- case 'o':
- if ((fh = Open("NULL:", MODE_NEWFILE)) || (fh = Open("NIL:", MODE_NEWFILE))) {
- ParMProcess->pr_CIS = fh;
- ParMProcess->pr_COS = fh;
- ParMProcess->pr_ConsoleTask = (APTR)((struct FileHandle *)(fh<<2))->fh_Type;
- }
- break;
- case 'h': /* those can only happen on CLI invocation */
- default:
- Usage();
- }
- }
-
-
- void main(int argc, char *argv[])
- {
- struct CommandLineInterface *cli;
- struct DiskObject *dop;
- struct MsgPort *WorkPort;
- struct IntuiMessage *IMsg;
- ULONG Class;
- USHORT Code,Qual;
- BOOL RefreshIt = TRUE;
- char *arg;
- short i;
-
- TheMenu = &Menu1;
- InitDefaults(&ParMConfig);
- ParMConfig.ReqTitle = "ParM Request";
- ParMConfig.LinkMenu = &Menu1;
- ParMConfig.ItemHeight = 10; /* 9 in BrowserII */
- ParMConfig.SimpleCmdMode = TRUE;
- FileReq.Dir = Dir;
- FileReq.File = File;
- FileReq.PathName = Path;
- FileReq.dirnamescolor = 3;
- FileReq.devicenamescolor = 3;
- FileReq.stringnamecolor = 2;
- FileReq.stringgadgetcolor = 2;
- FileReq.boxbordercolor = 2;
- FileReq.gadgetboxcolor = 2;
- strcpy(FileReq.Show, "*.cfg");
- ParMProcess = (struct Process *)SysBase->ThisTask;
- strcpy(ParMConfig.CurCfg, DEFAULT_CONFIG_FILE);
-
- if (WBenchMsg) { /* Tool Types parsing */
- ParMMode == MODE_WINDOW; /* may be latter overridden by MYMENU mode */
- if (dop = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
- ParMConfig.DefaultStack = dop->do_StackSize;
- for( i = 0 ; i < TTANUM ; i++ ) {
- if (arg = FindToolType(dop->do_ToolTypes, TTA_List[i].tta_Name))
- parse_arg(TTA_List[i].tta_cli_equ, arg);
- }
- FreeDiskObject(dop);
- }
- parse_arg('o', ""); /* allways redirect output to NULL: if started from WorkBench */
- }
- else { /* CLI parsing */
- cli = (struct CommandLineInterface *)((long)ParMProcess->pr_CLI << 2);
- ParMConfig.DefaultStack = cli->cli_DefaultStack << 2;
- for( i = 0 ; i < argc ; i++ ) {
- if (*argv[i] != '-' || strlen(argv[i]) < 2)
- Usage();
- parse_arg(argv[i][1], &argv[i][2]);
- }
- }
- switch(ParMMode) {
- case MODE_WINDOW:
- if (!(Win = OpenWindow(&NWS)))
- Bye(NO_WIN);
- Busy(FALSE); /* SetWindowTitles() */
- break;
- case MODE_CLI:
- Win = GetWindow();
- if (Win->UserPort) {
- if (Win->IDCMPFlags & MENUPICK) {
- SimpleRequest(ParMConfig.ReqTitle, "This window already have menus.");
- Bye(NO_WIN);
- }
- else {
- PortTaken = TRUE;
- OldIDCMP = Win->IDCMPFlags;
- }
- }
- ModifyIDCMP(Win, Win->IDCMPFlags|MENUPICK|CLOSEWINDOW);
- break;
- case MODE_MYMENU:
- if (Win = FindWorkBench()) {
- if (LastWBMenu->NextMenu) {
- SimpleRequest(ParMConfig.ReqTitle, "Menus already installed in WorkBench.");
- Bye(NO_WIN);
- }
- else
- PortTaken = TRUE;
- }
- else {
- SimpleRequest(ParMConfig.ReqTitle, "Can't find WorkBench.");
- Bye(NO_WIN);
- }
- }
- ParMConfig.Win = Win;
- if (PortTaken)
- TakeMsgPort();
- if (ParMenuColor < 0) ParMenuColor = Win->DetailPen;
- CreateParMenu(ParMenuColor);
- UpDateMenus();
-
- /* Monitor Menu Events */
-
- WorkPort = (PortTaken) ? &SwapPort : Win->UserPort;
- while (!quit) {
- WaitPort(WorkPort);
- while (IMsg = (struct IntuiMessage *)GetMsg(WorkPort)) {
- Class = IMsg->Class;
- Code = IMsg->Code;
- Qual = IMsg->Qualifier;
- /* Use raw keys to prevent ALT and CTRL convertions. Allow only Shift qualifiers */
- if (Class == RAWKEY) {
- Code = RawKeyToAscii(Code, Qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT), IMsg->IAddress);
- if (Code != 0 && (Qual & ParMConfig.ShortCutQual) && !(Qual & IEQUALIFIER_REPEAT)) {
- Code = MakeMenuShortCut(TheMenu, Code);
- Class = MENUPICK;
- }
- }
- /*
- * PutMsg() conditions (Messages given to port monitored):
- * MODE_WINDOW:
- * No such port, so all messages replied.
- * MODE_MYMENU:
- * give all messages but ParM's menus MENUPICK and RAWKEYs converted
- * to MENUPICK. handle NEWPREFS after PutMsg().
- * MODE_CLI:
- * if PortTaken, all but MENUPICK and CLOSEWINDOW.
- */
- if (!PortTaken
- || (Class == MENUPICK && (MENUNUM(Code) >= FirstParMMenuNum))
- || (ParMMode == MODE_CLI && Class == CLOSEWINDOW))
- {
- if (Class == 0x0FL) /* Msg sent bye 'ParMCD' command */
- ChangeDir((char *)IMsg->IAddress);
- ReplyMsg((struct Message *)IMsg);
- }
- else {
- PutMsg(&SwapPort, (struct Message *)IMsg);
- if (Class == NEWPREFS) {
- while (LastWBMenu->NextMenu)
- Delay(10);
- InstallWBMenus(&Menu1);
- }
- continue; /* Don't handle these messages */
- }
- switch (Class) {
- case CLOSEWINDOW:
- quit = TRUE;
- break;
- case REFRESHWINDOW:
- if (RefreshIt) {
- if (IsHidden(Win)) {
- WindowToFront(Win);
- RefreshIt = FALSE; /* prevent refresh caused by WindoToFront() */
- }
- }
- else
- RefreshIt = TRUE;
- break;
- case MENUPICK:
- DoNextSelect = TRUE;
- if (Code != MENUNULL) {
- if (ParMMode == MODE_WINDOW)
- Busy(TRUE);
- do {
- /* Prevent extended selection of workbench menus */
- if (MENUNUM(Code) == FirstParMMenuNum) {
- switch(ITEMNUM(Code)) {
- case OPEN_ITEM:
- OpenMenus();
- DoNextSelect = FALSE;
- break;
- case UPDATE_ITEM:
- UpDateMenus();
- DoNextSelect = FALSE;
- break;
- case STD_CFG_ITEM:
- strcpy(ParMConfig.CurCfg, DEFAULT_CONFIG_FILE);
- UpDateMenus();
- DoNextSelect = FALSE;
- break;
- case CMDMODE_ITEM:
- ParMConfig.SimpleCmdMode = SubItem1.Flags & CHECKED;
- break;
- case COMMAND_ITEM:
- Command(&ParMConfig);
- break;
- case CHDIR_ITEM:
- PathName(ParMProcess->pr_CurrentDir, Dir, REQ_DSIZE);
- FileReq.Flags = FRQDIRONLYM;
- FileReq.Title = "Enter New Dir...";
- if (FileRequester(&FileReq))
- ChangeDir(Dir);
- FileReq.Flags = 0;
- break;
- case QUIT_ITEM:
- quit = TRUE;
- DoNextSelect = FALSE;
- }
- }
- else if (MENUNUM(Code) > FirstParMMenuNum) /* custom menus */
- DoExtMenu(Code);
- } while (DoNextSelect && (Code = ItemAddress(TheMenu, Code)->NextSelect) != MENUNULL);
- if (ParMMode == MODE_WINDOW)
- Busy(FALSE);
- }
- break;
- }
- }
- /* See if some wb messages have been replied, and free them */
- FreeRepliedWBMessages();
- }
- Bye(THE_END);
- }
-
-
-