home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Programming
/
DOpus4-GPL
/
Program
/
arbiter.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-27
|
9KB
|
300 lines
/*
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);
}