home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / DTS.Lib / AERequired.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-07  |  11.1 KB  |  403 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** Program:        DTS.Lib
  5. ** File:        AERequired.c
  6. ** Written by:  Eric Soldan
  7. **
  8. ** Copyright © 1990-1991 Apple Computer, Inc.
  9. ** All rights reserved.
  10. **
  11. ** This code implements the required AppleEvents, specific to DTS.Lib.
  12. */
  13.  
  14. /* You may incorporate this sample code into your applications without
  15. ** restriction, though the sample code has been provided "AS IS" and the
  16. ** responsibility for its operation is 100% yours.  However, what you are
  17. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  18. ** after having made changes. If you're going to re-distribute the source,
  19. ** we require that you make it clear in the source that the code was
  20. ** descended from Apple Sample Code, but that you've made changes. */
  21.  
  22.  
  23.  
  24. /*****************************************************************************/
  25.  
  26.  
  27.  
  28. #include "DTS.Lib2.h"
  29. #include "DTS.Lib.protos.h"
  30.  
  31. #ifndef __GESTALTEQU__
  32. #include <GestaltEqu.h>
  33. #endif
  34.  
  35.  
  36.  
  37. /*****************************************************************************/
  38.  
  39.  
  40.  
  41. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  42.  
  43. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  44. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon);
  45. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon);
  46. static OSErr        OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode);
  47.  
  48.  
  49.  
  50. /*****************************************************************************/
  51.  
  52.  
  53.  
  54. AEHandler gRequiredAppleEventHandlers[] = {
  55.     { kCoreEventClass,        kAEOpenApplication,        (AEEventHandlerProcPtr)DoAEOpenApplication,        nil },
  56.     { kCoreEventClass,        kAEOpenDocuments,        (AEEventHandlerProcPtr)DoAEOpenDocuments,        nil },
  57.     { kCoreEventClass,        kAEPrintDocuments,        (AEEventHandlerProcPtr)DoAEPrintDocuments,        nil },
  58.     { kCoreEventClass,        kAEQuitApplication,        (AEEventHandlerProcPtr)DoAEQuitApplication,        nil }
  59.         /* The above are the four required AppleEvents. */
  60. };
  61.  
  62. #define kNumKeywords (sizeof(gRequiredAppleEventHandlers) / sizeof(AEHandler))
  63.  
  64. Boolean        gHasAppleEvents = false;
  65. Boolean        gHasPPCToolbox  = false;
  66. DescType    gAERequiredType;
  67.  
  68. extern TreeObjHndl    gWindowFormats;
  69. extern Boolean        gNoFinderPrint;
  70.  
  71.  
  72.  
  73. /*****************************************************************************/
  74.  
  75.  
  76.  
  77. extern Boolean        gQuitApplication, gNoDefaultDocument, gInBackground;
  78. extern short        gPrintPage;
  79.  
  80. extern Cursor        *gCursorPtr;
  81. extern OSType        gAppWindowType;
  82.  
  83.  
  84.  
  85. /*****************************************************************************/
  86. /*****************************************************************************/
  87.  
  88.  
  89.  
  90. /* Intializes AppleEvent dispatcher table for the required events.  It also
  91. ** determines if the machine is PPCBrowser and AppleEvent capable.  If so,
  92. ** the booleans gHasAppleEvents and gHasPPCToolbox are set true.  This function
  93. ** must be the first AppleEvents initialization DTS.framework function called, as the
  94. ** other functions depend on the booleans being set correctly. */
  95.  
  96. #pragma segment AppleEvents
  97. OSErr    InitRequiredAppleEvents(void)
  98. {
  99.     OSErr    err;
  100.     long    result;
  101.     short    i;
  102.  
  103.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  104.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  105.  
  106.     if (gHasAppleEvents) {
  107.  
  108.         for (i = 0; i < kNumKeywords; ++i) {
  109.  
  110.             if (!gRequiredAppleEventHandlers[i].theUPP)
  111.                 gRequiredAppleEventHandlers[i].theUPP =
  112.                     NewAEEventHandlerProc(gRequiredAppleEventHandlers[i].theHandler);
  113.  
  114.             err = AEInstallEventHandler(
  115.                 gRequiredAppleEventHandlers[i].theEventClass,    /* What class to install.  */
  116.                 gRequiredAppleEventHandlers[i].theEventID,        /* Keywords to install.    */
  117.                 gRequiredAppleEventHandlers[i].theUPP,            /* The AppleEvent handler. */
  118.                 0L,                                                /* Unused refcon.           */
  119.                 false                                            /* Only for our app.       */
  120.             );
  121.             if (err) {
  122.                 HCenteredAlert(rErrorAlert, nil, gAlertFilterUPP);
  123.                 return(err);
  124.             }
  125.         }
  126.     }
  127.  
  128.     return(noErr);
  129. }
  130.  
  131.  
  132.  
  133. /*****************************************************************************/
  134.  
  135.  
  136.  
  137. /* This function opens a new DTS.framework document due to an AppleEvents request. */
  138.  
  139. #pragma segment AppleEvents
  140. pascal OSErr    DoAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  141. {
  142. #ifndef __MWERKS__
  143. #pragma unused (message, reply, refcon)
  144. #endif
  145.  
  146.     FileRecHndl    frHndl;
  147.     OSErr        err;
  148.     short        i;
  149.     TreeObjHndl    wobj;
  150.     long        attr;
  151.  
  152.     gAERequiredType = 'oapp';
  153.  
  154.     gCursorPtr = nil;
  155.         /* Force re-calc of cursor region and cursor to use. */
  156.  
  157.     err = noErr;
  158.     if (gWindowFormats) {
  159.         for (i = (*gWindowFormats)->numChildren; i;) {
  160.             wobj = GetChildHndl(gWindowFormats, --i);
  161.             attr = mDerefWFMT(wobj)->attributes;
  162.             if (!(attr & kwRuntimeOnlyDoc)) {
  163.                 if (attr & kwAutoNew) {
  164.                     err = NewDocumentWindow(&frHndl, mDerefWFMT(wobj)->sfType, true);
  165.                     if (err) break;
  166.                 }
  167.             }
  168.         }
  169.     }
  170.     else {
  171.         if (!gNoDefaultDocument) {
  172.             err = NewDocument(&frHndl, gAppWindowType, true);
  173.             if (!err) {
  174.                 if (frHndl) {
  175.                     err = DoNewWindow(frHndl, nil, GetNextWindow(nil, 0), (WindowPtr)-1);
  176.                     if (err)
  177.                         DisposeDocument(frHndl);
  178.                 }
  179.             }
  180.         }
  181.     }
  182.  
  183.     gAERequiredType = 0;
  184.  
  185.     return(err);
  186. }
  187.  
  188.  
  189.  
  190. /*****************************************************************************/
  191.  
  192.  
  193.  
  194. /* This function opens existing DTS.framework documents due to an AppleEvents request. */
  195.  
  196. #pragma segment AppleEvents
  197. static pascal OSErr    DoAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  198. {
  199. #ifndef __MWERKS__
  200. #pragma unused (refcon)
  201. #endif
  202.  
  203.     OSErr    err;
  204.  
  205.     gAERequiredType = 'odoc';
  206.  
  207.     gCursorPtr = nil;        /* Force re-calc of cursor region and cursor to use. */
  208.     err = OpenDocEventHandler(message, reply, 0);
  209.         /* The 0 means regular open document. */
  210.  
  211.     gAERequiredType = 0;
  212.  
  213.     return(err);
  214. }
  215.  
  216.  
  217.  
  218. /*****************************************************************************/
  219.  
  220.  
  221.  
  222. /* This function prints DTS.framework documents due to an AppleEvents request. */
  223.  
  224. #pragma segment AppleEvents
  225. static pascal OSErr    DoAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  226. {
  227. #ifndef __MWERKS__
  228. #pragma unused (refcon)
  229. #endif
  230.  
  231.     short                openMode;
  232.     ProcessSerialNumber    cpsn, fpsn;
  233.     Boolean                procsSame;
  234.     OSErr                err;
  235.  
  236.     if (gNoFinderPrint) err = DoAEOpenDocuments(message, reply, refcon);
  237.     else {
  238.         gAERequiredType = 'pdoc';
  239.         gCursorPtr = nil;                /* Force re-calc of cursor region and cursor to use. */
  240.  
  241.         openMode = 1;
  242.         if (!AEInteractWithUser(kTimeOutInTicks, nil, nil))
  243.             ++openMode;
  244.  
  245.         GetCurrentProcess(&cpsn);        /* We may have been moved to the front. */
  246.         GetFrontProcess(&fpsn);
  247.         SameProcess(&cpsn, &fpsn, &procsSame);
  248.         gInBackground = !procsSame;
  249.  
  250.         err = OpenDocEventHandler(message, reply, openMode);
  251.             /* openMode is either 1 or 2, depending if user interaction is okay. */
  252.  
  253.         gAERequiredType = 0;
  254.     }
  255.  
  256.     return(err);
  257. }
  258.  
  259.  
  260.  
  261. /*****************************************************************************/
  262.  
  263.  
  264.  
  265. /* This function sets a quit flag so that DTS.framework will quit due to an
  266. ** AppleEvents request. */
  267.  
  268. #pragma segment AppleEvents
  269. static pascal OSErr    DoAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  270. {
  271. #ifndef __MWERKS__
  272. #pragma unused (message, reply, refcon)
  273. #endif
  274.  
  275.     OSErr    err;
  276.  
  277.     gCursorPtr = nil;
  278.         /* Force re-calc of cursor region and cursor to use. */
  279.  
  280.     if (DisposeAllWindows()) {
  281.         gQuitApplication = true;
  282.         err = noErr;
  283.     }
  284.     else err = errAEEventNotHandled;
  285.         /* All windows didn't close because user cancelled the quit. */
  286.  
  287.     return(err);
  288. }
  289.  
  290.  
  291.  
  292. /*****************************************************************************/
  293.  
  294.  
  295.  
  296. /* Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  297. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  298. ** and opens each indicated file.  It also shows the technique to be used in
  299. ** determining if you are doing everything the AppleEvent record is telling
  300. ** you.  Parameters can be divided up into two groups: required and optional.
  301. ** Before executing an event, you must make sure that you've read all the
  302. ** required events.  This is done by making an "any more?" call to the
  303. ** AppleEvent manager. */
  304.  
  305. #pragma segment AppleEvents
  306. static OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  307. {
  308. #ifndef __MWERKS__
  309. #pragma unused (reply)
  310. #endif
  311.  
  312.     OSErr        err;
  313.     OSErr        err2;
  314.     AEDesc        theDesc;
  315.     FSSpec        theFSS;
  316.     short        loop;
  317.     long        numFilesToOpen, wkind;
  318.     AEKeyword    ignoredKeyWord;
  319.     DescType    ignoredType;
  320.     Size        ignoredSize;
  321.     FileRecHndl    frHndl;
  322.     WindowPtr    docWindow, fwindow;
  323.  
  324.     theDesc.dataHandle = nil;
  325.         /* Make sure disposing of the descriptors is okay in all cases.
  326.         ** This will not be necessary after 7.0b3, since the calls that
  327.         ** attempt to create the descriptors will nil automatically
  328.         ** upon failure. */
  329.  
  330.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc);
  331.     if (err)
  332.         return(err);
  333.  
  334.     if (!MissedAnyParameters(message)) {
  335.  
  336. /* Got all the parameters we need.  Now, go through the direct object,
  337. ** see what type it is, and parse it up. */
  338.  
  339.         err = AECountItems(&theDesc, &numFilesToOpen);
  340.         if (!err) {
  341.             /* We have numFilesToOpen that need opening, as either a window
  342.             ** or to be printed.  Go to it... */
  343.  
  344.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  345.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  346.                     &theDesc,            /* List of file names.             */
  347.                     loop,                /* Item # in the list.             */
  348.                     typeFSS,            /* Item is of type FSSpec.         */
  349.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  350.                     &ignoredType,        /* Returned type -- we know.     */
  351.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  352.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  353.                     &ignoredSize        /* Actual size -- we know.         */
  354.                 );
  355.                 if (err) break;
  356.  
  357.                 err = OpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  358.                 if (err) break;
  359.  
  360.                 docWindow = (*frHndl)->fileState.window;
  361.                 if (!docWindow) {        /* New file being opened. */
  362.                     gPrintPage = mode;
  363.                         /* Open the window off-screen if we are printing.
  364.                         ** We use the gPrintPage global to flag this.  Normally, the
  365.                         ** gPrintPage global is to tell ImageDocument if we are imaging
  366.                         ** to the window or to paper.  We don't need it for this yet,
  367.                         ** as we can't image the document until it is opened.  DoNewWindow()
  368.                         ** uses gPrintPage as a flag to open the window off-screen, but
  369.                         ** visible, so that PrintMonitor can use the title of the window
  370.                         ** as the document name that is being printed. */
  371.  
  372.                     err = DoNewWindow(frHndl, &docWindow, GetNextWindow(nil, 0), (WindowPtr)-1);
  373.                     if (err)
  374.                         DisposeDocument(frHndl);
  375.                     else {
  376.                         if (gPrintPage) {
  377.                             err  = PrintDocument(frHndl, (mode == 2), (loop == 1));
  378.                             mode = 1;    /* No interaction mode (mode == 2) only valid
  379.                                         ** for the first printed document. */
  380.                             DisposeDocument(frHndl);
  381.                             DisposeAnyWindow(docWindow);
  382.                         }
  383.                     }
  384.                     gPrintPage = 0;
  385.                         /* Put the ImageDocument controlling global back to normal. */
  386.                 }
  387.                 else {
  388.                     wkind   = (*frHndl)->fileState.attributes & (kwIsPalette | kwIsModalDialog);
  389.                     fwindow = FrontWindowOfType(wkind, true);
  390.                     CleanSendInFront(docWindow, fwindow);
  391.                 }
  392.             }
  393.         }
  394.     }
  395.     DonePrinting();        /* Clean up after printing, if we did any. */
  396.  
  397.     err2 = AEDisposeDesc(&theDesc);
  398.     return(err ? err : err2);
  399. }
  400.  
  401.  
  402.  
  403.