2001-10-19 19:41:13 +00:00
|
|
|
|
#include "Application.h"
|
|
|
|
|
#include "Asynchronous.h" // for initing, idling, and disposing
|
|
|
|
|
#include "Errors.h"
|
|
|
|
|
#include "Files.h" // for open & save etc.
|
|
|
|
|
#include "FileWindow.h" // no particuar reason
|
|
|
|
|
#include "ResourceObject.h"
|
|
|
|
|
#include "Utility.h"
|
|
|
|
|
|
|
|
|
|
// set up prefs and globals
|
|
|
|
|
globals g;
|
|
|
|
|
prefs p;
|
|
|
|
|
|
|
|
|
|
/*** MAIN ***/
|
|
|
|
|
int main( int argc, char* argv[] )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( argc, argv )
|
|
|
|
|
|
|
|
|
|
// get system version
|
|
|
|
|
OSStatus error = Gestalt( gestaltSystemVersion, &g.systemVersion ); // this loads HIToolbox.framework on OS X
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
|
|
|
|
|
// initalise application
|
|
|
|
|
error = InitToolbox();
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
error = InitMenubar();
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
error = InitAppleEvents();
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
error = InitCarbonEvents();
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
error = InitGlobals();
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
InitCursor();
|
|
|
|
|
|
|
|
|
|
// check system version is at least 7.1
|
|
|
|
|
if( g.systemVersion < kMacOS71 )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( kStringOSNotGoodEnough, kExplanationOSNotGoodEnough );
|
|
|
|
|
QuitResKnife();
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-31 00:17:53 +00:00
|
|
|
|
#if TARGET_API_MAC_CARBON
|
2001-10-19 19:41:13 +00:00
|
|
|
|
// check carbon version is at least 1.1
|
|
|
|
|
error = Gestalt( gestaltCarbonVersion, &g.carbonVersion );
|
|
|
|
|
if( g.carbonVersion < kCarbonLib11 || error )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( kStringMinimumCarbonLib, kExplanationMinimumCarbonLib );
|
|
|
|
|
QuitResKnife();
|
|
|
|
|
}
|
|
|
|
|
else if( g.carbonVersion < kCarbonLib131 )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( kStringRecommendedCarbonLib, kExplanationRecommendedCarbonLib );
|
|
|
|
|
}
|
2002-05-31 00:17:53 +00:00
|
|
|
|
#endif
|
2001-10-19 19:41:13 +00:00
|
|
|
|
|
|
|
|
|
#if __profile__
|
|
|
|
|
error = ProfilerInit( collectDetailed, bestTimeBase, 400, 40 );
|
|
|
|
|
if( error ) DebugStr( "\pProfiler initalisation failed" ); // profiler failed
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
// run event loop
|
|
|
|
|
RunApplicationEventLoop();
|
|
|
|
|
#else
|
|
|
|
|
EventRecord theEvent;
|
|
|
|
|
while( !g.quitting )
|
|
|
|
|
{
|
|
|
|
|
WaitNextEvent( everyEvent, &theEvent, 20, null );
|
|
|
|
|
if( IsDialogEvent( &theEvent ) )
|
|
|
|
|
ParseDialogEvents( null, &theEvent, null );
|
|
|
|
|
else ParseEvents( &theEvent );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if __profile__
|
|
|
|
|
ProfilerDump( "\pResKnife profile" );
|
|
|
|
|
ProfilerTerm();
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-04-03 15:38:42 +00:00
|
|
|
|
#if !TARGET_API_MAC_CARBON
|
|
|
|
|
QuitResKnife();
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-10-19 19:41:13 +00:00
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** INIT TOOLBOX ***/
|
|
|
|
|
OSStatus InitToolbox( void )
|
|
|
|
|
{
|
|
|
|
|
#if !TARGET_API_MAC_CARBON
|
|
|
|
|
InitGraf( &qd.thePort );
|
|
|
|
|
InitFonts();
|
|
|
|
|
FlushEvents( everyEvent, 0 );
|
|
|
|
|
InitWindows();
|
|
|
|
|
InitMenus();
|
|
|
|
|
TEInit();
|
|
|
|
|
InitDialogs( 0L );
|
|
|
|
|
#endif
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** INITALIZE MENUBAR ***/
|
|
|
|
|
OSStatus InitMenubar( void )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
|
|
|
|
|
#if USE_NIBS
|
|
|
|
|
IBNibRef nibRef = null;
|
|
|
|
|
|
|
|
|
|
// create a nib reference (only searches the application bundle)
|
|
|
|
|
error = CreateNibReference( CFSTR("ResKnife"), &nibRef );
|
|
|
|
|
if( error != noErr )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pThe nib file reference could not be obtained." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get menu bar
|
|
|
|
|
error = SetMenuBarFromNib( nibRef, CFSTR("Menubar") );
|
|
|
|
|
if( error != noErr )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pMenus could not be obtained from nib file." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispose of nib ref
|
|
|
|
|
DisposeNibReference( nibRef );
|
|
|
|
|
|
|
|
|
|
#else /* ! USE_NIBS */
|
|
|
|
|
|
|
|
|
|
Handle menuList = GetNewMBar( kClassicMenuBar );
|
|
|
|
|
SetMenuBar( menuList );
|
|
|
|
|
ReleaseResource( menuList );
|
|
|
|
|
|
|
|
|
|
// delete quit and prefs on OS X
|
|
|
|
|
long result;
|
|
|
|
|
error = Gestalt( gestaltMenuMgrAttr, &result );
|
|
|
|
|
if( !error && (result & gestaltMenuMgrAquaLayoutMask) )
|
|
|
|
|
{
|
|
|
|
|
MenuRef fileMenu = GetMenuRef( kFileMenu );
|
|
|
|
|
MenuRef editMenu = GetMenuRef( kEditMenu );
|
|
|
|
|
DeleteMenuItem( fileMenu, kFileMenuQuitItem );
|
|
|
|
|
DeleteMenuItem( fileMenu, kFileMenuQuitItem -1 );
|
|
|
|
|
DeleteMenuItem( editMenu, kEditMenuPreferencesItem );
|
|
|
|
|
DeleteMenuItem( editMenu, kEditMenuPreferencesItem -1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set delete item character to the delete glyph
|
|
|
|
|
MenuRef editMenu = GetMenuRef( kEditMenu );
|
|
|
|
|
SetMenuItemKeyGlyph( editMenu, kEditMenuClearItem, kMenuDeleteLeftGlyph );
|
|
|
|
|
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
MenuRef windowMenu;
|
|
|
|
|
CreateStandardWindowMenu( 0, &windowMenu );
|
|
|
|
|
InsertMenu( windowMenu, kWindowMenu );
|
|
|
|
|
#else
|
|
|
|
|
AppendResMenu( GetMenuRef( kAppleMenu ), 'DRVR' );
|
|
|
|
|
#endif /* TARGET_CARBON */
|
|
|
|
|
DrawMenuBar();
|
|
|
|
|
|
|
|
|
|
#endif /* USE_NIBS */
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** INIT APPLE EVENTS ***/
|
|
|
|
|
OSStatus InitAppleEvents( void )
|
|
|
|
|
{
|
|
|
|
|
AEEventHandlerUPP appleEventParser = NewAEEventHandlerUPP( ParseAppleEvents );
|
|
|
|
|
AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, appleEventParser, 0, false );
|
|
|
|
|
AEInstallEventHandler( kCoreEventClass, kAEReopenApplication, appleEventParser, 0, false );
|
|
|
|
|
AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, appleEventParser, 0, false );
|
|
|
|
|
AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, appleEventParser, 0, false );
|
|
|
|
|
AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, appleEventParser, 0, false );
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** INIT CARBON EVENTS ***/
|
|
|
|
|
OSStatus InitCarbonEvents( void )
|
|
|
|
|
{
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
EventHandlerUPP handler = null;
|
|
|
|
|
EventHandlerRef ref = null;
|
|
|
|
|
EventTypeSpec update = { kEventClassMenu, kEventMenuEnableItems };
|
|
|
|
|
EventTypeSpec process = { kEventClassCommand, kEventCommandProcess };
|
|
|
|
|
|
|
|
|
|
// install menu adjust handler
|
|
|
|
|
handler = NewEventHandlerUPP( CarbonEventUpdateMenus );
|
|
|
|
|
InstallApplicationEventHandler( handler, 1, &update, null, &ref );
|
|
|
|
|
|
|
|
|
|
// install menu selection handler
|
|
|
|
|
handler = NewEventHandlerUPP( CarbonEventParseMenuSelection );
|
|
|
|
|
InstallApplicationEventHandler( handler, 1, &process, null, &ref );
|
|
|
|
|
|
|
|
|
|
// install default idle timer <20> 200 millisecond interval - bug: this should be in a seperate thread and the cursor blink time
|
|
|
|
|
EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP( DefaultIdleTimer );
|
|
|
|
|
OSStatus error = InstallEventLoopTimer( GetMainEventLoop(), kEventDurationNoWait, kEventDurationMillisecond * 200, timerUPP, null, &g.idleTimer );
|
|
|
|
|
return error;
|
|
|
|
|
#else
|
|
|
|
|
return noErr;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** INITALIZE GLOBALS ***/
|
|
|
|
|
OSStatus InitGlobals( void )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
|
|
|
|
|
// general app globals
|
|
|
|
|
g.quitting = false;
|
|
|
|
|
g.cancelQuit = false;
|
|
|
|
|
g.frontApp = true;
|
|
|
|
|
g.appResFile = CurResFile();
|
|
|
|
|
g.asyncSound = !(Boolean) SHInitSoundHelper( &g.callSH, kSHDefChannels );
|
|
|
|
|
g.emergencyMemory = NewHandleClear( kEmergencyMemory );
|
|
|
|
|
|
|
|
|
|
// files
|
|
|
|
|
g.tempCount = 0;
|
|
|
|
|
|
|
|
|
|
// debugging
|
|
|
|
|
g.debug = false;
|
|
|
|
|
g.surpressErrors = false;
|
|
|
|
|
g.useAppleEvents = true;
|
|
|
|
|
g.useSheets = (g.carbonVersion >= kCarbonLib11)? true:false;
|
|
|
|
|
|
|
|
|
|
// prefs dialog
|
|
|
|
|
g.prefsDialog = null;
|
|
|
|
|
p.warnOnDelete = true;
|
|
|
|
|
|
|
|
|
|
// colours
|
|
|
|
|
SetColour( &g.white, 0xFFFF, 0xFFFF, 0xFFFF );
|
|
|
|
|
SetColour( &g.bgColour, 0xEEEE, 0xEEEE, 0xEEEE );
|
|
|
|
|
SetColour( &g.sortColour, 0xDDDD, 0xDDDD, 0xDDDD );
|
|
|
|
|
SetColour( &g.bevelColour, 0xAAAA, 0xAAAA, 0xAAAA );
|
|
|
|
|
SetColour( &g.textColour, 0x7777, 0x7777, 0x7777 );
|
|
|
|
|
SetColour( &g.frameColour, 0x5555, 0x5555, 0x5555 );
|
|
|
|
|
SetColour( &g.black, 0x0000, 0x0000, 0x0000 );
|
|
|
|
|
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
// window manager
|
|
|
|
|
g.windowMgrAvailable = true;
|
|
|
|
|
g.extendedWindowAttr = true;
|
|
|
|
|
|
|
|
|
|
// drag manager
|
|
|
|
|
g.dragAvailable = true;
|
|
|
|
|
g.translucentDrag = true;
|
|
|
|
|
|
|
|
|
|
// appearance manager
|
|
|
|
|
g.appearanceAvailable = true;
|
|
|
|
|
g.useAppearance = g.appearanceAvailable; // assume if user has Appearence, s/he wants to use it
|
|
|
|
|
if( g.useAppearance ) RegisterAppearanceClient(); // register such with the OS
|
|
|
|
|
|
|
|
|
|
// nav services
|
|
|
|
|
g.navAvailable = true;
|
|
|
|
|
g.useNavServices = g.navAvailable; // assume if user has NavServices, s/he wants to use them
|
|
|
|
|
if( g.navAvailable ) NavLoad(); // preload for efficiency - ignored on OS X (always loaded)
|
|
|
|
|
#else
|
|
|
|
|
// check for drag manager presence/attributes
|
|
|
|
|
SInt32 result = null;
|
|
|
|
|
error = Gestalt( gestaltDragMgrAttr, &result );
|
|
|
|
|
if( !error ) {
|
|
|
|
|
g.dragAvailable = (Boolean) (result & (1 << gestaltDragMgrPresent));
|
|
|
|
|
g.translucentDrag = (Boolean) (result & (1 << gestaltDragMgrHasImageSupport)); }
|
|
|
|
|
else {
|
|
|
|
|
g.dragAvailable = false;
|
|
|
|
|
g.translucentDrag = false; }
|
|
|
|
|
|
|
|
|
|
// check appearance availablilty
|
|
|
|
|
result = null;
|
|
|
|
|
error = Gestalt( gestaltAppearanceAttr, &result );
|
|
|
|
|
if( !error ) {
|
|
|
|
|
g.appearanceAvailable = (Boolean) (result & (1 << gestaltAppearanceExists));
|
|
|
|
|
g.useAppearance = g.appearanceAvailable; } // assume if user has Appearence, s/he wants to use it
|
|
|
|
|
else {
|
|
|
|
|
g.appearanceAvailable = false;
|
|
|
|
|
g.useAppearance = false; }
|
|
|
|
|
if( g.useAppearance ) RegisterAppearanceClient(); // register such with the OS
|
|
|
|
|
|
|
|
|
|
// check nav services availablilty
|
|
|
|
|
g.navAvailable = (Boolean) NavServicesAvailable();
|
|
|
|
|
g.useNavServices = g.navAvailable; // assume if user has NavServices, s/he wants to use them
|
|
|
|
|
if( g.navAvailable ) NavLoad(); // preload for efficiency
|
|
|
|
|
|
|
|
|
|
// check for MacOS 8.5's window manager (also in CarbonLib 1.0 - backported to 8.1)
|
|
|
|
|
result = null;
|
|
|
|
|
error = Gestalt( gestaltWindowMgrAttr, &result );
|
|
|
|
|
if( !error ) {
|
|
|
|
|
g.windowMgrAvailable = (Boolean) (result & (1 << gestaltWindowMgrPresentBit));
|
|
|
|
|
g.extendedWindowAttr = (Boolean) (result & (1 << gestaltExtendedWindowAttributes)); }
|
|
|
|
|
else {
|
|
|
|
|
g.windowMgrAvailable = false;
|
|
|
|
|
g.extendedWindowAttr = false; }
|
|
|
|
|
|
|
|
|
|
UpdateMenus( null );
|
|
|
|
|
#endif
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !TARGET_API_MAC_CARBON
|
|
|
|
|
|
|
|
|
|
/*** PARSE EVENTS ***/
|
|
|
|
|
OSStatus ParseEvents( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
switch( event->what )
|
|
|
|
|
{
|
|
|
|
|
case nullEvent:
|
|
|
|
|
IdleEvent();
|
|
|
|
|
break;
|
|
|
|
|
case mouseDown:
|
|
|
|
|
error = MouseDownEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case mouseUp:
|
|
|
|
|
error = MouseUpEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case keyDown:
|
|
|
|
|
error = KeyDownEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case autoKey:
|
|
|
|
|
error = KeyRepeatEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case keyUp:
|
|
|
|
|
error = KeyUpEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case updateEvt:
|
|
|
|
|
error = UpdateEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case activateEvt:
|
|
|
|
|
error = ActivateEventOccoured( event );
|
|
|
|
|
break;
|
|
|
|
|
case osEvt:
|
|
|
|
|
error = ParseOSEvents( event );
|
|
|
|
|
break;
|
|
|
|
|
case kHighLevelEvent:
|
|
|
|
|
error = AEProcessAppleEvent( event );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** PARSE DIALOG EVENTS ***/
|
|
|
|
|
pascal Boolean ParseDialogEvents( DialogPtr dialog, EventRecord *event, DialogItemIndex *itemHit )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( dialog, event, itemHit )
|
|
|
|
|
/* OSStatus error = eventNotHandledErr;
|
|
|
|
|
if( dialog == null && itemHit == null );
|
|
|
|
|
*/ return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** PARSE OS EVENTS ***/
|
|
|
|
|
OSStatus ParseOSEvents( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( event )
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
SInt8 eventType = event->message >> 24; // high byte of message field
|
|
|
|
|
if( eventType & mouseMovedMessage )
|
|
|
|
|
{
|
|
|
|
|
// mouse moved event
|
|
|
|
|
}
|
|
|
|
|
else if( eventType & suspendResumeMessage ) // suspend/resume event
|
|
|
|
|
{
|
|
|
|
|
g.frontApp = ( event->message & resumeFlag ); // true on resume
|
|
|
|
|
if( FrontWindow() ) // only de/activate front window (if present)
|
|
|
|
|
{
|
|
|
|
|
WindowObjectPtr winObj = (WindowObjectPtr) GetWindowRefCon( FrontWindow() );
|
|
|
|
|
error = winObj->Activate( g.frontApp );
|
|
|
|
|
}
|
|
|
|
|
if( event->message & convertClipboardFlag )
|
|
|
|
|
{
|
|
|
|
|
// convert clipboard to private scrap
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else error = paramErr;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*** PARSE APPLE EVENTS ***/
|
|
|
|
|
pascal OSErr ParseAppleEvents( const AppleEvent *event, AppleEvent *reply, SInt32 refCon )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( reply, refCon )
|
|
|
|
|
|
|
|
|
|
OSErr error;
|
|
|
|
|
Size actualSize;
|
|
|
|
|
DescType actualType;
|
|
|
|
|
DescType eventClass, eventID;
|
|
|
|
|
|
|
|
|
|
error = AEGetAttributePtr( (AppleEvent *) event, keyEventClassAttr, typeType, &actualType, (Ptr) &eventClass, sizeof(eventClass), &actualSize );
|
|
|
|
|
if( error ) return errAEEventNotHandled;
|
|
|
|
|
|
|
|
|
|
error = AEGetAttributePtr( (AppleEvent *) event, keyEventIDAttr, typeType, &actualType, (Ptr) &eventID, sizeof(eventID), &actualSize );
|
|
|
|
|
if( error ) return errAEEventNotHandled;
|
|
|
|
|
|
|
|
|
|
switch( eventClass )
|
|
|
|
|
{
|
|
|
|
|
case kCoreEventClass:
|
|
|
|
|
switch( eventID )
|
|
|
|
|
{
|
|
|
|
|
case kAEOpenApplication: // sent when app opened directly (ie not file opened)
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
DisplayOpenDialog();
|
|
|
|
|
#else
|
|
|
|
|
if( g.useNavServices ) DisplayOpenDialog();
|
|
|
|
|
else DisplayStandardFileOpenDialog();
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kAEReopenApplication: // sent when app is double-clicked on, but is already open
|
|
|
|
|
if( FrontWindow() == null )
|
|
|
|
|
{
|
|
|
|
|
AEDescList list = {};
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
AppleEventSendSelf( kCoreEventClass, kAEOpenApplication, list );
|
|
|
|
|
#else
|
|
|
|
|
if( g.useAppleEvents ) AppleEventSendSelf( kCoreEventClass, kAEOpenApplication, list );
|
|
|
|
|
else if( g.useNavServices ) DisplayOpenDialog();
|
|
|
|
|
else DisplayStandardFileOpenDialog();
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kAEOpenDocuments: // sent when file is double-clicked on in finder,
|
|
|
|
|
AppleEventOpen( event ); // or open is chosen in the file menu and g.useAppleEvents is true
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kAEPrintDocuments: // sent when document is dragged onto printer
|
|
|
|
|
AppleEventPrint( event );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kAEQuitApplication: // sent from many locations (eg after restart command)
|
|
|
|
|
QuitResKnife();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* case kAECoreSuite: // i'm not even registering for these yet
|
|
|
|
|
switch( eventID )
|
|
|
|
|
{
|
|
|
|
|
case kAECut:
|
|
|
|
|
case kAECopy:
|
|
|
|
|
case kAEPaste:
|
|
|
|
|
case kAEDelete:
|
|
|
|
|
DisplayErrorDialog( "\pSorry, but cut, copy, paste and clear via Apple Events arn't yet supported." );
|
|
|
|
|
error = errAEEventNotHandled;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
*/ }
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************/
|
|
|
|
|
/* EVENT HANDLING */
|
|
|
|
|
/******************/
|
|
|
|
|
|
|
|
|
|
#if !TARGET_API_MAC_CARBON
|
|
|
|
|
|
|
|
|
|
/*** MOUSE DOWN EVENT OCCOURED ***/
|
|
|
|
|
OSStatus MouseDownEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
// get the window
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
WindowRef window;
|
|
|
|
|
SInt16 windowPart = FindWindow( event->where, &window );
|
|
|
|
|
WindowObjectPtr winObj = (WindowObjectPtr) GetWindowRefCon( window );
|
|
|
|
|
|
|
|
|
|
// find out where the click occoured
|
|
|
|
|
if( !windowPart ) return error;
|
|
|
|
|
else switch( windowPart )
|
|
|
|
|
{
|
|
|
|
|
case inMenuBar:
|
|
|
|
|
error = UpdateMenus( FrontWindow() ); // error ignored at the moment
|
|
|
|
|
UInt32 menuChoice = MenuSelect( event->where );
|
|
|
|
|
UInt16 menu = HiWord( menuChoice );
|
|
|
|
|
UInt16 item = LoWord( menuChoice );
|
|
|
|
|
error = ParseMenuSelection( menu, item ); // error ignored at the moment
|
|
|
|
|
HiliteMenu( 0 );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inSysWindow:
|
|
|
|
|
SystemClick( event, window );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inContent:
|
|
|
|
|
SelectWindow( window );
|
|
|
|
|
winObj->Click( event->where, event->modifiers );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inDrag:
|
|
|
|
|
DragWindow( window, event->where, &qdb );
|
|
|
|
|
winObj->BoundsChanged( null );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inGrow:
|
|
|
|
|
Rect bounds; // minimum and maximum bounds of window
|
|
|
|
|
SetRect( &bounds, 128, 128, 1024, 1024 );
|
|
|
|
|
SInt32 result = GrowWindow( window, event->where, &bounds );
|
|
|
|
|
if( result )
|
|
|
|
|
{
|
|
|
|
|
SInt16 newWidth = LoWord( result );
|
|
|
|
|
SInt16 newHeight = HiWord( result );
|
|
|
|
|
SizeWindow( window, newWidth, newHeight, false );
|
|
|
|
|
winObj->BoundsChanged( null );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inGoAway:
|
|
|
|
|
if( TrackGoAway( window, event->where ) )
|
|
|
|
|
winObj->Close();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inZoomIn:
|
|
|
|
|
case inZoomOut:
|
|
|
|
|
if( TrackBox( window, event->where, windowPart ) )
|
|
|
|
|
{
|
|
|
|
|
ZoomWindow( window, windowPart, window == FrontWindow() ); // I think the last param *might* need to be "g.frontApp"
|
|
|
|
|
winObj->BoundsChanged( null );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case inCollapseBox:
|
|
|
|
|
case inProxyIcon:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** MOUSE UP EVENT OCCOURED ***/
|
|
|
|
|
OSStatus MouseUpEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( event )
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** KEY DOWN EVENT OCCOURED ***/
|
|
|
|
|
OSStatus KeyDownEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
char key = (char)( event->message & charCodeMask ); // get the key pressed
|
|
|
|
|
if( event->modifiers & cmdKey ) // was it a menu shortcut?
|
|
|
|
|
{
|
|
|
|
|
UpdateMenus( FrontWindow() );
|
|
|
|
|
UInt32 menuChoice = MenuKey( key );
|
|
|
|
|
UInt16 menu = HiWord( menuChoice );
|
|
|
|
|
UInt16 item = LoWord( menuChoice );
|
|
|
|
|
if( menu && item )
|
|
|
|
|
error = ParseMenuSelection( menu, item );
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** KEY REPEAT EVENT OCCOURED ***/
|
|
|
|
|
OSStatus KeyRepeatEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = KeyDownEventOccoured( event );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** KEY UP EVENT OCCOURED ***/
|
|
|
|
|
OSStatus KeyUpEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( event )
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** UPDATE EVENT OCCOURED ***/
|
|
|
|
|
OSStatus UpdateEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
GrafPtr oldPort;
|
|
|
|
|
WindowRef window = (WindowRef) event->message;
|
|
|
|
|
|
|
|
|
|
// send update events to window
|
|
|
|
|
GetPort( &oldPort );
|
|
|
|
|
SetPortWindowPort( window );
|
|
|
|
|
BeginUpdate( window ); // this sets up the visRgn
|
|
|
|
|
{
|
|
|
|
|
RgnHandle updateRgn = NewRgn();
|
|
|
|
|
WindowObjectPtr winObj = (WindowObjectPtr) GetWindowRefCon( window );
|
|
|
|
|
GetPortVisibleRegion( GetWindowPort( window ), updateRgn );
|
|
|
|
|
if( winObj ) error = winObj->Update( updateRgn );
|
|
|
|
|
DisposeRgn( updateRgn );
|
|
|
|
|
}
|
|
|
|
|
EndUpdate( window );
|
|
|
|
|
SetPort( oldPort );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** ACTIVATE EVENT OCCOURED ***/
|
|
|
|
|
OSStatus ActivateEventOccoured( EventRecord *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
WindowObjectPtr winObj = (WindowObjectPtr) GetWindowRefCon( (WindowRef) event->message );
|
|
|
|
|
if( winObj ) error = winObj->Activate( (Boolean) (event->modifiers & activeFlag) );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** IDLE EVENT ***/
|
|
|
|
|
OSStatus IdleEvent( void )
|
|
|
|
|
{
|
|
|
|
|
// call sound idle routine
|
|
|
|
|
if( g.asyncSound ) SHIdle();
|
|
|
|
|
|
|
|
|
|
// compact all memory
|
|
|
|
|
/* SInt32 total, contig;
|
|
|
|
|
PurgeMem( kEmergencyMemory );
|
|
|
|
|
CompactMem( kEmergencyMemory );
|
|
|
|
|
PurgeSpace( &total, &contig );
|
|
|
|
|
|
|
|
|
|
// deal with emergency memory
|
|
|
|
|
if( total < kMinimumFreeMemory && g.emergencyMemory )
|
|
|
|
|
{
|
|
|
|
|
DisposeHandle( g.emergencyMemory ); // release emergence memory
|
|
|
|
|
DisplayError( "\pMemory is running low, please close some windows." );
|
|
|
|
|
}
|
|
|
|
|
else if( !g.emergencyMemory && contig > kEmergencyMemory ) // try to recover handle if possible
|
|
|
|
|
g.emergencyMemory = NewHandleClear( kEmergencyMemory );
|
|
|
|
|
*/ return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*** QUIT RES KNIFE ***/
|
|
|
|
|
void QuitResKnife( void )
|
|
|
|
|
{
|
|
|
|
|
// save all open files
|
|
|
|
|
WindowRef window = FrontNonFloatingWindow(), nextWindow;
|
|
|
|
|
while( window )
|
|
|
|
|
{
|
|
|
|
|
nextWindow = GetNextWindow( window );
|
|
|
|
|
SInt32 kind = GetWindowKind( window );
|
|
|
|
|
if( kind == kFileWindowKind )
|
|
|
|
|
{
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
EventRef event;
|
|
|
|
|
CreateEvent( null, kEventClassWindow, kEventWindowClose, kEventDurationNoWait, kEventAttributeNone, &event );
|
|
|
|
|
SendEventToWindow( event, window );
|
|
|
|
|
ReleaseEvent( event );
|
|
|
|
|
#else
|
|
|
|
|
// bug: this is totally the wrong thing to do here, but will have to do for now
|
|
|
|
|
DisposeWindow( window ); // bug: windows don't close when sent a WindowClose event!
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
window = nextWindow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !g.cancelQuit )
|
|
|
|
|
{
|
|
|
|
|
if( g.asyncSound ) SHKillSoundHelper();
|
|
|
|
|
if( g.navAvailable ) NavUnload();
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
QuitApplicationEventLoop();
|
|
|
|
|
#else
|
|
|
|
|
g.quitting = true;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*******************/
|
|
|
|
|
/* MENU SELECTIONS */
|
|
|
|
|
/*******************/
|
|
|
|
|
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
|
|
|
|
|
/*** CARBON EVENT UPDATE MENUS ***/
|
|
|
|
|
pascal OSStatus CarbonEventUpdateMenus( EventHandlerCallRef callRef, EventRef event, void *userData )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( callRef, event, userData )
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
2002-12-31 19:06:40 +00:00
|
|
|
|
Boolean fileOpen = (Boolean) (FrontNonFloatingWindow() != NULL);
|
2001-10-19 19:41:13 +00:00
|
|
|
|
|
|
|
|
|
// application menu (passing null causes all menus to be searched)
|
|
|
|
|
EnableCommand( null, kMenuCommandAbout, true );
|
|
|
|
|
EnableCommand( null, kHICommandPreferences, true );
|
|
|
|
|
|
|
|
|
|
// file menu
|
|
|
|
|
EnableCommand( null, kMenuCommandNewFile, true );
|
|
|
|
|
EnableCommand( null, kMenuCommandOpenFile, true );
|
|
|
|
|
EnableCommand( null, kMenuCommandCloseWindow, fileOpen );
|
|
|
|
|
EnableCommand( null, kMenuCommandCloseFile, fileOpen );
|
|
|
|
|
EnableCommand( null, kMenuCommandSaveFile, fileOpen ); // bug: shoud be disabled if file is unmodified
|
|
|
|
|
EnableCommand( null, kMenuCommandSaveFileAs, fileOpen );
|
|
|
|
|
EnableCommand( null, kMenuCommandRevertFile, fileOpen );
|
|
|
|
|
EnableCommand( null, kMenuCommandPageSetup, fileOpen );
|
|
|
|
|
EnableCommand( null, kMenuCommandPrint, fileOpen );
|
|
|
|
|
|
|
|
|
|
/* if( fileOpen )
|
|
|
|
|
{
|
|
|
|
|
// edit window
|
|
|
|
|
EnableCommand( null, kHICommandUndo, false );
|
|
|
|
|
EnableCommand( null, kHICommandRedo, false );
|
|
|
|
|
EnableCommand( null, kHICommandCut, false );
|
|
|
|
|
EnableCommand( null, kHICommandCopy, false );
|
|
|
|
|
EnableCommand( null, kHICommandPaste, false );
|
|
|
|
|
EnableCommand( null, kHICommandClear, false );
|
|
|
|
|
EnableCommand( null, kHICommandSelectAll, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandFind, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandFindAgain, false );
|
|
|
|
|
|
|
|
|
|
// resource menu
|
|
|
|
|
EnableCommand( null, kMenuCommandNewResource, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandOpenHex, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandOpenDefault, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandOpenTemplate, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandOpenSpecific, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandRevertResource, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandPlaySound, false );
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
// debug menu
|
|
|
|
|
EnableCommand( null, kMenuCommandDebug, true );
|
|
|
|
|
EnableCommand( null, kMenuCommandAppleEvents, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandAppearance, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandNavServices, false );
|
|
|
|
|
EnableCommand( null, kMenuCommandSheets, g.carbonVersion >= kCarbonLib11 );
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandDebug, g.debug? kMenuCheckmarkGlyph : kMenuNullGlyph );
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandSurpressErrors, g.surpressErrors? kMenuCheckmarkGlyph : kMenuNullGlyph );
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandAppleEvents, g.useAppleEvents? kMenuCheckmarkGlyph : kMenuNullGlyph ); // these three should always be true in Carbon
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandAppearance, g.useAppearance? kMenuCheckmarkGlyph : kMenuNullGlyph );
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandNavServices, g.useNavServices? kMenuCheckmarkGlyph : kMenuNullGlyph );
|
|
|
|
|
SetMenuCommandMark( null, kMenuCommandSheets, g.useSheets? kMenuCheckmarkGlyph : kMenuNullGlyph );
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** CARBON EVENT PARSE MENU SELECTION ***/
|
|
|
|
|
pascal OSStatus CarbonEventParseMenuSelection( EventHandlerCallRef callRef, EventRef event, void *userData )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( callRef, userData )
|
|
|
|
|
|
|
|
|
|
// get menu command
|
|
|
|
|
HICommand menuCommand;
|
|
|
|
|
OSStatus error = GetEventParameter( event, kEventParamDirectObject, typeHICommand, null, sizeof(HICommand), null, &menuCommand );
|
|
|
|
|
if( error ) return eventNotHandledErr;
|
|
|
|
|
|
|
|
|
|
switch( menuCommand.commandID )
|
|
|
|
|
{
|
|
|
|
|
// application menu
|
|
|
|
|
case kMenuCommandAbout:
|
|
|
|
|
ShowAboutBox();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kHICommandPreferences:
|
|
|
|
|
ShowPrefsWindow();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// file menu
|
|
|
|
|
case kMenuCommandNewFile:
|
|
|
|
|
new FileWindow;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kMenuCommandOpenFile:
|
|
|
|
|
if( g.useSheets ) error = DisplayModelessGetFileDialog();
|
|
|
|
|
else error = DisplayOpenDialog();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
// debug menu
|
|
|
|
|
case kMenuCommandDebug:
|
|
|
|
|
g.debug = !g.debug;
|
|
|
|
|
break;
|
|
|
|
|
case kMenuCommandSurpressErrors:
|
|
|
|
|
g.surpressErrors = !g.surpressErrors;
|
|
|
|
|
break;
|
|
|
|
|
case kMenuCommandAppleEvents:
|
|
|
|
|
g.useAppleEvents = !g.useAppleEvents;
|
|
|
|
|
break;
|
|
|
|
|
case kMenuCommandAppearance:
|
|
|
|
|
g.useAppearance = !g.useAppearance;
|
|
|
|
|
break;
|
|
|
|
|
case kMenuCommandNavServices:
|
|
|
|
|
g.useNavServices = !g.useNavServices;
|
|
|
|
|
break;
|
|
|
|
|
case kMenuCommandSheets:
|
|
|
|
|
g.useSheets = !g.useSheets;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return eventNotHandledErr; // pass all other events
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return error; // event handled here, so terminate.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** DEFAULT IDLE TIMER ***/
|
|
|
|
|
pascal void DefaultIdleTimer( EventLoopTimerRef timer, void *data )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( timer, data )
|
|
|
|
|
|
|
|
|
|
// idle controls (allow cursor blinking)
|
|
|
|
|
IdleControls( GetUserFocusWindow() ); // bug: apple should have the control install it's own timer
|
|
|
|
|
|
|
|
|
|
// call sound idle routine
|
|
|
|
|
if( g.asyncSound && g.callSH ) SHIdle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
/*** UPDATE MENUS ***/
|
|
|
|
|
OSStatus UpdateMenus( WindowRef window )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( window )
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
|
|
|
|
|
// disable/checkmark items in the debug menu
|
|
|
|
|
MenuRef debugMenu = GetMenuRef( kDebugMenu );
|
|
|
|
|
MenuItemEnable( debugMenu, kDebugMenuAppearanceItem, g.appearanceAvailable );
|
|
|
|
|
MenuItemEnable( debugMenu, kDebugMenuNavServicesItem, g.navAvailable );
|
|
|
|
|
MenuItemEnable( debugMenu, kDebugMenuSheetsItem, false );
|
|
|
|
|
CheckMenuItem( debugMenu, kDebugMenuDebugItem, g.debug );
|
|
|
|
|
CheckMenuItem( debugMenu, kDebugMenuSurpressErrorsItem, g.surpressErrors );
|
|
|
|
|
CheckMenuItem( debugMenu, kDebugMenuAppleEventsItem, g.useAppleEvents );
|
|
|
|
|
CheckMenuItem( debugMenu, kDebugMenuAppearanceItem, g.useAppearance );
|
|
|
|
|
CheckMenuItem( debugMenu, kDebugMenuNavServicesItem, g.useNavServices );
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** PARSE MENU SELECTION ***/
|
|
|
|
|
OSStatus ParseMenuSelection( UInt16 menu, UInt16 item )
|
|
|
|
|
{
|
|
|
|
|
// get the frontmost window, in all it's various forms
|
|
|
|
|
OSStatus error = eventNotHandledErr;
|
|
|
|
|
WindowRef window = FrontWindow();
|
|
|
|
|
WindowObjectPtr winObj = null;
|
|
|
|
|
FileWindowPtr file = null;
|
|
|
|
|
if( window )
|
|
|
|
|
{
|
|
|
|
|
winObj = (WindowObjectPtr) GetWindowRefCon( window );
|
|
|
|
|
if( GetWindowKind( window ) == kFileWindowKind )
|
|
|
|
|
file = (FileWindowPtr) winObj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// do the menu function
|
|
|
|
|
if( menu && item )
|
|
|
|
|
{
|
|
|
|
|
switch( menu )
|
|
|
|
|
{
|
|
|
|
|
case kAppleMenu:
|
|
|
|
|
switch( item )
|
|
|
|
|
{
|
|
|
|
|
case kAppleMenuAboutItem:
|
|
|
|
|
ShowAboutBox();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default: // something from "apple menu items" folder
|
|
|
|
|
Str255 itemName;
|
|
|
|
|
MenuHandle appleMenu = GetMenuHandle( kAppleMenu );
|
|
|
|
|
GetMenuItemText( appleMenu, item, itemName );
|
|
|
|
|
OpenDeskAcc( itemName );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kFileMenu:
|
|
|
|
|
switch( item )
|
|
|
|
|
{
|
|
|
|
|
case kFileMenuNewFileItem:
|
|
|
|
|
new FileWindow;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kFileMenuOpenFileItem:
|
|
|
|
|
if( g.useNavServices ) DisplayOpenDialog();
|
|
|
|
|
else DisplayStandardFileOpenDialog();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kFileMenuCloseWindowItem:
|
|
|
|
|
if( winObj ) winObj->Close();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kFileMenuQuitItem:
|
|
|
|
|
AEDescList list = {};
|
|
|
|
|
error = AppleEventSendSelf( kCoreEventClass, kAEQuitApplication, list );
|
|
|
|
|
if( error ) QuitResKnife();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kEditMenu:
|
|
|
|
|
/* switch( item )
|
|
|
|
|
{
|
|
|
|
|
case :
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
*/ break;
|
|
|
|
|
|
|
|
|
|
case kResourceMenu:
|
|
|
|
|
switch( item )
|
|
|
|
|
{
|
|
|
|
|
case kResourceMenuNewResource:
|
|
|
|
|
if( file ) file->DisplayNewResourceDialog();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kDebugMenu:
|
|
|
|
|
switch( item )
|
|
|
|
|
{
|
|
|
|
|
case kDebugMenuDebugItem:
|
|
|
|
|
g.debug = !g.debug;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kDebugMenuSurpressErrorsItem:
|
|
|
|
|
g.surpressErrors = !g.surpressErrors;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kDebugMenuAppleEventsItem:
|
|
|
|
|
g.useAppleEvents = !g.useAppleEvents;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kDebugMenuAppearanceItem:
|
|
|
|
|
g.useAppearance = !g.useAppearance;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case kDebugMenuNavServicesItem:
|
|
|
|
|
g.useNavServices = !g.useNavServices;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
error = UpdateMenus( FrontWindow() );
|
|
|
|
|
}
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/****************/
|
|
|
|
|
/* APPLE EVENTS */
|
|
|
|
|
/****************/
|
|
|
|
|
|
|
|
|
|
/*** SEND MYSELF AN APPLE EVENT ***/
|
|
|
|
|
OSStatus AppleEventSendSelf( DescType eventClass, DescType eventID, AEDescList list )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error;
|
|
|
|
|
AEAddressDesc myAddress; // all of these are really of type AEDesc
|
|
|
|
|
AppleEvent noReply;
|
|
|
|
|
AppleEvent event;
|
|
|
|
|
|
|
|
|
|
myAddress.descriptorType = typeNull;
|
|
|
|
|
myAddress.dataHandle = null;
|
|
|
|
|
noReply.descriptorType = typeNull;
|
|
|
|
|
noReply.dataHandle = null;
|
|
|
|
|
|
|
|
|
|
ProcessSerialNumber psn;
|
|
|
|
|
error = GetCurrentProcess( &psn );
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
|
|
|
|
|
error = AECreateDesc( typeProcessSerialNumber, &psn, sizeof(ProcessSerialNumber), &myAddress );
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
|
|
|
|
|
error = AECreateAppleEvent( eventClass, eventID, &myAddress, kAutoGenerateReturnID, kAnyTransactionID, &event );
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
|
|
|
|
|
error = AEPutParamDesc( &event, keyDirectObject, &list );
|
|
|
|
|
if( error ) return error;
|
|
|
|
|
|
|
|
|
|
error = AESend( &event, &noReply, kAENoReply, kAENormalPriority, kAEDefaultTimeout, null, null );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** GOT REQUIRED PARAMS ***/
|
|
|
|
|
Boolean GotRequiredParams( const AppleEvent *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
DescType actualType;
|
|
|
|
|
Size actualSize;
|
|
|
|
|
|
|
|
|
|
// check if we have retreived the required parameters
|
|
|
|
|
error = AEGetAttributePtr( event, keyMissedKeywordAttr, typeWildCard, &actualType, null, 0, &actualSize );
|
|
|
|
|
return error == errAEDescNotFound;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** OPEN ***/
|
|
|
|
|
OSStatus AppleEventOpen( const AppleEvent *event )
|
|
|
|
|
{
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
|
|
|
|
|
// get the list of objects to open
|
|
|
|
|
AEDescList list;
|
|
|
|
|
AEKeyword aeKeyword;
|
|
|
|
|
aeKeyword = keyDirectObject;
|
|
|
|
|
error = AEGetParamDesc( event, aeKeyword, typeAEList, &list );
|
|
|
|
|
if( !GotRequiredParams( event ) || error ) return errAEEventNotHandled;
|
|
|
|
|
|
|
|
|
|
// count how many we have
|
|
|
|
|
SInt32 itemCount;
|
|
|
|
|
error = AECountItems( &list, &itemCount );
|
|
|
|
|
if( error ) return errAEEventNotHandled;
|
|
|
|
|
|
|
|
|
|
// open each one
|
|
|
|
|
FSSpec fileSpec;
|
|
|
|
|
DescType actualType;
|
|
|
|
|
Size actualSize;
|
|
|
|
|
for( SInt32 n = 1; n <= itemCount; n++ )
|
|
|
|
|
{
|
|
|
|
|
error = AEGetNthPtr( &list, n, typeFSS, &aeKeyword, &actualType, (Ptr) &fileSpec, sizeof(FSSpec), &actualSize );
|
|
|
|
|
if( actualType == typeFSS && !error ) new FileWindow( &fileSpec );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AEDisposeDesc( &list );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** PRINT ***/
|
|
|
|
|
OSStatus AppleEventPrint( const AppleEvent *event )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( event )
|
|
|
|
|
return errAEEventNotHandled;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/************************/
|
|
|
|
|
/* NIB WINDOW MANAGMENT */
|
|
|
|
|
/************************/
|
|
|
|
|
|
|
|
|
|
/*** SHOW ABOUT BOX ***/
|
|
|
|
|
OSStatus ShowAboutBox( void )
|
|
|
|
|
{
|
|
|
|
|
#if TARGET_API_MAC_CARBON
|
|
|
|
|
#if USE_NIBS
|
|
|
|
|
// create a nib reference (only searches the application bundle)
|
|
|
|
|
IBNibRef nibRef = null;
|
|
|
|
|
OSStatus error = CreateNibReference( CFSTR("ResKnife"), &nibRef );
|
|
|
|
|
if( error != noErr || nibRef == null )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pThe nib file reference could not be obtained." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create window
|
|
|
|
|
WindowRef window;
|
|
|
|
|
error = CreateWindowFromNib( nibRef, CFSTR("About Box"), &window );
|
|
|
|
|
if( error != noErr || window == null )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pThe about box could not be obtained from the nib file." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispose of nib ref
|
|
|
|
|
DisposeNibReference( nibRef );
|
|
|
|
|
|
|
|
|
|
// show window
|
|
|
|
|
ShowWindow( window );
|
|
|
|
|
#else
|
|
|
|
|
Rect creationBounds;
|
|
|
|
|
WindowRef window;
|
|
|
|
|
SetRect( &creationBounds, 0, 0, 300, 300 );
|
|
|
|
|
OffsetRect( &creationBounds, 50, 50 );
|
|
|
|
|
OSStatus error = CreateNewWindow( kDocumentWindowClass, kWindowStandardDocumentAttributes | kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute, &creationBounds, &window );
|
2002-12-31 19:06:40 +00:00
|
|
|
|
if( error ) return error;
|
2001-10-19 19:41:13 +00:00
|
|
|
|
|
|
|
|
|
ControlRef picControl;
|
|
|
|
|
ControlButtonContentInfo content;
|
|
|
|
|
/* content.contentType = kControlContentPictHandle;
|
|
|
|
|
content.u.picture = GetPicture( 128 );
|
|
|
|
|
if( content.u.picture == null ) DebugStr("\ppicture == null");
|
|
|
|
|
*/ content.contentType = kControlContentPictRes;
|
|
|
|
|
content.u.resID = 128;
|
|
|
|
|
CreatePictureControl( window, &creationBounds, &content, true, &picControl );
|
|
|
|
|
// SetControlData( picControl, kControlPicturePart, kControlPictureHandleTag, sizeof(content.u.picture), content.u.picture );
|
|
|
|
|
#endif
|
|
|
|
|
#else
|
|
|
|
|
WindowRef window = null;
|
2002-02-02 11:31:28 +00:00
|
|
|
|
if( g.useAppearance && g.systemVersion >= kMacOS8 )
|
2001-10-19 19:41:13 +00:00
|
|
|
|
window = GetNewCWindow( kFileWindow8, null, kFirstWindowOfClass );
|
|
|
|
|
else
|
|
|
|
|
window = GetNewCWindow( kFileWindow7, null, kFirstWindowOfClass );
|
|
|
|
|
if( window == null ) return paramErr;
|
|
|
|
|
PicHandle picture = (PicHandle) GetPicture( 128 );
|
|
|
|
|
SetWindowPic( window, picture );
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ShowWindow( window );
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** SHOW PREFERENCES WINDOW ***/
|
|
|
|
|
OSStatus ShowPrefsWindow( void )
|
|
|
|
|
{
|
|
|
|
|
#if USE_NIBS
|
|
|
|
|
// create a nib reference (only searches the application bundle)
|
|
|
|
|
IBNibRef nibRef = null;
|
|
|
|
|
OSStatus error = CreateNibReference( CFSTR("ResKnife"), &nibRef );
|
|
|
|
|
if( error != noErr || nibRef == null )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pThe nib file reference could not be obtained." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// create window
|
|
|
|
|
WindowRef window;
|
|
|
|
|
error = CreateWindowFromNib( nibRef, CFSTR("Preferences"), &window );
|
|
|
|
|
if( error != noErr || window == null )
|
|
|
|
|
{
|
|
|
|
|
DisplayError( "\pThe preferences window could not be obtained from the nib file." );
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// dispose of nib ref
|
|
|
|
|
DisposeNibReference( nibRef );
|
|
|
|
|
|
|
|
|
|
// install tabs handler
|
|
|
|
|
ControlRef control;
|
|
|
|
|
ControlID id = { 'tabs', 1 };
|
|
|
|
|
GetControlByID( window, &id, &control );
|
|
|
|
|
EventTypeSpec event = { kEventClassControl, kEventControlHit };
|
|
|
|
|
InstallEventHandler( GetControlEventTarget(control), NewEventHandlerUPP( PrefsTabEventHandler ), 1, &event, &control, null );
|
|
|
|
|
|
|
|
|
|
// show window
|
|
|
|
|
ShowWindow( window );
|
|
|
|
|
#endif
|
|
|
|
|
return noErr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*** PREFS TAB EVENT HANDLER ***/
|
|
|
|
|
pascal OSStatus PrefsTabEventHandler( EventHandlerCallRef handlerRef, EventRef event, void* userData )
|
|
|
|
|
{
|
|
|
|
|
#pragma unused( handlerRef, event )
|
|
|
|
|
|
|
|
|
|
// get tabs control
|
|
|
|
|
OSStatus error = noErr;
|
|
|
|
|
ControlRef control = (ControlRef) userData;
|
|
|
|
|
SInt16 selectedTab = GetControlValue( control );
|
|
|
|
|
WindowRef window = GetControlOwner( control );
|
|
|
|
|
|
|
|
|
|
// select correct tab
|
|
|
|
|
ControlRef currentTab;
|
|
|
|
|
ControlID id = { 'pane', 1 };
|
|
|
|
|
GetControlByID( window, &id, ¤tTab );
|
|
|
|
|
SetControlVisibility( currentTab, selectedTab == id.id, true );
|
|
|
|
|
id.id = 2;
|
|
|
|
|
GetControlByID( window, &id, ¤tTab );
|
|
|
|
|
SetControlVisibility( currentTab, selectedTab == id.id, true );
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|