home *** CD-ROM | disk | FTP | other *** search
- /*
-
- Directory Opus 4
- Original GPL release version 4.12
- Copyright 1993-2000 Jonathan Potter
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- All users of Directory Opus 4 (including versions distributed
- under the GPL) are entitled to upgrade to the latest version of
- Directory Opus version 5 at a reduced price. Please see
- http://www.gpsoft.com.au for more information.
-
- The release of Directory Opus 4 under the GPL in NO WAY affects
- the existing commercial status of Directory Opus 5.
-
- */
-
- #include "dopus.h"
- #include "view.h"
-
- struct MsgPort *arbiter_reply_port;
- struct MsgPort *arbiter_msg_port=NULL;
- struct ProcessStart *arbiter_seglist=NULL;
- struct Message arbiter_startup;
-
- install_arbiter()
- {
- if (!(arbiter_reply_port=LCreatePort(NULL,0)) ||
- !(arbiter_seglist=AllocMem(sizeof(struct ProcessStart),MEMF_CLEAR|MEMF_PUBLIC)))
- return(0);
-
- arbiter_seglist->ps_NextSeg=NULL;
- arbiter_seglist->ps_JMP=0x4ef9;
- arbiter_seglist->ps_EntryPoint=(void *)arbiter_process;
-
- arbiter_startup.mn_Node.ln_Type=NT_MESSAGE;
- arbiter_startup.mn_Node.ln_Pri=0;
- arbiter_startup.mn_ReplyPort=arbiter_reply_port;
- arbiter_startup.mn_Length=(UWORD)sizeof(struct ArbiterMessage);
-
- if (!(arbiter_msg_port=(struct MsgPort *)
- CreateProc("dopus_arbiter",0,(long)arbiter_seglist>>2,4000))) return(0);
-
- PutMsg(arbiter_msg_port,&arbiter_startup);
- return(1);
- }
-
- void remove_arbiter()
- {
- if (arbiter_msg_port) {
- arbiter_command(ARBITER_REMOVE,NULL,0);
- WaitPort(arbiter_reply_port);
- GetMsg(arbiter_reply_port);
- }
-
- if (arbiter_seglist) FreeMem(arbiter_seglist,sizeof(struct ProcessStart));
- if (arbiter_reply_port) LDeletePort(arbiter_reply_port);
- }
-
- arbiter_command(command,data,flags)
- int command;
- APTR data;
- int flags;
- {
- struct ArbiterMessage arbiter_msg;
- struct MsgPort command_port;
-
- CopyMem((char *)arbiter_reply_port,(char *)&command_port,sizeof(struct MsgPort));
- NewList(&command_port.mp_MsgList);
-
- arbiter_msg.msg.mn_Node.ln_Type=NT_MESSAGE;
- arbiter_msg.msg.mn_Node.ln_Pri=0;
- arbiter_msg.msg.mn_ReplyPort=&command_port;
- arbiter_msg.msg.mn_Length=(UWORD)sizeof(struct ArbiterMessage);
- arbiter_msg.command=command;
- arbiter_msg.data=data;
- arbiter_msg.flags=flags;
- PutMsg(arbiter_msg_port,(struct Message *)&arbiter_msg);
- WaitPort(&command_port);
- GetMsg(&command_port);
-
- return(arbiter_msg.command);
- }
-
- struct LaunchList {
- struct LaunchList *next;
- struct ProcessStart *seglist;
- struct ArbiterMessage launch_msg;
- struct ArbiterMessage *reply_msg;
- struct DOpusRemember *memory;
- };
-
- void __saveds arbiter_process()
- {
- struct Process *my_process;
- struct Message *my_startup_message;
- struct ArbiterMessage *arb_msg,*remove_msg=NULL;
- struct LaunchList *first_launch=NULL,*launch,*launchpos;
- struct MsgPort *message_reply;
- char ret,remove=0;
- int wait_mask;
-
- my_process=(struct Process *)FindTask(NULL);
- my_process->pr_WindowPtr=(APTR)-1;
- WaitPort(&my_process->pr_MsgPort);
- my_startup_message=GetMsg(&my_process->pr_MsgPort);
-
- wait_mask=1<<my_process->pr_MsgPort.mp_SigBit;
-
- if (message_reply=LCreatePort(NULL,0))
- wait_mask|=1<<message_reply->mp_SigBit;
-
- FOREVER {
- if (message_reply) {
- while (arb_msg=(struct ArbiterMessage *)GetMsg(message_reply)) {
- launch=first_launch;
- launchpos=NULL;
- while (launch) {
- if (arb_msg==&launch->launch_msg) {
- if (launchpos) launchpos->next=launch->next;
- else first_launch=launch->next;
- if (launch->reply_msg) {
- launch->reply_msg->command=arb_msg->command;
- ReplyMsg((struct Message *)launch->reply_msg);
- }
- LFreeRemember(&launch->memory);
- FreeMem(launch,sizeof(struct LaunchList));
- break;
- }
- launchpos=launch;
- launch=launch->next;
- }
- }
- if (remove_msg && !first_launch) {
- ReplyMsg((struct Message *)remove_msg);
- break;
- }
- }
- while (arb_msg=(struct ArbiterMessage *)GetMsg(&my_process->pr_MsgPort)) {
- ret=0;
- switch (arb_msg->command) {
- case ARBITER_REMOVE:
- if (first_launch) {
- remove_msg=arb_msg;
- arb_msg=NULL;
- }
- else remove=1;
- break;
- case ARBITER_LAUNCH:
- if (message_reply &&
- (launch=AllocMem(sizeof(struct LaunchList),MEMF_CLEAR))) {
- struct ArbiterLaunch *arb_launch;
- struct MsgPort *port;
-
- if ((launchpos=first_launch)) {
- while (launchpos->next) launchpos=launchpos->next;
- }
- if (launchpos) launchpos->next=launch;
- else first_launch=launch;
-
- arb_launch=(struct ArbiterLaunch *)arb_msg->data;
-
- launch->memory=arb_launch->launch_memory;
-
- if (launch->seglist=LAllocRemember(&launch->memory,
- sizeof(struct ProcessStart),MEMF_PUBLIC|MEMF_CLEAR)) {
-
- launch->seglist->ps_JMP=0x4ef9;
- launch->seglist->ps_EntryPoint=arb_launch->launch_code;
-
- launch->launch_msg.msg.mn_Node.ln_Type=NT_MESSAGE;
- launch->launch_msg.msg.mn_ReplyPort=message_reply;
- launch->launch_msg.msg.mn_Length=sizeof(struct ArbiterMessage);
-
- launch->launch_msg.command=arb_msg->command;
- launch->launch_msg.data=arb_launch->data;
- launch->launch_msg.flags=arb_msg->flags;
-
- if ((port=(struct MsgPort *)
- CreateProc(arb_launch->launch_name,0,(long)launch->seglist>>2,4000))) {
- PutMsg(port,(struct Message *)&launch->launch_msg);
- if (arb_msg->flags&ARB_WAIT) {
- launch->reply_msg=arb_msg;
- arb_msg=NULL;
- }
- else ret=1;
- }
- }
- else {
- LFreeRemember(&launch->memory);
- FreeMem(launch,sizeof(struct ProcessStart));
- }
- }
- break;
- }
- if (arb_msg) {
- arb_msg->command=ret;
- ReplyMsg((struct Message *)arb_msg);
- }
- }
- if (remove) break;
- Wait(wait_mask);
- }
-
- if (message_reply) LDeletePort(message_reply);
- Forbid();
- ReplyMsg(my_startup_message);
- return;
- }
-
- struct Screen *open_subprocess_screen(title,font,memkey,pens)
- char *title;
- struct TextFont *font;
- struct DOpusRemember **memkey;
- short *pens;
- {
- struct ExtNewScreen newscreen;
- struct TagItem *screentags;
- struct TextAttr *screenattr;
- struct Screen *screen;
- UWORD *screen_drawinfo;
-
- if (!(screenattr=LAllocRemember(memkey,sizeof(struct TextAttr),MEMF_CLEAR)) ||
- !(screentags=LAllocRemember(memkey,sizeof(struct TagItem)*5,MEMF_CLEAR)) ||
- !(screen_drawinfo=LAllocRemember(memkey,sizeof(scr_drawinfo),0)))
- return(NULL);
-
- CopyMem((char *)scr_drawinfo,(char *)screen_drawinfo,sizeof(scr_drawinfo));
-
- if (pens) {
- screen_drawinfo[DETAILPEN]=pens[ARB_PEN_DETAIL];
- screen_drawinfo[BLOCKPEN]=pens[ARB_PEN_BLOCK];
- }
-
- screentags[0].ti_Tag=SA_DisplayID;
- screentags[0].ti_Data=clone_screen(MainScreen,&newscreen);
- screentags[1].ti_Tag=SA_Pens;
- screentags[1].ti_Data=(ULONG)screen_drawinfo;
- screentags[2].ti_Tag=SA_AutoScroll;
- screentags[2].ti_Data=TRUE;
- screentags[3].ti_Tag=SA_Interleaved;
- screentags[3].ti_Data=TRUE;
- screentags[4].ti_Tag=TAG_END;
- screentags[4].ti_Data=0;
-
- if (system_version2) {
- struct DimensionInfo dimbuf;
- int width,height;
-
- if ((GetDisplayInfoData(NULL,
- (char *)&dimbuf,
- sizeof(struct DimensionInfo),
- DTAG_DIMS,
- screentags[0].ti_Data))) {
-
- width=(dimbuf.TxtOScan.MaxX-dimbuf.TxtOScan.MinX)+1;
- height=(dimbuf.TxtOScan.MaxY-dimbuf.TxtOScan.MinY)+1;
- if (newscreen.Width>width) newscreen.Width=width;
- if (newscreen.Height>height) newscreen.Height=height;
- }
- }
-
- screenattr->ta_Name=font->tf_Message.mn_Node.ln_Name;
- screenattr->ta_YSize=font->tf_YSize;
-
- newscreen.LeftEdge=0;
- newscreen.TopEdge=0;
- if (pens) {
- newscreen.DetailPen=pens[ARB_PEN_DETAIL];
- newscreen.BlockPen=pens[ARB_PEN_BLOCK];
- }
- else {
- newscreen.DetailPen=0;
- newscreen.BlockPen=1;
- }
- newscreen.Type=CUSTOMSCREEN|NS_EXTENDED;
- newscreen.Font=screenattr;
- newscreen.DefaultTitle=title;
- newscreen.Gadgets=NULL;
- newscreen.Extension=screentags;
- newscreen.Depth=config->scrdepth;
-
- if (!(screen=OpenScreen((struct NewScreen *)&newscreen))) return(NULL);
- load_palette(screen,config->new_palette);
- return(screen);
- }
-