JPEGView/Source/C/cDocument.c
Aaron Giles 92bdb55672 JPEGView 3.3 for Macintosh
These are the sources for the final official release of JPEGView for the
Mac, back in 1994.
2015-02-05 00:18:10 -08:00

1 line
13 KiB
C

/*********************************************************/
/* This source code copyright (c) 1991-2001, Aaron Giles */
/* See the Read Me file for licensing information. */
/* Contact email: mac@aarongiles.com */
/*********************************************************/
#if THINK_C
#include "THINK.Header"
#elif applec
#pragma load ":Headers:MPW.Header"
#elif __MWERKS__
//#include "MW.Header"
#else
#include "JPEGView.h"
#endif
/*
* DocumentAccessor(classWanted, container, containerClass, keyForm, keyData,
* resultToken, theRefCon)
*
* Purpose: Finds a document according to the specified keyForm and returns the
* corresponding document token
* Inputs: classWanted = the element class desired (cDocument)
* container = token for this element's container
* containerClass = class of this element's container (typeNull/cWindow)
* keyForm = the search key type
* keyData = descriptor containing search key data
* resultToken = descriptor containing the resulting token
* theRefCon = reference constant
* Returns: an OSErr describing the result
*
*/
pascal OSErr DocumentAccessor(DescType classWanted, AEDesc *container,
DescType containerClass, DescType keyForm, AEDesc *keyData,
AEDesc *resultToken, long theRefCon)
{
#if applec
#pragma unused (classWanted, theRefCon)
#endif
ObjectTokenHandle theList;
OSErr theErr = noErr;
if (containerClass == cWindow) {
if (IsValidForOne(keyForm, keyData)) {
if ((theErr = HandToHand((Handle *)&theList)) != noErr) return theErr;
PurgeNonDocuments(theList);
} else return errAENoSuchObject;
} else {
switch (containerClass) {
case cDocument:
theList = (ObjectTokenHandle)container->dataHandle;
if ((theErr = HandToHand((Handle *)&theList)) != noErr) return theErr;
break;
case typeNull:
if (!(theList = MakeAllWindowsToken())) return memFullErr;
PurgeNonDocuments(theList);
break;
default:
return errAENoSuchObject;
}
switch (keyForm) {
case formAbsolutePosition:
theErr = GetAbsoluteWindow(keyData, &theList);
break;
case formName:
theErr = GetNamedDocument(keyData, &theList);
break;
case formRelativePosition:
case formTest:
case formRange:
case formPropertyID:
default:
return errAEBadKeyForm;
break;
}
}
if (!theList || !(*theList)->count || (theErr != noErr)) {
DisposeHandle((Handle)theList);
if (theErr == noErr) theErr = errAENoSuchObject;
} else {
theErr = AECreateHandleDesc(cDocument, (Handle)theList, resultToken);
DisposeHandle((Handle)theList);
}
return theErr;
}
/*
* DocPropertyAccessor(classWanted, container, containerClass, keyForm, keyData,
* resultToken, theRefCon)
*
* Purpose: Finds a document property and returns the corresponding property token
* Inputs: classWanted = the element class desired (typeProperty)
* container = token for this element's container
* containerClass = class of this element's container (cDocument)
* keyForm = the search key type
* keyData = descriptor containing search key data
* resultToken = descriptor containing the resulting token
* theRefCon = reference constant
* Returns: an OSErr describing the result
*
*/
pascal OSErr DocPropertyAccessor(DescType classWanted, AEDesc *container,
DescType containerClass, DescType keyForm, AEDesc *keyData,
AEDesc *resultToken, long theRefCon)
{
#if applec
#pragma unused (classWanted, containerClass, theRefCon)
#endif
ObjectTokenHandle theList = (ObjectTokenHandle)container->dataHandle;
DescType propertyType;
OSErr theErr;
if ((keyForm != formPropertyID) || (keyData->descriptorType != typeType))
return errAECantSupplyType;
propertyType = *(DescType *)*keyData->dataHandle;
switch (propertyType) {
// Non-modifiable properties
case pBestType:
case pClass:
case pDefaultType:
case pIsModified:
case pSelection:
// Modifiable properties
case pName:
break;
default:
return errAEEventNotHandled;
}
theErr = HandToHand((Handle *)&theList);
if (theErr != noErr) return theErr;
(*theList)->property = propertyType;
(*theList)->objclass = cDocument;
theErr = AECreateHandleDesc(typeProperty, (Handle)theList, resultToken);
DisposeHandle((Handle)theList);
return theErr;
}
/*
* GetDocumentData(theWindow, typeWanted, theData)
*
* Purpose: Extracts the data from the document
* Inputs: theWindow = the window associated with this object
* typeWanted = the type we're asking for
* theData = the data we save
* Returns: an OSErr describing the result
*
*/
OSErr GetDocumentData(WindowPtr theWindow, DescType typeWanted, AEDesc *theData)
{
if (typeWanted == typeWildCard) typeWanted = typeObjectSpecifier;
if (typeWanted == typeBest) typeWanted = typeObjectSpecifier;
if (typeWanted != typeObjectSpecifier) return errAECantSupplyType;
return MakeDocumentObject(theWindow, theData);
}
/*
* GetDocPropertyData(theWindow, theProperty, typeWanted, theData)
*
* Purpose: Extracts the data from the document's properties
* Inputs: theWindow = the window associated with this object
* theProperty = the property wanted
* typeWanted = the type we're asking for
* theData = the data we save
* Returns: an OSErr describing the result
*
*/
OSErr GetDocPropertyData(WindowPtr theWindow, DescType theProperty, DescType typeWanted,
AEDesc *theData)
{
ImageHandle theImage = FindImage(theWindow);
Boolean theBoolean = false;
DescType theType;
Str255 theString;
AEDesc bestData;
OSErr theErr;
if (!theImage) return errAEReadDenied;
switch (theProperty) {
case pBestType:
case pDefaultType:
theType = typeObjectSpecifier;
theErr = AECreateDesc(typeType, (void *)&theType, sizeof(DescType), &bestData);
break;
case pClass:
theType = cDocument;
theErr = AECreateDesc(typeType, (void *)&theType, sizeof(DescType), &bestData);
break;
case pIsModified:
theErr = AECreateDesc(typeBoolean, (void *)&theBoolean, sizeof(Boolean), &bestData);
break;
case pName:
if (theImage) {
BlockMove((*theImage)->file.name, theString, 64);
if ((*theImage)->num) {
AddChar(theString, ' ');
AddNumber(theString, (*theImage)->num);
}
theErr = AEMakeIntlDesc(theString, &bestData);
}
break;
case pSelection:
theErr = MakeSelectionObject(theWindow, &bestData);
break;
default:
return errAETypeError;
}
if (theErr != noErr) return theErr;
if ((bestData.descriptorType == typeWanted) ||
(typeWanted == typeWildCard) || (typeWanted == typeBest))
theErr = AEDuplicateDesc(&bestData, theData);
else theErr = AECoerceDesc(&bestData, typeWanted, theData);
AEDisposeDesc(&bestData);
return theErr;
}
/*
* SetDocPropertyData(theWindow, theProperty, theData)
*
* Purpose: Sets the data for the application's properties
* Inputs: theWindow = the associated window
* theProperty = the property wanted
* theData = the data to set it to
* Returns: an OSErr describing the result
*
*/
OSErr SetDocPropertyData(WindowPtr theWindow, DescType theProperty, AEDesc *theData)
{
ImageHandle theImage = FindImage(theWindow);
Str255 theString;
OSErr theErr;
if (!theImage) return errAEWriteDenied;
switch (theProperty) {
case pName:
theErr = AEExtractPString(theData, 0, theString);
if (theErr == noErr) theErr = DoSetWindowTitle(theWindow, theString);
break;
default:
theErr = errAEWriteDenied;
break;
}
return theErr;
}
/*
* MakeDocumentObject(theWindow, theObject)
*
* Purpose: Creates a document object descriptor for the given window
* Inputs: theWindow = pointer to the window, or nil for all windows
* theObject = pointer to an AEDesc to store the result
* Returns: an OSErr describing what went wrong
*
*/
OSErr MakeDocumentObject(WindowPtr theWindow, AEDesc *theObject)
{
long index = (theWindow == (WindowPtr)kAEAll) ? kAEAll : 0;
AEDesc theKey, theContainer;
OSErr theErr = noErr;
WindowPtr window;
if (!index) {
for (window = GetFirstWindow(), index++; window && (window != theWindow);
window = NextWindow(window))
if (FindImage(window)) index++;
}
theErr = AECreateDesc((index == kAEAll) ? typeAbsoluteOrdinal : typeLongInteger,
(void *)&index, sizeof(long), &theKey);
if (theErr == noErr) {
theContainer.descriptorType = typeNull;
theContainer.dataHandle = nil;
theErr = CreateObjSpecifier(cDocument, &theContainer, formAbsolutePosition,
&theKey, false, theObject);
AEDisposeDesc(&theKey);
}
return theErr;
}
/*
* MakeDocPropertyObject(theWindow, theProperty, theObject)
*
* Purpose: Creates a property object descriptor for the given drawing area's property
* Inputs: theWindow = pointer to the window, or nil for all windows
* theObject = pointer to an AEDesc to store the result
* Returns: an OSErr describing what went wrong
*
*/
OSErr MakeDocPropertyObject(WindowPtr theWindow, DescType theProperty, AEDesc *theObject)
{
AEDesc theKey, theContainer;
OSErr theErr = noErr;
theErr = MakeDocumentObject(theWindow, &theContainer);
if (theErr == noErr) {
theErr = AECreateDesc(typeType, (void *)&theProperty, sizeof(DescType), &theKey);
if (theErr == noErr) {
theErr = CreateObjSpecifier(typeProperty, &theContainer, formPropertyID,
&theKey, false, theObject);
AEDisposeDesc(&theKey);
}
AEDisposeDesc(&theContainer);
}
return theErr;
}
/*
* IsValidForOne(keyForm, keyData)
*
* Purpose: Determines if the given keyForm is valid for specifying a single object
* for classes that can only contain a single element
* Inputs: keyForm = the key form specified
* keyData = the associated key data
* Returns: true if this keyForm works for a single object; false otherwise
*
*/
Boolean IsValidForOne(DescType keyForm, AEDesc *keyData)
{
long index;
switch (keyForm) {
case formAbsolutePosition:
index = *(long *)*keyData->dataHandle;
switch (keyData->descriptorType) {
case typeLongInteger:
if ((index < -1) || (index > 1)) return false;
return true;
case typeAbsoluteOrdinal:
switch (index) {
case kAEFirst:
case kAELast:
case kAEMiddle:
case kAEAny:
case kAEAll:
return true;
default:
return false;
}
}
case formName:
case formRelativePosition:
case formTest:
case formRange:
case formPropertyID:
default:
return errAEBadKeyForm;
break;
}
}
/*
* PurgeNonDocuments(theList)
*
* Purpose: Scans through the given list of objects and removes any non-documents
* Inputs: theList = a handle to an object token list
* Returns: nothing
*
*/
void PurgeNonDocuments(ObjectTokenHandle theList)
{
short i, newCount = 0, count = (*theList)->count;
Ptr window;
for (i = 0; i < count; i++) {
window = (*theList)->object[i];
if (FindImage((WindowPtr)window)) (*theList)->object[newCount++] = window;
}
if (newCount != count) {
SetHandleSize((Handle)theList, sizeof(ObjectToken) + (newCount - 1) * sizeof(Ptr));
(*theList)->count = newCount;
}
}
/*
* GetNamedDocument(keyData, theList)
*
* Purpose: Looks up a window from a text string
* Inputs: keyData = descriptor containing search key data
* theList = handle to the set of windows to search
* Returns: an OSErr describing the result
*
*/
OSErr GetNamedDocument(AEDesc *keyData, ObjectTokenHandle *theList)
{
short i, count = (**theList)->count;
uchar theString[256];
WindowPtr *window;
ImageHandle image;
OSErr theErr;
if (!count) return errAENoSuchObject;
if ((theErr = AEExtractPString(keyData, 0, theString)) != noErr) return theErr;
for (i = 0, window = (WindowPtr *)(**theList)->object; i < count; i++, window++)
if (image = FindImage(*window))
if (EqualString((*image)->file.name, theString, false, false)) break;
if (i == count) return errAENoSuchObject;
DisposeHandle((Handle)*theList);
if (!(*theList = MakeSingleObjectToken((Ptr)*window))) return memFullErr;
return noErr;
}
/*
* CountDocuments()
*
* Purpose: Counts the number of documents in the application
* Inputs: none
* Returns: the number of windows found
*
*/
short CountDocuments(void)
{
ImageHandle image;
short count = 0;
for (image = gImageRoot; image; image = (*image)->next) count++;
return count;
}
/*
* IndexedDocument(index)
*
* Purpose: Locates a document in the linked list by index
* Inputs: index = the number of the image in the list we seek
* Returns: a pointer to the desired window, or nil if none found
*
*/
WindowPtr IndexedDocument(short index)
{
ImageHandle theImage;
short i;
for (i = 1, theImage = gImageRoot; theImage && (i < index);
i++, theImage = (*theImage)->next);
return theImage ? (*theImage)->window : nil;
}
/*
* GetDocumentIndex(theWindow)
*
* Purpose: Determines a document's numerical index in the linked list
* Inputs: theWindow = a pointer to the document's window whose index we shall find
* Returns: the index
*
*/
short GetDocumentIndex(WindowPtr theWindow)
{
ImageHandle curImage;
short i;
for (i = 1, curImage = gImageRoot; curImage && ((*curImage)->window != theWindow);
i++, curImage = (*curImage)->next);
return curImage ? i : 1;
}