home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 092.lha / ColorFull / getfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-21  |  27.0 KB  |  1,003 lines

  1. /***************************************************************************
  2. * getfile.c  by: Keith Young                                      12/20/87
  3. *
  4. *   These routines were origionally written by: Charlie Heath of Microsmiths
  5. * (getfile.c on Manx Aztec C examples disk) and were Heavily modified by me
  6. * ( Keith Young ) for use in my ShareWare terminal program: "Access!" and
  7. * then further modified for "portability" and infestation into the public.
  8. * (as FREEWARE).
  9. *  I'll not attemp to list all the modifications made (sounds to much like
  10. * work). Nor will I guarantee that they even work at all (but hey, they work
  11. * for me :-). 
  12. *
  13. *  You may Use these source files, modify 'em, throw 'em away, give 'em away,
  14. * without obligation. JUST DON'T SELL 'EM! (I doubt you'd get much anyway:-)
  15. *   If you do use 'em (in a noncomercial manner), I would appeciate a small
  16. * "mention" in the docs somewhere. (small print, lower left hand corner will
  17. * do )
  18. *  
  19. *  These routines now compile using AZTEC 3.4a using 16 bit ints.(horay!)
  20. * (see included makefile)
  21. *
  22. *   Any bug reports/suggestions/fixes/etc... would be appreciated.
  23. *   I can be reached at:              (703) 297-7639
  24. *
  25. * via    E-MAIL->  GEnie: K.Young
  26. *                 CA-AUG: Keith Young
  27. *           Deep Thought: Keith Young
  28. *             COMPUSERVE: 73170,307
  29. *
  30. * via Snail-Mail-> Keith Young
  31. *                  Rt.2 Box 261
  32. *                  Goodview, Va.   (yes, really :-)
  33. *                           24095
  34. *  
  35. ***************************************************************************/
  36.  
  37. #include <ctype.h>
  38. #include <stdio.h>
  39.  
  40. #include "standard.h"
  41. #include "safeclose.h"
  42. #include "img.h"
  43. #define FAST register
  44. #define NL 0L
  45.  
  46. extern UBYTE               *dmore(), *dinit();
  47. extern APTR                *AllocMem();
  48. extern UBYTE               *rindex(), *index();
  49. extern struct FileLock     *Lock();
  50. extern struct InfoData     *Info();
  51. extern struct Window       *OpenWindow();
  52. extern struct IntuiMessage *GetMsg();
  53.  
  54. static struct FileLock      *pdir = NL;
  55. static struct FileInfoBlock *dir_info;
  56. static struct Window        *eW;      /* Parent Window. Uck   */
  57.  
  58.  
  59.  /* this is initialized in "test.c" currently... */
  60. extern struct TextAttr MyFont;/* = { 
  61.    (UBYTE *)"topaz.font",     
  62.    TOPAZ_EIGHTY,
  63.    FS_NORMAL,
  64.    FPF_ROMFONT
  65.  };*/
  66.  
  67.  
  68. #define FGAD      0L           /* Offset gadget ID's from here */
  69.  
  70. #define FCHARS    32L          /* Number of chars allowed in file name   */
  71. #define DIR_SIZ   50L          /* Number of chars in a dir name...   */
  72. #define MAX_STR   DIR_SIZ+2L
  73.  
  74. #define DENTS     7L           /* Number of entries on screen   */
  75.                                /* It's not as simple as changing 'DENTS'... */
  76. #define DSIZE     FCHARS+1L    /* Size of a directory entry   */
  77. #define DBUFSIZ   4000L        /* Number of bytes to allocate for all ents */
  78.  
  79. #define BCOL      7L           /* Background color   */
  80. #define FCOL      6L           /* Foreground color   */
  81.  
  82. #define RHGHT   128L
  83. #define RWDTH   390L
  84. #define ZWDTH   250L           
  85.  
  86. static UBYTE  def1[DIR_SIZ] = "DF2:\0";  /* user defined directory #1 */
  87. static UBYTE  def2[DIR_SIZ] = "DH0:\0";  /* user defined directory #2 */
  88. static UBYTE  sbuff[20] = "\0";          /* string buffer for "Bytes Free:" */
  89. static UBYTE  ubuf[MAX_STR];             /* Undo buffer   */
  90.  
  91. static struct dirent {
  92.        struct dirent *next;    /* ptr to next dirent */ 
  93.        BOOL isfile;            /* file or directory ? */
  94.        LONG d_size;            /* file size */
  95.        UBYTE dE[DSIZE+2];      /* file name kept here */
  96.  };
  97. static struct dirent *FirstEntry;
  98. static struct dirent *NextEntry;
  99.  
  100. static struct dirhead {
  101.        struct dirent *next;
  102.  };
  103. static struct dirhead ListHead;
  104.  
  105. static ULONG  curent,maxent;
  106. static BOOL   more;
  107. static BOOL   up,dn;            /* toggle flags for quick-scrolling */
  108. static struct Window     *wRq = NL;      /* Requester window   */
  109. static struct RastPort   *wRp;
  110.  
  111. static struct IntuiText saydir = {1,2,JAM2,0,1,&MyFont,(UBYTE *)"(dir) ",NL};
  112.  
  113. /**************************************************************************
  114.  * the following IntuiText is paired together as text + shadowtext...
  115.  * (there are better ways to do this)
  116.  **************************************************************************/
  117.  
  118. static struct IntuiText partext[2] = {
  119.            {0,0,JAM1, 7,2,&MyFont,(UBYTE *)"PARENT",&partext[1]},
  120.            {5,0,JAM1, 5,1,&MyFont,(UBYTE *)"PARENT",NL}
  121.            };
  122.  
  123. static struct IntuiText bytext[2] = {
  124.            {0,0,JAM1,210,RHGHT-16,&MyFont, NL,&bytext[1]},
  125.            {4,0,JAM1,208,RHGHT-17,&MyFont, NL,NL}
  126.            };
  127.  
  128. static struct IntuiText freeTxt[2] = {
  129.            {0,0,JAM1,120,RHGHT-16,&MyFont,(UBYTE *)"Bytes Free:",&freeTxt[1]},
  130.            {5,0,JAM1,118,RHGHT-17,&MyFont,(UBYTE *)"Bytes Free:",NL}
  131.            };
  132.  
  133. static struct IntuiText otxt[2] = {
  134.            {0,0,JAM1,20,RHGHT-32,&MyFont,(UBYTE *)"File",&otxt[1] },
  135.            {5,0,JAM1,18,RHGHT-33,&MyFont,(UBYTE *)"File",&freeTxt[0] }
  136.            };
  137.  
  138. static struct IntuiText dtxt[2] = {
  139.            {0,0,JAM1,20,14,&MyFont,(UBYTE *)"Drawer",&dtxt[1]},
  140.            {5,0,JAM1,18,13,&MyFont,(UBYTE *)"Drawer",&otxt[0]}
  141.            };
  142.  
  143. static struct IntuiText rsize[DENTS] = {      /* File size list */
  144.    {5,2,JAM2,213,1,&MyFont,NL, NL},
  145.    {5,2,JAM2,213,1,&MyFont,NL, NL},
  146.    {5,2,JAM2,213,1,&MyFont,NL, NL}, 
  147.    {5,2,JAM2,213,1,&MyFont,NL, NL},
  148.    {5,2,JAM2,213,1,&MyFont,NL, NL},
  149.    {5,2,JAM2,213,1,&MyFont,NL, NL},
  150.    {5,2,JAM2,213,1,&MyFont,NL, NL}
  151. };
  152. static struct IntuiText rname[DENTS+6] = {    /* File name list */
  153.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  154.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  155.    {0,2,JAM2,48,1,&MyFont,NL, NL}, 
  156.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  157.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  158.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  159.    {0,2,JAM2,48,1,&MyFont,NL, NL},
  160.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"DH0:",NL}, /* device/dir name list */
  161.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"DF2:",NL},
  162.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"DF1:",NL},
  163.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"DF0:",NL},
  164.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"VD0:",NL},
  165.    {0,0,JAM1,5,16,&MyFont,(UBYTE *)"RAM:",NL}
  166.  };
  167.  
  168. /* Border for Drawer ... */
  169.  
  170. static SHORT oXY1[] = {
  171.    -1,-1,
  172.    193,-1,
  173.    193,8,
  174.    -1,8,
  175.    -1,-1
  176.  };
  177. static struct Border thebd1 = {
  178.    0,0,
  179.    6,0,JAM1,
  180.    5,oXY1,
  181.    NL
  182.  };
  183.  
  184. /* Border for file name ... */
  185.  
  186. static SHORT oXY2[] = {
  187.    -1,-1,
  188.    209,-1,
  189.    209,8,
  190.    -1,8,
  191.    -1,-1
  192.  };
  193. static struct Border thebd2 = {
  194.    0,0,
  195.    6,0,JAM1,
  196.    5,oXY2,
  197.    NL
  198.  };
  199.  
  200. static struct Image myknob;
  201. static struct PropInfo   cc_prop = {
  202.      AUTOKNOB | FREEVERT,         /* flags */
  203.      0,0,                         /* HPot, VPot */
  204.      0,0x10000,                   /* HBody,VBody */
  205.      0,0,0,0,0,0
  206.  };
  207. static struct Gadget gprop = {
  208.      NULL,                           /* Next gadget   */
  209.      RWDTH-120,23,                   /* Left, Top     */
  210.      20,70,                          /* Scroll Bar    */
  211.      GADGHIMAGE | GADGIMAGE ,        /* Flags         */
  212.      GADGIMMEDIATE | FOLLOWMOUSE,    /* Activation    */
  213.      PROPGADGET,                     /* Type          */
  214.      (APTR)&myknob,                  /* Render        */
  215.      NL,                             /* Select Render */
  216.      NL,NL,                          /* Text, Exclude */
  217.      (APTR)&cc_prop,                 /* Special Info  */
  218.      FGAD+13,                        /* GadgetID      */
  219.      NL                              /* UserData      */
  220.  };
  221.  
  222. static struct Gadget scr_dn = {
  223.    &gprop,
  224.    RWDTH-119,RHGHT-35,
  225.    20,10,                    /* scroll dn   */
  226.    GADGHNONE,      
  227.    GADGIMMEDIATE,      
  228.    BOOLGADGET,
  229.    NL,NL,  
  230.    NL,
  231.    NL,NL,           
  232.    FGAD+22,
  233.    NL
  234.  };                
  235. static struct Gadget scr_up = {
  236.    &scr_dn,
  237.    RWDTH-119,13,
  238.    20,10,                    /* scroll up   */
  239.    GADGHNONE,      
  240.    GADGIMMEDIATE,      
  241.    BOOLGADGET,
  242.    NL,NL,  
  243.    NL,
  244.    NL,NL,           
  245.    FGAD+21,
  246.    NL
  247.  };                
  248.  
  249. static struct Gadget par = {
  250.    &scr_up,
  251.    306,13,
  252.    58,10,                    /* PARENT   */
  253.    GADGHCOMP,      
  254.    RELVERIFY,      
  255.    BOOLGADGET,
  256.    NL,NL,  
  257.    &partext[0],
  258.    NL,NL,           
  259.    FGAD+20,
  260.    NL
  261.  };                
  262. static struct StringInfo gsdef2 = {
  263.     NL,
  264.     NL,
  265.     NL,
  266.     DIR_SIZ,
  267.     NL,NL,NL,NL,NL,NL,NL,NL,NL
  268.  };
  269. static struct Gadget gdef2 = { /* string gadget for user defined directory */
  270.    &par,
  271.    RWDTH-47,95,
  272.    32,10,                             /* string #2 */
  273.    GADGHCOMP, RELVERIFY, STRGADGET,
  274.    NL,NL, NL, /*txt*/
  275.    NL, (APTR)&gsdef2,
  276.    FGAD+19,
  277.    NL
  278.  };
  279.  
  280. static struct StringInfo gsdef1 = {
  281.     NL,
  282.     NL,
  283.     NL,
  284.     DIR_SIZ,
  285.     NL,NL,NL,NL,NL,NL,NL,NL,NL
  286.  };
  287. static struct Gadget gdef1 = { /* string gadget for user defined directory */
  288.    &gdef2,
  289.    RWDTH-87,95,
  290.    32,10,                               /* string #1 */
  291.    GADGHCOMP, RELVERIFY, STRGADGET,
  292.    NL,NL, NL, 
  293.    NL, (APTR)&gsdef1,
  294.    FGAD+18,
  295.    NL
  296.  };
  297.  
  298. static struct StringInfo gsfil = {
  299.    NL,
  300.    ubuf,
  301.    NL,
  302.    DSIZE,
  303.    NL,NL,NL,NL,NL,NL,NL,NL,NL
  304. };
  305. static struct Gadget gfil = {
  306.    &gdef1,
  307.    60,RHGHT-33,
  308.    RWDTH-178,10,                      /* File name gadget */
  309.    GADGHCOMP, RELVERIFY, STRGADGET,
  310.    (APTR)&thebd2,
  311.    NL, NL,/*txt*/
  312.    NL, (APTR)&gsfil,
  313.    FGAD+17,
  314.    NL
  315.  };
  316.  
  317. static struct StringInfo gsdir = {
  318.     NL,
  319.     ubuf,
  320.     NL,
  321.     DIR_SIZ,
  322.     NL,NL,NL,NL,NL,NL,NL,NL,NL
  323.  };
  324. static struct Gadget gdir = {
  325.    &gfil,
  326.    76,13,
  327.    RWDTH-193,10,                     /* Directory gadget */
  328.    GADGHCOMP, RELVERIFY, STRGADGET,
  329.    (APTR)&thebd1,
  330.    NL, NL,/*txt*/
  331.    NL, (APTR)&gsdir,
  332.    FGAD+16,
  333.    NL
  334.  };
  335.  
  336. static struct Gadget gok = {
  337.    &gdir,
  338.    15,RHGHT-19,
  339.    58,12,                    /* OTAY   */
  340.    GADGIMAGE | GADGHIMAGE,      
  341.    RELVERIFY, BOOLGADGET,
  342.    (APTR)&okupImage,
  343.    (APTR)&okdnImage,  
  344.    NL, NL,NL,           
  345.    FGAD+15,
  346.    NL
  347.  };                
  348. static struct Gadget gcan = {
  349.      &gok,
  350.      RWDTH-81,RHGHT-19,
  351.      58,12,                 /* CANCEL */
  352.      GADGIMAGE | GADGHIMAGE,
  353.      RELVERIFY, BOOLGADGET,
  354.      (APTR)&canupImage,
  355.      (APTR)&candnImage,
  356.      NL, NL,NL,
  357.      FGAD+14,
  358.      NL
  359.  };
  360.  
  361. static struct Gadget gram = {
  362.    &gcan,
  363.    RWDTH-90 ,26,
  364.    30,13,                     /* RAM */
  365.    GADGIMAGE | GADGHIMAGE,
  366.    RELVERIFY, BOOLGADGET,
  367.    (APTR)&disk1Image,
  368.    (APTR)&disk2Image,
  369.    &rname[12], NL,NL,
  370.    FGAD+12,
  371.    NL
  372.  };
  373. static struct Gadget gvd0 = {
  374.    &gram,
  375.    RWDTH-50,26,
  376.    30,13,                      /* VD0 */
  377.    GADGIMAGE | GADGHIMAGE,
  378.    RELVERIFY, BOOLGADGET,
  379.    (APTR)&disk1Image,
  380.    (APTR)&disk2Image,
  381.    &rname[11], NL,NL,
  382.    FGAD+11,
  383.    NL
  384.  };
  385. static struct Gadget gdf0 = {
  386.    &gvd0,
  387.    RWDTH-90 ,52,
  388.    30,13,                         /* DF0 */
  389.    GADGIMAGE | GADGHIMAGE,
  390.    RELVERIFY, BOOLGADGET,
  391.    (APTR)&disk1Image,
  392.    (APTR)&disk2Image,
  393.    &rname[10], NL,NL,
  394.    FGAD+10,
  395.    NL
  396.  };
  397. static struct Gadget gdf1 = {
  398.    &gdf0,
  399.    RWDTH-50 ,52,
  400.    30,13,                        /* DF1 */
  401.    GADGIMAGE | GADGHIMAGE,
  402.    RELVERIFY, BOOLGADGET,
  403.    (APTR)&disk1Image,
  404.    (APTR)&disk2Image,
  405.    &rname[9], NL,NL,
  406.    FGAD+9,
  407.    NL
  408.  };
  409. static struct Gadget gdf2 = {
  410.    &gdf1,
  411.    RWDTH-90 ,78,
  412.    30,13,                     /* DF2 */ /* (user #1) */
  413.    GADGIMAGE | GADGHIMAGE,
  414.    RELVERIFY, BOOLGADGET,
  415.    (APTR)&disk1Image,
  416.    (APTR)&disk2Image,
  417.    NL, NL,NL,
  418.    FGAD+8,
  419.    NL
  420.  };
  421. static struct Gadget gdh0 = {
  422.    &gdf2,
  423.    RWDTH-50 ,78,
  424.    30,13,                    /* DH0 */ /* (user #2) */
  425.    GADGIMAGE | GADGHIMAGE,
  426.    RELVERIFY, BOOLGADGET,
  427.    (APTR)&disk1Image,
  428.    (APTR)&disk2Image,
  429.    NL, NL,NL,
  430.    FGAD+7,
  431.    NL
  432.  };
  433.  
  434. static struct Gadget og7 = {
  435.    &gdh0,
  436.    20,83, ZWDTH,10,                      /* Gadgets For   */
  437.    GADGHCOMP, RELVERIFY, BOOLGADGET,     /* Directory entries   */
  438.    NL,NL, &rname[6],
  439.    NL,NL,
  440.    FGAD+6,
  441.    NL
  442.  };
  443. static struct Gadget og6 = {
  444.    &og7,
  445.    20,73, ZWDTH,10,  
  446.    GADGHCOMP, RELVERIFY, BOOLGADGET,
  447.    NL,NL, &rname[5],
  448.    NL,NL,
  449.    FGAD+5,
  450.    NL
  451.  };
  452. static struct Gadget og5 = {
  453.    &og6,
  454.    20,63, ZWDTH,10,
  455.    GADGHCOMP, RELVERIFY, BOOLGADGET,
  456.    NL,NL, &rname[4],
  457.    NL,NL,
  458.    FGAD+4,
  459.    NL
  460.  };
  461. static struct Gadget og4 = {
  462.    &og5,
  463.    20,53, ZWDTH,10,
  464.    GADGHCOMP, RELVERIFY, BOOLGADGET,
  465.    NL,NL, &rname[3],
  466.    NL,NL,
  467.    FGAD+3,
  468.    NL
  469.  };
  470. static struct Gadget og3 = {
  471.    &og4,
  472.    20,43, ZWDTH,10,
  473.    GADGHCOMP, RELVERIFY, BOOLGADGET,
  474.    NL,NL, &rname[2],
  475.    NL,NL,
  476.    FGAD+2,
  477.    NL
  478.  };
  479. static struct Gadget og2 = {
  480.    &og3,
  481.    20,33, ZWDTH,10,
  482.    GADGHCOMP, RELVERIFY, BOOLGADGET,
  483.    NL,NL, &rname[1],
  484.    NL,NL,
  485.    FGAD+1,
  486.    NL
  487.  };
  488. static struct Gadget og1 = {
  489.    &og2,
  490.    20,23, ZWDTH,10,   
  491.    GADGHCOMP, RELVERIFY, BOOLGADGET, 
  492.    NL,NL, &rname[0],
  493.    NL,NL,
  494.    FGAD,
  495.    NL
  496.  };
  497.  
  498. /* Open a requester "Window" */
  499.  
  500. static struct NewWindow NewFiles = {
  501.    120, 40,
  502.    RWDTH,RHGHT,
  503.    BCOL,FCOL,
  504.    NL, /* Fill in AFTER opening ... */
  505.    SMART_REFRESH | ACTIVATE | WINDOWDRAG,
  506.    &og1,
  507.    NL,(UBYTE *)"File Requester",NL,NL,
  508.    RWDTH,RHGHT,RWDTH,RHGHT,
  509.    WBENCHSCREEN  /* change this after call */
  510.  };
  511.  
  512. extern struct IntuitionBase  *IntuitionBase;
  513.  
  514. /*******************************************************************
  515. *  get_fname(window,screen,hail,ddef,ddir);
  516. *
  517. *   Displays a window/requester that
  518. * gets a file name for device,directory,default file, extension
  519. *
  520. *   Calling args:
  521. * window:   Window making the request
  522. * screen:   Screen, if NULL assummed workbench
  523. * hail:   Text prompt at top of requester
  524. * ddef:   Input default file-name. Has NO DIRECTORY OR EXTENSION.
  525. * ddir:   Directory of file, may be null
  526. */
  527.  
  528. /* Set a file-requester (actually a window) with title 'hail' */
  529.  
  530. UBYTE *get_fname(cW,screen,hail,ddef,ddir)
  531.    struct Window *cW;       /* Calling Window   */
  532.    struct Screen *screen;   /* screen .... if null assumed workbench */
  533.    UBYTE      *hail;        /* Hailing prompt   */
  534.    UBYTE      *ddef;        /* Probable file-name   */
  535.    UBYTE      *ddir;        /* Directory in which to search   */
  536. {
  537.    FAST struct IntuiMessage *imes;   /* Wait for message in HERE   */
  538.    FAST struct Gadget       *igad;   /* Get Gadget Mumbo Jumbo   */
  539.    FAST ULONG  i,class;
  540.    FAST TEXT   *pnam,*stomp;
  541.    FAST UBYTE  *retval;              /* return value */
  542.    FAST BOOL   dir_flag;
  543.    FAST BOOL   keepon;
  544.    USHORT      code;
  545.    TEXT        ch;
  546.  
  547.    if ( ! (eW = cW) )   return(NL);
  548.  
  549.     gsfil.Buffer = ddef;   /* Set default file name   */
  550.     gsdir.Buffer = ddir;   /* Set default device name   */
  551.    gsdef1.Buffer = def1;   /* Set #1 default drive */
  552.    gsdef2.Buffer = def2;   /* Set #2 default drive */
  553.  
  554.    up = FALSE;
  555.  
  556.    for ( i=0; i<DENTS; i++)
  557.    {
  558.       rname[i].IText    = NL;
  559.       rsize[i].IText    = NL;
  560.       rname[i].NextText = NL; 
  561.    };
  562.  
  563.    NewFiles.Title = hail;
  564.    if ((dir_info = (struct FileInfoBlock *)
  565.           AllocMem((ULONG)sizeof(struct FileInfoBlock),MEMF_CHIP)) == NULL)
  566.        return(NL);
  567.  
  568.    if (screen)      /* User supplied a screen */
  569.    {
  570.       NewFiles.Type   = CUSTOMSCREEN;
  571.       NewFiles.Screen = screen;
  572.    }
  573.  
  574.    if ( ! (FirstEntry = (struct dirent *)AllocMem((ULONG)DBUFSIZ,0L)) ||
  575.         ! (wRq = (struct Window *)OpenWindow( &NewFiles )) )
  576.    {
  577. /*      emits_rx("Need more memory to open File-Requester...\n");*/
  578.       if ( FirstEntry )   FreeMem(FirstEntry,(ULONG)DBUFSIZ);
  579.       FreeMem(dir_info,(ULONG)sizeof(struct FileInfoBlock));
  580.       return(NL);
  581.    }
  582.  
  583.    ActivateGadget(&gfil,wRq,0L);
  584.    wRp = wRq->RPort;
  585.  
  586.    wRq->UserPort = eW->UserPort;
  587.    ModifyIDCMP(wRq,(ULONG)(MOUSEBUTTONS | GADGETDOWN | GADGETUP | MOUSEMOVE));
  588.    SetAPen(wRp,2L);
  589.    RectFill(wRp,3L,10L,(ULONG)(RWDTH-5),(ULONG)(RHGHT-2));
  590.  
  591.    PrintIText(wRp,&dtxt,0L,0L);
  592.    DrawImage(wRp,&fmupImage,(long)(RWDTH-118),13L);/* up-dn scroll images */
  593.    DrawImage(wRp,&fmdnImage,(long)(RWDTH-118),(long)(RHGHT-35));
  594.    RefreshGadgets(&og1,wRq,0L); /* re-draw the gadgets after filling in the 
  595.                                     background color */
  596.    /* Set up directory, notify any errors...   */
  597.    if ( pnam = (UBYTE *)dinit(ddir) )   notify(pnam);
  598.  
  599.    for ( retval= NL, keepon=TRUE; keepon ; )
  600.    {
  601.       while ( ! (imes=(struct IntuiMessage *)GetMsg(wRq->UserPort)) )  
  602.       {
  603.        if (up)
  604.          {
  605.           cc_prop.VertPot -= (cc_prop.VPotRes/ DENTS);
  606.           RefreshGadgets(&gprop,wRq,0L); 
  607.          }
  608.        if (dn)
  609.          {
  610.           cc_prop.VertPot += (cc_prop.VPotRes/ DENTS);
  611.           RefreshGadgets(&gprop,wRq,0L); 
  612.          }
  613.        if ( dir_flag || up || dn)
  614.          {
  615.           i = (maxent-DENTS) * cc_prop.VertPot / MAXBODY;
  616.           if ( i > (maxent-DENTS) )
  617.           i = maxent-DENTS;
  618.           if ( i <0 )   i = 0;
  619.           curent = i;
  620.           cxxx();     /* display filenames/sizes  */
  621.           dir_flag = FALSE;
  622.          }
  623.          if ( more )
  624.          {
  625.           if (pnam = (UBYTE *)dmore())   /* Continue to read the directory */
  626.              notify(pnam);      /* Yucko error   */
  627.           if ( maxent <= DENTS ) dir_flag = TRUE;
  628.          }
  629.          else
  630.           if (!up && !dn)
  631.              WaitPort(wRq->UserPort);
  632.       }
  633.       igad = (struct Gadget *)imes->IAddress;
  634.       class = imes->Class;
  635.       code = imes->Code;
  636.       if(class != MOUSEMOVE && class != GADGETUP && class != GADGETDOWN &&
  637.          class != MOUSEBUTTONS)
  638.       {
  639.        /* Process_Your_other_window_messages_here(imes); */
  640.        WindowToFront(wRq);
  641.        continue;
  642.       }
  643.       ReplyMsg(imes);
  644.       switch (class)
  645.       {
  646.          case MOUSEMOVE:     dir_flag = TRUE; break;
  647.          case MOUSEBUTTONS:  if (code == SELECTUP)
  648.                                {
  649.                                 up = FALSE;
  650.                                 dn = FALSE;
  651.                                } 
  652.                              break;
  653.          case GADGETUP:
  654.          case GADGETDOWN:
  655.                             if(igad->GadgetID == FGAD+21)
  656.                                {
  657.                                 up = TRUE;
  658.                                 break;
  659.                                } 
  660.                             if(igad->GadgetID == FGAD+22)
  661.                                {
  662.                                 dn = TRUE;
  663.                                 break;
  664.                                } 
  665.           switch ( i = igad->GadgetID)
  666.            {
  667.             case FGAD+0:
  668.             case FGAD+1:
  669.             case FGAD+2:
  670.             case FGAD+3:
  671.             case FGAD+4:    /* Replace file or directory name   */
  672.             case FGAD+5:
  673.             case FGAD+6:
  674.             case FGAD+7:
  675.             case FGAD+8:
  676.             case FGAD+9:   
  677.             case FGAD+10:
  678.             case FGAD+11:
  679.             case FGAD+12:
  680.                  pnam = rname[i].IText;
  681.                  if   ( rname[i].NextText == NL && i<DENTS )
  682.                    {
  683.                     RemoveGadget(wRq,&gfil);
  684.                     for (i=0; i<DSIZE; i++)      ddef[i] = *pnam++;
  685.                     AddGadget(wRq,&gfil,21L);
  686.                     RefreshGadgets(&gfil,wRq,0L);
  687.                     ActivateGadget(&gfil,wRq,0L);
  688.                     break;
  689.                    }
  690.                  else
  691.                    {
  692.                     switch (i)
  693.                     {
  694.                      case FGAD+7 : *ddir = NL; pnam = def2;break;
  695.                      case FGAD+8 : *ddir = NL; pnam = def1;break;
  696.                      case FGAD+9 : *ddir = NL; break;
  697.                      case FGAD+10: *ddir = NL; break;
  698.                      case FGAD+11: *ddir = NL; break;
  699.                      case FGAD+12: *ddir = NL; break;
  700.                     }
  701.                     RemoveGadget(wRq,&gdir);
  702.                     rfnam(ddir,pnam);
  703.                     AddGadget(wRq,&gdir,21L);
  704.                     RefreshGadgets(&gdir,wRq,0L);
  705.                     }
  706.             case FGAD+16:             /* dir string gadget */
  707.                ch = ddir[ strlen(ddir)-1 ];
  708.                if(ch != ':' && ch != '/') strcat(ddir,"/");
  709.                if ( pnam = (UBYTE *)dinit(ddir) )
  710.                   notify(pnam);
  711.                ActivateGadget(&gfil,wRq,0L);
  712.             case FGAD+13:
  713.                dir_flag = TRUE;       /* prop gadget */
  714.                break;
  715.             case FGAD+15:             /* Name gadget, OTAY gadget   */
  716.             case FGAD+17:
  717.                retval = ddef;         /* only returns filename, a little code
  718.                                          could add ddir+ddef first */
  719.             case FGAD+14:             /* Cancel gadget   */
  720.                keepon = FALSE;
  721.             case FGAD+18:
  722.             case FGAD+19:break;       /* user definable string gadgets... */
  723.             case FGAD+20:             /* PARENT gadget */
  724.                 if (stomp = rindex(ddir,'/'))
  725.                   {
  726.                    *stomp = NULL;
  727.                    if (stomp = rindex(ddir,'/'))
  728.                      { 
  729.                       *stomp = NULL;
  730.                       *(stomp+1) = NULL;
  731.                       strcat(ddir,"/");
  732.                      }
  733.                    else if ( stomp = index(ddir,':')) 
  734.                           *(stomp+1) = NULL;
  735.                    RemoveGadget(wRq,&gdir);
  736.                    AddGadget(wRq,&gdir,-1L);
  737.                    RefreshGadgets(&gdir,wRq,0L);
  738.                    if ( pnam = (UBYTE *)dinit(ddir) )
  739.                      notify(pnam);
  740.                    dir_flag = TRUE;     
  741.                   }
  742.           }
  743.       }
  744.    }
  745.   FreeMem(FirstEntry,(ULONG)DBUFSIZ );
  746.   FreeMem(dir_info,(ULONG)sizeof(struct FileInfoBlock));
  747.   free_pdir();
  748.  
  749.   CloseWindowSafely(wRq);
  750.   return(retval);
  751. }
  752.  
  753. static free_pdir()
  754. {
  755.   if ( pdir )
  756.     {
  757.      UnLock(pdir);
  758.      pdir = NL;
  759.     }
  760. }
  761.  
  762. /*
  763.  *
  764.  * convert 'int.' to right justified 'string' ( for file size display )
  765.  *
  766.  */ 
  767.  
  768. char  *itos(fred)
  769. LONG  fred;
  770.  {
  771.    static char fredstring[6]; /* 6 chars. allows for up to 999999 Bytes...*/
  772.    int          next = 5;
  773.    
  774.    if (!fred) fredstring[next--] = '0';
  775.       
  776.    while ((fred+9)/10)
  777.       {      
  778.       fredstring[next--] = fred % 10 + 0x30;
  779.       fred /= 10;
  780.       }
  781.    while (next+1) fredstring[next--] = 0x20;/* ASCII <space> for left padding*/
  782.    return(fredstring);
  783.  }
  784.  
  785. /*****************************************************************
  786. * dinit()
  787. *   Initialize the fib for directory muck.  Null return
  788. * is good, else return is a pointer to an error string 
  789. */
  790.  
  791. static UBYTE *dinit(subdir)
  792.  UBYTE *subdir;
  793. {
  794.  extern long AvailMem();
  795.  struct InfoData *info;
  796.  ULONG           bytes = 0L; /*  Bytes Free on Drive:  */
  797.  
  798.    more = FALSE;
  799.    curent = maxent = 0;
  800.    cc_prop.VertBody = 0xFFFF;
  801.    cc_prop.VertPot = 0;        /* start at begining of file list*/
  802.    RefreshGadgets(&gprop,wRq,0L); 
  803.  
  804.    NextEntry = FirstEntry;      /* Allocate from here   */
  805.    ListHead.next = NL;          /* Clear the boogie     */
  806.  
  807.    free_pdir();   /* Unlock any old lock... */
  808.  
  809.    if (! (pdir=(struct FileLock *)Lock(subdir,(ULONG)ACCESS_READ)) )
  810.      return((UBYTE *)"Wrong Diskette?");
  811.  
  812.    if ( ! Examine(pdir, dir_info) )
  813.      return((UBYTE *)"Wierd Disk Error");
  814.  
  815.    if ( dir_info->fib_DirEntryType < 0L )
  816.      return((UBYTE *)"Bizzare Alert!!");
  817.  
  818.    if ( !strcmp(subdir,"RAM:") || !strcmp(subdir,"ram:"))
  819.      {
  820.       Forbid();
  821.       bytes = ( AvailMem(MEMF_CHIP) + AvailMem(MEMF_FAST));
  822.       Permit();
  823.       sprintf(sbuff,"%ld",bytes);
  824.      }
  825.    else
  826.      {
  827.       info = (struct InfoData *)
  828.                     AllocMem((ULONG)sizeof(struct InfoData),0L);
  829.       if (Info(pdir,info))
  830.       bytes = (info->id_NumBlocks - info->id_NumBlocksUsed) * info->id_BytesPerBlock;
  831.       FreeMem(info,(long)sizeof(*info));
  832.       sprintf(sbuff,"%ld",bytes);
  833.      }
  834.    bytext[0].IText = sbuff; /* my shadow and... */
  835.    bytext[1].IText = sbuff; /* I... */
  836.    SetAPen(wRp,2L);
  837.    RectFill(wRp,209L,(ULONG)(RHGHT-17),270L,(ULONG)(RHGHT-9));
  838.    PrintIText(wRp,&bytext[0],0L,0L);
  839.  
  840.    more = TRUE;
  841.    return(dmore());
  842. }
  843.  
  844.  
  845. static UBYTE *dmore()
  846. {
  847.   FAST struct dirent   *p_D = NextEntry;
  848.   FAST struct dirent   *ptr = (struct dirent *)&ListHead;
  849.   FAST struct dirent   *plink;
  850.   FAST TEXT            *p_mung;  
  851.   FAST ULONG    i;
  852.  
  853.    if ( ! more )   return(NL);
  854.  
  855.    if ( ExNext( pdir, dir_info ) )
  856.    {
  857.       if ( (ULONG)p_D >=
  858.          ((ULONG)FirstEntry + (ULONG)DBUFSIZ - (ULONG)sizeof(struct dirent)) )
  859.         {
  860.          more = FALSE;
  861.          return((UBYTE *)"Directory Truncated!");
  862.         }
  863.          /* Here you can add a file/directory filter   */
  864.          /* filename text string is at &p_D->dE[0]   */
  865.  
  866.       if ( p_D->isfile = ( dir_info->fib_DirEntryType < 0L ) )
  867.          p_D->d_size = (LONG)(dir_info->fib_Size);
  868.  
  869.       p_mung = &p_D->dE[0];
  870.       for ( i=0; i<FCHARS; i++)
  871.          if ( ! (*p_mung++ = dir_info->fib_FileName[i]) )   break;
  872.  
  873.       i = (ULONG)p_mung;
  874.       NextEntry = (struct dirent *)( (i+5L) & ~3L );
  875.  
  876.       for ( i=maxent++; i>=0; i--)
  877.       {
  878.        if ( ! (plink = ptr->next)  )   break;
  879.        if ( alpha_lower(p_D,plink) )   break;
  880.        ptr = plink;
  881.       }
  882.       p_D->next = plink;
  883.       ptr->next = p_D;
  884.  
  885.       if(maxent > DENTS)
  886.        {
  887.         cc_prop.VertBody = ((DENTS * 0x10000) / maxent);
  888.         RefreshGadgets(&gprop,wRq,0L); 
  889.        }
  890.       return(NL);
  891.    }
  892.    else return ( IoErr() == ERROR_NO_MORE_ENTRIES) ?
  893.        (UBYTE *)(more = 0L) : (UBYTE *)"Error Reading Directory!!!";
  894. }
  895.  
  896. /* dedicated alphabetizing function for dmore()   */
  897.  
  898. static alpha_lower(snew,sold)
  899.    struct dirent *snew,*sold;
  900. {
  901.    FAST struct dirent *pnew = snew;
  902.    FAST TEXT *ps1,*ps2, c,d;
  903.  
  904.    if ( pnew->isfile == sold->isfile)
  905.      {
  906.       ps1 = &pnew->dE[0];
  907.       ps2 = &sold->dE[0];
  908.       while ( (c=*ps1++) )
  909.          {
  910.           if ( c > (d=*ps2++) )   return(FALSE);
  911.           else if ( c < d )      break;
  912.          }
  913.       return(TRUE);
  914.      }
  915.    return(pnew->isfile);
  916. }   
  917.  
  918. /* Display directory stuff   */
  919.  
  920. static cxxx()
  921. {
  922.    FAST ULONG   i,new;
  923.    FAST ULONG   x,y;
  924.    FAST struct dirent *ohboy = (struct dirent *)&ListHead;
  925.  
  926.    new = curent;
  927.    for ( i=0; i<new; i++)   ohboy = ohboy->next;
  928.    SetBPen(wRp,2L);
  929.    SetDrMd(wRp,JAM2);
  930.    y = 13L;
  931.    for (i=0; i<DENTS; i++)
  932.      {
  933.       x = 20L;
  934.       y += 10;
  935.       rname[i].NextText = 0;
  936.       rname[i].IText = 0;
  937.       rsize[i].IText = (UBYTE *)"      ";
  938.       rname[i].LeftEdge = 0;
  939.       if ( (new+i) < maxent )
  940.         {
  941.          ohboy = ohboy->next;
  942.          rname[i].IText = &ohboy->dE[0];
  943.         if ( ohboy->isfile )
  944.             {                      
  945.              rsize[i].IText = (UBYTE *)itos(ohboy->d_size);
  946.              PrintIText(wRp,&rname[i],20L,y);
  947.             }
  948.          else
  949.             {
  950.              rname[i].LeftEdge = 48;
  951.              PrintIText(wRp,&saydir,20L,y);
  952.              PrintIText(wRp,&rname[i],20L,y);
  953.              rname[i].NextText = &saydir;
  954.             }
  955.         x = wRp->cp_x;
  956.         }
  957.       if ( x < 214 )
  958.         {
  959.          SetAPen(wRp,2L);  
  960.          RectFill(wRp,x,y,215L,(ULONG)(y+8L));
  961. /*         RectFill(wRp,x,(long)(y-6),215L,(long)(y+1));*/
  962.         }        
  963.       PrintIText(wRp,&rsize[i],0L,y);
  964.    }
  965. }
  966.  
  967.  
  968. /**************************************************
  969. * rfnam()
  970. *   Combines dir, plus name into dir   */
  971.  
  972. static rfnam(dir,fil_nam)
  973.    UBYTE *dir,*fil_nam;
  974.    {
  975.    FAST UBYTE   *pdst = dir;
  976.    FAST UBYTE   *psrc = fil_nam;
  977.    FAST UBYTE   c = ':';
  978.  
  979.    while ( *pdst )
  980.       c = *pdst++;
  981.    if ( c != ':' && c != '/' )   *pdst++ = '/';
  982.  
  983.    while ( *pdst++ = *psrc++ )
  984.       ;
  985.    }
  986.  
  987. static struct IntuiText b_txt = {0,1,JAM2, 5,20,NL,NL,    NL};
  988. static struct IntuiText p_txt = {0,1,JAM2, 5,3,NL,(UBYTE *)"OK", NL};
  989.  
  990. /****************************************************************
  991. * notify(txt)                    
  992. * Prompts for Yes/No response            
  993. */
  994. static notify(txt)
  995.    UBYTE *txt;
  996. {
  997.    b_txt.IText = txt;
  998.    AutoRequest(wRq,&b_txt,0L,&p_txt,0L,0L,
  999.       (ULONG)(IntuiTextLength(&b_txt)+50L),70L);
  1000. }
  1001.