Microsoft-3D-Movie-Maker/kauai/SRC/APPBMAC.CPP

668 lines
15 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Reviewed:
Copyright (c) Microsoft Corporation
Mac specific base application class methods.
***************************************************************************/
#include "frame.h"
ASSERTNAME
ulong _GrfcustFromEvt(PEVT pevt);
// by default grow the stack by 8K and call MoreMasters 10 times
const long _cbExtraStackDef = 0x2000L;
const long _cactMoreMastersDef = 10;
/***************************************************************************
main for the entire frame work app. Does system initialization and
calls FrameMain.
***************************************************************************/
void __cdecl main(void)
{
// Grow the stack and expand the heap. This MUST be done first!
if (pvNil == vpappb)
APPB::_SetupHeap(_cbExtraStackDef, _cactMoreMastersDef);
else
vpappb->SetupHeap();
InitGraf(&qd.thePort);
InitFonts();
FlushEvents(everyEvent, 0);
InitWindows();
InitMenus();
TEInit();
InitDialogs(pvNil);
InitCursor();
// Go to the app's main entry point.
FrameMain();
}
/***************************************************************************
Static method to increase the stack size by cbExtraStack and call
MoreMasters the specified number of times.
***************************************************************************/
void APPB::_SetupHeap(long cbExtraStack, long cactMoreMasters)
{
// This is called before any Mac OS stuff is initialized, so
// don't assert on anything.
static _fCalled = fFalse;
if (_fCalled)
{
Debug( Debugger(); )
return;
}
_fCalled = fTrue;
if (cbExtraStack > 0)
{
//limit the increase to 100K
SetApplLimit(PvSubBv(GetApplLimit(), LwMin(cbExtraStack, 102400L)));
}
MaxApplZone();
while (cactMoreMasters-- > 0)
MoreMasters();
}
/***************************************************************************
Method to set up the heap.
***************************************************************************/
void APPB::SetupHeap(void)
{
// This is called before any Mac OS stuff is initialized, so
// don't assert on anything.
//add 8K to the stack and call MoreMasters 10 times.
_SetupHeap(_cbExtraStackDef, _cactMoreMastersDef);
}
/***************************************************************************
Shutdown immediately.
***************************************************************************/
void APPB::Abort(void)
{
ExitToShell();
}
/***************************************************************************
Do OS specific initialization.
***************************************************************************/
bool APPB::_FInitOS(void)
{
AssertThis(0);
// we already initialized everything
return fTrue;
}
/***************************************************************************
Open a desk accessory.
***************************************************************************/
bool APPB::FCmdOpenDA(PCMD pcmd)
{
AssertThis(0);
AssertVarMem(pcmd);
PRT *pprt;
schar rgchs[256];
long cchs;
if (pcmd->pgg != pvNil && pcmd->pgg->IvMac() == 1 &&
(cchs = pcmd->pgg->Cb(0)) < size(rgchs))
{
pcmd->pgg->Get(0, rgchs + 1);
st[0] = (schar)cchs;
GetPort(&pprt);
OpenDeskAcc((byte *)rgchs);
SetPort(pprt);
}
pcmd->cid = cidNil; //don't record this command
return fTrue;
}
/***************************************************************************
Get the next event from the OS.
***************************************************************************/
bool APPB::_FGetNextEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
if (!WaitNextEvent(everyEvent, pevt, 0, hNil))
pevt->what = nullEvent;
_grfcust &= ~kgrfcustUser;
_grfcust |= _GrfcustFromEvt(pevt);
return pevt->what != nullEvent;
}
/***************************************************************************
The given GOB is tracking the mouse. See if there are any relevant
mouse events in the system event queue. Fill in *ppt with the location
of the mouse relative to pgob. Also ensure that GrfcustCur() will
return the correct mouse state.
***************************************************************************/
void APPB::TrackMouse(PGOB pgob, PT *ppt)
{
AssertThis(0);
AssertPo(pgob, 0);
AssertVarMem(ppt);
EVT evt;
while (EventAvail(everyEvent, &evt))
{
if (!GetNextEvent(everyEvent, &evt))
break;
_grfcust &= ~kgrfcustUser;
_grfcust |= _GrfcustFromEvt(&evt);
switch (evt.what)
{
case mouseDown:
_grfcust |= fcustMouse;
goto LDone;
case mouseUp:
_grfcust &= ~fcustMouse;
goto LDone;
case keyDown:
case autoKey:
break;
case updateEvt:
_UpdateEvt(&evt);
break;
case activateEvt:
_ActivateEvt(&evt);
break;
case diskEvt:
break;
case osEvt:
if ((evt.message & 0xFF000000) == 0xFA000000)
{
// mouse move
goto LDone;
}
if (evt.message & 0x01000000)
{
// suspend or resume
Bug("How can this happen?");
if (evt.message & 0x00000001)
_ActivateApp(&evt);
else
_DeactivateApp(&evt);
}
break;
}
}
LDone:
ppt->xp = evt.where.h;
ppt->yp = evt.where.v;
pgob->MapPt(ppt, cooGlobal, cooLocal);
}
/***************************************************************************
Dispatch the OS level event to a translator.
***************************************************************************/
void APPB::_DispatchEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
CMD cmd;
switch (pevt->what)
{
case mouseDown:
_MouseDownEvt(pevt);
break;
case mouseUp:
_MouseUpEvt(pevt);
break;
case keyDown:
case autoKey:
if (_FTranslateKeyEvt(pevt, (PCMD_KEY)&cmd))
vpcex->EnqueueCmd(&cmd);
break;
case updateEvt:
_UpdateEvt(pevt);
break;
case activateEvt:
_ActivateEvt(pevt);
break;
case diskEvt:
_DiskEvt(pevt);
break;
case osEvt:
if (pevt->message & 0x01000000)
{
// suspend or resume
if (pevt->message & 0x00000001)
_ActivateApp(pevt);
else
_DeactivateApp(pevt);
}
else if ((pevt->message & 0xFF000000) == 0xFA000000)
_MouseMovedEvt(pevt);
break;
}
}
/***************************************************************************
Dispatch an OS level mouse down event.
***************************************************************************/
void APPB::_MouseDownEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
short in;
HWND hwnd;
PGOB pgob;
in = FindWindow(pevt->where, (WindowPtr *)&hwnd);
switch (in)
{
case inMenuBar:
if (pvNil != vpmubCur)
vpmubCur->FDoClick(pevt);
break;
case inDrag:
RCS rcs = qd.screenBits.bounds;
InsetRect(&rcs, 4, 4);
DragWindow(&hwnd->port, pevt->where, &rcs);
break;
case inGoAway:
if (TrackGoAway(&hwnd->port, pevt->where) &&
(pgob = GOB::PgobFromHwnd(hwnd)) != pvNil)
{
vpcex->EnqueueCid(cidCloseWnd, pgob);
}
break;
case inGrow:
if ((pgob = GOB::PgobFromHwnd(hwnd)) != pvNil)
pgob->TrackGrow(pevt);
break;
case inContent:
if (hwnd != (HWND)FrontWindow())
SelectWindow(&hwnd->port);
else if ((pgob = GOB::PgobFromHwnd(hwnd)) != pvNil)
{
PPRT pprt;
PT pt;
PTS pts = pevt->where;
GetPort(&pprt);
SetPort(&hwnd->port);
GlobalToLocal(&pts);
SetPort(pprt);
if ((pgob = pgob->PgobFromPt(pts.h, pts.v, &pt)) != pvNil)
{
if (_pgobMouse == pgob &&
FIn(pevt->when - _tsMouse, 0, GetDblTime()))
{
_cactMouse++;
}
else
_cactMouse = 1;
_tsMouse = pevt->when;
if (_pgobMouse != pgob && pvNil != _pgobMouse)
{
AssertPo(_pgobMouse, 0);
vpcex->EnqueueCid(cidRollOff, _pgobMouse);
}
_pgobMouse = pgob;
_xpMouse = klwMax;
pgob->MouseDown(pt.xp, pt.yp, _cactMouse, GrfcustCur());
}
else
_pgobMouse = pvNil;
}
break;
case inSysWindow:
case inZoomIn:
case inZoomOut:
break;
}
}
/***************************************************************************
Dispatch an OS level mouse up event.
***************************************************************************/
void APPB::_MouseUpEvt(EVT *pevt)
{
//Ignore mouse up events
}
/***************************************************************************
Translate an OS level key down event to a CMD. This returns false if
the key maps to a menu item.
//REVIEW shonk: resolve (ch, vk) differences between Mac and Win
***************************************************************************/
bool APPB::_FTranslateKeyEvt(EVT *pevt, PCMD_KEY pcmd)
{
AssertThis(0);
AssertVarMem(pevt);
AssertVarMem(pcmd);
ClearPb(pcmd, size(*pcmd));
pcmd->cid = cidKey;
pcmd->grfcust = GrfcustCur();
if ((pcmd->grfcust & fcustCmd) && vpmubCur != pvNil &&
vpmubCur->FDoKey(pevt))
{
TrashVar(pcmd);
return fFalse;
}
pcmd->ch = B0Lw(pevt->message);
pcmd->vk = pcmd->ch;
pcmd->cact = 1;
return fTrue;
}
/***************************************************************************
Look at the next system event and if it's a key, fill in the *pcmd with
the relevant info.
***************************************************************************/
bool APPB::FGetNextKeyFromOsQueue(PCMD_KEY pcmd)
{
AssertThis(0);
AssertVarMem(pcmd);
EVT evt;
if (!EventAvail(everyEvent, &evt))
goto LFail;
if (evt.what != keyDown && evt.what != autoKey)
goto LFail;
if (!GetNextEvent(keyDownMask | autoKeyMask, &evt))
{
LFail:
TrashVar(pcmd);
return fFalse;
}
_grfcust &= ~kgrfcustUser;
_grfcust |= _GrfcustFromEvt(&evt);
return _FTranslateKeyEvt(&evt, pcmd);
}
/***************************************************************************
Returns the grfcust for the given event.
***************************************************************************/
ulong _GrfcustFromEvt(PEVT pevt)
{
AssertThis(0);
AssertVarMem(pevt);
ulong grfcust = 0;
if (pevt->modifiers & (cmdKey | controlKey))
grfcust |= fcustCmd;
if (pevt->modifiers & shiftKey)
grfcust |= fcustShift;
if (pevt->modifiers & optionKey)
grfcust |= fcustOption;
if (!(pevt->modifiers & btnState))
grfcust |= fcustMouse;
return grfcust;
}
/***************************************************************************
Dispatch an OS level update event.
***************************************************************************/
void APPB::_UpdateEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
PPRT pprt, pprtSav;
RCS rcs;
RC rc;
pprt = (PPRT)pevt->message;
InvalMarked((HWND)pprt);
rcs = (*((HWND)pprt)->updateRgn)->rgnBBox;
GetPort(&pprtSav);
SetPort(pprt);
GlobalToLocal((PTS *)&rcs);
GlobalToLocal((PTS *)&rcs + 1);
rc = rcs;
BeginUpdate(pprt);
UpdateHwnd((HWND)pprt, &rc);
EndUpdate(pprt);
SetPort(pprtSav);
}
/***************************************************************************
Dispatch an OS level activate event.
***************************************************************************/
void APPB::_ActivateEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
//Tell the gob code that an hwnd is being activated or deactivated
GOB::ActivateHwnd((HWND)pevt->message, pevt->modifiers & 1);
}
/***************************************************************************
Handle an OS level disk event.
***************************************************************************/
void APPB::_DiskEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
}
/***************************************************************************
Handle activation of the app.
***************************************************************************/
void APPB::_ActivateApp(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
_Activate(fTrue);
}
/***************************************************************************
Handle deactivation of the app.
***************************************************************************/
void APPB::_DeactivateApp(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
_Activate(fFalse);
}
/***************************************************************************
Handle an OS level mouse moved event.
***************************************************************************/
void APPB::_MouseMovedEvt(EVT *pevt)
{
AssertThis(0);
AssertVarMem(pevt);
}
/****************************************
Standard alert resources
****************************************/
enum
{
kridOkAlert = 128,
kridOkCancelAlert,
kridYesNoAlert,
kridYesNoCancelAlert
};
/***************************************************************************
Put an alert up. Return which button was hit. Returns tYes for yes
or ok; tNo for no; tMaybe for cancel.
***************************************************************************/
bool APPB::TGiveAlertSz(PSZ psz, long bk, long cok)
{
AssertThis(0);
AssertSz(psz);
short rid, bid;
STN stn;
stn = psz;
switch (bk)
{
default:
BugVar("bad bk value", &bk);
//fall through
case bkOk:
rid = kridOkAlert;
break;
case bkOkCancel:
rid = kridOkCancelAlert;
break;
case bkYesNo:
rid = kridYesNoAlert;
break;
case bkYesNoCancel:
rid = kridYesNoCancelAlert;
break;
}
ParamText(stn.Pst(), (uchar *)"", (uchar *)"", (uchar *)"");
switch (cok)
{
default:
BugVar("bad cok value", &cok);
Debug( ParamText(stn.Pst(), (uchar *)"", (uchar *)"", (uchar *)""); )
//fall through
case cokNil:
bid = Alert(rid, pvNil);
break;
case cokInformation:
bid = NoteAlert(rid, pvNil);
break;
case cokQuestion:
case cokExclamation:
bid = CautionAlert(rid, pvNil);
break;
case cokStop:
bid = StopAlert(rid, pvNil);
break;
}
switch (bid)
{
default:
case 1:
return tYes;
case 2:
return tNo;
case 3:
return tMaybe;
}
}
#ifdef DEBUG
const short kridAssert = 32000;
const short kbidDebugger = 1;
const short kbidIgnore = 2;
const short kbidQuit = 3;
/***************************************************************************
Debug initialization.
***************************************************************************/
bool APPB::_FInitDebug(void)
{
return fTrue;
}
/***************************************************************************
Assert proc.
REVIEW shonk: Mac FAssertProcApp: flesh out and fix for unicode.
***************************************************************************/
bool APPB::FAssertProcApp(PSZ pszFile, long lwLine, PSZ pszMsg,
void *pv, long cb)
{
short bid;
achar stLine[kcbMaxSt];
achar stFile[kcbMaxSt];
achar stMessage[kcbMaxSt];
if (_fInAssert)
return fFalse;
_fInAssert = fTrue;
if (pszMsg != pvNil)
CopySzSt(pszMsg, stMessage);
else
SetStCch(stMessage, 0);
if (pvNil != pszFile)
CopySzSt(pszFile, stFile);
else
CopySzSt("Some Header file", stFile);
NumToString(lwLine, (byte *)stLine);
ParamText((byte *)stLine, (byte *)stFile, (byte *)stMessage, (byte *)"\p");
bid = Alert(kridAssert, pvNil);
_fInAssert = fFalse;
switch (bid)
{
case kbidDebugger:
return 1;
case kbidIgnore:
break;
case kbidQuit:
ExitToShell();
default:
break;
}
return 0;
}
#endif