home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-10-11 | 12.6 KB | 529 lines | [TEXT/CWIE] |
- /***
- File: LMainCGI.cp
-
-
- Contains: Main thread for CGI
-
-
- Written by: Ken Wieschhoff
-
-
- Copyright: ©1996 Siren Enterprises, All Rights Reserved.
-
-
- Change History (most recent first):
-
-
-
- <1> 9/5/96 kw Original
-
- ***/
-
-
- #include <stdio.h>
- #include <LWindow.h>
- #include <PP_Messages.h>
- #include <PP_Resources.h>
- #include <URegistrar.h>
- #include <PPobClasses.h>
- #include <LGrowZone.h>
- #include <UMemoryMgr.h>
- #include <LMenuBar.h>
- #include <LMenu.h>
- #include <LListIterator.h>
- #include <LPicture.h>
- #include <LCaption.h>
- #include <LDialogBox.h>
- #include <LEditField.h>
- #include <LStdControl.h>
- #include <LWindow.h>
- #include <LThread.h>
- #include <PP_KeyCodes.h>
- #include <UAppleEventsMgr.h>
- #include <UDesktop.h>
- #include <UException.h>
- #include <UExtractFromAEDesc.h>
- #include <UReanimator.h>
- #include <UScreenPort.h>
- #include <UThread.h>
- #include <string.h>
- #include <UDrawingState.h>
- #include <TextServices.h>
- #include <Profiler.h>
- #include "LMainCGI.h"
- #include "LRequest.h"
-
-
- const UInt32 kAppRunQuantum = 0;
- const UInt32 ae_CGI = 5000;
- const UInt32 kPostDataSize = 8192;
-
-
- LMainCGI *LMainCGI::sApplication = nil;
- LThread *LMainCGI::sMainThread = nil;
- LCGIStatusThread *LMainCGI::sStatusThread = nil;
- AEIdleUPP LMainCGI::sIdleUPP = nil;
-
- ExitToShellProcUPP gOldExitToShell = nil;
- ExitToShellProcUPP gNewExitToShell = nil;
- Boolean gCreditsRunning = false;
-
- extern WindowPtr LStatusWindow::sMacWindowP;
- extern GetNextEventFilterUPP gOldHook;
-
-
- // ===========================================================================
- // • Main Program
- // ===========================================================================
-
- void main(void)
- {
- // Set Debugging options
-
- #ifdef Debug_Throw
- gDebugThrow = debugAction_Alert;
- #endif
-
- #ifdef Debug_Signal
- gDebugSignal = debugAction_Alert;
- #endif
-
- #if __profile__
- ProfilerInit( collectDetailed, bestTimeBase, 20, 5);
- #endif
-
- InitializeHeap(4);
- UQDGlobals::InitializeToolbox(&qd);
- new LGrowZone(20000);
-
- RunApplication();
-
- #if __profile__
- ProfilerDump( "\pProfileInfo.prof");
- ProfilerTerm();
- #endif
- }
-
-
- // ===========================================================================
- // • RunApplication
- // ===========================================================================
-
- static void RunApplication(void)
- {
- // create & initialize the application object
- LMainCGI *theApp;
-
-
- #if !GENERATINGCFM
- // Store our current A5 (globals frame) for use by the GNE Filter
- *A5Stash() = (long)LMGetCurrentA5();
- #endif
-
- // Patch ExitToShell so we can remove the GNEFilter in case of disaster
- gOldExitToShell = (ExitToShellProcUPP)NGetTrapAddress( _ExitToShell, ToolTrap);
- gNewExitToShell = NewExitToShellProc( ExitCGI);
- NSetTrapAddress( (UniversalProcPtr)gNewExitToShell, _ExitToShell, ToolTrap);
-
- theApp = new LMainCGI;
-
- // execute the app
- theApp->Run();
-
- delete theApp;
- }
-
- // ===========================================================================
- // • ExitCGI
- // ===========================================================================
-
- pascal void ExitCGI() {
-
- #if !GENERATINGCFM
- // Reset to our globals for 68K machines.
- long oldA5 = SetA5(*A5Stash());
- #endif
-
- ExitToShellProcUPP oldExitToShell = gOldExitToShell;
-
-
- if (LStatusWindow::sMacWindowP != nil) {
- ::CloseServiceWindow(LStatusWindow::sMacWindowP);
- LStatusWindow::sMacWindowP = nil;
- }
-
- // Remove the GNE Filter from the application
- RemoveGNEFilter();
-
- #if !GENERATINGCFM
- // Reset to caller's globals.
- SetA5( oldA5);
- #endif
-
- // Call the old trap.
- CallExitToShellProc( oldExitToShell);
-
- }
-
-
- // ===========================================================================
- // • GetApplication
- // ===========================================================================
- // Returns a pointer to the global application object
-
- LMainCGI *LMainCGI::GetApplication(void)
- {
- return (sApplication);
- }
-
-
- // ===========================================================================
- // • LMainCGI
- // ===========================================================================
- // Constructor
-
- LMainCGI::LMainCGI()
- {
- sApplication = this;
-
- // Create the UPP for the threaded AppleEvent Idler Proc
- sIdleUPP = NewAEIdleProc(AEIdleProc);
-
- // Create the main application thread.
- sMainThread = new LMainCGIThread;
-
- // Create the Status Window thread.
- sStatusThread = new LCGIStatusThread( this);
- sStatusThread->Resume();
-
- // Add the Yield attachment to yield to all new threads
- AddAttachment(new LYieldAttachment(kAppRunQuantum));
-
- UScreenPort::Initialize();
- }
-
-
- // ===========================================================================
- // • ~LMainCGI
- // ===========================================================================
- // Destructor
- //
-
- LMainCGI::~LMainCGI()
- {
- if (sIdleUPP != nil)
- DisposeRoutineDescriptor(sIdleUPP);
-
- }
-
-
-
- // ===========================================================================
- // • ObeyCommand
- // ===========================================================================
- // Respond to commands
-
- Boolean
- LMainCGI::ObeyCommand(
- CommandT inCommand,
- void *ioParam)
- {
- Boolean cmdHandled = true;
-
- switch (inCommand) {
-
- case cmd_Open:
- sStatusThread->OpenStatusWindow();
- break;
-
- case cmd_Close:
- sStatusThread->CloseStatusWindow();
- break;
-
- default:
- cmdHandled = LApplication::ObeyCommand(inCommand, ioParam);
- break;
- }
-
- return cmdHandled;
- }
-
- // ===========================================================================
- // • FindCommandStatus
- // ===========================================================================
- // This function enables menu commands.
- //
-
- void
- LMainCGI::FindCommandStatus(
- CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
-
- switch (inCommand) {
-
- case cmd_Open:
- if ( sStatusThread->mWindow == nil)
- outEnabled = true;
- else
- outEnabled = false;
-
- break;
-
- case cmd_Close:
- if ( sStatusThread->mWindow != nil)
- outEnabled = true;
- else
- outEnabled = false;
- break;
-
- case cmd_Quit:
- case cmd_About:
- outEnabled = true;
- break;
-
- default:
- LApplication::FindCommandStatus(inCommand, outEnabled,
- outUsesMark, outMark, outName);
- break;
- }
- }
-
- // ===========================================================================
- // • HandleAppleEvent
- // ===========================================================================
- // Dispatch the Apple Events that we know about.
-
- void LMainCGI::HandleAppleEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc &outResult,
- long inAENumber)
- {
-
- switch (inAENumber)
- {
- case ae_CGI:
- // We just received a CGI event. Handle it.
- HandleCGIEvent(inAppleEvent, outAEReply, outResult );
- break;
-
- default:
- LApplication::HandleAppleEvent(inAppleEvent, outAEReply, outResult, inAENumber);
- break;
- }
-
- }
-
-
- // ===========================================================================
- // • GetSleepTime
- // ===========================================================================
- long LMainCGI::GetSleepTime(void) const
- {
- return (mSleepTime);
- }
-
- // ===========================================================================
- // • HandleCGIEvent
- // ===========================================================================
- void
- LMainCGI::HandleCGIEvent(
- const AppleEvent &inAppleEvent,
- AppleEvent &outAEReply,
- AEDesc & )
- {
- LRequest *itsRequest;
- AEAddressDesc WebSTARAddress;
- DescType typeCode;
- Size actualDataSize;
- long connectionID;
- char *itsString = "<SEND_PARTIAL>";
- LStr255 itsReply;
- Handle data = nil;
- StHandleLocker *itsLocker = nil;
-
- Try_ {
- // Fetch WebStar's return address
- ThrowIfOSErr_( AEGetAttributeDesc( &inAppleEvent, 'from','****',&WebSTARAddress));
-
- // Fetch the connection ID.
- ThrowIfOSErr_( AEGetParamPtr( &inAppleEvent, 'Kcid',typeLongInteger,
- &typeCode, &connectionID, sizeof(connectionID) , &actualDataSize));
-
- // Reply immediately we'll be sending partial data.
- if ( outAEReply.descriptorType != typeNull)
- ThrowIfOSErr_( AEPutParamPtr( &outAEReply, keyDirectObject,typeChar,itsString,strlen(itsString)));
-
- // Create a pointer to hold the biggest block Webstar can send...
- data = NewHandleClear ( kPostDataSize );
- if ( data )
- {
- itsLocker = new StHandleLocker(data);
- // Pull the form data off the appleevent into our buffer
- Try_ {
- ThrowIfOSErr_( AEGetParamPtr ( &inAppleEvent, 'post', typeChar, &typeCode, *data, kPostDataSize, &actualDataSize ));
- } Catch_ (inErr) {
- actualDataSize = 0;
- } EndCatch_;
-
- delete itsLocker, itsLocker = nil;
-
- // Resize the buffer for actual data size
- SetHandleSize ( data, actualDataSize );
- }
-
- itsRequest = new LRequest( WebSTARAddress, connectionID, data );
-
- // start working
- itsRequest->Resume();
-
-
- } Catch_ (inErr) {
- // Ignore any errors.
- } EndCatch_;
-
- if ( itsLocker)
- delete itsLocker;
-
- if ( data)
- ::DisposeHandle( data);
- }
-
- // ===========================================================================
- // • ShowAboutBox
- // ===========================================================================
- // Display the About Box for the Application
- void
- LMainCGI::ShowAboutBox()
- {
-
- LCreditThread *itsCredits;
-
- itsCredits = new LCreditThread();
-
- itsCredits->Resume();
- }
-
-
- // ===========================================================================
- // • AEIdleProc
- // ===========================================================================
- // Thread-aware Apple Event idle proc, which does some of the same event
- // processing as LApplication::ProcessNextEvent(). In particular, it calls
- // LThread::Yield(), which gives control to other threads.
-
- static pascal Boolean AEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
- {
- LMainCGI *theApp = LMainCGI::GetApplication();
-
- *mouseRgn = nil;
- *sleepTime = theApp->GetSleepTime();
-
- if (theEvent->what != nullEvent)
- theApp->DispatchEvent(*theEvent);
- else
- theApp->UseIdleTime(*theEvent);
-
- LPeriodical::DevoteTimeToRepeaters(*theEvent);
-
- LThread::Yield();
-
- return (false);
- }
-
-
- // ===========================================================================
- // • LMainCGIThread (Constructor)
- // ===========================================================================
- LMainCGIThread::LMainCGIThread()
-
- : UMainThread()
- {
- // there's nothing else to do
- }
-
-
- // ===========================================================================
- // • SwapContext
- // ===========================================================================
- // Context-switching function for application's main thread. Since there's
- // more than one thread doing any drawing, and that we draw from the main
- // thread, we have to make sure that LView doesn't make any erroneous
- // assumptions about the currently focused view. In a nutshell, we have to
- // flush LView's cached view.
-
- #pragma profile off
- void LMainCGIThread::SwapContext(Boolean swappingIn)
- {
-
- UMainThread::SwapContext(swappingIn);
- }
-
- #pragma profile reset
-
- // ===========================================================================
- // • LCreditThread (Constructor)
- // ===========================================================================
- LCreditThread::LCreditThread()
- : LThread( false )
- {
- // So we don't count this thread in the status window.
- gCreditsRunning = true;
- }
-
- // ===========================================================================
- // • ~LCreditThread (Destructor)
- // ===========================================================================
- LCreditThread::~LCreditThread()
- {
- gCreditsRunning = false;
- }
-
-
- // ===========================================================================
- // • Run
- // ===========================================================================
- void*
- LCreditThread::Run()
- {
- WindowPtr itsWindow;
- PicHandle creditsPicture;
- short textOffset;
-
- DialogTHndl theWIND = (DialogTHndl) ::GetResource('DLOG', 129);
-
- // Create yet another TSM window to do the credits. For some reason
- // "regular" windows and dialogs seem to block the AppleEvents W* sends
- // which [obviously] upsets new connections.
- ::NewServiceWindow( nil, &(**theWIND).boundsRect, (**theWIND).title, (**theWIND).visible,
- (**theWIND).procID, window_InFront, (**theWIND).goAwayFlag,
- (ComponentInstance) kCurrentProcess, &itsWindow);
-
- if ( itsWindow) {
- ShowWindow( itsWindow);
-
- creditsPicture = (PicHandle)GetResource( 'PICT', 128);
- textOffset = -600;
-
- //ModalDialog( itsConfigDlgFilter, &item);
- while ( !Button()) {
- DrawCredits( itsWindow, creditsPicture, &textOffset); // <-Credits.c
- LThread::Yield();
- }
-
- ::CloseServiceWindow(itsWindow);
- FlushEvents( mDownMask, 0);
-
- }
-
- if ( creditsPicture)
- ReleaseResource( (Handle) creditsPicture);
-
- DeleteThread();
- return nil;
- }
-