home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK1.toast / Development Kits (Disc 1) / ColorSync SDK / Sample Code / CSDemo 2.1 / ShellSources / gxPrintUtils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-13  |  14.7 KB  |  467 lines  |  [TEXT/CWIE]

  1.  
  2. #include <Gestalt.h>
  3. #include <CodeFragments.h>
  4. #include <QDOffscreen.h>
  5. #include <Errors.h>
  6. #include <Resources.h>
  7. #include <GXGraphics.h>
  8. #include <GXEnvironment.h>
  9. #include <GXPrinting.h>
  10. #include <GXMath.h>
  11.  
  12. #include "appMain.h"          // neded for DoEvent
  13.  
  14. #include "gxGlobals.h"
  15. #include "gxUtils.h"
  16. #include "gxPrintUtils.h"
  17. #include "qdPrintUtils.h"
  18.  
  19.  
  20. /**\
  21. |**| ==============================================================================
  22. |**| PRIVATE FUNCTION PROTOTYPES
  23. |**| ==============================================================================
  24. \**/
  25. OSErr         PrintingEventProc        ( EventRecord *anEvent, Boolean filterEvent ) ;
  26. OSErr        MyGXPrintAShape            ( gxShape currentShape, void *refCon ) ;
  27.  
  28.  
  29. /**\
  30. |**| ==============================================================================
  31. |**| PRIVATE GLOBALS
  32. |**| ==============================================================================
  33. \**/
  34. OSErr        gGXPrinting_present_err = 1;
  35. OSErr        gGXPrinting_available_err = 1;
  36. OSErr        gGXPrinting_initialized_err = 1;
  37.  
  38.  
  39. /**\
  40. |**| ==============================================================================
  41. |**| PUBLIC FUNCTIONS
  42. |**| ==============================================================================
  43. \**/
  44.  
  45.  
  46. /*------------------------------------------------------------------------------*\
  47.     GXPrinting_present
  48.  *------------------------------------------------------------------------------*
  49.         This function returns noErr if QuickDraw GX graphics and typography are present
  50.         (i.e passes gestalt) and returns an error otherwise.
  51.         It also sets the global gGXPrinting_present_err based on the result.
  52. \*------------------------------------------------------------------------------*/
  53. OSErr GXPrinting_present ( void ) 
  54. {
  55.     OSErr err;
  56.     long response;
  57.  
  58.     if ( !gGXPrinting_present_err )
  59.         return noErr ;
  60.     
  61.     err = Gestalt(gestaltGXPrintingMgrVersion, &response) ;
  62.      
  63. #ifdef powerc
  64.     // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed
  65.     // just in case we are "weak" linked against QuickDrawGXLib
  66.     if (!err)
  67.         if ( kUnresolvedCFragSymbolAddress == (long)GXNewGraphicsClient) 
  68.             err = 1;                // QuickDraw GX is not available in Power Mac
  69. #endif
  70.  
  71.     gGXPrinting_present_err = err;
  72.     return err;
  73. }
  74.  
  75.  
  76. /*------------------------------------------------------------------------------*\
  77.     GXPrinting_available
  78.  *------------------------------------------------------------------------------*
  79.         This function returns noErr if QuickDraw GX printing is available
  80.         (i.e present and initialized) to the application and returns an error otherwise.
  81.         It also sets the global gGX_available_err based on the return value.
  82. \*------------------------------------------------------------------------------*/
  83. OSErr GXPrinting_available ( void ) 
  84. {
  85.     OSErr err ;
  86.  
  87.     err = GXPrinting_present();
  88.     if ( !err )
  89.         err = GXPrinting_initialize();
  90.         
  91.     if ( false )                    // there isn't a dtp 
  92.         return 1 ;                     // should return something else
  93.  
  94.     gGXPrinting_available_err = err;
  95.      return err ;
  96. }
  97.  
  98.  
  99. /*------------------------------------------------------------------------------*\
  100.     GXPrinting_initialize
  101.  *------------------------------------------------------------------------------*
  102.         This function initializes all the GX printing stuff.
  103.         It should be called early in the application.
  104. \*------------------------------------------------------------------------------*/
  105. OSErr GXPrinting_initialize ( void ) 
  106. {
  107.     OSErr err ;
  108.  
  109.     if ( !gGXPrinting_initialized_err )
  110.         return noErr;
  111.  
  112.     err = GXPrinting_present();
  113.     if ( !err )
  114.     {
  115.         err = GXInitPrinting() ;
  116.     }
  117.  
  118.     if ( !err ) 
  119.     {     // Initialize our printing event override UPP
  120.         gQDGXPrintingEventUPP = NewGXPrintingEventProc(PrintingEventProc) ;
  121.     }
  122.  
  123.     gGXPrinting_initialized_err = err;
  124.     return err ;
  125. }
  126.  
  127.  
  128. /*------------------------------------------------------------------------------*\
  129.     DisposeGXPrinting
  130.  *------------------------------------------------------------------------------*
  131.         This function disposes all the GX printing stuff.
  132.         It should be called before the application exits.
  133. \*------------------------------------------------------------------------------*/
  134. void DisposeGXPrinting ( void ) 
  135. {
  136.     if( !gGXPrinting_initialized_err )
  137.     {
  138.         DisposeRoutineDescriptor(gQDGXPrintingEventUPP) ;
  139.         GXExitPrinting() ;
  140.         gGXPrinting_initialized_err = 1;
  141.     }
  142. }
  143.  
  144.  
  145. /*------------------------------------------------------------------------------*\
  146.     GetDefaultGXJob
  147.  *------------------------------------------------------------------------------*
  148.         This routine sets up the default GX Job object.
  149. \*------------------------------------------------------------------------------*/
  150. OSErr GetDefaultGXJob ( gxJob *theJob )
  151. {
  152.     OSErr err ;
  153.     
  154.     err = GXNewJob( theJob ) ;
  155.     if (err)
  156.         *theJob = nil ;
  157.     else
  158.         GXInstallApplicationOverride( *theJob, gxPrintingEventMsg, gQDGXPrintingEventUPP) ;
  159.     return err ;
  160. }
  161.  
  162.  
  163. /*------------------------------------------------------------------------------*\
  164.     LoadResourceGXJob
  165.  *------------------------------------------------------------------------------*
  166.         This routine loads a print handle resource with the resType r_printJobType
  167.         If there is no print record resource in the indicated resource file,
  168.         the function returns resNotFound.
  169.         Upon entry, theJob is expected to be a valid job or nil.
  170. \*------------------------------------------------------------------------------*/
  171. OSErr LoadResourceGXJob ( gxJob *theJob, FSSpec *spec ) 
  172. {
  173.     short        savedRefNum;
  174.     short        resRefNum;
  175.     Handle        resHandle;
  176.     OSErr        err = noErr ;
  177.  
  178.     resRefNum = FSpOpenResFile( spec, fsRdPerm) ;
  179.     if (resRefNum == -1)
  180.         return fnfErr ;
  181.         
  182.     savedRefNum = CurResFile() ;                // Save the current resource file refNum
  183.     UseResFile( resRefNum ) ;                    // set the current res file
  184.  
  185.     // Get our resource, if there is one
  186.     resHandle = Get1IndResource(r_printJobType,1) ;
  187.     if ( resHandle==nil )
  188.     {    // check for and old THPrint rec and convert it if found
  189.         resHandle = Get1IndResource(r_printHdlType,1) ;
  190.         if ( resHandle != nil )
  191.         {
  192.             if (*theJob==nil) GXNewJob(theJob) ;
  193.             GXConvertPrintRecord( *theJob, (THPrint)resHandle ) ;
  194.             err = GXGetJobError( *theJob ) ;
  195.         }
  196.         else
  197.             err = ResError() ;
  198.     }
  199.     else
  200.     {
  201.         if (*theJob==nil) GXNewJob(theJob) ;
  202.         GXUnflattenJobFromHdl( *theJob, resHandle ) ;
  203.         err = GXGetJobError( *theJob ) ;
  204.     }
  205.  
  206.     if ( resHandle) ReleaseResource( resHandle ) ;
  207.     CloseResFile( resRefNum ) ;
  208.     UseResFile( savedRefNum ) ;                // switch back to the original resource file.
  209.     return err ;
  210. }
  211.  
  212.  
  213. /*------------------------------------------------------------------------------*\
  214.     SaveResourceGXJob
  215.  *------------------------------------------------------------------------------*
  216.         This routine saves the passed print job in resource fork of the 
  217.         indicated file. If there are already a print record resources, they are
  218.         deleted and replaced.
  219. \*------------------------------------------------------------------------------*/
  220. OSErr SaveResourceGXJob ( gxJob theJob, FSSpec *spec ) 
  221. {
  222.     short        savedRefNum, uniqID;
  223.     OSErr        err = noErr ;
  224.     Handle        oldHdl, resHandle;
  225.     short        resRefNum;
  226.     
  227.     resRefNum = FSpOpenResFile( spec, fsWrPerm ) ;
  228.     if (resRefNum == -1)
  229.         return fnfErr ;
  230.         
  231.     // flatten the job to a handle.
  232.     resHandle = NewHandle(0) ;
  233.     GXFlattenJobToHdl( theJob, resHandle ) ;
  234.     err = GXGetJobError( theJob ) ;
  235.  
  236.     if (!err)
  237.     {
  238.         savedRefNum = CurResFile() ;            // Save the current resource file refNum
  239.         UseResFile(resRefNum) ;                    // set the current res file
  240.         
  241.         // remove any existing resources
  242.         while ( (oldHdl=Get1IndResource(r_printHdlType,1)) != nil )
  243.         {
  244.             RemoveResource(oldHdl) ;                // remove the resource from the file
  245.             DisposeHandle(oldHdl) ;                // free the handle that is left behind
  246.         }
  247.         while ( (oldHdl=Get1IndResource(r_printJobType,1)) != nil )
  248.         {
  249.             RemoveResource(oldHdl) ;                // remove the resource from the file
  250.             DisposeHandle(oldHdl) ;                // free the handle that is left behind
  251.         }
  252.         
  253.         // Save the new resource with a unique ID.
  254.         uniqID = Unique1ID( r_printHdlType ) ;
  255.         AddResource( resHandle, r_printJobType, uniqID, "\p") ;
  256.         err = ResError() ;
  257.  
  258.         UseResFile(savedRefNum) ;                // switch back to the original resource file.
  259.     }
  260.  
  261.     CloseResFile( resRefNum ) ;
  262.     FlushVol( nil , spec->vRefNum ) ;
  263.     return noErr ;
  264. }
  265.  
  266.  
  267. /*------------------------------------------------------------------------------*\
  268.     GXGetPageSize
  269.  *------------------------------------------------------------------------------*
  270. \*------------------------------------------------------------------------------*/
  271. OSErr GXGetPageSize ( gxJob theJob, Rect *pageRect )
  272. {
  273.     gxFormat        pageFormat;
  274.     gxRectangle        gxpage ;
  275.     
  276.     pageFormat = GXGetJobFormat( theJob, 1) ;
  277.     GXGetFormatDimensions( pageFormat, &gxpage, nil ) ;        // get the pageSize
  278.     pageRect->top = FixedToInt( gxpage.top ) ;                // convert it to a regular rect
  279.     pageRect->left = FixedToInt( gxpage.left ) ;
  280.     pageRect->bottom = FixedToInt( gxpage.bottom ) ;
  281.     pageRect->right = FixedToInt( gxpage.right ) ;
  282.     
  283.     return noErr ;
  284. }
  285.  
  286.  
  287. /*------------------------------------------------------------------------------*\
  288.     GXStyleDlog
  289.  *------------------------------------------------------------------------------*
  290.         This routine displays the GX Page Setup dialog (a.k.a. Format dialog)
  291. \*------------------------------------------------------------------------------*/
  292. OSErr GXStyleDlog ( gxJob theJob )
  293. {
  294.     OSErr            err ;
  295.     gxDialogResult    result;
  296.     
  297.     result = GXJobDefaultFormatDialog(theJob, &gQDGXEditMenuRec) ;
  298.     if ( result == gxCancelSelected )
  299.         return userCanceledErr ;
  300.         
  301.     // just check we don't have an error    
  302.     err = GXGetJobError(theJob) ;
  303.     return err ;
  304. }
  305.  
  306.  
  307. /*------------------------------------------------------------------------------*\
  308.     GXStyleDlog
  309.  *------------------------------------------------------------------------------*
  310.         This routine displays the GX Print dialog (a.k.a. Job dialog)
  311. \*------------------------------------------------------------------------------*/
  312. OSErr GXJobDlog ( gxJob theJob )
  313. {
  314.     OSErr            err ;
  315.     gxDialogResult     result;
  316.     
  317.     result = GXJobPrintDialog( theJob, &gQDGXEditMenuRec ) ;
  318.     if ( result == gxCancelSelected )
  319.         return userCanceledErr ;
  320.     
  321.     // just check we don't have an error    
  322.     err = GXGetJobError(theJob) ;
  323.     return err ;
  324. }
  325.  
  326.  
  327. /*------------------------------------------------------------------------------*\
  328.     GXPrintLoopBegin
  329.  *------------------------------------------------------------------------------*
  330. \*------------------------------------------------------------------------------*/
  331. OSErr GXPrintLoopBegin ( GXPrintLoopParamsPtr params ) 
  332. {
  333.     OSErr                err ;
  334.     long                jobFirst, jobLast ;
  335.     Str255                title ;
  336.  
  337.     err = GXGetJobError( params->theJob ) ;
  338.     if (err) goto StartJobFailed ;
  339.  
  340.     //    Determine which pages the user selected to print.
  341.     //    If the user specifies a range that is greater than the actual number
  342.     //    of pages, then only print those pages that are in the document. 
  343.     GXGetJobPageRange( params->theJob, &jobFirst, &jobLast) ;
  344.     if (jobFirst > params->firstPage) params->firstPage = jobFirst;
  345.     if (jobLast  < params->lastPage ) params->lastPage = jobLast;
  346.  
  347.     //    begin printing if there are no errors.
  348.     GetWTitle ( params->window, title ) ;
  349.     GXStartJob( params->theJob, title, params->lastPage - params->firstPage + 1 ) ;
  350.     err = GXGetJobError( params->theJob ) ;
  351.     if (err) goto StartJobFailed ;
  352.  
  353.     //    Create a new viewport for printing. 
  354.     params->printViewPort = GXNewViewPort( gxScreenViewDevices ) ;
  355.     params->printingPort = (GrafPtr)(params->window) ;
  356.  
  357. StartJobFailed:
  358.     return err ;
  359. }
  360.  
  361.  
  362. /*------------------------------------------------------------------------------*\
  363.     GXPrintLoopPageBefore
  364.  *------------------------------------------------------------------------------*
  365. \*------------------------------------------------------------------------------*/
  366. OSErr GXPrintLoopPageBefore ( GXPrintLoopParamsPtr params ) 
  367. {
  368.     gxFormat        pageFormat;
  369.     Point            patStretch = {1,1};
  370.     Rect            everywhereRect = {0,0,32767,32767};
  371.     OSErr            err ;
  372.  
  373.     pageFormat = GXGetJobFormat( params->theJob, 1) ;
  374.     GXStartPage( params->theJob,
  375.                  params->currentPage - params->firstPage + 1,
  376.                  pageFormat,
  377.                  1, &(params->printViewPort) ) ;                                
  378.  
  379.     // Setup the translator.
  380.     GXInstallQDTranslator(    params->printingPort, gxDefaultOptionsTranslation,
  381.                             &everywhereRect, &everywhereRect,
  382.                             patStretch, NewgxShapeSpoolProc(MyGXPrintAShape),
  383.                             (void*)params->printViewPort) ;
  384.  
  385.     err = GXGetJobError( params->theJob ) ;
  386.     return err ;
  387. }
  388.  
  389.  
  390. /*------------------------------------------------------------------------------*\
  391.     GXPrintLoopPageAfter
  392.  *------------------------------------------------------------------------------*
  393. \*------------------------------------------------------------------------------*/
  394. OSErr GXPrintLoopPageAfter ( GXPrintLoopParamsPtr params ) 
  395. {
  396.     OSErr            err ;
  397.  
  398.     GXRemoveQDTranslator( params->printingPort, nil ) ;
  399.     // should dispose of MyPrintShape UPP
  400.     GXFinishPage( params->theJob ) ;
  401.     err = GXGetJobError( params->theJob ) ;
  402.     return noErr ;
  403. }
  404.  
  405.  
  406. /*------------------------------------------------------------------------------*\
  407.     GXPrintLoopEnd
  408.  *------------------------------------------------------------------------------*
  409. \*------------------------------------------------------------------------------*/
  410. OSErr GXPrintLoopEnd ( GXPrintLoopParamsPtr params ) 
  411. {
  412.     OSErr            err ;
  413.  
  414.     GXFinishJob( params->theJob ) ;
  415.     err = GXGetJobError( params->theJob ) ;
  416.     GXDisposeViewPort( params->printViewPort ) ;
  417.     return err ;
  418. }
  419.  
  420.  
  421. /**\
  422. |**| ==============================================================================
  423. |**| PRIVATE FUNCTIONS
  424. |**| ==============================================================================
  425. \**/
  426.  
  427.  
  428. /*------------------------------------------------------------------------------*\
  429.     PrintingEventProc
  430.  *------------------------------------------------------------------------------*
  431.         This routine handles update and menu events while a GX movable-modal
  432.         printing dialog box is displayed.  It is installed by InitGXPrinting()
  433.         and remover by RemoveGXPrinting()
  434. \*------------------------------------------------------------------------------*/
  435. static OSErr PrintingEventProc ( EventRecord *anEvent, Boolean filterEvent )
  436. {
  437.     if (!filterEvent)
  438.     {
  439.         switch (anEvent->what)
  440.         {
  441.             case mouseDown:
  442.             case keyDown:
  443.             case autoKey:
  444.                 break;
  445.             default:
  446.                 DoEvent(anEvent) ;
  447.         }
  448.     }
  449.     return(noErr) ;
  450. }
  451.  
  452.  
  453. /*------------------------------------------------------------------------------*\
  454.     MyGXPrintAShape
  455.  *------------------------------------------------------------------------------*
  456.         This is a spool proc for the QD-to-QDGX translator routines. In this 
  457.         routine, we simply draw each shape we're passed (printing it).
  458.         You could also capture each shape into one gxPicture shape, and then do
  459.         one draw of that picture afterwards.
  460. \*------------------------------------------------------------------------------*/
  461. static OSErr MyGXPrintAShape ( gxShape currentShape, void* refCon )
  462. {
  463.     GXSetShapeViewPorts(currentShape, 1, (gxViewPort*) refCon) ;
  464.     GXDrawShape(currentShape) ;
  465.     return ( GXGetGraphicsError(nil) ) ;
  466. }
  467.