]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/core/printmac.cpp
Applied Blit system options optimization to StretchBlit
[wxWidgets.git] / src / osx / core / printmac.cpp
index 0fafe8105c09d2ee5672bbfe5b68651dfaffb86d..9b1eded8fe430ecab38cc8ea4d28a8afb7af4d0e 100644 (file)
 
 #include <stdlib.h>
 
-IMPLEMENT_DYNAMIC_CLASS(wxMacCarbonPrintData, wxPrintNativeDataBase)
-IMPLEMENT_DYNAMIC_CLASS(wxMacPrinter, wxPrinterBase)
-IMPLEMENT_CLASS(wxMacPrintPreview, wxPrintPreviewBase)
+//
+// move to print_osx.cpp
+//
 
-bool wxMacCarbonPrintData::IsOk() const
+static int ResolutionSorter(const void *e1, const void *e2)
 {
-    return (m_macPageFormat != kPMNoPageFormat) && (m_macPrintSettings != kPMNoPrintSettings) && (m_macPrintSession != kPMNoReference);
-}
-wxMacCarbonPrintData::wxMacCarbonPrintData()
-{
-    m_macPageFormat = kPMNoPageFormat;
-    m_macPrintSettings = kPMNoPrintSettings;
-    m_macPrintSession = kPMNoReference ;
-    ValidateOrCreate() ;
+    const PMResolution *res1 = (const PMResolution *)e1;
+    const PMResolution *res2 = (const PMResolution *)e2;
+    const double area1 = res1->hRes * res1->vRes;
+    const double area2 = res2->hRes * res2->vRes;
+
+    if (area1 < area2)
+        return -1;
+    else if (area1 > area2)
+        return 1;
+    else
+        return 0;
 }
 
-wxMacCarbonPrintData::~wxMacCarbonPrintData()
+static PMResolution *GetSupportedResolutions(PMPrinter printer, UInt32 *count)
 {
-    if (m_macPageFormat != kPMNoPageFormat)
+    PMResolution res, *resolutions = NULL;
+    OSStatus status = PMPrinterGetPrinterResolutionCount(printer, count);
+    if (status == kPMNotImplemented)
     {
-        (void)PMRelease(m_macPageFormat);
-        m_macPageFormat = kPMNoPageFormat;
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+        resolutions = (PMResolution *)malloc(sizeof(PMResolution) * 4);
+        *count = 0;
+        if (PMPrinterGetPrinterResolution(printer, kPMMinRange, &res) == noErr)
+            resolutions[(*count)++] = res;
+        if (PMPrinterGetPrinterResolution(printer, kPMMinSquareResolution, &res) == noErr)
+            resolutions[(*count)++] = res;
+        if (PMPrinterGetPrinterResolution(printer, kPMMaxSquareResolution, &res) == noErr)
+            resolutions[(*count)++] = res;
+        if (PMPrinterGetPrinterResolution(printer, kPMMaxRange, &res) == noErr)
+            resolutions[(*count)++] = res;
+        if (*count == 0)
+        {
+            if (PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &res) == noErr)
+                resolutions[(*count)++] = res;
+        }
+#endif
     }
-
-    if (m_macPrintSettings != kPMNoPrintSettings)
+    else if (status == noErr)
     {
-        (void)PMRelease(m_macPrintSettings);
-        m_macPrintSettings = kPMNoPrintSettings;
-    }
+        resolutions = (PMResolution *)malloc(sizeof(PMResolution) * (*count));
+        UInt32 realCount = 0;
+        for (UInt32 i = 0; i < *count; i++)
+        {
+            if (PMPrinterGetIndexedPrinterResolution(printer, i + 1, &res) == noErr)
+                resolutions[realCount++] = res;
+        }
+        qsort(resolutions, realCount, sizeof(PMResolution), ResolutionSorter);
 
-    if ( m_macPrintSession != kPMNoReference )
+        *count = realCount;
+    }
+    if ((*count == 0) && (resolutions))
     {
-        (void)PMRelease(m_macPrintSession);
-        m_macPrintSession = kPMNoReference;
+        free(resolutions);
+        resolutions = NULL;
     }
