home *** CD-ROM | disk | FTP | other *** search
-
- #pragma load "MacHeaders"
-
-
- #ifndef __MAININCLUDES__
- #include "MainApp.h"
- #endif
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // The "g" prefix is used to emphasize that a variable is global.
-
- // gInBackground is maintained by our OSEvent handling routines. Any part of
- // the program can check it to find out if it is currently in the background.
- Boolean gInBackground; // maintained by Initialize and DoEvent
-
- // gAmplitude and gPitch are computed from the current state of the sliders in
- // the main app window.
- unsigned char gAmplitude;
- unsigned short gPitch;
- Boolean gUpdateWave;
-
- // gPrivatePtr gives us a ptr to MultiBuffer's private memory, so we can dispose of it
- // when the play is finished.
- Ptr gPrivatePtr;
-
-
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // prototypes
-
- void main(void);
- void EventLoop(void);
- void DoEvent(EventRecord *event);
- void DoUpdate(WindowPtr window);
- void DoActivate(WindowPtr window, Boolean becomingActive);
- void DoContentClick(WindowPtr window, EventRecord *event);
- void AdjustMenus(void);
- void DoMenuCommand(long menuResult);
- void DoCloseWindow(WindowPtr window);
- void Terminate(void);
- void Initialize(void);
- Boolean IsDAWindow(WindowPtr window);
- long GetSleep(void);
- void DoIdle(void);
- Boolean FailLowMemory(long memRequested);
- void AlertUser(short errNum, short errStrIndex, Boolean fatal);
- void NewMainWindow(void);
- void DrawMainWindow(WindowPtr window);
- void MainWindowClick(WindowPtr window, EventRecord *event);
- pascal void ScrollAdjust(ControlHandle control, short part);
- ControlHandle FindMyControl(WindowPtr window, short cntlRefCon);
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //This routine is part of the MPW runtime library. This external reference
- // to it is done so that we can unload its segment, %A5Init.
-
- extern void _DataInit();
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void main(void)
- {
- UnloadSeg((Ptr) _DataInit); // _DataInit must not be in the Main code segment
-
- MaxApplZone(); // expand the heap so code segments load at the top
- Initialize(); // initialize the program
- EventLoop(); // call the main event loop
- }
-
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Get events forever, and handle them by calling DoEvent. Get the events by
- // calling WaitNextEvent. This is alway available in System 6 or later.
- // WaitNextEvent will return false instead of giving up a nullEvent.
-
- void EventLoop(void)
- {
- EventRecord event;
-
- while (true) {
- if ( WaitNextEvent(everyEvent, &event, GetSleep(), nil) )
- DoEvent(&event);
- else
- DoIdle();
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoEvent(EventRecord *event)
- {
- short part, err;
- WindowPtr window;
- char key;
-
- switch (event->what) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch (part) {
- case inMenuBar:
- AdjustMenus(); // bring ’em up-to-date
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow:
- SystemClick(event, window);
- break;
- case inContent:
- if (window != FrontWindow())
- SelectWindow(window);
- else
- DoContentClick(window, event);
- break;
- case inDrag:
- DragWindow(window, event->where, &qd.screenBits.bounds);
- break;
- case inGoAway:
- if (TrackGoAway(window, event->where))
- HideWindow(window);
- break;
- case inGrow:
- break;
- case inZoomIn:
- case inZoomOut:
- if (TrackBox(window, event->where, part))
- break;
- }
- break;
- case keyDown:
- case autoKey:
- key = event->message & charCodeMask;
- if (event->modifiers & cmdKey) { // Command key down
- if (event->what == keyDown) {
- AdjustMenus(); // enable/disable/check menu items properly
- DoMenuCommand(MenuKey(key));
- }
- }
- break;
- case activateEvt:
- DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
- break;
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
- case diskEvt:
- if (HiWrd(event->message) != noErr)
- err = DIBadMount(kDIPosition, event->message);
- break;
- case osEvt:
- switch (event->message >> 24) {
- case suspendResumeMessage: // suspend/resume is also an activate/deactivate
- gInBackground = (event->message & resumeFlag) == 0;
- DoActivate(FrontWindow(), !gInBackground);
- break;
- }
- break;
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoUpdate(WindowPtr window)
- {
- SetPort(window);
- BeginUpdate(window); // this sets up the visRgn
- if (!EmptyRgn(window->visRgn)) { // draw if updating needs to be done
-
- PenNormal(); // get ready for standard drawing
- switch (GetWRefCon(window)) {
-
- case rMainWindow:
- DrawMainWindow(window);
- break;
-
- }
- }
- EndUpdate(window);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoActivate(WindowPtr window, Boolean becomingActive)
- {
-
- #pragma unused (window)
-
- if (becomingActive) {
- }
- else {
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoContentClick(WindowPtr window, EventRecord *event)
- {
-
- switch (GetWRefCon(window)) {
-
- case rMainWindow:
- MainWindowClick(window, event);
- break;
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Enable and disable menus based on the current state. The user can only
- // select enabled menu items. We set up all the menu items before calling
- // MenuSelect or MenuKey, since these are the only times that a menu item can
- // be selected. Note that MenuSelect is also the only time the user will see
- // menu items. This approach to deciding what enable/ disable state a menu item
- // has the advantage of concentrating all the decision-making in one routine,
- // as opposed to being spread throughout the application. Other application
- // designs may take a different approach that is just as valid.
-
- void AdjustMenus(void)
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMHandle(mEdit);
- if ( IsDAWindow(window) ) { // a desk accessory might need the edit menu
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- }
- else {
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
-
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // This is called when an item is chosen from the menu bar (after calling
- // MenuSelect or MenuKey). It performs the right operation for each command. It
- // is good to have both the result of MenuSelect and MenuKey go to one routine
- // like this to keep everything organized.
-
- void DoMenuCommand(long menuResult)
- {
- Str255 daName;
- short daRefNum;
- short menuID;
- short menuItem;
- short itemHit;
- OSErr err;
-
- menuID = HiWrd(menuResult);
- menuItem = LoWrd(menuResult);
- switch (menuID) {
- case mApple:
- switch (menuItem) {
- case iAbout: // bring up alert for About
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: // all non-About items in this menu are DAs et al
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch (menuItem) {
- case iPlay:
- KillDoubleBuffer (); // stop current play and
- FreeDBPrivateMem (gPrivatePtr); // release it's memory
-
- err = PlayFile(true, &gPrivatePtr);
- if (err != noErr)
- AlertUser(err, eUnexpected, !kFatalError);
- break;
- case iPlayBackwards:
- KillDoubleBuffer (); // stop current play and
- FreeDBPrivateMem (gPrivatePtr); // release it's memory
-
- err = PlayFile(false, &gPrivatePtr);
- if (err != noErr)
- AlertUser(err, eUnexpected, !kFatalError);
- break;
- case iRecord:
- err = RecordAIFFFile(kAppCreator);
- if (err != noErr)
- AlertUser(err, eUnexpected, !kFatalError);
- break;
- case iSynthisize:
- gUpdateWave = true;
- break;
- case iKill:
- KillDoubleBuffer (); // stop current play and
- FreeDBPrivateMem (gPrivatePtr); // release it's memory
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- }
- HiliteMenu(0); // unhighlight what MenuSelect (or MenuKey) hilited
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Close a window and dispose of any associating data. This handles desk accessory
- // and application windows.
-
- void DoCloseWindow(WindowPtr window)
- {
- if (IsDAWindow(window))
- CloseDeskAcc(((WindowPeek) window)->windowKind);
- else {
- switch (GetWRefCon(window)) {
-
- case rMainWindow:
- DisposeWindow(window);
- break;
- }
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void Terminate()
- {
- WindowPtr aWindow;
-
- do {
- aWindow = FrontWindow(); // get the current front window
- if (aWindow != nil)
- DoCloseWindow(aWindow); // close this window
- } while (aWindow != nil);
-
- CloseDoubleBuffer();
- ExitToShell(); // exit if no cancellation
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void Initialize()
- {
- Handle menuBar;
- EventRecord event;
- short count;
- OSErr err;
- long response;
-
- gInBackground = false;
-
- gPrivatePtr = nil;
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- // bring the app to the foreground
- for (count = 1; count <= 3; count++)
- EventAvail(everyEvent, &event);
-
- // I want to know if WaitNextEvent is available, which is always true for
- // System 6.02 or later. I should be checking for this trap to be implimented,
- // but I also don't trust any Sound Manager that was shipped privous to 6.02.
- // Since I checked for this version of the system I know that WaitNextEvent is
- // there, but otherwise I would be checking for the features that I want
- // and not for the system version.
-
- err = Gestalt(gestaltSystemVersion, &response);
- if (err != noErr)
- AlertUser(err, eSystemTooOld, kFatalError);
- else
- if (response < kOldestSystemAllowed)
- AlertUser(err, eSystemTooOld, kFatalError);
-
-
- menuBar = GetNewMBar(rMenuBar);
- if (menuBar == nil)
- AlertUser(MemError(), eNoMenuBar, kFatalError);
- SetMenuBar(menuBar);
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR');
- DrawMenuBar();
-
- NewMainWindow();
-
- err = InitDoubleBuffer();
- if (err != noErr)
- AlertUser(err, eUnexpected, kFatalError);
-
- // test for minimal memory requirements after allocating application's stuff
- if (FailLowMemory(kMinHeap))
- AlertUser(0, eNoMemory, kFatalError);
-
-
- // Make sure we have rational values for the amplitude and pitch globals.
- gPitch = kPitchDefault;
- gAmplitude = kAmpDefault;
-
- // Don't need a wave table until asked for it...
- gUpdateWave = false;
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Check to see if a window belongs to a desk accessory.
-
- Boolean IsDAWindow(WindowPtr window)
- {
- if (window) // DA windows have negative windowKinds
- return (((WindowPeek) window)->windowKind < 0);
- else
- return false;
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // Calculate a sleep value for WaitNextEvent. This takes into account the things
- // that DoIdle does with idle time.
-
- long GetSleep(void)
- {
- if (gInBackground)
- return (kBackSleep);
- else
- return (kForeSleep);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DoIdle(void)
- {
- WindowPtr window;
- WaveCyclePtr wave;
- long finalTick;
-
- window = FrontWindow();
-
- if (gUpdateWave == true) {
- // Should probably set a watch cursor here...
-
- wave = NewWaveForm (gAmplitude,gPitch);
-
- KillDoubleBuffer (); // stop current play and
-
- FreeDBPrivateMem (gPrivatePtr); // release it's memory
-
- Delay (20, &finalTick); // Let current play complete
-
- PlayWave (88000, wave, &gPrivatePtr); // About four seconds...
-
- gUpdateWave = false;
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Boolean FailLowMemory(long memRequested)
- {
- long total;
- long contig;
-
- PurgeSpace(&total, &contig);
- return ( total < (memRequested + kMinSpace) );
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void AlertUser(short errNum, short errStrIndex, Boolean fatal)
- {
- short itemHit;
- Str255 msg1;
- Str255 msg2;
-
- if (errNum != userCanceledErr) { // ignore cancels
- SetCursor(&qd.arrow);
- if (errNum)
- NumToString(errNum, msg1);
- else
- *msg1 = 0; // set length to zero
- GetIndString(msg2, rErrStrings, errStrIndex);
- ParamText(msg1, msg2, "\p", "\p");
- itemHit = Alert(rUserAlert, nil);
- if (fatal)
- ExitToShell();
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void NewMainWindow(void)
- {
- ControlHandle control;
- WindowPtr window;
- StringHandle strHandle;
-
- window = (WindowPtr) NewPtr(sizeof(MainWindow));
- if (window == nil)
- AlertUser(MemError(), eNoWindow, kFatalError);
- window = GetNewWindow(rMainWindow, window, (WindowPtr)-1);
- if (window == nil)
- AlertUser(MemError(), eNoWindow, kFatalError);
- SetPort(window);
- TextFont(systemFont);
- SetWRefCon(window, rMainWindow);
-
- control = GetNewControl(rAmpButton, window);
- if (control == nil)
- AlertUser(MemError(), eNoWindow, kFatalError);
- SetCRefCon(control, rAmpButton);
-
- control = GetNewControl(rPitchButton, window);
- if (control == nil)
- AlertUser(MemError(), eNoWindow, kFatalError);
- SetCRefCon(control, rPitchButton);
-
- strHandle = GetString(rAmpString);
- if (strHandle == nil)
- AlertUser(ResError(), eResourceErr, kFatalError);
- ((MainWindowPtr)window)->ampString = strHandle;
-
- strHandle = GetString(rPitchString);
- if (strHandle == nil)
- AlertUser(ResError(), eResourceErr, kFatalError);
- ((MainWindowPtr)window)->pitchString = strHandle;
-
- ShowWindow(window);
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void DrawMainWindow(WindowPtr window)
- {
- ControlHandle control;
- Rect drawArea;
-
- UpdateControls(window, window->visRgn);
- control = FindMyControl(window, rAmpButton);
- if (control != nil) {
- drawArea = (**control).contrlRect;
- OffsetRect(&drawArea, 0, kControlTextOffset);
- TextBox(*((MainWindowPtr)window)->ampString + 1,
- Length(*((MainWindowPtr)window)->ampString), &drawArea, teJustCenter);
- }
- control = FindMyControl(window, rPitchButton);
- if (control != nil) {
- drawArea = (**control).contrlRect;
- OffsetRect(&drawArea, 0, kControlTextOffset);
- TextBox(*((MainWindowPtr)window)->pitchString + 1,
- Length(*((MainWindowPtr)window)->pitchString), &drawArea, teJustCenter);
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- void MainWindowClick(WindowPtr window, EventRecord *event)
- {
- Point mouse;
- ControlHandle control;
- short part;
- short oldValue;
-
- SetPort(window);
- mouse = event->where; // get the click position
- GlobalToLocal(&mouse);
-
- part = FindControl(mouse, window, &control);
- if (part != 0) { // check for a hit
-
- switch (GetCRefCon(control)) {
-
- case rAmpButton:
- if (part == inThumb)
- TrackControl(control, mouse, nil);
- else
- TrackControl(control, mouse, (ProcPtr)ScrollAdjust);
- oldValue = gAmplitude; // save amplitude value
- gAmplitude = GetCtlValue(control);
-
- // Since recalculating the wave form may take a while, make sure
- // the value has actually changed...
- if (oldValue != gAmplitude)
- gUpdateWave = true;
-
- break;
-
- case rPitchButton:
- if (part == inThumb)
- TrackControl(control, mouse, nil);
- else
- TrackControl(control, mouse, (ProcPtr)ScrollAdjust);
- oldValue = gPitch; // save pitch value
- gPitch = GetCtlValue(control);
-
- // Since recalculating the wave form may take a while, make sure
- // the value has actually changed...
- if (oldValue != gAmplitude)
- gUpdateWave = true;
-
- break;
- }
- }
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- pascal void ScrollAdjust(ControlHandle control, short part)
- {
- short curValue;
- short minValue;
- short maxValue;
-
- curValue = GetCtlValue(control);
- minValue = GetCtlMin(control);
- maxValue = GetCtlMax(control);
-
- switch (part) {
-
- case inUpButton:
- if (curValue > minValue)
- SetCtlValue(control, curValue - 1);
- break;
- case inDownButton:
- if (curValue < maxValue)
- SetCtlValue(control, curValue + 1);
- break;
- case inPageUp:
- curValue -= 5;
- if (curValue < minValue)
- curValue = minValue;
- if (curValue >= minValue)
- SetCtlValue(control, curValue);
- break;
- case inPageDown:
- curValue += 5;
- if (curValue > maxValue)
- curValue = maxValue;
- if (curValue <= maxValue)
- SetCtlValue(control, curValue);
- break;
- }
-
- }
-
- //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ControlHandle FindMyControl(WindowPtr window, short cntlRefCon)
- {
- ControlHandle cntlHandle;
-
- cntlHandle = ((WindowPeek)(window))->controlList;
- while (cntlHandle != nil) {
- if (GetCRefCon(cntlHandle) != cntlRefCon)
- cntlHandle = (**cntlHandle).nextControl;
- else
- break;
- }
- return (cntlHandle);
- }
-
-
-