home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 191.lha / ARequester / req1.c < prev    next >
C/C++ Source or Header  |  1988-04-28  |  19KB  |  872 lines

  1. #include <intuition/intuition.h>
  2. #include <libraries/dosextens.h>
  3. #include <exec/memory.h>
  4. #include "reqdir.h"
  5. #include "req.h"
  6.  
  7. typedef struct
  8. {
  9. short x0, y0, x1, y1;
  10. } Rect;
  11. typedef struct
  12. {
  13. char *line;
  14. long len, x, y, color;
  15. } Txt;
  16.  
  17. typedef struct
  18. {
  19. struct TextFont *font;
  20. struct Window *window;
  21. struct RastPort *rp;
  22. struct MsgPort *port;
  23. PFV func;
  24. struct Gadget *gad;
  25. short countdown;
  26. short gfx_open;
  27. short intui_open;
  28. short finished;
  29. UWORD top;
  30. UWORD left;
  31. UWORD width;
  32. UWORD most;
  33. UBYTE ubuf[512];
  34. UBYTE pbuf[512];
  35. UBYTE fbuf[512];
  36. char scr_buf[6][28];
  37. UBYTE *buffer;
  38. Entry **ent;
  39. long bufsize;
  40. long max_entries;
  41. long num_entries;
  42. FileReq *req;
  43. } Base;
  44.  
  45. extern void shadow_area(), render_text(), border_area(), center_title();
  46. extern void write_screen(), init_dir(), pathgad(), close_libs();
  47. extern void cancel(), vert_scroll(), scrollh(), right_htik(), left_htik();
  48. extern void down_vtik(), up_vtik(), filegad(), okay_pressed();
  49. extern void *strcpy(), *strncpy(), *AllocMem(), *trim();
  50. extern short init();
  51. extern long reqdir(), TextLength(), Wait(), process_message();
  52. extern struct Library *OpenLibrary();
  53. extern struct ViewPort *ViewPortAddress();
  54. extern struct Window *OpenWindow();
  55. extern struct TextFont *OpenFont();
  56. extern struct Message *GetMsg();
  57.  
  58. extern struct IntuitionBase *IntuitionBase;
  59. extern struct GfxBase *GfxBase;
  60.  
  61. static UWORD NaturalColors[NUM_COLORS] =
  62.    {
  63.    0x2,
  64.    0xeee,
  65.    0x44f,
  66.    0xd00,
  67.    };
  68.  
  69. static struct TextAttr _ta =
  70. {
  71. (STRPTR) "topaz.font",
  72. 8,
  73. FS_NORMAL,
  74. FPF_ROMFONT,
  75. };
  76.  
  77. #define HV GADGHCOMP
  78. #define HI (GADGIMAGE|GADGHNONE)
  79. #define HC (GADGIMAGE|GADGHCOMP)
  80. #define RELV RELVERIFY
  81. #define BOOLG BOOLGADGET
  82. #define BACT (RELVERIFY|GADGIMMEDIATE)
  83. #define PGAD PROPGADGET
  84. #define PACT (RELVERIFY|GADGIMMEDIATE|FOLLOWMOUSE)
  85. #define SGAD STRGADGET
  86.  
  87. extern struct Image UpImg, DownImg, LeftImg, RightImg, vi, hi;
  88.  
  89. static struct PropInfo p[] =
  90. {
  91. {FREEVERT|PROPBORDERLESS,0,0,0xffff,0x0fff,0,0,0,0,0,0,},
  92. {FREEVERT|PROPBORDERLESS,0,0,0xffff,0xfff,0,0,0,0,0,0,},
  93. {FREEHORIZ|PROPBORDERLESS,0,0,0xfff,0xffff,0,0,0,0,0,0,},
  94. };
  95.  
  96. static struct StringInfo sin[] =
  97. {
  98. {NULL,NULL,0,512,0,0,0,0,0,0,0L,0L,0L},
  99. {NULL,NULL,0,512,0,0,0,0,0,0,0L,0L,0L},
  100. };
  101.  
  102. static struct Gadget g[] =
  103. {
  104. {&g[1],6,11,17,7,HC,BACT,BOOLG,(APTR)&UpImg,0L,0L,0L,0L,1,(APTR)up_vtik,},
  105. {&g[2],254,11,17,7,HC,BACT,BOOLG,(APTR)&UpImg,0L,0L,0L,0L,2,(APTR)up_vtik,},
  106. {&g[3],6,68,17,7,HC,BACT,BOOLG,(APTR)&DownImg,0L,0L,0L,0L,5,(APTR)down_vtik,},
  107. {&g[4],254,68,17,7,HC,BACT,BOOLG,(APTR)&DownImg,0L,0L,0L,0L,6,(APTR)down_vtik,},
  108. {&g[5],29,77,15,9,HC,BACT,BOOLG,(APTR)&LeftImg,0L,0L,0L,0L,7,(APTR)left_htik,},
  109. {&g[6],232,77,15,9,HC,BACT,BOOLG,(APTR)&RightImg,0L,0L,0L,0L,9,(APTR)right_htik,},
  110. {&g[7],218,90,53,11,HV,RELV,BOOLG,0L,0L,0L,0L,0L,12,(APTR)okay_pressed,},
  111. {&g[8],218,104,53,11,HV,RELV,BOOLG,0L,0L,0L,0L,0L,13,(APTR)cancel,},
  112. {&g[9],7,21,15,44,HI,PACT,PGAD,(APTR)&vi,0L,0L,0L,(APTR)&p[0],3,(APTR)vert_scroll,},
  113. {&g[10],255,21,15,44,HI,PACT,PGAD,(APTR)&vi,0L,0L,0L,(APTR)&p[1],4,(APTR)vert_scroll,},
  114. {&g[11],48,78,180,7,HI,PACT,PGAD,(APTR)&hi,0L,0L,0L,(APTR)&p[2],8,(APTR)scrollh,},
  115. {&g[12],55,94,140,10,HV,RELV,SGAD,0L,0L,0L,0L,(APTR)&sin[0],10,(APTR)pathgad,},
  116. {&g[13],55,104,140,10,HV,RELV,SGAD,0L,0L,0L,0L,(APTR)&sin[1],11,NULL,},
  117.  
  118. {&g[14],30,12,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,0,(APTR)filegad,},
  119. {&g[15],30,22,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,1,(APTR)filegad,},
  120. {&g[16],30,32,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,2,(APTR)filegad,},
  121. {&g[17],30,42,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,3,(APTR)filegad,},
  122. {&g[18],30,52,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,4,(APTR)filegad,},
  123. {NULL,30,62,217,10,HV,RELV,BOOLG,0L,0L,0L,0L,0L,5,(APTR)filegad,},
  124. };
  125.  
  126.  
  127. static struct NewWindow _nw =
  128. {
  129. 20, 20, 282, 122,
  130. (UBYTE) 1,
  131. (UBYTE) 1,
  132. MOUSEMOVE | GADGETDOWN | GADGETUP | RAWKEY | ACTIVEWINDOW |
  133. INTUITICKS | REFRESHWINDOW,
  134. BORDERLESS | ACTIVATE | SIMPLE_REFRESH | WINDOWDRAG,
  135. NULL,       /* gadgets */
  136. 0L,            /* check mark */
  137. 0L,            /* title */
  138. 0L,            /* screen */
  139. 0L,
  140. 282, 122,
  141. 282, 122,
  142. WBENCHSCREEN,
  143. };
  144.  
  145.  
  146. long file_requester(r)
  147. REGS FileReq *r;
  148. {
  149. REGS struct IntuiMessage *imsg;
  150. REGS ULONG signals, mysig;
  151. Base *base;
  152. long alloc_size = 0L, rv = FILEREQ_ERROR;
  153. struct IntuiMessage I;
  154.  
  155. /* Allocate temporary data storage */
  156. if( !(base = AllocMem((long)sizeof(Base),(long)MEMF_CLEAR)) )
  157.    return(rv);
  158.  
  159. /* If no buffer is provided attempt to allocate memory for it. */
  160. if( !r->buf )
  161.    {
  162.    if( !(r->buf = AllocMem(r->bufsize,(long)MEMF_CLEAR)) )
  163.       {
  164.       FreeMem(base,(long)sizeof(Base));
  165.       return(rv);
  166.       }
  167.    alloc_size = r->bufsize;
  168.    }
  169.  
  170. base->ent = (Entry **)r->buf;
  171. base->buffer = r->buf + (r->n_entries * sizeof(Entry *));
  172. base->bufsize = r->bufsize - (r->n_entries * sizeof(Entry *));
  173. base->max_entries = r->n_entries;
  174. base->req = r;
  175.  
  176. strcpy(base->pbuf,r->path);
  177. strcpy(base->fbuf,r->file);
  178.  
  179. if( _nw.Screen = r->screen )
  180.    _nw.Type = CUSTOMSCREEN;
  181. else
  182.    _nw.Type = WBENCHSCREEN;
  183.  
  184.  
  185. /* The requested number of entries has to fit in the
  186.  * buffer or it is an error. */
  187. if( base->bufsize >= (r->n_entries * sizeof(Entry)) )
  188.    {
  189.    if( init(base) )
  190.       {
  191.  
  192.       /*** The main IO loop ***/
  193.  
  194.       for(rv = CANCEL, mysig = (1L<<base->port->mp_SigBit);!base->finished;)
  195.          {
  196.          signals = Wait( mysig | r->user_signals );
  197.  
  198.          if( signals & mysig )
  199.             {
  200.             while( imsg = (struct IntuiMessage *)GetMsg(base->port) )
  201.                {
  202.                I = *imsg;
  203.                ReplyMsg(imsg);
  204.                process_message(base,&I);
  205.                }
  206.             }
  207.  
  208.          if( signals & r->user_signals )
  209.             if( r->user_func )
  210.                (*r->user_func)(signals);
  211.          }
  212.       }
  213.    }
  214.  
  215. /* close up some stuff */
  216. if( base->window )
  217.    CloseWindow(base->window);
  218. if( base->font )
  219.    CloseFont(base->font);
  220. close_libs(base);
  221.  
  222. if( base->finished == OKAY )
  223.    rv = OKAY;
  224.  
  225. if( alloc_size )
  226.    {
  227.    FreeMem(r->buf,alloc_size);
  228.    r->buf = 0L;
  229.    }
  230.  
  231. FreeMem(base,(long)sizeof(Base));
  232.  
  233. return(rv);
  234. }
  235.  
  236.  
  237. static void draw_all(base,flg)
  238. REGS Base *base;
  239. long flg;
  240. {
  241. static Rect file_area = {31,12,246,73};
  242. static Rect left_area = {7,20,21,65};
  243. static Rect right_area = {255,20,269,65};
  244. static Rect bottom_area = {46,78,229,84};
  245. static Rect path_area = {7,90,200,114};
  246. static Rect ok_area = {219,91,268,99};
  247. static Rect can_area = {219,105,268,113};
  248. static Rect area_path = {52,92,194,102};
  249. static Rect area_file = {52,102,194,112};
  250. static Txt path_txt = {"Path:",5L,11L,100L,1L};
  251. static Txt file_txt = {"File:",5L,11L,110L,1L};
  252. static Txt okay_txt = {"Okay",4L,229L,98L,1L};
  253. static Txt can_txt = {"Cancel",6L,221L,112L,0L};
  254.  
  255. REGS struct RastPort *rp = base->rp;
  256.  
  257. if( flg )
  258.    BeginRefresh(base->window);
  259.  
  260. SetRast(rp,1L);
  261. center_title(base);
  262. shadow_area(rp,file_area,1L,0L);
  263. shadow_area(rp,left_area,1L,0L);
  264. shadow_area(rp,right_area,1L,0L);
  265. shadow_area(rp,bottom_area,1L,0L);
  266. shadow_area(rp,path_area,2L,0L);
  267. shadow_area(rp,ok_area,2L,0L);
  268. shadow_area(rp,can_area,3L,0L);
  269. render_text(rp,&path_txt);
  270. render_text(rp,&file_txt);
  271. render_text(rp,&okay_txt);
  272. render_text(rp,&can_txt);
  273. border_area(rp,area_path,0L,1L);
  274. border_area(rp,area_file,0L,1L);
  275. if( flg )
  276.    {
  277.    write_screen(base);
  278.    RefreshGList(g,base->window,0L,-1);
  279.    EndRefresh(base->window,1L);
  280.    }
  281. }
  282.  
  283. static void close_libs(base)
  284. REGS Base *base;
  285. {
  286. if( !base->intui_open && IntuitionBase )
  287.    CloseLibrary(IntuitionBase);
  288. if( !base->gfx_open && GfxBase )
  289.    CloseLibrary(GfxBase);
  290. }
  291.  
  292. static long open_libs(base)
  293. REGS Base *base;
  294. {
  295.  
  296. if( !GfxBase )
  297.    {
  298.    GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",33L);
  299.    base->gfx_open = 0;
  300.    }
  301. else base->gfx_open = 1;
  302. if( !GfxBase )
  303.    return(0L);
  304.  
  305. if( !IntuitionBase )
  306.    {
  307.    IntuitionBase = (struct IntuitionBase *)
  308.    OpenLibrary("intuition.library",33L);
  309.    base->intui_open = 0;
  310.    }
  311. else base->intui_open = 0;
  312. if( !IntuitionBase )
  313.    return(0L);
  314.  
  315. return(1L);
  316. }
  317.  
  318. static void end(base,code)
  319. REGS Base *base;
  320. short code;
  321. {
  322. base->finished = code;
  323. if( code == OKAY )
  324.    {
  325.    strcpy(base->req->path,base->pbuf);
  326.    strcpy(base->req->file,base->fbuf);
  327.    }
  328. }
  329.  
  330.  
  331. static short init(base)
  332. REGS Base *base;
  333. {
  334. if( open_libs(base) )
  335.    {
  336.    if( base->font = OpenFont(&_ta) )
  337.       {
  338.       if( base->window = OpenWindow(&_nw) )
  339.          {
  340.          if( base->req->flags & NATURAL_COLOR_BIT ) /* use the natural colors */
  341.             {
  342.             REGS struct ViewPort *vp = ViewPortAddress(base->window);
  343.             LoadRGB4(vp,NaturalColors,NUM_COLORS);
  344.             }
  345.  
  346.          /* Attach the buffers to the gadgets */
  347.          sin[0].Buffer = base->pbuf;
  348.          sin[1].Buffer = base->fbuf;
  349.          sin[0].UndoBuffer = sin[1].UndoBuffer = base->ubuf;
  350.  
  351.          base->rp = base->window->RPort;
  352.          base->port = base->window->UserPort;
  353.          SetFont(base->rp,base->font);
  354.          draw_all(base,0L);
  355.          if( !base->pbuf[0] )
  356.             init_dir(base->pbuf,(UWORD)(base->req->flags & CLI_BIT));
  357.          AddGList(base->window,g,0,-1,0L);
  358.          RefreshGList(g,base->window,0L,-1);
  359.          pathgad(base,NULL);
  360.          }
  361.       else return(0);
  362.       }
  363.    else return(0);
  364.    }
  365. else return(0);
  366.  
  367. return(1);
  368. }
  369.  
  370.  
  371. static long process_message(base,i)
  372. REGS Base *base;
  373. REGS struct IntuiMessage *i;
  374. {
  375. REGS long rv = 0L;
  376.  
  377. switch( i->Class )
  378.    {
  379.    case MOUSEMOVE:
  380.       if( base->func )
  381.         (*base->func)(base,i);
  382.       break;
  383.    case INTUITICKS:
  384.       if( base->func )
  385.          {
  386.          if( base->gad->Flags & SELECTED )
  387.             {
  388.             if( !base->countdown )
  389.                (*base->func)(base,i);
  390.             else base->countdown--;
  391.             }
  392.          }
  393.       break;
  394.    case RAWKEY:
  395.       break;
  396.    case GADGETDOWN:
  397.       base->gad = (struct Gadget *)i->IAddress;
  398.       if( base->func = (PFV) base->gad->UserData )
  399.          (*base->func)(base,i);
  400.       base->countdown = 4;
  401.       break;
  402.    case GADGETUP:
  403.       base->gad = (struct Gadget *)i->IAddress;
  404.       if( base->func = (PFV) base->gad->UserData )
  405.          (*base->func)(base,i);
  406.       base->func = 0L;
  407.       base->gad = 0L;
  408.       base->countdown = 0;
  409.       break;
  410.    case ACTIVEWINDOW:
  411.       center_title(base);
  412.       break;
  413.    case REFRESHWINDOW:
  414.       draw_all(base,1L);
  415.       break;
  416.  
  417.    default: break;
  418.    }
  419.  
  420. return(rv);
  421. }
  422.  
  423. static void center_title(base)
  424. REGS Base *base;
  425. {
  426.  
  427. REGS struct RastPort *rp = base->rp;
  428. REGS short text_width, text_length, x;
  429.  
  430. if( text_length = strlen(base->req->heading) )
  431.    {
  432.    text_width = TextLength(rp,base->req->heading,(long)text_length);
  433.    x = (base->window->Width - text_width) >> 1;
  434.    SetAPen(rp,2L);
  435.    SetBPen(rp,1L);
  436.    Move(rp,(long)x,8L);
  437.    Text(rp,base->req->heading,(long)text_length);
  438.    }
  439. }
  440.  
  441. static void cancel(base,i)
  442. REGS Base *base;
  443. REGS struct IntuiMessage *i;
  444. {
  445. end(base,CANCEL);
  446. }
  447.  
  448. static UWORD write_entry(base,e,buf)
  449. REGS Base *base;
  450. REGS Entry *e;
  451. REGS char *buf;
  452. {
  453.  
  454. REGS char *pr;
  455. REGS UWORD len;
  456. char tmp_buf[130];
  457. char spc[6];
  458.  
  459. if( e->dir )
  460.    pr = "-Dir-";
  461. else
  462.    {
  463.    spc[0] = e->archive ? 'a' : '.';
  464.    spc[1] = e->read ? 'r' : '.';
  465.    spc[2] = e->write ? 'w' : '.';
  466.    spc[3] = e->execute ? 'e' : '.';
  467.    spc[4] = e->delete ? 'd' : '.';
  468.    spc[5] = '\0';
  469.    pr = spc;
  470.    }
  471. len = sprintf(tmp_buf,"%-10s %-5s %02d-%02d-%02d",
  472.                 EntryName(e),pr,
  473.                 e->month,e->day,e->year+78);
  474.  
  475. if( len > base->width ) base->width = len;
  476. if( (len = len-base->left) > 27 ) len = 27;
  477.  
  478. strncpy(buf,&tmp_buf[base->left],len);
  479. return(len);
  480. }
  481.  
  482. static void entries_write(base,lens)
  483. REGS Base *base;
  484. UWORD lens[];
  485. {
  486. REGS UWORD i, j;
  487. for( i = base->top, j = 0, base->width = 27;
  488.      j < 6 && i < base->num_entries; i++, j++)
  489.      lens[j] = write_entry(base,base->ent[i],base->scr_buf[j]);
  490. base->most = base->width - 27;
  491. }
  492.  
  493. static void write_screen(base)
  494. REGS Base *base;
  495. {
  496. static Rect wipe_area = {31L,12L,246L,72L};
  497. REGS UWORD i, j;
  498. UWORD lens[6];
  499.  
  500. entries_write(base,lens);
  501.  
  502. if( base->left > base->most )
  503.    {
  504.    base->left = base->most;
  505.    entries_write(base,lens);
  506.    }
  507.  
  508. SetAPen(base->rp,1L);
  509. RectFill(base->rp,(long)wipe_area.x0,(long)wipe_area.y0,
  510.                  (long)wipe_area.x1,(long)wipe_area.y1);
  511. SetAPen(base->rp,2L);
  512. SetBPen(base->rp,1L);
  513.  
  514. for( i = 0, j = 19; i < 6 && i < base->num_entries; i++, j+=10)
  515.    {
  516.    Move(base->rp,31L,(long)j);
  517.    Text(base->rp,base->scr_buf[i],(long)lens[i]);
  518.    }
  519. }
  520.  
  521. static void calc_vpot(base)
  522. REGS Base *base;
  523. {
  524. REGS struct PropInfo *pa, *pb;
  525. REGS UWORD most = base->num_entries - 6;
  526. REGS ULONG pot, body;
  527. REGS UWORD old_pot;
  528.  
  529. pa = (struct PropInfo *)g[8].SpecialInfo;
  530. pb = (struct PropInfo *)g[9].SpecialInfo;
  531. old_pot = pa->VertPot;
  532.  
  533. if( most <= 0 )
  534.    {
  535.    pa->VertPot = 0;
  536.    pa->VertBody = 0xFFFF;
  537.    }
  538. else
  539.    {
  540.    pot = base->top;
  541.    pot *= 0xFFFF;
  542.    pot /= most;
  543.    body = 6 * 0xFFFF;
  544.    body /= base->num_entries;
  545.  
  546.    pa->VertPot = pot;
  547.    pa->VertBody = body;
  548.    }
  549.  
  550. pb->VertBody = pa->VertBody;
  551. pb->VertPot = pa->VertPot;
  552.  
  553. if( pot != old_pot )
  554.    RefreshGList(&g[8],base->window,0L,2);
  555. }
  556.  
  557.  
  558. static void calc_hpot(base)
  559. REGS Base *base;
  560. {
  561. REGS ULONG pot;
  562. REGS struct PropInfo *pi = (struct PropInfo *)g[10].SpecialInfo;
  563. REGS UWORD old_pot;
  564.  
  565. old_pot = pi->HorizPot;
  566.  
  567. if( base->most )
  568.    {
  569.    pot = base->left;
  570.    pot *= 0xFFFF;
  571.    pot /= base->most;
  572.    pi->HorizPot = pot;
  573.    pi->HorizBody = 0xFFFF/base->width;
  574.    pi->HorizBody *= 27;
  575.    }
  576. else pi->HorizPot = 0;
  577.  
  578. if( old_pot != pi->HorizPot )
  579.    RefreshGList(&g[10],base->window,0L,1);
  580. }
  581.  
  582.  
  583. static void vert_scroll(base,i)
  584. REGS Base *base;
  585. REGS struct IntuiMessage *i;
  586. {
  587. REGS struct Gadget *a, *b;
  588. REGS long top, range;
  589.  
  590. if( i->Class == GADGETUP )
  591.    ModifyIDCMP(base->window,base->window->IDCMPFlags | INTUITICKS);
  592. else if( i->Class == GADGETDOWN )
  593.    ModifyIDCMP(base->window,base->window->IDCMPFlags & ~INTUITICKS);
  594.  
  595. a = base->gad;
  596. b = (a == &g[8]) ? &g[9] : &g[8];
  597.  
  598. if( ((struct PropInfo *)b->SpecialInfo)->VertPot !=
  599.     ((struct PropInfo *)a->SpecialInfo)->VertPot )
  600.    {
  601.    ((struct PropInfo *)b->SpecialInfo)->VertPot =
  602.    ((struct PropInfo *)a->SpecialInfo)->VertPot;
  603.    RefreshGList(b,base->window,0L,1);
  604.  
  605.    top = ((struct PropInfo *)b->SpecialInfo)->VertPot;
  606.  
  607.    range = base->num_entries - 6;
  608.    if( range <= 0 )
  609.       return;
  610.    top *= range;
  611.    top /= 0xFFFF;
  612.  
  613.    if( top != base->top )
  614.       {
  615.       base->top = top;
  616.       write_screen(base);
  617.       calc_hpot(base);
  618.       }
  619.    }
  620. }
  621.  
  622.  
  623. static void up_vtik(base,i)
  624. REGS Base *base;
  625. REGS struct IntuiMessage *i;
  626. {
  627.  
  628. if( base->top > 0 && i->Class != GADGETDOWN )
  629.    {
  630.    base->top--;
  631.    write_screen(base);
  632.    calc_vpot(base);
  633.    }
  634. }
  635.  
  636. static void down_vtik(base,i)
  637. REGS Base *base;
  638. REGS struct IntuiMessage *i;
  639. {
  640.  
  641. if( base->top < (base->num_entries - 6) && i->Class != GADGETDOWN )
  642.    {
  643.    base->top++;
  644.    write_screen(base);
  645.    calc_vpot(base);
  646.    }
  647. }
  648.  
  649. static void up_one_dir(base,path,len)
  650. REGS Base *base;
  651. UBYTE *path;
  652. REGS UWORD len;
  653. {
  654.  
  655. REGS UBYTE *end;
  656.  
  657. if( len )
  658.    {
  659.    end = path+(len-1);
  660.  
  661.    while( end >= path )
  662.       {
  663.       if( *end == '/' )
  664.          {
  665.          *end = '\0';
  666.          return;
  667.          }
  668.       else if( *end == ':' )
  669.          {
  670.          *(end+1) = '\0';
  671.          return;
  672.          }
  673.       end--;
  674.       }
  675.  
  676.    *path = '\0';
  677.    }
  678. }
  679.  
  680.  
  681. static void pathgad(base,i)
  682. REGS Base *base;
  683. REGS struct IntuiMessage *i;
  684. {
  685. long num_entries;
  686.  
  687. if( (num_entries = reqdir(trim(base->pbuf),base->buffer,
  688.     (ULONG)base->bufsize,base->ent,(ULONG)base->max_entries)) > 0L )
  689.    {
  690.    base->num_entries = num_entries;
  691.    base->top = base->left = 0;
  692.    write_screen(base);
  693.    calc_hpot(base);
  694.    calc_vpot(base);
  695.    }
  696. else if( num_entries < 0L )
  697.    {
  698.    strcpy(base->pbuf,base->ubuf);
  699.    RefreshGList(&g[11],base->window,0L,1);
  700.    }
  701. }
  702.  
  703. static void filegad(base,i)
  704. REGS Base *base;
  705. REGS struct IntuiMessage *i;
  706. {
  707. REGS Entry *e;
  708. REGS UWORD len;
  709. REGS struct StringInfo *si;
  710.  
  711. e = base->ent[base->top + base->gad->GadgetID];
  712.  
  713. if( e->dir )
  714.    {
  715.    len = strlen(trim(base->pbuf));
  716.  
  717.    if( strcmp("/",EntryName(e)) )
  718.       {
  719.       if( len )
  720.          {
  721.          if( base->pbuf[len-1] != ':' )
  722.             strcat(base->pbuf,"/");
  723.          }
  724.       strcat(base->pbuf,EntryName(e));
  725.       }
  726.    else
  727.       {
  728.       si = (struct StringInfo *)g[11].SpecialInfo;
  729.       si->DispPos = 0;
  730.       up_one_dir(base,base->pbuf,len);
  731.       }
  732.  
  733.    RefreshGList(&g[11],base->window,0L,1);
  734.    pathgad(base,NULL);
  735.    }
  736. else
  737.    {
  738.    strcpy(base->fbuf,EntryName(e));
  739.    RefreshGList(&g[12],base->window,0L,1);
  740.    }
  741. }
  742.  
  743.  
  744. static void scrollh(base,i)
  745. REGS Base *base;
  746. REGS struct IntuiMessage *i;
  747. {
  748. REGS struct PropInfo *pi;
  749. REGS ULONG pos;
  750.  
  751. pi = (struct PropInfo *)base->gad->SpecialInfo;
  752.  
  753. if( i->Class == GADGETUP )
  754.    ModifyIDCMP(base->window,base->window->IDCMPFlags | INTUITICKS);
  755. else if( i->Class == GADGETDOWN )
  756.    ModifyIDCMP(base->window,base->window->IDCMPFlags & ~INTUITICKS);
  757.  
  758. if( base->most && i->Class != GADGETDOWN )
  759.    {
  760.    pos = base->most;
  761.    pos *= pi->HorizPot;
  762.    pos /= 0xFFFF;
  763.    if( pos != base->left )
  764.       {
  765.       base->left = pos;
  766.       write_screen(base);
  767.       }
  768.    }
  769. }
  770.  
  771. static void right_htik(base,i)
  772. REGS Base *base;
  773. REGS struct IntuiMessage *i;
  774. {
  775.  
  776. if( base->left < base->most && i->Class != GADGETDOWN )
  777.    {
  778.    base->left++;
  779.    write_screen(base);
  780.    calc_hpot(base);
  781.    }
  782.  
  783. }
  784.  
  785. static void left_htik(base,i)
  786. REGS Base *base;
  787. REGS struct IntuiMessage *i;
  788. {
  789.  
  790. if( base->left > 0 && i->Class != GADGETDOWN )
  791.    {
  792.    base->left--;
  793.    write_screen(base);
  794.    calc_hpot(base);
  795.    }
  796.  
  797. }
  798.  
  799. static void okay_pressed(base,i)
  800. REGS Base *base;
  801. struct IntuiMessage *i;
  802. {
  803. end(base,OKAY);
  804. }
  805.  
  806.  
  807. static void shadow_area(rp,r,front_color,outline_color)
  808. REGS struct RastPort *rp;
  809. Rect r;
  810. REGS long front_color, outline_color;
  811. {
  812. SetAPen(rp,(long)front_color);
  813. RectFill(rp,(long)r.x0,(long)r.y0,(long)r.x1,(long)r.y1);
  814.  
  815. SetAPen(rp,(long)outline_color);
  816. r.x0--;
  817. r.y0--;
  818. r.x1++;
  819. r.y1++;
  820. Move(rp,(long)r.x0,(long)r.y0);
  821. Draw(rp,(long)r.x0,(long)r.y1);
  822. Draw(rp,(long)r.x1,(long)r.y1);
  823. Draw(rp,(long)r.x1,(long)r.y0);
  824. Draw(rp,(long)r.x0,(long)r.y0);
  825. r.x0 += 3;
  826. r.y0++;
  827. r.x1++;
  828. r.y1++;
  829. Move(rp,(long)r.x0,(long)r.y1);
  830. Draw(rp,(long)r.x1,(long)r.y1);
  831. Draw(rp,(long)r.x1,(long)r.y0);
  832. r.x1++;
  833. Move(rp,(long)r.x1,(long)r.y0);
  834. Draw(rp,(long)r.x1,(long)r.y1);
  835. r.x1++;
  836. Move(rp,(long)r.x1,(long)r.y0);
  837. Draw(rp,(long)r.x1,(long)r.y1);
  838. }
  839.  
  840. static void render_text(rp,t)
  841. REGS struct RastPort *rp;
  842. Txt *t;
  843. {
  844. SetAPen(rp,t->color);
  845. SetDrMd(rp,(long)JAM1);
  846. Move(rp,t->x,t->y);
  847. Text(rp,t->line,t->len);
  848. }
  849.  
  850. static void border_area(rp,r,front_color,outline_color)
  851. REGS struct RastPort *rp;
  852. Rect r;
  853. long front_color, outline_color;
  854. {
  855. SetAPen(rp,front_color);
  856. RectFill(rp,(long)r.x0,(long)r.y0,(long)r.x1,(long)r.y1);
  857.  
  858. SetAPen(rp,outline_color);
  859. Move(rp,(long)r.x0,(long)r.y0);
  860. Draw(rp,(long)r.x0,(long)r.y1);
  861. Draw(rp,(long)r.x1,(long)r.y1);
  862. Draw(rp,(long)r.x1,(long)r.y0);
  863. Draw(rp,(long)r.x0,(long)r.y0);
  864. r.x0++;
  865. r.x1--;
  866. Move(rp,(long)r.x0,(long)r.y0);
  867. Draw(rp,(long)r.x0,(long)r.y1);
  868. Move(rp,(long)r.x1,(long)r.y0);
  869. Draw(rp,(long)r.x1,(long)r.y1);
  870. }
  871.  
  872.