+    return resolutions;
 }
 
-void wxMacCarbonPrintData::ValidateOrCreate()
+
+
+IMPLEMENT_DYNAMIC_CLASS(wxOSXPrintData, wxPrintNativeDataBase)
+
+bool wxOSXPrintData::IsOk() const
 {
-    OSStatus err = noErr ;
-    if ( m_macPrintSession == kPMNoReference )
-    {
-        err = PMCreateSession( &m_macPrintSession ) ;
-    }
-    //  Set up a valid PageFormat object.
-    if ( m_macPageFormat == kPMNoPageFormat)
-    {
-        err = PMCreatePageFormat(&m_macPageFormat);
+    return (m_macPageFormat != kPMNoPageFormat) && (m_macPrintSettings != kPMNoPrintSettings) && (m_macPrintSession != kPMNoReference);
+}
 
-        //  Note that PMPageFormat is not session-specific, but calling
-        //  PMSessionDefaultPageFormat assigns values specific to the printer
-        //  associated with the current printing session.
-        if ((err == noErr) &&
-            ( m_macPageFormat != kPMNoPageFormat))
-        {
-            err = PMSessionDefaultPageFormat(m_macPrintSession,
-                m_macPageFormat);
-        }
-    }
-    else
-    {
-        err = PMSessionValidatePageFormat(m_macPrintSession,
-            m_macPageFormat,
-            kPMDontWantBoolean);
-    }
+wxOSXPrintData::wxOSXPrintData()
+{
+    m_macPageFormat = kPMNoPageFormat;
+    m_macPrintSettings = kPMNoPrintSettings;
+    m_macPrintSession = kPMNoReference ;
+    m_macPaper = kPMNoData;
+}
 
-    //  Set up a valid PrintSettings object.
-    if ( m_macPrintSettings == kPMNoPrintSettings)
-    {
-        err = PMCreatePrintSettings( &m_macPrintSettings);
+wxOSXPrintData::~wxOSXPrintData()
+{
+}
 
-        //  Note that PMPrintSettings is not session-specific, but calling
-        //  PMSessionDefaultPrintSettings assigns values specific to the printer
-        //  associated with the current printing session.
-        if ((err == noErr) &&
-            ( m_macPrintSettings != kPMNoPrintSettings))
-        {
-            err = PMSessionDefaultPrintSettings(m_macPrintSession,
-               m_macPrintSettings);
-        }
-    }
-    else
-    {
-        err = PMSessionValidatePrintSettings( m_macPrintSession,
-            m_macPrintSettings,
-            kPMDontWantBoolean);
-    }
+void wxOSXPrintData::UpdateFromPMState()
+{
+}
+
+void wxOSXPrintData::UpdateToPMState()
+{
 }
 
-bool wxMacCarbonPrintData::TransferFrom( const wxPrintData &data )
+void wxOSXPrintData::TransferPrinterNameFrom( const wxPrintData &data )
 {
     CFArrayRef printerList;
     CFIndex index, count;
-    PMPrinter printer;
     CFStringRef name;
-    
-    ValidateOrCreate() ;
-    
+
     if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr)
     {
+        PMPrinter printer = NULL;
         count = CFArrayGetCount(printerList);
         for (index = 0; index < count; index++)
         {
@@ -153,24 +155,106 @@ bool wxMacCarbonPrintData::TransferFrom( const wxPrintData &data )
             }
         }
         if (index < count)
-            PMSessionSetCurrentPMPrinter((PMPrintSession)m_macPrintSession, printer);
+            PMSessionSetCurrentPMPrinter(m_macPrintSession, printer);
         CFRelease(printerList);
     }
