home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / findfile.lha / FindFile / FindFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-05  |  38.4 KB  |  1,327 lines

  1. /************************************************************************************
  2.                                     FindFile
  3.  
  4.                         An AmigaDOS Release 2 Commodity
  5.  
  6.                         Code By :        Russell R. Steffen
  7.  
  8.                         Home Address :   11551 Sherman Rd.
  9.                                          Cedarburg WI, 53012
  10.                                          USA
  11.                                          ( Stable )
  12.  
  13.                         Email Address  : STEFFENR@UWSTOUT.EDU
  14.                                          ( Valid ubtil May 1993 )
  15.  
  16.                         School Address : 318 Callahan Hall
  17.                                          Menomonie, WI 54751
  18.                                          USA
  19.                                          ( Valid until May 1993 )
  20.  
  21.  
  22.       Purpose -- To Emulate the FindFile Desk Accessory of the Macintosh.
  23.  
  24.       Legal   -- This code is copyrighted by the author. However permission is
  25.                  granted for private use. Commercial use is prohibited without
  26.                  written consent of the author. This program is distrbuted
  27.                  WITHOUT ANY WARRANTY or IMPLIED WARRANTY of MERCHANTABILTY
  28.                  or FITNESS FOR A PARTICULAR PURPOSE.
  29.  
  30.  
  31.       CopyRight ⌐ 1992 -- Russell R. Steffen. All rights reserved.
  32.  
  33.       History
  34.       -----------------------------------------------------------------------------
  35.       29 JUN 1992 | File Creation, Inital Version
  36.       -----------------------------------------------------------------------------
  37.       26 JUL 1992 | Competetion of Inital Version 1.00
  38.                   | Implemented ToolTypes : CX_POPKEY, CX_PRIORITY, CX_POPUP,
  39.                   |                         DEF_PATTERN, CENTERWINDOW, IGNOREICONS
  40.       -----------------------------------------------------------------------------
  41.       30 JUL 1992 | Optimizations and cleanups. Added SORTLIST Tooltype
  42.                   | Version 1.00a
  43.       -----------------------------------------------------------------------------
  44.       31 JUL 1992 | Added key command for found-list gadget. Version 1.00b
  45.                   | Fixed bug in ScanDir(), wasn't honoring a user quit request
  46.                   | properly.
  47.       -----------------------------------------------------------------------------
  48.       04 NOV 1992 | Fixed another bug in ScanDir() with a near total rewrite.
  49.                   | Now works properly when launched from Workbench.
  50.                   | Fixed Window opening routine to use WA_InnerWidth and
  51.                   | and WA_InnerHeight. Window was a bit to small when the
  52.                   | prefs screen font was larger than 8 point.
  53.                   | Fixed problem with 'D' key, wasn't wraping around on
  54.                   | the device list.
  55.                   | Version 1.00c
  56.       -----------------------------------------------------------------------------
  57.  
  58. **********************************************************************************/
  59.  
  60. #include "FindFile.h"
  61.  
  62. /***************************** Global Constants **********************************/
  63.  
  64. #define _VERSION    "1.00c"
  65. #define DATE        "(04.10.92)"
  66. #define NAME        "FindFile"
  67. #define MAXSTR      256
  68. #define MAXPAT      ( MAXSTR * 2 ) + 4
  69. #define OPEN_WINDOW 1
  70. #define FF_WIDTH    310
  71. #define FF_HEIGHT   165
  72.  
  73. /*#define DEBUG*/
  74. #ifdef DEBUG
  75. #define DB( x )      printf("%s():",__FUNC__ );puts( x );
  76. #define DBf( x , y ) printf("%s():",__FUNC__ );printf( x , y );
  77. #else
  78. #define DB( x )
  79. #define DBf( x , y )
  80. #endif
  81.  
  82. /** Gadget ID's **/
  83.  
  84. enum { ID_PATGAD,ID_DEVGAD,ID_FOUNDLIST,ID_PATHLIST,ID_SEARCH,ID_HIDE,ID_QUIT };
  85.  
  86. /***************************** Structure Defs ************************************/
  87.  
  88. struct foundNode {
  89.   struct Node    fn_Node;
  90.   struct MinList fn_PathList;
  91.   UBYTE          fn_Name[MAXSTR];
  92. };
  93.  
  94. struct pathNode {
  95.   struct Node pn_Node;
  96.   UBYTE       pn_Name[MAXSTR];
  97. };
  98.  
  99. struct controlPanel {
  100.   struct Window *ffWindow;
  101.   SHORT   lastX,
  102.           lastY;
  103.   BOOL    centerWindow;
  104.   BOOL    ignoreIcons;
  105.   BOOL    sortList;
  106.   UBYTE   ignoreIconsPat[MAXPAT];
  107.   struct VisualInfo *ffWinVi;
  108.   struct Gadget *ffWinGadList;
  109.   struct {
  110.             struct Gadget *searchPatGad,
  111.                           *searchDevGad,
  112.                           *foundListGad,
  113.                           *pathListGad,
  114.                           *searchButton,
  115.                           *hideButton,
  116.                           *quitButton;
  117.   } ffWinGads;
  118.   UBYTE searchString[MAXSTR];
  119.   UBYTE searchPattern[MAXPAT];
  120.   UWORD searchDev;
  121.   WORD  numDevs;
  122.   STRPTR *devList;
  123.   struct MinList foundList;
  124.   UWORD  numFound;
  125.   UWORD  currFound;
  126.   struct {
  127.             struct MsgPort *cxPort;
  128.             CxObj          *ffBroker;
  129.             UBYTE           cxHotKeyString[MAXSTR];
  130.             LONG            cxPriority;
  131.   } cxInterface;
  132. };
  133.  
  134. /***************************** Function Prototypes *******************************/
  135.  
  136. void Init( struct controlPanel * );
  137. void SetUp( struct controlPanel * , int , char ** );
  138. void Shutdown( struct controlPanel * , int );
  139.  
  140. ULONG GetWaitMask( struct controlPanel * );
  141.  
  142. void OpenFFWindow( struct controlPanel * );
  143. void CloseFFWindow( struct controlPanel * );
  144. void HandleFFWindowCommand( struct controlPanel * );
  145.  
  146. void CreateFFGadgets( struct controlPanel *, STRPTR *, int , BYTE);
  147. void CenterWindow( struct Screen *, WORD *, WORD * );
  148. struct foundNode *NodeAddress( struct MinList * , UWORD );
  149. BOOL QuitCheck( struct controlPanel * );
  150.  
  151. void    Bstrcpy( UBYTE * , BSTR );
  152. STRPTR *GetDevList( struct controlPanel * );
  153. void    FreeDevList( STRPTR * );
  154. BOOL    ScanDir( STRPTR , struct controlPanel * , struct MinList * );
  155. BOOL    MatchFile( struct controlPanel *, STRPTR );
  156.  
  157. void AddPathNode( struct MinList * , UBYTE * );
  158. void DeletePathNode( struct MinList * );
  159. struct foundNode *AddFoundNode( struct MinList *, UBYTE * , BOOL );
  160. void DeleteFoundList( struct MinList * );
  161. void AddFoundFile( struct controlPanel *, STRPTR, struct MinList * );
  162.  
  163. void OpenCxInterface( struct controlPanel * );
  164. void CloseCxInterface( struct controlPanel * );
  165. void HandleCxCommand( struct controlPanel * );
  166.  
  167. void CMD_Show( struct controlPanel * );
  168. void CMD_Hide( struct controlPanel * );
  169. void CMD_Search( struct controlPanel * );
  170. void CMD_Quit( struct controlPanel * );
  171.  
  172. /***************************** Global Vars ***************************************/
  173.  
  174. struct Library *IntuitionBase;
  175. struct Library *GadToolsBase;
  176. struct Library *CxBase;
  177. struct Library *IconBase;
  178.  
  179. extern int Enable_Abort; /* needed to disable Aztec C's ^C checking */
  180.  
  181. static const UBYTE *verTag = "\0$VER: " NAME " " _VERSION " " DATE;
  182.  
  183. /** This TextAttr should be gone in a future release. I want to
  184.     write the window code to be Prefs font sensitive, eventually :)  **/
  185.  
  186. struct TextAttr DefaultFont = {
  187.   (UBYTE *)"topaz.font",
  188.   8,
  189.   FS_NORMAL,
  190.   FPF_ROMFONT
  191. };
  192.  
  193. /**************************** Code Starts Here ***********************************/
  194.  
  195. struct Process;
  196. struct WBStartup;
  197.  
  198. /*
  199. void
  200. _wb_parse( struct Process *pp, struct WBStartup *wbm )
  201. {
  202. }
  203. */
  204.  
  205. void
  206. main(int argc, char **argv)
  207. {
  208.   struct controlPanel *cp;
  209.  
  210.   Enable_Abort = 0; /* turn off auto CTRL-C handling */
  211.  
  212.   cp = AllocVec( sizeof( struct controlPanel ) , MEMF_PUBLIC | MEMF_CLEAR );
  213.  
  214.   Init( cp );
  215.  
  216.   SetUp( cp , argc , argv );
  217.  
  218.   FOREVER
  219.   {
  220.     ULONG mask;
  221.  
  222.     mask = GetWaitMask( cp );
  223.  
  224.     mask = Wait( mask );
  225.  
  226.     if( mask & SIGBREAKF_CTRL_C )
  227.       CMD_Quit( cp );
  228.  
  229.     if( cp->ffWindow )
  230.       if( mask & 1 << cp->ffWindow->UserPort->mp_SigBit )
  231.         HandleFFWindowCommand( cp );
  232.  
  233.     if( cp->cxInterface.cxPort )
  234.       if( mask & 1 << cp->cxInterface.cxPort->mp_SigBit )
  235.         HandleCxCommand( cp );
  236.   }
  237.  
  238. }
  239.  
  240. void
  241. SetUp( struct controlPanel *cp, int argc, char **argv )
  242. {
  243.   UBYTE    **toolTypes;
  244.   STRPTR     strTemp;
  245.   BOOL       openWindow=FALSE;
  246.  
  247.  
  248.  
  249.   /**** Parse WB & CLI Options ***************/
  250.  
  251.   toolTypes = ArgArrayInit( argc, argv );
  252.  
  253.   cp->cxInterface.cxPriority = ArgInt( toolTypes, "CX_PRIORITY", 0 );
  254.  
  255.   strTemp = ArgString( toolTypes, "CX_POPKEY", "LCommand help" );
  256.   strncpy( cp->cxInterface.cxHotKeyString , strTemp, MAXSTR );
  257.  
  258.   strTemp = ArgString( toolTypes, "CX_POPUP", "NO" );
  259.   if( ! strnicmp( strTemp, "YES" , MAXSTR ) )
  260.     openWindow = TRUE;
  261.  
  262.   strTemp = ArgString( toolTypes, "DEF_PATTERN", "#?" );
  263.   strncpy( cp->searchString , strTemp , MAXSTR );
  264.  
  265.   strTemp = ArgString( toolTypes, "CENTERWINDOW", "YES" );
  266.   if( ! strnicmp( strTemp, "YES", MAXSTR ) )
  267.     cp->centerWindow = TRUE;
  268.  
  269.   strTemp = ArgString( toolTypes, "IGNOREICONS" , "NO" );
  270.   if( ! strnicmp( strTemp, "YES", MAXSTR ) )
  271.   {
  272.     cp->ignoreIcons = TRUE;
  273.     ParsePatternNoCase( "#?.info" , cp->ignoreIconsPat, MAXPAT );
  274.   }
  275.   else
  276.     ParsePatternNoCase( "#?" , cp->ignoreIconsPat, MAXPAT );
  277.  
  278.   strTemp = ArgString( toolTypes, "SORTLIST", "YES" );
  279.   if( ! stricmp( strTemp, "YES" , MAXSTR ) )
  280.     cp->sortList = TRUE;
  281.  
  282.   ArgArrayDone();
  283.  
  284.   OpenCxInterface( cp );
  285.  
  286.   cp->lastX = cp->lastY = -1L;
  287.  
  288.   NewList( (struct List *)&(cp->foundList) );
  289.  
  290.   if( openWindow )
  291.     OpenFFWindow( cp );
  292.  
  293. }
  294.  
  295. void
  296. Init( struct controlPanel *cp )
  297. {
  298.  
  299.   if( ! ( IntuitionBase = OpenLibrary( "intuition.library", 37L ) ) )
  300.       Shutdown( cp , 20 );
  301.  
  302.   if( ! ( GadToolsBase = OpenLibrary( "gadtools.library", 37L ) ) )
  303.       Shutdown( cp , 20 );
  304.  
  305.   if( ! ( CxBase = OpenLibrary( "commodities.library" , 37L ) ) )
  306.       Shutdown( cp , 20 );
  307.  
  308.   if( ! ( IconBase = OpenLibrary( "icon.library", 37L ) ) )
  309.       Shutdown( cp , 20 );
  310.  
  311. }
  312.  
  313. ULONG
  314. GetWaitMask( struct controlPanel *cp )
  315. {
  316.   ULONG mask;
  317.  
  318.   mask = SIGBREAKF_CTRL_C;
  319.  
  320.   if( cp->ffWindow )
  321.     mask |= 1 << cp->ffWindow->UserPort->mp_SigBit;
  322.  
  323.   if( cp->cxInterface.cxPort )
  324.     mask |= 1 << cp->cxInterface.cxPort->mp_SigBit;
  325.  
  326.   return( mask );
  327. }
  328.  
  329. /******************************** FindFile Window Management **********************/
  330.  
  331. void
  332. OpenFFWindow( struct controlPanel *cp )
  333. {
  334.   struct Screen   *defScreen;
  335.   WORD             left,
  336.                    top;
  337.  
  338.  
  339.  
  340.   if( cp->ffWindow )
  341.   {
  342.     WindowToFront( cp->ffWindow );
  343.     ActivateWindow( cp->ffWindow );
  344.     return;
  345.   }
  346.  
  347.   if( !( defScreen = (struct Screen *)LockPubScreen( NULL )))
  348.     Shutdown( cp, 20 );
  349.  
  350.   if( !(cp->ffWinVi = GetVisualInfo( defScreen, TAG_DONE )))
  351.     Shutdown( cp, 20 );
  352.  
  353.   if( !( cp->devList = GetDevList(cp) ) )
  354.     Shutdown( cp, 20 );
  355.  
  356.   CreateFFGadgets( cp, cp->devList , ( defScreen->WBorTop + defScreen->Font->ta_YSize+1 ),
  357.                    defScreen->WBorLeft );
  358.  
  359.   if( (cp->centerWindow) || cp->lastX == -1 || cp->lastY == -1 )
  360.     CenterWindow( defScreen, &left, &top );
  361.   else
  362.   {
  363.     left = cp->lastX;
  364.     top  = cp->lastY;
  365.   }
  366.  
  367.   cp->ffWindow = OpenWindowTags( NULL,  WA_Left ,    left,
  368.                                         WA_Top,      top,
  369.                                         WA_InnerWidth,    FF_WIDTH,
  370.                                         WA_InnerHeight,   FF_HEIGHT,
  371.                                         WA_Activate, TRUE,
  372.                                         WA_Flags,    WFLG_DRAGBAR | WFLG_DEPTHGADGET |
  373.                                                      WFLG_CLOSEGADGET |
  374.                                                      WFLG_SMART_REFRESH,
  375.                                         WA_IDCMP,    STRINGIDCMP|CYCLEIDCMP|
  376.                                                      BUTTONIDCMP|LISTVIEWIDCMP|
  377.                                                      IDCMP_CLOSEWINDOW|
  378.                                                      IDCMP_VANILLAKEY|
  379.                                                      IDCMP_REFRESHWINDOW|
  380.                                                      IDCMP_DISKINSERTED|
  381.                                                      IDCMP_DISKREMOVED,
  382.                                         WA_PubScreen, defScreen,
  383.                                         WA_Title,    NAME " " _VERSION,
  384.                                         WA_Gadgets,  cp->ffWinGadList,
  385.                                         TAG_DONE );
  386.  
  387.   GT_RefreshWindow( cp->ffWindow, NULL );
  388.  
  389.   GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  390.                      cp->ffWindow, NULL,
  391.                      GTLV_Labels,  (&cp->foundList),
  392.                      GTLV_Selected, ~0L,
  393.                      TAG_DONE );
  394.  
  395.   UnlockPubScreen( NULL , defScreen );
  396.  
  397. }
  398.  
  399. void
  400. CloseFFWindow( struct controlPanel *cp )
  401. {
  402.  
  403.   cp->lastX = cp->ffWindow->LeftEdge;
  404.   cp->lastY = cp->ffWindow->TopEdge;
  405.  
  406.   CloseWindow( cp->ffWindow );
  407.   cp->ffWindow = NULL;
  408.  
  409.   FreeVisualInfo( cp->ffWinVi );
  410.   cp->ffWinVi = NULL;
  411.  
  412.   FreeGadgets( cp->ffWinGadList );
  413.   cp->ffWinGadList = NULL;
  414.  
  415.   cp->ffWinGads.searchPatGad = NULL;
  416.   cp->ffWinGads.searchDevGad = NULL;
  417.   cp->ffWinGads.pathListGad = NULL;
  418.   cp->ffWinGads.searchButton = NULL;
  419.   cp->ffWinGads.hideButton = NULL;
  420.   cp->ffWinGads.quitButton = NULL;
  421.  
  422.   FreeDevList( cp->devList );
  423.   cp->devList = NULL;
  424. }
  425.  
  426. void
  427. HandleFFWindowCommand( struct controlPanel *cp )
  428. {
  429.   struct IntuiMessage *msg;
  430.  
  431.   while( msg = GT_GetIMsg( cp->ffWindow->UserPort ) )
  432.   {
  433.     struct Gadget       *gad;
  434.     ULONG                class;
  435.     UWORD                code,
  436.                          qualifier;
  437.  
  438.     gad   = (struct Gadget *)msg->IAddress;
  439.     class = msg->Class;
  440.     code  = msg->Code;
  441.     qualifier = msg->Qualifier;
  442.  
  443.     GT_ReplyIMsg( msg );
  444.  
  445.     switch( class )
  446.     {
  447.       case IDCMP_CLOSEWINDOW : CMD_Hide( cp );
  448.                                break;
  449.  
  450.       case IDCMP_VANILLAKEY : switch( code )
  451.                               {
  452.                                 case 'p' :
  453.                                 case 'P' : ActivateGadget(cp->ffWinGads.searchPatGad,
  454.                                                           cp->ffWindow, NULL );
  455.                                            break;
  456.  
  457.                                 case 'D' : cp->searchDev = ((cp->searchDev)-1) % cp->numDevs;
  458.                                            GT_SetGadgetAttrs( cp->ffWinGads.searchDevGad,
  459.                                                               cp->ffWindow, NULL ,
  460.                                                               GTCY_Active,cp->searchDev,
  461.                                                               TAG_END );
  462.                                            break;
  463.                                 case 'd' : cp->searchDev = (++(cp->searchDev)) % cp->numDevs;
  464.                                            GT_SetGadgetAttrs( cp->ffWinGads.searchDevGad,
  465.                                                               cp->ffWindow, NULL ,
  466.                                                               GTCY_Active,cp->searchDev,
  467.                                                               TAG_END );
  468.                                            break;
  469.  
  470.                                 case 'F' : if( cp->currFound != ~0 )
  471.                                              cp->currFound = cp->currFound == 0 ?
  472.                                                              0 :
  473.                                                              (--(cp->currFound)) % cp->numFound;
  474.                                            { struct foundNode *fn;
  475.                                              fn = NodeAddress( &cp->foundList, cp->currFound );
  476.  
  477.                                              GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  478.                                                               cp->ffWindow, NULL,
  479.                                                               GTLV_Selected, cp->currFound,
  480.                                                               GTLV_Top,    cp->currFound,
  481.                                                               TAG_END );
  482.                                              GT_SetGadgetAttrs( cp->ffWinGads.pathListGad,
  483.                                                               cp->ffWindow, NULL,
  484.                                                               GTLV_Labels, &fn->fn_PathList,
  485.                                                               GTLV_Top, 0L,
  486.                                                               TAG_END );
  487.                                            }
  488.                                            break;
  489.                                 case 'f' : if( cp->currFound == ~0 )
  490.                                              cp->currFound = 0;
  491.                                            else
  492.                                              cp->currFound = cp->currFound == (cp->numFound-1) ?
  493.                                                              cp->currFound :
  494.                                                              (++cp->currFound) % cp->numFound;
  495.  
  496.                                            { struct foundNode *fn;
  497.                                              fn = NodeAddress( &cp->foundList, cp->currFound );
  498.  
  499.                                              GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  500.                                                               cp->ffWindow, NULL,
  501.                                                               GTLV_Selected, cp->currFound,
  502.                                                               GTLV_Top,    cp->currFound,
  503.                                                               TAG_END );
  504.                                              GT_SetGadgetAttrs( cp->ffWinGads.pathListGad,
  505.                                                               cp->ffWindow, NULL,
  506.                                                               GTLV_Labels, &fn->fn_PathList,
  507.                                                               GTLV_Top, 0L,
  508.                                                               TAG_END );
  509.                                            }
  510.                                            break;
  511.                                 case 'h' :
  512.                                 case 'H' : CMD_Hide( cp );
  513.                                            break;
  514.  
  515.                                 case 's' :
  516.                                 case 'S' : CMD_Search( cp );
  517.                                            break;
  518.  
  519.                                 case 'q' :
  520.                                 case 'Q' : CMD_Quit( cp );
  521.                                            break;
  522.  
  523.                               }
  524.                               break;
  525.  
  526.       case IDCMP_DISKINSERTED :
  527.       case IDCMP_DISKREMOVED  : {
  528.                                   STRPTR *newDevList;
  529.  
  530.                                   if( !( newDevList = GetDevList(cp) ) )
  531.                                     Shutdown( cp , 20 );
  532.  
  533.                                   GT_SetGadgetAttrs( cp->ffWinGads.searchDevGad ,
  534.                                                      cp->ffWindow , NULL ,
  535.                                                      GTCY_Labels , newDevList,
  536.                                                      GTCY_Active , 0,
  537.                                                      TAG_END );
  538.  
  539.                                   cp->searchDev = 0;
  540.  
  541.                                   if( cp->devList )
  542.                                   {
  543.                                     FreeDevList( cp->devList );
  544.                                     cp->devList = newDevList;
  545.                                   }
  546.  
  547.                                 }
  548.  
  549.                                 break;
  550.  
  551.       case IDCMP_REFRESHWINDOW : GT_BeginRefresh(cp->ffWindow);
  552.                                  GT_EndRefresh(cp->ffWindow,TRUE);
  553.                                  break;
  554.  
  555.       case IDCMP_GADGETUP : switch( gad->GadgetID )
  556.                             {
  557.                               case ID_PATGAD :  strncpy( cp->searchString ,
  558.                                                          ((struct StringInfo *)
  559.                                                          cp->ffWinGads.searchPatGad
  560.                                                          ->SpecialInfo)->Buffer ,
  561.                                                          MAXSTR );
  562.                                                 break;
  563.  
  564.                               case ID_DEVGAD :  cp->searchDev = code;
  565.                                                 break;
  566.  
  567.                               case ID_FOUNDLIST : if(!IsListEmpty((struct List *)
  568.                                                                   &(cp->foundList)))
  569.                                                   {
  570.                                                     struct foundNode *fn;
  571.                                                     fn=NodeAddress(&(cp->foundList),
  572.                                                                    code),
  573.                                                     GT_SetGadgetAttrs(
  574.                                                               cp->ffWinGads.pathListGad,
  575.                                                               cp->ffWindow,
  576.                                                               NULL,
  577.                                                        GTLV_Labels, &(fn->fn_PathList),
  578.                                                        GTLV_Top, 0L,
  579.                                                        TAG_END );
  580.                                                     cp->currFound = code;
  581.                                                   }
  582.                                                   break;
  583.  
  584.                               case ID_SEARCH :  CMD_Search( cp );
  585.                                                 break;
  586.  
  587.                               case ID_HIDE : CMD_Hide( cp );
  588.                                              break;
  589.  
  590.                               case ID_QUIT : CMD_Quit( cp );
  591.                                               break;
  592.  
  593.                             }
  594.                             break;
  595.     }
  596.     if( ! cp->ffWindow )
  597.       break;
  598.   }
  599. }
  600.  
  601. void
  602. CreateFFGadgets( struct controlPanel *cp, STRPTR *devList, int topEdge , BYTE leftEdge)
  603. {
  604.   struct Gadget    *gadget;
  605.   struct NewGadget  ng;
  606.  
  607.  
  608.  
  609.   cp->ffWinGadList = NULL;
  610.  
  611.   if( ! ( gadget = CreateContext( &(cp->ffWinGadList) ) ) )
  612.     Shutdown( cp , 20 );
  613.  
  614.   ng.ng_Width =       162;
  615.   ng.ng_Height =      16;
  616.   ng.ng_GadgetText =  "Search _Pattern :";
  617.   ng.ng_TextAttr =    &DefaultFont;
  618.   ng.ng_VisualInfo =  cp->ffWinVi;
  619.   ng.ng_GadgetID  =   ID_PATGAD;
  620.   ng.ng_Flags =       0;
  621.   ng.ng_LeftEdge =    ( strlen( ng.ng_GadgetText ) + 2 - 1 ) * 8 - 2 + leftEdge;
  622.   ng.ng_TopEdge =     5 + topEdge;
  623.  
  624.   cp->ffWinGads.searchPatGad = gadget = CreateGadget( STRING_KIND, gadget, &ng,
  625.                                                       GT_Underscore, '_',
  626.                                                       GTST_MaxChars, MAXSTR,
  627.                                                       GTST_String,   cp->searchString,
  628.                                                       TAG_DONE );
  629.  
  630.   ng.ng_GadgetID =    ID_DEVGAD;
  631.   ng.ng_GadgetText =  "_Device to Search :";
  632.   ng.ng_TopEdge +=    ng.ng_Height + INTERHEIGHT;
  633.   ng.ng_LeftEdge =    ( strlen( ng.ng_GadgetText ) + 2 - 1 ) * 8 - 2 + leftEdge;
  634.   ng.ng_Width =       145;
  635.   ng.ng_Height =      18;
  636.  
  637.  
  638.   cp->ffWinGads.searchDevGad = gadget = CreateGadget( CYCLE_KIND, gadget, &ng,
  639.                                                       GT_Underscore, '_',
  640.                                                       GTCY_Labels, devList,
  641.                                                       TAG_DONE );
  642.  
  643.  
  644.  
  645.  
  646.   ng.ng_GadgetID =    ID_FOUNDLIST;
  647.   ng.ng_GadgetText =   "_Files Found :";
  648.   ng.ng_TopEdge +=    ng.ng_Height + 16;
  649.   ng.ng_LeftEdge =    leftEdge + 5;
  650.   ng.ng_Width =       160;
  651.   ng.ng_Height =      76;
  652.  
  653.   cp->ffWinGads.foundListGad = gadget = CreateGadget( LISTVIEW_KIND, gadget, &ng,
  654.                                                       GTLV_ShowSelected, NULL,
  655.                                                       GT_Underscore, '_',
  656.                                                       TAG_DONE );
  657.  
  658.  
  659.   ng.ng_GadgetID =    ID_PATHLIST;
  660.   ng.ng_GadgetText =  "Path :";
  661.   ng.ng_LeftEdge  +=  ng.ng_Width + INTERWIDTH;
  662.   ng.ng_Width =       131;
  663.  
  664.   cp->ffWinGads.pathListGad = gadget = CreateGadget( LISTVIEW_KIND, gadget, &ng,
  665.                                                      GTLV_ReadOnly, TRUE,
  666.                                                      TAG_DONE );
  667.  
  668.  
  669.   ng.ng_GadgetID =    ID_SEARCH;
  670.   ng.ng_GadgetText =  "_Search";
  671.   ng.ng_LeftEdge =    leftEdge + 5L;
  672.   ng.ng_TopEdge +=    ng.ng_Height + 4;
  673.   ng.ng_Width =       94;
  674.   ng.ng_Height =      20;
  675.  
  676.   cp->ffWinGads.searchButton = gadget = CreateGadget( BUTTON_KIND, gadget, &ng,
  677.                                                       GT_Underscore, '_',
  678.                                                       TAG_DONE );
  679.  
  680.  
  681.   ng.ng_GadgetID =    ID_HIDE;
  682.   ng.ng_GadgetText =  "_Hide";
  683.   ng.ng_LeftEdge +=   ng.ng_Width + INTERWIDTH;
  684.  
  685.   cp->ffWinGads.hideButton = gadget = CreateGadget( BUTTON_KIND, gadget, &ng,
  686.                                                     GT_Underscore, '_',
  687.                                                     TAG_DONE );
  688.  
  689.  
  690.   ng.ng_GadgetID =    ID_QUIT;
  691.   ng.ng_GadgetText =  "_Quit";
  692.   ng.ng_LeftEdge +=   ng.ng_Width + INTERWIDTH;
  693.  
  694.   cp->ffWinGads.quitButton = gadget = CreateGadget( BUTTON_KIND, gadget, &ng,
  695.                                                     GT_Underscore, '_',
  696.                                                     TAG_DONE );
  697.  
  698. }
  699.  
  700. void
  701. CenterWindow( struct Screen *sc, WORD *leftEdge, WORD *topEdge )
  702. {
  703.  (*leftEdge)   = sc->MouseX - (FF_WIDTH >> 1);
  704.   (*topEdge)    = sc->MouseY - (FF_HEIGHT >> 1);
  705.  
  706.   while((*leftEdge) + FF_WIDTH > sc->Width)
  707.     (*leftEdge)--;
  708.  
  709.   while((*leftEdge) < 0)
  710.     (*leftEdge)++;
  711.  
  712.   while((*topEdge) + FF_HEIGHT > sc->Height)
  713.     (*topEdge)--;
  714.  
  715.   while((*topEdge) < 0)
  716.     (*topEdge)++;
  717. }
  718.  
  719. struct foundNode *
  720. NodeAddress( struct MinList *fl , UWORD ord )
  721. {
  722.   struct foundNode *fn;
  723.  
  724.   fn = (struct foundNode *)fl->mlh_Head;
  725.  
  726.   while( ord-- )
  727.   {
  728.     fn = (struct foundNode *)fn->fn_Node.ln_Succ;
  729.   }
  730.  
  731.   return( fn );
  732. }
  733.  
  734. BOOL
  735. QuitCheck( struct controlPanel *cp )
  736. {
  737.   struct IntuiMessage *msg;
  738.   BOOL                 quit = FALSE;
  739.  
  740.   while(  msg = GT_GetIMsg( cp->ffWindow->UserPort ) )
  741.   {
  742.     struct Gadget *gad;
  743.     ULONG          class;
  744.     UWORD          code;
  745.  
  746.     gad = msg->IAddress;
  747.     class = msg->Class;
  748.     code  = msg->Code;
  749.  
  750.     GT_ReplyIMsg( msg );
  751.  
  752.     if( class == IDCMP_GADGETUP )
  753.     {
  754.       if( gad->GadgetID == ID_QUIT )
  755.       {
  756.         quit = TRUE;
  757.       }
  758.     }
  759.     else
  760.       if( class == IDCMP_VANILLAKEY )
  761.       {
  762.         if( code == 'q' || code == 'Q' )
  763.         {
  764.           quit = TRUE;
  765.         }
  766.       }
  767.       else
  768.         if( class == IDCMP_REFRESHWINDOW )
  769.         {
  770.           GT_BeginRefresh(cp->ffWindow);
  771.           GT_EndRefresh(cp->ffWindow , TRUE);
  772.         }
  773.  
  774.   }
  775.  
  776.   return( quit );
  777.  
  778. }
  779.  
  780. /*********************************************************************************/
  781.  
  782. /******************************** DOS Interfacing Routines ***********************/
  783.  
  784. /**********************************************************
  785.   Copy a BSTR to CSTR. Equivalent to strcpy().
  786. **********************************************************/
  787.  
  788. void
  789. Bstrcpy( UBYTE *dest , BSTR bsrc )
  790. {
  791.   UBYTE *src = ( UBYTE *)BADDR( bsrc );
  792.   SHORT  pos;
  793.   UBYTE  len;
  794.  
  795.   len = *src++;
  796.  
  797.   for ( pos = 0; pos < len; pos++ )
  798.     *dest++ = *src++;
  799.  
  800.   *dest++ = ':';
  801.   *dest   = '\0';
  802.  
  803. }
  804.  
  805. STRPTR *
  806. GetDevList( struct controlPanel *cp )
  807. {
  808.   struct DosList    *dList,
  809.                     *sdList;
  810.   STRPTR            *devList;
  811.   int                numVols = 0;
  812.  
  813.   dList = LockDosList( LDF_VOLUMES|LDF_READ );
  814.  
  815.   sdList = dList;
  816.  
  817.   while( dList = NextDosEntry( dList , LDF_VOLUMES|LDF_READ ) )
  818.     numVols++;
  819.  
  820.   cp->numDevs = numVols;
  821.  
  822.   if( !( devList = AllocVec( (numVols + 1) * sizeof( STRPTR ) , MEMF_ANY|MEMF_CLEAR )))
  823.     goto exitgdl;
  824.  
  825.   numVols = 0;
  826.  
  827.   while( sdList = NextDosEntry( sdList , LDF_VOLUMES|LDF_READ ) )
  828.   {
  829.     if( !( devList[numVols] = AllocVec( MAXSTR , MEMF_ANY|MEMF_CLEAR )))
  830.       goto exitgdl;
  831.  
  832.     Bstrcpy( devList[numVols++] , sdList->dol_Name );
  833.   }
  834.  
  835. exitgdl:
  836.  
  837.   UnLockDosList( LDF_VOLUMES|LDF_READ );
  838.  
  839.   return( devList );
  840. }
  841.  
  842. void
  843. FreeDevList( STRPTR *devList )
  844. {
  845.   int loc = 0;
  846.  
  847.   while( devList[loc] )
  848.     FreeVec( devList[loc++] );
  849.  
  850.   FreeVec( devList );
  851.  
  852. }
  853.  
  854. BOOL
  855. ScanDir( STRPTR dirName , struct controlPanel *cp , struct MinList *pathList )
  856. {
  857.   BPTR                  currentDir,
  858.                         parentDir;
  859.   struct FileInfoBlock *fib;
  860.   BOOL                  cont = FALSE,
  861.                         done = FALSE;
  862.  
  863.  
  864.   if(!(fib = AllocDosObject( DOS_FIB, NULL ) ) )
  865.     return( FALSE );
  866.  
  867.  
  868.   currentDir = Lock( dirName, ACCESS_READ );
  869.  
  870.   Examine( currentDir, fib );
  871.  
  872.   AddPathNode( pathList, fib->fib_FileName );
  873.  
  874.   parentDir = CurrentDir( currentDir );
  875.  
  876.   while( !done )
  877.   {
  878.     if( !ExNext( currentDir, fib ) )
  879.       break;
  880.  
  881.     if( fib->fib_DirEntryType >= 0 )
  882.       cont = ScanDir( fib->fib_FileName, cp, pathList );
  883.     else
  884.     {
  885.       if( MatchFile( cp, fib->fib_FileName ) )
  886.       {
  887.         AddFoundFile( cp, fib->fib_FileName, pathList );
  888.  
  889.         /* Gadget Work */
  890.         GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  891.                            cp->ffWindow, NULL,
  892.                              GTLV_Labels, (&cp->foundList),
  893.                              GTLV_Selected, 0L,
  894.                            TAG_DONE );
  895.  
  896.         GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  897.                            cp->ffWindow, NULL,
  898.                              GTLV_Labels, ~0L,
  899.                            TAG_DONE );
  900.  
  901.       }
  902.     }
  903.  
  904.     if( cont )
  905.     {
  906.       done = QuitCheck( cp );
  907.     }
  908.   }
  909.  
  910.   currentDir = CurrentDir( parentDir );
  911.  
  912.   UnLock( currentDir );
  913.  
  914.   if( done == FALSE && IoErr() == ERROR_NO_MORE_ENTRIES )
  915.     cont = TRUE;
  916.   else
  917.     cont = FALSE;
  918.  
  919.   DeletePathNode( pathList );
  920.  
  921.   FreeDosObject( DOS_FIB, fib );
  922.  
  923.   return( cont );
  924.  
  925. }
  926.  
  927. BOOL
  928. MatchFile( struct controlPanel *cp, STRPTR fileName )
  929. {
  930.   if( MatchPatternNoCase( cp->ignoreIconsPat, fileName ) )
  931.   {
  932.     if( MatchPatternNoCase( cp->searchPattern, fileName ) )
  933.     {
  934.       return( TRUE );
  935.     }
  936.   }
  937.   return( FALSE );
  938.  
  939. }
  940.  
  941. /******************************** Custom List Mgmt *******************************/
  942.  
  943. void
  944. AddPathNode( struct MinList *list , UBYTE *pathName )
  945. {
  946.   struct pathNode *pn;
  947.  
  948.   pn = AllocVec( sizeof( struct pathNode ) , MEMF_ANY|MEMF_CLEAR );
  949.  
  950.   pn->pn_Node.ln_Name = pn->pn_Name;
  951.  
  952.   strcpy( pn->pn_Name , pathName );
  953.  
  954.   AddTail( (struct List *)list , &pn->pn_Node );
  955. }
  956.  
  957. void
  958. DeletePathNode( struct MinList *list )
  959. {
  960.   struct pathNode *pn;
  961.  
  962.   pn = ( struct pathNode *)RemTail( (struct List *)list );
  963.  
  964.   FreeVec( pn );
  965.  
  966. }
  967.  
  968. struct foundNode *
  969. AddFoundNode( struct MinList *list , UBYTE *foundName , BOOL sort )
  970. {
  971.   struct foundNode *fn;
  972.   struct Node      *node,
  973.                    *pred;
  974.  
  975.   fn = AllocVec( sizeof( struct foundNode ) , MEMF_ANY|MEMF_CLEAR );
  976.  
  977.   fn->fn_Node.ln_Name = fn->fn_Name;
  978.  
  979.   strcpy( fn->fn_Name , foundName );
  980.  
  981.   NewList( (struct List *)&fn->fn_PathList );
  982.  
  983.   if( sort )
  984.   {
  985.     pred = NULL;
  986.  
  987.     for( node = (struct Node *)list->mlh_Head ; node->ln_Succ ; node = node->ln_Succ )
  988.     {
  989.       if( stricmp( node->ln_Name , foundName ) > 0 )
  990.         break;
  991.       pred = node;
  992.     }
  993.  
  994.   }
  995.   else
  996.     pred = (struct Node *)&list->mlh_Tail;
  997.  
  998.   Insert( (struct List *)list, (struct Node *)fn, pred );
  999.  
  1000.   return( fn );
  1001.  
  1002. }
  1003.  
  1004. void
  1005. DeleteFoundList( struct MinList *list )
  1006. {
  1007.   while( ! IsListEmpty( (struct List *)list ))
  1008.   {
  1009.     struct foundNode *fn;
  1010.     struct pathNode  *pn;
  1011.  
  1012.     fn = (struct foundNode *)RemHead( (struct List *)list );
  1013.     while(! IsListEmpty( (struct List *)&fn->fn_PathList ) )
  1014.     {
  1015.       pn = (struct pathNode *)RemHead( (struct List *)&fn->fn_PathList );
  1016.       FreeVec( pn );
  1017.     }
  1018.     FreeVec( fn );
  1019.   }
  1020. }
  1021.  
  1022. void
  1023. AddFoundFile( struct controlPanel *cp, STRPTR fileName,
  1024.               struct MinList *pathList )
  1025. {
  1026.   struct foundNode *fn;
  1027.   struct Node  *pn;
  1028.  
  1029.   fn = AddFoundNode(&cp->foundList, fileName, cp->sortList );
  1030.   if( !IsListEmpty((struct List *)pathList ))
  1031.   {
  1032.     for( pn = (struct Node *)pathList->mlh_Head; pn->ln_Succ; pn = pn->ln_Succ )
  1033.       AddPathNode( &fn->fn_PathList, pn->ln_Name );
  1034.   }
  1035.   ++(cp->numFound);
  1036. }
  1037.  
  1038. /******************************** Commodities Exchange Handling Routines *********/
  1039.  
  1040. void
  1041. OpenCxInterface( struct controlPanel *cp )
  1042. {
  1043.   struct NewBroker nb = {
  1044.     NB_VERSION,
  1045.     ( BYTE *)NAME,
  1046.     ( BYTE *)NAME " " _VERSION,
  1047.     ( BYTE *)"Searches a volume for a file",
  1048.     NBU_UNIQUE | NBU_NOTIFY,
  1049.     COF_SHOW_HIDE,
  1050.     0,
  1051.     NULL,
  1052.     0
  1053.   };
  1054.  
  1055.  
  1056.   nb.nb_Pri = cp->cxInterface.cxPriority;
  1057.  
  1058.  
  1059.   /******* Allocate And Initialize MessagePort *********/
  1060.   if( !( cp->cxInterface.cxPort = CreateMsgPort() ) )
  1061.     Shutdown( cp, 20 );
  1062.  
  1063.  
  1064.   nb.nb_Port = cp->cxInterface.cxPort;
  1065.  
  1066.   /******* Create Main Broker CxObj ********************/
  1067.  
  1068.   if( !( cp->cxInterface.ffBroker = CxBroker( &nb, NULL ) ) )
  1069.     Shutdown( cp, 20 );
  1070.  
  1071.  
  1072.   /******* Create HotKey CxObj *************************/
  1073.  
  1074.   AttachCxObj( cp->cxInterface.ffBroker, HotKey( cp->cxInterface.cxHotKeyString,
  1075.                                                  cp->cxInterface.cxPort,
  1076.                                                  OPEN_WINDOW ));
  1077.  
  1078.   /******* If all went well, activate the Broker *******/
  1079.  
  1080.   if( ! CxObjError( cp->cxInterface.ffBroker ) )
  1081.     ActivateCxObj( cp->cxInterface.ffBroker , TRUE );
  1082.   else
  1083.     Shutdown( cp , 20 );
  1084.  
  1085. }
  1086.  
  1087. void
  1088. CloseCxInterface( struct controlPanel *cp )
  1089. {
  1090.   if( cp->cxInterface.cxPort )
  1091.   {
  1092.     struct Message *msg;
  1093.  
  1094.     if( cp->cxInterface.ffBroker )
  1095.       DeleteCxObjAll( cp->cxInterface.ffBroker );
  1096.     cp->cxInterface.ffBroker = NULL;
  1097.  
  1098.     while( msg = GetMsg( cp->cxInterface.cxPort ) )
  1099.       ReplyMsg( msg );
  1100.  
  1101.     DeleteMsgPort( cp->cxInterface.cxPort );
  1102.     cp->cxInterface.cxPort = NULL;
  1103.  
  1104.   }
  1105. }
  1106.  
  1107. void
  1108. HandleCxCommand( struct controlPanel *cp )
  1109. {
  1110.   CxMsg          *msg;
  1111.  
  1112.   while( msg = ( CxMsg *)GetMsg( cp->cxInterface.cxPort ) )
  1113.   {
  1114.     ULONG           messageID;
  1115.     ULONG           messageType;
  1116.  
  1117.     messageID = CxMsgID( msg );
  1118.     messageType = CxMsgType( msg );
  1119.  
  1120.     ReplyMsg( ( struct Message *)msg );
  1121.  
  1122.     switch( messageType )
  1123.     {
  1124.       case CXM_IEVENT : switch( messageID )
  1125.                         {
  1126.                           case OPEN_WINDOW : CMD_Show( cp );
  1127.                                              break;
  1128.                         }
  1129.                         break;
  1130.  
  1131.       case CXM_COMMAND :  switch( messageID )
  1132.                           {
  1133.                             case CXCMD_DISABLE : ActivateCxObj( cp->cxInterface.ffBroker,
  1134.                                                                 FALSE );
  1135.                                                  break;
  1136.                             case CXCMD_ENABLE :  ActivateCxObj( cp->cxInterface.ffBroker,
  1137.                                                                 TRUE );
  1138.                                                  break;
  1139.  
  1140.                             case CXCMD_APPEAR :
  1141.                             case CXCMD_UNIQUE :  CMD_Show( cp );
  1142.                                                  break;
  1143.  
  1144.                             case CXCMD_DISAPPEAR : CMD_Hide( cp );
  1145.                                                    break;
  1146.  
  1147.                             case CXCMD_KILL : CMD_Quit( cp );
  1148.                                               break;
  1149.                           }
  1150.                           break;
  1151.     }
  1152.   }
  1153. }
  1154.  
  1155. /**********************************************************************************/
  1156.  
  1157. /***************  Command functions start here ************************************/
  1158.  
  1159. void
  1160. CMD_Show( struct controlPanel *cp )
  1161. {
  1162.   OpenFFWindow( cp );
  1163. }
  1164.  
  1165. void
  1166. CMD_Hide( struct controlPanel *cp )
  1167. {
  1168.   CloseFFWindow( cp );
  1169. }
  1170.  
  1171. void
  1172. CMD_Search( struct controlPanel *cp )
  1173. {
  1174.   struct foundNode *fn;
  1175.   struct pathNode  *pn;
  1176.   struct MinList    pathList;
  1177.  
  1178.  
  1179.   GT_SetGadgetAttrs( cp->ffWinGads.searchPatGad,
  1180.                      cp->ffWindow, NULL,
  1181.                      GA_Disabled,  TRUE,
  1182.                      TAG_END );
  1183.  
  1184.   GT_SetGadgetAttrs( cp->ffWinGads.searchDevGad,
  1185.                      cp->ffWindow, NULL,
  1186.                      GA_Disabled,  TRUE,
  1187.                      TAG_END );
  1188.  
  1189.   GT_SetGadgetAttrs( cp->ffWinGads.searchButton,
  1190.                      cp->ffWindow, NULL,
  1191.                      GA_Disabled,  TRUE,
  1192.                      TAG_END );
  1193.  
  1194.   GT_SetGadgetAttrs( cp->ffWinGads.hideButton,
  1195.                      cp->ffWindow, NULL,
  1196.                      GA_Disabled,  TRUE,
  1197.                      TAG_END );
  1198.  
  1199.   GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  1200.                      cp->ffWindow, NULL,
  1201.                      GTLV_Labels,  NULL,
  1202.                      TAG_END );
  1203.  
  1204.   GT_SetGadgetAttrs( cp->ffWinGads.pathListGad,
  1205.                      cp->ffWindow, NULL,
  1206.                      GTLV_Labels,  NULL,
  1207.                      TAG_END );
  1208.  
  1209.   DeleteFoundList( &cp->foundList );
  1210.  
  1211.   cp->numFound = 0;
  1212.   cp->currFound = ~0;
  1213.  
  1214.   NewList( (struct List *)&pathList );
  1215.  
  1216.   if( ParsePatternNoCase( cp->searchString , cp->searchPattern , MAXPAT ) == -1 )
  1217.     return;
  1218.  
  1219.   ScanDir( cp->devList[cp->searchDev] , cp , &pathList );
  1220.  
  1221.         /** Forget about the return from ScanDir(). It is only
  1222.             used as an abort code for the recursion, and meaningful
  1223.             only inside that func. ScanDir() will return a valid, but
  1224.             not complete list even if the user aborted the search      **/
  1225.  
  1226.   GT_SetGadgetAttrs( cp->ffWinGads.foundListGad,
  1227.                      cp->ffWindow, NULL,
  1228.                      GTLV_Labels,  (&cp->foundList),
  1229.                      GTLV_Selected, ~0L,
  1230.                      TAG_DONE );
  1231.  
  1232.   GT_SetGadgetAttrs( cp->ffWinGads.searchPatGad,
  1233.                      cp->ffWindow, NULL,
  1234.                      GA_Disabled,  FALSE,
  1235.                      TAG_END );
  1236.  
  1237.   GT_SetGadgetAttrs( cp->ffWinGads.searchDevGad,
  1238.                      cp->ffWindow, NULL,
  1239.                      GA_Disabled,  FALSE,
  1240.                      TAG_END );
  1241.  
  1242.   GT_SetGadgetAttrs( cp->ffWinGads.searchButton,
  1243.                      cp->ffWindow, NULL,
  1244.                      GA_Disabled,  FALSE,
  1245.                      TAG_END );
  1246.  
  1247.   GT_SetGadgetAttrs( cp->ffWinGads.hideButton,
  1248.                      cp->ffWindow, NULL,
  1249.                      GA_Disabled,  FALSE,
  1250.                      TAG_END );
  1251.  
  1252. }
  1253.  
  1254. void
  1255. CMD_Quit( struct controlPanel *cp )
  1256. {
  1257.   Shutdown( cp , 0 );
  1258. }
  1259.  
  1260. /**********************************************************************************/
  1261.  
  1262. /***************  Comprehensive Shutdown Code *************************************/
  1263. void
  1264. Shutdown( struct controlPanel *cp , int retCode )
  1265. {
  1266.  
  1267.   if( cp )
  1268.   {
  1269.  
  1270.     /*************************** Close Cx port and interface ************************/
  1271.  
  1272.     if( cp->cxInterface.cxPort )
  1273.     {
  1274.       CloseCxInterface( cp );
  1275.     }
  1276.  
  1277.     /*************************** Get Rid of Window and Related GadTools Stuff *******/
  1278.  
  1279.     if( cp->ffWindow )
  1280.     {
  1281.       CloseFFWindow( cp );
  1282.       cp->ffWindow = NULL;
  1283.     }
  1284.  
  1285.     if( cp->ffWinGadList )
  1286.     {
  1287.       FreeGadgets( cp->ffWinGadList );
  1288.       cp->ffWinGadList = NULL;
  1289.     }
  1290.  
  1291.     if( cp->ffWinVi );
  1292.     {
  1293.       FreeVisualInfo( cp->ffWinVi );
  1294.       cp->ffWinGadList = NULL;
  1295.     }
  1296.  
  1297.     DeleteFoundList( &cp->foundList );
  1298.  
  1299.     if( cp->devList )
  1300.     {
  1301.       FreeDevList( cp->devList );
  1302.       cp->devList = NULL;
  1303.     }
  1304.  
  1305.     FreeVec( cp );
  1306.  
  1307.   }
  1308.   /******************************* Close Libraries & exit ************************/
  1309.  
  1310.   if( IntuitionBase )
  1311.     CloseLibrary( IntuitionBase );
  1312.  
  1313.   if( GadToolsBase )
  1314.     CloseLibrary( GadToolsBase );
  1315.  
  1316.   if( IconBase )
  1317.     CloseLibrary( IconBase );
  1318.  
  1319.   if( CxBase )
  1320.     CloseLibrary( CxBase );
  1321.  
  1322.   exit( retCode );
  1323.  
  1324. }
  1325. /********************************************************************************/
  1326.  
  1327.