home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / DOpus4-GPL / Program / launchexternal.c < prev    next >
C/C++ Source or Header  |  2000-01-27  |  18KB  |  673 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopus.h"
  32. #include "view.h"
  33.  
  34. start_external(func)
  35. struct dopus_func_start *func;
  36. {
  37.     int arg;
  38.     char path[256],*ptr;
  39.  
  40.     func->key=NULL;
  41.     func->status=0;
  42.     func->resseg=NULL;
  43.  
  44.     if (!(func->replyport=LCreatePort(NULL,0))) return(0);
  45.     if (!(func->startup.wbstartup.sm_ArgList=LAllocRemember(&func->key,
  46.         sizeof(struct WBArg)*(func->argcount+1),MEMF_CLEAR|MEMF_PUBLIC)))
  47.         return(0);
  48.  
  49.     func->startup.wbstartup.sm_Message.mn_Node.ln_Type=NT_MESSAGE;
  50.     func->startup.wbstartup.sm_Message.mn_ReplyPort=func->replyport;
  51.     func->startup.wbstartup.sm_Message.mn_Length=(UWORD)sizeof(struct DOpusStartup);
  52.  
  53.     func->startup.wbstartup.sm_NumArgs=func->argcount;
  54.     for (arg=0;arg<func->argcount;arg++)
  55.         func->startup.wbstartup.sm_ArgList[arg].wa_Name=func->args[arg];
  56.  
  57.     strcpy(path,func->segname);
  58.     if (ptr=BaseName(path)) *ptr=0;
  59.     if (!(func->startup.wbstartup.sm_ArgList[0].wa_Lock=Lock(path,ACCESS_READ)))
  60.         return(0);
  61.  
  62.     func->startup.retcode=0;
  63.  
  64.     func->status=FS_CURDIR;
  65.     func->olddir=CurrentDir(func->startup.wbstartup.sm_ArgList[0].wa_Lock);
  66.  
  67.     if (!func->segment) {
  68.         if (system_version2) {
  69.             Forbid();
  70.             if (func->resseg=FindSegment(func->segname,NULL,0)) {
  71.                 func->resseg->seg_UC++;
  72.                 func->segment=func->resseg->seg_Seg;
  73.             }
  74.             Permit();
  75.         }
  76.         if (!func->segment &&
  77.             !(func->segment=(BPTR)LoadSeg(func->segname)))
  78.             return(0);
  79.     }
  80.  
  81.     func->status=FS_SEGMENT;
  82.  
  83.     func->startup.wbstartup.sm_Segment=func->segment;
  84.     if (!(func->startup.wbstartup.sm_Process=CreateProc(func->procname,
  85.         main_proc->pr_Task.tc_Node.ln_Pri,func->startup.wbstartup.sm_Segment,func->stack)))
  86.         return(0);
  87.  
  88.     func->startup.wbstartup.sm_ToolWindow=NULL;
  89.     PutMsg(func->startup.wbstartup.sm_Process,(struct Message *)&func->startup);
  90.  
  91.     func->status=FS_LAUNCHED;
  92.     return(1);
  93. }
  94.  
  95. close_external(func,wait)
  96. struct dopus_func_start *func;
  97. int wait;
  98. {
  99.     if (func->status>=FS_LAUNCHED && wait) {
  100.         WaitPort(func->replyport);
  101.         GetMsg(func->replyport);
  102.     }
  103.     if (func->status>=FS_SEGMENT) {
  104.         Forbid();
  105.         if (func->resseg) {
  106.             func->resseg->seg_UC--;
  107.             func->segment=0;
  108.         }
  109.         else if (!func->flags&FF_SAVESEG && func->segment) {
  110.             UnLoadSeg(func->segment);
  111.             func->segment=0;
  112.         }
  113.         Permit();
  114.     }
  115.     if (func->status>=FS_CURDIR) {
  116.         CurrentDir(func->olddir);
  117.         UnLock(func->startup.wbstartup.sm_ArgList[0].wa_Lock);
  118.     }
  119.     if (func->replyport) LDeletePort(func->replyport);
  120.     LFreeRemember(&func->key);
  121.     return(func->startup.retcode);
  122. }
  123.  
  124. void doconfig()
  125. {
  126.     char buf[100],buf1[20],replyname[50],portname[50],funcpath[80];
  127.     int old_bufcount,a;
  128.     struct MsgPort *conport,*cmdport;
  129.     struct dopusconfigmsg *repmsg;
  130.     struct configconfig cfg,*rcfg;
  131.     struct ConfigStuff cstuff;
  132.     struct dopus_func_start config_func;
  133.     char *func_args[2];
  134.     char *old_name;
  135.     char old_language[30];
  136.  
  137.     if (!(checkwindowquit())) return;
  138.  
  139.     lsprintf(replyname,"dopus4_config_reply%ld",system_dopus_runcount);
  140.     if (!(conport=LCreatePort(replyname,20))) return;
  141.  
  142.     lsprintf(buf,"%ld",system_dopus_runcount);
  143.     lsprintf(buf1,"dopus4_config%ld",system_dopus_runcount);
  144.  
  145.     strcpy(funcpath,"ConfigOpus");
  146.  
  147.     if (!configopus_segment) {
  148.         dostatustext(globstring[STR_LOADING_CONFIG]);
  149.         FindSystemFile("ConfigOpus",funcpath,80,SYSFILE_MODULE);
  150.     }
  151.  
  152.     func_args[0]=funcpath;
  153.     func_args[1]=buf;
  154.  
  155.     config_func.segment=configopus_segment;
  156.     config_func.procname="ConfigOpus";
  157.  
  158.     config_func.segname=funcpath;
  159.     config_func.argcount=2;
  160.     config_func.args=func_args;
  161.     config_func.stack=8000;
  162.     config_func.flags=(config->loadexternal&LOAD_CONFIG)?FF_SAVESEG:0;
  163.  
  164.     if (!(start_external(&config_func))) {
  165.         close_external(&config_func,0);
  166.         dostatustext(globstring[STR_CONFIG_NOT_FOUND]);
  167.         LDeletePort(conport);
  168.         return;
  169.     }
  170.  
  171.     dostatustext(globstring[STR_WAITING_FOR_PORT]);
  172.     lsprintf(portname,"dopus4_config_port%ld",system_dopus_runcount);
  173.     cmdport=NULL;
  174.  
  175.     for (a=0;a<100;a++) {
  176.         Forbid();
  177.         cmdport=FindPort(portname);
  178.         Permit();
  179.         if (cmdport) break;
  180.         Delay(5);
  181.     }
  182.  
  183.     if (!cmdport) {
  184.         close_external(&config_func,0);
  185.         dostatustext(globstring[STR_CONFIG_NOT_FOUND]);
  186.         LDeletePort(conport);
  187.         return;
  188.     }
  189.  
  190.     status_configuring=-1;
  191.     shutthingsdown(10);
  192.     old_bufcount=config->bufcount;
  193.     strcpy(old_language,config->language);
  194.     dotaskmsg(hotkeymsg_port,HOTKEY_KILLHOTKEYS,0,0,NULL,0);
  195.  
  196.     endnotifies();
  197.  
  198.     Forbid();
  199.     old_name=arexx_port->mp_Node.ln_Name;
  200.     arexx_port->mp_Node.ln_Name="foo";
  201.     Permit();
  202.  
  203.     FOREVER {
  204.         while (repmsg=(struct dopusconfigmsg *)GetMsg(conport)) {
  205.             switch (repmsg->command) {
  206.                 case CONFIG_ALL_DONE:
  207.                     ReplyMsg((struct Message *)repmsg);
  208.                     goto configdone;
  209.                 case CONFIG_GET_CONFIG:
  210.                     cfg.config=config;
  211.                     cfg.firsttype=dopus_firsttype;
  212.                     cfg.typekey=filetype_key;
  213.                     cfg.firstbank=dopus_firstgadbank;
  214.                     cfg.changed=config_changed;
  215.                     cfg.firsthotkey=dopus_firsthotkey;
  216.                     strcpy(cfg.configname,str_config_basename);
  217.                     repmsg->buffer=(char *)&cfg;
  218.                     break;
  219.                 case CONFIG_HERES_CONFIG:
  220.                     rcfg=(struct configconfig *)repmsg->buffer;
  221.                     dopus_firsttype=rcfg->firsttype;
  222.                     dopus_firstgadbank=rcfg->firstbank;
  223.                     dopus_firsthotkey=rcfg->firsthotkey;
  224.                     filetype_key=rcfg->typekey;
  225.                     config_changed=rcfg->changed;
  226.                     StrCombine(str_config_file,rcfg->configname,".CFG",256);
  227.                     strcpy(str_config_basename,rcfg->configname);
  228.                     Window=rcfg->Window; MainScreen=rcfg->Screen;
  229.                     status_configuring=1;
  230.                     break;
  231.                 case CONFIG_NEW_HOTKEY:
  232.                     dotaskmsg(hotkeymsg_port,HOTKEY_HOTKEYCHANGE,0,0,NULL,0);
  233.                     break;
  234.             }
  235.             ReplyMsg((struct Message *)repmsg);
  236.         }
  237.  
  238.         Wait(1<<conport->mp_SigBit);
  239.     }
  240.  
  241. configdone:
  242.     config_func.flags=(config->loadexternal&LOAD_CONFIG)?FF_SAVESEG:0;
  243.     close_external(&config_func,1);
  244.     configopus_segment=config_func.segment;
  245.  
  246.     status_configuring=-1;
  247.     Window=NULL; MainScreen=NULL;
  248.     dopus_curgadbank=dopus_firstgadbank;
  249.     data_gadgetrow_offset=data_drive_offset=0;
  250.     dotaskmsg(hotkeymsg_port,HOTKEY_HOTKEYCHANGE,0,0,NULL,0);
  251.     dotaskmsg(hotkeymsg_port,HOTKEY_NEWHOTKEYS,0,0,NULL,0);
  252.     if (config->bufcount!=old_bufcount) {
  253.         allocdirbuffers(config->bufcount);
  254.         for (a=0;a<2;a++) strcpy(str_pathbuffer[a],dopus_curwin[a]->directory);
  255.     }
  256.     if (strcmp(old_language,config->language)) read_data_files(0);
  257.  
  258.     for (a=0;a<3;a++) {
  259.         if (!(config->loadexternal&(1<<a)) && external_mod_segment[a]) {
  260.             UnLoadSeg(external_mod_segment[a]);
  261.             external_mod_segment[a]=0;
  262.         }
  263.     }
  264.  
  265.     fixcstuff(&cstuff);
  266.     CheckConfig(&cstuff);
  267.     SetUp(2);
  268.  
  269.     LDeletePort(conport);
  270.  
  271.     Forbid();
  272.     arexx_port->mp_Node.ln_Name=old_name;
  273.     Permit();
  274.  
  275.     rexx_command(config->configreturnscript,NULL);
  276.  
  277.     startnotifies();
  278.     status_configuring=0;
  279. }
  280.  
  281. static char *external_modules[3]={
  282.     "DOpus_Disk",
  283.     "DOpus_Print",
  284.     "DOpus_Icon"};
  285.  
  286. struct DiskData {
  287.     int function;
  288.     char funcpath[80];
  289.     char *args[16];
  290.     int argcount;
  291.     int background;
  292. };
  293.  
  294. void dopus_diskop(function,rexx,bg)
  295. int function,rexx,bg;
  296. {
  297.     struct ArbiterLaunch launch;
  298.     struct DiskData *disk_data;
  299.     struct DOpusRemember *memkey=NULL;
  300.     int a,fail=1;
  301.  
  302.     if ((disk_data=LAllocRemember(&memkey,sizeof(struct DiskData),MEMF_CLEAR))) {
  303.         dostatustext(globstring[STR_STARTING_DISK_MODULE]);
  304.  
  305.         disk_data->function=function;
  306.         disk_data->background=bg;
  307.  
  308.         strcpy(disk_data->funcpath,external_modules[SEG_DISK]);
  309.         if (external_mod_segment[SEG_DISK] ||
  310.             (FindSystemFile(external_modules[SEG_DISK],disk_data->funcpath,80,SYSFILE_MODULE))) {
  311.             disk_data->args[0]=disk_data->funcpath;
  312.  
  313.             switch (function) {
  314.                 case FUNC_FORMAT:
  315.                 case FUNC_BGFORMAT:
  316.                     disk_data->args[1]="f";
  317.                     break;
  318.                 case FUNC_DISKCOPY:
  319.                 case FUNC_BGDISKCOPY:
  320.                     disk_data->args[1]="d";
  321.                     break;
  322.                 case FUNC_INSTALL:
  323.                 case FUNC_BGINSTALL:
  324.                     disk_data->args[1]="i";
  325.                     break;
  326.                 default:
  327.                     return;
  328.             }
  329.  
  330.             disk_data->argcount=3;
  331.  
  332.             if (rexx) {
  333.                 if ((disk_data->argcount+=rexx_argcount)>16) disk_data->argcount=16;
  334.                 for (a=3;a<disk_data->argcount;a++) {
  335.                     if (disk_data->args[a]=LAllocRemember(&memkey,strlen(rexx_args[a-3])+1,0))
  336.                         strcpy(disk_data->args[a],rexx_args[a-3]);
  337.                 }
  338.             }
  339.  
  340.             for (a=disk_data->argcount;a<16;a++) disk_data->args[a]="";
  341.  
  342.             launch.launch_code=(void *)launch_diskop;
  343.             launch.launch_name="dopus_disk_launch";
  344.             launch.launch_memory=memkey;
  345.             launch.data=(APTR)disk_data;
  346.  
  347.             if (!bg) data_window_refresh=0;
  348.  
  349.             arbiter_command(ARBITER_LAUNCH,(APTR)&launch,(bg)?0:ARB_WAIT);
  350.  
  351.             if (!bg) {
  352.                 for (a=0;a<2;a++) {
  353.                     if (data_window_refresh&(1<<a)) {
  354.                         strcpy(str_pathbuffer[a],dopus_curwin[a]->realdevice);
  355.                         startgetdir(a,1);
  356.                     }
  357.                 }
  358.             }
  359.  
  360.             okay();
  361.             fail=0;
  362.         }
  363.     }
  364.     if (fail) dostatustext(globstring[STR_UNABLE_TO_LOAD_MODULE]);
  365. }
  366.  
  367. void __saveds launch_diskop()
  368. {
  369.     struct Process *my_process;
  370.     struct ArbiterMessage *my_startup_message;
  371.     struct DiskData *disk_data;
  372.     struct MsgPort *control_port;
  373.     struct dopus_func_start disk_func;
  374.     struct DOpusMessage *dopusmsg;
  375.     struct Screen *screen;
  376.     char portname[22],portbuf[22];
  377.     int retcode=-1;
  378.  
  379.     my_process=(struct Process *)FindTask(NULL);
  380.     my_process->pr_WindowPtr=(APTR)-1;
  381.     WaitPort(&my_process->pr_MsgPort);
  382.     my_startup_message=(struct ArbiterMessage *)GetMsg(&my_process->pr_MsgPort);
  383.  
  384.     disk_data=(struct DiskData *)(my_startup_message->data);
  385.  
  386.     if (control_port=CreateUniquePort("DOPUS_DISK",portbuf,NULL)) {
  387.         disk_func.segment=external_mod_segment[SEG_DISK];
  388.         disk_func.procname=external_modules[SEG_DISK];
  389.         disk_func.segname=disk_data->funcpath;
  390.  
  391.         StrCombine(portname,"&",portbuf,20);
  392.         disk_data->args[2]=portname;
  393.  
  394.         disk_func.argcount=disk_data->argcount;
  395.         disk_func.args=disk_data->args;
  396.         disk_func.stack=5000;
  397.         disk_func.flags=(config->loadexternal&LOAD_DISK)?FF_SAVESEG:0;
  398.  
  399.         if (start_external(&disk_func)) {
  400.             struct DOpusRemember *memory=NULL;
  401.             int newscreen=0;
  402.  
  403.             screen=NULL;
  404.  
  405.             if (disk_data->background && MainScreen &&
  406.                 (screen=open_subprocess_screen(globstring[STR_DISK_OP_TITLE],
  407.                     scr_font[FONT_REQUEST],&memory,NULL))) newscreen=1;
  408.  
  409.             FOREVER {
  410.                 if (GetMsg(disk_func.replyport)) break;
  411.                 while (dopusmsg=(struct DOpusMessage *)GetMsg(control_port)) {
  412.                     switch (dopusmsg->command) {
  413.                         case DOPUSMSG_GETVIS:
  414.                             fill_out_visinfo((struct VisInfo *)dopusmsg->data,screen);
  415.                             break;
  416.                         case DOPUSMSG_UPDATEDRIVE:
  417.                             if (!disk_data->background) {
  418.                                 BPTR lock,testlock;
  419.                                 int win,ret;
  420.                                 char *drive;
  421.  
  422.                                 drive=(char *)dopusmsg->data;
  423.                                 if (drive && drive[0]) {
  424.                                     if (lock=Lock(drive,ACCESS_READ)) {
  425.                                         for (win=0;win<2;win++) {
  426.                                             if (dopus_curwin[win]->realdevice[0] &&
  427.                                                 (testlock=Lock(dopus_curwin[win]->realdevice,ACCESS_READ))) {
  428.                                                 ret=CompareLock(lock,testlock);
  429.                                                 if (ret!=LOCK_DIFFERENT) data_window_refresh|=1<<win;
  430.                                                 UnLock(testlock);
  431.                                             }
  432.                                         }
  433.                                         UnLock(lock);
  434.                                     }
  435.                                 }
  436.                             }
  437.                             break;
  438.                     }
  439.                     ReplyMsg((struct Message *)dopusmsg);
  440.                 }
  441.                 Wait(1<<disk_func.replyport->mp_SigBit|1<<control_port->mp_SigBit);
  442.             }
  443.             if (newscreen) CloseScreen(screen);
  444.             LFreeRemember(&memory);
  445.         }
  446.  
  447.         close_external(&disk_func,0);
  448.         external_mod_segment[SEG_DISK]=disk_func.segment;
  449.         LDeletePort(control_port);
  450.         retcode=0;
  451.     }
  452.  
  453.     my_startup_message->command=retcode;
  454.     Forbid();
  455.     ReplyMsg((struct Message *)my_startup_message);
  456.     return;
  457. }
  458.  
  459. void dopus_print(rexx,arglist,printdir,port,vdata)
  460. int rexx;
  461. struct DOpusArgsList *arglist;
  462. int printdir;
  463. char *port;
  464. struct ViewData *vdata;
  465. {
  466.     char *args[16],portname[21],arglistbuf[20],funcpath[80];
  467.     struct dopus_func_start print_func;
  468.     int a,argcount,waitbits,abase=3;
  469.  
  470.     if (!vdata) dostatustext(globstring[STR_STARTING_PRINT_MODULE]);
  471.  
  472.     print_func.segment=external_mod_segment[SEG_PRINT];
  473.     print_func.procname=external_modules[SEG_PRINT];
  474.  
  475.     strcpy(funcpath,external_modules[SEG_PRINT]);
  476.  
  477.     if (!print_func.segment)
  478.         FindSystemFile(external_modules[SEG_PRINT],funcpath,80,SYSFILE_MODULE);
  479.  
  480.     print_func.segname=funcpath;
  481.  
  482.     args[0]=print_func.segname;
  483.  
  484.     StrCombine(portname,"&",port,20);
  485.     args[1]=portname;
  486.  
  487.     if (printdir) {
  488.         int win;
  489.  
  490.         if (!rexx || rexx_argcount<1 ||
  491.             (win=atoi(rexx_args[0]))<0 || win>1) win=data_active_window;
  492.         lsprintf(arglistbuf,"@%ld",win);
  493.         abase=2;
  494.         --rexx_argcount;
  495.     }
  496.     else lsprintf(arglistbuf,"!%ld",arglist);
  497.  
  498.     args[2]=arglistbuf;
  499.     argcount=3;
  500.  
  501.     if (rexx && rexx_argcount>0) {
  502.         if ((argcount+=rexx_argcount)>16) argcount=16;
  503.         for (a=3;a<argcount;a++) args[a]=rexx_args[a-abase];
  504.     }
  505.  
  506.     for (a=argcount;a<16;a++) args[a]="";
  507.  
  508.     print_func.argcount=argcount;
  509.     print_func.args=args;
  510.     print_func.stack=5000;
  511.     print_func.flags=(config->loadexternal&LOAD_PRINT)?FF_SAVESEG:0;
  512.  
  513.     if (!(start_external(&print_func))) {
  514.         close_external(&print_func,0);
  515.         if (!vdata) dostatustext(globstring[STR_UNABLE_TO_LOAD_MODULE]);
  516.         return;
  517.     }
  518.  
  519.     waitbits=1<<print_func.replyport->mp_SigBit;
  520.     if (vdata) waitbits|=1<<vdata->view_port->mp_SigBit;
  521.     else waitbits|=rexx_signalbit;
  522.  
  523.     FOREVER {
  524.         if ((Wait(waitbits))&rexx_signalbit && !vdata) {
  525.             rexx_dispatch(0);
  526.             continue;
  527.         }
  528.         if (vdata) {
  529.             struct DOpusMessage *dmsg;
  530.             struct DOpusArgsList *arg;
  531.  
  532.             while (dmsg=(struct DOpusMessage *)GetMsg(vdata->view_port)) {
  533.                 switch (dmsg->command) {
  534.                     case DOPUSMSG_GETVIS:
  535.                         CopyMem((char *)&vdata->view_vis_info,(char *)dmsg->data,
  536.                             sizeof(struct VisInfo));
  537.                         break;
  538.                     case DOPUSMSG_GETNEXTFILE:
  539.                         arg=(struct DOpusArgsList *)dmsg->data;
  540.                         if (arg->single_file) {
  541.                             strcpy(arg->file_data,arg->single_file);
  542.                             arg->single_file=NULL;
  543.                         }
  544.                         else arg->file_data[0]=0;
  545.                         break;
  546.                 }
  547.                 ReplyMsg((struct Message *)dmsg);
  548.             }
  549.         }
  550.         if (GetMsg(print_func.replyport)) break;
  551.     }
  552.  
  553.     close_external(&print_func,0);
  554.     external_mod_segment[SEG_PRINT]=print_func.segment;
  555.  
  556.     if (!vdata) okay();
  557. }
  558.  
  559. dopus_iconinfo(filename)
  560. char *filename;
  561. {
  562.     char *args[3],portname[14],funcpath[80];
  563.     struct dopus_func_start icon_func;
  564.     int a;
  565.  
  566.     icon_func.segment=external_mod_segment[SEG_ICON];
  567.     icon_func.procname=external_modules[SEG_ICON];
  568.  
  569.     strcpy(funcpath,external_modules[SEG_ICON]);
  570.  
  571.     if (!icon_func.segment)
  572.         FindSystemFile(external_modules[SEG_ICON],funcpath,80,SYSFILE_MODULE);
  573.  
  574.     icon_func.segname=funcpath;
  575.  
  576.     StrCombine(portname,"&",str_arexx_portname,13);
  577.  
  578.     args[0]=icon_func.segname;
  579.     args[1]=portname;
  580.     args[2]=filename;
  581.  
  582.     icon_func.argcount=3;
  583.     icon_func.args=args;
  584.     icon_func.stack=5000;
  585.     icon_func.flags=(config->loadexternal&LOAD_ICON)?FF_SAVESEG:0;
  586.  
  587.     if (!(start_external(&icon_func))) {
  588.         close_external(&icon_func,0);
  589.         dostatustext(globstring[STR_UNABLE_TO_LOAD_MODULE]);
  590.         return(-4);
  591.     }
  592.  
  593.     FOREVER {
  594.         if ((Wait(1<<icon_func.replyport->mp_SigBit|rexx_signalbit))&rexx_signalbit) {
  595.             rexx_dispatch(0);
  596.             continue;
  597.         }
  598.         if (GetMsg(icon_func.replyport)) break;
  599.     }
  600.  
  601.     a=close_external(&icon_func,0);
  602.     external_mod_segment[SEG_ICON]=icon_func.segment;
  603.     return(a);
  604. }
  605.  
  606. void setup_externals()
  607. {
  608.     int a;
  609.     char funcbuf[256];
  610.     APTR wsave;
  611.  
  612.     wsave=main_proc->pr_WindowPtr;
  613.     main_proc->pr_WindowPtr=(APTR)-1;
  614.  
  615.     if (config->loadexternal&LOAD_CONFIG) {
  616.         FindSystemFile("ConfigOpus",funcbuf,256,SYSFILE_MODULE);
  617.         configopus_segment=LoadSeg(funcbuf);
  618.     }
  619.     else configopus_segment=NULL;
  620.  
  621.     for (a=0;a<3;a++) {
  622.         if (config->loadexternal&(1<<a)) {
  623.             FindSystemFile(external_modules[a],funcbuf,256,SYSFILE_MODULE);
  624.             external_mod_segment[a]=LoadSeg(funcbuf);
  625.         }
  626.         else external_mod_segment[a]=NULL;
  627.     }
  628.  
  629.     main_proc->pr_WindowPtr=wsave;
  630. }
  631.  
  632. void fill_out_visinfo(vis,scr)
  633. struct VisInfo *vis;
  634. struct Screen *scr;
  635. {
  636.     if (scr && (!Window || Window->WScreen!=scr)) {
  637.         vis->vi_flags&=~VISF_WINDOW;
  638.         vis->vi_screen=scr;
  639.  
  640.         vis->vi_fg=config->requestfg;
  641.         vis->vi_bg=config->requestbg;
  642.         vis->vi_shine=config->gadgettopcol;
  643.         vis->vi_shadow=config->gadgetbotcol;
  644.         vis->vi_stringcol[0]=config->stringfgcol;
  645.         vis->vi_stringcol[1]=config->stringbgcol;
  646.         vis->vi_activestringcol[0]=config->stringselfgcol;
  647.         vis->vi_activestringcol[1]=config->stringselbgcol;
  648.     }
  649.     else {
  650.         if (vis->vi_flags&VISF_WINDOW) vis->vi_screen=(struct Screen *)Window;
  651.         else if (Window) vis->vi_screen=Window->WScreen;
  652.         else vis->vi_screen=NULL;
  653.  
  654.         vis->vi_fg=screen_pens[config->requestfg].pen;
  655.         vis->vi_bg=screen_pens[config->requestbg].pen;
  656.         vis->vi_shine=screen_pens[config->gadgettopcol].pen;
  657.         vis->vi_shadow=screen_pens[config->gadgetbotcol].pen;
  658.         vis->vi_stringcol[0]=screen_pens[config->stringfgcol].pen;
  659.         vis->vi_stringcol[1]=screen_pens[config->stringbgcol].pen;
  660.         vis->vi_activestringcol[0]=screen_pens[config->stringselfgcol].pen;
  661.         vis->vi_activestringcol[1]=screen_pens[config->stringselbgcol].pen;
  662.     }
  663.  
  664.     if (vis->vi_flags&VISF_8POINTFONT) vis->vi_font=scr_font[FONT_GENERAL];
  665.     else vis->vi_font=scr_font[FONT_REQUEST];
  666.  
  667.     if (config->generalscreenflags&SCR_GENERAL_REQDRAG)
  668.         vis->vi_flags|=VISF_BORDERS;
  669.     else vis->vi_flags&=~VISF_BORDERS;
  670.  
  671.     vis->vi_language=config->language;
  672. }
  673.