-    
-    PMSetCopies( m_macPrintSettings , data.GetNoCopies() , false ) ;
-    PMSetCollate(m_macPrintSettings, data.GetCollate());
-    
-#if wxOSX_USE_CARBON
-    PMColorMode color ;
-    PMGetColorMode(  (PMPrintSettings) m_macPrintSettings, &color ) ;
-    if ( data.GetColour() )
+}
+
+void wxOSXPrintData::TransferPaperInfoFrom( const wxPrintData &data )
+{
+    PMPrinter printer;
+    PMSessionGetCurrentPrinter(m_macPrintSession, &printer);
+
+    wxSize papersize = wxDefaultSize;
+    const wxPaperSize paperId = data.GetPaperId();
+    if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase )
     {
-        if ( color == kPMBlackAndWhite )
-            PMSetColorMode( (PMPrintSettings) m_macPrintSettings, kPMColor ) ;
+        papersize = wxThePrintPaperDatabase->GetSize(paperId);
+        if ( papersize != wxDefaultSize )
+        {
+            papersize.x /= 10;
+            papersize.y /= 10;
+        }
     }
     else
-        PMSetColorMode( (PMPrintSettings) m_macPrintSettings, kPMBlackAndWhite ) ;
+    {
+        papersize = data.GetPaperSize();
+    }
+
+    if ( papersize != wxDefaultSize )
+    {
+        papersize.x = (wxInt32) (papersize.x * mm2pt);
+        papersize.y = (wxInt32) (papersize.y * mm2pt);
+
+        double height, width;
+        PMPaperGetHeight(m_macPaper, &height);
+        PMPaperGetWidth(m_macPaper, &width);
+
+        if ( fabs( width - papersize.x ) >= 5 ||
+            fabs( height - papersize.y ) >= 5 )
+        {
+            // we have to change the current paper
+            CFArrayRef paperlist = 0 ;
+            if ( PMPrinterGetPaperList( printer, &paperlist ) == noErr )
+            {
+                PMPaper bestPaper = kPMNoData ;
+                CFIndex top = CFArrayGetCount(paperlist);
+                for ( CFIndex i = 0 ; i < top ; ++ i )
+                {
+                    PMPaper paper = (PMPaper) CFArrayGetValueAtIndex( paperlist, i );
+                    PMPaperGetHeight(paper, &height);
+                    PMPaperGetWidth(paper, &width);
+                    if ( fabs( width - papersize.x ) < 5 &&
+                        fabs( height - papersize.y ) < 5 )
+                    {
+                        // TODO test for duplicate hits and use additional
+                        // criteria for best match
+                        bestPaper = paper;
+                    }
+                }
+                PMPaper paper = kPMNoData;
+                if ( bestPaper == kPMNoData )
+                {
+                    const PMPaperMargins margins = { 0.0, 0.0, 0.0, 0.0 };
+                    wxString id, name(wxT("Custom paper"));
+                    id.Printf(wxT("wxPaperCustom%dx%d"), papersize.x, papersize.y);
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+                    if ( PMPaperCreateCustom != NULL)
+                    {
+                        PMPaperCreateCustom(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ),
+                                            papersize.x, papersize.y, &margins, &paper);
+                    }
+#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+                    if ( paper == kPMNoData )
+                    {
+                        PMPaperCreate(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ),
+                                      papersize.x, papersize.y, &margins, &paper);
+                    }
 #endif
+                }
+                if ( bestPaper != kPMNoData )
+                {
+                    PMPageFormat pageFormat;
+                    PMCreatePageFormatWithPMPaper(&pageFormat, bestPaper);
+                    PMCopyPageFormat( pageFormat, m_macPageFormat );
+                    PMRelease(pageFormat);
+                    PMGetPageFormatPaper(m_macPageFormat, &m_macPaper);
+                }
+                PMRelease(paper);
+            }
+        }
+    }
+
+    PMSetCopies( m_macPrintSettings , data.GetNoCopies() , false ) ;
+    PMSetCollate(m_macPrintSettings, data.GetCollate());
+    if ( data.IsOrientationReversed() )
+        PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
+                         kPMReverseLandscape : kPMReversePortrait , false ) ;
+    else
+        PMSetOrientation( m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
+                         kPMLandscape : kPMPortrait , false ) ;
 
     PMDuplexMode mode = 0 ;
     switch( data.GetDuplex() )
