home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Abalone 1.4.2 / src / AppleEvent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-21  |  7.0 KB  |  258 lines  |  [TEXT/MPS ]

  1. #define APPLE_EVENT_C
  2. #include "AppleEvent.h"
  3.  
  4.  
  5. #if defined(__MWERKS__)
  6. #pragma segment __%Main
  7. #else
  8. #pragma segment Main
  9. #endif
  10.  
  11.  
  12. struct triplets
  13. {
  14.     AEEventClass        theEventClass;
  15.     AEEventID            theEventID;
  16.     ProcPtr                theHandler;
  17.     AEEventHandlerUPP    theUPP;
  18. };
  19. typedef struct triplets triplets;
  20.  
  21. static triplets keywordsToInstall[] =
  22. {
  23. //    These are the four required AppleEvents.
  24.  
  25.     { kCoreEventClass,        kAEOpenApplication,        (ProcPtr) DoAEOpenApplication },
  26.     { kCoreEventClass,        kAEOpenDocuments,        (ProcPtr) DoAEOpenDocuments },
  27.     { kCoreEventClass,        kAEPrintDocuments,        (ProcPtr) DoAEPrintDocuments },
  28.     { kCoreEventClass,        kAEQuitApplication,        (ProcPtr) DoAEQuitApplication },
  29.     
  30. //    These are the Abalone AppleEvents.
  31.  
  32.     { kAbaloneEventClass,    kSendMove,        (ProcPtr) DoAEMove },
  33.     { kAbaloneEventClass,    kSendGame,        (ProcPtr) DoAEGame },
  34.     { kAbaloneEventClass,    kSendInit,        (ProcPtr) DoAEInit },
  35.     { kAbaloneEventClass,    kSendNew1,        (ProcPtr) DoAENew1 },
  36.     { kAbaloneEventClass,    kSendAdrs,        (ProcPtr) DoAEAdrs },
  37.     { kAbaloneEventClass,    kSendStop,        (ProcPtr) DoAEStop }
  38. };
  39.  
  40.  
  41.  
  42. Boolean        gHasPPCToolbox  = true;        //    Test for system 7 done elsewhere
  43.  
  44.  
  45.  
  46.  
  47. // Intializes our AppleEvent dispatcher table.
  48.  
  49. void
  50. InitAppleEvents (void)
  51. {
  52.     OSErr    err;
  53.     short    i;
  54.  
  55.     for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(triplets)); ++i)
  56.     {
  57.         if (!keywordsToInstall[i].theUPP)
  58.             keywordsToInstall[i].theUPP = NewAEEventHandlerProc(keywordsToInstall[i].theHandler);
  59.  
  60.         err = AEInstallEventHandler(
  61.             keywordsToInstall[i].theEventClass,    // What class to install.
  62.             keywordsToInstall[i].theEventID,    // Keywords to install.
  63.             keywordsToInstall[i].theUPP,    // The AppleEvent handler.
  64.             0L,                                    // Unused refcon.
  65.             false                                // Only for our app.
  66.         );
  67.  
  68.         Assert (err == noErr, HIGH_LEVEL_EVENT_INSTALL);
  69.     }
  70. }
  71.  
  72.  
  73.  
  74. void
  75. DoHighLevelEvent (EventRecord *event)
  76. {
  77.     if (AEProcessAppleEvent (event) != noErr)
  78.     //    Warning (HIGH_LEVEL_EVENT_FAIL);
  79.         ;
  80. }
  81.  
  82.  
  83.  
  84. OSErr
  85. GetTargetInfo    (    AEAddressDesc targetDesc,
  86.                     char *zone,
  87.                     char *machine,
  88.                     char *application
  89.                 )
  90. {
  91.     ProcessSerialNumber targetPSN;
  92.     PortInfoRec            portInfo;
  93.     TargetID            theTargetID;
  94.     OSErr                err = noErr;
  95.  
  96.     zone[0]        = 0;
  97.     machine[0]     = 0;
  98.     application[0] = 0;
  99.  
  100.     if (targetDesc.descriptorType == typeProcessSerialNumber)
  101.     {
  102.         targetPSN = **(ProcessSerialNumber **)(targetDesc.dataHandle);
  103.         err = GetPortNameFromProcessSerialNumber (&portInfo.name, &targetPSN);
  104.         if (!err) pstrcpy (application, (char *) portInfo.name.name);
  105.         return err;
  106.     }
  107.     if (targetDesc.descriptorType == typeTargetID)
  108.     {
  109.         theTargetID = **(TargetID **)(targetDesc.dataHandle);
  110.         switch (theTargetID.location.locationKindSelector)
  111.         {
  112.             case ppcNoLocation:
  113.             break;
  114.             case ppcNBPLocation:
  115.                 pstrcpy(zone,    (char *) theTargetID.location.u.nbpEntity.zoneStr);
  116.                 pstrcpy(machine, (char *) theTargetID.location.u.nbpEntity.objStr);
  117.             break;
  118.             case ppcNBPTypeLocation:
  119.             break;
  120.         }
  121.         pstrcpy (application, (char *) theTargetID.name.name);
  122.         return noErr;
  123.     }
  124.  
  125.     return errAEWrongDataType;
  126. }
  127.  
  128.  
  129.  
  130.  
  131.  
  132. /* MakeTarget
  133. **
  134. ** Creates a TargetID.
  135. **
  136. ** If sendDirect is TRUE, the target is specified by setting a
  137. ** ProcessSerialNumber to kCurrentProcess.  This has the advantage of sending
  138. ** the message directly to ourselves, bypassing ePPC and gaining about a 10-15x
  139. ** speed improvement.  If sendDirect is FALSE, we see if we have the
  140. ** PPCToolBox.  If not, then we are forced to do a direct send.  If we do have
  141. ** the PPCToolbox, then we call PPCBrowser.  We then look at the reply, and
  142. ** factor in the mode we are going to use in AESend.  If that mode is
  143. ** kAEWaitReply and the user selected us as the target, we have to turn that
  144. ** into a direct send.  This is because the AppleEvent Manager will otherwise
  145. ** post the event as a high-level event.  However, we are busy waiting for a
  146. ** reply, not looking for events, so we'll hang.  We avoid this by forcing a
  147. ** direct send.
  148. */
  149.  
  150. OSErr
  151. MakeTarget    (    AEAddressDesc *target, 
  152.                 Boolean sendDirect,
  153.                 short replyMode,
  154.                 Str255 prompt,
  155.                 Str255 applListLabel,
  156.                 PPCFilterUPP portFilter
  157.             )
  158. {
  159.     OSErr                    err;
  160.     ProcessSerialNumber     targetPSN;
  161.     ProcessSerialNumber     myPSN;
  162.     TargetID                theTargetID;
  163.     Boolean                    sendingToSelf;
  164.  
  165.     static LocationNameRec    location;
  166.     static PortInfoRec        portInfo;
  167.     static Boolean            defaultOK = false;
  168.  
  169.     err = noErr;    /* Make sure we do the code for the second main if. */
  170.  
  171.     target->dataHandle = nil;
  172.         /* Assume we will fail and nil this descriptor out. */
  173.  
  174.     if (!sendDirect) {
  175.         if (!gHasPPCToolbox)
  176.             sendDirect = true;    /* No tools to send with, so send direct. */
  177.  
  178.         else {        /* We are not sending to self. */
  179.                     /* sendDirect is false.           */
  180.             err = PPCBrowser(
  181.                 prompt,            /* Browse dialog box prompt.           */
  182.                 applListLabel,    /* The 'programs' list title.           */
  183.                 defaultOK,        /* Initially false.                       */
  184.                 &location,        /* Correct if defaultOK is true.       */
  185.                 &portInfo,        /* Correct if defaultOK is true.       */
  186.                 portFilter,        /* No port filtering.                   */
  187.                 nil                /* List ports of type 'PPCToolBox'.       */
  188.             );
  189.  
  190.             if (!err) {                    /* If user didn't cancel... */
  191.                 defaultOK = true;        /* Default to the same port next time. */
  192.                 if (replyMode == kAEWaitReply) {
  193.                     /* Sender wants a reply and will be waiting... */
  194.  
  195.                     sendingToSelf = false;
  196.                         /* Assume that we aren't sending to ourselves. */
  197.  
  198.                     if (!location.locationKindSelector) {
  199.                         /* Hey, we are sending to ourselves! */
  200.  
  201.                         err = GetProcessSerialNumberFromPortName(
  202.                                 &portInfo.name, &targetPSN);
  203.                         if (!err) {
  204.                             GetCurrentProcess(&myPSN);
  205.                             err = SameProcess(&targetPSN, &myPSN, &sendingToSelf);
  206.                         }
  207.                     }
  208.  
  209.                     if (sendingToSelf) sendDirect = true;
  210.  
  211.                 }
  212.             }
  213.         }
  214.     }
  215.  
  216.     if (!err) {
  217.         if (sendDirect) {
  218.             /* Finally, we get to the point... */
  219.  
  220.             targetPSN.highLongOfPSN = 0;
  221.             targetPSN.lowLongOfPSN = kCurrentProcess;
  222.                 /* Process serial # is equal to kCurrentProcess.  This
  223.                 ** bypasses ePPC and speeds up things considerably. */
  224.  
  225.             err = AECreateDesc(
  226.                 typeProcessSerialNumber,    /* Standard PSN descriptor type. */
  227.                 (Ptr)&targetPSN,            /* "No ePPC" process serial #.     */
  228.                 sizeof(targetPSN),            /* Size of data (2 longs).         */
  229.                 target                        /* Wherefore art thou desc.         */
  230.             );
  231.         }
  232.         else {
  233.             theTargetID.location = location;
  234.             theTargetID.name     = portInfo.name;
  235.                 /* The fields sessionID does not need to be filled in now.
  236.                 ** The sessionID is returned when you actually connect to
  237.                 ** a port.  You can then use the sessionID from that point
  238.                 ** on to improve speed.
  239.                 **
  240.                 ** You also don't need to fill in the recvrName field at this
  241.                 ** point.  This is filled in, again, when the session is
  242.                 ** actually established.
  243.                 **
  244.                 ** The amount of data for a non-us target is bigger.
  245.                 ** We need the whole dealie for our target, since
  246.                 ** it is out on the net somewhere. */
  247.  
  248.             err = AECreateDesc(
  249.                 typeTargetID,            /* Standard target descriptor type. */
  250.                 (Ptr)&theTargetID,        /* The data for the descriptor.        */
  251.                 sizeof(theTargetID),    /* Size of the data.                */
  252.                 target                    /* Wherefore art thou desc.            */
  253.             );
  254.         }
  255.     }
  256.     return (err);
  257. }
  258.