home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
system_utils
/
clis&shells
/
climax
/
climax.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-10
|
13KB
|
517 lines
#ifdef This_Is_A_Comment
Have you ever wanted CLI on a custom screen with 25 lines of 80 characters?
Here it is! By Paul Kienitz, 11/27/88. When compiling with Aztec C, DO NOT
use the +M (3.6) or -BD (5.0) stack checking option. There are some
provisions for compiling it without Aztec, but they are UNTESTED AND
INCOMPLETE. Last revision date: 12/31/90.
Use the +A flag on the Aztec linker.
Improvements needed:
=> o Make it work without ConMan.
o Make it Pure someday.
o B option for inactive window on screen opened in back?
o Cn xxx option to set RGB colors.
o Mn option to set overscanmargin?
o Someday, P option for "productivity mode" screen.
o Dn option for screen depth.
o hot key to bring to front and activate? Make your own, I don't need one.
o Invisible screen gadgets? Nah, too difficult to make text show through.
#endif
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#include <Paul.h>
#define GREENISHNESS {0x484, 0x000, 0x0b0, 0xcc0}
#define DEFAULTISHNESS {0x05a, 0xfff, 0x002, 0xf80}
#define SCLI struct CommandLineInterface
typedef struct {
adr ibase, gbase, dosbase;
struct TextFont *fawnt;
struct Screen *scr;
struct Window *win;
BPTR wandle, ceedee;
} stuffy;
adr IntuitionBase, DOSBase, IconBase, DiskfontBase;
struct GfxBase *GfxBase;
struct WBStartup *WBenchMsg;
struct Process *me;
struct Preferences *prufs;
#define PREFSIZE (long) ( (str) &prufs->color3 + 2 - (str) prufs)
SCLI *fakli = null;
str prompt, setname;
str command, processname;
BPTR oriout, fakeseglist;
bool lace = false, unshelled = false, greenify = false,
frum = false, newfont = false, closeori = false;;
str fontname = "topaz.font"; /* no other choices for now */
long fontsize = 11;
stuffy *stuff;
struct NewScreen scrdef = {
0, 0, 640, 204, /* Width and Height will be set later */
2, /* 4 colors */
0, 0, /* detail pen = background so no white stripe at top */
HIRES, /* inventor of root beer */
CUSTOMSCREEN,
null, null, /* title (won't actually show) filled in later */
null, null
};
struct NewWindow windef = {
0, 4, 640, 200, /* TopEdge and Height will be set later */
0, 1,
0L,
ACTIVATE | BACKDROP | BORDERLESS,
null, null, null, /* no special gadget or checkmark, no title */
null, /* screen pointer; will get set later */
null, /* no custom bitmap */
0, 0, 0, 0, /* ignored */
CUSTOMSCREEN
};
/* these are all in bud.a */
extern void beginning(), ending(), CloseStuff();
extern short StuffOffs, CommandOffs, NameOffs, FakeOffs;
/* for debugging:
#define puf(S, N) (sprintf(buf, S, N), spew(buf))
#define puff(S, N, NN) (sprintf(buf, S, N, NN), spew(buf))
char buf[256];
*/
void exit();
void spew(s) str s;
{
register long l = strlen(s);
if (!oriout && !closeori) {
closeori = true;
oriout = OOpen("CON:60/40/450/80/ CLImax error: ");
}
if (oriout) Write(oriout, s, l);
}
void Die()
{
BPTR *p, *pp;
UnLoadSeg(fakeseglist);
if (stuff->ceedee)
UnLock(stuff->ceedee);
if (fakli && fakli->cli_CommandDir) {
p = gbip(fakli->cli_CommandDir);
while (p) {
UnLock(p[1]);
pp = gbip(*p);
FreeMem(p, 8);
p = pp;
}
}
CloseStuff(stuff);
exit(10);
}
void OpenStuff ()
{ ushort *wbcolor, tallth;
static ushort lacecolor[4] = GREENISHNESS,
unlacecolor[4] = DEFAULTISHNESS;
long collor; /* that's how Joan spelled it once */
struct ViewPort *vp;
short margin = (lace ? 10 : 4);
tallth = (GfxBase->NormalDisplayRows << lace) - margin;
if (tallth < (200 << lace))
tallth = 200 << lace;
else if (tallth > (246 << lace) && tallth < (256 << lace))
tallth = 256 << lace;
if (lace)
scrdef.ViewModes = HIRES | LACE;
windef.TopEdge = margin;
windef.Height = tallth;
scrdef.Height = tallth + margin;
scrdef.Width = windef.Width = GfxBase->NormalDisplayColumns;
scrdef.DefaultTitle = (ubyte *) processname;
if (!(stuff->scr = OpenScreen(&scrdef))) {
spew("\nCLImax: can't open screen.\n");
Die();
}
windef.Screen = stuff->scr;
if (!(stuff->win = OpenWindow(&windef))) {
spew("\nCLImax: can't open backdrop window.\n");
Die();
}
ShowTitle(stuff->scr, FALSE);
vp = &stuff->scr->ViewPort;
prufs = null;
if (greenify) wbcolor = lacecolor;
else if (prufs = Alloc(PREFSIZE)) {
GetPrefs(prufs, PREFSIZE);
wbcolor = &prufs->color0;
} else wbcolor = unlacecolor;
for (collor = 0; collor <= 3; collor++, wbcolor++)
SetRGB4(vp, collor, (*wbcolor >> 8) & 15L,
(*wbcolor >> 4) & 15L,
*wbcolor & 15L);
if (prufs) FreeMem(prufs, PREFSIZE);
}
BPTR CopyPath(tass) str tass;
{
struct Process *wb = (adr) FindTask(tass);
SCLI *wbclap;
BPTR *wext, *mext, *lastmext, newpath = 0;
lastmext = &newpath;
if (!wb) return 0;
if (!(wbclap = gbip(wb->pr_CLI))) return 0;
for (wext = gbip(wbclap->cli_CommandDir); wext; wext = gbip(*wext)) {
if (!(mext = AllocP(2 * sizeof(BPTR))))
break;
*lastmext = (long) mext >> 2;
lastmext = mext;
mext[1] = DupLock(wext[1]);
mext[0] = 0;
}
return (newpath);
}
void bcpy(dest, src, limit) ubyte *dest, *src; short limit;
{
register ushort l = *(src++);
if (l >= limit) l = limit - 1;
*(dest++) = l;
while (l > 0) {
*(dest++) = *(src++);
l--;
}
}
void FakeCLI()
{
if (me->pr_CLI) {
SCLI *mec = gbip(me->pr_CLI);
fakli->cli_DefaultStack = mec->cli_DefaultStack; /* NewCLI does this */
bcpy(prompt, gbip(mec->cli_Prompt), 64);
bcpy(setname, gbip(mec->cli_SetName), 88);
/* I just happen to know that the CLI allocates 64 bytes for the
prompt and 88 bytes for the setname. On its stack. */
fakli->cli_CommandDir = CopyPath(null);
} else {
register BPTR p;
fakli->cli_DefaultStack = 1000L;
if (!(p = CopyPath("Workbench")))
if (!(p = CopyPath("Initial CLI")))
if (!(p = CopyPath("AmigaShell")))
if (!(p = CopyPath("New CLI")))
p = CopyPath("Background CLI");
fakli->cli_CommandDir = p;
/* Why, you ask, am I including code that assumes the CLImax process
has been launched neither from a CLI nor from Workbench?
well, I use MyMenu. and sometimes the path will get set
elsewhere after workbench is already under way so it doesn't know
it. besides, I just had this lying around in FixCLI. */
}
fakli->cli_Prompt = (long) prompt >> 2;
fakli->cli_SetName = (long) setname >> 2;
/* if (!stuff->ceedee) stuff->ceedee = RLock("SYS:"); */
}
void DooFont()
{
struct TextAttr f;
f.ta_Name = (adr) fontname;
f.ta_YSize = fontsize;
f.ta_Style = f.ta_Flags = 0;
stuff->fawnt = OpenFont(&f);
if (stuff->fawnt && fontsize != stuff->fawnt->tf_YSize) {
CloseFont(stuff->fawnt);
stuff->fawnt = null;
}
if (!stuff->fawnt)
if (DiskfontBase = (adr) OpenLibrary("diskfont.library", 0L)) {
stuff->fawnt = OpenDiskFont(&f);
CloseLibrary(DiskfontBase);
}
if (stuff->fawnt)
SetFont(stuff->win->RPort, stuff->fawnt);
}
void wandle()
{
struct DiskObject *bob;
str toop;
register char c;
if (!(IconBase = OpenLibrary("icon.library", 0L))) return;
CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
if (bob = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
if (toop = FindToolType(bob->do_ToolTypes, "OPTION"))
for (c = tolower(*toop); c; c = tolower(*++toop)) {
if (c == 'v') unshelled = true;
else if (c == 'g') greenify = true;
else if (c == 'i') lace = true;
else if (c == 'e') newfont = true;
}
if (toop = FindToolType(bob->do_ToolTypes, "CD")) {
while (*toop && *toop <= ' ') toop++;
if (stuff->ceedee = RLock(toop)) {
register int l = strlen(toop);
if (l >= 88) l = 87;
*setname = l;
strncpy(setname + 1, toop, l);
}
}
if (toop = FindToolType(bob->do_ToolTypes, "FROM")) {
while (*toop && *toop <= ' ') toop++;
if (*toop) {
strcpy(command, "execute ");
strcpy(command + 8, toop);
} else *command = 0;
frum = true;
}
FreeDiskObject(bob);
}
CurrentDir(stuff->ceedee);
CloseLibrary(IconBase);
IconBase = null;
}
int word, chair, ac; stray av;
char nerg()
{
if (word > ac) return (0);
else if (av[word][chair]) return (tolower(av[word][chair++]));
else if (++word <= ac) return (tolower(av[word][chair = 0]));
else return (0);
}
void handle(argc, argv) int argc; str argv[];
{
char c;
bool kelp = false;
ac = argc; av = argv; word = 1; chair = 0;
lace = false;
for (c = nerg(); c; c = nerg()) {
if (c == 'v') unshelled = true;
else if (c == 'i') lace = true;
else if (c == 'g') greenify = true;
else if (c == 'e') newfont = true;
else if (c == '?' || c == 'h') kelp = true;
else if (c == 'f' && nerg() == 'r' && nerg() == 'o' && nerg() == 'm') {
for (c = nerg(); c && c <= ' '; c = nerg()) ;
frum = true;
if (!c) *command = 0;
else {
register str cc = command + 8;
strcpy(command, "execute ");
while (c >= ' ') {
*(cc++) = c;
c = nerg();
}
}
}
}
if (kelp) {
spew(
"\nCLImax by Paul Kienitz -- in the public domain -- usage:\n\n"
" CLIMAX [ V ] [ I ] [ G ] [ E ] [ FROM [ scriptfile ] ]\n\n"
"The letters V, I, G, and E can be in any order, case, or spacing.\n"
" V (vanilla) means use s:CLI-Startup instead of s:Shell-Startup.\n"
" I means make an interlace screen.\n"
" G means use black-on-greenish (good for interlace) instead of\n"
" the Workbench colors (maybe someday there'll be an RGB option).\n"
" E means use the topaz 11 font instead of the system default font.\n"
" FROM scriptfile means execute the named file (instead of S:Shell-Startup)\n"
" before giving the first prompt. Must be the LAST option on the line.\n"
" Use FROM with nothing after it to use no script.\n"
"? or H means show this message.\n\n"
"For Workbench, use a tooltype OPTION= followed by V, I, G, and/or E.\n"
"Also you can use tooltype CD= to specify its current directory.\n"
"And use FROM= to specify a startup scriptfile.\n\n");
Die();
}
stuff->ceedee = DupLock(me->pr_CurrentDir);
}
void Bud() /* grow a "bud" which can detach as a child process */
{
long tize = ((str) &ending - (str) &beginning) + 8;
register str taskspace = AllocP(tize);
if (!taskspace || !IntuitionBase || !GfxBase) {
spew("\nGaaah! Not enough memory for CLImax!\n");
exit(20);
}
CopyMemQuick((str) &beginning, taskspace + 8, tize - 8);
*((long *) taskspace) = (tize + 3) & ~3;
((long *) taskspace)[1] = 0; /* fakeseglist next bptr */
fakeseglist = (((long) taskspace) >> 2) + 1;
taskspace += 8;
command = (adr) (taskspace + CommandOffs);
processname = (adr) (taskspace + NameOffs);
fakli = (adr) (taskspace + FakeOffs);
prompt = (str) fakli + sizeof(SCLI);
setname = prompt + 64;
stuff = (adr) (taskspace + StuffOffs);
stuff->wandle = stuff->ceedee = 0;
stuff->scr = (adr) stuff->win = stuff->fawnt = null;
stuff->ibase = IntuitionBase;
stuff->gbase = GfxBase;
stuff->dosbase = DOSBase;
}
void speck(b, a) str b; long a;
{
short hid, nyb, end;
strcat(b, "CON:Wxxxxxx"); /* uses ConMan */
end = strlen(b) - 1;
for (hid = 0; hid <= 5; hid++) {
nyb = (a >> (4*hid)) & 15;
b[end - hid] = (nyb >= 10 ? (char) nyb + 'A' - 10 : (char) nyb + '0');
}
}
void main(argc, argv) int argc; stray argv;
{
char boof[50];
BPTR L, Seg = 1;
APTR mywptr;
oriout = Output();
#ifndef AZTEC_C
me = ThisProcess();
=== do something to get WBenchMsg ===
#endif
IntuitionBase = (adr) OpenLibrary ("intuition.library", 0L);
GfxBase = (adr) OpenLibrary ("graphics.library", 0L);
Bud();
if (WBenchMsg)
wandle();
else
handle(argc, argv);
OpenStuff();
mywptr = me->pr_WindowPtr;
me->pr_WindowPtr = (APTR) -1L;
if (!frum)
if (!unshelled && (L = RLock("s:shell-startup"))) {
strcpy(command, "execute s:shell-startup");
UnLock(L);
} else if (L = RLock("s:cli-startup")) {
strcpy(command, "execute s:cli-startup");
UnLock(L);
} else *command = 0;
me->pr_WindowPtr = mywptr;
FakeCLI();
boof[0] = 0;
speck(boof, stuff->win);
if (newfont) DooFont();
if (stuff->wandle = OOpen(boof)) {
Write(stuff->wandle,
"CLImax by Paul Kienitz maximizes your CLI.\n", 43L);
CreateProc(processname, 0L, fakeseglist, 2000L);
} else {
spew("\nCLImax can't open the CON: for the window.\n"
"If you do not have ConMan installed, you\n"
"have to do that first!\n");
Die();
}
}
/* reduce size by a few K: */
#ifdef AZTEC_C
char arg[256];
str argp[3] = { "CLImax", arg, null };
void _main(alen, aptr) long alen; str aptr; /* simplified startup code */
{
int al = alen;
me = ThisProcess();
if (me->pr_CLI) {
if (al > 255) al = 255;
strncpy(arg, aptr, al);
arg[al - 1] = 0;
WBenchMsg = null;
} else {
WaitPort(&me->pr_MsgPort);
WBenchMsg = (adr) GetMsg(&me->pr_MsgPort);
}
main(1, argp); /* pack all args into argv[1] */
exit(0);
}
void exit(code) int code;
{
char c;
if (oriout && closeori) {
spew("\n - press return - ");
Read(oriout, &c, 1L);
Close(oriout);
}
if (WBenchMsg) {
Forbid();
ReplyMsg((struct Message *) WBenchMsg);
}
Exit((long) code);
}
#endif