home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / fm2000 / event.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-04  |  22.2 KB  |  908 lines

  1. /*
  2.      Filemaster - Multitasking directory utility.
  3.      Copyright (C) 2000  Toni Wilen
  4.      
  5.      This program is free software; you can redistribute it and/or
  6.      modify it under the terms of the GNU General Public License
  7.      as published by the Free Software Foundation; either version 2
  8.      of the License, or (at your option) any later version.
  9.      
  10.      This program is distributed in the hope that it will be useful,
  11.      but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.      GNU General Public License for more details.
  14.      
  15.      You should have received a copy of the GNU General Public License
  16.      along with this program; if not, write to the Free Software
  17.      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19.  
  20. #include <proto/all.h>
  21. #include <exec/types.h>
  22. #include <exec/memory.h>
  23. #include <intuition/intuition.h>
  24. #include <libraries/gadtools.h>
  25. #include <intuition/gadgetclass.h>
  26. #include <workbench/workbench.h>
  27. #include <workbench/startup.h>
  28. #include <strings.h>
  29. #include <stdio.h>
  30. #include "fmnode.h"
  31. #include "fmdos.h"
  32. #include "child.h"
  33. #include "fmlocale.h"
  34. #include "fmgui.h"
  35. #include "audio.h"
  36. #include "commodity.h"
  37.  
  38. struct QuitConfig {
  39.     unsigned areyousure:2;
  40. };
  41. struct SleepConfig {
  42.     unsigned sleepwindow:2;
  43. };
  44.  
  45. #define IDCMP IDCMP_MOUSEBUTTONS|IDCMP_GADGETDOWN|IDCMP_GADGETUP|IDCMP_RAWKEY|IDCMP_REFRESHWINDOW|IDCMP_NEWSIZE|IDCMP_CLOSEWINDOW|IDCMP_ACTIVEWINDOW|IDCMP_INACTIVEWINDOW
  46.  
  47. extern void __asm RealTimeScroll(register __a0 struct ReqScrollStruct*);
  48. extern struct FMMain fmmain;
  49. extern struct FMList fmlist[];
  50. extern UBYTE workbench[];
  51.  
  52. void windownewsize(void);
  53. void taskwindow(WORD);
  54. void nextlist(struct ListInfo*,WORD);
  55. void clickfile(void);
  56. void parentpath(struct FMList*,BPTR);
  57. WORD getparent(struct FMList*);
  58. void setparent(struct FMList*);
  59. void setcmenu(void);
  60. void parse(void);
  61. WORD suljenaytto(WORD);
  62. WORD avaanaytto(WORD);
  63. void freegadgets(struct Gadget*);
  64. void askmodabort(void);
  65. struct FMNode *iteratenode(struct FMNode**);
  66. void gparent(void);
  67. void aboutti(WORD);
  68. void dirfileclick(struct FMList*,struct FMNode*,WORD);
  69. void setnewconfig(void);
  70. WORD config(void);
  71.  
  72. void operate(void);
  73. void __asm jump(register __a0 APTR,register __a1 APTR);
  74. extern APTR launchtable[];
  75. extern struct FMMain fmmain;
  76. extern struct FMConfig *fmconfig;
  77. extern struct FMList fmlist[];
  78.  
  79. void getdir(void);
  80. void dirmeters(void);
  81. void drives(struct FMList*);
  82.  
  83. static WORD sleep(WORD sleepv)
  84. {
  85. WORD ret=0;
  86.  
  87. if(!sleepv) if (!suljenaytto(3)) {
  88.     return(0);
  89. }
  90. SetSignal(0,SIGBREAKF_CTRL_F);
  91. fmmain.sleepon=fmmain.quitti;
  92. Signal((struct Task*)fmmain.timeproc,SIGBREAKF_CTRL_F);
  93. while(fmmain.sleepon==fmmain.quitti) waitsig(SIGBREAKF_CTRL_F);
  94. if(fmmain.sleepon) {
  95.     for(;;) {
  96.         ret=avaanaytto(3);
  97.         if(ret) break;
  98.         DisplayBeep(0);
  99.         Delay(50);
  100.     }
  101. }
  102. fmmain.sleepon=0;
  103. return(1);
  104. }
  105.  
  106. void setsource(struct FMList *list1)
  107. {
  108. struct FMList *vlist;
  109.  
  110. if(list1==fmmain.sourcedir) return;
  111. if(list1==fmmain.destdir) {
  112.     vlist=fmmain.sourcedir;
  113.     fmmain.sourcedir=list1;
  114.     fmmain.destdir=vlist;
  115. } else {
  116.     fmmain.sourcedir->flags&=~(LDESTINATION|LSOURCE);
  117.     fmmain.sourcedir=list1;
  118. }
  119. fmmain.sourcedir->flags&=~LDESTINATION;
  120. fmmain.sourcedir->flags|=LSOURCE;
  121. fmmain.destdir->flags&=~LSOURCE;
  122. fmmain.destdir->flags|=LDESTINATION;
  123. fmmessage(list1);
  124. dirmeters();
  125. }
  126.  
  127. static struct FMNode *mousenode(struct FMList *list,WORD xx,WORD yy)
  128. {
  129. struct ListInfo *li;
  130. struct FMNode *node;
  131. WORD cnt,apu1;
  132.  
  133. li=list->li;
  134. if (xx>=li->dirx && xx<=li->edirx && yy>=li->diry && yy<li->ediry) {
  135.     node=(struct FMNode*)list;
  136.     iteratenode(&node);
  137.     cnt=list->firstline;
  138.     yy-=li->diry; if (yy<0) return(0);
  139.     yy/=fmmain.listysize;
  140.     apu1=cnt+yy;
  141.     while(cnt--) iteratenode(&node);
  142.     while(node && yy--) iteratenode(&node);
  143.     if (!node||!node->succ) return(0);
  144.     fmmain.sourcedir->keyline=apu1;
  145.     return(node);
  146. }
  147. return(0);
  148. }
  149.  
  150. static WORD processclick(struct IntuiMessage *msg)
  151. {
  152. struct timeval tv1,tv2;
  153. struct FMNode *node;
  154. struct FMList *list1=0;
  155. struct ListInfo *li;
  156. WORD xx,yy,apu1,cnt1;
  157. WORD dragtype=-1;
  158.  
  159. xx=msg->MouseX-fmmain.ikkuna->BorderLeft;
  160. yy=msg->MouseY-fmmain.ikkuna->BorderTop;
  161. if (msg->Code==MENUDOWN && xx>=fmmain.cmenux && xx<=fmmain.cmenux+fmmain.totalcmenuwidth && yy>=fmmain.cmenuy && yy<=fmmain.cmenuy+fmmain.totalcmenuheight) {
  162.     fmmain.cmenu+=fmmain.cmenugadnumperline*fmconfig->cmenucolumns;
  163.     apu1=0;
  164.     for(cnt1=0;cnt1<TOTALCOMMANDS;cnt1++) {
  165.         if(fmconfig->cmenuconfig[cnt1].position==1) apu1++;
  166.     }
  167.     if(fmmain.cmenu>apu1) fmmain.cmenu=0;
  168.     setcmenu();
  169. }
  170. for(apu1=0;apu1<LISTS;apu1++) {
  171.     li=fmlist[apu1].li;
  172.     if(li&&xx>=li->x&&xx<=li->x+li->width&&yy>=li->y&&yy<=li->y+li->height) { 
  173.         list1=&fmlist[apu1];
  174.         break;
  175.     }
  176. }
  177. if (yy>=fmmain.messageliney1 && msg->Code==MENUDOWN) askmodabort();
  178.  
  179. if (!list1||!li) return(dragtype);
  180.  
  181. if (msg->Code==MENUDOWN && fmmain.sourcedir->flags&LACTIVE) fmmain.sourcedir->flags|=LABORTREQ;
  182.  
  183. setsource(list1);
  184.  
  185. if(list1->flags&LALLOCATED) return(dragtype);
  186.  
  187. if(msg->Code==MENUDOWN) {
  188.     if(xx>=li->slider1.LeftEdge&&xx<=li->slider1.LeftEdge+li->slider1.Width&&yy>=li->slider1.TopEdge&&yy<=li->slider1.TopEdge+li->slider1.Height) {
  189.         launch(launchtable[PARENTCONFIG],getconfignumber(PARENTCONFIG),0,0);
  190. //        gparent();
  191.         return(dragtype);
  192.     }
  193.     if (yy>=li->topliney&&yy<=li->topliney+fmmain.txtysize+1) {
  194.         if (list1->flags&LDIRLIST)
  195.             launch((APTR)&getdir,0,0,MSUBPROC);
  196.             else
  197.             drives(list1);
  198.     }
  199.     if(fmconfig->rightmouse==1) {
  200.         launch(launchtable[PARENTCONFIG],getconfignumber(PARENTCONFIG),0,0);
  201. //        gparent();
  202.         return(dragtype);
  203.     }
  204. }
  205.  
  206. node=mousenode(list1,xx,yy);
  207. if(!node) return(dragtype);
  208.  
  209. if(msg->Code==MENUDOWN&&fmconfig->rightmouse==0) dirfileclick(list1,node,xx);
  210. if (msg->Code==SELECTDOWN) {
  211.     node->flags^=NSELECTED;
  212.     if(node->flags&NSELECTED) dragtype=1; else dragtype=0;
  213.     if (list1->flags&LDIRLIST&&node->flags&NSELECTED) endofdirtxt(list1,node);
  214.     if (list1->flags&LDIRLIST&&!(node->flags&NSELECTED)) endofdirtxt(list1,0);
  215.     outputlistline(list1,node);
  216.     tv1.tv_secs=fmmain.secs;tv1.tv_micro=fmmain.mics;
  217.     tv2.tv_secs=msg->Seconds;tv2.tv_micro=msg->Micros;
  218.     SubTime(&tv2,&tv1);
  219.     if (list1->lastclicked==node && !tv2.tv_secs && tv2.tv_micro/10000<=fmconfig->doubleclick) {
  220.         dirfileclick(list1,node,xx);
  221.         list1->lastclicked=0;
  222.     } else {
  223.         list1->lastclicked=node;
  224.     }
  225.     fmmain.secs=msg->Seconds; fmmain.mics=msg->Micros;
  226. }
  227. return(dragtype);
  228. }
  229.  
  230.  
  231. static void processgadget(WORD id,ULONG class)
  232. {
  233. if (id>=301 && id<(301+TOTALCOMMANDS)) {
  234.     if(id-301<TOTALCOMMANDS) runcommand(&fmmain.gadkeytab[id-301+LISTGADGETS*WINDOWLISTS]);
  235. }
  236.     // slider1s 101->
  237.     // slider2s 111->
  238.     // string gadgets 201->
  239.     // taskgadget 401->
  240.     // ltaskgadget 411->
  241.     // rtaskgadget 421->
  242.  
  243. if (id>=401&&id<=410) {
  244.     setsource(fmmain.li[id-401]->list);
  245.     taskwindow(id-401);
  246.     return;
  247. }
  248. if (id>=411&&id<=420) {
  249.     setsource(fmmain.li[id-411]->list);
  250.     nextlist(fmmain.sourcedir->li,-1);
  251.     return;
  252. }
  253. if (id>=421&&id<=430) {
  254.     setsource(fmmain.li[id-421]->list);
  255.     nextlist(fmmain.sourcedir->li,1);
  256.     return;
  257. }
  258. if (id>=201&&id<=210) {
  259.     setsource(fmmain.li[id-201]->list);
  260.     setparent(fmmain.sourcedir);
  261.     fmmain.sourcedir->fmmessage1[0]=0;
  262.     fmmain.sourcedir->fmmessage2[0]=0;
  263.     fmmessage(fmmain.sourcedir);
  264.     launch((APTR)&getdir,0,0,MSUBPROC);
  265.     return;
  266. }
  267. if (id>=101&&id<=110) {
  268.     setsource(fmmain.li[id-101]->list);
  269.     RealTimeScroll(&fmmain.sourcedir->li->rscroll1);
  270.     fmmain.sourcedir->firstline=fmmain.sourcedir->li->rscroll1.TopEntryNumber;
  271.     return;
  272. }
  273. if (id>=111&&id<=120) {
  274.     setsource(fmmain.li[id-111]->list);
  275.     RealTimeScroll(&fmmain.sourcedir->li->rscroll2);
  276.     fmmain.sourcedir->firstlinew=fmmain.sourcedir->li->rscroll2.TopEntryNumber;
  277.     return;
  278. }
  279. }
  280.  
  281.  
  282. void runhotkey(WORD hotkey)
  283. {
  284. struct GadKeyTab *gkt;
  285.  
  286. gkt=&fmmain.gadkeytab[hotkey];
  287. if((gkt->onelist&&gkt->listnum==fmmain.sourcedir->listnumber)||(!gkt->onelist)) {
  288.     if(gkt->cmc) {
  289.         runcommand(gkt);
  290.     } else {
  291.         processgadget(gkt->g->GadgetID,0);
  292.     }
  293. }
  294. }
  295.  
  296. static void frameoutput(struct FMList *l)
  297. {
  298. fmmain.framenode=scrollifneeded(l,&l->keyline,&l->keylinew);
  299. fmmain.framelist=l;
  300. fmmain.framenode->flags|=NKEYBOARD;
  301. outputlistline(fmmain.framelist,fmmain.framenode);
  302. }
  303. static WORD endframeoutput(void)
  304. {
  305. WORD was;
  306.  
  307. was=0;
  308. if(fmmain.framenode) {
  309.     fmmain.framenode->flags&=~NKEYBOARD;
  310.     outputlistline(fmmain.framelist,fmmain.framenode);
  311.     was=1;
  312. }
  313. fmmain.framenode=0;
  314. fmmain.framelist=0;
  315. return(was);
  316. }
  317.  
  318. WORD smallevent(struct Window *win,ULONG *class,UWORD *code)
  319. {
  320. struct IntuiMessage *message;
  321. ULONG sigs;
  322.  
  323. while(!(message=(struct IntuiMessage*)GetMsg(win->UserPort))) {
  324.         sigs=Wait((1L<<win->UserPort->mp_SigBit)|SIGBREAKF_CTRL_C);
  325.         if(sigs&SIGBREAKF_CTRL_C) {
  326.             SetSignal(SIGBREAKF_CTRL_C,SIGBREAKF_CTRL_C);
  327.             return(1);
  328.         }
  329. }
  330. *class=message->Class;
  331. *code=message->Code;
  332. ReplyMsg((struct Message*)message);
  333. return(0);
  334. }
  335.  
  336. void getappdir(struct AppMessage *appmsg)
  337. {
  338. BPTR lock;
  339.  
  340. ActivateWindow(fmmain.ikkuna);
  341. if(!(fmmain.sourcedir->flags&LALLOCATED)&&appmsg->am_NumArgs>=1) {
  342.     lock=DupLock(appmsg->am_ArgList->wa_Lock);
  343.     if(lock) {
  344.         parentpath(fmmain.sourcedir,lock);
  345.         launch((APTR)&getdir,0,0,MSUBPROC);
  346.     }
  347. }
  348. }
  349.  
  350. void event(WORD sleepv)
  351. {
  352. ULONG class,signalmask,sigs;
  353. struct IntuiMessage *message=0;
  354. struct AppMessage *appwinmsg=0;
  355. struct IntuiMessage fakeintu;
  356. struct InputEvent ie;
  357. struct FMNode *apunode1,*apunode2;
  358. struct FMList *apulist;
  359. UWORD code;
  360. UBYTE asciicode;
  361. WORD draggi=-1,dragged=0;
  362. WORD apu1,apu2,apu3,framewas;
  363. LONG apu4;
  364. UBYTE chartab[2];
  365. struct ReqScrollStruct *rss;
  366. WORD waiti=0,superhotkey;
  367.  
  368. signalmask=1L<<fmmain.ikkuna->UserPort->mp_SigBit;
  369. if(fmmain.appwinport) signalmask|=(1L<<fmmain.appwinport->mp_SigBit);
  370. signalmask|=SIGBREAKF_CTRL_F;
  371.  
  372. ie.ie_Class=IECLASS_RAWKEY;
  373. ie.ie_SubClass=0;
  374. if(sleepv) {
  375.     launch(launchtable[SLEEPCONFIG],getconfignumber(SLEEPCONFIG),0,0);
  376.     sleep(1);
  377.     if(fmmain.kill) return;
  378. }
  379. setsource(&fmlist[1]);
  380. setsource(&fmlist[0]);
  381. Signal((struct Task*)fmmain.timeproc,SIGBREAKF_CTRL_D);
  382. fmmain.fmactive=1|2;
  383.  
  384. eventti:
  385.  
  386. framewas=0; class=0; code=0; fmmain.quitti=0;
  387. superhotkey=-1;
  388. while(!fmmain.quitti) {
  389.  
  390.     if(waiti) {
  391.         if(framewas) frameoutput(fmmain.sourcedir);
  392.  
  393.         sigs=waitsig(signalmask);
  394.  
  395.         waiti=0;
  396.         if(sigs&SIGBREAKF_CTRL_F) {
  397.             if(fmmain.passhotkey) {
  398.                 runhotkey(fmmain.passhotkey-1);
  399.                 fmmain.passhotkey=0;
  400.             } else {
  401.                 launch(launchtable[SLEEPCONFIG],getconfignumber(SLEEPCONFIG),0,0);
  402.             }
  403.         }
  404.     }
  405.  
  406.     if(fmmain.appwinport) {
  407.         appwinmsg=(struct AppMessage*)GetMsg(fmmain.appwinport);
  408.         if(appwinmsg) {
  409.             getappdir(appwinmsg);
  410.             ReplyMsg((struct Message*)appwinmsg);
  411.             appwinmsg=0;
  412.             continue;
  413.         }
  414.     }
  415.     if(superhotkey>=0) runhotkey(superhotkey);
  416.     superhotkey=-1;
  417.  
  418.     message=(struct IntuiMessage*)GetMsg(fmmain.ikkuna->UserPort);
  419.  
  420.     if(!message) {
  421.         waiti=1;
  422.         continue;
  423.     }
  424.     superhotkey=checkhotkeys(message);
  425.     framewas=endframeoutput();
  426.  
  427.     class=message->Class;
  428.     code=message->Code;
  429.     fakeintu.MouseX=message->MouseX;
  430.     fakeintu.MouseY=message->MouseY;
  431.     fakeintu.Seconds=message->Seconds;
  432.     fakeintu.Micros=message->Micros;
  433.     asciicode=0;
  434.     if (class==IDCMP_RAWKEY&&!(code&0x80)&&!(fmmain.sourcedir->flags&LALLOCATED)) {
  435.         switch(code)
  436.         {
  437.         case 0x4c:    //cursor up
  438.         if(message->Qualifier&0x0003) fmmain.sourcedir->keyline-=fmmain.sourcedir->li->visiblelines-2;
  439.         if(message->Qualifier&0x0008) fmmain.sourcedir->keyline=1;
  440.         fmmain.sourcedir->keyline--;
  441.         frameoutput(fmmain.sourcedir);
  442.         break;
  443.         case 0x4d:    //cursor down
  444.         if(message->Qualifier&0x0003) fmmain.sourcedir->keyline+=fmmain.sourcedir->li->visiblelines-2;
  445.         if(message->Qualifier&0x0008) fmmain.sourcedir->keyline=fmmain.sourcedir->totlines-2;
  446.         fmmain.sourcedir->keyline++;
  447.         frameoutput(fmmain.sourcedir);
  448.         break;
  449.         case 0x4e:    //cursor left
  450.         if(message->Qualifier&0x0008)
  451.             fmmain.sourcedir->keylinew=fmmain.sourcedir->totlinesw-1;
  452.             else
  453.             fmmain.sourcedir->keylinew+=fmmain.sourcedir->li->visiblelinesw;
  454.         frameoutput(fmmain.sourcedir);
  455.         break;
  456.         case 0x4f:    //cursor right
  457.         if(message->Qualifier&0x0008)
  458.             fmmain.sourcedir->keylinew=0;
  459.             else
  460.             fmmain.sourcedir->keylinew-=fmmain.sourcedir->li->visiblelinesw;
  461.         frameoutput(fmmain.sourcedir);
  462.         break;
  463.         }
  464.     }
  465.     if(class==IDCMP_RAWKEY) {
  466.         apu1=0;
  467.         switch(code)
  468.         {
  469.         case 0x00:    //~pushed
  470.         if(fmmain.modflag==MODPLAY) *((UBYTE*)(fmmain.modptr))=1;
  471.         apu1=1;
  472.         break;
  473.         case 0x80:    //~released
  474.         if(fmmain.modflag==MODPLAY) *((UBYTE*)(fmmain.modptr))=0;
  475.         apu1=1;
  476.         break;
  477.         }
  478.         if(!apu1) {
  479.             if (!(message->Code&0x80)) {
  480.                 ie.ie_Code=message->Code;
  481.                 ie.ie_Qualifier=message->Qualifier;
  482.                 ie.ie_EventAddress=(APTR*)*((ULONG*)message->IAddress);
  483.                 if (MapRawKey(&ie,chartab,2,0)==1) asciicode=ToUpper(chartab[0]);
  484.             }
  485.         }
  486.     }
  487.  
  488.     if(asciicode) {
  489.         framewas=0;
  490.         if(asciicode==9) {
  491.             apu1=fmmain.sourcedir->listnumber;
  492.             for(;;) {
  493.                 if (message->Qualifier&0x03) apu1--; else apu1++;
  494.                 if (apu1==LISTS) apu1=0;
  495.                 if (apu1<0) apu1=LISTS-1;
  496.                 if(fmlist[apu1].li) {
  497.                     setsource(&fmlist[apu1]);
  498.                     break;
  499.                 }
  500.             }
  501.             if (!(fmmain.sourcedir->flags&LALLOCATED)) {
  502.                 frameoutput(fmmain.sourcedir);
  503.             }
  504.         } else if (!(fmmain.sourcedir->flags&LALLOCATED)&&asciicode) {
  505.             switch(asciicode)
  506.             {
  507.             break;
  508.             case 13:    //return
  509.             fakeintu.MouseX=fmmain.sourcedir->li->dirx+fmmain.ikkuna->BorderLeft;
  510.             fakeintu.MouseY=(fmmain.sourcedir->keyline-fmmain.sourcedir->firstline)*fmmain.listysize+fmmain.sourcedir->li->diry+fmmain.ikkuna->BorderTop;
  511.             if(message->Qualifier&0x03) fakeintu.Code=MENUDOWN; else fakeintu.Code=SELECTDOWN;
  512.             fakeintu.Class=IDCMP_MOUSEBUTTONS;
  513.             processclick(&fakeintu);
  514.             if(!(fmmain.sourcedir->flags&LALLOCATED)) {
  515.                 frameoutput(fmmain.sourcedir);
  516.             }
  517.             break;
  518.             }
  519.         }
  520.     }
  521.  
  522.     switch(class)
  523.     {
  524.     case IDCMP_ACTIVEWINDOW:
  525.     fmmain.fmactive|=2;
  526.     framewas=0;
  527.     break;
  528.     case IDCMP_INACTIVEWINDOW:
  529.     fmmain.fmactive&=~2;
  530.     framewas=0;
  531.     break;
  532.     case IDCMP_RAWKEY:
  533.     if(code&0x80&&fmmain.framenode&&!(fmmain.sourcedir->flags&LALLOCATED)) {
  534.         frameoutput(fmmain.sourcedir);
  535.     }
  536.     break;
  537.     case IDCMP_CLOSEWINDOW:
  538.     framewas=0;
  539.     launch(launchtable[QUITCONFIG],getconfignumber(QUITCONFIG),0,0);
  540.     break;
  541.     case IDCMP_REFRESHWINDOW:
  542.     BeginRefresh(fmmain.ikkuna);
  543.     EndRefresh(fmmain.ikkuna,1);
  544.     break;
  545.     case IDCMP_NEWSIZE:
  546.     framewas=0;
  547.     windownewsize();
  548.     break;
  549.     case IDCMP_DISKINSERTED:
  550.     case IDCMP_DISKREMOVED:
  551.     framewas=0;
  552.     for(code=0;code<WINDOWLISTS;code++) {
  553.         if (fmmain.li[code]&&!(fmmain.li[code]->list->flags&LALLOCATED)&&fmmain.li[code]->list->flags&LDEVLIST) drives(fmmain.li[code]->list);
  554.     }
  555.     break;
  556.     case IDCMP_MOUSEMOVE:
  557.     framewas=0;
  558.     apu1=message->MouseY-fmmain.ikkuna->BorderTop;
  559.     apulist=fmmain.sourcedir;
  560.     if(draggi==-1||!(message->Qualifier&IEQUALIFIER_LEFTBUTTON)) {
  561.         ReportMouse(0,fmmain.ikkuna);
  562.         draggi=-1;dragged=0;
  563.         break;
  564.     }
  565.     apunode1=mousenode(apulist,apulist->li->dirx,apu1);
  566.     do {
  567.         apu4=-1;
  568.         if(!apunode1&&apu1>=0) {
  569.             rss=&apulist->li->rscroll1;
  570.             if(apu1<apulist->li->diry&&apulist->firstline) {
  571.                     apulist->firstline--;
  572.                     apu4=apulist->firstline;
  573.             } else if (apu1>apulist->li->ediry&&apulist->firstline<apulist->totlines+apulist->li->visiblelines) {
  574.                     apulist->firstline++;
  575.                     apu4=apulist->firstline+apulist->li->visiblelines-1;
  576.             }
  577.             if(apu4>=0) {
  578.                 apunode2=(struct FMNode*)apulist;
  579.                 iteratenode(&apunode2);
  580.                 while(apu4--) iteratenode(&apunode2);
  581.                 if(apunode2&&apunode2->succ) {
  582.                     if(draggi)
  583.                         apunode2->flags|=NSELECTED;
  584.                         else
  585.                         apunode2->flags&=~NSELECTED;
  586.                 }
  587.                 apu3=rss->LineSpacing;
  588.                 rss->LineSpacing=1;
  589.                 apu2=rss->TopEntryNumber;
  590.                 updatelist(apulist);
  591.                 rss->TopEntryNumber=apu2;
  592.                 RealTimeScroll(rss);
  593.                 apulist->firstline=rss->TopEntryNumber;
  594.                 rss->LineSpacing=apu3;
  595.                 dragged=1;
  596.             }
  597.         }
  598.     } while(apu1&&!fmmain.ikkuna->UserPort->mp_MsgList.lh_Head->ln_Succ);
  599.     apu1=0;
  600.     apunode2=(struct FMNode*)apulist;
  601.     if(!(!apunode1||apunode1==apulist->lastclicked||!apulist->lastclicked||apunode1==apunode2||draggi<0)) {
  602.         while(iteratenode(&apunode2)) {
  603.             apu3=-1;
  604.             if(apunode2==apunode1||apunode2==apulist->lastclicked) apu3=apu1^1;
  605.             if(apu3==1) apu1=apu3;
  606.             apu2=apunode2->flags&NSELECTED;
  607.             if(apu1&&((apu2&&!draggi)|(!apu2&&draggi))) {
  608.                 apunode2->flags^=NSELECTED;
  609.                 outputlistline(apulist,apunode2);
  610.                 dragged=1;
  611.             }
  612.             if(!apu3) apu1=apu3;
  613.         }
  614.     }
  615.     break;
  616.     case IDCMP_GADGETUP:
  617.     case IDCMP_GADGETDOWN:
  618.     framewas=0;
  619.     processgadget(((struct Gadget*)message->IAddress)->GadgetID,class);
  620.     break;
  621.     case IDCMP_MOUSEBUTTONS:
  622.     framewas=0;
  623.     if (code==SELECTUP||code==SELECTDOWN||code==MENUDOWN||code==MENUUP) {
  624.         if(code==SELECTUP&&dragged) {
  625.             endofdirtxt(fmmain.sourcedir,0);
  626.             ReportMouse(0,fmmain.ikkuna);
  627.             draggi=-1;
  628.             dragged=0;
  629.         } else {    
  630.             draggi=processclick(message);
  631.             if(code==SELECTDOWN&&draggi>=0) ReportMouse(1,fmmain.ikkuna);
  632.         }
  633.     }
  634.     break;
  635.     }
  636.     ReplyMsg((struct Message*)message);
  637.     message=0;
  638.  
  639.     fmmain.fmactive&=~1;
  640.     if(fmmain.newconfig&0x0f) {
  641.         if((fmmain.newconfig&0x0f)==3) {
  642.             while(!suljenaytto(3));
  643.             fmconfig->screentype=fmmain.newconfig>>8;
  644.             if (!avaanaytto(3)) fmmain.quitti=1;
  645.             for(apu1=0;apu1<LISTS;apu1++) if(fmlist[apu1].flags==0) drives(&fmlist[apu1]);
  646.         } else if ((fmmain.newconfig&0x0f)==2) {
  647.             while(!suljenaytto(2));
  648.             fmconfig->screentype=fmmain.newconfig>>8;
  649.             if (!avaanaytto(2)) fmmain.quitti=1;
  650.         } else {
  651.             windownewsize();
  652.         }
  653.         framewas=0;
  654.     }
  655.     fmmain.newconfig=0;
  656.     fmmain.fmactive|=1;
  657.  
  658. }
  659. if(fmmain.quitti>4) {
  660.     if(fmmain.kill) return;
  661.     sleep(0);
  662.     if(fmmain.kill) return;
  663.     goto eventti;
  664. }
  665. if(fmmain.ikkuna) {
  666.     if(tstsubproc(1)) goto eventti;
  667. } else {
  668.     while(tstsubproc(0)) Delay(10);
  669. }
  670. if (fmmain.ikkuna&&fmmain.quitti==2&&!requestmsg(getstring(MSG_MAIN_QUIT),MSG_YES,MSG_NO,MSG_MAIN_AREYOUSURE)) goto eventti;
  671. aboutti(1);
  672. qquit:
  673. while(tstsubproc(0)) Delay(10);
  674. endframeoutput();
  675. }
  676.  
  677. void dirfileclick(struct FMList *list1,struct FMNode *node,WORD xx)
  678. {
  679. setparent(list1);
  680. if (node->flags & (NDEVICE|NASSIGN|NDIRECTORY)) {
  681.     if (list1->flags & LDIRLIST) {
  682.         AddPart(list1->path,NDFILE(node),PATH);
  683.     } else {
  684.         if (xx>=list1->li->dirx+8*fmmain.listxsize&&xx<list1->li->edirx&&NDCOMM(node)[0])
  685.             strcpy(list1->path,NDCOMM(node));
  686.             else
  687.             strcpy(list1->path,NDFILE(node));
  688.         if (node->flags&NASSIGN) parentpath(list1,0);
  689.     }
  690.     launch((APTR)&getdir,0,0,MSUBPROC);
  691. } else {
  692.     list1->fmmessage1[0]=0;
  693.     list1->fmmessage2[0]=0;
  694.     fmmessage(list1);
  695.     list1->lastclicked=node;
  696.     launch((APTR)&clickfile,0,0,MSUBPROC);
  697. }
  698. }
  699.  
  700. void gquit(void)
  701. {
  702. struct ProcMsg *pm;
  703. struct QuitConfig *config;
  704.  
  705. pm=sinitproc();
  706. config=getconfig(pm->cmc);
  707. if(config->areyousure)
  708.     fmmain.quitti=2;
  709.     else
  710.     fmmain.quitti=1;
  711. deinitproc(pm);
  712. }
  713. WORD getappicon(void)
  714. {
  715. struct SleepConfig *sc;
  716.  
  717. sc=getconfignumber(SLEEPCONFIG)->moreconfig;
  718. return((WORD)(sc->sleepwindow));
  719. }
  720. void gsleep(void)
  721. {
  722. struct ProcMsg *pm;
  723. struct SleepConfig *config;
  724.  
  725. pm=sinitproc();
  726. config=getconfig(pm->cmc);
  727. if(config->sleepwindow)
  728.     fmmain.quitti=6;
  729.     else
  730.     fmmain.quitti=5;
  731. deinitproc(pm);
  732. }
  733. void gstod(void)
  734. {
  735. struct ProcMsg *pm;
  736.  
  737. pm=sinitproc();
  738. if(((fmmain.sourcedir->flags|fmmain.destdir->flags)&LALLOCATED)==0) {
  739.     clearlist(fmmain.destdir);
  740.     duplist(fmmain.sourcedir,fmmain.destdir);
  741.     fmmain.destdir->firstline=fmmain.sourcedir->firstline;
  742.     fmmain.destdir->firstlinew=fmmain.sourcedir->firstlinew;
  743.     strcpy(fmmain.destdir->path,fmmain.sourcedir->path);
  744.     fmmain.destdir->flags&=~(LDIRLIST|LDEVLIST);
  745.     fmmain.destdir->flags|=fmmain.sourcedir->flags&(LDIRLIST|LDEVLIST);
  746.     if (fmmain.destdir->li) RefreshGList(&fmmain.destdir->li->string,fmmain.ikkuna,0,1);
  747.     csortlist(fmmain.destdir);
  748.     parselist(fmmain.destdir,0);
  749.     updadirmeter(fmmain.destdir);
  750.     outputlist(fmmain.destdir);
  751. }
  752. deinitproc(pm);
  753. }
  754.  
  755. void gconfig(void)
  756. {
  757. struct ProcMsg *pm;
  758. pm=sinitproc();
  759. if(!tstsubproc(1)) {
  760.     fmmain.newconfig=config();
  761.     Signal((struct Task*)fmmain.timeproc,SIGBREAKF_CTRL_D);
  762. }
  763. deinitproc(pm);
  764. }
  765. void gdrives(void)
  766. {
  767. struct ProcMsg *pm;
  768. pm=sinitproc();
  769. if (!(fmmain.sourcedir->flags&LALLOCATED)) drives(fmmain.sourcedir);
  770. deinitproc(pm);
  771. }
  772. void gparent(void)
  773. {
  774. struct ProcMsg *pm;
  775. UBYTE *apup1;
  776.  
  777. pm=sinitproc();
  778. if (!(fmmain.sourcedir->flags&LALLOCATED)) {
  779.     if(*(fmmain.sourcedir->path+strlen(fmmain.sourcedir->path)-1)==':') {
  780.         drives(fmmain.sourcedir);
  781.     } else {
  782.         apup1=PathPart(fmmain.sourcedir->path);*apup1=0; 
  783.         if (apup1==&fmmain.sourcedir->path[0]) {
  784.             drives(fmmain.sourcedir);
  785.         } else {
  786.             if (!getparent(fmmain.sourcedir)) launch((APTR)&getdir,0,0,MSUBPROC);
  787.         }
  788.     }
  789. }
  790. deinitproc(pm);
  791. }
  792. void ginvert(void)
  793. {
  794. struct ProcMsg *pm;
  795. struct FMNode *node;
  796.  
  797. pm=sinitproc();
  798. if (!(fmmain.sourcedir->flags&LALLOCATED)) {
  799.     for(node=fmmain.sourcedir->head;node->succ;node=node->succ) {
  800.         if(node->flags&NMATCHED) node->flags^=NSELECTED;
  801.     }
  802.     outputlist(fmmain.sourcedir);
  803.     endofdirtxt(fmmain.sourcedir,0);
  804. }
  805. deinitproc(pm);
  806. }
  807. void gclear(void)
  808. {
  809. struct ProcMsg *pm;
  810. struct FMNode *node;
  811.  
  812. pm=sinitproc();
  813. if (!(fmmain.sourcedir->flags&LALLOCATED)) {
  814.     for(node=fmmain.sourcedir->head;node->succ;node=node->succ) {
  815.         node->flags&=~NSELECTED;
  816.     }
  817.     outputlist(fmmain.sourcedir);
  818.     endofdirtxt(fmmain.sourcedir,0);
  819. }
  820. deinitproc(pm);
  821. }
  822.  
  823. ULONG waitsig(ULONG sigs)
  824. {
  825. ULONG rsigs;
  826.  
  827. for(;;) {
  828.     rsigs=Wait(sigs|SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D);
  829.     if(rsigs&SIGBREAKF_CTRL_C) {
  830.         Signal((struct Task*)fmmain.timeproc,SIGBREAKF_CTRL_C);
  831.     }
  832.     if(rsigs&SIGBREAKF_CTRL_D) {
  833.         Signal((struct Task*)fmmain.timeproc,SIGBREAKF_CTRL_D);
  834.     }
  835.     rsigs&=~((LONG)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D));
  836.     if(rsigs) break;
  837. }
  838. return(rsigs);
  839. }
  840.  
  841.  
  842. void *sleepconfigdefault(struct CMenuConfig *cmc)
  843. {
  844. struct SleepConfig *config;
  845. WORD ret;
  846.  
  847. ret=allocconfig(cmc,sizeof(struct SleepConfig));
  848. if(ret<0) return(cmc->moreconfig);
  849. if(!ret) return(0);
  850. config=(struct SleepConfig*)cmc->moreconfig;
  851. config->sleepwindow|=2;
  852. return(cmc->moreconfig);
  853. }
  854.  
  855. WORD sleepconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  856. {
  857. WORD c;
  858. struct SleepConfig *sc;
  859. WORD sleepwindow,appwindow;
  860.  
  861. sc=getconfig(cmc);
  862. setguigroup(gb,1,0);
  863. reqinfomsg(gb,MSG_SLEEP_SLEEPWINDOW,200,guiUC|guiLEFT);
  864. reqinfomsg(gb,MSG_SLEEP_APPICON,201,guiUC|guiLEFT);
  865. setguigroup(gb,2,0);
  866. sleepwindow=sc->sleepwindow&1;
  867. appwindow=(sc->sleepwindow&2)?1:0;
  868. reqcycle2msg(gb,200,&sleepwindow);
  869. reqcycle2msg(gb,201,&appwindow);
  870. commandanswer(gb);
  871. c=quickreq(gb);
  872. sc->sleepwindow=sleepwindow;
  873. sc->sleepwindow|=appwindow<<1;
  874. if(!appwindow) sc->sleepwindow|=1;
  875. return(c);
  876. }
  877.  
  878. void *quitconfigdefault(struct CMenuConfig *cmc)
  879. {
  880. struct QuitConfig *config;
  881. WORD ret;
  882.  
  883. ret=allocconfig(cmc,sizeof(struct QuitConfig));
  884. if(ret<0) return(cmc->moreconfig);
  885. if(!ret) return(0);
  886. config=(struct QuitConfig*)cmc->moreconfig;
  887. config->areyousure=1;
  888. return(cmc->moreconfig);
  889. }
  890.  
  891. WORD quitconfig(struct GUIBase *gb,struct CMenuConfig *cmc)
  892. {
  893. WORD c;
  894. struct QuitConfig *qc;
  895. WORD ays;
  896.  
  897. qc=getconfig(cmc);
  898. ays=qc->areyousure;
  899. setguigroup(gb,1,0);
  900. reqinfomsg(gb,MSG_MAIN_AREYOUSURE,200,guiUC|guiLEFT);
  901. setguigroup(gb,2,0);
  902. reqcycle2msg(gb,200,&ays);
  903. commandanswer(gb);
  904. c=quickreq(gb);
  905. qc->areyousure=ays;
  906. return(c);
  907. }
  908.