/* File: DummyExport.c Copyright 1990 by Thomas Knoll. Copyright 1993 by Adobe Systems, Inc. C source file for DummyExport example. */ #include #include #include #include #include #include #include #include #include #include "PITypes.h" #include "PIGeneral.h" #include "PIExport.h" #include "DialogUtilities.h" #include "PIUtilities.h" #ifdef THINK_C #define ENTRYPOINT main #endif /*****************************************************************************/ typedef struct Globals { short result; ExportRecord *stuff; short fRefNum; short vRefNum; } Globals, *GPtr; #define gResult ((*globals).result) #define gStuff ((*globals).stuff) #define gFRefNum ((*globals).fRefNum) #define gVRefNum ((*globals).vRefNum) /*****************************************************************************/ void InitGlobals (GPtr globals); void DoAbout (GPtr globals); void DoPrepare (GPtr globals); void DoStart (GPtr globals); void DoContinue (GPtr globals); void DoFinish (GPtr globals); /*****************************************************************************/ /* All calls to the plug-in module come through this routine. It must be placed first in the resource. To achieve this, most development systems require that this be the first routine in the source. */ pascal void ENTRYPOINT (short selector, ExportRecord *stuff, long *data, short *result) { GPtr globals; if (!*data) { *data = (long) NewPtr (sizeof (Globals)); if (!*data) { *result = memFullErr; return; } InitGlobals ((GPtr) *data); } globals = (GPtr) *data; gStuff = stuff; gResult = noErr; switch (selector) { case exportSelectorAbout: DoAbout (globals); break; case exportSelectorPrepare: DoPrepare (globals); break; case exportSelectorStart: DoStart (globals); break; case exportSelectorContinue: DoContinue (globals); break; case exportSelectorFinish: DoFinish (globals); break; default: gResult = exportBadParameters; } *result = gResult; } /*****************************************************************************/ void InitGlobals (GPtr globals) { #pragma unused (globals) /* None of the globals requires initialization. */ } /*****************************************************************************/ /* Displays the about dialog box for the plug-in module. */ void DoAbout (GPtr globals) { #pragma unused (globals) #define dialogID 17000 ShowAbout (dialogID); #undef dialogID } /*****************************************************************************/ /* Prepare to export an image. If the plug-in module needs only a limited amount of memory, it can lower the value of the 'maxData' field. */ void DoPrepare (GPtr globals) { if (gStuff->maxData > 0x80000) gStuff->maxData = 0x80000; } /*****************************************************************************/ void DoInitialRect (GPtr globals); Boolean DoNextRect (GPtr globals); void DoExportRect (GPtr globals); /*****************************************************************************/ /* Requests pointer to the first part of the image to be filtered. */ void DoStart (GPtr globals) { OSErr err; Point where; Str255 prompt; SFReply reply; StringPtr name; DialogTHndl dt; #define kStringsID 17000 /* This plug-in does not support bitmap images */ if (gStuff->imageMode == plugInModeBitmap) { gResult = exportBadMode; return; } /* Get prompt string */ GetIndString (prompt, kStringsID, 1); /* Center dialog */ dt = (DialogTHndl) GetResource ('DLOG', putDlgID); HNoPurge ((Handle) dt); CenterDialog (dt); where.v = (**dt).boundsRect.top; where.h = (**dt).boundsRect.left; HPurge ((Handle) dt); /* Ask the user */ name = (StringPtr) &gStuff->filename; SFPutFile (where, prompt, name, nil, &reply); if (!reply.good) { gResult = 1; return; } gVRefNum = reply.vRefNum; /* Create the file. */ err = FSDelete (reply.fName, gVRefNum); err = Create (reply.fName, gVRefNum, '????', '????'); if (err != noErr) { gResult = err; return; } /* Open the file. */ err = FSOpen (reply.fName, gVRefNum, &gFRefNum); if (err != noErr) { gResult = err; return; } DoInitialRect (globals); #undef kStringsID } /*****************************************************************************/ /* Filters the area and requests the next area. */ void DoContinue (GPtr globals) { if (TestAbort ()) { gResult = 1; return; } DoExportRect (globals); if (!DoNextRect (globals)) SetRect (&gStuff->theRect, 0, 0, 0, 0); } /*****************************************************************************/ /* Requests first part of the image to be filtered. */ void DoInitialRect (GPtr globals) { gStuff->theRect.top = 0; gStuff->theRect.bottom = 0; gStuff->theRect.left = 0; gStuff->theRect.right = gStuff->imageSize.h; if (!DoNextRect (globals)) SetRect (&gStuff->theRect, 0, 0, 0, 0); } /*****************************************************************************/ /* Request the next area. */ Boolean DoNextRect (GPtr globals) { /* Compute maximum number of rows we should request at once */ long count = gStuff->maxData / gStuff->imageSize.h / gStuff->planes; long top = gStuff->theRect.bottom; if (top >= gStuff->imageSize.v) return FALSE; if (count < 1) count = 1; gStuff->loPlane = 0; gStuff->hiPlane = gStuff->planes - 1; gStuff->theRect.left = 0; gStuff->theRect.right = gStuff->imageSize.h; gStuff->theRect.top = (short) top; if (gStuff->theRect.bottom + count > gStuff->imageSize.v) gStuff->theRect.bottom = gStuff->imageSize.v; else gStuff->theRect.bottom = top + count; return TRUE; } /*****************************************************************************/ /* Filter the area. */ void DoExportRect (GPtr globals) { OSErr err; short row; long count; for (row = gStuff->theRect.top; row < gStuff->theRect.bottom; row++) { /* See if user was aborted the operation */ if (TestAbort ()) { gResult = 1; return; } /* Update the progress indicator */ UpdateProgress ((long) row, (long) gStuff->imageSize.v); /* Write out this row of the image */ count = gStuff->planes * (long) gStuff->imageSize.h; err = FSWrite (gFRefNum, &count, (Ptr) ((long) (gStuff->data) + gStuff->rowBytes * (row - gStuff->theRect.top))); if (err != noErr) { gResult = err; return; } } } /*****************************************************************************/ /* This routine will always be called if DoStart does not return an error (even if DoContinue returns an error or the user aborts the operation). This allows the module to perform any needed cleanup. None is required in this example. */ void DoFinish (GPtr globals) { OSErr err; /* Close the file */ err = FSClose (gFRefNum); if (err != noErr) { gResult = err; return; } /* Flush the volume */ err = FlushVol (nil, gVRefNum); if (err != noErr) { gResult = err; return; } /* Clear the image's unsaved changes flag */ gStuff->dirty = false; } /*****************************************************************************/