home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / SnoopDos / SnoopDos_Source / snoopdos.c < prev    next >
C/C++ Source or Header  |  2000-01-12  |  13KB  |  459 lines

  1. /*
  2.  *        SNOOPDOS.C                                                vi:ts=4
  3.  *
  4.  *      Copyright (c) Eddy Carroll, September 1994.
  5.  *
  6.  *        The mainline, where we co-ordinate everything.
  7.  */
  8.  
  9. #define MAIN
  10.  
  11. #define RAWDOFMT_COPY (void (*))"\x16\xc0\x4e\x75" /* MOVE.B D0,(A3)+ | RTS */
  12.  
  13. #include "system.h"
  14. #include "snoopdos.h"
  15.  
  16. #define OldPrint(s)        Write(Output(), s, strlen(s))
  17. #define OldFPrint(f,s)    Write(f, s, strlen(s))
  18.  
  19. #if _PROFILE
  20. #include "sprof.h"
  21. #else
  22. #define PROFILE_ON()
  23. #define PROFILE_OFF()
  24. #endif
  25.  
  26. #define NAME            "SnoopDos 3.1"
  27. #define DATENAME        "January 2000"
  28. #define DATENUM            "11.1.00"
  29.  
  30. char Version[]            = "$VER: " NAME " (" DATENUM ")";
  31. char SnoopDosTitle[]    = NAME " \251 Eddy Carroll, " DATENAME ".";
  32. char SnoopDosTitleKey[] = NAME " \251 Eddy Carroll, " DATENAME ". Hotkey=<%s>";
  33. char CommodityTitle[]   = NAME " by Eddy Carroll";
  34.  
  35. long __stack = MINSTACKSIZE;            /* Ensure stack size is sufficient    */
  36.  
  37. static ULONG StartPri;                    /* Start priority of our task        */
  38.  
  39. /*
  40.  *        Cleanup(errcode)
  41.  *
  42.  *        Frees all resources allocated by the program and exits with
  43.  *        the specified error code
  44.  */
  45. void Cleanup(int errcode)
  46. {
  47.     CleanupHotKey();
  48.     CleanupWindows();
  49.     CleanupAGuide();
  50.     CleanupIcons();
  51.     CleanupLocale();
  52.     CleanupRexxPort();
  53.     CleanupPatches();
  54.     CleanupBuffers();
  55.  
  56.     if (AslBase)            CloseLibrary(AslBase);
  57.     if (RexxSysBase)        CloseLibrary(RexxSysBase);
  58.     if (DiskfontBase)        CloseLibrary(DiskfontBase);
  59.     if (GadToolsBase)        CloseLibrary(GadToolsBase);
  60.     if (IntuitionBase)        CloseLibrary(IntuitionBase);
  61.     if (LayersBase)            CloseLibrary(LayersBase);
  62.     if (GfxBase)            CloseLibrary(GfxBase);
  63.     if (IconBase)            CloseLibrary(IconBase);
  64.     if (UtilityBase)        CloseLibrary(UtilityBase);
  65.     if (KeymapBase)            CloseLibrary(KeymapBase);
  66.     if (CxBase)                CloseLibrary(CxBase);
  67.  
  68.     /*
  69.      *        Restore our requester status and task priority before we
  70.      *        exit, in case we were run from a CLI prompt
  71.      */
  72.     *TaskWindowPtr = SaveWindowPtr;
  73.     SetTaskPri(SysBase->ThisTask, StartPri);
  74.     exit(errcode);
  75. }
  76.  
  77. /*
  78.  *        OpenLibs()
  79.  *
  80.  *        Opens all the main libraries we'll need. We must have intuition,
  81.  *        graphics, and gadtools, but everything else we can manage without.
  82.  *
  83.  *        dos.library and exec.library will already be open at this point.
  84.  *
  85.  */
  86. void OpenLibs(void)
  87. {
  88.     APTR oldwinptr = *TaskWindowPtr;
  89.  
  90.     if (SysBase->LibNode.lib_Version < 37) {
  91.         if (WBenchMsg) {
  92.             /*
  93.              *        Open a text window to display error message in.
  94.              */
  95.             BPTR file = Open("CON:0/0/520/80/SnoopDos 3.1", MODE_NEWFILE);
  96.  
  97.  
  98.             if (file) {
  99.                 char ch;
  100.  
  101.                 OldFPrint(file,
  102.                           "\nSorry, " NAME " requires Workbench 2.04 or above."
  103.                           "\n\nPress RETURN to close this window. ");
  104.                 Read(file, &ch, 1);
  105.                 Close(file);
  106.             }
  107.         } else {
  108.             /*
  109.              *        Just print it in the CLI
  110.              */
  111.             OldPrint("Sorry, " NAME " requires Workbench 2.04 or above.\n");
  112.         }
  113.         Cleanup(50);
  114.     }
  115.  
  116.     IntuitionBase = (void *)OpenLibrary("intuition.library", 37);
  117.     GfxBase       = (void *)OpenLibrary("graphics.library",  37);
  118.     LayersBase      = OpenLibrary("layers.library",       37);
  119.     GadToolsBase  = OpenLibrary("gadtools.library",       37);
  120.     IconBase      = OpenLibrary("icon.library",        0);
  121.     RexxSysBase   = OpenLibrary("rexxsyslib.library",  0);
  122.     UtilityBase   = OpenLibrary("utility.library",       0);
  123.     KeymapBase      = OpenLibrary("keymap.library",       37);
  124.  
  125.     /*
  126.      *        We don't need diskfont.library to run, but just in case we're
  127.      *        run after booting with no startup-sequence, we disable AmigaDOS
  128.      *        requesters so that diskfont.library doesn't ask us to insert
  129.      *        volume ENV:
  130.      */
  131.     *TaskWindowPtr = (APTR)-1;
  132.     DiskfontBase   = OpenLibrary("diskfont.library",    0);
  133.     *TaskWindowPtr = oldwinptr;
  134.     CxBase           = OpenLibrary("commodities.library", 37);
  135.  
  136.     if (!IntuitionBase || !GfxBase || !LayersBase) {
  137.         OldPrint("Couldn't open intuition, graphics or layers libraries!\n");
  138.         Cleanup(50);
  139.     }
  140.     if (!GadToolsBase || !UtilityBase || !KeymapBase) {
  141.         OldPrint("Couldn't open gadtools, utilities or keymap library!\n");
  142.         Cleanup(50);
  143.     }
  144. }
  145.  
  146. /*
  147.  *        My own version of sprintf, using the exec routine. Saves pulling
  148.  *        in a lot of unnecessary library routines (5-10K!)
  149.  */
  150. void mysprintf(char *outstr, char *fmtstr, ...)
  151. {
  152.     RawDoFmt(fmtstr, &fmtstr+1, RAWDOFMT_COPY, outstr);
  153. }
  154.  
  155. /*
  156.  *        InstallSettings(set, which)
  157.  *
  158.  *        Installs the specified set of settings into CurSettings, and
  159.  *        adjusts any other variables that may be required to reflect
  160.  *        these new settings.
  161.  *
  162.  *        This includes updating the appropriate windows if necessary.
  163.  */
  164. void InstallSettings(Settings *set, int which)
  165. {
  166.     int resetwin    = 0;
  167.     int redrawwin   = 0;
  168.  
  169.     if (which & SET_FUNC) {
  170.         /*
  171.          *        First, go down through the new function options and
  172.          *        update the function window to match the new set of
  173.          *        options. For speed, we only update those that are
  174.          *        different.
  175.          */
  176.         if (FuncWindow) {
  177.             ShowFuncOpts(set->Func.Opts, FIRST_BOOL_GADGET, LAST_BOOL_GADGET);
  178.             ResetFuncToSelected();
  179.             if (strcmp(CurSettings.Func.Pattern, set->Func.Pattern) != 0) {
  180.                 GT_SetGadgetAttrs(Gadget[GID_MATCHNAME], FuncWindow, NULL,
  181.                                   GTST_String,    set->Func.Pattern,
  182.                                   TAG_DONE);
  183.             }
  184.         }
  185.         CurSettings.Func = set->Func;
  186.         LoadFuncSettings(&set->Func);
  187.     }
  188.     if (which & SET_SETUP) {
  189.         struct SetupSettings *curset = &CurSettings.Setup;
  190.         struct SetupSettings *newset = &set->Setup;
  191.         char oldwinfont[MAX_SHORT_LEN+2];
  192.         char oldbuffont[MAX_SHORT_LEN+2];
  193.         int  oldwinsize;
  194.         int  oldbufsize;
  195.  
  196.         if (!CxBase)
  197.             newset->HideMethod = HIDE_NONE;
  198.  
  199.         if (SetWindow) {
  200.             /*
  201.              *        Update settings window to reflect new gadget settings
  202.              *
  203.              *        While we can optimise some of our update methods, we
  204.              *        have to blindly ALWAYS update string gadgets since
  205.              *        we have no way of knowing if they have been changed
  206.              *        by the user in a way that was not yet detected by
  207.              *        SnoopDos (e.g. entering a new value and forgetting
  208.              *        to press RETURN).
  209.              */
  210.             if (curset->HideMethod != newset->HideMethod)
  211.                 GT_SetGadgetAttrs(Gadget[GID_HIDEMETHOD], SetWindow, NULL,
  212.                                   GTCY_Active,        newset->HideMethod,
  213.                                   TAG_DONE);
  214.  
  215.             if (curset->ScreenType != newset->ScreenType)
  216.                 GT_SetGadgetAttrs(Gadget[GID_OPENON], SetWindow, NULL,
  217.                                   GTCY_Active,        newset->ScreenType,
  218.                                   TAG_DONE);
  219.  
  220.             if (curset->LogMode != newset->LogMode)
  221.                 GT_SetGadgetAttrs(Gadget[GID_LOGMODE], SetWindow, NULL,
  222.                                   GTCY_Active,        newset->LogMode,
  223.                                   TAG_DONE);
  224.  
  225.             if (curset->FileIOType != newset->FileIOType)
  226.                 GT_SetGadgetAttrs(Gadget[GID_FILEIO], SetWindow, NULL,
  227.                                   GTCY_Active,        newset->FileIOType,
  228.                                   TAG_DONE);
  229.  
  230.             GT_SetGadgetAttrs(Gadget[GID_BUFFERSIZE], SetWindow, NULL,
  231.                               GTIN_Number,        newset->BufferSize,
  232.                               TAG_DONE);
  233.  
  234.             GT_SetGadgetAttrs(Gadget[GID_HOTKEY], SetWindow, NULL,
  235.                               GTST_String,        newset->HotKey,
  236.                               TAG_DONE);
  237.  
  238.             GT_SetGadgetAttrs(Gadget[GID_SCREENNAME], SetWindow, NULL,
  239.                               GTST_String,        newset->ScreenName,
  240.                               TAG_DONE);
  241.  
  242.             GT_SetGadgetAttrs(Gadget[GID_LOGFILE], SetWindow, NULL,
  243.                               GTST_String,        newset->LogFile,
  244.                               TAG_DONE);
  245.  
  246.             GT_SetGadgetAttrs(Gadget[GID_BUFFORMAT], SetWindow, NULL,
  247.                               GTST_String,    newset->BufferFormat,
  248.                               TAG_DONE);
  249.  
  250.             GT_SetGadgetAttrs(Gadget[GID_LOGFORMAT], SetWindow, NULL,
  251.                               GTST_String,    newset->LogfileFormat,
  252.                               TAG_DONE);
  253.         }
  254.         if (strcmp(curset->HotKey, newset->HotKey) != 0) {
  255.             InstallHotKey(newset->HotKey);
  256.             SetMainHideState(newset->HideMethod);
  257.         }
  258.         if (newset->HideMethod != curset->HideMethod) {
  259.             if (newset->HideMethod == HIDE_NONE)
  260.                 CleanupHotKey();
  261.             else {
  262.                 curset->HideMethod = newset->HideMethod;
  263.                 InstallHotKey(newset->HotKey);
  264.             }
  265.             SetMainHideState(newset->HideMethod);
  266.         }
  267.         if (curset->BufferSize != newset->BufferSize) {
  268.             ClearWindowBuffer();
  269.             if (!SetTotalBufferSize(newset->BufferSize * 1024,
  270.                                                             SETBUF_FORCENEW)) {
  271.                 ShowError(MSG(MSG_ERROR_NOBUFMEM), newset->BufferSize);
  272.                 Cleanup(20);
  273.             }
  274.         }
  275.         if (strcmp(curset->BufferFormat, newset->BufferFormat)) {
  276.             strcpy(curset->BufferFormat, newset->BufferFormat);
  277.             InstallNewFormat(NEW_STRING);
  278.         }
  279.  
  280.         /*
  281.          *        Since the font settings may have been reset to the default
  282.          *        fonts (i.e. size = 0) we need to change them to actual
  283.          *        font names before we check if they've changed. Thus, we
  284.          *        must save the existing names first (since InitFonts()
  285.          *        modifies the current settings directly and would trash
  286.          *        them).
  287.          */
  288.         strcpy(oldwinfont, curset->WindowFont);
  289.         strcpy(oldbuffont, curset->BufferFont);
  290.         oldwinsize = curset->WinFontSize;
  291.         oldbufsize = curset->BufFontSize;
  292.  
  293.         if (curset->LogMode != newset->LogMode)
  294.             SetLogGadget(newset->LogMode, LG_REFRESH);
  295.  
  296.         *curset = *newset;                /* Copy in new settings */
  297.  
  298.         if (curset->WinFontSize == 0 || curset->BufFontSize == 0)
  299.             InitFonts();
  300.  
  301.         if (strcmp(oldbuffont, curset->BufferFont) != 0 ||
  302.                    oldbufsize != curset->BufFontSize    ||
  303.             strcmp(oldwinfont, curset->WindowFont) != 0 ||
  304.                    oldwinsize != curset->WinFontSize)
  305.         {
  306.             /*
  307.              *        Got a font change so update font info
  308.              *        accordingly and set flag to say we need
  309.              *        to reset the main window.
  310.              */
  311.             extern struct TextAttr WindowFontAttr;
  312.             extern struct TextAttr BufferFontAttr;
  313.  
  314.             WindowFontAttr.ta_YSize = curset->WinFontSize;
  315.             BufferFontAttr.ta_YSize = curset->BufFontSize;
  316.             resetwin = 1;
  317.             if (SetWindow) {
  318.                 GT_SetGadgetAttrs(Gadget[GID_WINDOWFONT], SetWindow, NULL,
  319.                                   GTTX_Text, GetFontDesc(WindowFontDesc,
  320.                                                            WindowFontName,
  321.                                                            WindowFontSize),
  322.                                   TAG_DONE);
  323.  
  324.                 GT_SetGadgetAttrs(Gadget[GID_BUFFERFONT], SetWindow, NULL,
  325.                                   GTTX_Text, GetFontDesc(BufferFontDesc,
  326.                                                            BufferFontName,
  327.                                                             BufferFontSize),
  328.                                   TAG_DONE);
  329.             }
  330.             PurgeFuncGadgets = 1;      /* Ensure function window gets updated */
  331.             if (!FuncWindow)
  332.                 CloseFunctionWindow();    /* Free gadgets now if window closed */
  333.         }
  334.  
  335.         /*
  336.          *        Now update everything to take advantage of the new settings
  337.          */
  338.     }
  339.     if ((which & SET_MAIN) == SET_MAIN) {
  340.         int updatefunc = set->StackLimit != CurSettings.StackLimit;
  341.  
  342.         if (CurSettings.SimpleRefresh != set->SimpleRefresh)
  343.             resetwin = 1;
  344.  
  345.         if (!resetwin && set->TextSpacing != BoxInterGap)
  346.             SetTextSpacing(set->TextSpacing);
  347.         else if (set->RightAlign != RightAligned && !resetwin && MainWindow) {
  348.             RightAligned = set->RightAlign;
  349.             ShowBuffer(TopSeq, DISPLAY_ALL);
  350.         }
  351.         if (set->ShowStatus != StatusLine || set->ShowGadgets != GadgetsLine)
  352.             redrawwin = 1;
  353.  
  354.         CurSettings = *set;                    /* Copy all settings               */
  355.         InitFonts();                        /* Make sure fonts are current     */
  356.         SetMenuOptions();                    /* Update main menu if necessary */
  357.  
  358.         if (updatefunc) {
  359.             /*
  360.              *        If we changed our stack limit, re-install all the
  361.              *        function settings ... this has the side effect of
  362.              *        fixing up the stack on the way
  363.              */
  364.             LoadFuncSettings(&set->Func);
  365.         }
  366.     }
  367.     if (resetwin) {
  368.         ReOpenMainWindow();
  369.     } else if (redrawwin) {
  370.        RecalcMainWindow(MainWindow->Width, MainWindow->Height, REDRAW_GADGETS);
  371.     }
  372. }
  373.  
  374. /*
  375.  *        MainLoop()
  376.  *
  377.  *        Opens the main window, then processes all incoming events
  378.  */
  379. void MainLoop(void)
  380. {
  381.     if (QuitFlag)
  382.         return;
  383.  
  384.     if (HideOnStartup) {
  385.         HideSnoopDos();
  386.     } else {
  387.         if (!ShowSnoopDos()) {
  388.             ShowError(MSG(MSG_ERROR_INITGUI));
  389.             return;
  390.         }
  391.     }
  392.  
  393.     while (!QuitFlag) {
  394.         ULONG mask;
  395.  
  396.         PROFILE_OFF();
  397.         mask = Wait(MainWindowMask        |
  398.                     FuncWindowMask        |
  399.                     FormWindowMask        |
  400.                     SetWindowMask        |
  401.                     NewEventMask        |
  402.                     ScanDosListMask        |
  403.                     AmigaGuideMask        |
  404.                     CommodityMask        |
  405.                     RexxPortMask        |
  406.                     WorkbenchMask        |
  407.                     SIGBREAKF_CTRL_C    |
  408.                     SIGBREAKF_CTRL_D    |
  409.                     SIGBREAKF_CTRL_E    |
  410.                     SIGBREAKF_CTRL_F);
  411.         PROFILE_ON();
  412.  
  413.         if (mask & MainWindowMask)        HandleMainMsgs();
  414.         if (mask & FuncWindowMask)        HandleFuncMsgs();
  415.         if (mask & FormWindowMask)        HandleFormatMsgs();
  416.         if (mask & SetWindowMask)        HandleSettingsMsgs();
  417.         if (mask & NewEventMask)        HandleNewEvents();
  418.         if (mask & ScanDosListMask)        UpdateDeviceList(SCANDEV_DELAY);
  419.         if (mask & AmigaGuideMask)        HandleAGuideMsgs();
  420.         if (mask & CommodityMask)        HandleHotKeyMsgs();
  421.         if (mask & RexxPortMask)        HandleRexxMsgs();
  422.         if (mask & WorkbenchMask)        HandleWorkbenchMsgs();
  423.         if (mask & SIGBREAKF_CTRL_C)    QuitFlag = 1;
  424.         if (mask & SIGBREAKF_CTRL_D)    SetMonitorMode(MONITOR_DISABLED);
  425.         if (mask & SIGBREAKF_CTRL_E)    SetMonitorMode(MONITOR_NORMAL);
  426.         if (mask & SIGBREAKF_CTRL_F)    ShowSnoopDos();
  427.     }
  428.     CleanupWindows();
  429. }
  430.  
  431. int main(int argc, char **argv)
  432. {
  433.     struct Process *myproc = (struct Process *)(SysBase->ThisTask);
  434.  
  435.     TaskWindowPtr = &(myproc->pr_WindowPtr);
  436.     SaveWindowPtr = *TaskWindowPtr;
  437.     StartPri      = SysBase->ThisTask->tc_Node.ln_Pri;
  438.  
  439.     OpenLibs();
  440.  
  441.     InitSettings();
  442.     InitTextTable();
  443.     InitRexxPort();
  444.     InitBuffers();
  445.     CheckSegTracker();
  446.     /*
  447.      *        Now parse our startup options, read default configuration files
  448.      *        and so on.
  449.      */
  450.     if (!ParseStartupOpts(argc, argv))
  451.         Cleanup(0);
  452.  
  453.     RestoreSettings = CurSettings;    /* Record for later restoration */
  454.     MainLoop();
  455.     SetMonitorMode(MONITOR_DISABLED);
  456.     Cleanup(0);
  457.     return (0);
  458. }
  459.