home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / DocShell / OpenDocX.cpp < prev    next >
Encoding:
Text File  |  1996-08-28  |  25.7 KB  |  887 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        OpenDocX.cpp
  3.  
  4.     Contains:    OpenDoc™ launcher application
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <16>    22.07.1996    NP        1370914: Remove System Process.
  13.         <15>     7/11/96    TJ        Fixed Name of function to check for MacOS 8
  14.         <14>    11.07.1996    NP        1365143: Can't find system process error
  15.                                     messages.
  16.         <13>     6/23/96    NP        10002: Launch time speedups. 1323565:
  17.                                     Refuse to run under MacOS 8. 131565: change
  18.                                     name of system process to OpenDoc
  19.         <12>     6/19/96    NP        10002: Launch time speedups.
  20.         <11>     6/18/96    NP        10002: Launch time speedups. 1351368: Make
  21.                                     watch cursor go away.
  22.         <10>     6/14/96    NP        10002: Launch time speedups, 1303832: can't
  23.                                     make stationery when part editor lib is
  24.                                     already in use.
  25.          <9>    .06.1996    NP        10002: Launch time fixes, system process.
  26.          <8>    .05.1996    NP        1352438: Add call to NotifyLaunchFailed.
  27.          <7>      5/8/96    NP        1332028: Remove wasted function call for
  28.                                     launch time speedup.
  29.          <6>     4/15/96    TJ        Nolonger include ODXDef.h
  30.          <5>    .04.1996    NP        1337753: Never show splash screen.
  31.          <4>     3/14/96    NP        1258295: Displayed alert when app is
  32.                                     double-clicked.
  33.          <3>     1/15/96    TJ        Cleaned Up
  34.          <2>     1/15/96    JA        1269485: Display splash screen only 1st
  35.                                     time launched.
  36.         <26>    10/27/95    TÇ        Remove code which checks for 32 bit
  37.                                     addressing.
  38.         <25>    10/25/95    TÇ        1281409 GM: OpenDoc needs an AboutBox.
  39.         <24>    10/24/95    CC        1290114: Unload the scrap earlier to avoid
  40.                                     segment loader errors or crash on low
  41.                                     application heap space.
  42.         <23>     9/29/95    eeh        1287262: use ShellDef.h
  43.         <22>     8/26/95    TÇ        1269688 FB1:  There is an unnecessary
  44.                                     variable
  45.         <21>     6/23/95    CC        1260976: Added UnloadScrap() after toolbox
  46.                                     initialization.
  47.         <20>     5/19/95    TÇ        1249396 (was BB) OpenDoc shell should
  48.                                     serialize stationery creation., 1235942
  49.                                     Launching the OpenDoc pref file causes a
  50.                                     1000 exception to be thrown, 1234877 BB:
  51.                                     OpenDoc creates a bad document if
  52.                                     stationary launch fails.
  53.         <19>     4/15/95    TÇ        #1236388 The launcher splash screen no
  54.                                     longer goes away when a document window is
  55.                                     opened
  56.         <18>      4/7/95    eeh        1234548: check for 24-bit mode
  57.         <17>      4/7/95    eeh        1221297: generalize ODOC handler to
  58.                                     HandleRequiredEvent
  59.         <16>     3/31/95    TÇ        1223445 Launcher barfs generating
  60.                                     stationery from R/O library
  61.                                     1223493 BB: Creating a stationary under low
  62.                                     disk space.
  63.                                     1226040 Launcher crashes if CFM68K is not
  64.                                     installed.
  65.                                     1222903 Launcher doesn't check whether it
  66.                                     could open the resource file for a library.
  67.                                     1233754 OpenDoc™ Launcher splash screen
  68.                                     should use vers 2 resource.
  69.         <15>     2/20/95    TÇ        #1210979 BB: 5-$ Bugs need to be evaluated
  70.                                     and removed from Shell
  71.                                     #1221861 BB: Incomplete AOCE support needs
  72.                                     to be removed from OpenDoc
  73.         <14>      2/2/95    CG        Added qd global.
  74.         <13>      2/2/95    CG        #1205177:  "Editors" and "OpenDoc
  75.                                     Libraries" folders are being registered
  76.                                     with cfm (PPC only).
  77.         <12>      1/9/95    NP        1209979: No changes. Check in to force
  78.                                     rebuild for old runtime.
  79.         <11>      1/6/95    jpa        Fix error reporting in HandleOpenDocuments.
  80.                                     [1198075]
  81.         <10>    12/20/94    jpa        Wait longer for CFM error event [1198075]
  82.          <9>     12/5/94    jpa        Catch CFM errors on document launch.
  83.                                     Display splash screen. [1198075]
  84.          <8>    10/12/94    TÇ        68K: check to see if an AEDesc is null
  85.                                     before disposing
  86.          <7>     9/15/94    TÇ        #1183572 implement OpenDoc Shell PlugIns,
  87.                                     got rid of a few warnings
  88.          <6>      9/8/94    eeh        #1185443: fix HandleOpenDocuments to
  89.                                     preserve "special params".
  90.          <5>     8/25/94    TÇ        #1183223 Enabled launching of documents in
  91.                                     folders other than that of the OpenDoc
  92.                                     libraries
  93.          <4>     7/25/94    TÇ        added Jens' fixes for better error
  94.                                     reporting and a few bug fixes of my own
  95.          <3>     7/19/94    TÇ        fixed a bug in ODXstrncpy
  96.          <2>     7/14/94    TÇ        changed resource copying code to using
  97.                                     constant names instead of hard coded
  98.                                     constants (for PPC)
  99.          <1>     7/13/94    TÇ        first checked in
  100.          <0>     6/27/94    SV        SOMverted
  101.         <11>     4/19/94    TÇ        Don't append a null character onto the end
  102.                                     of the name of the stationery file because
  103.                                     AFP chokes on it.
  104.         <10>     4/18/94    TÇ        Another fix for Symantec.  This time to
  105.                                     ODXstrncpy.
  106.          <9>     4/18/94    HL        Fixed Symantec Compilation.
  107.          <8>     4/18/94    TÇ        #1144379 Stationery model & generation have
  108.                                     been fixed to enable dragging & dropping of
  109.                                     stationery onto open documents.
  110.          <7>     4/11/94    TÇ        #1155854 Use CustomPutFile for Save A Copy.
  111.                                     Checks to make sure document's resource
  112.                                     fork was properly opened.
  113.          <6>     3/24/94    eeh        bug #1153053: Changes for PPC nativity (or
  114.                                     is it nativeness...?)
  115.          <5>     3/17/94    CG        #1151392: Removed #include ConstDef.h.
  116.          <4>     3/16/94    eeh        bug #1149649 cont'd: CopyNonDPParams needed
  117.                                     a return statement for Symantec
  118.          <3>     3/16/94    eeh        bug #1149649: added CopyNonDPParams
  119.          <2>     3/10/94    eeh        bug #1149632: added alias param to
  120.                                     LaunchDocument()
  121.         <14>      2/9/94    TÇ        PowerPC header fixes
  122.         <13>     1/18/94    TÇ        conserve type and creator of documents
  123.                                     being opened
  124.         <12>    12/17/93    TÇ        removed bogus semicolon at the end of the
  125.                                     line "    if (needUpdate);"
  126.         <11>    12/17/93    eeh        Code to install 'scsz' resource in
  127.                                     documents.
  128.         <10>     12/1/93    TÇ        added calls to FlushInstructionCache()
  129.                                     FlushDataCache() right before
  130.                                     LaunchApplication to fix 040 data cache vs.
  131.                                     instruction cache problem with copying
  132.                                     resources as data then launching a document
  133.                                     which uses them as code.
  134.          <9>    11/30/93    TÇ        added a cast to Ptr to pacify CFront
  135.          <8>    11/23/93    TÇ        mostly formatting
  136.          <7>    10/28/93    TÇ        use sizeof(FSSpec) instead of
  137.                                     GetPtrSize(theDocument)
  138.          <6>    10/27/93    TÇ        more of the same.
  139.          <5>    10/26/93    TÇ        nil out fields of AEDesc.
  140.          <4>    10/26/93    TÇ        add code to construct 'ODOC' aevt and pass
  141.                                     it along in the LaunchApplication call to
  142.                                     the document being launched
  143.          <3>    10/26/93    TÇ        need to also use CODE 2 "32-bit blah blah
  144.                                     blah" resource
  145.          <2>    10/23/93    TÇ        added code to verify and update CODE 0,
  146.                                     CODE 1, and SIZE -1 resource in documents
  147.                                     before they are launched
  148.          <1>    10/18/93    TÇ        first checked in
  149.  
  150.     To Do:
  151.     In Progress:
  152.         
  153. */
  154.  
  155.  
  156.  
  157. /*
  158.  
  159. This is the OpenDoc™ extension which is actually an application.
  160. The sole purpose of this extension is to satisfy the currnt "APPL" launching model in the Finder.
  161. When OpenDoc™ documents are double-clicked in the Finder, 
  162. Finder notices that the creator of the documents is the same as this extension,
  163. then launches this extension with those documents.
  164. The OpenDoc™ extension verifies and fixes if necessary,
  165. the resources in the documents,
  166. then launches the documents using the ProcessManager directly and quits.
  167.  
  168. */
  169.  
  170. #define ppcinterfaces        /* keeps GX headers quiet */
  171.  
  172. #ifndef __TYPES__
  173. #include <Types.h>
  174. #endif
  175.  
  176. #ifndef __GESTALTEQU__
  177. #include <GestaltEqu.h>
  178. #endif
  179.  
  180. #ifndef __TEXTUTILS__
  181. #include <TextUtils.h>
  182. #endif
  183.  
  184. #ifndef __OSEVENTS__
  185. #include <OSEvents.h>
  186. #endif
  187.  
  188. #ifndef __QUICKDRAW__
  189. #include <Quickdraw.h>
  190. #endif
  191.  
  192. #ifndef __FONTS__
  193. #include <Fonts.h>
  194. #endif
  195.  
  196. #ifndef __FILES__
  197. #include <Files.h>
  198. #endif
  199.  
  200. #ifndef __RESOURCES__
  201. #include <Resources.h>
  202. #endif
  203.  
  204. #ifndef __EVENTS__
  205. #include <Events.h>
  206. #endif
  207.  
  208. #ifndef __APPLEEVENTS__
  209. #include <AppleEvents.h>
  210. #endif
  211.  
  212. #ifndef __DIALOGS__
  213. #include <Dialogs.h>
  214. #endif
  215.  
  216. #ifndef __MENUS__
  217. #include <Menus.h>
  218. #endif
  219.  
  220. #ifndef __OSUTILS__
  221. #include <OSUtils.h>
  222. #endif
  223.  
  224. #ifndef __TOOLUTILS__
  225. #include <ToolUtils.h>
  226. #endif
  227.  
  228. #ifndef __ERRORS__
  229. #include <Errors.h>
  230. #endif
  231.  
  232. #ifndef __SCRAP__
  233. #include <Scrap.h>
  234. #endif
  235.  
  236.  
  237. #ifndef _REGISTER_
  238. #include <RegisterFileLibs.h>
  239. #endif
  240.  
  241. #ifndef _SHELLDEF_
  242. #include "ShellDef.h"
  243. #endif
  244.  
  245. #ifndef _ODPRCS_
  246. #include "ODPrcs.h"
  247. #endif
  248.  
  249. #ifndef _ODXDPFNS_
  250. #include "ODXDpFns.h"
  251. #endif
  252.  
  253. #ifndef _ODXFUNCS_
  254. #include "ODXFuncs.h"
  255. #endif
  256.  
  257. #ifndef _PASCLSTR_
  258. #include "PasclStr.h"
  259. #endif
  260.  
  261. #ifndef _ERRUTILS_
  262. #include "ErrUtils.h"
  263. #endif
  264.  
  265. #ifndef ODDebug
  266. #error "Expected \"ODDEBUG\" to be defined."
  267. #endif
  268.  
  269. //==============================================================================
  270. // Constants
  271. //==============================================================================
  272.  
  273. const short kLaunchFailedAlert = 130;
  274. const short kGenericLaunchFailedAlert = 129;
  275.  
  276.  
  277. const long kQuitDelay          =  5 * 60;        /* Wait 1 second for an Apple event */
  278. const long kWaitForErrorDelay =  8 * 60;        /* Wait 8 seconds after trying to launch */
  279.  
  280.  
  281. #define SPLASHSCREEN 0                /* 1 enables splash screen, 0 disables */
  282.  
  283. //==============================================================================
  284. // Globals
  285. //==============================================================================
  286.  
  287. #ifndef __MWERKS__
  288. QDGlobals qd;
  289. #endif
  290.  
  291. FSSpec    gFileSpec;
  292.  
  293. //==============================================================================
  294. // Macros
  295. //==============================================================================
  296.  
  297. #define CHECK(EXPR)    if((err=(EXPR)) == noErr) ; else return err
  298. #if ODDebug
  299. #define LauncherDebugStr(x) DebugStr(CToPascalString(x))
  300. #else
  301. #define LauncherDebugStr(x)
  302. #endif
  303.  
  304. //==============================================================================
  305. // Function Prototypes
  306. //==============================================================================
  307.  
  308. static DialogPtr    gSplashScreen = NULL;
  309. static long            gQuitTime;
  310.  
  311. void            main( );
  312. static void        MainEventLoop( );
  313. static Boolean    FirstTimeLaunched( );
  314. static Boolean    ColorScreen( );
  315.  
  316. //static OSErr    CheckAppleEventForMissingParams(AppleEvent *theAppleEvent);
  317.  
  318. static pascal OSErr    HandleOpenAppEvent(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon);
  319. static pascal OSErr    NoOpAEHandler(AppleEvent *theAppleEvent,AppleEvent *reply,long refCon);
  320. static OSErr        GetOurCreator(OSType& type);
  321. static OSErr            ChangeOurCreator(OSType);
  322. static void            BumpOurFolderModDate();
  323. static OSErr        ReenableSystemProcess(FSSpec* fileSpec);
  324. static OSErr        GetCreator(FSSpec* fileSpec, OSType& type);
  325. static OSErr        ChangeCreator(FSSpec* fileSpec, OSType type);
  326. static OSErr        EnableApp(FSSpec* fileSpec);
  327. static OSErr        EnableAppIfNotAlready(FSSpec* fileSpec);
  328. static OSErr        DisableOurselves(FSSpec* fileSpec, OSType newSignature);
  329. static OSErr        SimpleLaunchApp(FSSpec* fileSpec);
  330. static void            DoTheRenamingThang(StringPtr newNameForSystemProcess);
  331.  
  332. //==============================================================================
  333. // OpenDocX Main and Event Loop
  334. //==============================================================================
  335.  
  336. //------------------------------------------------------------------------------
  337. // main
  338. //------------------------------------------------------------------------------
  339.  
  340. void main(void)
  341. {
  342.     MaxApplZone();
  343.     MoreMasters();
  344.  
  345.     // The scrap is copied into our application heap when the process is launched,
  346.     // occuping space otherwise used for launching documents.
  347.     // If the scrap is just the right size (approx. 30K), there isn't enough
  348.     // heap space left to launch a single document (the launcher will bail with 
  349.     // error -108).  Worse, if the scrap is just the right size, around 40K, 
  350.     // InitWindows will hang the system.  To avoid this, always unload the scrap.
  351.     // Testing for a nil scrap handle seems to avoid a write to nil by UnloadScrap.
  352.     // [cc]
  353.     if ( InfoScrap()->scrapHandle != nil )
  354.         UnloadScrap();
  355.  
  356.     InitGraf((Ptr)&qd.thePort);
  357.     InitFonts();
  358.     InitWindows();
  359.     InitMenus();
  360.     TEInit();
  361.     InitDialogs(nil);
  362.  
  363.     long gestaltResponse;
  364.     if ((Gestalt(gestaltCFMAttr, &gestaltResponse) != noErr) ||
  365.         !(gestaltResponse & (1<<gestaltCFMPresent)))
  366.     {
  367.         ReportDocumentError("\p",fragMgrInitErr);
  368.         return;
  369.     }
  370.  
  371.     if (RunningUnderMacOS8())
  372.         return;
  373. #define SYSTEMPROCESS 0
  374. #if SYSTEMPROCESS
  375.     // DISABLE OURSELVES IF WE ARE RUNNING IN A SYSTEM LATER THAN 7.5
  376.     ProcessSerialNumber psn = {0, kCurrentProcess};
  377.     ProcessInfoRec        info;
  378.  
  379.     info.processInfoLength = sizeof(ProcessInfoRec);
  380.     info.processName = NULL;
  381.     info.processAppSpec = &gFileSpec;
  382.  
  383.     if (GetProcessInformation(&psn, &info))
  384.         LauncherDebugStr("main: Totally unexpected error from GetProcessInformation.");
  385.     else
  386.     {
  387.         OSType    creator;
  388.         OSErr    error;
  389.         FSSpec    fileSpec;
  390.  
  391.         error = GetOurCreator(creator);
  392.         if (error)
  393.             LauncherDebugStr("main: Totally unexpected error from GetOurCreator.");
  394.         else
  395.         {
  396.             if (!IsSystem753OrGreater())
  397.             {
  398.                 if (creator != kODShellSignature)
  399.                     EnableApp(&gFileSpec);
  400.             }
  401.             else
  402.             {
  403.                 // THIS IS THE CASE I CARE MORE ABOUT. USER CAN ONLY UPGRADE A
  404.                 //    PARTICULAR SYSTEM, NOT DOWNGRADE IT.
  405.                 if (creator != kODDisabledProcessSignature)
  406.                 {
  407.                     Str255    newSystemProcessName;
  408.  
  409.                     if (!ReenableSystemProcess(&fileSpec))
  410.                     {
  411.                         if(!DisableOurselves(&gFileSpec,
  412.                                             kODDisabledProcessSignature))
  413.                             DoTheRenamingThang(newSystemProcessName);
  414.                     }
  415.                     CopyPascalString(fileSpec.name, newSystemProcessName);
  416.  
  417.                     SimpleLaunchApp(&fileSpec);
  418.                 }
  419.             }
  420.         }
  421.     }
  422. #endif /* SYSTEMPROCESS */
  423.     SetCursor(*GetCursor(watchCursor));
  424.  
  425.     AEEventHandlerUPP odocUPP = NewAEEventHandlerProc(HandleRequiredEvent);
  426.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  427.             odocUPP, 0, false);
  428.     (void) AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  429.             odocUPP, 0, false);
  430.  
  431.     AEEventHandlerUPP openAppUPP = NewAEEventHandlerProc(HandleOpenAppEvent);
  432.     (void) AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  433.             openAppUPP, 0, false); // no refcon, not system handler
  434.  
  435. //    (void) AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  436. //            noOpUPP, 0, false);
  437.  
  438.     // Install a handler for both "launch-failed" notification events
  439.     // so we can notify the user:
  440.     AEEventHandlerUPP handleErrUPP = NewAEEventHandlerProc(HandleLaunchFailed);
  441.     (void) AEInstallEventHandler(kCoreEventClass, kAEApplicationDied,
  442.             handleErrUPP, 0, false);
  443.     (void) AEInstallEventHandler(kCFMLaunchFailedEventClass, kCFMLaunchFailedEventID,
  444.             handleErrUPP, 0, false);
  445.     
  446.     MainEventLoop();
  447. }
  448.  
  449. //------------------------------------------------------------------------------
  450. //  MainEventLoop
  451. //------------------------------------------------------------------------------
  452.  
  453. static void MainEventLoop(void)
  454. {
  455.     EventRecord        anEvent;
  456.     
  457.     FlushEvents(everyEvent,0);
  458.     
  459. #if SPLASHSCREEN
  460.     if( !AreODDocumentsRunning() && FirstTimeLaunched() )
  461.         gSplashScreen = ShowAboutScreen();
  462. #endif
  463.  
  464.     for( gQuitTime=TickCount()+kQuitDelay; TickCount()<gQuitTime; ) {
  465.         (void) WaitNextEvent(everyEvent,&anEvent,5,(RgnHandle) nil);
  466.         switch (anEvent.what)
  467.         {
  468.             case nullEvent:
  469.                 break;
  470.             
  471.             case osEvt:
  472.                 break;
  473.  
  474.             case kHighLevelEvent:
  475.                 AEProcessAppleEvent(&anEvent);
  476.                 break;
  477.             
  478.             default:
  479.                 if( IsDialogEvent(&anEvent) ) {
  480.                     DialogPtr whichDlog;
  481.                     short itemHit;
  482.                     if( DialogSelect(&anEvent,&whichDlog,&itemHit) && itemHit>0 )
  483.                         return;
  484.                 } else
  485.                     return;
  486.         }
  487.     }
  488. }
  489.  
  490. //------------------------------------------------------------------------------
  491. // FirstTimeLaunched
  492. //------------------------------------------------------------------------------
  493.  
  494. static Boolean FirstTimeLaunched( )
  495. {
  496.     /* To figure out if this is the first time launched today, check the mod
  497.        date of the "OpenDoc Preferences" file and compare it with today's date.
  498.        If it's earlier, this is the first time today; set the mod date to the
  499.        current date/time to signal that the launcher has run today. */
  500.     
  501.     FSSpec prefss;
  502.     if( GetPrefsFileSpec(&prefss) != noErr )
  503.         return true;
  504.     
  505.     CInfoPBRec pb;
  506.     pb.hFileInfo.ioNamePtr = prefss.name;
  507.     pb.hFileInfo.ioFDirIndex = 0;
  508.     pb.hFileInfo.ioVRefNum = prefss.vRefNum;
  509.     pb.hFileInfo.ioDirID = prefss.parID;
  510.     OSErr error = PBGetCatInfoSync(&pb);
  511.     if( error )
  512.         return (error==fnfErr);
  513.     
  514.     // Convert mod-time to date format, and get current date:
  515.     DateTimeRec prefsDate,curDate;
  516.     SecondsToDate(pb.hFileInfo.ioFlMdDat,&prefsDate);
  517.     GetTime(&curDate);
  518.  
  519.     // Compare:
  520.     if( prefsDate.year==curDate.year && prefsDate.month==curDate.month && prefsDate.day==curDate.day )
  521.         return false;
  522.     
  523.     // Not yet launched today. Bump mod date of file & return true:
  524.     GetDateTime(&pb.hFileInfo.ioFlMdDat);
  525.     pb.hFileInfo.ioDirID = prefss.parID;
  526.     PBSetCatInfoSync(&pb);
  527.     return true;
  528. }
  529.  
  530. //==============================================================================
  531. // Error reporting
  532. //==============================================================================
  533.  
  534. void ReportDocumentError(StringPtr docName, OSErr err)
  535. {    
  536.     // If it's not legal to interact with the user, do nothing:
  537.     if(AEInteractWithUser(0,NULL,NULL) == errAENoUserInteraction)
  538.         return;
  539.     
  540.     // Bring myself to the front:
  541.     ProcessSerialNumber psn;
  542.     psn.highLongOfPSN = 0;
  543.     psn.lowLongOfPSN = kCurrentProcess;
  544.     SetFrontProcess(&psn);
  545.     
  546. #if SPLASHSCREEN
  547.     if( gSplashScreen ) {
  548.         DisposeDialog(gSplashScreen);
  549.         gSplashScreen = NULL;
  550.     }
  551. #endif
  552.  
  553.     // Display the alert:
  554.     short alertID = docName[0] ?kODXErrAlert :kODXAnonErrAlert;
  555.     if( Get1Resource('ALRT',alertID) ) {
  556.         unsigned char errStr[12];
  557.         NumToString(err,errStr);
  558.         ParamText(docName,errStr,NULL,NULL);
  559.         InitCursor();
  560.         StopAlert(alertID, NULL);
  561.     } else {
  562.         SysBeep(3);
  563.         SysBeep(3);
  564.     }
  565. }
  566.  
  567. //==============================================================================
  568. // Apple Event handlers
  569. //==============================================================================
  570.  
  571. //------------------------------------------------------------------------------
  572. // HandleOpenAppEvent
  573. //
  574. //    We only expect to handle open-document events. If we get an open-application
  575. //    event, then the user must have double-clicked us. This doesn't do anything,
  576. //    so we put up an alert telling him so.
  577. //------------------------------------------------------------------------------
  578.  
  579. static pascal OSErr HandleOpenAppEvent(
  580.     AppleEvent * /*theAppleEvent*/,
  581.     AppleEvent * /*reply*/,
  582.     long /*refCon*/)
  583. {
  584.     SetCursor(&qd.arrow);
  585.     CautionAlert(kODXDoubleClickAlert, NULL);
  586.     return noErr;
  587. }
  588.  
  589. //------------------------------------------------------------------------------
  590. // NoOpAEHandler
  591. //
  592. //    NP: No reason to have this as far as I know
  593. //------------------------------------------------------------------------------
  594.  
  595. static pascal OSErr NoOpAEHandler(
  596.     AppleEvent * /*theAppleEvent*/,
  597.     AppleEvent * /*reply*/,
  598.     long /*refCon*/)
  599. {
  600.     return(noErr);
  601. }
  602.  
  603. //------------------------------------------------------------------------------
  604. //  NotifyLaunchFailed
  605. //------------------------------------------------------------------------------
  606.  
  607. void NotifyLaunchFailed(OSErr launchError, Str255 appName, Str255 libName)
  608. {
  609.     unsigned char    launchErrorString[12];
  610.     
  611.     // Force myself to the foreground:
  612.     ProcessSerialNumber psn = {0, kCurrentProcess};
  613.     (void) SetFrontProcess(&psn);
  614.     
  615. #if SPLASHSCREEN
  616.     if( gSplashScreen ) {
  617.         DisposeDialog(gSplashScreen);
  618.         gSplashScreen = NULL;
  619.     }
  620. #endif
  621.  
  622.     InitCursor();
  623.  
  624.     NumToString(launchError, launchErrorString);
  625.  
  626.     if( appName[0]==0 )
  627.     {
  628.         LauncherDebugStr("No document name available for dialog.");
  629.         ParamText(NULL, launchErrorString, NULL, NULL);
  630.         StopAlert(kGenericLaunchFailedAlert, NULL);
  631.     }
  632.     else
  633.     {
  634.         short index;
  635.         Str255 errorDescription;
  636.         if( launchError <= -2800 && launchError >= -2824 )
  637.             index = 2-2800-launchError;        // Maps -2800..-2824 -> 2..26
  638.         else
  639.             index = 1;
  640.         GetIndString(errorDescription, kLaunchFailedErrStrings, index);
  641.         ParamText(appName, errorDescription, libName, launchErrorString);
  642.         StopAlert(kLaunchFailedAlert, NULL);
  643.     }
  644. }
  645.  
  646. //------------------------------------------------------------------------------
  647. //  DocumentLaunched
  648. //
  649. //
  650. //------------------------------------------------------------------------------
  651.  
  652. void DocumentLaunched()
  653. {
  654.     // Give time for error to come back
  655.     gQuitTime = TickCount() + kWaitForErrorDelay;
  656. }
  657.  
  658. //------------------------------------------------------------------------------
  659. //  ReportErrorGeneric
  660. //------------------------------------------------------------------------------
  661.  
  662. void ReportErrorGeneric(StringPtr errorString)
  663. {
  664.     ReportErrorSimple(errorString);
  665. }
  666.  
  667. //------------------------------------------------------------------------------
  668. //    GetOurCreator
  669. //------------------------------------------------------------------------------
  670.  
  671. static OSErr GetOurCreator(OSType& type)
  672. {
  673.     return GetCreator(&gFileSpec, type);
  674. }
  675.  
  676. //------------------------------------------------------------------------------
  677. //    ChangeOurCreator
  678. //------------------------------------------------------------------------------
  679.  
  680. static OSErr ChangeOurCreator(OSType type)
  681. {
  682.     return ChangeCreator(&gFileSpec, type);
  683. }
  684.  
  685. //------------------------------------------------------------------------------
  686. //    GetCreator
  687. //------------------------------------------------------------------------------
  688.  
  689. static OSErr GetCreator(FSSpec* fileSpec, OSType& type)
  690. {
  691.     FInfo    fileInfo;
  692.     OSErr    error;
  693.     
  694.     error = FSpGetFInfo(fileSpec, &fileInfo);
  695.     type = fileInfo.fdCreator;
  696.     
  697.     return error;
  698. }
  699.  
  700. //------------------------------------------------------------------------------
  701. //    ChangeCreator
  702. //------------------------------------------------------------------------------
  703.  
  704. static OSErr ChangeCreator(FSSpec* fileSpec, OSType type)
  705. {
  706.     OSErr    error;
  707.     FInfo    fileInfo;
  708.         
  709.     error = FSpGetFInfo(fileSpec, &fileInfo);
  710.     if (!error)
  711.     {
  712.         fileInfo.fdCreator = type;
  713.         error = FSpSetFInfo(fileSpec, &fileInfo);
  714.         if (!error)
  715.             BumpOurFolderModDate();
  716.     }
  717.     
  718.     return error;
  719. }
  720.  
  721. //------------------------------------------------------------------------------
  722. //    EnableApp
  723. //------------------------------------------------------------------------------
  724.  
  725. OSErr EnableApp(FSSpec* fileSpec)
  726. {
  727.     OSErr    error;
  728.  
  729.     error = ChangeCreator(fileSpec, kODShellSignature);
  730.     if (!error)
  731.         ChangeDesktopDatabase(fileSpec, kODAddAPPL);
  732.     
  733.     return error;
  734. }
  735.  
  736. //------------------------------------------------------------------------------
  737. //    EnableAppIfNotAlready
  738. //
  739. //    Don't want to hit the desktop database if we don't have to.
  740. //------------------------------------------------------------------------------
  741.  
  742. OSErr EnableAppIfNotAlready(FSSpec* fileSpec)
  743. {
  744.     OSErr    error;
  745.     OSType    type;
  746.  
  747.     error = GetCreator(fileSpec, type);
  748.  
  749.     if (!error && type != kODShellSignature)
  750.         EnableApp(fileSpec);
  751.     
  752.     return error;
  753. }
  754.  
  755. //------------------------------------------------------------------------------
  756. //    SimpleLaunchApp
  757. //------------------------------------------------------------------------------
  758.  
  759. OSErr SimpleLaunchApp(FSSpec* fileSpec)
  760. {
  761.     LaunchParamBlockRec    launchPB;
  762.  
  763.     launchPB.launchBlockID = extendedBlock;
  764.     launchPB.launchEPBLength = extendedBlockLen;
  765.     // HOW ABOUT OTHER FLAGS?
  766.     launchPB.launchControlFlags = launchContinue
  767.                                     | launchNoFileFlags
  768.                                     | launchDontSwitch;
  769.     launchPB.launchAppSpec = fileSpec;
  770.     launchPB.launchAppParameters = NULL;
  771.     
  772.     return LaunchApplication(&launchPB);
  773. }
  774.  
  775. //------------------------------------------------------------------------------
  776. //    DisableOurselves
  777. //------------------------------------------------------------------------------
  778.  
  779. OSErr DisableOurselves(FSSpec* fileSpec, OSType newSignature)
  780. {
  781.     OSErr    error;
  782.  
  783.     error = ChangeCreator(fileSpec, newSignature);
  784.     if (!error)
  785.         ChangeDesktopDatabase(fileSpec, kODRemoveAPPL);
  786.  
  787.     return error;
  788. }
  789.  
  790. //------------------------------------------------------------------------------
  791. //    BumpFolderModDate
  792. //
  793. //    Stolen from PlfmFile.cpp. Original code can be used when the launcher is
  794. //    revved to use OpenDoc (like the system process).
  795. //------------------------------------------------------------------------------
  796.  
  797. static void BumpOurFolderModDate()
  798. {
  799.     CInfoPBRec    theParamBlock;
  800.  
  801.     memset (&theParamBlock, 0, sizeof(theParamBlock));
  802.     // ioNamePtr = 0
  803.     theParamBlock.dirInfo.ioFDirIndex = -1;
  804.     theParamBlock.dirInfo.ioVRefNum = gFileSpec.vRefNum;
  805.     theParamBlock.dirInfo.ioDrDirID = gFileSpec.parID;
  806.     OSErr err = PBGetCatInfoSync(&theParamBlock);
  807.     if( err )
  808.         LauncherDebugStr("BumpFolderModDate: Couldn't get dir mod date.");
  809.     else
  810.     {
  811.         ODULong newTime;
  812.  
  813.         GetDateTime(&newTime);
  814.         // set to the future if it is now
  815.         if (theParamBlock.dirInfo.ioDrMdDat >= newTime)
  816.             ++newTime;
  817.         theParamBlock.dirInfo.ioDrMdDat = newTime;
  818.         err = PBSetCatInfoSync(&theParamBlock);
  819.         if( err )
  820.             LauncherDebugStr("BumpFolderModDate: Couldn't bump dir mod date.");
  821.     }
  822. }
  823.                 
  824. //------------------------------------------------------------------------------
  825. //    ReenableSystemProcess
  826. //------------------------------------------------------------------------------
  827.  
  828. OSErr ReenableSystemProcess(FSSpec* fileSpec)
  829. {
  830.     OSErr        error;
  831.     StringPtr    string;
  832.  
  833.     string = *GetString(kSHLSystemProcessNameResID);
  834.     CopyPascalString(fileSpec->name, string);
  835.  
  836.     // TRY TO FIND THE SYSTEM PROCESS WHERE THE INSTALLER PUTS IT
  837.     error = GetOpenDocLibsFolderInfo(&(fileSpec->parID), &(fileSpec->vRefNum));
  838.     if (!error)
  839.         error = EnableAppIfNotAlready(fileSpec);
  840.  
  841.     if (error)
  842.     {
  843.         // MAYBE IT HAS BEEN RENAMED
  844.         error = FindODLibFileWithSignature(fileSpec->name,
  845.                                             fileSpec->vRefNum,
  846.                                             fileSpec->parID,
  847.                                             kODSystemProcessSignature);
  848.         if (!error)
  849.             error = EnableAppIfNotAlready(fileSpec);
  850.     }
  851.  
  852.     return error;
  853. }
  854.  
  855. //------------------------------------------------------------------------------
  856. //    DoTheRenamingThang
  857. //
  858. //    Ourselves        ->    some disabled name
  859. //    System Process    ->    "OpenDoc™"
  860. //------------------------------------------------------------------------------
  861.  
  862. void DoTheRenamingThang(StringPtr newNameForSystemProcess)
  863. {
  864.     FSSpec            fileSpec;
  865.     OSErr            error;
  866.     Str255            oldLauncherName;
  867.  
  868.     // TRY TO FIND SYSTEM PROCESS WHERE THE INSTALLER PUTS IT
  869.     CopyPascalString(fileSpec.name, *GetString(kSHLSystemProcessNameResID));
  870.     error = GetOpenDocLibsFolderInfo(&fileSpec.parID, &fileSpec.vRefNum);
  871.     if (!error)
  872.     {
  873.         CopyPascalString(oldLauncherName, *GetString(kSHLOldLauncherNameResID));
  874.         error = FSpRename(&gFileSpec, oldLauncherName);
  875.         if (!error)
  876.         {
  877.             CopyPascalString(newNameForSystemProcess,
  878.                                 *GetString(kSHLLauncherNameResID));
  879.             ChangeDesktopDatabase(&fileSpec, kODRemoveAPPL);
  880.             error = FSpRename(&fileSpec, newNameForSystemProcess);
  881.             CopyPascalString(fileSpec.name, newNameForSystemProcess);
  882.             ChangeDesktopDatabase(&fileSpec, kODAddAPPL);
  883.         }
  884.     }
  885. }
  886.  
  887.