@@ -186,100 +270,87 @@ bool wxMacCarbonPrintData::TransferFrom( const wxPrintData &data )
             mode = kPMDuplexNone ;
             break ;
     }
-    PMSetDuplex( (PMPrintSettings) m_macPrintSettings, mode ) ;
+    PMSetDuplex(  m_macPrintSettings, mode ) ;
 
-    // PMQualityMode not yet accessible via API
-    
-    PMResolution res;
+
+    if ( data.IsOrientationReversed() )
+        PMSetOrientation(  m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
+                         kPMReverseLandscape : kPMReversePortrait , false ) ;
+    else
+        PMSetOrientation(  m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
+                         kPMLandscape : kPMPortrait , false ) ;
+}
+
+void wxOSXPrintData::TransferResolutionFrom( const wxPrintData &data )
+{
+    PMPrinter printer;
     PMSessionGetCurrentPrinter(m_macPrintSession, &printer);
 
-    bool found = false;
-    CFArrayRef formatList;
-    PMSessionCreatePageFormatList(m_macPrintSession, printer, &formatList);
-    if (formatList)
-    {
-        count = CFArrayGetCount(formatList);
-        for (index = 0; index < count; index++)
-        {
-            PMPageFormat temp = (PMPageFormat)CFArrayGetValueAtIndex(formatList, index);
-            PMRect rPaper;
-            PMGetUnadjustedPaperRect(temp, &rPaper);
-            wxSize sz((int)(( rPaper.right - rPaper.left ) * pt2mm + 0.5 ) ,
-                 (int)(( rPaper.bottom - rPaper.top ) * pt2mm + 0.5 ));
-            wxPaperSize id = wxThePrintPaperDatabase->GetSize(wxSize(sz.x* 10, sz.y * 10));
-            if (((data.GetPaperId() != wxPAPER_NONE) && (id == data.GetPaperId())) ||
-                ((data.GetPaperId() == wxPAPER_NONE) && (sz == data.GetPaperSize())))
-            {
-                PMCopyPageFormat(temp, m_macPageFormat);
-                found = true;
-                break;
-            }
-        }
-        CFRelease(formatList);
-    }
-    if (!found)
+    UInt32 resCount;
+    PMResolution *resolutions = GetSupportedResolutions(printer, &resCount);
+    if (resolutions)
     {
-        PMPaper paper;
-        const PMPaperMargins margins = { 0.0, 0.0, 0.0, 0.0 };
-        wxString id, name(_T("Custom paper"));
-        wxSize sz;
-        double width, height;
-        
-        id.Printf(_T("wxPaperCustom%dx%d"), sz.x, sz.y);
-        if (data.GetPaperId() == wxPAPER_NONE)
-            sz = data.GetPaperSize();
+        wxPrintQuality quality = data.GetQuality();
+        if (quality >= 0)
+            quality = wxPRINT_QUALITY_HIGH;
+
+        PMResolution res = resolutions[((quality - wxPRINT_QUALITY_DRAFT) * (resCount - 1)) / 3];
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+        if ( PMPrinterSetOutputResolution != NULL )
+            PMPrinterSetOutputResolution(printer, m_macPrintSettings, &res);
         else
-            sz = wxThePrintPaperDatabase->GetSize(data.GetPaperId());
-        width = ((double)sz.x / 10.0) * mm2pt;
-        height = ((double)sz.y / 10.0) * mm2pt;
-        
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 
-        PMPaperCreate(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ), width, height, &margins, &paper);
-#else
-        if (PMPaperCreateCustom(printer, wxCFStringRef( id, wxFont::GetDefaultEncoding() ), wxCFStringRef( name, wxFont::GetDefaultEncoding() ), width, height, &margins, &paper) != noErr)
-            paper = NULL;
 #endif
-        if (paper)
         {
-            PMPageFormat temp;
-            if (PMCreatePageFormatWithPMPaper(&temp, paper) == noErr) {
-                PMCopyPageFormat(temp, m_macPageFormat);
-                PMRelease(temp);
-            }
-            PMRelease(paper);
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+            PMSetResolution( m_macPageFormat, &res);
+#endif
         }
+
+        free(resolutions);
     }
