4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
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.
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.
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.
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.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
33 #include <dos/dostags.h>
36 #define STACK_SIZE AROS_STACKSIZE
38 #define STACK_SIZE 8192
41 static ULONG data_window_refresh
; /* Windows that need refreshing */
43 int start_external(func
)
44 struct dopus_func_start
*func
;
48 ULONG stacksize
= func
->stack
;
54 if (!(func
->replyport
=LCreatePort(NULL
,0))) return(0);
55 if (!(func
->startup
.wbstartup
.sm_ArgList
=LAllocRemember(&func
->key
,
56 sizeof(struct WBArg
)*(func
->argcount
+1),MEMF_CLEAR
|MEMF_PUBLIC
)))
59 func
->startup
.wbstartup
.sm_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
60 func
->startup
.wbstartup
.sm_Message
.mn_ReplyPort
=func
->replyport
;
61 func
->startup
.wbstartup
.sm_Message
.mn_Length
=(UWORD
)sizeof(struct DOpusStartup
);
63 func
->startup
.wbstartup
.sm_NumArgs
=func
->argcount
;
64 for (arg
=0;arg
<func
->argcount
;arg
++)
65 func
->startup
.wbstartup
.sm_ArgList
[arg
].wa_Name
=func
->args
[arg
];
67 strcpy(path
,func
->segname
);
68 if ((ptr
=BaseName(path
))) *ptr
=0;
69 D(bug("start_external: Lock(%s)\n",path
));
70 if (!(func
->startup
.wbstartup
.sm_ArgList
[0].wa_Lock
=Lock(path
,ACCESS_READ
)))
73 func
->startup
.retcode
=0;
75 func
->status
=FS_CURDIR
;
76 func
->olddir
=CurrentDir(func
->startup
.wbstartup
.sm_ArgList
[0].wa_Lock
);
79 // if (system_version2) {
81 if ((func
->resseg
=FindSegment(func
->segname
,NULL
,0))) {
82 D(bug("Segment %s found\n",func
->segname
));
83 func
->resseg
->seg_UC
++;
84 func
->segment
=func
->resseg
->seg_Seg
;
89 !(func
->segment
=(BPTR
)LoadSeg(func
->segname
)))
93 func
->status
=FS_SEGMENT
;
95 func
->startup
.wbstartup
.sm_Segment
=func
->segment
;
96 D(bug("start_external: CreateProc(%s from %lx)\n",func
->procname
,func
->startup
.wbstartup
.sm_Segment
));
97 // if (!(func->startup.wbstartup.sm_Process=CreateProc(func->procname,
98 // main_proc->pr_Task.tc_Node.ln_Pri,func->startup.wbstartup.sm_Segment,func->stack)))
100 if (stacksize
< STACK_SIZE
) stacksize
= STACK_SIZE
;
101 if (!(func
->startup
.wbstartup
.sm_Process
=&CreateNewProcTags(NP_Name
, (IPTR
)func
->procname
,
102 NP_Priority
, main_proc
->pr_Task
.tc_Node
.ln_Pri
,
103 NP_Seglist
, func
->startup
.wbstartup
.sm_Segment
,
104 NP_StackSize
, stacksize
,
105 NP_FreeSeglist
, FALSE
,
106 NP_CloseInput
, FALSE
,
107 NP_CloseOutput
, FALSE
,
108 TAG_END
)->pr_MsgPort
))
112 func
->startup
.wbstartup
.sm_ToolWindow
=NULL
;
113 PutMsg(func
->startup
.wbstartup
.sm_Process
,(struct Message
*)&func
->startup
);
115 func
->status
=FS_LAUNCHED
;
119 int close_external(func
,wait
)
120 struct dopus_func_start
*func
;
123 if (func
->status
>=FS_LAUNCHED
&& wait
) {
124 WaitPort(func
->replyport
);
125 GetMsg(func
->replyport
);
127 if (func
->status
>=FS_SEGMENT
) {
130 func
->resseg
->seg_UC
--;
133 else if (!func
->flags
&FF_SAVESEG
&& func
->segment
) {
134 UnLoadSeg(func
->segment
);
139 if (func
->status
>=FS_CURDIR
) {
140 CurrentDir(func
->olddir
);
141 UnLock(func
->startup
.wbstartup
.sm_ArgList
[0].wa_Lock
);
143 if (func
->replyport
) LDeletePort(func
->replyport
);
144 LFreeRemember(&func
->key
);
145 return(func
->startup
.retcode
);
150 char buf
[100],buf1
[20],replyname
[50],portname
[50],funcpath
[80];
152 struct MsgPort
*conport
,*cmdport
;
153 struct dopusconfigmsg
*repmsg
;
154 struct configconfig cfg
,*rcfg
;
155 struct ConfigStuff cstuff
;
156 struct dopus_func_start config_func
;
159 char old_language
[30];
161 if (!(checkwindowquit())) return;
163 lsprintf(replyname
,"%s%ld",config_replyport_basename
,(long int)system_dopus_runcount
);
164 if (!(conport
=LCreatePort(replyname
,20))) return;
166 lsprintf(buf
,"%ld",(long int)system_dopus_runcount
);
167 lsprintf(buf1
,"dopus4_config%ld",(long int)system_dopus_runcount
);
169 strcpy(funcpath
,"ConfigOpus");
171 if (!configopus_segment
) {
172 dostatustext(globstring
[STR_LOADING_CONFIG
]);
173 FindSystemFile("ConfigOpus",funcpath
,80,SYSFILE_MODULE
);
176 func_args
[0]=funcpath
;
179 config_func
.segment
=configopus_segment
;
180 config_func
.procname
="ConfigOpus";
182 config_func
.segname
=funcpath
;
183 config_func
.argcount
=2;
184 config_func
.args
=func_args
;
185 config_func
.stack
=STACK_SIZE
;
186 config_func
.flags
=(config
->loadexternal
&LOAD_CONFIG
)?FF_SAVESEG
:0;
188 if (!(start_external(&config_func
))) {
189 close_external(&config_func
,0);
190 dostatustext(globstring
[STR_CONFIG_NOT_FOUND
]);
191 LDeletePort(conport
);
195 dostatustext(globstring
[STR_WAITING_FOR_PORT
]);
196 lsprintf(portname
,"dopus4_config_port%ld",(long int)system_dopus_runcount
);
199 for (a
=0;a
<100;a
++) {
201 cmdport
=FindPort(portname
);
208 close_external(&config_func
,0);
209 dostatustext(globstring
[STR_CONFIG_NOT_FOUND
]);
210 LDeletePort(conport
);
213 status_configuring
=-1;
215 old_bufcount
=config
->bufcount
;
216 strcpy(old_language
,config
->language
);
217 dotaskmsg(hotkeymsg_port
,HOTKEY_KILLHOTKEYS
,0,0,NULL
,0);
222 old_name
=arexx_port
->mp_Node
.ln_Name
;
223 arexx_port
->mp_Node
.ln_Name
="foo";
227 while ((repmsg
=(struct dopusconfigmsg
*)GetMsg(conport
))) {
228 switch (repmsg
->command
) {
229 case CONFIG_ALL_DONE
:
230 ReplyMsg((struct Message
*)repmsg
);
232 case CONFIG_GET_CONFIG
:
234 cfg
.firsttype
=dopus_firsttype
;
235 cfg
.typekey
=filetype_key
;
236 cfg
.firstbank
=dopus_firstgadbank
;
237 cfg
.changed
=config_changed
;
238 cfg
.firsthotkey
=dopus_firsthotkey
;
239 strcpy(cfg
.configname
,str_config_basename
);
240 D(bug("launchexternal: MainScreen = %lx\n",MainScreen
));
241 cfg
.Screen
=MainScreen
;
242 repmsg
->buffer
=(char *)&cfg
;
244 case CONFIG_HERES_CONFIG
:
245 rcfg
=(struct configconfig
*)repmsg
->buffer
;
246 dopus_firsttype
=rcfg
->firsttype
;
247 dopus_firstgadbank
=rcfg
->firstbank
;
248 dopus_firsthotkey
=rcfg
->firsthotkey
;
249 filetype_key
=rcfg
->typekey
;
250 config_changed
=rcfg
->changed
;
251 StrCombine(str_config_file
,rcfg
->configname
,".CFG",256);
252 strcpy(str_config_basename
,rcfg
->configname
);
253 // Window=rcfg->Window; MainScreen=rcfg->Screen;
254 status_configuring
=1;
256 case CONFIG_NEW_HOTKEY
:
257 dotaskmsg(hotkeymsg_port
,HOTKEY_HOTKEYCHANGE
,0,0,NULL
,0);
260 ReplyMsg((struct Message
*)repmsg
);
263 Wait(1<<conport
->mp_SigBit
);
267 config_func
.flags
=(config
->loadexternal
&LOAD_CONFIG
)?FF_SAVESEG
:0;
268 close_external(&config_func
,1);
269 configopus_segment
=config_func
.segment
;
271 dopus_curgadbank
=dopus_firstgadbank
;
272 data_gadgetrow_offset
=data_drive_offset
=0;
275 if (config_changed
==2) config_changed
=0;
277 status_configuring
=-1;
278 // Window=NULL; MainScreen=NULL;
279 dotaskmsg(hotkeymsg_port
,HOTKEY_HOTKEYCHANGE
,0,0,NULL
,0);
280 dotaskmsg(hotkeymsg_port
,HOTKEY_NEWHOTKEYS
,0,0,NULL
,0);
281 if (config
->bufcount
!=old_bufcount
) {
282 allocdirbuffers(config
->bufcount
);
283 for (a
=0;a
<2;a
++) strcpy(str_pathbuffer
[a
],dopus_curwin
[a
]->directory
);
285 if (strcmp(old_language
,config
->language
)) read_data_files(0);
288 if (!(config
->loadexternal
&(1<<a
)) && external_mod_segment
[a
]) {
289 UnLoadSeg(external_mod_segment
[a
]);
290 external_mod_segment
[a
]=0;
295 CheckConfig(&cstuff
);
304 dostatustext(globstring
[STR_WELCOME_BACK_TO_DOPUS
]);
308 LDeletePort(conport
);
311 arexx_port
->mp_Node
.ln_Name
=old_name
;
314 rexx_command(config
->configreturnscript
,NULL
);
317 status_configuring
=0;
320 static char *external_modules
[3]={
333 void dopus_diskop(function
,rexx
,bg
)
334 int function
,rexx
,bg
;
336 struct ArbiterLaunch launch
;
337 struct DiskData
*disk_data
;
338 struct DOpusRemember
*memkey
=NULL
;
341 if ((disk_data
=LAllocRemember(&memkey
,sizeof(struct DiskData
),MEMF_CLEAR
))) {
342 dostatustext(globstring
[STR_STARTING_DISK_MODULE
]);
344 disk_data
->function
=function
;
345 disk_data
->background
=bg
;
347 strcpy(disk_data
->funcpath
,external_modules
[SEG_DISK
]);
348 if (external_mod_segment
[SEG_DISK
] ||
349 (FindSystemFile(external_modules
[SEG_DISK
],disk_data
->funcpath
,80,SYSFILE_MODULE
)))
351 D(bug("dopus_diskop: funcpath = %s\n",disk_data
->funcpath
));
352 disk_data
->args
[0]=disk_data
->funcpath
;
357 disk_data
->args
[1]="f";
360 case FUNC_BGDISKCOPY
:
361 disk_data
->args
[1]="d";
365 disk_data
->args
[1]="i";
371 disk_data
->argcount
=3;
374 if ((disk_data
->argcount
+=rexx_argcount
)>16) disk_data
->argcount
=16;
375 for (a
=3;a
<disk_data
->argcount
;a
++) {
376 if ((disk_data
->args
[a
]=LAllocRemember(&memkey
,strlen(rexx_args
[a
-3])+1,0)))
377 strcpy(disk_data
->args
[a
],rexx_args
[a
-3]);
381 for (a
=disk_data
->argcount
;a
<16;a
++) disk_data
->args
[a
]="";
383 launch
.launch_code
=(void *)launch_diskop
;
384 launch
.launch_name
="dopus_disk_launch";
385 launch
.launch_memory
=memkey
;
386 launch
.data
=(APTR
)disk_data
;
388 if (!bg
) data_window_refresh
=0;
390 arbiter_command(ARBITER_LAUNCH
,(APTR
)&launch
,(bg
)?0:ARB_WAIT
);
394 if (data_window_refresh
&(1<<a
)) {
395 strcpy(str_pathbuffer
[a
],dopus_curwin
[a
]->realdevice
);
405 if (fail
) dostatustext(globstring
[STR_UNABLE_TO_LOAD_MODULE
]);
408 void __saveds
launch_diskop()
410 struct Process
*my_process
;
411 struct ArbiterMessage
*my_startup_message
;
412 struct DiskData
*disk_data
;
413 struct MsgPort
*control_port
;
414 struct dopus_func_start disk_func
;
415 struct DOpusMessage
*dopusmsg
;
416 struct Screen
*screen
;
417 char portname
[22],portbuf
[22];
420 my_process
=(struct Process
*)FindTask(NULL
);
421 my_process
->pr_WindowPtr
=(APTR
)-1;
422 WaitPort(&my_process
->pr_MsgPort
);
423 my_startup_message
=(struct ArbiterMessage
*)GetMsg(&my_process
->pr_MsgPort
);
425 disk_data
=(struct DiskData
*)(my_startup_message
->data
);
427 if ((control_port
=CreateUniquePort("DOPUS_DISK",portbuf
,NULL
))) {
428 disk_func
.segment
=external_mod_segment
[SEG_DISK
];
429 disk_func
.procname
=external_modules
[SEG_DISK
];
430 disk_func
.segname
=disk_data
->funcpath
;
432 StrCombine(portname
,"&",portbuf
,20);
433 disk_data
->args
[2]=portname
;
435 disk_func
.argcount
=disk_data
->argcount
;
436 disk_func
.args
=disk_data
->args
;
437 disk_func
.stack
=STACK_SIZE
;
438 disk_func
.flags
=(config
->loadexternal
&LOAD_DISK
)?FF_SAVESEG
:0;
440 if (start_external(&disk_func
)) {
441 struct DOpusRemember
*memory
=NULL
;
446 if (disk_data->background && MainScreen &&
447 (screen=open_subprocess_screen(globstring[STR_DISK_OP_TITLE],
448 scr_font[FONT_REQUEST],&memory,NULL))) newscreen=1;
451 if (GetMsg(disk_func
.replyport
)) break;
452 while ((dopusmsg
=(struct DOpusMessage
*)GetMsg(control_port
))) {
453 switch (dopusmsg
->command
) {
454 case DOPUSMSG_GETVIS
:
455 fill_out_visinfo((struct VisInfo
*)dopusmsg
->data
,screen
);
457 case DOPUSMSG_UPDATEDRIVE
:
458 if (!disk_data
->background
) {
463 drive
=(char *)dopusmsg
->data
;
464 if (drive
&& drive
[0]) {
465 if ((lock
=Lock(drive
,ACCESS_READ
))) {
466 for (win
=0;win
<2;win
++) {
467 if (dopus_curwin
[win
]->realdevice
[0] &&
468 (testlock
=Lock(dopus_curwin
[win
]->realdevice
,ACCESS_READ
))) {
469 ret
=CompareLock(lock
,testlock
);
470 if (ret
!=LOCK_DIFFERENT
) data_window_refresh
|=1<<win
;
480 ReplyMsg((struct Message
*)dopusmsg
);
482 Wait(1<<disk_func
.replyport
->mp_SigBit
|1<<control_port
->mp_SigBit
);
484 // if (newscreen) CloseScreen(screen);
485 LFreeRemember(&memory
);
488 close_external(&disk_func
,0);
489 external_mod_segment
[SEG_DISK
]=disk_func
.segment
;
490 LDeletePort(control_port
);
494 my_startup_message
->command
=retcode
;
496 ReplyMsg((struct Message
*)my_startup_message
);
500 void dopus_print(rexx
,arglist
,printdir
,port
,vdata
)
502 struct DOpusArgsList
*arglist
;
505 struct ViewData
*vdata
;
507 char *args
[16],portname
[21],arglistbuf
[20],funcpath
[80];
508 struct dopus_func_start print_func
;
509 int a
,argcount
,waitbits
,abase
=3;
511 if (!vdata
) dostatustext(globstring
[STR_STARTING_PRINT_MODULE
]);
513 print_func
.segment
=external_mod_segment
[SEG_PRINT
];
514 print_func
.procname
=external_modules
[SEG_PRINT
];
516 strcpy(funcpath
,external_modules
[SEG_PRINT
]);
518 if (!print_func
.segment
)
519 FindSystemFile(external_modules
[SEG_PRINT
],funcpath
,80,SYSFILE_MODULE
);
521 print_func
.segname
=funcpath
;
523 args
[0]=print_func
.segname
;
525 StrCombine(portname
,"&",port
,20);
531 if (!rexx
|| rexx_argcount
<1 ||
532 (win
=atoi(rexx_args
[0]))<0 || win
>1) win
=data_active_window
;
533 lsprintf(arglistbuf
,"@%ld",(long int)win
);
537 else lsprintf(arglistbuf
,"!%ld",(long int)arglist
);
542 if (rexx
&& rexx_argcount
>0) {
543 if ((argcount
+=rexx_argcount
)>16) argcount
=16;
544 for (a
=3;a
<argcount
;a
++) args
[a
]=rexx_args
[a
-abase
];
547 for (a
=argcount
;a
<16;a
++) args
[a
]="";
549 print_func
.argcount
=argcount
;
550 print_func
.args
=args
;
551 print_func
.stack
=STACK_SIZE
;
552 print_func
.flags
=(config
->loadexternal
&LOAD_PRINT
)?FF_SAVESEG
:0;
554 if (!(start_external(&print_func
))) {
555 close_external(&print_func
,0);
556 if (!vdata
) dostatustext(globstring
[STR_UNABLE_TO_LOAD_MODULE
]);
560 waitbits
=1<<print_func
.replyport
->mp_SigBit
;
561 if (vdata
) waitbits
|=1<<vdata
->view_port
->mp_SigBit
;
562 else waitbits
|=rexx_signalbit
;
565 if ((Wait(waitbits
))&rexx_signalbit
&& !vdata
) {
570 struct DOpusMessage
*dmsg
;
571 struct DOpusArgsList
*arg
;
573 while ((dmsg
=(struct DOpusMessage
*)GetMsg(vdata
->view_port
))) {
574 switch (dmsg
->command
) {
575 case DOPUSMSG_GETVIS
:
576 CopyMem((char *)&vdata
->view_vis_info
,(char *)dmsg
->data
,
577 sizeof(struct VisInfo
));
579 case DOPUSMSG_GETNEXTFILE
:
580 arg
=(struct DOpusArgsList
*)dmsg
->data
;
581 if (arg
->single_file
) {
582 strcpy(arg
->file_data
,arg
->single_file
);
583 arg
->single_file
=NULL
;
585 else arg
->file_data
[0]=0;
588 ReplyMsg((struct Message
*)dmsg
);
591 if (GetMsg(print_func
.replyport
)) break;
594 close_external(&print_func
,0);
595 external_mod_segment
[SEG_PRINT
]=print_func
.segment
;
600 int dopus_iconinfo(filename
)
603 char *args
[3],portname
[14],funcpath
[80];
604 struct dopus_func_start icon_func
;
607 icon_func
.segment
=external_mod_segment
[SEG_ICON
];
608 icon_func
.procname
=external_modules
[SEG_ICON
];
610 strcpy(funcpath
,external_modules
[SEG_ICON
]);
612 if (!icon_func
.segment
)
613 FindSystemFile(external_modules
[SEG_ICON
],funcpath
,80,SYSFILE_MODULE
);
615 icon_func
.segname
=funcpath
;
617 StrCombine(portname
,"&",str_arexx_portname
,13);
619 args
[0]=icon_func
.segname
;
623 icon_func
.argcount
=3;
625 icon_func
.stack
=STACK_SIZE
;
626 icon_func
.flags
=(config
->loadexternal
&LOAD_ICON
)?FF_SAVESEG
:0;
628 if (!(start_external(&icon_func
))) {
629 close_external(&icon_func
,0);
630 dostatustext(globstring
[STR_UNABLE_TO_LOAD_MODULE
]);
635 if ((Wait(1<<icon_func
.replyport
->mp_SigBit
|rexx_signalbit
))&rexx_signalbit
) {
639 if (GetMsg(icon_func
.replyport
)) break;
642 a
=close_external(&icon_func
,0);
643 external_mod_segment
[SEG_ICON
]=icon_func
.segment
;
647 void setup_externals()
653 wsave
=main_proc
->pr_WindowPtr
;
654 main_proc
->pr_WindowPtr
=(APTR
)-1;
656 if (config
->loadexternal
&LOAD_CONFIG
) {
657 FindSystemFile("ConfigOpus",funcbuf
,256,SYSFILE_MODULE
);
658 configopus_segment
=LoadSeg(funcbuf
);
660 else configopus_segment
=NULL
;
663 if (config
->loadexternal
&(1<<a
)) {
664 FindSystemFile(external_modules
[a
],funcbuf
,256,SYSFILE_MODULE
);
665 external_mod_segment
[a
]=LoadSeg(funcbuf
);
667 else external_mod_segment
[a
]=NULL
;
670 main_proc
->pr_WindowPtr
=wsave
;
673 void fill_out_visinfo(vis
,scr
)
677 if (scr
&& (!Window
|| Window
->WScreen
!=scr
)) {
678 vis
->vi_flags
&=~VISF_WINDOW
;
681 vis
->vi_fg
=config
->requestfg
;
682 vis
->vi_bg
=config
->requestbg
;
683 vis
->vi_shine
=config
->gadgettopcol
;
684 vis
->vi_shadow
=config
->gadgetbotcol
;
685 vis
->vi_stringcol
[0]=config
->stringfgcol
;
686 vis
->vi_stringcol
[1]=config
->stringbgcol
;
687 vis
->vi_activestringcol
[0]=config
->stringselfgcol
;
688 vis
->vi_activestringcol
[1]=config
->stringselbgcol
;
691 if (vis
->vi_flags
&VISF_WINDOW
) vis
->vi_screen
=(struct Screen
*)Window
;
692 else if (Window
) vis
->vi_screen
=Window
->WScreen
;
693 else vis
->vi_screen
=NULL
;
695 vis
->vi_fg
=screen_pens
[config
->requestfg
].pen
;
696 vis
->vi_bg
=screen_pens
[config
->requestbg
].pen
;
697 vis
->vi_shine
=screen_pens
[config
->gadgettopcol
].pen
;
698 vis
->vi_shadow
=screen_pens
[config
->gadgetbotcol
].pen
;
699 vis
->vi_stringcol
[0]=screen_pens
[config
->stringfgcol
].pen
;
700 vis
->vi_stringcol
[1]=screen_pens
[config
->stringbgcol
].pen
;
701 vis
->vi_activestringcol
[0]=screen_pens
[config
->stringselfgcol
].pen
;
702 vis
->vi_activestringcol
[1]=screen_pens
[config
->stringselbgcol
].pen
;
705 if (vis
->vi_flags
&VISF_8POINTFONT
) vis
->vi_font
=scr_font
[FONT_GENERAL
];
706 else vis
->vi_font
=scr_font
[FONT_REQUEST
];
708 if (config
->generalscreenflags
&SCR_GENERAL_REQDRAG
)
709 vis
->vi_flags
|=VISF_BORDERS
;
710 else vis
->vi_flags
&=~VISF_BORDERS
;
712 vis
->vi_language
=config
->language
;