home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PrintingLibrary.c
-
- Contains: Graphics library for printing QuickDraw GX data.
-
- This library supports the basic job, format, dialog, and
- spooling functions of the QuickDraw GX Printing Manager. It
- provides an abstraction layer to handle printing through the
- QuickDraw GX and classic QuickDraw printing architectures,
- depending on which environment is available when the library
- is initialized. Only the basic features of QuickDraw GX
- printing are supported; i.e., the library does not handle
- application message overrides, custom dialog panels, or custom
- page formatting.
-
- For classic QuickDraw printing, the library uses QuickTime
- compression and decompression to image QuickDraw GX data. The
- basic technique is to encapsulate the QuickDraw GX image in a
- compressed data format using the object flattening functions
- from QuickDraw GX. Once the compressed image data is created,
- it may be passed to the QuickDraw GX codec and drawn using the
- QuickTime image compression functions or embedded within a
- QuickDraw picture and drawn using the DrawPicture function. In
- either case, the compressed data is passed to the the
- low-level QuickDraw drawing routines through the StdPix
- bottleneck routine. StdPix decompresses the data using the
- QuickDraw GX codec and passes the decompressed data to the
- bitsProc bottleneck routine when rendering the image.
-
- LaserWriter drivers starting with version 8.3 recognize
- compressed data that may be drawn using QuickTime, like
- QuickDraw GX flattened objects. For version 8.4.3, the
- LaserWriter driver has been modified to render the QuickDraw
- GX data at the device resolution of the printer. When
- despooling, the printer driver changes the resolution of the
- offscreen drawing port and uses the QuicDraw GX codec to
- rasterize the compressed data. The QuickDraw printer drivers
- from Apple render the compressed data during spooling and use
- the resolution of the active graphics port. The library uses
- the device resolution commands of the PrGeneral routine to
- improve the quality of their printed images as described in
- “Meet PrGeneral, the Trap That Makes the Most of the Printing
- Manager,” in develop 3 (July 1990).
-
- Written by: Daniel Lipton
-
- Copyright: © 1997 by Apple Computer, Inc., all rights reserved.
-
- Writers:
-
- (DIL) Daniel Lipton
- (IK) Ingrid Kelly
-
- Change History (most recent first):
-
- <1> 6/1/97 IK First created.
- */
-
- #include <CodeFragments.h>
- #include <Gestalt.h>
- #include <Resources.h>
- #include <TextUtils.h>
-
- #include "CodecLibrary.h"
- #include "PrintingLibrary.h"
- #include "GetShapeLocalBounds.h"
-
- /* ---------------------------------------------------------------------------
- Function prototypes
- --------------------------------------------------------------------------- */
-
- static gxRectangle *ShortRectToFixed(const Rect *shortRect, gxRectangle *fixedRect);
- static Rect *FixedRectToShort(const gxRectangle *fixedRect, Rect *shortRect);
- static OSErr QDInitPrinting(void);
- static OSErr QDPrOpen(void);
- static void QDPrClose(void);
- static OSErr QDPrGetMaxResolution(short *maxDPI);
- static OSErr QDPrSetResolution(THPrint prRecHdl, short iXRsl, short iYRsl);
- pascal void QDIdleProc(void);
- static OSErr QDCommandPeriod(void);
-
- static OSErr ReplaceCollectionItem(
- Collection collectionRef,
- OSType collectionType,
- long collectionID,
- long collectionSize,
- void *newData,
- long *oldDataSize,
- void **oldDataPtr);
-
- static OSErr SetViewportContext(gxprJobHdl gxprJob, long numViewPorts, gxViewPort *viewPortList);
- static OSErr RestoreViewportContext(gxprJobHdl gxprJob);
- static Boolean TestMappingIdentity(gxMapping *mapping);
- static void GXPrViewPortFilter(gxShape toFilter, gxViewPort portOrder, long refCon);
-
- /* ===========================================================================
- Global variables
- =========================================================================== */
-
- static PrintingArchitecture gPrintingArchitecture = kAnyPrArch;
- static PrintingOptions gPrintingOptions = kNilOptions;
-
- static gxUserViewPortFilterUPP gGXUserViewPortFilterUPP = nil;
- static long gPrOpenCount = 0;
-
- /* ===========================================================================
- Public functions
- =========================================================================== */
-
- /* ---------------------------------------------------------------------------
- GXPrInitPrinting
- --------------------------------------------------------------------------- */
-
- OSErr GXPrInitPrinting(void)
- {
- long theFeature;
- OSErr error;
-
- /* Before making any calls, check if the Printing Manager is available. */
-
- if ( Gestalt(gestaltGXPrintingMgrVersion, &theFeature) != noErr )
- gPrintingArchitecture = kQDPrArch;
- else
- gPrintingArchitecture = kGXPrArch;
-
- #ifdef powerc
- /* This is a sanity check to see if the GXPrintingLib shared library is
- installed. If the application is "weak" linked to the library, the
- Process Manager will launch it even if the library is missing,
- although the Code Fragment Manager will not resolve the addresses of
- the functions in the library. If the application calls any of these
- functions, it will crash.
-
- The application should check if any of the Printing Manager functions
- cannot be resolved and exit gracefully if the library is missing. Note
- that the check could be performed against any function the application
- calls in the library. GXInitPrinting is often the first function that
- is called from the library, so it is convenient.
- */
- if ( (UInt32)GXInitPrinting == kUnresolvedCFragSymbolAddress )
- gPrintingArchitecture = kQDPrArch;
- #endif
-
- if ( gPrintingArchitecture == kGXPrArch )
- error = GXInitPrinting();
- else
- {
- gGXUserViewPortFilterUPP = NewgxUserViewPortFilterProc(GXPrViewPortFilter);
- error = QDInitPrinting();
- }
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrExitPrinting
- --------------------------------------------------------------------------- */
-
- OSErr GXPrExitPrinting(void)
- {
- OSErr error;
-
- if ( gPrintingArchitecture == kGXPrArch )
- error = GXExitPrinting();
- else
- {
- if ( gGXUserViewPortFilterUPP != nil )
- {
- DisposeRoutineDescriptor(gGXUserViewPortFilterUPP);
- gGXUserViewPortFilterUPP = nil;
- }
- error = noErr;
- }
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetPrintingArchitecture
- --------------------------------------------------------------------------- */
-
- PrintingArchitecture GXPrGetPrintingArchitecture(void)
- {
- return gPrintingArchitecture;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetPrintingOptions
- --------------------------------------------------------------------------- */
-
- PrintingOptions GXPrGetPrintingOptions(void)
- {
- return gPrintingOptions;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrSetPrintingOptions
- --------------------------------------------------------------------------- */
-
- void GXPrSetPrintingOptions(PrintingOptions options)
- {
- gPrintingOptions = options;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetJobError
- --------------------------------------------------------------------------- */
-
- OSErr GXPrGetJobError(gxprJobHdl gxprJob)
- {
- OSErr error;
-
- if ( gxprJob == nil )
- return paramErr;
-
- error = (*gxprJob)->error;
- (*gxprJob)->error = noErr;
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrSetJobError
- --------------------------------------------------------------------------- */
-
- void GXPrSetJobError(gxprJobHdl gxprJob, OSErr error)
- {
- if ( gxprJob == nil )
- return;
-
- (*gxprJob)->error = error;
- GXSetJobError((*gxprJob)->job, error);
- }
-
- /* ---------------------------------------------------------------------------
- GXPrNewJob
- This routine returns a default print handle for the current printer driver.
- The printer driver is expected to be closed upon entry, and is therefore
- opened and closed in this routine.
- --------------------------------------------------------------------------- */
-
- OSErr GXPrNewJob(gxprJobHdl *gxprJob)
- {
- gxprJobHdl tempJob;
- THPrint prRecHdl = nil;
- OSErr error = noErr;
-
- *gxprJob = nil;
-
- tempJob = (gxprJobHdl)NewHandleClear(sizeof(gxprJobRecord));
- if ( tempJob == nil )
- {
- error = MemError();
- goto NewHandleClearFailed;
- }
-
- if ( gPrintingArchitecture == kGXPrArch )
- {
- error = GXNewJob(&(*tempJob)->job);
- if ( error != noErr )
- goto GXNewJobFailed;
- }
- else
- {
- prRecHdl = (THPrint)NewHandle(sizeof(TPrint));
- if ( prRecHdl == nil )
- {
- error = MemError();
- goto NewHandleFailed;
- }
-
- /* The PrintDefault routine sets the default values for the current
- printer, which are stored in the printer driver’s resource file,
- in the TPrint record, replacing the ones that may already be
- there. It calls the PrValidate function to ensure that the TPrint
- record is compatible with the current version of the printer
- driver.
- */
- error = QDPrOpen();
-
- if ( error == noErr )
- {
- PrintDefault(prRecHdl);
- error = PrError();
- }
-
- /* Select the maximum resolution of the printer. */
-
- if ( error == noErr && ((**prRecHdl).iPrVersion != 3 ||
- (gPrintingOptions & kUseShapeToQuickDrawPictureConversion) != 0) )
- error = QDPrGetMaxResolution(&(*tempJob)->prResolution);
-
- QDPrClose();
-
- if ( error != noErr )
- goto InitPrintRecordFailed;
-
- (*tempJob)->prRecHdl = prRecHdl;
- }
-
- (*tempJob)->architecture = gPrintingArchitecture;
- (*tempJob)->prResFile = -1;
-
- *gxprJob = tempJob;
-
- goto Completed;
-
- InitPrintRecordFailed:
- if ( prRecHdl != nil )
- DisposeHandle((Handle)prRecHdl);
-
- NewHandleFailed:
- GXNewJobFailed:
- if ( tempJob != nil )
- DisposeHandle((Handle)tempJob);
-
- NewHandleClearFailed:
- Completed:
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrDisposeJob
- --------------------------------------------------------------------------- */
-
- OSErr GXPrDisposeJob(gxprJobHdl gxprJob)
- {
- OSErr error = noErr;
-
- if ( gxprJob == nil )
- return paramErr;
-
- if ( (*gxprJob)->job != nil )
- error = GXDisposeJob((*gxprJob)->job);
-
- if ( (*gxprJob)->prRecHdl != nil )
- {
- DisposeHandle((Handle)(*gxprJob)->prRecHdl);
-
- if ( error == noErr )
- error = MemError();
- }
-
- DisposeHandle((Handle)gxprJob);
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrFlattenJobToFile
- This routine saves a print record handle in resource fork of a file; any
- existing print record resources are deleted and replaced.
- --------------------------------------------------------------------------- */
-
- void GXPrFlattenJobToFile(gxprJobHdl gxprJob, FSSpecPtr fileSpec)
- {
- Handle dataHandle;
- ResType rsrcType;
- short rsrcID;
- short resRefNum;
- Handle tempHandle;
- short savedRefNum;
-
- if ( gxprJob == nil )
- return;
-
- /* Save the current resource file reference number. */
-
- savedRefNum = CurResFile();
-
- resRefNum = FSpOpenResFile(fileSpec, fsRdWrPerm);
- if ( resRefNum == -1 )
- {
- (*gxprJob)->error = ResError();
- goto FSpOpenResFileFailed;
- }
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- dataHandle = GXFlattenJobToHdl((*gxprJob)->job, nil);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- if ( (*gxprJob)->error != noErr )
- goto GXFlattenJobToHdlFailed;
-
- rsrcType = rJobObjectRsrcType;
- rsrcID = rJobObjectRsrcID;
- }
- else
- {
- dataHandle = (Handle)(*gxprJob)->prRecHdl;
-
- rsrcType = rPrintRecordRsrcType;
- rsrcID = rPrintRecordRsrcID;
- }
-
- /* Delete any existing job object or print record resources. */
-
- UseResFile(resRefNum);
- tempHandle = Get1Resource(rsrcType, rsrcID);
- if ( tempHandle != nil )
- {
- RemoveResource(tempHandle);
- UpdateResFile(resRefNum);
- DisposeHandle(tempHandle);
- }
-
- /* Add the job object or print record resource. */
-
- if ( (*gxprJob)->error == noErr )
- {
- AddResource(dataHandle, rsrcType, rsrcID, "\p");
- (*gxprJob)->error = ResError();
-
- if ( (*gxprJob)->error == noErr )
- {
- WriteResource(dataHandle);
- UpdateResFile(resRefNum);
- ReleaseResource(dataHandle);
- }
- }
-
- GXFlattenJobToHdlFailed:
- NewHandleFailed:
- CloseResFile(resRefNum);
- FlushVol(nil, fileSpec->vRefNum);
-
- /* Switch back to the original resource file. */
-
- UseResFile(savedRefNum);
-
- FSpOpenResFileFailed:
- return;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrUnflattenJobFromFile
- This routine loads the first indexed print record resource from a file. If
- there are no matching resources in the file the function returns
- resNotFound.
- --------------------------------------------------------------------------- */
-
- gxprJobHdl GXPrUnflattenJobFromFile(gxprJobHdl gxprJob, FSSpecPtr fileSpec)
- {
- Handle dataHandle;
- ResType rsrcType;
- short rsrcID;
- short resRefNum;
- short savedRefNum;
- Boolean changed = false;
-
- if ( gxprJob == nil )
- return nil;
-
- /* Save the current resource file reference number. */
-
- savedRefNum = CurResFile();
-
- resRefNum = FSpOpenResFile(fileSpec, fsRdWrPerm);
- if ( resRefNum == -1 )
- {
- (*gxprJob)->error = ResError();
- goto FSpOpenResFileFailed;
- }
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- rsrcType = rJobObjectRsrcType;
- rsrcID = rJobObjectRsrcID;
- }
- else
- {
- rsrcType = rPrintRecordRsrcType;
- rsrcID = rPrintRecordRsrcID;
- }
-
- dataHandle = Get1IndResource(rsrcType, rsrcID);
- if ( dataHandle == nil )
- {
- (*gxprJob)->error = ResError();
- goto Get1IndResourceFailed;
- }
- DetachResource(dataHandle);
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- (*gxprJob)->job = GXUnflattenJobFromHdl(nil, dataHandle);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- if ( (*gxprJob)->error != noErr )
- goto GXUnflattenJobFromHdlFailed;
- }
- else
- {
- (*gxprJob)->prRecHdl = (THPrint)dataHandle;
- }
-
- (void)GXPrUpdateJob(gxprJob);
-
- GXUnflattenJobFromHdlFailed:
- Get1IndResourceFailed:
- CloseResFile(resRefNum);
- FlushVol(nil, fileSpec->vRefNum);
-
- /* Switch back to the original resource file. */
-
- UseResFile(savedRefNum);
-
- FSpOpenResFileFailed:
- return gxprJob;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrInstallApplicationOverride
- --------------------------------------------------------------------------- */
-
- void GXPrInstallApplicationOverride(gxprJobHdl gxprJob, short messageID, void *override)
- {
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXInstallApplicationOverride((*gxprJob)->job, messageID, override);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrUpdateJob
- --------------------------------------------------------------------------- */
-
- Boolean GXPrUpdateJob(gxprJobHdl gxprJob)
- {
- Boolean changed = false;
-
- if ( gxprJob == nil )
- return false;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- changed = GXUpdateJob((*gxprJob)->job);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
- OSErr error;
-
- error = QDPrOpen();
-
- if ( error == noErr )
- {
- /* With the TPrint record, whether an existing one from the current
- document or a new one just created, the PrValidate function
- ensures that the contents of the specified TPrint record are
- compatible with the current version of the printer driver for the
- current printer.
- */
- changed = PrValidate(prRecHdl);
- error = PrError();
-
- /* Select the maximum resolution of the printer. */
-
- if ( error == noErr && ((**prRecHdl).iPrVersion != 3 ||
- (gPrintingOptions & kUseShapeToQuickDrawPictureConversion) != 0) )
- error = QDPrGetMaxResolution(&(*gxprJob)->prResolution);
- }
-
- QDPrClose();
-
- (*gxprJob)->error = error;
- }
-
- return changed;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrNewFormat
- --------------------------------------------------------------------------- */
-
- gxprFormatHdl GXPrNewFormat(gxprJobHdl gxprJob)
- {
- gxprFormatHdl gxprFormat = nil;
-
- if ( gxprJob == nil )
- return nil;
-
- gxprFormat = (gxprFormatHdl)NewHandleClear(sizeof(gxprFormatRecord));
- if ( gxprFormat == nil )
- {
- (*gxprJob)->error = MemError();
- goto NewHandleClearFailed;
- }
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- (*gxprFormat)->format = GXNewFormat((*gxprJob)->job);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
-
- (*gxprFormat)->gxprJob = gxprJob;
-
- NewHandleClearFailed:
- return gxprFormat;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrDisposeFormat
- --------------------------------------------------------------------------- */
-
- void GXPrDisposeFormat(gxprFormatHdl gxprFormat)
- {
- if ( gxprFormat == nil )
- return;
-
- if ( (*gxprFormat)->format != nil )
- GXDisposeFormat((*gxprFormat)->format);
-
- DisposeHandle((Handle)gxprFormat);
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetFormatJob
- --------------------------------------------------------------------------- */
-
- gxprJobHdl GXPrGetFormatJob(gxprFormatHdl gxprFormat)
- {
- if ( gxprFormat == nil )
- return nil;
-
- return (*gxprFormat)->gxprJob;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetFormatDimensions
- --------------------------------------------------------------------------- */
-
- void GXPrGetFormatDimensions(gxprFormatHdl gxprFormat, gxRectangle *pageSize, gxRectangle *paperSize)
- {
- gxprJobHdl gxprJob;
-
- if ( gxprFormat == nil )
- return;
-
- gxprJob = (*gxprFormat)->gxprJob;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXGetFormatDimensions((*gxprFormat)->format, pageSize, paperSize);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
- Rect pageRect;
- Rect paperRect;
-
- pageRect = (**prRecHdl).prInfo.rPage;
- paperRect = (**prRecHdl).rPaper;
-
- (void)ShortRectToFixed(&pageRect, pageSize);
- (void)ShortRectToFixed(&paperRect, paperSize);
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetFormatCollection
- --------------------------------------------------------------------------- */
-
- Collection GXPrGetFormatCollection(gxprFormatHdl gxprFormat)
- {
- gxprJobHdl gxprJob;
- Collection formatCollection = nil;
-
- if ( gxprFormat == nil )
- return nil;
-
- if ( (*gxprFormat)->format == nil )
- return nil;
-
- gxprJob = (*gxprFormat)->gxprJob;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- formatCollection = GXGetFormatCollection((*gxprFormat)->format);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
-
- return formatCollection;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrJobDefaultFormatDialog
- This routine displays the standard page format dialog.
- --------------------------------------------------------------------------- */
-
- gxDialogResult GXPrJobDefaultFormatDialog(gxprJobHdl gxprJob, gxEditMenuRecord *anEditMenuRec)
- {
- gxDialogResult result = gxCancelSelected;
-
- if ( gxprJob == nil )
- return gxCancelSelected;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- result = GXJobDefaultFormatDialog((*gxprJob)->job, anEditMenuRec);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
- Boolean changed = false;
- OSErr error;
-
- error = QDPrOpen();
-
- if ( error == noErr )
- {
- (void)PrValidate(prRecHdl);
- error = PrError();
-
- if ( error == noErr )
- {
- changed = PrStlDialog(prRecHdl);
- error = PrError();
-
- if ( changed )
- result = gxOKSelected;
- else
- result = gxCancelSelected;
-
- if ( error == noErr && result == gxCancelSelected )
- {
- PrSetError(iPrAbort);
- error = iPrAbort;
- }
- }
- }
-
- QDPrClose();
-
- (*gxprJob)->error = error;
- }
-
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrJobPrintDialog
- This routine displays the standard print dialog.
- --------------------------------------------------------------------------- */
-
- gxDialogResult GXPrJobPrintDialog(gxprJobHdl gxprJob, gxEditMenuRecord *anEditMenuRec)
- {
- gxDialogResult result = gxCancelSelected;
-
- if ( gxprJob == nil )
- {
- (*gxprJob)->error = paramErr;
- return gxCancelSelected;
- }
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- gxJob job = (*gxprJob)->job;
-
- result = GXJobPrintDialog(job, anEditMenuRec);
- (*gxprJob)->error = GXGetJobError(job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
- Boolean changed = false;
- OSErr error;
-
- error = QDPrOpen();
-
- if ( error == noErr )
- {
- (void)PrValidate(prRecHdl);
- error = PrError();
-
- if ( error == noErr )
- {
- changed = PrJobDialog(prRecHdl);
- error = PrError();
-
- if ( changed )
- result = gxOKSelected;
- else
- result = gxCancelSelected;
-
- if ( error == noErr && result == gxCancelSelected )
- {
- PrSetError(iPrAbort);
- error = iPrAbort;
- }
- }
- }
-
- QDPrClose();
-
- (*gxprJob)->error = error;
- }
-
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrFormatDialog
- This routine displays the custom page format dialog.
- --------------------------------------------------------------------------- */
-
- gxDialogResult GXPrFormatDialog(gxprFormatHdl gxprFormat, gxEditMenuRecord *anEditMenuRec, StringPtr title)
- {
- gxprJobHdl gxprJob;
- gxDialogResult result = gxCancelSelected;
- Boolean changed = false;
- OSErr error;
-
- if ( gxprFormat == nil )
- return gxCancelSelected;
-
- gxprJob = (*gxprFormat)->gxprJob;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- result = GXFormatDialog((*gxprFormat)->format, anEditMenuRec, title);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- error = QDPrOpen();
-
- if ( error == noErr )
- {
- (void)PrValidate(prRecHdl);
- error = PrError();
-
- if ( error == noErr )
- {
- changed = PrStlDialog(prRecHdl);
- error = PrError();
-
- if ( changed )
- result = gxOKSelected;
- else
- result = gxCancelSelected;
-
- if ( error == noErr && result == gxCancelSelected )
- {
- PrSetError(iPrAbort);
- error = iPrAbort;
- }
- }
- }
- QDPrClose();
-
- (*gxprJob)->error = error;
- }
-
- return result;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrGetJobPageRange
- --------------------------------------------------------------------------- */
-
- void GXPrGetJobPageRange(gxprJobHdl gxprJob, long *firstPage, long *lastPage)
- {
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXGetJobPageRange((*gxprJob)->job, firstPage, lastPage);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- *firstPage = (**prRecHdl).prJob.iFstPage;
- *lastPage = (**prRecHdl).prJob.iLstPage;
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrStartJob
- --------------------------------------------------------------------------- */
-
- void GXPrStartJob(gxprJobHdl gxprJob, StringPtr docName, long pageCount)
- {
- PrIdleUPP idleUPP = nil;
-
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXStartJob((*gxprJob)->job, docName, pageCount);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- /* SetUpCursors(kWatchACursor); */
- GetPort(&(*gxprJob)->savedPort);
-
- (*gxprJob)->error = QDPrOpen();
-
- if ( (*gxprJob)->error == noErr )
- {
- /* Save the current resource file (i.e., the printer driver's)
- so the driver will not lose its resources upon return from the
- pIdleProc.
- */
- (*gxprJob)->prResFile = CurResFile();
-
- /* Install a routine descriptor for the pIdle proc in the print
- record. Use an intermediate variable to assign this indirectly
- because NewPrIdleProc may move memory.
- */
- idleUPP = NewPrIdleProc(QDIdleProc);
- (**prRecHdl).prJob.pIdleProc = idleUPP;
-
- /* Select the maximum resolution of the printer. */
-
- if ( (*gxprJob)->prResolution != 0 )
- {
- (*gxprJob)->savedHRes = (**prRecHdl).prInfo.iHRes;
- (*gxprJob)->savedVRes = (**prRecHdl).prInfo.iVRes;
- (*gxprJob)->error = QDPrSetResolution(prRecHdl, (*gxprJob)->prResolution, (*gxprJob)->prResolution);
- }
-
- #if 0
- {
- long jobFirst, jobLast;
-
- /* DetermineNumberOfPagesinDoc determines the number of pages
- contained in the document by comparing the size of the document
- with rPage from the TPrInfo record (Inside Macintosh: Imaging With
- QuickDraw p.9-46). It returns the number of pages required to
- print the document for the currently selected printer.
- */
- realNumberOfPagesInDoc = DetermineNumberOfPagesinDoc((**prRecHdl).prInfo.rPage);
-
- /* Get the number of copies of the document that the user wants
- printed from iCopies of the TPrJob record (Inside Macintosh:
- Imaging With QuickDraw p.9-47).
- */
- numberOfCopies = (**prRecHdl).prJob.iCopies;
-
- /* Determine which pages the user selected to print. If the
- user specifies a range that is greater than the actual number of
- pages, then only print those pages that are in the document.
- */
- jobFirst = (**prRecHdl).prJob.iFstPage;
- jobLast = (**prRecHdl).prJob.iLstPage;
-
- if ( jobFirst < 1 )
- jobFirst = 1;
- if ( jobFirst > realNumberOfPagesInDoc )
- jobFirst = realNumberOfPagesInDoc;
-
- if ( jobLast < jobFirst )
- jobLast = jobFirst;
- if ( jobLast > realNumberOfPagesInDoc )
- jobLast = realNumberOfPagesInDoc;
- }
- #endif
-
- (**prRecHdl).prJob.iFstPage = 1;
- (**prRecHdl).prJob.iLstPage = 9999;
-
- /* Restore the resource file to the printer driver's. */
-
- UseResFile((*gxprJob)->prResFile);
-
- (*gxprJob)->prPort = PrOpenDoc(prRecHdl, nil, nil);
- (*gxprJob)->error = PrError();
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrStartPage
- --------------------------------------------------------------------------- */
-
- void GXPrStartPage(gxprJobHdl gxprJob, long pageNumber, gxprFormatHdl gxprFormat, long numViewPorts, gxViewPort *viewPortList)
- {
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- gxFormat format;
-
- if ( gxprFormat != nil )
- format = (*gxprFormat)->format;
- else
- format = GXGetJobFormat((*gxprJob)->job, 1);
-
- GXStartPage((*gxprJob)->job, pageNumber, format, numViewPorts, viewPortList);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- SetPort((GrafPtr)(*gxprJob)->prPort);
-
- (*gxprJob)->error = SetViewportContext(gxprJob, numViewPorts, viewPortList);
-
- if ( (gPrintingOptions & kUseShapeToQuickDrawPictureConversion) == 0 )
- {
- PrOpenPage((*gxprJob)->prPort, nil);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = PrError();
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrDrawPicture
- This routine converts a shape to a QuickDraw picture containing flattened
- QuickDraw GX data encoded as QuickTime compressed data. It then
- calls the DrawPicture function to display the image, which uses the StdPix
- bottleneck routine to decompress the data and the StdBits bottleneck
- routine to render the image.
- --------------------------------------------------------------------------- */
-
- void GXPrDrawPicture(gxprJobHdl gxprJob, gxShape theShape, Fixed hScale, Fixed vScale)
- {
- PicHandle picture;
-
- picture = GXCdShapeToPicture(theShape, nil, ff(1), ff(1), false, true);
-
- if ( picture == nil )
- return;
-
- PrOpenPage((*gxprJob)->prPort, nil);
- (*gxprJob)->error = PrError();
-
- /* Draw the data for the page if there are no errors. */
-
- if ( (*gxprJob)->error == noErr )
- {
- gxRectangle bounds;
- Rect dstRect;
- gxRectangle geometry;
- gxShape shape;
-
- (void)ShortRectToFixed(&(**picture).picFrame, &bounds);
- shape = GXNewRectangle(&bounds);
-
- GXScaleShape(shape, hScale, vScale, bounds.left, bounds.top);
- GXGetShapeBounds(shape, 0, &geometry);
-
- FixedRectToShort(&geometry, &dstRect);
- GXDisposeShape(shape);
-
- DrawPicture(picture, &dstRect);
- KillPicture(picture);
- }
-
- PrClosePage((*gxprJob)->prPort);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = PrError();
- }
-
- /* ---------------------------------------------------------------------------
- GXPrPrintPage
- --------------------------------------------------------------------------- */
-
- void GXPrPrintPage(gxprJobHdl gxprJob, long pageNumber, gxprFormatHdl gxprFormat, gxShape thePage)
- {
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXPrintPage((*gxprJob)->job, pageNumber, (*gxprFormat)->format, thePage);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- Fixed hScale = ff(1);
- Fixed vScale = ff(1);
-
- if ( (*gxprJob)->prResolution != 0 )
- {
- hScale = FixRatio((*gxprJob)->prResolution, (*gxprJob)->savedHRes);
- vScale = FixRatio((*gxprJob)->prResolution, (*gxprJob)->savedVRes);
- }
-
- SetPort((GrafPtr)(*gxprJob)->prPort);
-
- if ( (gPrintingOptions & kUseShapeToQuickDrawPictureConversion) != 0 )
- {
- GXPrDrawPicture(gxprJob, thePage, hScale, vScale);
- }
- else
- {
- PrOpenPage((*gxprJob)->prPort, nil);
- (*gxprJob)->error = PrError();
-
- if ( (*gxprJob)->error == noErr )
- GXCdDrawShape(thePage, nil, hScale, vScale, false, true);
-
- PrClosePage((*gxprJob)->prPort);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = PrError();
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrFinishPage
- --------------------------------------------------------------------------- */
-
- void GXPrFinishPage(gxprJobHdl gxprJob)
- {
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXFinishPage((*gxprJob)->job);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- Fixed hScale = ff(1);
- Fixed vScale = ff(1);
- OSErr error;
-
- if ( (*gxprJob)->prResolution != 0 )
- {
- hScale = FixRatio((*gxprJob)->prResolution, (*gxprJob)->savedHRes);
- vScale = FixRatio((*gxprJob)->prResolution, (*gxprJob)->savedVRes);
- }
-
- if ( (gPrintingOptions & kUseShapeToQuickDrawPictureConversion) != 0 )
- {
- GXPrDrawPicture(gxprJob, (**(*gxprJob)->vpContextHdl).shape, hScale, vScale);
- }
- else
- {
- GXCdDrawShape((**(*gxprJob)->vpContextHdl).shape, nil, hScale, vScale, false, true);
-
- PrClosePage((*gxprJob)->prPort);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = PrError();
- }
-
- error = RestoreViewportContext(gxprJob);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = error;
-
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrFinishJob
- --------------------------------------------------------------------------- */
-
- void GXPrFinishJob(gxprJobHdl gxprJob)
- {
- TPrStatus prStatus;
-
- if ( gxprJob == nil )
- return;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- GXFinishJob((*gxprJob)->job);
- (*gxprJob)->error = GXGetJobError((*gxprJob)->job);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- if ( (*gxprJob)->prPort != nil )
- {
- PrCloseDoc((*gxprJob)->prPort);
-
- if ( (*gxprJob)->error == noErr )
- (*gxprJob)->error = PrError();
- }
-
- if ( prRecHdl != nil )
- {
- if ( (*gxprJob)->error == noErr && (**prRecHdl).prJob.bJDocLoop == bSpoolLoop )
- PrPicFile(prRecHdl, nil, nil, nil, &prStatus);
- }
-
- /* Restore the resolution of the printer. */
-
- if ( (*gxprJob)->prResolution != 0 )
- {
- QDPrSetResolution(prRecHdl, (*gxprJob)->savedHRes, (*gxprJob)->savedVRes);
- (*gxprJob)->savedHRes = 0;
- (*gxprJob)->savedVRes = 0;
- }
-
- QDPrClose();
-
- SetPort((*gxprJob)->savedPort);
- /* TearDownCursors(kArrowCursor); */
-
- if ( prRecHdl != nil )
- {
- PrIdleUPP idleUPP;
-
- if ( (idleUPP = (**prRecHdl).prJob.pIdleProc) != nil )
- DisposeRoutineDescriptor((UniversalProcPtr)idleUPP);
-
- (**prRecHdl).prJob.pIdleProc = nil;
- }
- }
- }
-
- /* ---------------------------------------------------------------------------
- GXPrSetJobCopies
- This routine sets or replaces the information in the copies item of a print
- job. If the oldDataPtr parameter is not nil, this routine returns the
- information stored in the old item prior to replacing it with the new
- information. If the collection item does not exist, it returns nil in the
- oldDataPtr parameter.
- --------------------------------------------------------------------------- */
-
- OSErr GXPrSetJobCopies(gxprJobHdl gxprJob, gxCopiesInfo *newData, gxCopiesInfo **oldDataPtr)
- {
- long oldDataSize = sizeof(gxCopiesInfo);
- OSErr error = noErr;
-
- if ( gxprJob == nil )
- return paramErr;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- Collection collectionRef;
-
- collectionRef = GXGetJobCollection((*gxprJob)->job);
- error = ReplaceCollectionItem(collectionRef,
- gxCopiesTag,
- gxPrintingTagID,
- sizeof(gxCopiesInfo),
- newData,
- &oldDataSize,
- oldDataPtr);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- if ( oldDataPtr != nil )
- {
- /* Allocate the temporary buffer for the old collection item information. */
-
- *oldDataPtr = (gxCopiesInfo *)NewPtrClear(oldDataSize);
- if ( *oldDataPtr == nil )
- {
- error = MemError();
- goto NewPtrClearFailed;
- }
-
- (**oldDataPtr).copies = (**prRecHdl).prJob.iCopies;
- }
-
- /* Set the new value in the print record. */
-
- (**prRecHdl).prJob.iCopies = (*newData).copies;
- }
-
- NewPtrClearFailed:
- (*gxprJob)->error = error;
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrSetJobFileDestination
- This routine sets or replaces the information in the file destination item
- of a print job. If the oldDataPtr parameter is not nil, this routine
- returns the information stored in the old item prior to replacing it with
- the new information. If the collection item does not exist, it returns nil
- in the oldDataPtr parameter.
- --------------------------------------------------------------------------- */
-
- OSErr GXPrSetJobFileDestination(gxprJobHdl gxprJob, gxFileDestinationInfo *newData, gxFileDestinationInfo **oldDataPtr)
- {
- long oldDataSize = sizeof(gxFileDestinationInfo);
- OSErr error = noErr;
-
- if ( gxprJob == nil )
- return paramErr;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- Collection collectionRef;
-
- collectionRef = GXGetJobCollection((*gxprJob)->job);
- error = ReplaceCollectionItem(collectionRef,
- gxFileDestinationTag,
- gxPrintingTagID,
- sizeof(gxFileDestinationInfo),
- newData,
- &oldDataSize,
- oldDataPtr);
- }
- else
- {
- if ( oldDataPtr != nil )
- {
- /* Allocate the temporary buffer for the old collection item information. */
-
- *oldDataPtr = (gxFileDestinationInfo *)NewPtrClear(oldDataSize);
- if ( *oldDataPtr == nil )
- {
- error = MemError();
- goto NewPtrClearFailed;
- }
-
- /* There is no way to determine or set this information in the QuickDraw
- print record, so the printer destination is set by default.
- */
- (**oldDataPtr).toFile = false;
- }
- }
-
- NewPtrClearFailed:
- (*gxprJob)->error = error;
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrSetJobPageRange
- This routine sets or replaces the information in the page range item of a
- print job. If the oldDataPtr parameter is not nil, this routine returns
- the information stored in the old item prior to replacing it with the new
- information. If the collection item does not exist, it returns nil in the
- oldDataPtr parameter. Note that newDataSize is in the parameter list of
- this function because gxPageRangeInfo is a variable size data structure.
- --------------------------------------------------------------------------- */
-
- OSErr GXPrSetJobPageRange(gxprJobHdl gxprJob, long newDataSize, gxPageRangeInfo *newData, long *oldDataSize, gxPageRangeInfo **oldDataPtr)
- {
- OSErr error = noErr;
-
- if ( gxprJob == nil )
- return paramErr;
-
- if ( (*gxprJob)->architecture == kGXPrArch )
- {
- Collection collectionRef;
-
- collectionRef = GXGetJobCollection((*gxprJob)->job);
- error = ReplaceCollectionItem(collectionRef,
- gxPageRangeTag,
- gxPrintingTagID,
- newDataSize,
- newData,
- oldDataSize,
- oldDataPtr);
- }
- else
- {
- THPrint prRecHdl = (*gxprJob)->prRecHdl;
-
- if ( oldDataPtr != nil )
- {
- /* Allocate the temporary buffer for the old collection item information. */
-
- *oldDataPtr = (gxPageRangeInfo *)NewPtrClear(*oldDataSize);
- if ( *oldDataPtr == nil )
- {
- error = MemError();
- goto NewPtrClearFailed;
- }
-
- (**oldDataPtr).simpleRange.optionChosen = gxDefaultPageRange;
- (**oldDataPtr).simpleRange.fromPage = (**prRecHdl).prJob.iFstPage;
- (**oldDataPtr).simpleRange.toPage = (**prRecHdl).prJob.iLstPage;
- (**oldDataPtr).simpleRange.printAll = false;
- }
-
- /* Set the new values in the print record. */
-
- if ( newData->simpleRange.printAll )
- {
- (**prRecHdl).prJob.iFstPage = 1;
- (**prRecHdl).prJob.iLstPage = iPrPgMax;
- }
- else
- {
- (**prRecHdl).prJob.iFstPage = (*newData).simpleRange.fromPage;
- (**prRecHdl).prJob.iLstPage = (*newData).simpleRange.toPage;
- }
- }
-
- NewPtrClearFailed:
- (*gxprJob)->error = error;
- return error;
- }
-
- /* ===========================================================================
- Private functions
- =========================================================================== */
-
- /* ---------------------------------------------------------------------------
- QuickDraw conversion utility functions
- --------------------------------------------------------------------------- */
-
- static gxRectangle *ShortRectToFixed(const Rect *shortRect, gxRectangle *fixedRect)
- {
- register Fixed *coord;
-
- if (shortRect == nil)
- {
- GXPostGraphicsError(parameter_is_nil);
- return nil;
- }
-
- if (fixedRect == nil)
- {
- GXPostGraphicsError(parameter_is_nil);
- return nil;
- }
-
- coord = (Fixed *)fixedRect;
- *coord++ = IntToFixed(shortRect->left);
- *coord++ = IntToFixed(shortRect->top);
- *coord++ = IntToFixed(shortRect->right);
- *coord = IntToFixed(shortRect->bottom);
- return fixedRect;
- }
-
- static Rect *FixedRectToShort(const gxRectangle *fixedRect, Rect *shortRect)
- {
- register short *coord;
-
- if (shortRect == nil)
- {
- GXPostGraphicsError(parameter_is_nil);
- return nil;
- }
-
- if (fixedRect == nil)
- {
- GXPostGraphicsError(parameter_is_nil);
- return nil;
- }
-
- coord = (short *)shortRect;
- *coord++ = FixedRound(fixedRect->top);
- *coord++ = FixedRound(fixedRect->left);
- *coord++ = FixedRound(fixedRect->bottom);
- *coord = FixedRound(fixedRect->right);
- return shortRect;
- }
-
- /* ---------------------------------------------------------------------------
- QDInitPrinting
- This routine checks if the QuickDraw printing manager is available to the
- application.
- --------------------------------------------------------------------------- */
-
- static OSErr QDInitPrinting(void)
- {
- OSErr error = QDPrOpen();
- QDPrClose();
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- QDPrOpen
- This routine allows nested calls to PrOpen/PrClose by keeping track of
- the number of calls that have been made in the global gPrOpenCount.
- --------------------------------------------------------------------------- */
-
- static OSErr QDPrOpen(void)
- {
- OSErr error = noErr;
-
- gPrOpenCount++;
-
- if ( gPrOpenCount == 1 )
- {
- PrOpen();
- error = PrError();
-
- /* Here "file not found" really means "no printer chosen." */
-
- if ( error == fnfErr )
- error = noPrinterChosenErr;
- }
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- QDPrClose
- This routine allows nested calls to PrOpen/PrClose by keeping track of
- the number of calls that have been made in the global gPrOpenCount.
- --------------------------------------------------------------------------- */
-
- static void QDPrClose(void)
- {
- if ( gPrOpenCount > 0 )
- gPrOpenCount--;
-
- if ( gPrOpenCount == 0 )
- PrClose();
- }
-
- /* ---------------------------------------------------------------------------
- QDPrGetMaxResolution
- Find the highest "square" resolution supported by the currently selected
- printer driver.
- --------------------------------------------------------------------------- */
-
- static OSErr QDPrGetMaxResolution(short *maxDPI)
- {
- OSErr error = noErr;
-
- *maxDPI = 0;
-
- {
- short resIndex;
- TGetRslBlk getResRec;
-
- getResRec.iOpCode = getRslDataOp;
- PrGeneral((Ptr)&getResRec);
-
- error = PrError();
-
- if ( error == noErr )
- {
- error = getResRec.iError;
- }
- else if ( error == resNotFound )
- {
- /* If resNotFound is returned by PrError, then the current printer
- driver doesn’t support PrGeneral.
- */
- PrSetError(noErr);
- }
-
- /* At this point, we have an array of possible resolutions. After
- checking for errors, we loop through each resolution range record
- looking for the highest resolution available, where x and y are equal.
- This loop makes no assumptions about the order of the resolution
- records.
- */
- if ( error == noErr )
- {
- for ( resIndex = 0; resIndex < getResRec.iRslRecCnt; resIndex++ )
- {
- if ( getResRec.rgRslRec[resIndex].iXRsl == getResRec.rgRslRec[resIndex].iYRsl &&
- getResRec.rgRslRec[resIndex].iXRsl > *maxDPI )
- *maxDPI = getResRec.rgRslRec[resIndex].iYRsl;
- }
- }
- }
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- QDPrSetResolution
- Set the resolution of the currently selected printer driver.
- --------------------------------------------------------------------------- */
-
- static OSErr QDPrSetResolution(THPrint prRecHdl, short iXRsl, short iYRsl)
- {
- OSErr error = noErr;
-
- if ( prRecHdl == nil )
- return paramErr;
-
- {
- TSetRslBlk setResRec;
-
- if ( iXRsl != 0 && iYRsl != 0 )
- {
- setResRec.iOpCode = setRslOp;
- setResRec.hPrint = prRecHdl;
- setResRec.iXRsl = iXRsl;
- setResRec.iYRsl = iYRsl;
- PrGeneral((Ptr)&setResRec);
-
- error = PrError();
-
- if ( error == noErr )
- {
- error = setResRec.iError;
- }
- else if ( error == resNotFound )
- {
- /* If resNotFound is returned by PrError, then the current printer
- driver doesn’t support PrGeneral.
- */
- PrSetError(noErr);
- }
- }
- }
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- QDIdleProc
- This routine is a PrIdleProcPtr that spins the cursor and looks for
- command-period presses during printing.
- --------------------------------------------------------------------------- */
-
- pascal void QDIdleProc(void)
- {
- OSErr error;
-
- // BumpCursor();
- error = QDCommandPeriod();
- if ( error != noErr )
- PrSetError(error);
- }
-
- /* ---------------------------------------------------------------------------
- QDCommandPeriod
- This routine checks to see if the user has pressed command-period. The
- Printing Manager does this for us, but a routine like this is helpful to
- allow users to cancel in the middle of a rendering routine, rather than
- only Printing Manager operations. If there's a command-period in the event
- queue, the routine returns iPrAbort just like the Printing Manager;
- otherwise, it returns noErr.
- --------------------------------------------------------------------------- */
-
- static OSErr QDCommandPeriod(void)
- {
- short eventMask = keyDownMask | autoKeyMask | mDownMask;
- EventRecord event;
- WindowPtr window;
- short itemHit;
- Boolean userCancel = false;
-
- if ( WaitNextEvent(eventMask, &event, 0, nil) )
- {
- switch ( event.what )
- {
- case mouseDown:
- if ( IsDialogEvent(&event) )
- if ( FindWindow(event.where, &window) == inContent )
- if ( window != nil )
- {
- // if ( ((WindowPeek)window)->windowKind == userKind )
- if ( DialogSelect(&event, (DialogPtr *)&window, &itemHit) )
- userCancel = (itemHit == kStdCancelItemIndex);
- }
- break;
-
- case keyDown:
- case autoKey:
- userCancel = (event.modifiers & cmdKey) && ((event.message & charCodeMask) == '.');
- break;
- }
- }
-
- return ( (userCancel) ? (iPrAbort) : (noErr) );
- }
-
- /* ---------------------------------------------------------------------------
- ReplaceCollectionItem
- This utility routine sets or replaces the information in a collection item.
- If the oldDataPtr parameter is not nil, this routine returns the
- information stored in the old item prior to replacing it with the new
- information. If the collection item does not exist, it returns nil in the
- oldDataPtr parameter.
- --------------------------------------------------------------------------- */
-
- static OSErr ReplaceCollectionItem(
- Collection collectionRef,
- OSType collectionType,
- long collectionID,
- long collectionSize,
- void *newData,
- long *oldDataSize,
- void **oldDataPtr)
- {
- long index;
- OSErr error = noErr;
-
- if ( newData == nil )
- return paramErr;
-
- if ( oldDataPtr != nil )
- {
- /* Determine the size of the collection item. */
-
- error = GetCollectionItem(collectionRef,
- collectionType,
- collectionID,
- oldDataSize,
- dontWantData);
-
- if ( error == noErr )
- {
- /* Allocate the temporary buffer for the old collection item information. */
-
- *oldDataPtr = NewPtrClear(*oldDataSize);
- if ( *oldDataPtr == nil )
- {
- error = MemError();
- goto NewPtrClearFailed;
- }
-
- /* Obtain a copy of the collection item information. */
-
- error = GetCollectionItem(collectionRef,
- collectionType,
- collectionID,
- dontWantSize,
- *oldDataPtr);
-
- if ( error != noErr )
- goto GetCollectionItemDataFailed;
- }
- else
- *oldDataPtr = nil;
- }
-
- /* Add or replace the collection item information. */
-
- error = AddCollectionItem(collectionRef,
- collectionType,
- collectionID,
- collectionSize,
- newData);
-
- if ( error == collectionItemLockedErr )
- {
- error = GetCollectionItemInfo(collectionRef,
- collectionType,
- collectionID,
- &index,
- dontWantSize,
- dontWantAttributes);
-
- if ( error == noErr )
- error = ReplaceIndexedCollectionItem(collectionRef, index, collectionSize, newData);
- }
-
- goto Completed;
-
- GetCollectionItemDataFailed:
- if ( *oldDataPtr != nil )
- {
- DisposePtr(*oldDataPtr);
- *oldDataPtr = nil;
- }
-
- NewPtrClearFailed:
- Completed:
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- Viewport filter handling functions
- --------------------------------------------------------------------------- */
-
- static OSErr SetViewportContext(gxprJobHdl gxprJob, long numViewPorts, gxViewPort *viewPortList)
- { gxprViewportContextHdl context;
- gxShape shape;
- long index;
- OSErr error;
-
- if ( gxprJob == nil )
- return paramErr;
-
- context = (gxprViewportContextHdl)NewHandleClear(sizeof(gxShape) + sizeof(long) + sizeof(vpContextRecord) * numViewPorts);
-
- shape = GXNewShape(gxPictureType);
- error = (OSErr)GXGetGraphicsError(nil);
-
- if ( error != noErr )
- goto GXNewShapeFailed;
-
- (**context).shape = shape;
- (**context).vpCount = numViewPorts;
- (**context).vpContextArray;
-
- for ( index = 0; error == noErr && index < numViewPorts; index++ )
- {
- (**context).vpContextArray[index].viewport = viewPortList[index];
- (**context).vpContextArray[index].viewportFilter = GXGetViewPortFilter(viewPortList[index],
- &(**context).vpContextArray[index].refcon);
-
- GXSetViewPortFilter(viewPortList[index], (gxUserViewPortFilter)gGXUserViewPortFilterUPP, (long)shape);
-
- error = (OSErr)GXGetGraphicsError(nil);
- }
-
- if ( error == noErr )
- (*gxprJob)->vpContextHdl = context;
-
- GXNewShapeFailed:
- return error;
- }
-
- static OSErr RestoreViewportContext(gxprJobHdl gxprJob)
- {
- gxprViewportContextHdl context;
- long index;
- OSErr error = noErr;
-
- if ( gxprJob == nil )
- return paramErr;
-
- context = (*gxprJob)->vpContextHdl;
- if ( context == nil )
- return noErr;
-
- GXDisposeShape((**context).shape);
-
- for ( index = 0; error == noErr && index < (**context).vpCount; index++ )
- {
- GXSetViewPortFilter((**context).vpContextArray[index].viewport,
- (**context).vpContextArray[index].viewportFilter,
- (**context).vpContextArray[index].refcon);
-
- error = (OSErr)GXGetGraphicsError(nil);
- }
-
- DisposeHandle((Handle)context);
- (*gxprJob)->vpContextHdl = nil;
-
- return error;
- }
-
- /* ---------------------------------------------------------------------------
- GXPrViewPortFilter
- This filter is used to gather all shapes drawn in the viewports specified
- in StartPage. The shapes are gathered into a picture which will be passed
- to PrintPage at FinishPage.
-
- If the port has a clip or mapping, then the shape passed in is first
- inserted into a new picture that has the port's clip and mapping. This
- picture is then added to the page picture (which is passed in as the
- refcon).
- --------------------------------------------------------------------------- */
-
- static Boolean TestMappingIdentity(gxMapping *mapping)
- {
- Boolean result;
-
- result = ( (mapping->map[0][0] == ff(1)) && (mapping->map[0][1] == ff(0)) && (mapping->map[0][2] == ff(0)) &&
- (mapping->map[1][0] == ff(0)) && (mapping->map[1][1] == ff(1)) && (mapping->map[1][2] == ff(0)) &&
- (mapping->map[2][0] == ff(0)) && (mapping->map[2][1] == ff(0)) && (mapping->map[2][2] == fract1)
- ) ? true : false;
-
- return result;
- }
-
- static void GXPrViewPortFilter(gxShape toFilter, gxViewPort portOrder, long refCon)
- {
- gxShape printingPicture;
- gxShape portClip;
- gxMapping portMapping;
-
- /* Add the shape to a picture for printing */
-
- printingPicture = (gxShape)refCon;
-
- /* If the portOrder port has no clip or mapping, just add the shape to
- the printing picture.
- */
- portClip = GXGetViewPortClip(portOrder);
- GXGetViewPortMapping(portOrder, &portMapping);
- if ( (GXGetShapeType(portClip) == gxFullType) && TestMappingIdentity(&portMapping) )
- {
- GXSetPictureParts(printingPicture, 0, 0, 1, &toFilter, nil, nil, nil);
- }
- else
- {
- /* The port had a mapping/clip, so add the shape nested in a picture
- with the port's mapping and clip.
- */
- gxShape nestPicture = GXNewShape(gxPictureType);
- GXSetShapeClip(nestPicture, portClip);
- GXSetShapeMapping(nestPicture, &portMapping);
-
- /* Add the toFilter shape to the nest picture. */
-
- GXSetPictureParts(nestPicture, 0, 0, 1, &toFilter, nil, nil, nil);
-
- /* Add the nest picture to the page. */
-
- GXSetPictureParts(printingPicture, 0, 0, 1, &nestPicture, nil, nil, nil);
-
- GXDisposeShape(nestPicture);
- }
-
- GXDisposeShape(portClip);
- }
-