-    
-    if ( data.IsOrientationReversed() )
-        PMSetOrientation( (PMPageFormat) m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
-            kPMReverseLandscape : kPMReversePortrait , false ) ;
-    else
-        PMSetOrientation( (PMPageFormat) m_macPageFormat , ( data.GetOrientation() == wxLANDSCAPE ) ?
-            kPMLandscape : kPMPortrait , false ) ;
-    
-#if wxOSX_USE_CARBON
-    PMTag tag = kPMMaxSquareResolution;
-    PMPrinterGetPrinterResolution(printer, tag, &res);
-    PMSetResolution((PMPageFormat) m_macPageFormat, &res);
-#else
-    PMPrinterGetOutputResolution( printer,  
-        (PMPrintSettings) m_macPrintSettings,  &res) ;
-    // TODO transfer ? into page format ?
-    // may fail !
-#endif
-    // after setting the new resolution the format has to be updated, otherwise the page rect remains 
+}
+
+bool wxOSXPrintData::TransferFrom( const wxPrintData &data )
+{
+    TransferPrinterNameFrom(data);
+    TransferPaperInfoFrom(data);
+    TransferResolutionFrom(data);
+
+    // after setting the new resolution the format has to be updated, otherwise the page rect remains
     // at the 'old' scaling
-    PMSessionValidatePageFormat((PMPrintSession) m_macPrintSession,
-            (PMPageFormat) m_macPageFormat,
-            kPMDontWantBoolean) ;
+
+    PMSessionValidatePageFormat(m_macPrintSession,
+                                m_macPageFormat, kPMDontWantBoolean);
+    PMSessionValidatePrintSettings(m_macPrintSession,
+                                   m_macPrintSettings, kPMDontWantBoolean);
+
+#if wxOSX_USE_COCOA
+    UpdateFromPMState();
+#endif
 
     return true ;
 }
 
-bool wxMacCarbonPrintData::TransferTo( wxPrintData &data )
+void wxOSXPrintData::TransferPrinterNameTo( wxPrintData &data )
 {
-    OSStatus err = noErr ;
+    CFStringRef name;
+    PMPrinter printer ;
+    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
+    if (PMPrinterIsDefault(printer))
+        data.SetPrinterName(wxEmptyString);
+    else
+    {
+        name = PMPrinterGetName(printer);
+        CFRetain(name);
+        data.SetPrinterName(wxCFStringRef(name).AsString());
+    }
+}
 
