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 >
C/C++ Source or Header  |  1993-10-13  |  12KB  |  510 lines

  1. /* AppCon Main Source
  2. **
  3. ** Done by Stephan Fuhrmann
  4. **
  5. */
  6.  
  7. #define EXEC_MINIMUM 36
  8. #define MY_ID 3111973
  9. /*#define DEBUG_ME*/
  10.  
  11. #include <AppCon.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15.  
  16. #include <dos/dos.h>
  17. #include <dos/dosextens.h>
  18. #include <exec/execbase.h>
  19. #include <exec/ports.h>
  20. #include <exec/io.h>
  21. #include <exec/libraries.h>
  22. #include <exec/memory.h>
  23. #include <exec/interrupts.h>
  24. #include <exec/tasks.h>
  25. #include <devices/console.h>
  26. #include <devices/conunit.h>
  27. #include <devices/keymap.h>
  28. #include <devices/input.h>
  29. #include <devices/inputevent.h>
  30. #include <devices/timer.h>
  31. #include <intuition/intuition.h>
  32. #include <intuition/intuitionbase.h>
  33. #include <workbench/startup.h>
  34. #include <workbench/workbench.h>
  35.  
  36. #include <proto/exec.h>
  37. #include <proto/dos.h>
  38. #include <proto/intuition.h>
  39. #include <proto/wb.h>
  40. #include <proto/keymap.h>
  41.  
  42. #ifdef LATTICE
  43. int CXBRK(void) { return(0); }
  44. int chkabort(void) { return(0); }
  45. #endif
  46.  
  47. char __stdiowin[]="CON:10/10/500/100/AppCon";
  48. char __stdio37[]="/CLOSE/WAIT";
  49.  
  50. long timeout=10;    /* in tenths of a second */
  51.  
  52. const char vt[]=VERSTAG;
  53.  
  54. struct Process *AppConTask=0L;
  55. struct CommandLineInterface *AppCLI;
  56. struct Window *AppConWindow;
  57.  
  58. extern struct ExecBase *SysBase;
  59. extern struct IntuitionBase *IntuitionBase;
  60. extern struct Library *WorkbenchBase;
  61. extern struct Library *KeymapBase;
  62. extern struct Library *DosBase;
  63.  
  64. struct MsgPort *timeport=0L;
  65. struct MsgPort *appport=0L;
  66. struct MsgPort *ioreply=0L;
  67. struct IOStdReq *iorequest=0L;
  68. struct timerequest *timerio=0L;
  69.  
  70. struct AppWindow *AppWindow;
  71.  
  72. struct AppMessage *AppMessage;
  73.  
  74. struct InputEvent *InputEvent;
  75.  
  76. ULONG WaitSignals=SIGBREAKF_CTRL_C;
  77. ULONG ReceivedSignals;
  78.  
  79. long __OSlibversion=EXEC_MINIMUM;
  80.  
  81. char filename[FILENAME_MAX];
  82. char dirname[FILENAME_MAX];
  83. char pathname[FILENAME_MAX*2];
  84.  
  85. char AppConName[]="AppCon";
  86. char Couldnt[]="AppCon: Couldn't %s %s!\n";
  87.  
  88. #define TEMPLATE    "TimeOut=Time/K/N"
  89. enum templates {OPT_TIMEOUT,OPT_COUNT};
  90.  
  91. LONG opts[OPT_COUNT];
  92.  
  93. char HelpPage[]=
  94.     "\nAppCon Help\n"\
  95.     "-----------\n"\
  96.     "© 1993 Stephan Fuhrmann\n\n"\
  97.     "Options\n"\
  98.     "---------\n"\
  99.     "TIMEOUT...timeout between checks of window closing, in tenths of a second\\NUMBER\n"\
  100.     "\nExample: AppCon TIMEOUT=10\n";
  101.  
  102. char WBHelp[]=
  103.     "\nNote: AppCon is a Shell-only utility and can't be started\n"\
  104.     "from the Workbench.\n";
  105.  
  106. struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs);
  107. void MakeActive (struct Window *ActivateMe);
  108. struct InputEvent *BrewInputevent(char *ASCII);
  109. void FreeIEs (struct InputEvent *firstie);
  110. struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort);
  111. long AntiBlocking (struct Window *MyWin);
  112. void MegaAbort (struct IOStdReq *);
  113. void LaunchRequest (long secs,long micros,struct timerequest *mytimerio);
  114.  
  115. int main(int argc,char *argv[])
  116. {
  117.     struct RDArgs *argsptr;
  118.  
  119.     fprintf (stderr,VSTRING);
  120.  
  121.     if (!argc)
  122.     {
  123.         fprintf (stderr,WBHelp);
  124.         return (0);
  125.     }
  126.  
  127.     fprintf (stderr,"PUBLIC DOMAIN written 1993 by Stephan Fuhrmann\n");
  128.  
  129.     argsptr=AllocDosObject (DOS_RDARGS,0);
  130.  
  131.     if (argsptr)
  132.     {
  133.         argsptr->RDA_ExtHelp=HelpPage;
  134.  
  135.         if (!ReadArgs (TEMPLATE,opts,argsptr))
  136.         {
  137.             PrintFault (IoErr(),NULL);
  138.             FreeArgs (argsptr);
  139.             FreeDosObject (DOS_RDARGS,argsptr);
  140.             return (0);
  141.         }
  142.     
  143.         if (opts[OPT_TIMEOUT])
  144.             timeout=*(LONG *)opts[OPT_TIMEOUT];
  145.  
  146.         if ((ioreply=CreateMsgPort()) && (appport=CreateMsgPort()) && (timeport=CreateMsgPort()))
  147.         {
  148.             appport->mp_Node.ln_Name=AppConName;
  149.  
  150.             WaitSignals |= 1L << (ioreply->mp_SigBit);
  151.             WaitSignals |= 1L << (timeport->mp_SigBit);
  152.             WaitSignals |= 1L << (appport->mp_SigBit);
  153.  
  154.             if ((iorequest=CreateIORequest(ioreply,sizeof(struct IOStdReq)))
  155.                && (timerio=CreateIORequest(timeport,sizeof(struct timerequest))))
  156.             {
  157.  
  158.                 if (!OpenDevice ("timer.device",UNIT_VBLANK,(struct IORequest *)timerio,0))
  159.                 {
  160.                     AppConTask=(struct Process *) FindTask(NULL);
  161.  
  162.                     if (!OpenDevice ("input.device",0L,(struct IORequest *)iorequest,0))
  163.                     {
  164.  
  165.                         AppConWindow=GetConWindow (AppConTask,ioreply);
  166.  
  167.                         if (AppConWindow)
  168.                         {
  169.                             if (AppWindow=AddAppWindowA (MY_ID,NULL,AppConWindow,appport,NULL))
  170.                             {
  171.                                 ReceivedSignals=0;
  172.     
  173.                                 LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
  174.     
  175.                                 while (!(ReceivedSignals & SIGBREAKF_CTRL_C))
  176.                                 {
  177.                                     ReceivedSignals=Wait (WaitSignals);
  178.     
  179.                                     if (ReceivedSignals & (1L << (timeport->mp_SigBit)))
  180.                                     {
  181.                                         MegaAbort ((struct IOStdReq *)timerio);
  182.                                         LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
  183.  
  184.                                         if (AntiBlocking (AppConTask->pr_ConsoleTask) <= 1)
  185.                                             Signal ((struct Task *)AppConTask,SIGBREAKF_CTRL_C);
  186.                                     
  187.                                         ReceivedSignals &= ~ (1L << (timeport->mp_SigBit));
  188.                                     }
  189.  
  190.                                     if (ReceivedSignals & (1L << (appport->mp_SigBit)))
  191.                                     {
  192.                                         ReceivedSignals &= ~ (1L << (appport->mp_SigBit));
  193.     
  194.                                         while (AppMessage = (struct AppMessage *)GetMsg (appport))
  195.                                         {
  196.                                             register long cnt,max;
  197.                                             register struct WBArg *curarg;
  198.                                             struct WBArg *argptr;
  199.     
  200.                                             if ((AppMessage->am_Type)!=MTYPE_APPWINDOW)
  201.                                             {
  202. #ifdef DEBUG_ME
  203.                                                 fprintf (stderr,"Unknown type (%ld)!",AppMessage->am_Type);
  204. #endif    
  205.                                                 ReplyMsg((struct Message *)AppMessage);
  206.                                                 continue;
  207.                                             }
  208.     
  209.                                             max=AppMessage->am_NumArgs;
  210.                                             curarg=AppMessage->am_ArgList;
  211.     
  212.                                             if (!max)
  213.                                             {
  214. #ifdef DEBUG_ME
  215.                                                 fprintf (stderr,"Not enough arguments (%ld)!",max);
  216. #endif    
  217.                                                 ReplyMsg((struct Message *)AppMessage);
  218.                                                 continue;
  219.                                             }
  220.     
  221.                                             argptr=curarg;
  222.     
  223.                                             for (cnt=0;cnt<max;cnt++)
  224.                                             {
  225.                                                 if (argptr->wa_Lock)
  226.                                                     NameFromLock(argptr->wa_Lock,dirname,FILENAME_MAX);
  227.     
  228.                                                 strcpy (pathname,dirname);
  229.         
  230.                                                 if (argptr->wa_Name)
  231.                                                     AddPart(pathname,argptr->wa_Name,FILENAME_MAX*2);
  232.     
  233.                                                 if (cnt)
  234.                                                 {
  235.                                                     if (InputEvent=BrewInputevent (" "))
  236.                                                     {
  237.                                                         MakeActive (AppConWindow);
  238.         
  239.                                                         FreeIEs(SendEvents (iorequest,InputEvent));
  240.                                                     }
  241.                                                     else
  242.                                                         DisplayBeep(0);
  243.                                                 }
  244.     
  245.                                                 if (strchr(pathname,' '))
  246.                                                 {
  247.                                                     if (InputEvent=BrewInputevent ("\""))
  248.                                                     {
  249.                                                         MakeActive (AppConWindow);
  250.     
  251.                                                         FreeIEs(SendEvents (iorequest,InputEvent));
  252.                                                     }
  253.                                                     else
  254.                                                         DisplayBeep(0);
  255.                                                 }
  256.     
  257.                                                 if (InputEvent=BrewInputevent (pathname))
  258.                                                 {
  259.                                                     MakeActive (AppConWindow);
  260.     
  261.                                                     FreeIEs (SendEvents (iorequest,InputEvent));
  262.                                                 }
  263.                                                 else
  264.                                                     DisplayBeep (0);
  265.                                                 
  266.                                                 if (strchr(pathname,' '))
  267.                                                 {
  268.                                                     if (InputEvent=BrewInputevent ("\""))
  269.                                                     {
  270.                                                         MakeActive (AppConWindow);
  271.     
  272.                                                         FreeIEs(SendEvents (iorequest,InputEvent));
  273.                                                     }
  274.                                                     else
  275.                                                         DisplayBeep (0);
  276.                                                 }
  277.                                                 argptr++;
  278.                                             }
  279.                                             ReplyMsg((struct Message *)AppMessage);
  280.                                         }
  281.                                     }
  282.                                 }
  283.                                 RemoveAppWindow (AppWindow);
  284.                             }
  285.                             else
  286.                                 fprintf (stderr,Couldnt,"add","AppWindow");
  287.                         }
  288.                         else
  289.                             fprintf (stderr,Couldnt,"find","console window!");
  290.  
  291.                         MegaAbort (iorequest);
  292.  
  293.                         CloseDevice ((struct IORequest *)iorequest);
  294.                     }
  295.                     else
  296.                         fprintf (stderr,Couldnt,"open","console.device");
  297.  
  298.                     MegaAbort ((struct IOStdReq *)timerio);
  299.                     CloseDevice ((struct IORequest *)timerio);
  300.                 }
  301.                 else
  302.                     fprintf (stderr,Couldnt,"open","timer.device");
  303.             }
  304.             else
  305.                 fprintf (stderr,Couldnt,"create","IORequest");
  306.  
  307.             DeleteIORequest (timerio);
  308.             DeleteIORequest (iorequest);
  309.         }
  310.         else
  311.             fprintf (stderr,Couldnt,"create","msgport");
  312.  
  313.         DeleteMsgPort (timeport);            
  314.         DeleteMsgPort (ioreply);
  315.         DeleteMsgPort (appport);
  316.     }    
  317.     else
  318.         fprintf (stderr,Couldnt,"allocate","ReadArgs-Object");
  319.  
  320.     FreeArgs (argsptr);
  321.  
  322.     if (argsptr)
  323.         FreeDosObject (DOS_RDARGS,argsptr);
  324.  
  325.     return (0);
  326. }
  327.  
  328. struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs)
  329. {
  330.     struct InputEvent *ThisEvent,*NextEvent;
  331.     
  332.     ThisEvent=SendUs;
  333.     
  334.     while (ThisEvent)
  335.     {
  336.         iorequest->io_Command=IND_WRITEEVENT;
  337.         iorequest->io_Length=sizeof(struct InputEvent);
  338.         iorequest->io_Data=ThisEvent;
  339.         NextEvent=ThisEvent->ie_NextEvent;
  340.         ThisEvent->ie_NextEvent=0L;
  341.         DoIO ((struct IORequest *)iorequest);
  342.         ThisEvent->ie_NextEvent=NextEvent;        /* recover NextEvent-field for later FreeMem-stuff */
  343.         ThisEvent=NextEvent;
  344.     }
  345.  
  346.     return (SendUs);
  347. }
  348.  
  349. void MakeActive (struct Window *ActivateMe)
  350. {
  351.     if (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
  352.     {
  353.         ActivateWindow (ActivateMe);
  354.         while (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
  355.             Delay (1);
  356.     }
  357. }
  358.  
  359. void FreeIEs (struct InputEvent *firstie)
  360. {
  361.     register struct InputEvent *nextie;
  362.  
  363.     while (firstie)
  364.     {
  365.         nextie=firstie->ie_NextEvent;
  366.         FreeMem (firstie,sizeof (struct InputEvent));
  367.         firstie=nextie;
  368.     }
  369. }
  370.  
  371. struct InputEvent *BrewInputevent(char *ASCII)
  372. {
  373.     struct InputEvent *thisie,*oldie,*grandpa,*firstie;
  374.     register long cnt;
  375.     long junksize;
  376.     WORD *junkbuf;
  377.     long rawsize;
  378.  
  379.     firstie=0;
  380.     thisie=0;
  381.     oldie=0;
  382.  
  383.     junksize=strlen(ASCII)*3;
  384.  
  385.     if (!(junkbuf=AllocMem(junksize*sizeof(WORD),MEMF_PUBLIC)))
  386.         return (0);
  387.  
  388.     rawsize=MapANSI (ASCII,strlen(ASCII),(STRPTR)junkbuf,junksize,0);
  389.  
  390.     switch (rawsize)
  391.     {
  392.         case 0:
  393.         case -1:
  394.         case -2:
  395.             FreeMem (junkbuf,junksize*sizeof(WORD));
  396.             return (0);
  397.     }
  398.  
  399.     for (cnt=0;cnt<rawsize;cnt++)
  400.     {
  401.         grandpa=oldie;
  402.         oldie=thisie;
  403.  
  404.         thisie=AllocMem(sizeof (struct InputEvent),MEMF_CLEAR|MEMF_PUBLIC);
  405.  
  406.         if (!thisie)
  407.         {
  408.             FreeMem (junkbuf,junksize*sizeof(WORD));
  409.             FreeIEs(firstie);
  410.             return (0);
  411.         }
  412.         
  413.         if (oldie)
  414.             oldie->ie_NextEvent=thisie;
  415.         else
  416.             firstie=thisie;
  417.  
  418.         /* PARANOIA! */
  419.         thisie->ie_NextEvent=0;
  420.  
  421.         thisie->ie_Class=IECLASS_RAWKEY;
  422.         thisie->ie_SubClass=0;
  423.         thisie->ie_Code=(*(junkbuf+cnt)>>8) & 255;
  424.         thisie->ie_Qualifier=*(junkbuf+cnt) & 255;
  425.  
  426.         if (oldie)
  427.         {
  428.             thisie->ie_position.ie_dead.ie_prev1DownCode=oldie->ie_Code;
  429.             thisie->ie_position.ie_dead.ie_prev1DownQual=oldie->ie_Qualifier;
  430.         }
  431.  
  432.         if (grandpa)
  433.         {
  434.             thisie->ie_position.ie_dead.ie_prev2DownCode=grandpa->ie_Code;
  435.             thisie->ie_position.ie_dead.ie_prev2DownQual=grandpa->ie_Qualifier;
  436.         }
  437.     }
  438.  
  439.     FreeMem (junkbuf,junksize*sizeof(WORD));
  440.     return (firstie);
  441. }
  442.  
  443. struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort)
  444. {
  445.     struct Window *ResultWindow;
  446.     struct MsgPort *con;
  447.     struct StandardPacket packet;
  448.     struct InfoData id;
  449.  
  450.     ResultWindow=0L;
  451.  
  452.     if (ConProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS)
  453.     {
  454.         con=ConProcess->pr_ConsoleTask;
  455.  
  456.         if (con)
  457.         {
  458.             packet.sp_Msg.mn_Node.ln_Name=(char *)&(packet.sp_Pkt);
  459.             packet.sp_Pkt.dp_Link=&(packet.sp_Msg);
  460.             packet.sp_Pkt.dp_Port=MyPort;
  461.             packet.sp_Pkt.dp_Type=ACTION_DISK_INFO;
  462.             packet.sp_Pkt.dp_Arg1=((ULONG) &id) >> 2;
  463.             PutMsg (con,(struct Message *)&packet);
  464.             WaitPort (MyPort);
  465.             ResultWindow=(struct Window *)id.id_VolumeNode;
  466.         }
  467.     }
  468.  
  469.     return (ResultWindow);
  470. }
  471.  
  472. long AntiBlocking (APTR MyConsoleTask)
  473. {
  474.     long winusers=0;
  475.     long cnt,max;
  476.  
  477.     Forbid();
  478.  
  479.     max=MaxCli()+1;
  480.  
  481.     for (cnt=1;cnt < max;cnt++)
  482.     {
  483.         struct Process *ThisProc;
  484.  
  485.         if (ThisProc=FindCliProc (cnt))
  486.         {
  487.             if (ThisProc->pr_ConsoleTask == MyConsoleTask)
  488.                 winusers++;
  489.         }
  490.     }
  491.  
  492.     Permit();
  493.     return (winusers);
  494. }
  495.  
  496. void MegaAbort (struct IOStdReq *AbortMe)
  497. {
  498.     AbortIO ((struct IORequest *)AbortMe);
  499.     WaitIO ((struct IORequest *)AbortMe);
  500.     SetSignal (0L,1L << (AbortMe->io_Message.mn_ReplyPort->mp_SigBit));
  501. }
  502.  
  503. void LaunchRequest (long secs,long micros,struct timerequest *mytimerio)
  504. {
  505.     timerio->tr_node.io_Command=TR_ADDREQUEST;
  506.     timerio->tr_time.tv_secs=secs;
  507.     timerio->tr_time.tv_micro=micros;
  508.     SendIO ((struct IORequest *)mytimerio);
  509. }
  510.