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 >
C/C++ Source or Header  |  1988-10-02  |  15KB  |  476 lines

  1. /*****************************************************************
  2.  *                                                               *
  3.  *    XICON V2.01                                                *
  4.  *                                                               *
  5.  *   Runs Command Script Files from an Icon                      *
  6.  *                                                               *
  7.  *   copyright 1986, 1987, 1988 by Pete Goodeve                  *
  8.  *      -- All Rights Reserved                                   *
  9.  *                                                               *
  10.  *    Compile with pass2 -v option (Lattice)                     *
  11.  *    Link with c.o, amiga.lib, lc.lib                           *
  12.  *                                                               *
  13.  * vers 88:2:14                                                  *
  14.  *****************************************************************/
  15.  
  16. #include "exec/types.h"
  17. #include "exec/exec.h"
  18. #include "workbench/startup.h"
  19. #include "workbench/workbench.h"
  20. #include "workbench/icon.h"
  21. #include "libraries/dosextens.h"
  22.  
  23. LONG IntuitionBase;
  24. short V1_2 = FALSE;
  25. LONG IconBase;
  26.  
  27.  
  28. extern struct Window  *findwindow();
  29.  
  30. extern struct WBStartup *WBenchMsg;
  31.  
  32. struct WBArg *argptr;
  33. short nargs;
  34. short autoclose=TRUE, /* will be FALSEified by non-use of 'closewindow' */
  35.     usescript=TRUE, usewindow = TRUE, istext = FALSE;
  36. short abortmark = FALSE;
  37.  
  38. #define MAXDESCR 120
  39. char ConDescr[MAXDESCR+4] = "CON:0/10/640/185/XICON 2.01";
  40.                          /* available for later fiddling */
  41. #define MAXTITLE 100
  42. char Title[MAXTITLE];
  43.  
  44. LONG outfile = NULL;
  45. extern struct Window *conWindow;
  46. extern struct ConUnit *conUnit;
  47. LONG windowsig;
  48.  
  49. /** Close Gadget structure */
  50.  
  51. LONG Close_Data[] = { /* move to chip ram before use */
  52.  0x3FFFFC80,
  53.  0x30000C80,
  54.  0x33FFCC80,
  55.  0x33FFCC80,
  56.  0x33C3CC80,
  57.  0x33C3CC80,
  58.  0x33FFCC80,
  59.  0x33FFCC80,
  60.  0x30000C80,
  61.  0x3FFFFC80,
  62.  
  63.  0x00000000,
  64.  0x00000000,
  65.  0x00000000,
  66.  0x00000000,
  67.  0x003C0000,
  68.  0x003C0000,
  69.  0x00000000,
  70.  0x00000000,
  71.  0x00000000,
  72.  0x00000000
  73. };
  74.  
  75.  
  76. struct Image Close_Image = {
  77.  0, 0, /* Left, Top  */
  78.  0x0019, 0x000A, 2, /* Width, Height, Depth */
  79.  NULL, /* filled in to point to image in chip ram */
  80.  3, 0,
  81.  NULL
  82. };
  83.  
  84. struct Gadget Close_Gadg = {
  85.    NULL,    /* pointer to Next Gadget */
  86.    4, 0, 0x019, 0x0A,  /* (Left Top Width Height) Hit Box */
  87.    GADGHCOMP | GADGIMAGE,   /* Flags */
  88.    /* Activation flags */
  89.    RELVERIFY,
  90.    SYSGADGET | CLOSE,       /* Type (!) */
  91.    (APTR)&Close_Image,    /* pointer to GadgetRender */
  92.    NULL,             /* no pointer to SelectRender */
  93.    NULL,             /* no pointer to GadgetText */
  94.    0,                /* no MutualExclude */
  95.    NULL,             /* no pointer to SpecialInfo */
  96.    0,                /* no ID */
  97.    NULL              /* no pointer to special data */
  98. };
  99.  
  100. /* Continue Gadget structure */
  101.  
  102. struct IntuiText Cont_Text = {
  103.    3,0,         /* front, back pens */
  104.    JAM2,        /* draw mode */
  105.    10,1,        /* left, top edge */
  106.    NULL,        /* default font */
  107.    NULL,        /* text string -- filled in before use */
  108.    NULL         /* no next */
  109. };
  110.  
  111. struct Gadget Cont_Gadg = {
  112.    NULL,    /* pointer to Next Gadget */
  113.    0, -9, 0, 9,  /* (Left Top Full-Width Height) Hit Box */
  114.    GADGHCOMP | GRELWIDTH | GRELBOTTOM ,   /* Flags */
  115.    /* Activation flags */
  116.    RELVERIFY,
  117.    BOOLGADGET,       /* Type */
  118.    NULL,            /* no pointer to GadgetRender */
  119.    NULL,             /* no pointer to SelectRender */
  120.    &Cont_Text,       /*  pointer to GadgetText */
  121.    0,                /* no MutualExclude */
  122.    NULL,             /* no pointer to SpecialInfo */
  123.    0,                /* no ID */
  124.    NULL              /* no pointer to special data */
  125. };
  126.  
  127. _main() /* bypasses standard C startup code */
  128. {
  129.  
  130.    if (!WBenchMsg)
  131.       return 0;
  132.  
  133.    if (IntuitionBase = OpenLibrary("intuition.library",33)) V1_2 = TRUE;
  134.     else IntuitionBase = OpenLibrary("intuition.library",0);
  135.    IconBase = OpenLibrary(ICONNAME,1); /* doesn't matter much if not there */
  136.  
  137.  
  138.    argptr = WBenchMsg->sm_ArgList;
  139.    nargs = WBenchMsg->sm_NumArgs;
  140.    /* Skip the first arg (the program itself) and process the rest */
  141.    for(argptr++, nargs--; nargs; argptr++, nargs--)
  142.       if (!doito(argptr)) goto clean_exit; /* sometimes a goto is good */
  143.  
  144.    SetSignal(0, SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
  145.    if (usewindow && !autoclose) {
  146.       Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D | windowsig);
  147.    }
  148.  
  149. clean_exit:
  150.    dump_window();
  151.  
  152.    if (outfile) Close(outfile);
  153.    if (IconBase) CloseLibrary(IconBase);
  154.    CloseLibrary(IntuitionBase); /* this is in "ROM" (so no check needed) */
  155. }
  156. /*** end main ***/
  157.  
  158. /************************************************************
  159.  * In the code below, I don't follow the usual method of    *
  160.  * passing each command string in turn to Execute.  Instead *
  161.  * I pass the entire command file as the new input stream,  *
  162.  * which Execute accepts after processing the null string   *
  163.  * it gets as a "command".  This avoids the system having   *
  164.  * to reload the DOS "RUN" module for every line of the     *
  165.  * command file, though on the other hand it does lock out  *
  166.  * the possibility of redirecting keyboard input through    *
  167.  * the "current window" to the command.  I thought the      *
  168.  * trade-off was worth it.                                  *
  169.  ************************************************************/
  170.  
  171. doito(argp) struct WBArg *argp;
  172. {
  173.    LONG oldir;
  174.  
  175.    oldir = CurrentDir(argp->wa_Lock);
  176.    if (!readtt(argp) || abortmark) return FALSE;
  177.    if (istext) dispfile(argp->wa_Name);
  178.    else if (usescript)
  179.       if (!execfile(argp->wa_Name)) return FALSE;
  180.             /* I don't see how that could happen, but...*/
  181.    CurrentDir(oldir);
  182.    return TRUE;
  183. }
  184.  
  185.  
  186. execfile(fname) char *fname;
  187. {
  188.    LONG infile;
  189.    infile = Open(fname, MODE_OLDFILE);
  190.    if (!infile) return FALSE;
  191.    Execute("", infile, outfile);
  192.    Close(infile);
  193.    return TRUE;
  194. }
  195.  
  196.  
  197. /* Read ToolTypes of current icon */
  198.  
  199. readtt(argp) struct WBArg *argp;
  200. {
  201.    struct DiskObject *iconobj=NULL, *GetDiskObject();
  202.    char **toolarray, *FindToolType();
  203.    char *modes, *windowstring, *titlestring, *locdir;
  204.    LONG dirfile;
  205.  
  206.    if (!IconBase) {
  207.       if (!get_window(ConDescr)) return FALSE;
  208.       display("Icon Library not found -- ignoring ToolTypes\n");
  209.       return TRUE; /* just soldier on...*/
  210.    }
  211.    /* we don't do any checks here for icon type -- probably should...*/
  212.    if (!(iconobj = GetDiskObject(argp->wa_Name))) {
  213.       display("COULDN'T GET INFO FOR ICON!!\n");
  214.       return TRUE;
  215.    }
  216.    toolarray = iconobj->do_ToolTypes;
  217.    modes = FindToolType(toolarray,"MODE");
  218.    autoclose &= MatchToolValue(modes,"closewindow");
  219.                  /* ALL must agree to close the window automatically */
  220.    usescript = !MatchToolValue(modes,"noscript");
  221.    istext = MatchToolValue(modes,"text");
  222.  
  223.    if (windowstring = FindToolType(toolarray,"WINDOW"))
  224.         strncpy(&ConDescr[4], windowstring, MAXDESCR); /* append to 'CON:' */
  225.         /* the above is probably a Lattice special...*/
  226.    if (!outfile) {
  227.     usewindow = !MatchToolValue(modes,"nowindow");
  228.     if (usewindow)
  229.       get_window(ConDescr);
  230.     else
  231.       outfile = Open("NIL:", MODE_OLDFILE);
  232.    }
  233.    if (!outfile) return FALSE;
  234.  
  235.    if (conWindow && (titlestring = FindToolType(toolarray,"TITLE"))) {
  236.         strncpy(Title, titlestring, MAXTITLE);
  237.         /* Note that SetWindowTitles does NOT copy the string! */
  238.         SetWindowTitles(conWindow, Title, -1);
  239.    }
  240.    if ((locdir = FindToolType(toolarray,"LOCDIR")) &&
  241.        (dirfile = Open(locdir,MODE_NEWFILE)))
  242.    {
  243.         Write(dirfile,"\"",1);
  244.         traverse(argp->wa_Lock, dirfile);
  245.         Write(dirfile,"\"\n",2);
  246.         Close(dirfile);
  247.    }
  248.    dotoolcmds(toolarray); /* some tooltypes may be commands */
  249.    FreeDiskObject(iconobj);
  250.    return TRUE;
  251. }
  252.  
  253.  
  254. /* Execute any commands specified in the ToolTypes */
  255.  
  256. dotoolcmds(toolarray) char **toolarray;
  257. {
  258.    char *holdnext, *toolstr, *FindToolType();
  259.    LONG lock;
  260.    while (*toolarray) {
  261.       holdnext = toolarray[1];
  262.       toolarray[1] = NULL;
  263.       if (!abortmark) {
  264.         if (toolstr=FindToolType(toolarray,"REM")) {
  265.            display(toolstr);
  266.            display("\n");
  267.         }
  268.         else if (toolstr=FindToolType(toolarray,"TEXT"))
  269.            dispfile(toolstr);
  270.         else if (toolstr=FindToolType(toolarray,"CMD"))
  271.            Execute(toolstr,0,outfile);
  272.         else if (toolstr=FindToolType(toolarray,"SCRIPT"))
  273.            execfile(toolstr);
  274.         else if (!strcmp(*toolarray,"PAUSE")) /*FindT-T- needs "=" */
  275.            abortmark = pausekey();
  276.         else if (toolstr=FindToolType(toolarray,"EXISTS")) {
  277.            if (lock = Lock(toolstr,ACCESS_READ)) UnLock(lock);
  278.            else abortmark = TRUE;
  279.         }
  280.       } /* end !abortmark */
  281.       else /* abort has been signalled */ {
  282.         if (toolstr=FindToolType(toolarray,"ABORT-REM")) {
  283.            display(toolstr);
  284.            display("\n");
  285.         }
  286.         else if (toolstr=FindToolType(toolarray,"ABORT-TEXT"))
  287.            dispfile(toolstr);
  288.         else if (toolstr=FindToolType(toolarray,"ABORT-CMD"))
  289.            Execute(toolstr,0,outfile);
  290.         else if (toolstr=FindToolType(toolarray,"ABORT-SCRIPT"))
  291.            execfile(toolstr);
  292.         else if (!strcmp(*toolarray,"ABORT-PAUSE"))
  293.            abortmark = pausekey();
  294.         else if (!strcmp(*toolarray,"RESTORE"))
  295.            abortmark = FALSE;
  296.       }
  297.       *++toolarray = holdnext; /* restore next item & move to it */
  298.    }
  299. }
  300.  
  301.  
  302. traverse(lock, dirfile) ULONG lock, dirfile;
  303. {
  304.    short level;
  305.    ULONG pdlock;
  306.    struct DeviceList *volp;
  307.    struct FileLock *lockp;
  308.    char *namep;
  309.    struct FileInfoBlock *fib;
  310.    if (lock) {
  311.       fib = AllocMem(sizeof(struct FileInfoBlock),MEMF_PUBLIC | MEMF_CLEAR);
  312.       if (!fib) return 2; /* ...being lazy */
  313.       level = traverse(pdlock=ParentDir(lock), dirfile);
  314.       UnLock(pdlock);
  315.       if (level > 1) /* there is a superior non-root directory */
  316.            Write(dirfile, "/", 1);
  317.       if (level == 0) /* this was the root directory */ {
  318.                 /* all this to overcome RAM: handler bug...*/
  319.                 lockp = (struct FileLock *)BADDR(lock);
  320.                 volp = (struct DeviceList *)BADDR(lockp->fl_Volume);
  321.                 namep = (char *)BADDR(volp->dl_Name);
  322.                 Write(dirfile, namep+1, *namep);
  323.                 Write(dirfile, ":", 1);
  324.       }
  325.       else {
  326.               if (Examine(lock,fib))
  327.                 Write(dirfile,fib->fib_FileName,strlen(fib->fib_FileName));
  328.       }
  329.       FreeMem(fib,sizeof(struct FileInfoBlock));
  330.       return level+1;
  331.    }
  332.    else return 0;
  333. }
  334.  
  335. get_window(windescr) char *windescr;
  336. {
  337.    if (outfile) /* already open */ return TRUE;
  338.  
  339.    outfile = Open(windescr, MODE_OLDFILE);
  340.  
  341.    if (!outfile) return FALSE;
  342.  
  343.    if (!findWindow(outfile)) return FALSE;
  344.  
  345.    if (!(Close_Image.ImageData = AllocMem(sizeof(Close_Data), MEMF_CHIP)))
  346.         return TRUE; /* just ignore close gadget */
  347.    /* the following may be a Lattice special..?*/
  348.    movmem(Close_Data, Close_Image.ImageData, sizeof(Close_Data));
  349.    ModifyIDCMP(conWindow, CLOSEWINDOW); /* Heh..again*/
  350.    windowsig = 1<<(conWindow->UserPort->mp_SigBit);
  351.    conWindow->Flags |= WINDOWCLOSE; /* Heh heh! */
  352.    AddGadget(conWindow, &Close_Gadg, 0); /* Must be on TOP of drag gadget */
  353.    if (V1_2)
  354.         RefreshWindowFrame(conWindow);
  355.    else {
  356.         SetWindowTitles(conWindow, conWindow->Title, -1);
  357.         RefreshGadgets(&Close_Gadg, conWindow, NULL);
  358.    }
  359.    return TRUE;
  360. } /* get_window */
  361.  
  362. dump_window()
  363. {
  364.    if (!Close_Image.ImageData) return;
  365.    ModifyIDCMP(conWindow, 0);
  366.    RemoveGadget(conWindow, &Close_Gadg);
  367.    FreeMem(Close_Image.ImageData, sizeof(Close_Data));
  368.    /* file & window are closed at a higher level */
  369. }
  370.  
  371.  
  372. display(msg) char *msg;
  373. {
  374.    Write(outfile, msg, strlen(msg));
  375. }
  376. /**************************************/
  377.  
  378.  
  379. #define BUFSIZE 200
  380.  
  381. LONG textfile;
  382. static short curmax = 0;
  383.  
  384. dispfile(fname) char *fname;
  385. {
  386.    char inbuf[BUFSIZE], outbuf[BUFSIZE], ansbuf[2];
  387.    short inpos = 0, lcount = 20;
  388.    curmax = 0;
  389.    textfile = Open(fname, MODE_OLDFILE);
  390.    if (!textfile || !conWindow) return FALSE;
  391.    ModifyIDCMP(conWindow, conWindow->IDCMPFlags | RAWKEY);
  392.    while (copyline(inbuf, &inpos, outbuf)) {
  393.       if (!lcount-- || *outbuf == '\014' /*Formfeed*/) {
  394.       if (pausekey()) goto cutit; /* just continues unless CLOSE */
  395.          display(outbuf);
  396.          lcount = 15; /* leave some overlap with previous page */
  397.       }
  398.       else display(outbuf);
  399.    }
  400.   cutit:
  401.    Close(textfile);
  402.    ModifyIDCMP(conWindow, conWindow->IDCMPFlags & ~RAWKEY);
  403. }
  404.  
  405. copyline(in, pos, out) char *in, *out; short *pos;
  406. {
  407.    char ch, copych();
  408.    short trunc=BUFSIZE-1;
  409.    while ((*out++ = ch = copych(in, pos)) && ch != '\n' && --trunc)
  410.        /*loop*/;
  411.    *out = '\0';
  412.    return (int) ch /* FALSE if EOF */;
  413. }
  414.  
  415.  
  416. char copych(in, pos) char *in; short *pos;
  417. {
  418.    if (*pos >= curmax) {
  419.       curmax = Read(textfile,in,BUFSIZE);
  420.       *pos = 0;
  421.       if (!curmax) return '\0';
  422.    }
  423.    return in[(*pos)++];
  424. }
  425.  
  426. pausekey()
  427. {
  428.     int code;
  429.     Cont_Text.IText = "to CONTINUE -- Click here or Type any key";
  430.     AddGadget(conWindow, &Cont_Gadg, -1);
  431.     RefreshGadgets(&Cont_Gadg, conWindow, NULL);
  432.     code = pause(RAWKEY | GADGETUP);
  433.     Cont_Text.IText = "                                          ";
  434.            /* seems crude, but it's all I can figger.. */
  435.     RefreshGadgets(&Cont_Gadg, conWindow, NULL);
  436.     RemoveGadget(conWindow, &Cont_Gadg);
  437.     return code;
  438. }
  439.  
  440. #define CODE_C 0x033
  441.  
  442. pause(evmask) ULONG evmask; /* waits for a relevant event from the window */
  443.                   /* if it is a CLOSEWINDOW or cntrl-C it returns TRUE,
  444.                      otherwise FALSE */
  445. {
  446.    struct IntuiMessage *eventmsg, *GetMsg();
  447.    ULONG oldIDCMP, class, mark = FALSE;
  448.    USHORT code, qual;
  449.    if (!conWindow) return FALSE; /* only wait if there's a window */
  450.    oldIDCMP = conWindow->IDCMPFlags;
  451.    if (evmask) ModifyIDCMP(conWindow, conWindow->IDCMPFlags | evmask);
  452.    do {
  453.      Wait(windowsig);
  454.      while(eventmsg = GetMsg(conWindow->UserPort)) {
  455.        class = eventmsg->Class;
  456.        code = eventmsg->Code;
  457.        qual = eventmsg->Qualifier;
  458.        ReplyMsg(eventmsg);
  459.        if((class == CLOSEWINDOW) ||
  460.           (class == RAWKEY && (qual & IEQUALIFIER_CONTROL) && code == CODE_C ))
  461.        {
  462.           mark = TRUE;
  463.           break;
  464.        }
  465.  
  466.      }
  467.    } while ((class == RAWKEY) && (code & IECODE_UP_PREFIX));
  468.                /* ignore left-over key-ups */
  469.   if (evmask) ModifyIDCMP(conWindow, oldIDCMP);
  470.    return mark;
  471. }
  472.  
  473. /**************************************/
  474.  
  475.  
  476.