home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / DTS.Lib / AEUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-04  |  9.0 KB  |  338 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.     OSErr    err;
  81.  
  82.     err = AEProcessAppleEvent(event);
  83. }
  84.  
  85.  
  86.  
  87. /*****************************************************************************/
  88.  
  89.  
  90.  
  91. /* This function returns the zone, machine, and application name for the
  92. ** indicated target descriptor. */
  93.  
  94. #pragma segment AppleEvents
  95. OSErr    GetTargetInfo(AEAddressDesc targetDesc, StringPtr zone,
  96.                       StringPtr machine, StringPtr application)
  97. {
  98.     ProcessSerialNumber targetPSN;
  99.     PortInfoRec            portInfo;
  100.     TargetID            theTargetID;
  101.     OSErr                err;
  102.  
  103.     zone[0]        = 0;
  104.     machine[0]     = 0;
  105.     application[0] = 0;
  106.     err = noErr;
  107.  
  108.     if (targetDesc.descriptorType == typeProcessSerialNumber) {
  109.         targetPSN = **(ProcessSerialNumber **)(targetDesc.dataHandle);
  110.         err = GetPortNameFromProcessSerialNumber(&portInfo.name, &targetPSN);
  111.         if (!err)
  112.             pcpy(application, portInfo.name.name);
  113.         return(err);
  114.     }
  115.  
  116.     if (targetDesc.descriptorType == typeTargetID) {
  117.         theTargetID = **(TargetID **)(targetDesc.dataHandle);
  118.         switch (theTargetID.location.locationKindSelector) {
  119.             case ppcNoLocation:
  120.                 break;
  121.             case ppcNBPLocation:
  122.                 pcpy(zone,    theTargetID.location.u.nbpEntity.zoneStr);
  123.                 pcpy(machine, theTargetID.location.u.nbpEntity.objStr);
  124.                 break;
  125.             case ppcNBPTypeLocation:
  126.                 break;
  127.         }
  128.         pcpy(application, theTargetID.name.name);
  129.         return(noErr);
  130.     }
  131.  
  132.     return(errAEWrongDataType);
  133. }
  134.  
  135.  
  136.  
  137. /*****************************************************************************/
  138.  
  139.  
  140.  
  141. /* Creates a TargetID.
  142. **
  143. ** If sendDirect is TRUE, the target is specified by setting a
  144. ** ProcessSerialNumber to kCurrentProcess.  This has the advantage of sending
  145. ** the message directly to ourselves, bypassing ePPC and gaining about a 10-15x
  146. ** speed improvement.  If sendDirect is FALSE, we see if we have the
  147. ** PPCToolBox.  If not, then we are forced to do a direct send.  If we do have
  148. ** the PPCToolbox, then we call PPCBrowser.  We then look at the reply, and
  149. ** factor in the mode we are going to use in AESend.  If that mode is
  150. ** kAEWaitReply and the user selected us as the target, we have to turn that
  151. ** into a direct send.  This is because the AppleEvent Manager will otherwise
  152. ** post the event as a high-level event.  However, we are busy waiting for a
  153. ** reply, not looking for events, so we'll hang.  We avoid this by forcing a
  154. ** direct send. */
  155.  
  156. #pragma segment AppleEvents
  157. OSErr    MakeTarget(AEAddressDesc *target, Boolean sendDirect, short replyMode,
  158.                    Str255 prompt, Str255 applListLabel,
  159.                    PPCFilterUPP portFilter,
  160.                    char *theLocNBPType)
  161. {
  162.     OSErr                    err;
  163.     ProcessSerialNumber     targetPSN;
  164.     ProcessSerialNumber     myPSN;
  165.     TargetID                theTargetID;
  166.     Boolean                    sendingToSelf;
  167.  
  168.     static LocationNameRec    location;
  169.     static PortInfoRec        portInfo;
  170.     static Boolean            defaultOK = false;
  171.  
  172.     err = noErr;    /* Make sure we do the code for the second main if. */
  173.  
  174.     target->dataHandle = nil;
  175.         /* Assume we will fail and nil this descriptor out. */
  176.  
  177.     if (!sendDirect) {
  178.         if (!gHasPPCToolbox)
  179.             sendDirect = true;    /* No tools to send with, so send direct. */
  180.  
  181.         else {        /* We are not sending to self. */
  182.                     /* sendDirect is false.           */
  183.             err = PPCBrowser(
  184.                 prompt,            /* Browse dialog box prompt.           */
  185.                 applListLabel,    /* The 'programs' list title.           */
  186.                 defaultOK,        /* Initially false.                       */
  187.                 &location,        /* Correct if defaultOK is true.       */
  188.                 &portInfo,        /* Correct if defaultOK is true.       */
  189.                 portFilter,        /* Port filtering.                       */
  190.                 (StringPtr)theLocNBPType    /* List ports of this type */
  191.             );
  192.  
  193.             if (!err) {                    /* If user didn't cancel... */
  194.                 defaultOK = true;        /* Default to the same port next time. */
  195.                 if (replyMode == kAEWaitReply) {
  196.                     /* Sender wants a reply and will be waiting... */
  197.  
  198.                     sendingToSelf = false;
  199.                         /* Assume that we aren't sending to ourselves. */
  200.  
  201.                     if (!location.locationKindSelector) {
  202.                         /* Hey, we are sending to ourselves! */
  203.  
  204.                         err = GetProcessSerialNumberFromPortName(
  205.                                 &portInfo.name, &targetPSN);
  206.                         if (!err) {
  207.                             GetCurrentProcess(&myPSN);
  208.                             err = SameProcess(&targetPSN, &myPSN, &sendingToSelf);
  209.                         }
  210.                     }
  211.  
  212.                     if (sendingToSelf)
  213.                         sendDirect = true;
  214.  
  215.                 }
  216.             }
  217.         }
  218.     }
  219.  
  220.     if (!err) {
  221.         if (sendDirect) {
  222.             /* Finally, we get to the point... */
  223.  
  224.             targetPSN.highLongOfPSN = 0;
  225.             targetPSN.lowLongOfPSN = kCurrentProcess;
  226.                 /* Process serial # is equal to kCurrentProcess.  This
  227.                 ** bypasses ePPC and speeds up things considerably. */
  228.  
  229.             err = AECreateDesc(
  230.                 typeProcessSerialNumber,    /* Standard PSN descriptor type. */
  231.                 (Ptr)&targetPSN,            /* "No ePPC" process serial #.     */
  232.                 sizeof(targetPSN),            /* Size of data (2 longs).         */
  233.                 target                        /* Wherefore art thou desc.         */
  234.             );
  235.         }
  236.         else {
  237.             theTargetID.location = location;
  238.             theTargetID.name     = portInfo.name;
  239.                 /* The fields sessionID does not need to be filled in now.
  240.                 ** The sessionID is returned when you actually connect to
  241.                 ** a port.  You can then use the sessionID from that point
  242.                 ** on to improve speed.
  243.                 **
  244.                 ** You also don't need to fill in the recvrName field at this
  245.                 ** point.  This is filled in, again, when the session is
  246.                 ** actually established.
  247.                 **
  248.                 ** The amount of data for a non-us target is bigger.
  249.                 ** We need the whole dealie for our target, since
  250.                 ** it is out on the net somewhere. */
  251.  
  252.             err = AECreateDesc(
  253.                 typeTargetID,            /* Standard target descriptor type. */
  254.                 (Ptr)&theTargetID,        /* The data for the descriptor.        */
  255.                 sizeof(theTargetID),    /* Size of the data.                */
  256.                 target                    /* Wherefore art thou desc.            */
  257.             );
  258.         }
  259.     }
  260.     return (err);
  261. }
  262.  
  263.  
  264.  
  265. /*****************************************************************************/
  266.  
  267.  
  268.  
  269. /* Used to check for any unread required parameters. Returns true if we
  270. ** missed at least one. */
  271.  
  272. #pragma segment AppleEvents
  273. Boolean    MissedAnyParameters(AppleEvent *message)
  274. {
  275.     OSErr        err;
  276.     DescType    ignoredActualType;
  277.     AEKeyword    missedKeyword;
  278.     Size        ignoredActualSize;
  279.  
  280.     err = AEGetAttributePtr(    /* SEE IF PARAMETERS ARE ALL USED UP.          */
  281.         message,                /* AppleEvent to check.                          */
  282.         keyMissedKeywordAttr,    /* Look for unread parameters.                  */
  283.         typeWildCard,            /* So we can see what type we missed, if any. */
  284.         &ignoredActualType,        /* What it would have been if not coerced.      */
  285.         (Ptr)&missedKeyword,    /* Data area.  (Keyword not handled.)          */
  286.         sizeof(missedKeyword),    /* Size of data area.                          */
  287.         &ignoredActualSize        /* Actual data size.                          */
  288.     );
  289.  
  290. /* No error means that we found some unused parameters. */
  291.  
  292.     if (err == noErr)
  293.         err = errAEEventNotHandled;
  294.  
  295. /* errAEDescNotFound means that there are no more parameters.  If we get
  296. ** an error code other than that, flag it. */
  297.  
  298.     return(err != errAEDescNotFound);
  299. }
  300.  
  301.  
  302.  
  303. /*****************************************************************************/
  304.  
  305.  
  306.  
  307. #pragma segment AppleEvents
  308. void    NotifyCancel(void)
  309. {
  310.     if (gNotifyActive) {
  311.         NMRemove((NMRecPtr)&gNotifyUserInfo);
  312.         gNotifyActive = false;
  313.     }
  314. }
  315.  
  316.  
  317.  
  318. /*****************************************************************************/
  319.  
  320.  
  321.  
  322. #pragma segment AppleEvents
  323. void    NotifyUser(void)
  324. {
  325.     if (gNotifyUser) {
  326.         if (gInBackground) {
  327.             if (!gNotifyActive) {
  328.                 gNotifyUserInfo.nmIcon = GetResource('SICN', 128);
  329.                 NMInstall(&gNotifyUserInfo);
  330.                 gNotifyActive = true;
  331.             }
  332.         }
  333.     }
  334. }
  335.  
  336.  
  337.  
  338.