home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 298.lha / FileReq / FileReq.c < prev    next >
C/C++ Source or Header  |  1980-12-02  |  39KB  |  1,314 lines

  1. /****************************************************************************
  2.  *                                                                          *
  3.  *                              File Requester                              *
  4.  *                                                                          *
  5.  *                   (c) Copyright 1989 Jonathan Potter                     *
  6.  *                                                                          *
  7.  * This program is freely redistributable, although all rights to it remain *
  8.  * with the author. It may be used freely in any program as long as this    *
  9.  * notice remains intact, however, if you do this, please mention the       *
  10.  * author in the program. If you wish to use this in a commercial program   *
  11.  * of any kind, you must register with a $15 donation.                      *
  12.  * Please send donations, bug reports, comments and suggestions to :        *
  13.  *                                                                          *
  14.  *                              Jonathan Potter                             *
  15.  *                              3 William Street                            *
  16.  *                              Clarence Park 5034                          *
  17.  *                              South Australia                             *
  18.  *                              Australia                                   *
  19.  *                                                                          *
  20.  *                         Ph : (08) 2932788  home                          *
  21.  *                                                                          *
  22.  ****************************************************************************/
  23.  
  24. #include <exec/types.h>
  25. #include <exec/memory.h>
  26. #include <intuition/intuitionbase.h>
  27. #include <libraries/dosextens.h>
  28. #include <graphics/gfxbase.h>
  29. #include "filereq.h"
  30.  
  31. #define FILEBASE 1
  32. #define DEVICEBASE 6
  33. #define DRAWERBASE 11
  34. #define FILENAME 16
  35. #define DRAWERNAME 17
  36. #define DEVICENAME 18
  37. #define FILENAMEUP 19
  38. #define DRAWERUP 20
  39. #define DEVICEUP 21
  40. #define FILENAMEDOWN 22
  41. #define DRAWERDOWN 23
  42. #define DEVICEDOWN 24
  43. #define FILENAMEPOS 25
  44. #define DRAWERPOS 26
  45. #define DEVICEPOS 27
  46. #define OKAY 28
  47. #define CANCEL 29
  48. #define RENAME 30
  49. #define DELETE 31
  50. #define MAKEDIR 32
  51. #define PARENT 33
  52. #define SUPEROKAY 34
  53.  
  54. /* Image-Ed Sprite generation */
  55.  
  56. /* Start of Sprite Data */
  57. static USHORT BusySpriteData[]={
  58.     0x0000, 0x0000,
  59.     0x3c00, 0x3c00,
  60.     0x7e00, 0x4200,
  61.     0x7e00, 0x4200,
  62.     0x7e00, 0x4200,
  63.     0x7e00, 0x4200,
  64.     0x7e00, 0x7e00,
  65.     0xff00, 0x8100,
  66.     0xef00, 0x9100,
  67.     0xef00, 0x9100,
  68.     0xe300, 0x9d00,
  69.     0xff00, 0x8100,
  70.     0xff00, 0x8100,
  71.     0x7e00, 0x7e00,
  72.     0x7e00, 0x4200,
  73.     0x7e00, 0x4200,
  74.     0x7eee, 0x42ee,
  75.     0x7eaa, 0x42ee,
  76.     0x3cee, 0x3cee,
  77.     0xffff, 0xffff
  78. };
  79. /* End of Sprite Data */
  80.  
  81. /* End of Image-Ed Sprite generation */
  82.  
  83. /* Image-Ed Image generation */
  84.  
  85. /* Start of Image data */
  86. static USHORT UpArrow1ImageData[]={
  87.     /* Plane 0 */
  88.     0x0040, 0x0000, 0x01f0, 0x0000, 0x07fc, 0x0000, 0x1fff, 0x0000, 
  89.     0x7fff, 0xc000, 0xffff, 0xe000, 0x03f8, 0x0000, 0x03f8, 0x0000, 
  90.     0x03f8, 0x0000, 0x03f8, 0x0000, 
  91.     /* Plane 1 */
  92.     0x0030, 0x0000, 0x000c, 0x0000, 0x0003, 0x0000, 0x0000, 0xc000, 
  93.     0x0000, 0x3000, 0x0000, 0x1800, 0x0006, 0x0000, 0x0006, 0x0000, 
  94.     0x0006, 0x0000, 0x0006, 0x0000
  95. };
  96. /* End of Image data */
  97.  
  98. static struct Image UpArrow1Image={
  99.     0,0, /* LeftEdge, TopEdge */
  100.     21,10,2, /* Width, Height, Depth */
  101.     &UpArrow1ImageData[0], /* ImageData */
  102.     0x3,0x0, /* PlanePick, PlaneOnOff */
  103.     NULL /* Next Image */
  104. };
  105.  
  106. /* Start of Image data */
  107. static USHORT UpArrow2ImageData[]={
  108.     /* Plane 0 */
  109.     0x0010, 0x0000, 0x007c, 0x0000, 0x01ff, 0x0000, 0x07ff, 0xc000, 
  110.     0x1fff, 0xf000, 0x3fff, 0xf800, 0x00fe, 0x0000, 0x00fe, 0x0000, 
  111.     0x00fe, 0x0000, 0x00fe, 0x0000, 
  112.     /* Plane 1 */
  113.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
  114.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
  115.     0x0000, 0x0000, 0x0000, 0x0000
  116. };
  117. /* End of Image data */
  118.  
  119. static struct Image UpArrow2Image={
  120.     0,0, /* LeftEdge, TopEdge */
  121.     21,10,2, /* Width, Height, Depth */
  122.     &UpArrow2ImageData[0], /* ImageData */
  123.     0x3,0x0, /* PlanePick, PlaneOnOff */
  124.     NULL /* Next Image */
  125. };
  126.  
  127. /* Start of Image data */
  128. static USHORT DownArrow1ImageData[]={
  129.     /* Plane 0 */
  130.     0x03f8, 0x0000, 0x03f8, 0x0000, 0x03f8, 0x0000, 0x03f8, 0x0000, 
  131.     0xffff, 0xe000, 0x7fff, 0xc000, 0x1fff, 0x0000, 0x07fc, 0x0000, 
  132.     0x01f0, 0x0000, 0x0040, 0x0000, 
  133.     /* Plane 1 */
  134.     0x0006, 0x0000, 0x0006, 0x0000, 0x0006, 0x0000, 0x0006, 0x0000, 
  135.     0x0000, 0x1800, 0x0000, 0x3000, 0x0000, 0xc000, 0x0003, 0x0000, 
  136.     0x000c, 0x0000, 0x0030, 0x0000
  137. };
  138. /* End of Image data */
  139.  
  140. static struct Image DownArrow1Image={
  141.     0,0, /* LeftEdge, TopEdge */
  142.     21,10,2, /* Width, Height, Depth */
  143.     &DownArrow1ImageData[0], /* ImageData */
  144.     0x3,0x0, /* PlanePick, PlaneOnOff */
  145.     NULL /* Next Image */
  146. };
  147.  
  148. /* Start of Image data */
  149. static USHORT DownArrow2ImageData[]={
  150.     /* Plane 0 */
  151.     0x00fe, 0x0000, 0x00fe, 0x0000, 0x00fe, 0x0000, 0x00fe, 0x0000, 
  152.     0x3fff, 0xf800, 0x1fff, 0xf000, 0x07ff, 0xc000, 0x01ff, 0x0000, 
  153.     0x007c, 0x0000, 0x0010, 0x0000, 
  154.     /* Plane 1 */
  155.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
  156.     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
  157.     0x0000, 0x0000, 0x0000, 0x0000
  158. };
  159. /* End of Image data */
  160.  
  161. static struct Image DownArrow2Image={
  162.     0,0, /* LeftEdge, TopEdge */
  163.     21,10,2, /* Width, Height, Depth */
  164.     &DownArrow2ImageData[0], /* ImageData */
  165.     0x3,0x0, /* PlanePick, PlaneOnOff */
  166.     NULL /* Next Image */
  167. };
  168.  
  169. /* End of Image-Ed Image generation */
  170.  
  171. static struct TextAttr TopazText={
  172.     (STRPTR)"topaz.font",8,0,0};
  173.  
  174. static char filenamebuffer[32], drawernamebuffer[236], devicenamebuffer[32];
  175. static char filetextbuffer[5][16], drawertextbuffer[5][16], devicetextbuffer[5][16];
  176.  
  177. static short border1_xy[]={
  178.     -1,-1,120,-1,120,40,-1,40,-1,-1};
  179. static struct Border border1={
  180.     0,0,2,0,JAM1,5,border1_xy,NULL};
  181. static short border2_xy[]={
  182.      -1,-1,120,-1,120,8,-1,8,-1,-1};
  183. static struct Border border2={
  184.     0,0,2,0,JAM1,5,border2_xy,NULL};
  185.  
  186. static struct PropInfo
  187.     filenameprop={AUTOKNOB|FREEVERT,0,0,0,0x1000},
  188.     drawerprop={AUTOKNOB|FREEVERT,0,0,0,0x1000},
  189.     deviceprop={AUTOKNOB|FREEVERT,0,0,0,0x1000};
  190.  
  191. static struct Image filenameimage, drawerimage, deviceimage;
  192.  
  193. static struct StringInfo
  194.     filenamesinfo={(STRPTR)filenamebuffer,NULL,0,32,0},
  195.     drawernamesinfo={(STRPTR)drawernamebuffer,NULL,0,236,0},
  196.     devicenamesinfo={(STRPTR)devicenamebuffer,NULL,0,32,0};
  197.  
  198. static struct IntuiText
  199.     filetext[5]={
  200.     {1,0,JAM2,0,0,&TopazText,(STRPTR)filetextbuffer[0],NULL},
  201.     {1,0,JAM2,0,0,&TopazText,(STRPTR)filetextbuffer[1],NULL},
  202.     {1,0,JAM2,0,0,&TopazText,(STRPTR)filetextbuffer[2],NULL},
  203.     {1,0,JAM2,0,0,&TopazText,(STRPTR)filetextbuffer[3],NULL},
  204.     {1,0,JAM2,0,0,&TopazText,(STRPTR)filetextbuffer[4],NULL}},
  205.     drawertext[5]={
  206.     {1,0,JAM2,0,0,&TopazText,(STRPTR)drawertextbuffer[0],NULL},
  207.     {1,0,JAM2,0,0,&TopazText,(STRPTR)drawertextbuffer[1],NULL},
  208.     {1,0,JAM2,0,0,&TopazText,(STRPTR)drawertextbuffer[2],NULL},
  209.     {1,0,JAM2,0,0,&TopazText,(STRPTR)drawertextbuffer[3],NULL},
  210.     {1,0,JAM2,0,0,&TopazText,(STRPTR)drawertextbuffer[4],NULL}},
  211.     devicetext[5]={
  212.     {1,0,JAM2,0,0,&TopazText,(STRPTR)devicetextbuffer[0],NULL},
  213.     {1,0,JAM2,0,0,&TopazText,(STRPTR)devicetextbuffer[1],NULL},
  214.     {1,0,JAM2,0,0,&TopazText,(STRPTR)devicetextbuffer[2],NULL},
  215.     {1,0,JAM2,0,0,&TopazText,(STRPTR)devicetextbuffer[3],NULL},
  216.     {1,0,JAM2,0,0,&TopazText,(STRPTR)devicetextbuffer[4],NULL}},
  217.     filenametext={
  218.         3,1,JAM2,44,-54,&TopazText,(UBYTE *)"File",NULL},
  219.     drawernametext={
  220.         3,1,JAM2,36,-54,&TopazText,(UBYTE *)"Drawer",NULL},
  221.     devicenametext={
  222.         3,1,JAM2,36,-54,&TopazText,(UBYTE *)"Volume",NULL},
  223.     parenttext={
  224.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"    PARENT     ",NULL},
  225.     okaytext={
  226.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"     OKAY      ",NULL},
  227.     canceltext={
  228.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"    CANCEL     ",NULL},
  229.     renametext={
  230.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"    RENAME     ",NULL},
  231.     deletetext={
  232.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"    DELETE     ",NULL},
  233.     makedirtext={
  234.         3,2,JAM2,0,0,&TopazText,(UBYTE *)"   MAKE DIR    ",NULL};
  235.  
  236. static struct Gadget
  237.     filegadget[5]={
  238.     {&filegadget[1],10,23,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border1,NULL,
  239.     &filetext[0],NULL,NULL,FILEBASE,NULL},
  240.     {&filegadget[2],10,31,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  241.     &filetext[1],NULL,NULL,FILEBASE+1,NULL},
  242.     {&filegadget[3],10,39,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  243.     &filetext[2],NULL,NULL,FILEBASE+2,NULL},
  244.     {&filegadget[4],10,47,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  245.     &filetext[3],NULL,NULL,FILEBASE+3,NULL},
  246.     {NULL,10,55,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  247.     &filetext[4],NULL,NULL,FILEBASE+4,NULL}},
  248.     devicegadget[5]={
  249.     {&devicegadget[1],10,90,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border1,NULL,
  250.     &devicetext[0],NULL,NULL,DEVICEBASE,NULL},
  251.     {&devicegadget[2],10,98,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  252.     &devicetext[1],NULL,NULL,DEVICEBASE+1,NULL},
  253.     {&devicegadget[3],10,106,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  254.     &devicetext[2],NULL,NULL,DEVICEBASE+2,NULL},
  255.     {&devicegadget[4],10,114,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  256.     &devicetext[3],NULL,NULL,DEVICEBASE+3,NULL},
  257.     {&filegadget[0],10,122,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  258.     &devicetext[4],NULL,NULL,DEVICEBASE+4,NULL}},
  259.     drawergadget[5]={
  260.     {&drawergadget[1],159,23,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border1,NULL,
  261.     &drawertext[0],NULL,NULL,DRAWERBASE,NULL},
  262.     {&drawergadget[2],159,31,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  263.     &drawertext[1],NULL,NULL,DRAWERBASE+1,NULL},
  264.     {&drawergadget[3],159,39,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  265.     &drawertext[2],NULL,NULL,DRAWERBASE+2,NULL},
  266.     {&drawergadget[4],159,47,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  267.     &drawertext[3],NULL,NULL,DRAWERBASE+3,NULL},
  268.     {&devicegadget[0],159,55,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,NULL,NULL,
  269.     &drawertext[4],NULL,NULL,DRAWERBASE+4,NULL}},
  270.     filenamegadget={
  271.         &drawergadget[0],10,67,120,8,GADGHCOMP,RELVERIFY|TOGGLESELECT,STRGADGET,
  272.         (APTR)&border2,NULL,&filenametext,NULL,(APTR)&filenamesinfo,FILENAME,NULL},
  273.     drawernamegadget={
  274.         &filenamegadget,159,67,120,8,GADGHCOMP,RELVERIFY|TOGGLESELECT,STRGADGET,
  275.         (APTR)&border2,NULL,&drawernametext,NULL,(APTR)&drawernamesinfo,DRAWERNAME,NULL},
  276.     devicenamegadget={
  277.         &drawernamegadget,10,134,120,8,GADGHCOMP,RELVERIFY|TOGGLESELECT,STRGADGET,
  278.         (APTR)&border2,NULL,&devicenametext,NULL,(APTR)&devicenamesinfo,DEVICENAME,NULL},
  279.     filenameupgadget={
  280.         &devicenamegadget,134,23,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  281.         (APTR)&UpArrow1Image,(APTR)&UpArrow2Image,NULL,NULL,NULL,FILENAMEUP,NULL},
  282.     drawerupgadget={
  283.         &filenameupgadget,283,23,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  284.         (APTR)&UpArrow1Image,(APTR)&UpArrow2Image,NULL,NULL,NULL,DRAWERUP,NULL},
  285.     deviceupgadget={
  286.         &drawerupgadget,134,90,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  287.         (APTR)&UpArrow1Image,(APTR)&UpArrow2Image,NULL,NULL,NULL,DEVICEUP,NULL},
  288.     filedowngadget={
  289.         &deviceupgadget,134,65,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  290.         (APTR)&DownArrow1Image,(APTR)&DownArrow2Image,NULL,NULL,NULL,FILENAMEDOWN,NULL},
  291.     drawerdowngadget={
  292.         &filedowngadget,283,65,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  293.         (APTR)&DownArrow1Image,(APTR)&DownArrow2Image,NULL,NULL,NULL,DRAWERDOWN,NULL},
  294.     devicedowngadget={
  295.         &drawerdowngadget,134,132,21,10,GADGHIMAGE|GADGIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,
  296.         (APTR)&DownArrow1Image,(APTR)&DownArrow2Image,NULL,NULL,NULL,DEVICEDOWN,NULL},
  297.     filenamepropgadget={
  298.         &devicedowngadget,134,34,21,30,GADGHCOMP,GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,PROPGADGET,
  299.         (APTR)&filenameimage,NULL,NULL,NULL,(APTR)&filenameprop,FILENAMEPOS,NULL},
  300.     drawerpropgadget={
  301.         &filenamepropgadget,283,34,21,30,GADGHCOMP,GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,PROPGADGET,
  302.         (APTR)&drawerimage,NULL,NULL,NULL,(APTR)&drawerprop,DRAWERPOS,NULL},
  303.     devicepropgadget={
  304.         &drawerpropgadget,134,101,21,30,GADGHCOMP,GADGIMMEDIATE|FOLLOWMOUSE|RELVERIFY,PROPGADGET,
  305.         (APTR)&deviceimage,NULL,NULL,NULL,(APTR)&deviceprop,DEVICEPOS,NULL},
  306.     parentgadget={
  307.         &devicepropgadget,159,79,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  308.         &parenttext,NULL,NULL,PARENT,NULL},
  309.     okaygadget={
  310.         &parentgadget,159,90,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  311.         &okaytext,NULL,NULL,OKAY,NULL},
  312.     cancelgadget={
  313.         &okaygadget,159,101,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  314.         &canceltext,NULL,NULL,CANCEL,NULL},
  315.     renamegadget={
  316.         &cancelgadget,159,112,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  317.         &renametext,NULL,NULL,RENAME,NULL},
  318.     deletegadget={
  319.         &renamegadget,159,123,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  320.         &deletetext,NULL,NULL,DELETE,NULL},
  321.     makedirgadget={
  322.         &deletegadget,159,134,120,8,GADGHCOMP,RELVERIFY,BOOLGADGET,(APTR)&border2,NULL,
  323.         &makedirtext,NULL,NULL,MAKEDIR,NULL};
  324.  
  325. static struct NewWindow fr_window={
  326.     8,25,311,147,1,3,
  327.     GADGETUP|GADGETDOWN|MOUSEMOVE|MOUSEBUTTONS|DISKINSERTED|DISKREMOVED,
  328.     SMART_REFRESH|NOCAREREFRESH|ACTIVATE|RMBTRAP,
  329.     NULL,NULL,(STRPTR)"File request",NULL,NULL,0,0,0,0,CUSTOMSCREEN};
  330.  
  331. static struct Window *fr_Window;
  332. static struct IntuiMessage *fr_Msg;
  333. extern struct IntuitionBase *IntuitionBase;
  334. extern struct GfxBase *GfxBase;
  335. extern struct DosLibrary *DosBase;
  336.  
  337. static struct direntry {
  338.     struct direntry *next;
  339.     char name[35];
  340. };
  341. static struct direntry 
  342.     *FirstFileEntry, *FileEntry,
  343.     *FirstDrawerEntry, *DrawerEntry,
  344.     *FirstDeviceEntry, *DeviceEntry;
  345.  
  346. static int deviceentries=0, fileentries=0, drawerentries=0;
  347. static int deviceoffset=0, fileoffset=0, draweroffset=0;
  348. static int olddeviceoffset=-1, oldfileoffset=-1, olddraweroffset=-1;
  349. static char *nullstring="               ";
  350.  
  351. static BOOL SortOn;
  352.  
  353. file_request(dest_scr,hail,x,y,device,directory,filename,so)
  354. struct Screen *dest_scr;
  355. char *hail;
  356. int x,y;
  357. char *device, *directory, *filename;
  358. BOOL so;
  359. {
  360.     int Class, Code, GadgetID, i;
  361.     SortOn=so;
  362.     if (!IntuitionBase) return(NO_INTUITION);
  363.     if (!GfxBase) return(NO_GRAPHICS);
  364.     if (!DosBase) return(NO_DOS);
  365.     if (!directory) return(NO_DIRECTORY);
  366.     if (!filename) return(NO_FILENAME);
  367.     if (!device) return(NO_DEVICE);
  368.     if (!dest_scr) fr_window.Type=WBENCHSCREEN;
  369.     else fr_window.Screen=dest_scr;
  370.     if (x>-1 && fr_window.Screen->Width>=x+fr_window.Width) fr_window.LeftEdge=x;
  371.     if (y>-1 && fr_window.Screen->Height>=y+fr_window.Height) fr_window.TopEdge=y;
  372.     if (hail) fr_window.Title=hail;
  373.     strncpy(filenamebuffer,filename,32);
  374.     strncpy(drawernamebuffer,directory,236);
  375.     strncpy(devicenamebuffer,device,32);
  376.     if (strlen(devicenamebuffer)==0) strcpy(devicenamebuffer,":");
  377.     fr_Window=(struct Window *) OpenWindow(&fr_window);
  378.     if (!fr_Window) return(OPENWINDOW_FAILED);
  379.     SetAPen(fr_Window->RPort,1);
  380.     RectFill(fr_Window->RPort,3,11,307,144);
  381.     SetAPen(fr_Window->RPort,0);
  382.     RectFill(fr_Window->RPort,10,90,129,129);
  383.     RectFill(fr_Window->RPort,10,23,129,62);
  384.     RectFill(fr_Window->RPort,159,23,278,62);
  385.     AddGList(fr_Window,&makedirgadget,-1,-1,35,NULL);
  386.     RefreshGList(&makedirgadget,fr_Window,NULL,-1);
  387.     SetAPen(fr_Window->RPort,1);
  388.     ActivateGadget(&filenamegadget,fr_Window,NULL);
  389.     i=get_devicenames();
  390.     if (i==CANCEL) {
  391.         close_req();
  392.         goto quit_req;
  393.     }
  394.     if (i==OKAY || i==SUPEROKAY) {
  395.         close_req();
  396.         goto do_okay;
  397.     }
  398.     i=get_filenames();
  399.     if (i==CANCEL) {
  400.         close_req();
  401.         goto quit_req;
  402.     }
  403.     if (i==OKAY || i==SUPEROKAY) {
  404.         close_req();
  405.         goto do_okay;
  406.     }
  407.     FOREVER {
  408.         Wait(1<<fr_Window->UserPort->mp_SigBit);
  409.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  410.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  411.             if (Class==GADGETDOWN || Class==GADGETUP)
  412.                 GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  413.             ReplyMsg((struct Message *) fr_Msg);
  414.             i=do_idcmp(Class,Code,GadgetID);
  415.             if (i==CANCEL) {
  416.                 close_req();
  417.                 goto quit_req;
  418.                 break;
  419.             }
  420.             if (i==OKAY || i==SUPEROKAY) {
  421.                 close_req();
  422.                 goto do_okay;
  423.             }
  424.         }
  425.     }
  426.     quit_req:
  427.     return(FALSE);
  428.     do_okay:
  429.     strcpy(device,devicenamebuffer);
  430.     strcpy(directory,drawernamebuffer);
  431.     strcpy(filename,filenamebuffer);
  432.     return(TRUE);
  433. }
  434.  
  435. static close_req()
  436. {
  437.     if (fr_Window) CloseWindow(fr_Window);
  438.     deallocate_entries(7);
  439.     return(0);
  440. }
  441.  
  442. static DOSDisk(device)
  443. struct DeviceList *device;
  444. {
  445.     struct MsgPort *port;
  446.     BOOL result;
  447.     struct InfoData *info;
  448.     struct StandardPacket *packet;
  449.  
  450.     result=FALSE;
  451.     info=(struct InfoData *) AllocMem(sizeof(struct InfoData),MEMF_CLEAR);
  452.     packet=(struct StandardPacket *) AllocMem(sizeof(struct StandardPacket),MEMF_CLEAR);
  453.     port=(struct MsgPort *) CreatePort(NULL,0);
  454.     if (port&&info&&packet) {
  455.         packet->sp_Msg.mn_Node.ln_Type=NT_MESSAGE;
  456.         packet->sp_Msg.mn_Node.ln_Name=(char *)&packet->sp_Pkt;
  457.         packet->sp_Msg.mn_ReplyPort=port;
  458.         packet->sp_Pkt.dp_Link=&packet->sp_Msg;
  459.         packet->sp_Pkt.dp_Type=ACTION_DISK_INFO;
  460.         packet->sp_Pkt.dp_Arg1=((LONG)info>>2);
  461.         packet->sp_Pkt.dp_Port=port;
  462.         PutMsg(device->dl_Task,&packet->sp_Msg);
  463.         WaitPort(port);
  464.         if (info->id_DiskType==ID_DOS_DISK) result=TRUE;
  465.     }
  466.     if (port) DeletePort(port);
  467.     if (info) FreeMem(info, sizeof(struct InfoData));
  468.     if (packet) FreeMem(packet, sizeof(struct StandardPacket));
  469.     return(result);
  470. }
  471.  
  472. static get_devicenames()
  473. {
  474.     struct RootNode *rootnode;
  475.     struct DosInfo *dosinfo;
  476.     struct DeviceList *devlist;
  477.     struct FileLock *lock;
  478.     struct InfoData *data;
  479.     struct FileInfoBlock *finfo;
  480.     UBYTE devname[32];
  481.     int Class, Code, GadgetID;
  482.     int ret=0;
  483.  
  484.     FirstDeviceEntry=NULL; DeviceEntry=NULL;
  485.     data=(struct InfoData *)AllocMem(sizeof(struct InfoData),MEMF_CLEAR);
  486.     finfo=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
  487.     rootnode=(struct RootNode *) DosBase->dl_Root;
  488.     dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
  489.  
  490.     Forbid();
  491.     busy();
  492.     devlist=(struct DeviceList *) BADDR(dosinfo->di_DevInfo);
  493.     while (devlist) {
  494.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  495.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  496.             if (Class==GADGETDOWN || Class==GADGETUP)
  497.                 GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  498.             ReplyMsg((struct Message *) fr_Msg);
  499.             if (Class==GADGETUP && do_idtype(GadgetID)) goto defin;
  500.             unbusy();
  501.             ret=do_idcmp(Class,Code,GadgetID);
  502.             busy();
  503.             if (ret==SUPEROKAY) goto fin;
  504.         }
  505.         if (devlist->dl_Type!=DLT_DEVICE || !devlist->dl_Task) {
  506.             devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  507.             continue;
  508.         }
  509.         if (!DOSDisk(devlist)) {
  510.             devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  511.             continue;
  512.         }
  513.         conbstr((BPTR)devlist->dl_Name,devname);
  514.         strcat(devname,":");
  515.         lock=(struct FileLock *) Lock(devname,ACCESS_READ);
  516.         if (lock==NULL) goto fin;
  517.         Info(lock,data);
  518.         Examine(lock,finfo);
  519.         if (FirstDeviceEntry==NULL) {
  520.             FirstDeviceEntry=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  521.             strncpy(FirstDeviceEntry->name,finfo->fib_FileName,32);
  522.             strcat(FirstDeviceEntry->name,":");
  523.             DeviceEntry=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  524.             FirstDeviceEntry->next=DeviceEntry;
  525.             strncpy(DeviceEntry->name,devname,32);
  526.             deviceentries+=2;
  527.         }
  528.         else {
  529.             DeviceEntry->next=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  530.             DeviceEntry=DeviceEntry->next;
  531.             strncpy(DeviceEntry->name,finfo->fib_FileName,32);
  532.             strcat(DeviceEntry->name,":");
  533.             DeviceEntry->next=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  534.             DeviceEntry=DeviceEntry->next;
  535.             strncpy(DeviceEntry->name,devname,32);
  536.             deviceentries+=2;
  537.         }
  538.         UnLock(lock);
  539.         devlist=(struct DeviceList *) BADDR(devlist->dl_Next);
  540.         DeviceEntry->next=NULL;
  541.         DisplayDevices(FALSE);
  542.     }
  543.     goto fin;
  544.     defin:
  545.     unbusy();
  546.     ret=do_idcmp(Class,Code,GadgetID);
  547.     fin:
  548.     Permit();
  549.     if (data) FreeMem(data,sizeof(struct InfoData));
  550.     if (finfo) FreeMem(finfo,sizeof(struct FileInfoBlock));
  551.     if (deviceentries && SortOn) Sort(FirstDeviceEntry,deviceentries);
  552.     olddeviceoffset=-1;
  553.     DisplayDevices(TRUE);
  554.     unbusy();
  555.     return(ret);
  556. }
  557.  
  558. static DisplayDevices(clear)
  559. BOOL clear;
  560. {
  561.     struct direntry *work;
  562.     int a,b;
  563.     if (deviceoffset==olddeviceoffset && clear) return(0);
  564.     olddeviceoffset=deviceoffset;
  565.     if (clear) {
  566.         SetAPen(fr_Window->RPort,0);
  567.         RectFill(fr_Window->RPort,10,90,129,129);
  568.         SetAPen(fr_Window->RPort,1);
  569.     }
  570.     work=FirstDeviceEntry;
  571.     for (a=0;a<deviceoffset;a++) {
  572.         work=work->next;
  573.         if (!work) return(0);
  574.     }
  575.     for (b=0;b<5;b++) {
  576.         strncpy(devicetextbuffer[b],work->name,15);
  577.         if (!work) strncpy(devicetextbuffer[b],nullstring,15);
  578.         work=work->next;
  579.     }
  580.     RefreshGList(&devicegadget[0],fr_Window,NULL,5);
  581. }
  582.  
  583. static conbstr(in,out)
  584. BSTR in;
  585. char *out;
  586. {
  587.     register UBYTE *ch;
  588.     register int len,i;
  589.     ch=(UBYTE *) BADDR(in);
  590.     len=(int) *(ch++);
  591.     len=(len>20)?20:len;
  592.     for (i=0;i<len;i++) out[i]=*(ch++);
  593.     out[i]='\0';
  594.     return(0);
  595. }
  596.  
  597. static get_filenames()
  598. {
  599.     struct FileLock *lock;
  600.     struct FileInfoBlock *finfo;
  601.     int Class, Code, GadgetID;
  602.     int ret;
  603.     char directory[400];
  604.  
  605.     strcpy(directory,devicenamebuffer);
  606.     strcat(directory,drawernamebuffer);
  607.  
  608.     FirstFileEntry=NULL; FirstDrawerEntry=NULL;
  609.     FileEntry=NULL; DrawerEntry=NULL;
  610.     finfo=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR);
  611.     busy();
  612.     Forbid();
  613.     lock=(struct FileLock *) Lock(directory,ACCESS_READ);
  614.     if (lock==NULL) goto fin;
  615.     Examine(lock,finfo);
  616.     while (ExNext(lock,finfo)) {
  617.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  618.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  619.             if (Class==GADGETDOWN || Class==GADGETUP)
  620.                 GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  621.             ReplyMsg((struct Message *) fr_Msg);
  622.             if (Class==GADGETUP && do_idtype(GadgetID)) goto defin;
  623.             unbusy();
  624.             ret=do_idcmp(Class,Code,GadgetID);
  625.             busy();
  626.             if (ret==SUPEROKAY) goto fin;
  627.         }
  628.         if (finfo->fib_DirEntryType>0) {
  629.             if (FirstDrawerEntry==NULL) {
  630.                 FirstDrawerEntry=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  631.                 strncpy(FirstDrawerEntry->name,finfo->fib_FileName,32);
  632.                 DrawerEntry=FirstDrawerEntry;
  633.                 ++drawerentries;
  634.             }
  635.             else {
  636.                 DrawerEntry->next=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  637.                 DrawerEntry=DrawerEntry->next;
  638.                 strncpy(DrawerEntry->name,finfo->fib_FileName,32);
  639.                 ++drawerentries;
  640.             }
  641.             DrawerEntry->next=NULL;
  642.             DisplayDrawers(FALSE);
  643.         }
  644.         else {
  645.             if (FirstFileEntry==NULL) {
  646.                 FirstFileEntry=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  647.                 strncpy(FirstFileEntry->name,finfo->fib_FileName,32);
  648.                 FileEntry=FirstFileEntry;
  649.                 ++fileentries;
  650.             }
  651.             else {
  652.                 FileEntry->next=(struct direntry *) AllocMem((sizeof(struct direntry)),MEMF_CLEAR);
  653.                 FileEntry=FileEntry->next;
  654.                 strncpy(FileEntry->name,finfo->fib_FileName,32);
  655.                 ++fileentries;
  656.             }
  657.             FileEntry->next=NULL;
  658.             DisplayFiles(FALSE);
  659.         }
  660.     }
  661.     defin:
  662.     unbusy();
  663.     ret=do_idcmp(Class,Code,GadgetID);
  664.     busy();
  665.     fin:
  666.     if (lock) UnLock(lock);
  667.     Permit();
  668.     if (finfo) FreeMem(finfo,sizeof(struct FileInfoBlock));
  669.     if (drawerentries && SortOn) Sort(FirstDrawerEntry,drawerentries);
  670.     if (fileentries && SortOn) Sort(FirstFileEntry,fileentries);
  671.     olddraweroffset=-1; oldfileoffset=-1;
  672.     DisplayDrawers(TRUE); DisplayFiles(TRUE);
  673.     unbusy();
  674.     return(ret);
  675. }
  676.  
  677. static DisplayFiles(clear)
  678. BOOL clear;
  679. {
  680.     struct direntry *work;
  681.     int a,b;
  682.     if (fileoffset==oldfileoffset && clear) return(0);
  683.     oldfileoffset=fileoffset;
  684.     if (clear) {
  685.         SetAPen(fr_Window->RPort,0);
  686.         RectFill(fr_Window->RPort,10,23,129,62);
  687.         SetAPen(fr_Window->RPort,1);
  688.     }
  689.     work=FirstFileEntry;
  690.     for (a=0;a<fileoffset;a++) {
  691.         work=work->next;
  692.         if (!work) return(0);
  693.     }
  694.     for (b=0;b<5;b++) {
  695.         strncpy(filetextbuffer[b],work->name,15);
  696.         if (!work) strncpy(filetextbuffer[b],nullstring,15);
  697.         work=work->next;
  698.     }
  699.     RefreshGList(&filegadget[0],fr_Window,NULL,5);
  700. }
  701.  
  702. static DisplayDrawers(clear)
  703. BOOL clear;
  704. {
  705.     struct direntry *work;
  706.     int a,b;
  707.     if (draweroffset==olddraweroffset && clear) return(0);
  708.     olddraweroffset=draweroffset;
  709.     if (clear) {
  710.         SetAPen(fr_Window->RPort,0);
  711.         RectFill(fr_Window->RPort,159,23,278,62);
  712.         SetAPen(fr_Window->RPort,1);
  713.     }
  714.     work=FirstDrawerEntry;
  715.     for (a=0;a<draweroffset;a++) {
  716.         work=work->next;
  717.         if (!work) return(0);
  718.     }
  719.     for (b=0;b<5;b++) {
  720.         strncpy(drawertextbuffer[b],work->name,15);
  721.         if (!work) strncpy(drawertextbuffer[b],nullstring,15);
  722.         work=work->next;
  723.     }
  724.     RefreshGList(&drawergadget[0],fr_Window,NULL,5);
  725. }
  726.  
  727. static deallocate_entries(which)
  728. int which;
  729. {
  730.     struct direntry *work;
  731.     if (which&1) {
  732.         work=FirstDeviceEntry;
  733.         while (work) {
  734.             DeviceEntry=work->next;
  735.             if (work) FreeMem(work,(sizeof(struct direntry)));
  736.             work=DeviceEntry;
  737.         }
  738.         FirstDeviceEntry=NULL; DeviceEntry=NULL;
  739.         deviceentries=0; deviceoffset=0; olddeviceoffset=-1;
  740.     }
  741.     if (which&2) {
  742.         work=FirstDrawerEntry;
  743.         while (work) {
  744.             DrawerEntry=work->next;
  745.             if (work) FreeMem(work,(sizeof(struct direntry)));
  746.             work=DrawerEntry;
  747.         }
  748.         FirstDrawerEntry=NULL; DrawerEntry=NULL;
  749.         drawerentries=0; draweroffset=0; olddraweroffset=-1;
  750.     }
  751.     if (which&4) {
  752.         work=FirstFileEntry;
  753.         while (work) {
  754.             FileEntry=work->next;
  755.             if (work) FreeMem(work,(sizeof(struct direntry)));
  756.             work=FileEntry;
  757.         }
  758.         FirstFileEntry=NULL; FileEntry=NULL;
  759.         fileentries=0; fileoffset=0; oldfileoffset=-1;
  760.     }
  761.     return(0);
  762. }
  763.  
  764. static doposprop(vertpot,wp)
  765. long vertpot;
  766. int wp;
  767. {
  768.     register int i,a;
  769.     if (wp==0) a=deviceentries;
  770.     else if (wp==1) a=drawerentries;
  771.     else a=fileentries;
  772.     i=(a-5)*vertpot/0xffff;
  773.     if (i>(a-5)) i=a-5;
  774.     if (i<0) i=0;
  775.     if (wp==0) {
  776.         deviceoffset=i;
  777.         DisplayDevices(TRUE);
  778.     }
  779.     else if (wp==1) {
  780.         draweroffset=i;
  781.         DisplayDrawers(TRUE);
  782.     }
  783.     else {
  784.         fileoffset=i;
  785.         DisplayFiles(TRUE);
  786.     }
  787.     return(0);
  788. }
  789.  
  790. static getnewdevice()
  791. {
  792.     if (strlen(devicenamebuffer)==0) {
  793.         strcpy(devicenamebuffer,":");
  794.         RefreshGList(&devicenamegadget,fr_Window,NULL,1);
  795.     }
  796.     if (strlen(devicenamebuffer)>0) {
  797.         if (devicenamebuffer[(strlen(devicenamebuffer)-1)]!=':') {
  798.             strcat(devicenamebuffer,":");
  799.             RefreshGList(&devicenamegadget,fr_Window,NULL,1);
  800.         }
  801.     }
  802.     deallocate_entries(6);
  803.     drawernamebuffer[0]='\0';
  804.     RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  805.     DisplayDrawers(TRUE);
  806.     DisplayFiles(TRUE);
  807.     return(get_filenames());
  808. }
  809.  
  810. static getnewdrawer()
  811. {
  812.     if (strlen(drawernamebuffer)>0) {
  813.         if (drawernamebuffer[(strlen(drawernamebuffer)-1)]!='/') {
  814.             strcat(drawernamebuffer,"/");
  815.             RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  816.         }
  817.     }
  818.     ActivateGadget(&filenamegadget,fr_Window,NULL);
  819.     deallocate_entries(6);
  820.     DisplayFiles(TRUE);
  821.     DisplayDrawers(TRUE);
  822.     return(get_filenames());
  823. }
  824.  
  825. static do_parent()
  826. {
  827.     int i,b;
  828.     if (strlen(drawernamebuffer)==0) return(0);
  829.     i=strlen(drawernamebuffer)-1;
  830.     if (drawernamebuffer[i]=='/') --i;
  831.     for (b=i;b>-1;b--) if (drawernamebuffer[b]=='/') break;
  832.     if (b<0) b=0;
  833.     drawernamebuffer[b]='\0';
  834.     RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  835.     return(getnewdrawer());
  836. }
  837.  
  838. static getnew_drawer(which)
  839. int which;
  840. {
  841.     int i,b;
  842.     struct direntry *work;
  843.     i=draweroffset+which;
  844.     work=FirstDrawerEntry;
  845.     if (!work) return(FALSE);
  846.     for (b=0;b<i;b++) work=work->next;
  847.     if (!work) return(FALSE);
  848.     if (strlen(drawernamebuffer)+strlen(work->name)>236) return(FALSE);
  849.     strcat(drawernamebuffer,work->name);
  850.     RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  851.     return(getnewdrawer());
  852. }
  853.  
  854. static getnew_device(which)
  855. int which;
  856. {
  857.     int i,b;
  858.     struct direntry *work;
  859.     i=deviceoffset+which;
  860.     work=FirstDeviceEntry;
  861.     if (!work) return(FALSE);
  862.     for (b=0;b<i;b++) work=work->next;
  863.     if (!work) return(FALSE);
  864.     strcpy(devicenamebuffer,work->name);
  865.     RefreshGList(&devicenamegadget,fr_Window,NULL,1);
  866.     return(getnewdevice());
  867. }
  868.  
  869. static getnew_file(which)
  870. int which;
  871. {
  872.     int i,b;
  873.     struct direntry *work;
  874.     i=fileoffset+which;
  875.     work=FirstFileEntry;
  876.     if (!work) return(FALSE);
  877.     for (b=0;b<i;b++) work=work->next;
  878.     if (!work) return(FALSE);
  879.     if ((strcmp(filenamebuffer,work->name))==0) return(SUPEROKAY);
  880.     strcpy(filenamebuffer,work->name);
  881.     RefreshGList(&filenamegadget,fr_Window,NULL,1);
  882.     return(FALSE);
  883. }
  884.  
  885. static do_idtype(GadgetID)
  886. int GadgetID;
  887. {
  888.     switch (GadgetID) {
  889.         case CANCEL:
  890.         case OKAY:
  891.         case FILENAME:
  892.         case DRAWERNAME:
  893.         case DEVICENAME:
  894.         case DRAWERBASE:
  895.         case DRAWERBASE+1:
  896.         case DRAWERBASE+2:
  897.         case DRAWERBASE+3:
  898.         case DRAWERBASE+4:
  899.         case DEVICEBASE:
  900.         case DEVICEBASE+1:
  901.         case DEVICEBASE+2:
  902.         case DEVICEBASE+3:
  903.         case DEVICEBASE+4:
  904.         case RENAME:
  905.         case DELETE:
  906.         case MAKEDIR:
  907.         case PARENT:
  908.             return(TRUE);
  909.         default:
  910.             return(FALSE);
  911.     }
  912. }
  913.  
  914. static do_idcmp(Class,Code,GadgetID)
  915. int Class, Code, GadgetID;
  916. {
  917.     int ret;
  918.     fr_Msg=NULL;
  919.     switch (Class) {
  920.         case GADGETDOWN:
  921.         case MOUSEMOVE:
  922.             switch (GadgetID) {
  923.                 case FILENAMEPOS:
  924.                     doposprop((filenameprop.VertPot),2);
  925.                     break;
  926.                 case DRAWERPOS:
  927.                     doposprop((drawerprop.VertPot),1);
  928.                     break;
  929.                 case DEVICEPOS:
  930.                     doposprop((deviceprop.VertPot),0);
  931.                     break;
  932.                 case FILENAMEUP:
  933.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  934.                         if (fileoffset==0) break;
  935.                         --fileoffset;
  936.                         DisplayFiles(TRUE);
  937.                         doprops(&filenamepropgadget,fileentries,fileoffset);
  938.                     }
  939.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  940.                     break;
  941.                 case FILENAMEDOWN:
  942.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  943.                         if (fileoffset>=fileentries-5) break;
  944.                         ++fileoffset;
  945.                         DisplayFiles(TRUE);
  946.                         doprops(&filenamepropgadget,fileentries,fileoffset);
  947.                     }
  948.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  949.                     break;
  950.                 case DRAWERUP:
  951.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  952.                         if (draweroffset==0) break;
  953.                         --draweroffset;
  954.                         DisplayDrawers(TRUE);
  955.                         doprops(&drawerpropgadget,drawerentries,draweroffset);
  956.                     }
  957.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  958.                     break;
  959.                 case DRAWERDOWN:
  960.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  961.                         if (draweroffset>=drawerentries-5) break;
  962.                         ++draweroffset;
  963.                         DisplayDrawers(TRUE);
  964.                         doprops(&drawerpropgadget,drawerentries,draweroffset);
  965.                     }
  966.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  967.                     break;
  968.                 case DEVICEUP:
  969.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  970.                         if (deviceoffset==0) break;
  971.                         --deviceoffset;
  972.                         DisplayDevices(TRUE);
  973.                         doprops(&devicepropgadget,deviceentries,deviceoffset);
  974.                     }
  975.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  976.                     break;
  977.                 case DEVICEDOWN:
  978.                     while (!(fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort))) {
  979.                         if (deviceoffset>=deviceentries-5) break;
  980.                         ++deviceoffset;
  981.                         DisplayDevices(TRUE);
  982.                         doprops(&devicepropgadget,deviceentries,deviceoffset);
  983.                     }
  984.                     if (fr_Msg) ReplyMsg((struct Message *) fr_Msg);
  985.                     break;
  986.             }
  987.             if (GadgetID!=FILENAMEPOS && GadgetID!=DRAWERPOS && GadgetID!=DEVICEPOS)
  988.                 ActivateGadget(&filenamegadget,fr_Window,NULL);
  989.             break;
  990.         case GADGETUP:
  991.             switch (GadgetID) {
  992.                 case CANCEL:
  993.                     ret=CANCEL;
  994.                     break;
  995.                 case OKAY:
  996.                     ret=OKAY;
  997.                     break;
  998.                 case DRAWERNAME:
  999.                     ret=getnewdrawer();
  1000.                     break;
  1001.                 case DEVICENAME:
  1002.                     ActivateGadget(&drawernamegadget,fr_Window,NULL);
  1003.                     ret=getnewdevice();
  1004.                     break;
  1005.                 case FILENAME:
  1006.                     ret=OKAY;
  1007.                     break;
  1008.                 case DRAWERBASE:
  1009.                 case DRAWERBASE+1:
  1010.                 case DRAWERBASE+2:
  1011.                 case DRAWERBASE+3:
  1012.                 case DRAWERBASE+4:
  1013.                     ret=getnew_drawer((GadgetID-DRAWERBASE));
  1014.                     break;
  1015.                 case DEVICEBASE:
  1016.                 case DEVICEBASE+1:
  1017.                 case DEVICEBASE+2:
  1018.                 case DEVICEBASE+3:
  1019.                 case DEVICEBASE+4:
  1020.                     ActivateGadget(&drawernamegadget,fr_Window,NULL);
  1021.                     ret=getnew_device((GadgetID-DEVICEBASE));
  1022.                     break;
  1023.                 case FILEBASE:
  1024.                 case FILEBASE+1:
  1025.                 case FILEBASE+2:
  1026.                 case FILEBASE+3:
  1027.                 case FILEBASE+4:
  1028.                     ret=getnew_file((GadgetID-FILEBASE));
  1029.                     break;
  1030.                 case PARENT:
  1031.                     do_parent();
  1032.                     ret=PARENT;
  1033.                     break;
  1034.                 case DELETE:
  1035.                     do_delete();
  1036.                     ret=DELETE;
  1037.                     break;
  1038.                 case RENAME:
  1039.                     do_rename();
  1040.                     ret=RENAME;
  1041.                     break;
  1042.                 case MAKEDIR:
  1043.                     do_makedir();
  1044.                     ret=MAKEDIR;
  1045.                     break;
  1046.             }
  1047.             switch (GadgetID) {
  1048.                 case DEVICENAME:
  1049.                 case DEVICEBASE:
  1050.                 case DEVICEBASE+1:
  1051.                 case DEVICEBASE+2:
  1052.                 case DEVICEBASE+3:
  1053.                 case DEVICEBASE+4:
  1054.                     ActivateGadget(&drawernamegadget,fr_Window,NULL);
  1055.                     break;
  1056.                 default:
  1057.                 ActivateGadget(&filenamegadget,fr_Window,NULL);
  1058.             }
  1059.             return(ret);
  1060.             break;
  1061.         case DISKINSERTED:
  1062.         case DISKREMOVED:
  1063.             deallocate_entries(1);
  1064.             olddeviceoffset=-1;
  1065.             DisplayDevices(TRUE);
  1066.             get_devicenames();
  1067.             break;
  1068.         default:
  1069.             if (!GadgetID) ActivateGadget(&filenamegadget,fr_Window,NULL);
  1070.             break;
  1071.     }
  1072.     return(GadgetID);
  1073. }
  1074.  
  1075. static Sort(which,count)
  1076. struct direntry *which;
  1077. int count;
  1078. {
  1079.     register int gap,i,j;
  1080.     register struct direntry *file1, *file2;
  1081.     char *hail;
  1082.     hail=fr_Window->Title;
  1083.     SetWindowTitles(fr_Window,"Please wait... Sorting...",-1);
  1084.     busy();
  1085.     for (gap=count/2;gap>0;gap/=2)
  1086.         for (i=gap;i<count;i++)
  1087.             for (j=i-gap;j>=0;j-=gap) {
  1088.                 file1=(struct direntry *) getentry(j,which);
  1089.                 file2=(struct direntry *) getentry((j+gap),which);
  1090.                 if (mystrcmp(file1->name,file2->name)<=0) break;
  1091. #ifdef LATTICE
  1092.                 swmem(file1->name,file2->name,32);
  1093. #else
  1094.                 swapmem(file1->name,file2->name,32);
  1095. #endif
  1096.             }
  1097.     SetWindowTitles(fr_Window,hail,-1);
  1098.     unbusy();
  1099.     return(0);
  1100. }
  1101.  
  1102. static getentry(h,which)
  1103. int h;
  1104. struct direntry *which;
  1105. {
  1106.     struct direntry *work;
  1107.     register int a;
  1108.     work=which;
  1109.     for (a=0;a<h;a++) work=work->next;
  1110.     return(work);
  1111. }
  1112.  
  1113. static mystrcmp(s,t)
  1114. char s[], t[];
  1115. {
  1116.     register int i;
  1117.     i=0;
  1118.     while (toupper(s[i])==toupper(t[i]))
  1119.         if (s[i++]=='\0') return(0);
  1120.     return(toupper(s[i])-toupper(t[i]));
  1121. }
  1122.  
  1123. static doprops(gadget,entries,offset)
  1124. struct Gadget *gadget;
  1125. register int entries;
  1126. register int offset;
  1127. {
  1128.     register long vertpot;
  1129.     struct PropInfo *pinfo;
  1130.     if (entries<=5) return(0);
  1131.     vertpot=(offset*0xffff)/(entries-5);
  1132.     pinfo=(struct PropInfo *)&(gadget->SpecialInfo);
  1133.     if (vertpot==pinfo->VertPot) return(0);
  1134.     NewModifyProp(gadget,fr_Window,NULL,AUTOKNOB|FREEVERT,0,vertpot,0,0x1000,1);
  1135. }
  1136.  
  1137. static do_delete()
  1138. {
  1139.     int Class, Code, GadgetID, i;
  1140.     char file[400];
  1141.     struct direntry *work, *work1;
  1142.     char *hail;
  1143.     if (strlen(filenamebuffer)==0) return(0);
  1144.     hail=fr_Window->Title;
  1145.     SetWindowTitles(fr_Window,"OKAY to confirm, or CANCEL to cancel",-1);
  1146.     FOREVER {
  1147.         Wait(1<<fr_Window->UserPort->mp_SigBit);
  1148.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  1149.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  1150.             if (Class==GADGETUP) GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  1151.             ReplyMsg((struct Message *) fr_Msg);
  1152.             if (Class!=GADGETUP) break;
  1153.             if (GadgetID!=OKAY && GadgetID!=CANCEL) break;
  1154.             if (GadgetID==CANCEL) {
  1155.                 SetWindowTitles(fr_Window,hail,-1);
  1156.                 return(FALSE);
  1157.             }
  1158.             busy();
  1159.             SetWindowTitles(fr_Window,"Please wait...",-1);
  1160.             strcpy(file,devicenamebuffer);
  1161.             strcat(file,drawernamebuffer);
  1162.             strcat(file,filenamebuffer);
  1163.             i=DeleteFile(file);
  1164.             if (!i) {
  1165.                 SetWindowTitles(fr_Window,"Delete failed.",-1);
  1166.                 DisplayBeep(NULL);
  1167.                 Delay(50);
  1168.             }
  1169.             if (i) {
  1170.                 work=FirstFileEntry;
  1171.                 strcpy(file,filenamebuffer);
  1172.                 strcpy(filenamebuffer,"");
  1173.                 RefreshGList(&filenamegadget,fr_Window,NULL,1);
  1174.                 --fileentries;
  1175.                 while ((strcmp(work->name,file)!=0)) {
  1176.                     work1=work;
  1177.                     work=work->next;
  1178.                     if (!work) break;
  1179.                 }
  1180.                 if (work->next) {
  1181.                     if (work1) work1->next=work->next;
  1182.                     if (work==FirstFileEntry) FirstFileEntry=work->next;
  1183.                 }
  1184.                 else {
  1185.                     if (work1) work1->next=NULL;
  1186.                     if (work==FirstFileEntry) FirstFileEntry=NULL;
  1187.                 }
  1188.                 if (work) FreeMem(work,(sizeof(struct direntry)));
  1189.                 oldfileoffset=-1;
  1190.                 if (fileoffset>0) --fileoffset;
  1191.                 DisplayFiles(TRUE);
  1192.                 doprops(&filenamepropgadget,fileentries,fileoffset);
  1193.             }
  1194.             SetWindowTitles(fr_Window,hail,-1);
  1195.             unbusy();
  1196.             return(i);
  1197.         }
  1198.     }
  1199. }
  1200.  
  1201. static do_rename()
  1202. {
  1203.     int Class, Code, GadgetID, i;
  1204.     char file1[400], file2[400], file[32];
  1205.     struct direntry *work, *work1;
  1206.     char *hail;
  1207.     if (strlen(filenamebuffer)==0) return(0);
  1208.     hail=fr_Window->Title;
  1209.     SetWindowTitles(fr_Window,"Enter new name and choose OKAY",-1);
  1210.     strcpy(file,filenamebuffer);
  1211.     strcpy(file1,devicenamebuffer);
  1212.     strcat(file1,drawernamebuffer);
  1213.     strcat(file1,filenamebuffer);
  1214.     ActivateGadget(&filenamegadget,fr_Window,NULL);
  1215.     FOREVER {
  1216.         Wait(1<<fr_Window->UserPort->mp_SigBit);
  1217.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  1218.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  1219.             if (Class==GADGETUP) GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  1220.             ReplyMsg((struct Message *) fr_Msg);
  1221.             if (Class!=GADGETUP) break;
  1222.             if (GadgetID!=OKAY) break;
  1223.             busy();
  1224.             SetWindowTitles(fr_Window,"Please wait...",-1);
  1225.             strcpy(file2,devicenamebuffer);
  1226.             strcat(file2,drawernamebuffer);
  1227.             strcat(file2,filenamebuffer);
  1228.             i=Rename(file1,file2);
  1229.             if (!i) {
  1230.                 SetWindowTitles(fr_Window,"Rename failed.",-1);
  1231.                 DisplayBeep(NULL);
  1232.                 Delay(50);
  1233.                 strcpy(filenamebuffer,file);
  1234.                 RefreshGList(&filenamegadget,fr_Window,NULL,1);
  1235.             }
  1236.             if (i) {
  1237.                 work=FirstFileEntry;
  1238.                 while ((strcmp(work->name,file)!=0)) {
  1239.                     work1=work;
  1240.                     work=work->next;
  1241.                     if (!work) break;
  1242.                 }
  1243.                 strcpy(work->name,filenamebuffer);
  1244.                 oldfileoffset=-1;
  1245.                 if (SortOn) Sort(FirstFileEntry,fileentries);
  1246.                 DisplayFiles(TRUE);
  1247.                 doprops(&filenamepropgadget,fileentries,fileoffset);
  1248.             }
  1249.             SetWindowTitles(fr_Window,hail,-1);
  1250.             unbusy();
  1251.             return(i);
  1252.         }
  1253.     }
  1254. }
  1255.  
  1256. static do_makedir()
  1257. {
  1258.     int Class, Code, GadgetID;
  1259.     char file1[400], file2[400];
  1260.     struct FileLock *i;
  1261.     char *hail;
  1262.     hail=fr_Window->Title;
  1263.     SetWindowTitles(fr_Window,"Enter new dir. name, OKAY or CANCEL",-1);
  1264.     strcpy(file1,drawernamebuffer);
  1265.     ActivateGadget(&drawernamegadget,fr_Window,NULL);
  1266.     FOREVER {
  1267.         Wait(1<<fr_Window->UserPort->mp_SigBit);
  1268.         while (fr_Msg=(struct IntuiMessage *) GetMsg(fr_Window->UserPort)) {
  1269.             Class=fr_Msg->Class; Code=fr_Msg->Code;
  1270.             if (Class==GADGETUP) GadgetID=((struct Gadget *) fr_Msg->IAddress)->GadgetID;
  1271.             ReplyMsg((struct Message *) fr_Msg);
  1272.             if (Class!=GADGETUP) break;
  1273.             if (GadgetID!=OKAY && GadgetID!=CANCEL) break;
  1274.             if (GadgetID==CANCEL) {
  1275.                 strcpy(drawernamebuffer,file1);
  1276.                 RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  1277.                 SetWindowTitles(fr_Window,hail,-1);
  1278.                 return(FALSE);
  1279.             }
  1280.             busy();
  1281.             SetWindowTitles(fr_Window,"Please wait...",-1);
  1282.             strcpy(file2,devicenamebuffer);
  1283.             strcat(file2,drawernamebuffer);
  1284.             i=(struct FileLock *) CreateDir(file2);
  1285.             if (!i) {
  1286.                 SetWindowTitles(fr_Window,"Make Dir failed.",-1);
  1287.                 DisplayBeep(NULL);
  1288.                 Delay(50);
  1289.                 strcpy(drawernamebuffer,file1);
  1290.                 RefreshGList(&drawernamegadget,fr_Window,NULL,1);
  1291.             }
  1292.             if (i) {
  1293.                 UnLock(i);
  1294.                 getnewdrawer();
  1295.             }
  1296.             SetWindowTitles(fr_Window,hail,-1);
  1297.             unbusy();
  1298.             return(TRUE);
  1299.         }
  1300.     }
  1301. }
  1302.  
  1303. static busy()
  1304. {
  1305.     SetPointer(fr_Window,&BusySpriteData[0],18,16,0,0);
  1306.     return(0);
  1307. }
  1308.  
  1309. static unbusy()
  1310. {
  1311.     ClearPointer(fr_Window);
  1312.     return(0);
  1313. }
  1314.