home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d9xx
/
d953
/
appcon.lha
/
AppCon
/
Src
/
AppCon.c
next >
Wrap
C/C++ Source or Header
|
1993-10-13
|
12KB
|
510 lines
/* AppCon Main Source
**
** Done by Stephan Fuhrmann
**
*/
#define EXEC_MINIMUM 36
#define MY_ID 3111973
/*#define DEBUG_ME*/
#include <AppCon.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <exec/execbase.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <exec/tasks.h>
#include <devices/console.h>
#include <devices/conunit.h>
#include <devices/keymap.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <devices/timer.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/wb.h>
#include <proto/keymap.h>
#ifdef LATTICE
int CXBRK(void) { return(0); }
int chkabort(void) { return(0); }
#endif
char __stdiowin[]="CON:10/10/500/100/AppCon";
char __stdio37[]="/CLOSE/WAIT";
long timeout=10; /* in tenths of a second */
const char vt[]=VERSTAG;
struct Process *AppConTask=0L;
struct CommandLineInterface *AppCLI;
struct Window *AppConWindow;
extern struct ExecBase *SysBase;
extern struct IntuitionBase *IntuitionBase;
extern struct Library *WorkbenchBase;
extern struct Library *KeymapBase;
extern struct Library *DosBase;
struct MsgPort *timeport=0L;
struct MsgPort *appport=0L;
struct MsgPort *ioreply=0L;
struct IOStdReq *iorequest=0L;
struct timerequest *timerio=0L;
struct AppWindow *AppWindow;
struct AppMessage *AppMessage;
struct InputEvent *InputEvent;
ULONG WaitSignals=SIGBREAKF_CTRL_C;
ULONG ReceivedSignals;
long __OSlibversion=EXEC_MINIMUM;
char filename[FILENAME_MAX];
char dirname[FILENAME_MAX];
char pathname[FILENAME_MAX*2];
char AppConName[]="AppCon";
char Couldnt[]="AppCon: Couldn't %s %s!\n";
#define TEMPLATE "TimeOut=Time/K/N"
enum templates {OPT_TIMEOUT,OPT_COUNT};
LONG opts[OPT_COUNT];
char HelpPage[]=
"\nAppCon Help\n"\
"-----------\n"\
"© 1993 Stephan Fuhrmann\n\n"\
"Options\n"\
"---------\n"\
"TIMEOUT...timeout between checks of window closing, in tenths of a second\\NUMBER\n"\
"\nExample: AppCon TIMEOUT=10\n";
char WBHelp[]=
"\nNote: AppCon is a Shell-only utility and can't be started\n"\
"from the Workbench.\n";
struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs);
void MakeActive (struct Window *ActivateMe);
struct InputEvent *BrewInputevent(char *ASCII);
void FreeIEs (struct InputEvent *firstie);
struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort);
long AntiBlocking (struct Window *MyWin);
void MegaAbort (struct IOStdReq *);
void LaunchRequest (long secs,long micros,struct timerequest *mytimerio);
int main(int argc,char *argv[])
{
struct RDArgs *argsptr;
fprintf (stderr,VSTRING);
if (!argc)
{
fprintf (stderr,WBHelp);
return (0);
}
fprintf (stderr,"PUBLIC DOMAIN written 1993 by Stephan Fuhrmann\n");
argsptr=AllocDosObject (DOS_RDARGS,0);
if (argsptr)
{
argsptr->RDA_ExtHelp=HelpPage;
if (!ReadArgs (TEMPLATE,opts,argsptr))
{
PrintFault (IoErr(),NULL);
FreeArgs (argsptr);
FreeDosObject (DOS_RDARGS,argsptr);
return (0);
}
if (opts[OPT_TIMEOUT])
timeout=*(LONG *)opts[OPT_TIMEOUT];
if ((ioreply=CreateMsgPort()) && (appport=CreateMsgPort()) && (timeport=CreateMsgPort()))
{
appport->mp_Node.ln_Name=AppConName;
WaitSignals |= 1L << (ioreply->mp_SigBit);
WaitSignals |= 1L << (timeport->mp_SigBit);
WaitSignals |= 1L << (appport->mp_SigBit);
if ((iorequest=CreateIORequest(ioreply,sizeof(struct IOStdReq)))
&& (timerio=CreateIORequest(timeport,sizeof(struct timerequest))))
{
if (!OpenDevice ("timer.device",UNIT_VBLANK,(struct IORequest *)timerio,0))
{
AppConTask=(struct Process *) FindTask(NULL);
if (!OpenDevice ("input.device",0L,(struct IORequest *)iorequest,0))
{
AppConWindow=GetConWindow (AppConTask,ioreply);
if (AppConWindow)
{
if (AppWindow=AddAppWindowA (MY_ID,NULL,AppConWindow,appport,NULL))
{
ReceivedSignals=0;
LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
while (!(ReceivedSignals & SIGBREAKF_CTRL_C))
{
ReceivedSignals=Wait (WaitSignals);
if (ReceivedSignals & (1L << (timeport->mp_SigBit)))
{
MegaAbort ((struct IOStdReq *)timerio);
LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
if (AntiBlocking (AppConTask->pr_ConsoleTask) <= 1)
Signal ((struct Task *)AppConTask,SIGBREAKF_CTRL_C);
ReceivedSignals &= ~ (1L << (timeport->mp_SigBit));
}
if (ReceivedSignals & (1L << (appport->mp_SigBit)))
{
ReceivedSignals &= ~ (1L << (appport->mp_SigBit));
while (AppMessage = (struct AppMessage *)GetMsg (appport))
{
register long cnt,max;
register struct WBArg *curarg;
struct WBArg *argptr;
if ((AppMessage->am_Type)!=MTYPE_APPWINDOW)
{
#ifdef DEBUG_ME
fprintf (stderr,"Unknown type (%ld)!",AppMessage->am_Type);
#endif
ReplyMsg((struct Message *)AppMessage);
continue;
}
max=AppMessage->am_NumArgs;
curarg=AppMessage->am_ArgList;
if (!max)
{
#ifdef DEBUG_ME
fprintf (stderr,"Not enough arguments (%ld)!",max);
#endif
ReplyMsg((struct Message *)AppMessage);
continue;
}
argptr=curarg;
for (cnt=0;cnt<max;cnt++)
{
if (argptr->wa_Lock)
NameFromLock(argptr->wa_Lock,dirname,FILENAME_MAX);
strcpy (pathname,dirname);
if (argptr->wa_Name)
AddPart(pathname,argptr->wa_Name,FILENAME_MAX*2);
if (cnt)
{
if (InputEvent=BrewInputevent (" "))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep(0);
}
if (strchr(pathname,' '))
{
if (InputEvent=BrewInputevent ("\""))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep(0);
}
if (InputEvent=BrewInputevent (pathname))
{
MakeActive (AppConWindow);
FreeIEs (SendEvents (iorequest,InputEvent));
}
else
DisplayBeep (0);
if (strchr(pathname,' '))
{
if (InputEvent=BrewInputevent ("\""))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep (0);
}
argptr++;
}
ReplyMsg((struct Message *)AppMessage);
}
}
}
RemoveAppWindow (AppWindow);
}
else
fprintf (stderr,Couldnt,"add","AppWindow");
}
else
fprintf (stderr,Couldnt,"find","console window!");
MegaAbort (iorequest);
CloseDevice ((struct IORequest *)iorequest);
}
else
fprintf (stderr,Couldnt,"open","console.device");
MegaAbort ((struct IOStdReq *)timerio);
CloseDevice ((struct IORequest *)timerio);
}
else
fprintf (stderr,Couldnt,"open","timer.device");
}
else
fprintf (stderr,Couldnt,"create","IORequest");
DeleteIORequest (timerio);
DeleteIORequest (iorequest);
}
else
fprintf (stderr,Couldnt,"create","msgport");
DeleteMsgPort (timeport);
DeleteMsgPort (ioreply);
DeleteMsgPort (appport);
}
else
fprintf (stderr,Couldnt,"allocate","ReadArgs-Object");
FreeArgs (argsptr);
if (argsptr)
FreeDosObject (DOS_RDARGS,argsptr);
return (0);
}
struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs)
{
struct InputEvent *ThisEvent,*NextEvent;
ThisEvent=SendUs;
while (ThisEvent)
{
iorequest->io_Command=IND_WRITEEVENT;
iorequest->io_Length=sizeof(struct InputEvent);
iorequest->io_Data=ThisEvent;
NextEvent=ThisEvent->ie_NextEvent;
ThisEvent->ie_NextEvent=0L;
DoIO ((struct IORequest *)iorequest);
ThisEvent->ie_NextEvent=NextEvent; /* recover NextEvent-field for later FreeMem-stuff */
ThisEvent=NextEvent;
}
return (SendUs);
}
void MakeActive (struct Window *ActivateMe)
{
if (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
{
ActivateWindow (ActivateMe);
while (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
Delay (1);
}
}
void FreeIEs (struct InputEvent *firstie)
{
register struct InputEvent *nextie;
while (firstie)
{
nextie=firstie->ie_NextEvent;
FreeMem (firstie,sizeof (struct InputEvent));
firstie=nextie;
}
}
struct InputEvent *BrewInputevent(char *ASCII)
{
struct InputEvent *thisie,*oldie,*grandpa,*firstie;
register long cnt;
long junksize;
WORD *junkbuf;
long rawsize;
firstie=0;
thisie=0;
oldie=0;
junksize=strlen(ASCII)*3;
if (!(junkbuf=AllocMem(junksize*sizeof(WORD),MEMF_PUBLIC)))
return (0);
rawsize=MapANSI (ASCII,strlen(ASCII),(STRPTR)junkbuf,junksize,0);
switch (rawsize)
{
case 0:
case -1:
case -2:
FreeMem (junkbuf,junksize*sizeof(WORD));
return (0);
}
for (cnt=0;cnt<rawsize;cnt++)
{
grandpa=oldie;
oldie=thisie;
thisie=AllocMem(sizeof (struct InputEvent),MEMF_CLEAR|MEMF_PUBLIC);
if (!thisie)
{
FreeMem (junkbuf,junksize*sizeof(WORD));
FreeIEs(firstie);
return (0);
}
if (oldie)
oldie->ie_NextEvent=thisie;
else
firstie=thisie;
/* PARANOIA! */
thisie->ie_NextEvent=0;
thisie->ie_Class=IECLASS_RAWKEY;
thisie->ie_SubClass=0;
thisie->ie_Code=(*(junkbuf+cnt)>>8) & 255;
thisie->ie_Qualifier=*(junkbuf+cnt) & 255;
if (oldie)
{
thisie->ie_position.ie_dead.ie_prev1DownCode=oldie->ie_Code;
thisie->ie_position.ie_dead.ie_prev1DownQual=oldie->ie_Qualifier;
}
if (grandpa)
{
thisie->ie_position.ie_dead.ie_prev2DownCode=grandpa->ie_Code;
thisie->ie_position.ie_dead.ie_prev2DownQual=grandpa->ie_Qualifier;
}
}
FreeMem (junkbuf,junksize*sizeof(WORD));
return (firstie);
}
struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort)
{
struct Window *ResultWindow;
struct MsgPort *con;
struct StandardPacket packet;
struct InfoData id;
ResultWindow=0L;
if (ConProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS)
{
con=ConProcess->pr_ConsoleTask;
if (con)
{
packet.sp_Msg.mn_Node.ln_Name=(char *)&(packet.sp_Pkt);
packet.sp_Pkt.dp_Link=&(packet.sp_Msg);
packet.sp_Pkt.dp_Port=MyPort;
packet.sp_Pkt.dp_Type=ACTION_DISK_INFO;
packet.sp_Pkt.dp_Arg1=((ULONG) &id) >> 2;
PutMsg (con,(struct Message *)&packet);
WaitPort (MyPort);
ResultWindow=(struct Window *)id.id_VolumeNode;
}
}
return (ResultWindow);
}
long AntiBlocking (APTR MyConsoleTask)
{
long winusers=0;
long cnt,max;
Forbid();
max=MaxCli()+1;
for (cnt=1;cnt < max;cnt++)
{
struct Process *ThisProc;
if (ThisProc=FindCliProc (cnt))
{
if (ThisProc->pr_ConsoleTask == MyConsoleTask)
winusers++;
}
}
Permit();
return (winusers);
}
void MegaAbort (struct IOStdReq *AbortMe)
{
AbortIO ((struct IORequest *)AbortMe);
WaitIO ((struct IORequest *)AbortMe);
SetSignal (0L,1L << (AbortMe->io_Message.mn_ReplyPort->mp_SigBit));
}
void LaunchRequest (long secs,long micros,struct timerequest *mytimerio)
{
timerio->tr_node.io_Command=TR_ADDREQUEST;
timerio->tr_time.tv_secs=secs;
timerio->tr_time.tv_micro=micros;
SendIO ((struct IORequest *)mytimerio);
}