+void wxOSXPrintData::TransferPaperInfoTo( wxPrintData &data )
+{
+    PMPrinter printer ;
+    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
+    OSStatus err = noErr ;
     UInt32 copies ;
     err = PMGetCopies( m_macPrintSettings , &copies ) ;
     if ( err == noErr )
@@ -304,27 +375,10 @@ bool wxMacCarbonPrintData::TransferTo( wxPrintData &data )
     Boolean collate;
     if (PMGetCollate(m_macPrintSettings, &collate) == noErr)
         data.SetCollate(collate);
-    
-    CFStringRef name;
-    PMPrinter printer ;
-    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
-    if (PMPrinterIsDefault(printer))
-        data.SetPrinterName(wxEmptyString);
-    else
-    {
-        name = PMPrinterGetName(printer);
-        CFRetain(name);
-        data.SetPrinterName(wxCFStringRef(name).AsString());
-    }
-    
-#ifndef __LP64__
-    PMColorMode color ;
-    err = PMGetColorMode( m_macPrintSettings, &color ) ;
-    if ( err == noErr )
-        data.SetColour( !(color == kPMBlackAndWhite) ) ;
-#endif
+
+
     PMDuplexMode mode = 0 ;
-    PMGetDuplex( (PMPrintSettings) m_macPrintSettings, &mode ) ;
+    PMGetDuplex(  m_macPrintSettings, &mode ) ;
     switch( mode )
     {
         case kPMDuplexNoTumble :
@@ -338,33 +392,86 @@ bool wxMacCarbonPrintData::TransferTo( wxPrintData &data )
             data.SetDuplex(wxDUPLEX_SIMPLEX);
             break ;
     }
-    // PMQualityMode not yet accessible via API
-    
-    PMPaper paper ;
-    PMGetPageFormatPaper( m_macPageFormat, &paper );
-    
-    PMRect rPaper;
-    err = PMGetUnadjustedPaperRect( m_macPageFormat, &rPaper);
-    if ( err == noErr )
+
+    double height, width;
+    PMPaperGetHeight(m_macPaper, &height);
+    PMPaperGetWidth(m_macPaper, &width);
+
+    wxSize sz((int)(width * pt2mm + 0.5 ) ,
+              (int)(height * pt2mm + 0.5 ));
+    data.SetPaperSize(sz);
+    wxPaperSize id = wxThePrintPaperDatabase->GetSize(wxSize(sz.x* 10, sz.y * 10));
+    if (id != wxPAPER_NONE)
     {
-        wxSize sz((int)(( rPaper.right - rPaper.left ) * pt2mm + 0.5 ) * 10,
-             (int)(( rPaper.bottom - rPaper.top ) * pt2mm + 0.5 ) * 10);
-        data.SetPaperSize(sz);
-        wxPaperSize id = wxThePrintPaperDatabase->GetSize(sz);
         data.SetPaperId(id);
     }
+}
+
+void wxOSXPrintData::TransferResolutionTo( wxPrintData &data )
+{
+    PMPrinter printer ;
+    PMSessionGetCurrentPrinter( m_macPrintSession, &printer );
+
+    /* assume high quality, will change below if we are able to */
+    data.SetQuality(wxPRINT_QUALITY_HIGH);
+
+    PMResolution *resolutions;
+    UInt32 resCount;
+    resolutions = GetSupportedResolutions(printer, &resCount);
+    if (resolutions)
+    {
+        bool valid = false;
+        PMResolution res;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+        if ( PMPrinterGetOutputResolution != NULL )
+        {
+            if ( PMPrinterGetOutputResolution(printer, m_macPrintSettings, &res) == noErr )
+                valid = true;
+        }
+#endif
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+        if (PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &res) == noErr)
+            valid = true;
+#endif
+        if ( valid )
+        {
+            UInt32 i;
+            for (i = 0; i < resCount; i++)
+            {
+                if ((resolutions[i].hRes == res.hRes) && (resolutions[i].vRes = res.vRes))
+                    break;
+            }
+            if (i < resCount)
+                data.SetQuality((((i + 1) * 3) / resCount) + wxPRINT_QUALITY_DRAFT);
+        }
+        free(resolutions);
+    }
+}
+
+bool wxOSXPrintData::TransferTo( wxPrintData &data )
+{
+#if wxOSX_USE_COCOA
+    UpdateToPMState();
+#endif
+
+    TransferPrinterNameTo(data);
+    TransferPaperInfoTo(data);
+    TransferResolutionTo(data);
     return true ;
 }
 
-void wxMacCarbonPrintData::TransferFrom( wxPageSetupData *WXUNUSED(data) )
+void wxOSXPrintData::TransferFrom( wxPageSetupData *WXUNUSED(data) )
 {
     // should we setup the page rect here ?
     // since MacOS sometimes has two same paper rects with different
     // page rects we could make it roundtrip safe perhaps
 }
 
-void wxMacCarbonPrintData::TransferTo( wxPageSetupData* data )
+void wxOSXPrintData::TransferTo( wxPageSetupData* data )
 {
+#if wxOSX_USE_COCOA
+    UpdateToPMState();
+#endif
     PMRect rPaper;
     OSStatus err = PMGetUnadjustedPaperRect(m_macPageFormat, &rPaper);
     if ( err == noErr )
@@ -403,8 +510,11 @@ void wxMacCarbonPrintData::TransferTo( wxPageSetupData* data )
     }
 }
 
