home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d157
/
xicon.lha
/
Xicon
/
Xicon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-02
|
15KB
|
476 lines
/*****************************************************************
* *
* XICON V2.01 *
* *
* Runs Command Script Files from an Icon *
* *
* copyright 1986, 1987, 1988 by Pete Goodeve *
* -- All Rights Reserved *
* *
* Compile with pass2 -v option (Lattice) *
* Link with c.o, amiga.lib, lc.lib *
* *
* vers 88:2:14 *
*****************************************************************/
#include "exec/types.h"
#include "exec/exec.h"
#include "workbench/startup.h"
#include "workbench/workbench.h"
#include "workbench/icon.h"
#include "libraries/dosextens.h"
LONG IntuitionBase;
short V1_2 = FALSE;
LONG IconBase;
extern struct Window *findwindow();
extern struct WBStartup *WBenchMsg;
struct WBArg *argptr;
short nargs;
short autoclose=TRUE, /* will be FALSEified by non-use of 'closewindow' */
usescript=TRUE, usewindow = TRUE, istext = FALSE;
short abortmark = FALSE;
#define MAXDESCR 120
char ConDescr[MAXDESCR+4] = "CON:0/10/640/185/XICON 2.01";
/* available for later fiddling */
#define MAXTITLE 100
char Title[MAXTITLE];
LONG outfile = NULL;
extern struct Window *conWindow;
extern struct ConUnit *conUnit;
LONG windowsig;
/** Close Gadget structure */
LONG Close_Data[] = { /* move to chip ram before use */
0x3FFFFC80,
0x30000C80,
0x33FFCC80,
0x33FFCC80,
0x33C3CC80,
0x33C3CC80,
0x33FFCC80,
0x33FFCC80,
0x30000C80,
0x3FFFFC80,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
0x003C0000,
0x003C0000,
0x00000000,
0x00000000,
0x00000000,
0x00000000
};
struct Image Close_Image = {
0, 0, /* Left, Top */
0x0019, 0x000A, 2, /* Width, Height, Depth */
NULL, /* filled in to point to image in chip ram */
3, 0,
NULL
};
struct Gadget Close_Gadg = {
NULL, /* pointer to Next Gadget */
4, 0, 0x019, 0x0A, /* (Left Top Width Height) Hit Box */
GADGHCOMP | GADGIMAGE, /* Flags */
/* Activation flags */
RELVERIFY,
SYSGADGET | CLOSE, /* Type (!) */
(APTR)&Close_Image, /* pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
NULL, /* no pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
/* Continue Gadget structure */
struct IntuiText Cont_Text = {
3,0, /* front, back pens */
JAM2, /* draw mode */
10,1, /* left, top edge */
NULL, /* default font */
NULL, /* text string -- filled in before use */
NULL /* no next */
};
struct Gadget Cont_Gadg = {
NULL, /* pointer to Next Gadget */
0, -9, 0, 9, /* (Left Top Full-Width Height) Hit Box */
GADGHCOMP | GRELWIDTH | GRELBOTTOM , /* Flags */
/* Activation flags */
RELVERIFY,
BOOLGADGET, /* Type */
NULL, /* no pointer to GadgetRender */
NULL, /* no pointer to SelectRender */
&Cont_Text, /* pointer to GadgetText */
0, /* no MutualExclude */
NULL, /* no pointer to SpecialInfo */
0, /* no ID */
NULL /* no pointer to special data */
};
_main() /* bypasses standard C startup code */
{
if (!WBenchMsg)
return 0;
if (IntuitionBase = OpenLibrary("intuition.library",33)) V1_2 = TRUE;
else IntuitionBase = OpenLibrary("intuition.library",0);
IconBase = OpenLibrary(ICONNAME,1); /* doesn't matter much if not there */
argptr = WBenchMsg->sm_ArgList;
nargs = WBenchMsg->sm_NumArgs;
/* Skip the first arg (the program itself) and process the rest */
for(argptr++, nargs--; nargs; argptr++, nargs--)
if (!doito(argptr)) goto clean_exit; /* sometimes a goto is good */
SetSignal(0, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
if (usewindow && !autoclose) {
Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
}
clean_exit:
dump_window();
if (outfile) Close(outfile);
if (IconBase) CloseLibrary(IconBase);
CloseLibrary(IntuitionBase); /* this is in "ROM" (so no check needed) */
}
/*** end main ***/
/************************************************************
* In the code below, I don't follow the usual method of *
* passing each command string in turn to Execute. Instead *
* I pass the entire command file as the new input stream, *
* which Execute accepts after processing the null string *
* it gets as a "command". This avoids the system having *
* to reload the DOS "RUN" module for every line of the *
* command file, though on the other hand it does lock out *
* the possibility of redirecting keyboard input through *
* the "current window" to the command. I thought the *
* trade-off was worth it. *
************************************************************/
doito(argp) struct WBArg *argp;
{
LONG oldir;
oldir = CurrentDir(argp->wa_Lock);
if (!readtt(argp) || abortmark) return FALSE;
if (istext) dispfile(argp->wa_Name);
else if (usescript)
if (!execfile(argp->wa_Name)) return FALSE;
/* I don't see how that could happen, but...*/
CurrentDir(oldir);
return TRUE;
}
execfile(fname) char *fname;
{
LONG infile;
infile = Open(fname, MODE_OLDFILE);
if (!infile) return FALSE;
Execute("", infile, outfile);
Close(infile);
return TRUE;
}
/* Read ToolTypes of current icon */
readtt(argp) struct WBArg *argp;
{
struct DiskObject *iconobj=NULL, *GetDiskObject();
char **toolarray, *FindToolType();
char *modes, *windowstring, *titlestring, *locdir;
LONG dirfile;
if (!IconBase) {
if (!get_window(ConDescr)) return FALSE;
display("Icon Library not found -- ignoring ToolTypes\n");
return TRUE; /* just soldier on...*/
}
/* we don't do any checks here for icon type -- probably should...*/
if (!(iconobj = GetDiskObject(argp->wa_Name))) {
display("COULDN'T GET INFO FOR ICON!!\n");
return TRUE;
}
toolarray = iconobj->do_ToolTypes;
modes = FindToolType(toolarray,"MODE");
autoclose &= MatchToolValue(modes,"closewindow");
/* ALL must agree to close the window automatically */
usescript = !MatchToolValue(modes,"noscript");
istext = MatchToolValue(modes,"text");
if (windowstring = FindToolType(toolarray,"WINDOW"))
strncpy(&ConDescr[4], windowstring, MAXDESCR); /* append to 'CON:' */
/* the above is probably a Lattice special...*/
if (!outfile) {
usewindow = !MatchToolValue(modes,"nowindow");
if (usewindow)
get_window(ConDescr);
else
outfile = Open("NIL:", MODE_OLDFILE);
}
if (!outfile) return FALSE;
if (conWindow && (titlestring = FindToolType(toolarray,"TITLE"))) {
strncpy(Title, titlestring, MAXTITLE);
/* Note that SetWindowTitles does NOT copy the string! */
SetWindowTitles(conWindow, Title, -1);
}
if ((locdir = FindToolType(toolarray,"LOCDIR")) &&
(dirfile = Open(locdir,MODE_NEWFILE)))
{
Write(dirfile,"\"",1);
traverse(argp->wa_Lock, dirfile);
Write(dirfile,"\"\n",2);
Close(dirfile);
}
dotoolcmds(toolarray); /* some tooltypes may be commands */
FreeDiskObject(iconobj);
return TRUE;
}
/* Execute any commands specified in the ToolTypes */
dotoolcmds(toolarray) char **toolarray;
{
char *holdnext, *toolstr, *FindToolType();
LONG lock;
while (*toolarray) {
holdnext = toolarray[1];
toolarray[1] = NULL;
if (!abortmark) {
if (toolstr=FindToolType(toolarray,"REM")) {
display(toolstr);
display("\n");
}
else if (toolstr=FindToolType(toolarray,"TEXT"))
dispfile(toolstr);
else if (toolstr=FindToolType(toolarray,"CMD"))
Execute(toolstr,0,outfile);
else if (toolstr=FindToolType(toolarray,"SCRIPT"))
execfile(toolstr);
else if (!strcmp(*toolarray,"PAUSE")) /*FindT-T- needs "=" */
abortmark = pausekey();
else if (toolstr=FindToolType(toolarray,"EXISTS")) {
if (lock = Lock(toolstr,ACCESS_READ)) UnLock(lock);
else abortmark = TRUE;
}
} /* end !abortmark */
else /* abort has been signalled */ {
if (toolstr=FindToolType(toolarray,"ABORT-REM")) {
display(toolstr);
display("\n");
}
else if (toolstr=FindToolType(toolarray,"ABORT-TEXT"))
dispfile(toolstr);
else if (toolstr=FindToolType(toolarray,"ABORT-CMD"))
Execute(toolstr,0,outfile);
else if (toolstr=FindToolType(toolarray,"ABORT-SCRIPT"))
execfile(toolstr);
else if (!strcmp(*toolarray,"ABORT-PAUSE"))
abortmark = pausekey();
else if (!strcmp(*toolarray,"RESTORE"))
abortmark = FALSE;
}
*++toolarray = holdnext; /* restore next item & move to it */
}
}
traverse(lock, dirfile) ULONG lock, dirfile;
{
short level;
ULONG pdlock;
struct DeviceList *volp;
struct FileLock *lockp;
char *namep;
struct FileInfoBlock *fib;
if (lock) {
fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC | MEMF_CLEAR);
if (!fib) return 2; /* ...being lazy */
level = traverse(pdlock=ParentDir(lock), dirfile);
UnLock(pdlock);
if (level > 1) /* there is a superior non-root directory */
Write(dirfile, "/", 1);
if (level == 0) /* this was the root directory */ {
/* all this to overcome RAM: handler bug...*/
lockp = (struct FileLock *)BADDR(lock);
volp = (struct DeviceList *)BADDR(lockp->fl_Volume);
namep = (char *)BADDR(volp->dl_Name);
Write(dirfile, namep+1, *namep);
Write(dirfile, ":", 1);
}
else {
if (Examine(lock,fib))
Write(dirfile,fib->fib_FileName,strlen(fib->fib_FileName));
}
FreeMem(fib,sizeof(struct FileInfoBlock));
return level+1;
}
else return 0;
}
get_window(windescr) char *windescr;
{
if (outfile) /* already open */ return TRUE;
outfile = Open(windescr, MODE_OLDFILE);
if (!outfile) return FALSE;
if (!findWindow(outfile)) return FALSE;
if (!(Close_Image.ImageData = AllocMem(sizeof(Close_Data), MEMF_CHIP)))
return TRUE; /* just ignore close gadget */
/* the following may be a Lattice special..?*/
movmem(Close_Data, Close_Image.ImageData, sizeof(Close_Data));
ModifyIDCMP(conWindow, CLOSEWINDOW); /* Heh..again*/
windowsig = 1<<(conWindow->UserPort->mp_SigBit);
conWindow->Flags |= WINDOWCLOSE; /* Heh heh! */
AddGadget(conWindow, &Close_Gadg, 0); /* Must be on TOP of drag gadget */
if (V1_2)
RefreshWindowFrame(conWindow);
else {
SetWindowTitles(conWindow, conWindow->Title, -1);
RefreshGadgets(&Close_Gadg, conWindow, NULL);
}
return TRUE;
} /* get_window */
dump_window()
{
if (!Close_Image.ImageData) return;
ModifyIDCMP(conWindow, 0);
RemoveGadget(conWindow, &Close_Gadg);
FreeMem(Close_Image.ImageData, sizeof(Close_Data));
/* file & window are closed at a higher level */
}
display(msg) char *msg;
{
Write(outfile, msg, strlen(msg));
}
/**************************************/
#define BUFSIZE 200
LONG textfile;
static short curmax = 0;
dispfile(fname) char *fname;
{
char inbuf[BUFSIZE], outbuf[BUFSIZE], ansbuf[2];
short inpos = 0, lcount = 20;
curmax = 0;
textfile = Open(fname, MODE_OLDFILE);
if (!textfile || !conWindow) return FALSE;
ModifyIDCMP(conWindow, conWindow->IDCMPFlags | RAWKEY);
while (copyline(inbuf, &inpos, outbuf)) {
if (!lcount-- || *outbuf == '\014' /*Formfeed*/) {
if (pausekey()) goto cutit; /* just continues unless CLOSE */
display(outbuf);
lcount = 15; /* leave some overlap with previous page */
}
else display(outbuf);
}
cutit:
Close(textfile);
ModifyIDCMP(conWindow, conWindow->IDCMPFlags & ~RAWKEY);
}
copyline(in, pos, out) char *in, *out; short *pos;
{
char ch, copych();
short trunc=BUFSIZE-1;
while ((*out++ = ch = copych(in, pos)) && ch != '\n' && --trunc)
/*loop*/;
*out = '\0';
return (int) ch /* FALSE if EOF */;
}
char copych(in, pos) char *in; short *pos;
{
if (*pos >= curmax) {
curmax = Read(textfile,in,BUFSIZE);
*pos = 0;
if (!curmax) return '\0';
}
return in[(*pos)++];
}
pausekey()
{
int code;
Cont_Text.IText = "to CONTINUE -- Click here or Type any key";
AddGadget(conWindow, &Cont_Gadg, -1);
RefreshGadgets(&Cont_Gadg, conWindow, NULL);
code = pause(RAWKEY | GADGETUP);
Cont_Text.IText = " ";
/* seems crude, but it's all I can figger.. */
RefreshGadgets(&Cont_Gadg, conWindow, NULL);
RemoveGadget(conWindow, &Cont_Gadg);
return code;
}
#define CODE_C 0x033
pause(evmask) ULONG evmask; /* waits for a relevant event from the window */
/* if it is a CLOSEWINDOW or cntrl-C it returns TRUE,
otherwise FALSE */
{
struct IntuiMessage *eventmsg, *GetMsg();
ULONG oldIDCMP, class, mark = FALSE;
USHORT code, qual;
if (!conWindow) return FALSE; /* only wait if there's a window */
oldIDCMP = conWindow->IDCMPFlags;
if (evmask) ModifyIDCMP(conWindow, conWindow->IDCMPFlags | evmask);
do {
Wait(windowsig);
while(eventmsg = GetMsg(conWindow->UserPort)) {
class = eventmsg->Class;
code = eventmsg->Code;
qual = eventmsg->Qualifier;
ReplyMsg(eventmsg);
if((class == CLOSEWINDOW) ||
(class == RAWKEY && (qual & IEQUALIFIER_CONTROL) && code == CODE_C ))
{
mark = TRUE;
break;
}
}
} while ((class == RAWKEY) && (code & IECODE_UP_PREFIX));
/* ignore left-over key-ups */
if (evmask) ModifyIDCMP(conWindow, oldIDCMP);
return mark;
}
/**************************************/