home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 August: Tool Chest / Dev.CD Aug 94.toast / Sample Code / AppsToGo / DTS.Lib / AEUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-24  |  9.0 KB  |  336 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:         DTS.Lib
  5. ** File:         AEUtils.c
  6. ** Written by:   Keith Rollin
  7. ** Modified by:  Eric Soldan
  8. **
  9. ** Copyright © 1990-1991 Apple Computer, Inc.
  10. ** All rights reserved.
  11. */
  12.  
  13. /* You may incorporate this sample code into your applications without
  14. ** restriction, though the sample code has been provided "AS IS" and the
  15. ** responsibility for its operation is 100% yours.  However, what you are
  16. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  17. ** after having made changes. If you're going to re-distribute the source,
  18. ** we require that you make it clear in the source that the code was
  19. ** descended from Apple Sample Code, but that you've made changes. */
  20.  
  21.  
  22.  
  23. /*****************************************************************************/
  24.  
  25.  
  26.  
  27. #include "DTS.Lib2.h"
  28. #include "DTS.Lib.protos.h"
  29.  
  30. #ifndef __NOTIFICATION__
  31. #include <Notification.h>
  32. #endif
  33.  
  34. #ifndef __RESOURCES__
  35. #include <Resources.h>
  36. #endif
  37.  
  38. #ifndef __EPPC__
  39. #include <EPPC.h>
  40. #endif
  41.  
  42.  
  43.  
  44. /*****************************************************************************/
  45.  
  46.  
  47.  
  48. extern Boolean        gHasPPCToolbox;
  49.  
  50. Boolean                gNotifyUser   = true;
  51. static Boolean        gNotifyActive = false;
  52. static NMRec        gNotifyUserInfo = {
  53.     nil,        /* qLink */
  54.     nmType,        /* qType */
  55.     0,            /* nmFlags */
  56.     0L,            /* nmPrivate */
  57.     0,            /* nmReserved */
  58.     1,            /* nmMark */
  59.     nil,        /* nmIcon */
  60.     (Handle)-1,    /* nmSound */
  61.     nil,        /* nmStr */
  62.     nil,        /* nmResp */
  63.     0L            /* nmRefCon */
  64. };
  65.  
  66.  
  67.  
  68. /*****************************************************************************/
  69. /*****************************************************************************/
  70.  
  71.  
  72.  
  73. /* Simply calls AEProcessAppleEvent and reports any errors.
  74. ** AEProcessAppleEvent looks in its table of registered events and sees if
  75. ** the current event is registered.  If so, off we go. */
  76.  
  77. #pragma segment AppleEvents
  78. void    DoHighLevelEvent(EventRecord *event)
  79. {
  80.     AEProcessAppleEvent(event);
  81. }
  82.  
  83.  
  84.  
  85. /*****************************************************************************/
  86.  
  87.  
  88.  
  89. /* This function returns the zone, machine, and application name for the
  90. ** indicated target descriptor. */
  91.  
  92. #pragma segment AppleEvents
  93. OSErr    GetTargetInfo(AEAddressDesc targetDesc, StringPtr zone,
  94.                       StringPtr machine, StringPtr application)
  95. {
  96.     ProcessSerialNumber targetPSN;
  97.     PortInfoRec            portInfo;
  98.     TargetID            theTargetID;
  99.     OSErr                err;
  100.  
  101.     zone[0]        = 0;
  102.     machine[0]     = 0;
  103.     application[0] = 0;
  104.     err = noErr;
  105.  
  106.     if (targetDesc.descriptorType == typeProcessSerialNumber) {
  107.         targetPSN = **(ProcessSerialNumber **)(targetDesc.dataHandle);
  108.         err = GetPortNameFromProcessSerialNumber(&portInfo.name, &targetPSN);
  109.         if (!err)
  110.             pcpy(application, portInfo.name.name);
  111.         return(err);
  112.     }
  113.  
  114.     if (targetDesc.descriptorType == typeTargetID) {
  115.         theTargetID = **(TargetID **)(targetDesc.dataHandle);
  116.         switch (theTargetID.location.locationKindSelector) {
  117.             case ppcNoLocation:
  118.                 break;
  119.             case ppcNBPLocation:
  120.                 pcpy(zone,    theTargetID.location.u.nbpEntity.zoneStr);
  121.                 pcpy(machine, theTargetID.location.u.nbpEntity.objStr);
  122.                 break;
  123.             case ppcNBPTypeLocation:
  124.                 break;
  125.         }
  126.         pcpy(application, theTargetID.name.name);
  127.         return(noErr);
  128.     }
  129.  
  130.     return(errAEWrongDataType);
  131. }
  132.  
  133.  
  134.  
  135. /*****************************************************************************/
  136.  
  137.  
  138.  
  139. /* Creates a TargetID.
  140. **
  141. ** If sendDirect is TRUE, the target is specified by setting a
  142. ** ProcessSerialNumber to kCurrentProcess.  This has the advantage of sending
  143. ** the message directly to ourselves, bypassing ePPC and gaining about a 10-15x
  144. ** speed improvement.  If sendDirect is FALSE, we see if we have the
  145. ** PPCToolBox.  If not, then we are forced to do a direct send.  If we do have
  146. ** the PPCToolbox, then we call PPCBrowser.  We then look at the reply, and
  147. ** factor in the mode we are going to use in AESend.  If that mode is
  148. ** kAEWaitReply and the user selected us as the target, we have to turn that
  149. ** into a direct send.  This is because the AppleEvent Manager will otherwise
  150. ** post the event as a high-level event.  However, we are busy waiting for a
  151. ** reply, not looking for events, so we'll hang.  We avoid this by forcing a
  152. ** direct send. */
  153.  
  154. #pragma segment AppleEvents
  155. OSErr    MakeTarget(AEAddressDesc *target, Boolean sendDirect, short replyMode,
  156.                    Str255 prompt, Str255 applListLabel,
  157.                    PPCFilterUPP portFilter,
  158.                    char *theLocNBPType)
  159. {
  160.     OSErr                    err;
  161.     ProcessSerialNumber     targetPSN;
  162.     ProcessSerialNumber     myPSN;
  163.     TargetID                theTargetID;
  164.     Boolean                    sendingToSelf;
  165.  
  166.     static LocationNameRec    location;
  167.     static PortInfoRec        portInfo;
  168.     static Boolean            defaultOK = false;
  169.  
  170.     err = noErr;    /* Make sure we do the code for the second main if. */
  171.  
  172.     target->dataHandle = nil;
  173.         /* Assume we will fail and nil this descriptor out. */
  174.  
  175.     if (!sendDirect) {
  176.         if (!gHasPPCToolbox)
  177.             sendDirect = true;    /* No tools to send with, so send direct. */
  178.  
  179.         else {        /* We are not sending to self. */
  180.                     /* sendDirect is false.           */
  181.             err = PPCBrowser(
  182.                 prompt,            /* Browse dialog box prompt.           */
  183.                 applListLabel,    /* The 'programs' list title.           */
  184.                 defaultOK,        /* Initially false.                       */
  185.                 &location,        /* Correct if defaultOK is true.       */
  186.                 &portInfo,        /* Correct if defaultOK is true.       */
  187.                 portFilter,        /* Port filtering.                       */
  188.                 (StringPtr)theLocNBPType    /* List ports of this type */
  189.             );
  190.  
  191.             if (!err) {                    /* If user didn't cancel... */
  192.                 defaultOK = true;        /* Default to the same port next time. */
  193.                 if (replyMode == kAEWaitReply) {
  194.                     /* Sender wants a reply and will be waiting... */
  195.  
  196.                     sendingToSelf = false;
  197.                         /* Assume that we aren't sending to ourselves. */
  198.  
  199.                     if (!location.locationKindSelector) {
  200.                         /* Hey, we are sending to ourselves! */
  201.  
  202.                         err = GetProcessSerialNumberFromPortName(
  203.                                 &portInfo.name, &targetPSN);
  204.                         if (!err) {
  205.                             GetCurrentProcess(&myPSN);
  206.                             err = SameProcess(&targetPSN, &myPSN, &sendingToSelf);
  207.                         }
  208.                     }
  209.  
  210.                     if (sendingToSelf)
  211.                         sendDirect = true;
  212.  
  213.                 }
  214.             }
  215.         }
  216.     }
  217.  
  218.     if (!err) {
  219.         if (sendDirect) {
  220.             /* Finally, we get to the point... */
  221.  
  222.             targetPSN.highLongOfPSN = 0;
  223.             targetPSN.lowLongOfPSN = kCurrentProcess;
  224.                 /* Process serial # is equal to kCurrentProcess.  This
  225.                 ** bypasses ePPC and speeds up things considerably. */
  226.  
  227.             err = AECreateDesc(
  228.                 typeProcessSerialNumber,    /* Standard PSN descriptor type. */
  229.                 (Ptr)&targetPSN,            /* "No ePPC" process serial #.     */
  230.                 sizeof(targetPSN),            /* Size of data (2 longs).         */
  231.                 target                        /* Wherefore art thou desc.         */
  232.             );
  233.         }
  234.         else {
  235.             theTargetID.location = location;
  236.             theTargetID.name     = portInfo.name;
  237.                 /* The fields sessionID does not need to be filled in now.
  238.                 ** The sessionID is returned when you actually connect to
  239.                 ** a port.  You can then use the sessionID from that point
  240.                 ** on to improve speed.
  241.                 **
  242.                 ** You also don't need to fill in the recvrName field at this
  243.                 ** point.  This is filled in, again, when the session is
  244.                 ** actually established.
  245.                 **
  246.                 ** The amount of data for a non-us target is bigger.
  247.                 ** We need the whole dealie for our target, since
  248.                 ** it is out on the net somewhere. */
  249.  
  250.             err = AECreateDesc(
  251.                 typeTargetID,            /* Standard target descriptor type. */
  252.                 (Ptr)&theTargetID,        /* The data for the descriptor.        */
  253.                 sizeof(theTargetID),    /* Size of the data.                */
  254.                 target                    /* Wherefore art thou desc.            */
  255.             );
  256.         }
  257.     }
  258.     return (err);
  259. }
  260.  
  261.  
  262.  
  263. /*****************************************************************************/
  264.  
  265.  
  266.  
  267. /* Used to check for any unread required parameters. Returns true if we
  268. ** missed at least one. */
  269.  
  270. #pragma segment AppleEvents
  271. Boolean    MissedAnyParameters(AppleEvent *message)
  272. {
  273.     OSErr        err;
  274.     DescType    ignoredActualType;
  275.     AEKeyword    missedKeyword;
  276.     Size        ignoredActualSize;
  277.  
  278.     err = AEGetAttributePtr(    /* SEE IF PARAMETERS ARE ALL USED UP.          */
  279.         message,                /* AppleEvent to check.                          */
  280.         keyMissedKeywordAttr,    /* Look for unread parameters.                  */
  281.         typeWildCard,            /* So we can see what type we missed, if any. */
  282.         &ignoredActualType,        /* What it would have been if not coerced.      */
  283.         (Ptr)&missedKeyword,    /* Data area.  (Keyword not handled.)          */
  284.         sizeof(missedKeyword),    /* Size of data area.                          */
  285.         &ignoredActualSize        /* Actual data size.                          */
  286.     );
  287.  
  288. /* No error means that we found some unused parameters. */
  289.  
  290.     if (err == noErr)
  291.         err = errAEEventNotHandled;
  292.  
  293. /* errAEDescNotFound means that there are no more parameters.  If we get
  294. ** an error code other than that, flag it. */
  295.  
  296.     return(err != errAEDescNotFound);
  297. }
  298.  
  299.  
  300.  
  301. /*****************************************************************************/
  302.  
  303.  
  304.  
  305. #pragma segment AppleEvents
  306. void    NotifyCancel(void)
  307. {
  308.     if (gNotifyActive) {
  309.         NMRemove((NMRecPtr)&gNotifyUserInfo);
  310.         gNotifyActive = false;
  311.     }
  312. }
  313.  
  314.  
  315.  
  316. /*****************************************************************************/
  317.  
  318.  
  319.  
  320. #pragma segment AppleEvents
  321. void    NotifyUser(void)
  322. {
  323.     if (gNotifyUser) {
  324.         if (gInBackground) {
  325.             if (!gNotifyActive) {
  326.                 gNotifyUserInfo.nmIcon = GetResource('SICN', 128);
  327.                 NMInstall(&gNotifyUserInfo);
  328.                 gNotifyActive = true;
  329.             }
  330.         }
  331.     }
  332. }
  333.  
  334.  
  335.  
  336.