-void wxMacCarbonPrintData::TransferTo( wxPrintDialogData* data )
+void wxOSXPrintData::TransferTo( wxPrintDialogData* data )
 {
+#if wxOSX_USE_COCOA
+    UpdateToPMState();
+#endif
     UInt32 minPage , maxPage ;
     PMGetPageRange( m_macPrintSettings , &minPage , &maxPage ) ;
     data->SetMinPage( minPage ) ;
@@ -420,7 +530,7 @@ void wxMacCarbonPrintData::TransferTo( wxPrintDialogData* data )
         data->SetAllPages( true ) ;
         // This means all pages, more or less
         data->SetFromPage(1);
-        data->SetToPage(32000);
+        data->SetToPage(9999);
     }
     else
     {
@@ -430,7 +540,7 @@ void wxMacCarbonPrintData::TransferTo( wxPrintDialogData* data )
     }
 }
 
-void wxMacCarbonPrintData::TransferFrom( wxPrintDialogData* data )
+void wxOSXPrintData::TransferFrom( wxPrintDialogData* data )
 {
     // Respect the value of m_printAllPages
     if ( data->GetAllPages() )
@@ -444,12 +554,28 @@ void wxMacCarbonPrintData::TransferFrom( wxPrintDialogData* data )
         PMSetLastPage( m_macPrintSettings , (UInt32) kPMPrintAllPages, true ) ;
     else
         PMSetLastPage( m_macPrintSettings , (UInt32) data->GetToPage() , false ) ;
+#if wxOSX_USE_COCOA
+    UpdateFromPMState();
+#endif
+}
+
+wxPrintNativeDataBase* wxOSXCreatePrintData()
+{
+#if wxOSX_USE_COCOA
+    return new wxOSXCocoaPrintData();
+#elif wxOSX_USE_CARBON
+    return new wxOSXCarbonPrintData();
+#else
+    return NULL;
+#endif
 }
 
 /*
 * Printer
 */
 
