mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-11 02:10:17 +01:00
939 lines
25 KiB
C++
939 lines
25 KiB
C++
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|||
|
/* ***** BEGIN LICENSE BLOCK *****
|
|||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|||
|
*
|
|||
|
* The contents of this file are subject to the Mozilla Public License Version
|
|||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|||
|
* the License. You may obtain a copy of the License at
|
|||
|
* http://www.mozilla.org/MPL/
|
|||
|
*
|
|||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|||
|
* for the specific language governing rights and limitations under the
|
|||
|
* License.
|
|||
|
*
|
|||
|
* The Original Code is Mozilla Communicator client code.
|
|||
|
*
|
|||
|
* The Initial Developer of the Original Code is
|
|||
|
* Netscape Communications Corporation.
|
|||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|||
|
* the Initial Developer. All Rights Reserved.
|
|||
|
*
|
|||
|
* Contributor(s):
|
|||
|
* Simon Fraser <sfraser@netscape.com>
|
|||
|
*
|
|||
|
* Alternatively, the contents of this file may be used under the terms of
|
|||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
|||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|||
|
* of those above. If you wish to allow use of your version of this file only
|
|||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|||
|
* use your version of this file under the terms of the MPL, indicate your
|
|||
|
* decision by deleting the provisions above and replace them with the notice
|
|||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|||
|
* the provisions above, a recipient may use your version of this file under
|
|||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|||
|
*
|
|||
|
* ***** END LICENSE BLOCK ***** */
|
|||
|
|
|||
|
|
|||
|
#include <Sound.h>
|
|||
|
#include <Scrap.h>
|
|||
|
|
|||
|
#include "nsAEUtils.h"
|
|||
|
#include "nsAETokens.h"
|
|||
|
#include "nsAECoreClass.h"
|
|||
|
#include "nsAEDocumentClass.h"
|
|||
|
#include "nsAEWindowClass.h"
|
|||
|
|
|||
|
#include "nsAEApplicationClass.h"
|
|||
|
|
|||
|
#include "nsINativeAppSupport.h"
|
|||
|
#include "nsCommandLineServiceMac.h"
|
|||
|
#include "nsCOMPtr.h"
|
|||
|
#include "nsIAppStartup.h"
|
|||
|
#include "nsXPFEComponentsCID.h"
|
|||
|
|
|||
|
#include "nsComponentManagerUtils.h"
|
|||
|
#include "nsServiceManagerUtils.h"
|
|||
|
|
|||
|
#ifdef MOZ_XUL_APP
|
|||
|
#include "nsAppRunner.h"
|
|||
|
#endif
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
AEApplicationClass
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
AEApplicationClass::AEApplicationClass()
|
|||
|
: AEGenericClass(cApplication, typeNull)
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
~AEApplicationClass
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
AEApplicationClass::~AEApplicationClass()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
GetPropertyFromApp
|
|||
|
|
|||
|
Override default to customize behaviour.
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::GetProperty( DescType desiredClass,
|
|||
|
const AEDesc* containerToken,
|
|||
|
DescType containerClass,
|
|||
|
DescType keyForm,
|
|||
|
const AEDesc* keyData,
|
|||
|
AEDesc* resultToken)
|
|||
|
{
|
|||
|
OSErr err;
|
|||
|
CoreTokenRecord token;
|
|||
|
DescType requestedProperty = **(DescType**)keyData->dataHandle;
|
|||
|
|
|||
|
token.dispatchClass = GetClass();
|
|||
|
token.objectClass = GetClass();
|
|||
|
token.propertyCode = requestedProperty;
|
|||
|
|
|||
|
if (CanGetProperty(requestedProperty) || CanSetProperty(requestedProperty))
|
|||
|
{
|
|||
|
err = AECreateDesc(cProperty, (Ptr)&token, sizeof(CoreTokenRecord), resultToken);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
GetItemFromContainer
|
|||
|
|
|||
|
Not appropriate for the application
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::GetItemFromContainer( DescType desiredClass,
|
|||
|
const AEDesc* containerToken,
|
|||
|
DescType containerClass,
|
|||
|
DescType keyForm,
|
|||
|
const AEDesc* keyData,
|
|||
|
AEDesc* resultToken)
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleClose
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
|
|||
|
StAEDesc saving;
|
|||
|
StAEDesc savingIn;
|
|||
|
|
|||
|
// Extract the [saving yes/no/ask] optional parameter, if present
|
|||
|
err = AEGetParamDesc(appleEvent,
|
|||
|
keyAESaveOptions,
|
|||
|
typeWildCard,
|
|||
|
&saving);
|
|||
|
|
|||
|
if (err != errAEDescNotFound)
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
// Extract the [saving in <alias>] optional parameter, if present
|
|||
|
err = AEGetParamDesc(appleEvent,
|
|||
|
keyAEFile,
|
|||
|
typeWildCard,
|
|||
|
&savingIn);
|
|||
|
|
|||
|
if (err != errAEDescNotFound)
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
// Check for any required parameters we may have missed
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
// Now, do the application-related work
|
|||
|
SysBeep(2);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleCount
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
long numberOfObjects = 0L;
|
|||
|
|
|||
|
DescType objectClass;
|
|||
|
|
|||
|
if (!reply->dataHandle)
|
|||
|
return;
|
|||
|
|
|||
|
// Get the class of object that we will count
|
|||
|
err = GetObjectClassFromAppleEvent(appleEvent, &objectClass);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
// Make sure we got & handled all of the required paramters
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
// Send back the results
|
|||
|
numberOfObjects = CountApplicationObjects(token, objectClass);
|
|||
|
err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&numberOfObjects, sizeof(long));
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleDataSize
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
StAEDesc data;
|
|||
|
long size = 0L;
|
|||
|
|
|||
|
// First, get the data
|
|||
|
HandleGetData(token, appleEvent, reply);
|
|||
|
|
|||
|
// now, extract it from the reply
|
|||
|
err = AEGetKeyDesc(reply, keyDirectObject, typeWildCard, &data);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
size = data.GetDataSize();
|
|||
|
|
|||
|
// do we leak all the data here?
|
|||
|
err = AEPutParamPtr(reply,
|
|||
|
keyAEResult,
|
|||
|
typeLongInteger,
|
|||
|
(Ptr)&size,
|
|||
|
sizeof(long));
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleDelete
|
|||
|
|
|||
|
All attempts to delete an empty list are handled here
|
|||
|
Application contains documents and windows, and they can't be deleted
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
|
|||
|
if (AEListUtils::TokenContainsTokenList(token))
|
|||
|
{
|
|||
|
long numItems;
|
|||
|
|
|||
|
AECountItems(token, &numItems);
|
|||
|
|
|||
|
if (numItems > 0)
|
|||
|
err = errAEEventNotHandled;
|
|||
|
}
|
|||
|
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleDuplicate
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleExists
|
|||
|
|
|||
|
If <referenceToObject> exists...
|
|||
|
The AEResolve() function in AERCoreSuite.c will already have filtered
|
|||
|
out all cases where the object did not exist, so this function should
|
|||
|
always return TRUE.
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
Boolean foundIt = true;
|
|||
|
|
|||
|
err = AEPutParamPtr(reply,
|
|||
|
keyAEResult,
|
|||
|
typeBoolean,
|
|||
|
(Ptr)&foundIt,
|
|||
|
sizeof(Boolean));
|
|||
|
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleMake
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleMove
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleRun
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
|
|||
|
// do stuff on startup that we want to do
|
|||
|
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleReOpen
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleReOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
nsresult rv = NS_OK;
|
|||
|
nsCOMPtr<nsINativeAppSupport> nas;
|
|||
|
|
|||
|
#ifdef MOZ_XUL_APP
|
|||
|
nas = do_CreateInstance(NS_NATIVEAPPSUPPORT_CONTRACTID);
|
|||
|
if (!nas) ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
#else
|
|||
|
nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
|
|||
|
NS_WARN_IF_FALSE(appStartup, "Failed to get appstartup service");
|
|||
|
if(!appStartup) ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
|
|||
|
rv = appStartup->GetNativeAppSupport(getter_AddRefs(nas));
|
|||
|
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to get NativeAppSupport");
|
|||
|
if(NS_FAILED(rv)) ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
#endif
|
|||
|
|
|||
|
rv = nas->ReOpen();
|
|||
|
if(NS_FAILED(rv)) ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleOpen
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err;
|
|||
|
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
long numItems, i;
|
|||
|
Boolean openedGroups = false;
|
|||
|
|
|||
|
err = ::AECountItems(token, &numItems);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
for (i = 1; i <= numItems; i++)
|
|||
|
{
|
|||
|
FSSpec fSpec;
|
|||
|
FInfo fndrInfo;
|
|||
|
AEKeyword keywd;
|
|||
|
DescType returnedType;
|
|||
|
Size actualSize;
|
|||
|
|
|||
|
err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
err = ::FSpGetFInfo(&fSpec, &fndrInfo);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
|
|||
|
cmdLine.HandleOpenOneDoc(fSpec, fndrInfo.fdType);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandlePrint
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err=noErr;
|
|||
|
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
long numItems, i;
|
|||
|
Boolean openedGroups = false;
|
|||
|
|
|||
|
err = ::AECountItems(token, &numItems);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
for (i = 1; i <= numItems; i++)
|
|||
|
{
|
|||
|
FSSpec fSpec;
|
|||
|
FInfo fndrInfo;
|
|||
|
AEKeyword keywd;
|
|||
|
DescType returnedType;
|
|||
|
Size actualSize;
|
|||
|
|
|||
|
err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
err = ::FSpGetFInfo(&fSpec, &fndrInfo);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
|
|||
|
cmdLine.HandlePrintOneDoc(fSpec, fndrInfo.fdType);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleQuit
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
// get optional saving param
|
|||
|
StAEDesc savingParam;
|
|||
|
TAskSave askSave = eSaveUnspecified;
|
|||
|
|
|||
|
OSErr err = ::AEGetKeyDesc(appleEvent, keyAESaveOptions, typeEnumeration, &savingParam);
|
|||
|
if (err != errAEDescNotFound)
|
|||
|
{
|
|||
|
DescType enumValue = savingParam.GetEnumType();
|
|||
|
|
|||
|
switch (enumValue)
|
|||
|
{
|
|||
|
case 'yes ': askSave = eSaveYes; break;
|
|||
|
case 'no ': askSave = eSaveNo; break;
|
|||
|
case 'ask ': askSave = eSaveAsk; break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
err = CheckForUnusedParameters(appleEvent);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
nsMacCommandLine& cmdLine = nsMacCommandLine::GetMacCommandLine();
|
|||
|
err = cmdLine.Quit(askSave);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleSave
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
HandleSetData
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
StAEDesc tokenData;
|
|||
|
AETokenDesc tokenDesc(token);
|
|||
|
DescType propertyCode;
|
|||
|
|
|||
|
if (token->descriptorType == cProperty)
|
|||
|
{
|
|||
|
propertyCode = tokenDesc.GetPropertyCode();
|
|||
|
|
|||
|
if (CanSetProperty(propertyCode))
|
|||
|
{
|
|||
|
// only the clipboard property is writeable
|
|||
|
// the clipboard data should be in a list, so we extract that list
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
case pClipboard:
|
|||
|
err = AEGetKeyDesc(appleEvent, keyAEData, typeAEList, &tokenData);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
SetDataForObject(token, &tokenData); // may throw
|
|||
|
|
|||
|
err = AEPutKeyDesc(reply, keyDirectObject, &tokenData); // return the requested data
|
|||
|
ThrowIfOSErr(err);
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
ThrowIfOSErr(errAENotModifiable); // "Can't set xxx to nnn"
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAENotModifiable);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ThrowIfOSErr(errAEEventNotHandled);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
CountObjects
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::CountObjects( DescType desiredType,
|
|||
|
DescType containerClass,
|
|||
|
const AEDesc * container,
|
|||
|
long * result)
|
|||
|
{
|
|||
|
long numberOfObjects = CountApplicationObjects(container, desiredType);
|
|||
|
*result = numberOfObjects;
|
|||
|
}
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
GetDataFromObject
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
|
|||
|
Str255 applicationName = "\p";
|
|||
|
Str255 versionString;
|
|||
|
|
|||
|
ConstAETokenDesc tokenDesc(token);
|
|||
|
|
|||
|
ProcessSerialNumber applicationProcessNumber;
|
|||
|
ProcessInfoRec applicationInfo;
|
|||
|
FSSpec appFSSpec;
|
|||
|
|
|||
|
Boolean isFrontProcess = true; // <20><><EFBFBD> !gInBackground;
|
|||
|
|
|||
|
DescType aDescType = cApplication;
|
|||
|
|
|||
|
long documentNumber = 0L;
|
|||
|
unsigned long elementNumber = 0L;
|
|||
|
|
|||
|
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
|
|||
|
DescType propertyCode;
|
|||
|
|
|||
|
long free;
|
|||
|
long contiguous;
|
|||
|
unsigned long ticks;
|
|||
|
|
|||
|
err = GetCurrentProcess(&applicationProcessNumber);
|
|||
|
|
|||
|
if (err == noErr)
|
|||
|
{
|
|||
|
applicationInfo.processInfoLength = sizeof(ProcessInfoRec);
|
|||
|
applicationInfo.processName = applicationName;
|
|||
|
applicationInfo.processAppSpec = &appFSSpec;
|
|||
|
err = GetProcessInformation(&applicationProcessNumber, &applicationInfo);
|
|||
|
}
|
|||
|
|
|||
|
GetShortVersionString(2, versionString);
|
|||
|
PurgeSpace(&free, &contiguous);
|
|||
|
|
|||
|
ticks = TickCount();
|
|||
|
|
|||
|
propertyCode = tokenDesc.GetPropertyCode();
|
|||
|
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
case pProperties:
|
|||
|
err = AECreateList(nil, 0, true, data);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
err = AEPutKeyPtr(data, pObjectType, typeType, &aDescType, sizeof(DescType));
|
|||
|
err = AEPutKeyPtr(data, pName, typeChar, &applicationName[1], applicationName[0]);
|
|||
|
err = AEPutKeyPtr(data, pVersion, typeChar, &versionString[1], versionString[0]);
|
|||
|
err = AEPutKeyPtr(data, pIsFrontProcess, typeBoolean, &isFrontProcess, sizeof(Boolean));
|
|||
|
err = AEPutKeyPtr(data, pFreeMemory, typeLongInteger, &free, sizeof(long));
|
|||
|
err = AEPutKeyPtr(data, pLargestFreeBlock, typeLongInteger, &contiguous, sizeof(long));
|
|||
|
err = AEPutKeyPtr(data, pTicks, typeLongInteger, &ticks, sizeof(long));
|
|||
|
break;
|
|||
|
|
|||
|
case pBestType:
|
|||
|
case pClass:
|
|||
|
case pDefaultType:
|
|||
|
case pObjectType:
|
|||
|
err = AECreateDesc(typeType, &aDescType, sizeof(DescType), data);
|
|||
|
break;
|
|||
|
|
|||
|
case pName:
|
|||
|
err = AECreateDesc(typeChar, &applicationName[1], applicationName[0], data);
|
|||
|
break;
|
|||
|
|
|||
|
case pVersion:
|
|||
|
err = AECreateDesc(typeChar, &versionString[1], versionString[0], data);
|
|||
|
break;
|
|||
|
|
|||
|
case pIsFrontProcess:
|
|||
|
err = AECreateDesc(typeBoolean, &isFrontProcess, sizeof(Boolean), data);
|
|||
|
break;
|
|||
|
|
|||
|
case pFreeMemory:
|
|||
|
err = AECreateDesc(typeLongInteger, &free, sizeof(long), data);
|
|||
|
break;
|
|||
|
|
|||
|
case pLargestFreeBlock:
|
|||
|
err = AECreateDesc(typeLongInteger, &contiguous, sizeof(long), data);
|
|||
|
break;
|
|||
|
|
|||
|
case pTicks:
|
|||
|
err = AECreateDesc(typeLongInteger, &ticks, sizeof(long), data);
|
|||
|
break;
|
|||
|
|
|||
|
case pClipboard:
|
|||
|
#if !TARGET_CARBON
|
|||
|
{
|
|||
|
// Return all of the items currently on the clipboard.
|
|||
|
// The returned information is an AEList, and each data type
|
|||
|
// on the scrap gets its own entry in the list
|
|||
|
// Since the OS doesn't supply the tools for getting all
|
|||
|
// of the types in the scrap, we have to scan the scrap ourselves
|
|||
|
|
|||
|
char *scrapPtr;
|
|||
|
char *scrapEnd;
|
|||
|
PScrapStuff scrapInfo;
|
|||
|
OSType itemType;
|
|||
|
long itemLength;
|
|||
|
long index;
|
|||
|
|
|||
|
err = AECreateList(NULL, 0, false, data);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
err = LoadScrap(); // Make sure the scrap is in memory, not on disk.
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
scrapInfo = InfoScrap(); // Get the base address of the scrap in RAM
|
|||
|
MoveHHi(scrapInfo->scrapHandle);
|
|||
|
HLock (scrapInfo->scrapHandle); // ...and lock it
|
|||
|
|
|||
|
scrapPtr = (char *)*scrapInfo->scrapHandle;
|
|||
|
scrapEnd = scrapPtr + scrapInfo->scrapSize;
|
|||
|
|
|||
|
// scan the scrap in memory and extract each scrap type
|
|||
|
|
|||
|
index = 1;
|
|||
|
while (scrapPtr < scrapEnd)
|
|||
|
{
|
|||
|
itemType = *(OSType *)scrapPtr;
|
|||
|
scrapPtr += sizeof(itemType);
|
|||
|
itemLength = *(long *)scrapPtr;
|
|||
|
scrapPtr += sizeof(itemLength);
|
|||
|
|
|||
|
// Move this information into the next entry on the list
|
|||
|
err = AEPutPtr(data, index, itemType, scrapPtr, itemLength);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
index++;
|
|||
|
|
|||
|
// Adjust the pointer to the start of the next item
|
|||
|
|
|||
|
if (itemLength & 1)
|
|||
|
itemLength++; // If it's odd, make it even
|
|||
|
|
|||
|
scrapPtr += itemLength;
|
|||
|
}
|
|||
|
HUnlock (scrapInfo->scrapHandle);
|
|||
|
}
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
Inherited::GetDataFromObject(token, desiredTypes, data);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
SetDataForObject
|
|||
|
|
|||
|
Assumption: HandleSetData() has already filtered out all attempts
|
|||
|
to write to a read-only property.
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::SetDataForObject(const AEDesc *token, AEDesc *data)
|
|||
|
{
|
|||
|
OSErr err = noErr;
|
|||
|
ConstAETokenDesc tokenDesc(token);
|
|||
|
Boolean usePropertyCode = tokenDesc.UsePropertyCode();
|
|||
|
DescType propertyCode;
|
|||
|
|
|||
|
if (usePropertyCode)
|
|||
|
{
|
|||
|
propertyCode = tokenDesc.GetPropertyCode();
|
|||
|
|
|||
|
#if !TARGET_CARBON
|
|||
|
long numItems;
|
|||
|
#endif
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
// the clipboard is the only writeable property for the application object
|
|||
|
case pClipboard:
|
|||
|
// The data should be an AE list containing a series of things to be placed on the
|
|||
|
// clipboard. The data type of each item is also the clipboard type for that data
|
|||
|
#if !TARGET_CARBON
|
|||
|
err = ZeroScrap();
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
AECountItems(data, &numItems);
|
|||
|
|
|||
|
// Copy each item onto the clipboard
|
|||
|
|
|||
|
for (long index = 1; index <= numItems; index++)
|
|||
|
{
|
|||
|
StAEDesc currentItemDesc;
|
|||
|
AEKeyword theAEKeyword;
|
|||
|
err = AEGetNthDesc(data, index, typeWildCard, &theAEKeyword, ¤tItemDesc);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
|
|||
|
HLock(currentItemDesc.dataHandle);
|
|||
|
err = PutScrap(GetHandleSize(currentItemDesc.dataHandle),
|
|||
|
currentItemDesc.descriptorType,
|
|||
|
*currentItemDesc.dataHandle);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
#endif
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
ThrowIfOSErr(errAENotModifiable);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
GetKeyEventDataAs
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
DescType AEApplicationClass::GetKeyEventDataAs(DescType propertyCode)
|
|||
|
{
|
|||
|
DescType returnType;
|
|||
|
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
case pClipboard:
|
|||
|
returnType = typeAEList;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
returnType = typeWildCard;
|
|||
|
|
|||
|
}
|
|||
|
return returnType;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
CanSetProperty
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
Boolean AEApplicationClass::CanSetProperty(DescType propertyCode)
|
|||
|
{
|
|||
|
Boolean result = false;
|
|||
|
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
// Properties we can set:
|
|||
|
|
|||
|
case pClipboard:
|
|||
|
result = true;
|
|||
|
break;
|
|||
|
|
|||
|
// Properties we should be able to set, but they're not implemented yet:
|
|||
|
|
|||
|
|
|||
|
// Properties that are read-only
|
|||
|
|
|||
|
case pBestType:
|
|||
|
case pClass:
|
|||
|
case pDefaultType:
|
|||
|
case pObjectType:
|
|||
|
|
|||
|
case pProperties:
|
|||
|
|
|||
|
case pFreeMemory:
|
|||
|
case pLargestFreeBlock:
|
|||
|
case pTicks:
|
|||
|
|
|||
|
case pIsFrontProcess:
|
|||
|
case pName:
|
|||
|
case pVersion:
|
|||
|
case pInsertionLoc:
|
|||
|
case pSelection:
|
|||
|
case pUserSelection:
|
|||
|
result = false;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
result = Inherited::CanSetProperty(propertyCode);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
CanGetProperty
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
Boolean AEApplicationClass::CanGetProperty(DescType propertyCode)
|
|||
|
{
|
|||
|
Boolean result = false;
|
|||
|
|
|||
|
switch (propertyCode)
|
|||
|
{
|
|||
|
// Properties we can get:
|
|||
|
|
|||
|
case pBestType:
|
|||
|
case pClass:
|
|||
|
case pDefaultType:
|
|||
|
case pObjectType:
|
|||
|
|
|||
|
case pProperties:
|
|||
|
|
|||
|
case pFreeMemory:
|
|||
|
case pLargestFreeBlock:
|
|||
|
case pTicks:
|
|||
|
|
|||
|
case pIsFrontProcess:
|
|||
|
case pName:
|
|||
|
case pVersion:
|
|||
|
case pInsertionLoc:
|
|||
|
case pSelection:
|
|||
|
case pUserSelection:
|
|||
|
result = true;
|
|||
|
break;
|
|||
|
|
|||
|
// Properties we should be able to get, but they're not implemented yet:
|
|||
|
|
|||
|
// Properties we should not be able to get:
|
|||
|
|
|||
|
default:
|
|||
|
result = Inherited::CanGetProperty(propertyCode);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
CreateSelfSpecifier
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
void AEApplicationClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
|
|||
|
{
|
|||
|
OSErr err = ::AECreateDesc(typeNull, nil, 0, outSpecifier);
|
|||
|
ThrowIfOSErr(err);
|
|||
|
}
|
|||
|
|
|||
|
#pragma mark -
|
|||
|
|
|||
|
/*----------------------------------------------------------------------------
|
|||
|
CountApplicationObjects
|
|||
|
|
|||
|
----------------------------------------------------------------------------*/
|
|||
|
long AEApplicationClass::CountApplicationObjects(const AEDesc *token, DescType desiredType)
|
|||
|
{
|
|||
|
long numberOfObjects = 0;
|
|||
|
OSErr err = noErr;
|
|||
|
|
|||
|
if (AEListUtils::TokenContainsTokenList(token))
|
|||
|
{
|
|||
|
err = AECountItems(token, &numberOfObjects);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
AEDispatchHandler* countHandler = AECoreClass::sAECoreHandler->GetDispatchHandler(desiredType);
|
|||
|
if (countHandler == nil)
|
|||
|
ThrowOSErr(errAEEventNotHandled);
|
|||
|
|
|||
|
countHandler->CountObjects(desiredType, typeNull, token, &numberOfObjects);
|
|||
|
/*
|
|||
|
switch (desiredType)
|
|||
|
{
|
|||
|
case cDocument:
|
|||
|
numberOfObjects = AEDocumentClass::CountDocuments();
|
|||
|
break;
|
|||
|
|
|||
|
case cWindow:
|
|||
|
numberOfObjects = AEWindowClass::CountWindows(kAnyWindowKind);
|
|||
|
break;
|
|||
|
|
|||
|
// application specific classes
|
|||
|
case cGroupWindow:
|
|||
|
numberOfObjects = AEWindowClass::CountWindows(kUserGroupWindowKind);
|
|||
|
break;
|
|||
|
|
|||
|
|
|||
|
default:
|
|||
|
err = errAEEventNotHandled;
|
|||
|
break;
|
|||
|
}
|
|||
|
*/
|
|||
|
}
|
|||
|
|
|||
|
ThrowIfOSErr(err);
|
|||
|
return numberOfObjects;
|
|||
|
}
|