home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-15 | 13.7 KB | 666 lines | [TEXT/CWIE] |
- #include "EventLoop.h"
- #include "Exceptions.h"
- #include "DebugWrite.h"
-
- #include <Threads.h>
-
- DefineClassSingle(EventLoop);
-
- struct AEHandlerInfo
- {
- AEEventHandlerProcPtr proc;
- Size size;
- char data[1];
- };
-
- #define sizeofAEHandlerInfo(n) (offsetof(AEHandlerInfo, data) + (n))
-
- //------------------------------------------------------------------------------
-
- #if GENERATINGCFM
-
- RoutineDescriptor EventLoop::gProcDescriptors[EventLoop::kNumProcSelectors] =
- {
- BUILD_ROUTINE_DESCRIPTOR(uppAEIdleProcInfo, EventLoop::xAEIdleProc),
- BUILD_ROUTINE_DESCRIPTOR(uppAEFilterProcInfo, EventLoop::xAEFilterProc),
- BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, EventLoop::xModalFilterProc),
- BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, EventLoop::xAEEventHandlerProc),
- BUILD_ROUTINE_DESCRIPTOR(uppAEEventHandlerProcInfo, EventLoop::xAEEventHandlerProc1)
- };
-
- #endif
-
- EventLoop* EventLoop::gEventLoop = nil;
-
- //------------------------------------------------------------------------------
-
- pascal Boolean EventLoop::xAEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
- {
- OSStatus status = Exception::CatchOSStatus(vAEIdleProc, gEventLoop, theEvent, sleepTime, mouseRgn);
-
- if (status == userCanceledErr)
- {
- return true;
- }
- else
- {
- LogIfErr(status);
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- pascal Boolean EventLoop::xAEFilterProc(EventRecord *theEvent, long returnID, long transactionID, const AEAddressDesc *sender)
- {
- OSStatus status = Exception::CatchOSStatus(vAEFilterProc, gEventLoop, theEvent, returnID, transactionID, sender);
-
- if (status == 1)
- {
- return true;
- }
- else
- {
- LogIfErr(status);
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- pascal Boolean EventLoop::xModalFilterProc(DialogPtr theDialog, EventRecord *theEvent, DialogItemIndex *itemHit)
- {
- OSStatus status = Exception::CatchOSStatus(vModalFilterProc, gEventLoop, theDialog, theEvent, itemHit);
-
- if (status == 1)
- {
- return true;
- }
- else
- {
- LogIfErr(status);
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- pascal OSErr EventLoop::xAEEventHandlerProc(
- const AppleEvent* theAppleEvent,
- AppleEvent* reply,
- UInt32 handlerRefcon)
- {
- return Exception::CatchOSErrors(vAEEventHandlerProc, theAppleEvent, reply, (long) 0, handlerRefcon);
- }
-
- //------------------------------------------------------------------------------
-
- pascal OSErr EventLoop::xAEEventHandlerProc1(
- const AppleEvent* theAppleEvent,
- AppleEvent* reply,
- UInt32 handlerRefcon)
- {
- AEHandlerInfo* info = (AEHandlerInfo*) handlerRefcon;
-
- return Exception::CatchOSErrors(vAEEventHandlerProc, theAppleEvent, reply, &info->data[0], info->proc);
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus EventLoop::vAEIdleProc(va_list args)
- {
- VA_ARG(EventRecord*, theEvent, args);
- VA_ARG(long*, sleepTime, args);
- VA_ARG(RgnHandle*, mouseRgn, args);
-
- return gEventLoop ? gEventLoop->AEIdleProc(*theEvent, *sleepTime, *mouseRgn) : false;
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus EventLoop::vAEFilterProc(va_list args)
- {
- VA_ARG(EventRecord*, theEvent, args);
- VA_ARG(long, returnID, args);
- VA_ARG(long, transactionID, args);
- VA_ARG(const AEAddressDesc*, sender, args);
-
- EventLoop* loop = gEventLoop;
-
- return loop ? loop->AEFilterProc(*theEvent, returnID, transactionID, *sender) : false;
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus EventLoop::vModalFilterProc(va_list args)
- {
- VA_ARG(DialogPtr, theDialog, args);
- VA_ARG(EventRecord*, theEvent, args);
- VA_ARG(DialogItemIndex*, itemHit, args);
-
- return gEventLoop ? gEventLoop->ModalFilterProc(theDialog, *theEvent, *itemHit) : false;
- }
-
- //------------------------------------------------------------------------------
-
- OSStatus EventLoop::vAEEventHandlerProc(va_list args)
- {
- VA_ARG(const AppleEvent*, theAppleEvent, args);
- VA_ARG(AppleEvent*, reply, args);
- VA_ARG(UInt32, handlerRefcon, args);
- VA_ARG(AEEventHandlerProcPtr, handler, args);
-
- return (*handler)(theAppleEvent, reply, handlerRefcon);
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::HandleEventProc(EventRecord& theEvent, long *sleepTime, RgnHandle *mouseRgn)
- {
- WithNewEvent evt(*this, theEvent, sleepTime, mouseRgn);
-
- return HandleEvent(evt);
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::AEIdleProc(EventRecord& theEvent, long& sleepTime, RgnHandle& mouseRgn)
- {
- WithNewEvent evt(*this, theEvent, &sleepTime, &mouseRgn);
-
- bool handled = HandleEvent(evt);
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::InteractWithUser(
- long timeOutInTicks,
- NMRecPtr nmReqPtr)
- {
- FailOSErr(AEInteractWithUser(timeOutInTicks, nmReqPtr, GetAEIdleProc()));
- }
-
- //------------------------------------------------------------------------------
-
- void* EventLoop::InstallAEHandler(
- AEEventClass theAEEventClass,
- AEEventID theAEEventID,
- AEEventHandlerProcPtr handler,
- Size dataSize)
- {
- long refcon;
- AEEventHandlerUPP upp;
- void* result;
-
- if (dataSize > 0)
- {
- AEHandlerInfo* info = (AEHandlerInfo*) NewPtrClear(sizeofAEHandlerInfo(dataSize));
-
- FailNIL(info);
-
- info->proc = handler;
- info->size = dataSize;
-
- upp = GetAEEventHandlerProc1();
- refcon = (long) info;
- result = &info->data[0];
- }
- else
- {
- upp = GetAEEventHandlerProc();
- refcon = (long) handler;
- result = nil;
- }
-
- FailOSErr(AEInstallEventHandler(theAEEventClass, theAEEventID, upp, refcon, false));
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::AEFilterProc(
- EventRecord& theEvent,
- long /*returnID*/,
- long /*transactionID*/,
- const AEAddressDesc& /*sender*/)
- {
- if (!HandleEventProc(theEvent, nil, nil))
- {
- Yield();
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::ModalFilterProc(
- DialogPtr /*theDialog*/,
- EventRecord& theEvent,
- DialogItemIndex& /*itemHit*/)
- {
- if (!HandleEventProc(theEvent, nil, nil))
- {
- Yield();
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::PollForEvent(EventRecord& theEvent)
- {
- long sleep = fLastEvent.IsNullEvent() ? fSleepTime : 0;
-
- return WaitNextEvent(fEventMask, &theEvent, sleep, fMouseRgn);
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::ProcessEvent(
- EventRecord& theEvent,
- long* sleepTime,
- RgnHandle* mouseRgn)
- {
- EventLoop* loop = gEventLoop;
- bool handled = false;
-
- if (loop != nil)
- {
- WithNewEvent evt(*loop, theEvent, sleepTime, mouseRgn);
-
- handled = loop->FilterEvent(evt);
-
- if (!handled)
- {
- handled = loop->HandleEvent(evt);
- }
-
- Yield();
-
- if (sleepTime != nil)
- {
- *sleepTime = loop->GetSleepTime();
- }
-
- if (mouseRgn != nil)
- {
- *mouseRgn = loop->GetMouseRgn();
- }
- }
-
- return handled;
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::DoIdle()
- {
- if (fNestLevel == 0)
- {
- EventRecord theEvent;
-
- PollForEvent(theEvent);
-
- ProcessEvent(theEvent, nil, nil);
- }
- else
- {
- Yield();
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::Yield()
- {
- YieldToAnyThread();
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::BeginEvent(ToolboxEvent& /*theEvent*/)
- {
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::FilterEvent(ToolboxEvent& theEvent)
- {
- return fFilterChain.FilterEvent(theEvent);
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::HandleEvent(ToolboxEvent& theEvent)
- {
- bool result = FilterEvent(theEvent);
-
- if (!result)
- {
- EventKind what = theEvent.GetEventKind();
-
- switch (what)
- {
- case nullEvent:
- result = HandleNullEvent(theEvent);
- break;
-
- case kHighLevelEvent:
- result = HandleHighLevelEvent(theEvent);
- break;
-
- default:
- break;
- }
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::EndEvent(ToolboxEvent& theEvent)
- {
- EventKind what = theEvent.GetEventKind();
-
- if (what != kHighLevelEvent)
- {
- // HLE's don't affect sleep time, etc.
-
- switch (what)
- {
- case mouseDown:
- fLastMouseUp.SetToNullEvent();
- break;
-
- case mouseUp:
- fLastMouseUp = theEvent;
- break;
- }
-
- fLastEvent = theEvent;
- }
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::HandleNullEvent(ToolboxEvent& theEvent)
- {
- if (fLastEvent.IsNullEvent())
- {
- do
- {
- Yield();
- }
- while (TickCount() < theEvent.GetEventTime() + fDreamTime);
- }
- else
- {
- // Calc sleep time
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool EventLoop::HandleHighLevelEvent(ToolboxEvent& theEvent)
- {
- OSErr err = AEProcessAppleEvent(theEvent);
-
- LogIfErr(err);
-
- return err == noErr;
- }
-
- //------------------------------------------------------------------------------
-
- EventLoop::~EventLoop()
- {
- if (fMouseRgn)
- {
- DisposeRgn(fMouseRgn);
- fMouseRgn = nil;
- }
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::Initialize()
- {
- TModule::Initialize();
- EventFilterChain::Initialize();
-
- // this initializes fLastEvent and allows the porcess manager to complete
- // switching to our task
-
- for (int i = 3; i > 0; --i)
- {
- WaitNextEvent(0, fLastEvent, 0, nil);
- }
- }
-
- //--------------------------------------------------------------------------------
-
- void EventLoop::Finalize(void)
- {
- TModule::Finalize();
- EventFilterChain::Finalize();
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::Run()
- {
- if (gEventLoop)
- {
- gEventLoop->DoRun();
- }
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::Quit()
- {
- if (gEventLoop)
- {
- gEventLoop->DoQuit();
- }
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::PushEventFilter(EventFilter& filter)
- {
- if (gEventLoop)
- {
- gEventLoop->GetFilterList().AddFirst(filter);
- }
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::DoRun()
- {
- BeforeEventLoop();
-
- while (fAppPhase < kAppDone)
- {
- DoIdle();
- }
-
- AfterEventLoop();
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::DoQuit()
- {
- fAppPhase = kAppDone;
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::BeforeEventLoop()
- {
- }
-
- //------------------------------------------------------------------------------
-
- void EventLoop::AfterEventLoop()
- {
- }
-
- //------------------------------------------------------------------------------
-
- EventLoop::WithNewEvent::WithNewEvent(
- EventLoop& loop,
- EventRecord& theEvent,
- long* sleepTime,
- RgnHandle* mouseRgn)
- : ToolboxEvent(theEvent),
- fLoop(loop),
- fSleepTime(sleepTime),
- fMouseRgn(mouseRgn)
- {
- fLoop.BeginEvent(*this);
- }
-
- //------------------------------------------------------------------------------
-
- EventLoop::WithNewEvent::~WithNewEvent()
- {
- fLoop.EndEvent(*this);
-
- if (fSleepTime != nil)
- {
- *fSleepTime = fLoop.GetSleepTime();
- }
-
- if (fMouseRgn != nil)
- {
- *fMouseRgn = fLoop.GetMouseRgn();
- }
- }
-
- //------------------------------------------------------------------------------
-
- FGEventLoop::~FGEventLoop()
- {
- }
-
- //------------------------------------------------------------------------------
-
- bool FGEventLoop::HandleEvent(ToolboxEvent& theEvent)
- {
- bool handled = Inherited::HandleEvent(theEvent);
-
- if (!handled)
- {
- EventKind what = theEvent.GetEventKind();
-
- switch (what)
- {
- case nullEvent:
- handled = HandleNullEvent(theEvent);
- break;
-
- case mouseDown:
- case mouseUp:
- handled = HandleMouseEvent(theEvent);
- break;
-
- case keyDown:
- case keyUp:
- case autoKey:
- handled = HandleKeyboardEvent(theEvent);
- break;
-
- case updateEvt:
- case activateEvt:
- handled = HandleWindowEvent(theEvent);
- break;
-
- case kHighLevelEvent:
- handled = HandleHighLevelEvent(theEvent);
- break;
-
- default:
- case diskEvt:
- case osEvt:
- break;
- }
- }
-
- return handled;
- }
-
- //------------------------------------------------------------------------------
-
- bool FGEventLoop::HandleMouseEvent(ToolboxEvent& theEvent)
- {
- return HandleWindowEvent(theEvent);
- }
-
- //------------------------------------------------------------------------------
-
- bool FGEventLoop::HandleKeyboardEvent(ToolboxEvent& theEvent)
- {
- if (theEvent.GetEventKind() == keyDown)
- {
- if (theEvent.GetModifierBits().cmdKey)
- // if (theEvent.CmdKeyDown())
- {
- return HandleMenuSelection(MenuKey(theEvent.GetCharCode()));
- }
- }
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool FGEventLoop::HandleWindowEvent(ToolboxEvent& theEvent)
- {
- switch (theEvent.GetPartCode())
- {
- case inMenuBar:
- HandleMenuSelection(MenuSelect(theEvent.GetMousePosition()));
- break;
- }
-
- /*
- inDesk = 0,
- inNoWindow = 0,
- inMenuBar = 1,
- inSysWindow = 2,
- inContent = 3,
- inDrag = 4,
- inGrow = 5,
- inGoAway = 6,
- inZoomIn = 7,
- inZoomOut = 8,
- inCollapseBox = 11
- */
-
- return false;
- }
-
- //------------------------------------------------------------------------------
-
- bool FGEventLoop::HandleMenuSelection(long what)
- {
- HiliteMenu(0);
-
- return false;
- }