+IMPLEMENT_DYNAMIC_CLASS(wxMacPrinter, wxPrinterBase)
+
 wxMacPrinter::wxMacPrinter(wxPrintDialogData *data):
 wxPrinterBase(data)
 {
@@ -465,9 +591,11 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     sm_abortWindow = NULL;
 
     if (!printout)
+    {
+        sm_lastError = wxPRINTER_ERROR;
         return false;
+    }
 
-    printout->SetIsPreview(false);
     if (m_printDialogData.GetMinPage() < 1)
         m_printDialogData.SetMinPage(1);
     if (m_printDialogData.GetMaxPage() < 1)
@@ -499,16 +627,35 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
 
     // on the mac we have always pixels as addressing mode with 72 dpi
     printout->SetPPIScreen(72, 72);
+
     PMResolution res;
-    wxMacCarbonPrintData* nativeData = (wxMacCarbonPrintData*)
-          (m_printDialogData.GetPrintData().GetNativeData());
-#if wxOSX_USE_CARBON
-    PMGetResolution((PMPageFormat) (nativeData->m_macPageFormat), &res);
-#else 
     PMPrinter printer;
-    PMSessionGetCurrentPrinter(nativeData->m_macPrintSession, &printer);
-    PMPrinterGetOutputResolution( printer, nativeData->m_macPrintSettings, &res) ;
+    wxOSXPrintData* nativeData = (wxOSXPrintData*)
+          (m_printDialogData.GetPrintData().GetNativeData());
+
+    if (PMSessionGetCurrentPrinter(nativeData->GetPrintSession(), &printer) == noErr)
+    {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+        if ( PMPrinterGetOutputResolution != NULL )
+        {
+            if (PMPrinterGetOutputResolution( printer, nativeData->GetPrintSettings(), &res) == -9589 /* kPMKeyNotFound */ )
+            {
+                res.hRes = res.vRes = 300;
+            }
+        }
+        else
+#endif
+        {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
+            PMPrinterGetPrinterResolution(printer, kPMCurrentValue, &res);
 #endif
+        }
+    }
+    else
+    {
+        // fallback
+        res.hRes = res.vRes = 300;
+    }
     printout->SetPPIPrinter(int(res.hRes), int(res.vRes));
 
     // Set printout parameters
@@ -534,11 +681,11 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
 
     if (maxPage == 0)
     {
-        wxEndBusyCursor();
+        sm_lastError = wxPRINTER_ERROR;
         return false;
     }
 
-    // Only set min and max, because from and to have been
+    // Only set min and max, because from and to will be
     // set by the user
     m_printDialogData.SetMinPage(minPage);
     m_printDialogData.SetMaxPage(maxPage);
@@ -560,7 +707,6 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     {
         if (sm_abortIt)
         {
-                keepGoing = false;
                 break;
         }
         else
@@ -577,8 +723,7 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
     if (sm_abortWindow)
     {
         sm_abortWindow->Show(false);
-        delete sm_abortWindow;
-        sm_abortWindow = NULL;
+        wxDELETE(sm_abortWindow);
     }
 
     wxEndBusyCursor();
@@ -590,7 +735,7 @@ bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
 
 wxDC* wxMacPrinter::PrintDialog(wxWindow *parent)
 {
-    wxDC* dc = (wxDC*) NULL;
+    wxDC* dc = NULL;
 
     wxPrintDialog dialog(parent, & m_printDialogData);
     int ret = dialog.ShowModal();
@@ -618,13 +763,15 @@ bool wxMacPrinter::Setup(wxWindow *WXUNUSED(parent))
     return (ret == wxID_OK);
 #endif
 
-    return wxID_CANCEL;
+    return false;
 }
 
 /*
 * Print preview
 */
 
+IMPLEMENT_CLASS(wxMacPrintPreview, wxPrintPreviewBase)
+
 wxMacPrintPreview::wxMacPrintPreview(wxPrintout *printout,
                                      wxPrintout *printoutForPrinting,
                                      wxPrintDialogData *data)
@@ -659,10 +806,10 @@ void wxMacPrintPreview::DetermineScaling(void)
 
     wxSize ppiScreen( 72 , 72 ) ;
     wxSize ppiPrinter( 72 , 72 ) ;
-    
+
     // Note that with Leopard, screen dpi=72 is no longer a given
     m_previewPrintout->SetPPIScreen( ppiScreen.x , ppiScreen.y ) ;
-    
+
     wxCoord w , h ;
     wxCoord ww, hh;
     wxRect paperRect;
@@ -689,7 +836,7 @@ void wxMacPrintPreview::DetermineScaling(void)
     }
     m_pageWidth = w;
     m_pageHeight = h;
-    
+
     m_previewPrintout->SetPageSizePixels(w , h) ;
     m_previewPrintout->SetPageSizeMM(ww, hh);
     m_previewPrintout->SetPaperRectPixels(paperRect);
@@ -699,4 +846,39 @@ void wxMacPrintPreview::DetermineScaling(void)
     m_previewScaleY = float(ppiScreen.y) / ppiPrinter.y;
 }
 
+//
+// end of print_osx.cpp
+//
+
+#if wxOSX_USE_CARBON
+
+IMPLEMENT_DYNAMIC_CLASS(wxOSXCarbonPrintData, wxOSXPrintData)
+
+wxOSXCarbonPrintData::wxOSXCarbonPrintData()
+{
+    if ( PMCreateSession( &m_macPrintSession ) == noErr )
+    {
+        if ( PMCreatePageFormat(&m_macPageFormat) == noErr )
+        {
+            PMSessionDefaultPageFormat(m_macPrintSession,
+                    m_macPageFormat);
+            PMGetPageFormatPaper(m_macPageFormat, &m_macPaper);
+        }
+
+        if ( PMCreatePrintSettings(&m_macPrintSettings) == noErr )
+        {
+            PMSessionDefaultPrintSettings(m_macPrintSession,
+                m_macPrintSettings);
+        }
+    }
+}
+
+wxOSXCarbonPrintData::~wxOSXCarbonPrintData()
+{
+    (void)PMRelease(m_macPageFormat);
+    (void)PMRelease(m_macPrintSettings);
+    (void)PMRelease(m_macPrintSession);
+}
+#endif
+
 #endif