home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff224.lzh / CLImax / climax.c < prev    next >
C/C++ Source or Header  |  1989-06-20  |  12KB  |  450 lines

  1. #ifdef This_Is_A_Big_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 option (stack checking).  There are some provisions for compiling
  6. it without Aztec, but they are UNTESTED AND PROBABLY INCOMPLETE.  Last
  7. revision date: 3/26/89.
  8.  
  9. The major question is, how do we get EndCLI to wait for filehandles on the
  10. window to close?  Is it a ConMan problem?  YES.  If I use an ordinary window,
  11. the CON handler waits; only with a strange Wnnnnnn window does the handler
  12. close the window when I Close the file handle without seeing if anyone else
  13. is still using it.  And how do I tell whether Shell-Seg is resident?  Scan
  14. the resident list for something the right size?  No, don't bother.  How do
  15. you make a failing Workbench program beep the screen and set "last error"? 
  16. With the startup message reply somehow?  I don't think so.
  17.  
  18. Improvements needed:
  19. => o Make it work without ConMan.
  20. => o Make it wait for other things with window filehandles to quit.  I guess
  21.     this comes down to getting rid of ConMan dependency.
  22.    o Make it not need to be "Run CLImax".  Create global permanent piece of
  23.     cleanup code and patch it into file handle's closefunc field?
  24.    o hot key to bring to front and activate?  Make your own, I don't need one.
  25.    o Invisible full size screen depth gadgets?  Nah.
  26.    o Command line options for colors, wbenchscreen?, overscanmargin?, startup
  27.     command?.  ToolTypes for all those plus CD.
  28.    o After I've got FastExNext down, how about FastExecute?
  29.    o There's not much I can do to reduce the memory consumption.  Aside from
  30.     the 33K of chip ram for the screen, it uses no more than a Workbench
  31.     Shell does, which is a lot (22K).  It's only about 10K for a NewCLI. 
  32.     That's with ConMan; it's probably less with vanilla CON:.  The
  33.     experimental cli-cleans-itself-up version would probably use less
  34.     memory that the waiting-process version.
  35.  
  36. #endif /* big comment */
  37.  
  38.  
  39.  
  40. #define INTUITIONPRIVATE
  41. /* So IntuitionBase->Preferences is visible.  We're examining only. */
  42. #include <exec/exec.h>
  43. #include <graphics/gfxbase.h>
  44. #include <intuition/intuition.h>
  45. #include <intuition/intuitionbase.h>
  46. #include <workbench/workbench.h>
  47. #include <workbench/startup.h>
  48. #include <libraries/dosextens.h>
  49. #ifdef AZTEC_C
  50. #include <functions.h>    /* modified so BPTR () functions are declared so */
  51. #endif
  52. #include <Paul.h>
  53.  
  54.  
  55. /* screen/window stuff based on copied leo schwab code */
  56.  
  57. #define XSIZE           640
  58. #define GREENISHNESS    {0x484, 0x000, 0x0b0, 0xcc0}
  59. #define OverscanMargin    4
  60. /* we overscan so there's a small space at the top to pull the screen down
  61.    with; lets you see part of the screen depth gadgets */
  62.  
  63. #define SCLI struct CommandLineInterface
  64.  
  65.  
  66. struct IntuitionBase    *IntuitionBase;
  67. struct GfxBase          *GfxBase;
  68. struct Screen        *scr;
  69. struct Window        *win;
  70. extern struct WBStartup    *WBenchMsg;
  71. adr            IconBase;
  72. adr            wopter;
  73. struct Process        *me;
  74. bool            lace = false, unshelled = false,
  75.                 greenify = false, baloney = false;
  76.  
  77.  
  78. UBYTE scr_tit[] = " CLImax screen ";  /* won't actually show */
  79.  
  80. struct NewScreen scrdef = {
  81.         0, 0, XSIZE, 47L,  /* YSIZE will be set later */
  82.         2,              /*  4 colors  */
  83.         0, 0,           /*  detail pen = background so no white stripe at top */
  84.         HIRES, CUSTOMSCREEN,
  85.         null, scr_tit, null, null  /* no special font, gadget, or bitmap */
  86. };
  87.  
  88.  
  89. struct NewWindow windef = {
  90.         0, OverscanMargin, XSIZE, 44L,    /* YSISE will be set later */
  91.         0, 1,
  92.         0L,
  93.         ACTIVATE | BACKDROP | BORDERLESS,
  94.         null, null, null,       /* no special gadget or checkmark, no title */
  95.         69L,                    /* screen pointer; will get set later */
  96.         null,                   /* no custom bitmap */
  97.         0, 0, 0, 0,             /* ignored */
  98.         CUSTOMSCREEN
  99. };
  100.  
  101.  
  102.  
  103. /*
  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. void spew(s) str s;
  110. {
  111.     register BPTR o = Output();
  112.     register long l = strlen(s);
  113.     if (o) Write(o, s, l);
  114. }
  115.  
  116.  
  117.  
  118. openstuff ()
  119. {    ushort *wbcolor, tallth;
  120.     static ushort lacecolor[4] = GREENISHNESS;
  121.     long collor;  /* that's how Joan spelled it once */
  122.     struct ViewPort *vp;
  123.  
  124.         IntuitionBase = (adr) OpenLibrary ("intuition.library", 1L);
  125.         GfxBase = (adr) OpenLibrary ("graphics.library", 1L);
  126.     /* Look Ma, no error check! */
  127.  
  128.     tallth = IntuitionBase->MaxDisplayHeight & ~15;
  129.     if (lace) scrdef.ViewModes = HIRES | LACE;
  130.     else tallth >>= 1;
  131.     windef.Height = tallth;
  132.     scrdef.Height = tallth + OverscanMargin;
  133.         if (!(scr = OpenScreen (&scrdef))) {
  134.                 spew ("Can't open screen.\n");
  135.         closestuff();
  136.                 exit (10);
  137.         }
  138.  
  139.     windef.Screen = scr;
  140.         if (!(win = OpenWindow (&windef))) {
  141.                 spew ("Can't open window.\n");
  142.         closestuff();
  143.                 exit (10);
  144.         }
  145.  
  146.     ShowTitle(scr, FALSE);
  147.     vp = &(scr -> ViewPort);  /* set colors according to Preferences */
  148.     if (greenify) wbcolor = lacecolor;    /* except when G option */
  149.     else wbcolor = &IntuitionBase->Preferences->color0;
  150.     /* nothing multitasking-unsafe about examining in place, right? */
  151.     for (collor = 0; collor <= 3; collor++, wbcolor++)
  152.         SetRGB4(vp, collor, (*wbcolor >> 8) & 15L,
  153.                     (*wbcolor >> 4) & 15L,
  154.                     *wbcolor & 15L);
  155. }
  156.  
  157.  
  158.  
  159. closestuff ()
  160. {
  161.     register struct Window *w;
  162.     me->pr_WindowPtr = wopter;
  163. /* ConMan 1.3 closes the window when you close the file handle.  Older ConMen
  164. don't.  We have to handle both cases, so we see if the window is still
  165. attached to the screen: */
  166.     if (scr && win)
  167.         for (w = scr->FirstWindow; w; w = w->NextWindow)
  168.             if (w == win) {
  169.                 CloseWindow(win);
  170.                 break;
  171.             }
  172.         if (scr) CloseScreen (scr);
  173.         if (GfxBase) CloseLibrary (GfxBase);
  174.         if (IntuitionBase) CloseLibrary (IntuitionBase);
  175. }
  176.  
  177.  
  178.  
  179. /* strlen that doesn't look past length 255 */
  180. int blen(m) register str m;
  181. {    register int l;
  182.     for(l = 0; l < 255; l++,m++) if (!*m) break;
  183.     return (l);
  184. }
  185.  
  186.  
  187.  
  188. BPTR bstr(s) str s;
  189. {
  190.     int l = blen(s);
  191.     long al = (l + 8) & ~3;
  192.     str b;
  193.     if (!(b = AllocPZ(al)))
  194.         return (null);
  195.     *(long *) b = al;
  196.     b[4] = l;
  197.     strncpy(b + 5, s, l);
  198.     return (((long) b + 4) >> 2);
  199. }
  200.  
  201.  
  202.  
  203. void freebeast(b) BPTR b;
  204. {
  205.     long *p = bip(long, b);
  206.     FreeMem(p - 1, p[-1]);
  207. }
  208.  
  209.  
  210.  
  211. BPTR CopyWBPath()
  212. {
  213.     struct Process *wb = (adr) FindTask("Workbench");
  214.     SCLI *wbclap;
  215.     BPTR *wext, *mext, *lastmext, newpath = null;
  216.     lastmext = &newpath;
  217.     if (!wb) return (null);
  218.     if (!(wbclap = gbip(wb->pr_CLI))) return (null);
  219.     for (wext = gbip(wbclap->cli_CommandDir); wext; wext = gbip(*wext)) {
  220.         if (!(mext = AllocP(2 * sizeof(BPTR))))
  221.             break;
  222.         *lastmext = (long) mext >> 2;
  223.         lastmext = mext;
  224.         mext[1] = DupLock(wext[1]);
  225.         mext[0] = null;
  226.     }
  227.     return (newpath);
  228. }
  229.  
  230.  
  231.  
  232. void FakeCLI()
  233. {
  234.     SCLI *clap;
  235.     if (!(clap = NewPZ(SCLI)))  /* clear|public */
  236.         return;
  237.     baloney = true;
  238.     me->pr_CLI = (long) clap >> 2;
  239.     clap->cli_SetName = bstr("SYS:");
  240.     clap->cli_Prompt = bstr("%N> ");
  241.     clap->cli_DefaultStack = 1000L;
  242.     CurrentDir(RLock("SYS:"));    /* old CD was zero */
  243.     clap->cli_CommandDir = CopyWBPath();
  244. }
  245.  
  246.  
  247.  
  248. void NukePath(path) BPTR path;
  249. {
  250.     BPTR *next, *p;
  251.     for (p = gbip(path); p; p = next) {
  252.         next = gbip(p[0]);
  253.         if (p[1]) UnLock(p[1]);
  254.         FreeMem(p, 2L * sizeof(BPTR));
  255.     }
  256. }
  257.  
  258.  
  259.  
  260. void StopFakery()
  261. {
  262.     BPTR cd = CurrentDir(null);
  263.     SCLI *clap = gbip(me->pr_CLI);
  264.     if (cd) UnLock(cd);
  265.     if (!clap) return;
  266.     freebeast(clap->cli_SetName);
  267.     freebeast(clap->cli_Prompt);
  268.     NukePath(clap->cli_CommandDir);
  269.     me->pr_CLI = null;
  270.     Free(SCLI, clap);
  271. }
  272.  
  273.  
  274.  
  275. void wandle()
  276. {
  277.     struct DiskObject *bob;
  278.     str toop;
  279.     register char c;
  280.     if (!(IconBase = OpenLibrary("icon.library", 0L))) return;
  281.     CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  282.     if (bob = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
  283.         if (toop = FindToolType(bob->do_ToolTypes, "OPTION"))
  284.             for (c = tolower(*toop); c; c = tolower(*++toop)) {
  285.                 if (c == 'v') unshelled = true;
  286.                 else if (c == 'g') greenify = true;
  287.                 else if (c == 'i') lace = true;
  288.             }
  289.         FreeDiskObject(bob);
  290.     }
  291.     CurrentDir(null);
  292.     CloseLibrary(IconBase);
  293.     IconBase = null;
  294. }
  295.  
  296.  
  297.  
  298. int word, chair, ac; str *av;
  299.  
  300. char nerg()
  301. {
  302. #ifdef AZTEC_C
  303.     if (((str) av)[chair]) return (((str) av)[chair++]);
  304.     else return (0);
  305. #else
  306.     if (av[word][chair]) return (av[word][chair++]);
  307.     else if (av[++word]) return (av[word][chair = 0]);
  308.     else return (0);
  309. #endif
  310. }
  311.  
  312.  
  313.  
  314. void handle(argc, argv) int argc; str argv[];
  315. {
  316.     char c;
  317.     bool kelp = false;
  318.     ac = argc; av = argv; word = 1; chair = 0;
  319.     lace = false;
  320.     for (c = tolower(nerg()); c; c = tolower(nerg())) {
  321.         if (c == 'v') unshelled = true;
  322.         if (c == 'i') lace = true;
  323.         if (c == 'g') greenify = true;
  324.         if (c == '?' | c == 'h') kelp = true;
  325.     }
  326.     if (kelp) {
  327.         spew(
  328. "\nCLImax by Paul Kienitz -- usage:\n\n"
  329. "    Run > nil: CLImax [V] [I] [G]\n\n"
  330. "Spaces and letter cases and order of appearence never matter.\n"); spew(
  331. "V (vanilla) means start with s:CLI-Startup instead of s:Shell-Startup.\n"
  332. "I means make an interlace screen.\n"); spew(
  333. "G means use black-on-greenish (good for interlace) instead of\n"
  334. "     the Workbench colors (maybe someday there'll be an RGB option).\n"
  335. "? or H means show this message.\n\n"); spew(
  336. "For Workbench, use a tooltype OPTION= followed by V, I, and/or G.\n\n");
  337.         closestuff();
  338.         exit(0);
  339.     }
  340. }
  341.  
  342.  
  343.  
  344. main(argc, argv) int argc; stray argv;
  345. {
  346.     char boof[50];
  347.     str command;
  348.     BPTR window_handle, L, Seg = 1;
  349.  
  350. #ifndef AZTEC_C
  351.     me = (adr) FindTask(null);
  352.     === do something to set WBenchMsg ===
  353. #endif
  354.     if (WBenchMsg) wandle();
  355.     else handle(argc, argv);
  356. /*    spew("Maximum CLI for you, from Paul Kienitz.  Public Domain.\n"); */
  357.     openstuff();
  358.     wopter = me->pr_WindowPtr;
  359.     me->pr_WindowPtr = -1L;
  360. #ifdef EXPERIMENTAL
  361.     window_handle = OOpen("nil:");
  362.     if (!unshelled && (L = RLock("C:NewShell"))) {
  363.         strcpy(boof, "c:newshell >nil: ");
  364.         UnLock(L);
  365.     } else if (L = RLock("C:NewCLI")) {
  366.         strcpy(boof, "c:newcli >nil: ");
  367.         UnLock(L);
  368.     }
  369.     speck(boof, win);
  370.     me->pr_WindowPtr = (adr) win;  /* setting gets passed to child cli */
  371. /*    if (Seg = LoadSeg("L:CLImax-Cleanup")) */
  372.         if (!Execute(boof, null, window_handle))
  373.             spew("Can't start CLI.  ConMan not present?\n");
  374.         else { win = null; scr = null; }    /* prevent closure */
  375. /*    else spew("Can't find L:CliMAX-Cleanup.\n"); */
  376. #else
  377.     if (!unshelled && (L = RLock("S:Shell-Startup"))) {
  378.         command = "Execute S:Shell-Startup";
  379.         UnLock(L);
  380.     } else if (L = RLock("S:CLI-Startup")) {
  381.         command = "Execute S:CLI-Startup";
  382.         UnLock(L);
  383.     } else command = "";
  384.     if (!me->pr_CLI) FakeCLI();
  385.     boof[0] = 0;
  386.     speck(boof, win);
  387.     window_handle = NOpen(boof);
  388.     me->pr_WindowPtr = (adr) win;  /* setting gets passed to child cli */
  389.     if (window_handle) {
  390.         Execute(command, window_handle, null);
  391.         /* wait for other things using window_handle to stop! */
  392.         Close(window_handle);
  393.     } else spew("Can't open the CON: for the window.  ConMan absent?\n");
  394.     if (baloney) StopFakery();
  395. #endif
  396.     closestuff();
  397. }
  398.  
  399.  
  400.  
  401. speck(b, a) str b; long a;
  402. {
  403.    short hid, nyb, blem;
  404.    strcat(b, "CON:Wxxxxxx");   /* uses ConMan */
  405.    blem = strlen(b) - 1;
  406.    for (hid = 0; hid <= 5; hid++) {
  407.       nyb = (a >> (4*hid)) & 15;
  408.       b[blem - hid] = (nyb >= 10 ? (char) nyb + 'A' - 10 : (char) nyb + '0');
  409.    }
  410. }
  411.  
  412.  
  413.  
  414. /* reduce size by a few K: */
  415.  
  416. #ifdef AZTEC_C
  417.  
  418. char arg[256];
  419.  
  420. void _cli_parse(alen, aptr) long alen; str aptr;
  421. {    strncpy(arg, aptr, (int) alen); arg[alen - 1] = 0; }
  422.  
  423.  
  424. _main(alen, aptr) long alen; str aptr;  /* simplified startup code */
  425. {
  426.     me = (struct Process *) FindTask(null);
  427.     if (me->pr_CLI) {
  428.         _cli_parse(alen, aptr);
  429.         WBenchMsg = null;
  430.     } else {
  431.         WaitPort(&me->pr_MsgPort);
  432.         WBenchMsg = (adr) GetMsg(&me->pr_MsgPort);
  433.     }
  434.     main(1, arg);
  435.     exit(0);
  436. }
  437.  
  438.  
  439.  
  440. exit(code) int code;
  441. {
  442.     if (WBenchMsg) {
  443.         Forbid();
  444.         ReplyMsg(WBenchMsg);
  445.     }
  446.     Exit((long) code);
  447. }
  448.  
  449. #endif
  450.