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 >
C/C++ Source or Header  |  1991-01-10  |  13KB  |  517 lines

  1. #ifdef This_Is_A_Comment
  2.  
  3. Have you ever wanted CLI on a custom screen with 25 lines of 80 characters? 
  4. Here it is!  By Paul Kienitz, 11/27/88.  When compiling with Aztec C, DO NOT
  5. use the +M (3.6) or -BD (5.0) stack checking option.  There are some
  6. provisions for compiling it without Aztec, but they are UNTESTED AND
  7. INCOMPLETE.  Last revision date:  12/31/90.
  8.  
  9. Use the +A flag on the Aztec linker.
  10.  
  11. Improvements needed:
  12. => o Make it work without ConMan.
  13.    o Make it Pure someday.
  14.    o B option for inactive window on screen opened in back?
  15.    o Cn xxx option to set RGB colors.
  16.    o Mn option to set overscanmargin?
  17.    o Someday, P option for "productivity mode" screen.
  18.    o Dn option for screen depth.
  19.    o hot key to bring to front and activate?  Make your own, I don't need one.
  20.    o Invisible screen gadgets?  Nah, too difficult to make text show through.
  21.  
  22. #endif
  23.  
  24.  
  25. #include <exec/exec.h>
  26. #include <intuition/intuition.h>
  27. #include <graphics/gfxbase.h>
  28. #include <workbench/workbench.h>
  29. #include <workbench/startup.h>
  30. #include <libraries/dosextens.h>
  31. #include <Paul.h>
  32.  
  33.  
  34. #define GREENISHNESS    {0x484, 0x000, 0x0b0, 0xcc0}
  35. #define DEFAULTISHNESS    {0x05a, 0xfff, 0x002, 0xf80}
  36.  
  37. #define SCLI struct CommandLineInterface
  38.  
  39.  
  40. typedef struct {
  41.     adr ibase, gbase, dosbase;
  42.     struct TextFont *fawnt;
  43.     struct Screen *scr;
  44.     struct Window *win;
  45.     BPTR wandle, ceedee;
  46. } stuffy;
  47.  
  48.  
  49. adr IntuitionBase, DOSBase, IconBase, DiskfontBase;
  50. struct GfxBase *GfxBase;
  51.  
  52. struct WBStartup *WBenchMsg;
  53. struct Process *me;
  54. struct Preferences *prufs;
  55.  
  56. #define PREFSIZE (long) ( (str) &prufs->color3 + 2 - (str) prufs)
  57.  
  58. SCLI *fakli = null;
  59. str prompt, setname;
  60.  
  61. str command, processname;
  62. BPTR oriout, fakeseglist;
  63.  
  64. bool lace = false, unshelled = false, greenify = false,
  65.     frum = false, newfont = false, closeori = false;;
  66.  
  67.  
  68. str fontname = "topaz.font";        /* no other choices for now */
  69. long fontsize = 11;
  70.  
  71. stuffy *stuff;
  72.  
  73.  
  74. struct NewScreen scrdef = {
  75.     0, 0, 640, 204,    /* Width and Height will be set later */
  76.     2,            /*  4 colors  */
  77.     0, 0,        /*  detail pen = background so no white stripe at top */
  78.     HIRES,        /* inventor of root beer */
  79.     CUSTOMSCREEN,
  80.     null, null,    /* title (won't actually show) filled in later */
  81.     null, null
  82. };
  83.  
  84.  
  85. struct NewWindow windef = {
  86.     0, 4, 640, 200,    /* TopEdge and Height will be set later */
  87.     0, 1,
  88.     0L,
  89.     ACTIVATE | BACKDROP | BORDERLESS,
  90.     null, null, null,    /* no special gadget or checkmark, no title */
  91.     null,            /* screen pointer; will get set later */
  92.     null,            /* no custom bitmap */
  93.     0, 0, 0, 0,        /* ignored */
  94.     CUSTOMSCREEN
  95. };
  96.  
  97.  
  98. /* these are all in bud.a */
  99. extern void beginning(), ending(), CloseStuff();
  100. extern short StuffOffs, CommandOffs, NameOffs, FakeOffs;
  101.  
  102.  
  103. /* for debugging:
  104. #define puf(S, N) (sprintf(buf, S, N), spew(buf))
  105. #define puff(S, N, NN) (sprintf(buf, S, N, NN), spew(buf))
  106. char buf[256];
  107. */
  108.  
  109.  
  110. void exit();
  111.  
  112.  
  113.  
  114. void spew(s) str s;
  115. {
  116.     register long l = strlen(s);
  117.     if (!oriout && !closeori) {
  118.     closeori = true;
  119.     oriout = OOpen("CON:60/40/450/80/ CLImax error: ");
  120.     }
  121.     if (oriout) Write(oriout, s, l);
  122. }
  123.  
  124.  
  125.  
  126. void Die()
  127. {
  128.     BPTR *p, *pp;
  129.     UnLoadSeg(fakeseglist);
  130.     if (stuff->ceedee)
  131.     UnLock(stuff->ceedee);
  132.     if (fakli && fakli->cli_CommandDir) {
  133.     p = gbip(fakli->cli_CommandDir);
  134.     while (p) {
  135.         UnLock(p[1]);
  136.         pp = gbip(*p);
  137.         FreeMem(p, 8);
  138.         p = pp;
  139.     }
  140.     }
  141.     CloseStuff(stuff);
  142.     exit(10);
  143. }
  144.  
  145.  
  146.  
  147. void OpenStuff ()
  148. {   ushort *wbcolor, tallth;
  149.     static ushort lacecolor[4] = GREENISHNESS,
  150.           unlacecolor[4] = DEFAULTISHNESS;
  151.     long collor;    /* that's how Joan spelled it once */
  152.     struct ViewPort *vp;
  153.     short margin = (lace ? 10 : 4);
  154.  
  155.     tallth = (GfxBase->NormalDisplayRows << lace) - margin;
  156.     if (tallth < (200 << lace))
  157.     tallth = 200 << lace;
  158.     else if (tallth > (246 << lace) && tallth < (256 << lace))
  159.     tallth = 256 << lace;
  160.     if (lace)
  161.     scrdef.ViewModes = HIRES | LACE;
  162.     windef.TopEdge = margin;
  163.     windef.Height = tallth;
  164.     scrdef.Height = tallth + margin;
  165.     scrdef.Width = windef.Width = GfxBase->NormalDisplayColumns;
  166.     scrdef.DefaultTitle = (ubyte *) processname;
  167.     if (!(stuff->scr = OpenScreen(&scrdef))) {
  168.     spew("\nCLImax: can't open screen.\n");
  169.     Die();
  170.     }
  171.     windef.Screen = stuff->scr;
  172.     if (!(stuff->win = OpenWindow(&windef))) {
  173.     spew("\nCLImax: can't open backdrop window.\n");
  174.     Die();
  175.     }
  176.     ShowTitle(stuff->scr, FALSE);
  177.     vp = &stuff->scr->ViewPort;
  178.     prufs = null;
  179.     if (greenify) wbcolor = lacecolor;
  180.     else if (prufs = Alloc(PREFSIZE)) {
  181.     GetPrefs(prufs, PREFSIZE);
  182.     wbcolor = &prufs->color0;
  183.     } else wbcolor = unlacecolor;
  184.     for (collor = 0; collor <= 3; collor++, wbcolor++)
  185.     SetRGB4(vp, collor, (*wbcolor >> 8) & 15L,
  186.             (*wbcolor >> 4) & 15L,
  187.             *wbcolor & 15L);
  188.     if (prufs) FreeMem(prufs, PREFSIZE);
  189. }
  190.  
  191.  
  192.  
  193. BPTR CopyPath(tass) str tass;
  194. {
  195.     struct Process *wb = (adr) FindTask(tass);
  196.     SCLI *wbclap;
  197.     BPTR *wext, *mext, *lastmext, newpath = 0;
  198.     lastmext = &newpath;
  199.     if (!wb) return 0;
  200.     if (!(wbclap = gbip(wb->pr_CLI))) return 0;
  201.     for (wext = gbip(wbclap->cli_CommandDir); wext; wext = gbip(*wext)) {
  202.     if (!(mext = AllocP(2 * sizeof(BPTR))))
  203.         break;
  204.     *lastmext = (long) mext >> 2;
  205.     lastmext = mext;
  206.     mext[1] = DupLock(wext[1]);
  207.     mext[0] = 0;
  208.     }
  209.     return (newpath);
  210. }
  211.  
  212.  
  213.  
  214. void bcpy(dest, src, limit) ubyte *dest, *src; short limit;
  215. {
  216.     register ushort l = *(src++);
  217.     if (l >= limit) l = limit - 1;
  218.     *(dest++) = l;
  219.     while (l > 0) {
  220.     *(dest++) = *(src++);
  221.     l--;
  222.     }
  223. }
  224.  
  225.  
  226.  
  227. void FakeCLI()
  228. {
  229.     if (me->pr_CLI) {
  230.     SCLI *mec = gbip(me->pr_CLI);
  231.     fakli->cli_DefaultStack = mec->cli_DefaultStack;  /* NewCLI does this */
  232.     bcpy(prompt, gbip(mec->cli_Prompt), 64);
  233.     bcpy(setname, gbip(mec->cli_SetName), 88);
  234.     /* I just happen to know that the CLI allocates 64 bytes for the
  235.         prompt and 88 bytes for the setname.  On its stack. */
  236.     fakli->cli_CommandDir = CopyPath(null);
  237.     } else {
  238.     register BPTR p;
  239.     fakli->cli_DefaultStack = 1000L;
  240.     if (!(p = CopyPath("Workbench")))
  241.         if (!(p = CopyPath("Initial CLI")))
  242.         if (!(p = CopyPath("AmigaShell")))
  243.             if (!(p = CopyPath("New CLI")))
  244.             p = CopyPath("Background CLI");
  245.     fakli->cli_CommandDir = p;
  246.     /* Why, you ask, am I including code that assumes the CLImax process
  247.        has been launched neither from a CLI nor from Workbench?
  248.            well, I use MyMenu.  and sometimes the path will get set
  249.        elsewhere after workbench is already under way so it doesn't know
  250.        it.  besides, I just had this lying around in FixCLI. */
  251.     }
  252.     fakli->cli_Prompt = (long) prompt >> 2;
  253.     fakli->cli_SetName = (long) setname >> 2;
  254. /*  if (!stuff->ceedee) stuff->ceedee = RLock("SYS:");  */
  255. }
  256.  
  257.  
  258.  
  259. void DooFont()
  260. {
  261.     struct TextAttr f;
  262.     f.ta_Name = (adr) fontname;
  263.     f.ta_YSize = fontsize;
  264.     f.ta_Style = f.ta_Flags = 0;
  265.     stuff->fawnt = OpenFont(&f);
  266.     if (stuff->fawnt && fontsize != stuff->fawnt->tf_YSize) {
  267.     CloseFont(stuff->fawnt);
  268.     stuff->fawnt = null;
  269.     }
  270.     if (!stuff->fawnt)
  271.     if (DiskfontBase = (adr) OpenLibrary("diskfont.library", 0L)) {
  272.         stuff->fawnt = OpenDiskFont(&f);
  273.         CloseLibrary(DiskfontBase);
  274.     }
  275.     if (stuff->fawnt)
  276.     SetFont(stuff->win->RPort, stuff->fawnt);
  277. }
  278.  
  279.  
  280.  
  281. void wandle()
  282. {
  283.     struct DiskObject *bob;
  284.     str toop;
  285.     register char c;
  286.  
  287.     if (!(IconBase = OpenLibrary("icon.library", 0L))) return;
  288.     CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  289.     if (bob = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
  290.     if (toop = FindToolType(bob->do_ToolTypes, "OPTION"))
  291.         for (c = tolower(*toop); c; c = tolower(*++toop)) {
  292.         if (c == 'v') unshelled = true;
  293.         else if (c == 'g') greenify = true;
  294.         else if (c == 'i') lace = true;
  295.         else if (c == 'e') newfont = true;
  296.         }
  297.     if (toop = FindToolType(bob->do_ToolTypes, "CD")) {
  298.         while (*toop && *toop <= ' ') toop++;
  299.         if (stuff->ceedee = RLock(toop)) {
  300.         register int l = strlen(toop);
  301.         if (l >= 88) l = 87;
  302.         *setname = l;
  303.         strncpy(setname + 1, toop, l);
  304.         }
  305.     }
  306.     if (toop = FindToolType(bob->do_ToolTypes, "FROM")) {
  307.         while (*toop && *toop <= ' ') toop++;
  308.         if (*toop) {
  309.         strcpy(command, "execute ");
  310.         strcpy(command + 8, toop);
  311.         } else *command = 0;
  312.         frum = true;
  313.     }
  314.     FreeDiskObject(bob);
  315.     }
  316.     CurrentDir(stuff->ceedee);
  317.     CloseLibrary(IconBase);
  318.     IconBase = null;
  319. }
  320.  
  321.  
  322.  
  323. int word, chair, ac; stray av;
  324.  
  325. char nerg()
  326. {
  327.     if (word > ac) return (0);
  328.     else if (av[word][chair]) return (tolower(av[word][chair++]));
  329.     else if (++word <= ac) return (tolower(av[word][chair = 0]));
  330.     else return (0);
  331. }
  332.  
  333.  
  334.  
  335. void handle(argc, argv) int argc; str argv[];
  336. {
  337.     char c;
  338.     bool kelp = false;
  339.     ac = argc; av = argv; word = 1; chair = 0;
  340.     lace = false;
  341.     for (c = nerg(); c; c = nerg()) {
  342.     if (c == 'v') unshelled = true;
  343.     else if (c == 'i') lace = true;
  344.     else if (c == 'g') greenify = true;
  345.     else if (c == 'e') newfont = true;
  346.     else if (c == '?' || c == 'h') kelp = true;
  347.     else if (c == 'f' && nerg() == 'r' && nerg() == 'o' && nerg() == 'm') {
  348.         for (c = nerg(); c && c <= ' '; c = nerg()) ;
  349.         frum = true;
  350.         if (!c) *command = 0;
  351.         else {
  352.         register str cc = command + 8;
  353.         strcpy(command, "execute ");
  354.         while (c >= ' ') {
  355.             *(cc++) = c;
  356.             c = nerg();
  357.         }
  358.         }
  359.     }
  360.     }
  361.     if (kelp) {
  362.     spew(
  363. "\nCLImax by Paul Kienitz -- in the public domain -- usage:\n\n"
  364. "    CLIMAX [ V ]  [ I ]  [ G ]  [ E ]   [ FROM [ scriptfile ] ]\n\n"
  365. "The letters V, I, G, and E can be in any order, case, or spacing.\n"
  366. " V (vanilla) means use s:CLI-Startup instead of s:Shell-Startup.\n"
  367. " I means make an interlace screen.\n"
  368. " G means use black-on-greenish (good for interlace) instead of\n"
  369. "     the Workbench colors (maybe someday there'll be an RGB option).\n"
  370. " E means use the topaz 11 font instead of the system default font.\n"
  371. " FROM scriptfile means execute the named file (instead of S:Shell-Startup)\n"
  372. "     before giving the first prompt.  Must be the LAST option on the line.\n"
  373. "     Use FROM with nothing after it to use no script.\n"
  374. "? or H means show this message.\n\n"
  375. "For Workbench, use a tooltype OPTION= followed by V, I, G, and/or E.\n"
  376. "Also you can use tooltype CD= to specify its current directory.\n"
  377. "And use FROM= to specify a startup scriptfile.\n\n");
  378.     Die();
  379.     }
  380.     stuff->ceedee = DupLock(me->pr_CurrentDir);
  381. }
  382.  
  383.  
  384.  
  385. void Bud()    /* grow a "bud" which can detach as a child process */
  386. {
  387.     long tize = ((str) &ending - (str) &beginning) + 8;
  388.     register str taskspace = AllocP(tize);
  389.     if (!taskspace || !IntuitionBase || !GfxBase) {
  390.     spew("\nGaaah!  Not enough memory for CLImax!\n");
  391.     exit(20);
  392.     }
  393.     CopyMemQuick((str) &beginning, taskspace + 8, tize - 8);
  394.     *((long *) taskspace) = (tize + 3) & ~3;
  395.     ((long *) taskspace)[1] = 0;        /* fakeseglist next bptr */
  396.     fakeseglist = (((long) taskspace) >> 2) + 1;
  397.     taskspace += 8;
  398.     command = (adr) (taskspace + CommandOffs);
  399.     processname = (adr) (taskspace + NameOffs);
  400.     fakli = (adr) (taskspace + FakeOffs);
  401.     prompt = (str) fakli + sizeof(SCLI);
  402.     setname = prompt + 64;
  403.     stuff = (adr) (taskspace + StuffOffs);
  404.     stuff->wandle = stuff->ceedee = 0;
  405.     stuff->scr = (adr) stuff->win = stuff->fawnt = null;
  406.     stuff->ibase = IntuitionBase;
  407.     stuff->gbase = GfxBase;
  408.     stuff->dosbase = DOSBase;
  409. }
  410.  
  411.  
  412.  
  413. void speck(b, a) str b; long a;
  414. {
  415.    short hid, nyb, end;
  416.    strcat(b, "CON:Wxxxxxx");        /* uses ConMan */
  417.    end = strlen(b) - 1;
  418.    for (hid = 0; hid <= 5; hid++) {
  419.       nyb = (a >> (4*hid)) & 15;
  420.       b[end - hid] = (nyb >= 10 ? (char) nyb + 'A' - 10 : (char) nyb + '0');
  421.    }
  422. }
  423.  
  424.  
  425.  
  426. void main(argc, argv) int argc; stray argv;
  427. {
  428.     char boof[50];
  429.     BPTR L, Seg = 1;
  430.     APTR mywptr;
  431.  
  432.     oriout = Output();
  433. #ifndef AZTEC_C
  434.     me = ThisProcess();
  435.     === do something to get WBenchMsg ===
  436. #endif
  437.     IntuitionBase = (adr) OpenLibrary ("intuition.library", 0L);
  438.     GfxBase = (adr) OpenLibrary ("graphics.library", 0L);
  439.     Bud();
  440.     if (WBenchMsg)
  441.     wandle();
  442.     else
  443.     handle(argc, argv);
  444.     OpenStuff();
  445.     mywptr = me->pr_WindowPtr;
  446.     me->pr_WindowPtr = (APTR) -1L;
  447.     if (!frum)
  448.     if (!unshelled && (L = RLock("s:shell-startup"))) {
  449.         strcpy(command, "execute s:shell-startup");
  450.         UnLock(L);
  451.     } else if (L = RLock("s:cli-startup")) {
  452.         strcpy(command, "execute s:cli-startup");
  453.         UnLock(L);
  454.     } else *command = 0;
  455.     me->pr_WindowPtr = mywptr;
  456.     FakeCLI();
  457.     boof[0] = 0;
  458.     speck(boof, stuff->win);
  459.     if (newfont) DooFont();
  460.     if (stuff->wandle = OOpen(boof)) {
  461.     Write(stuff->wandle,
  462.         "CLImax by Paul Kienitz maximizes your CLI.\n", 43L);
  463.     CreateProc(processname, 0L, fakeseglist, 2000L);
  464.     } else {
  465.     spew("\nCLImax can't open the CON: for the window.\n"
  466.         "If you do not have ConMan installed, you\n"
  467.         "have to do that first!\n");
  468.     Die();
  469.     }
  470. }
  471.  
  472.  
  473.  
  474. /* reduce size by a few K: */
  475.  
  476. #ifdef AZTEC_C
  477.  
  478. char arg[256];
  479. str argp[3] = { "CLImax", arg, null };
  480.  
  481.  
  482. void _main(alen, aptr) long alen; str aptr;  /* simplified startup code */
  483. {
  484.     int al = alen;
  485.     me = ThisProcess();
  486.     if (me->pr_CLI) {
  487.     if (al > 255) al = 255;
  488.     strncpy(arg, aptr, al);
  489.     arg[al - 1] = 0;
  490.     WBenchMsg = null;
  491.     } else {
  492.     WaitPort(&me->pr_MsgPort);
  493.     WBenchMsg = (adr) GetMsg(&me->pr_MsgPort);
  494.     }
  495.     main(1, argp);    /* pack all args into argv[1] */
  496.     exit(0);
  497. }
  498.  
  499.  
  500.  
  501. void exit(code) int code;
  502. {
  503.     char c;
  504.     if (oriout && closeori) {
  505.     spew("\n  - press return -  ");
  506.     Read(oriout, &c, 1L);
  507.     Close(oriout);
  508.     }
  509.     if (WBenchMsg) {
  510.     Forbid();
  511.     ReplyMsg((struct Message *) WBenchMsg);
  512.     }
  513.     Exit((long) code);
  514. }
  515.  
  516. #endif
  517.