Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > media > main-testing-src > by-pkgid > e9de60276cedfc5ae7ca1246aa19d59c > files > 35

mozilla-thunderbird-2.0.0.19-0.2mdv2009.0.src.rpm

https://bugzilla.mozilla.org/show_bug.cgi?id=324060

Index: gfx/src/gtk/nsDeviceContextSpecG.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/gtk/Attic/nsDeviceContextSpecG.cpp,v
retrieving revision 1.67
diff -u -8 -p -r1.67 nsDeviceContextSpecG.cpp
--- gfx/src/gtk/nsDeviceContextSpecG.cpp	24 Oct 2004 18:34:37 -0000	1.67
+++ gfx/src/gtk/nsDeviceContextSpecG.cpp	15 Nov 2006 11:02:45 -0000
@@ -61,16 +61,17 @@
 
 #ifdef USE_XPRINT
 #include "xprintutil.h"
 #endif /* USE_XPRINT */
 
 #ifdef USE_POSTSCRIPT
 #include "nsPSPrinters.h"
 #include "nsPaperPS.h"  /* Paper size list */
+#include "nsPaperFactoryPS.h"  /* Paper size list factory */
 #endif /* USE_POSTSCRIPT */
 
 /* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
 #define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
 
 #ifdef PR_LOGGING 
 static PRLogModuleInfo *DeviceContextSpecGTKLM = PR_NewLogModule("DeviceContextSpecGTK");
 #endif /* PR_LOGGING */
@@ -1205,44 +1206,48 @@ NS_IMETHODIMP nsPrinterEnumeratorGTK::In
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
     printerFeatures.SetColorspaceRecord(0, "default");
     printerFeatures.SetNumColorspaceRecords(1);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */   
 
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
     printerFeatures.SetCanChangePaperSize(PR_TRUE);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
-    nsXPIDLCString papername;
-    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
-      nsPaperSizePS paper;
-
-      if (paper.Find(papername)) {
-        DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
-              paper.Name(), paper.Width_mm(), paper.Height_mm()));
-        aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
-            (int)nsIPrintSettings::kPaperSizeMillimeters :
-            (int)nsIPrintSettings::kPaperSizeInches);
-        aPrintSettings->SetPaperWidth(paper.Width_mm());
-        aPrintSettings->SetPaperHeight(paper.Height_mm());
-        aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get());
-      }
-      else {
-        DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
+    {
+      nsIPaperSizePS* paper;
+      nsresult rv;
+      rv = nsPaperFactoryPS::CreatePaper
+        (fullPrinterName.get(), printerName.get(), paper);
+      if (NS_FAILED(rv)) return rv;
+      paper->SystemDefault();
+      
+      nsXPIDLCString papername;
+      if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", fullPrinterName, "print_paper_name", getter_Copies(papername)))) {
+        if (!paper->Find(papername)) {
+          DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
+        }
       }
+      DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
+              paper->Name(), paper->Width_mm(), paper->Height_mm()));
+      aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
+      aPrintSettings->SetPaperWidth(paper->Width_mm());
+      aPrintSettings->SetPaperHeight(paper->Height_mm());
+      aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper->Name()).get());
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
-      paper.First();
+      paper->First();
       int count = 0;
-      while (!paper.AtEnd())
+      while (!paper->AtEnd())
       {
-        printerFeatures.SetPaperRecord(count++, paper.Name(),
-            (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
-        paper.Next();
+        printerFeatures.SetPaperRecord(count++, paper->Name(),
+            (int)paper->Width_mm(), (int)paper->Height_mm(), !paper->IsMetric());
+        paper->Next();
       }
       printerFeatures.SetNumPaperSizeRecords(count);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
+      delete(paper);
     }
 
     PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
         nsPSPrinterList::GetPrinterType(fullPrinterName));
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
     printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd);
     printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd);
 
Index: gfx/src/ps/nsPostScriptObj.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPostScriptObj.cpp,v
retrieving revision 1.124
diff -u -8 -p -r1.124 nsPostScriptObj.cpp
--- gfx/src/ps/nsPostScriptObj.cpp	26 Jul 2005 15:54:18 -0000	1.124
+++ gfx/src/ps/nsPostScriptObj.cpp	15 Nov 2006 11:02:45 -0000
@@ -68,16 +68,17 @@
 #include "nsReadableUtils.h"
 
 #include "nsICharsetAlias.h"
 #include "nsNetUtil.h"
 #include "nsIPersistentProperties2.h"
 #include "nsCRT.h"
 #include "nsFontMetricsPS.h"
 #include "nsPaperPS.h"
+#include "nsPaperFactoryPS.h"
 
 #ifndef NS_BUILD_ID
 #include "nsBuildID.h"
 #endif /* !NS_BUILD_ID */
 
 #include "nsPrintfCString.h"
 
 #include "prenv.h"
@@ -293,37 +294,66 @@ nsPostScriptObj::Init( nsIDeviceContextS
     nsresult rv = mTempfileFactory.CreateTempFile(
 	getter_AddRefs(mDocScript), &mScriptFP, "a+");
     NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_FILE_IO_ERROR);
 
     mPrintContext = new PSContext();
     memset(mPrintContext, 0, sizeof(struct PSContext_));
     memset(pi, 0, sizeof(struct PrintInfo_));
 
+    const char* fullPrinterName; /* Full name of printer incl. driver-specific prefix */ 
+    const char* printerName;     /* "Stripped" name of printer */
+
+    rv = aSpec->GetPrinterName(&fullPrinterName);
+    if (NS_FAILED(rv))
+      return rv;
+
+    printerName = fullPrinterName;
+    
+    PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG,
+           ("printerName='%s'\n", printerName));
+  
+    /* "Demangle" printer name */
+    /* Strip the printing method name from the printer,
+     * e.g. turn "PostScript/foobar" to "foobar" */
+
+    printerName = strchr(printerName, '/');
+    if (printerName) {
+      printerName++;
+    } else {
+      printerName = fullPrinterName;
+    }
+
     /* Find PS paper size record by name */
     aSpec->GetPaperName(&(mPrintSetup->paper_name));
-    nsPaperSizePS paper;
-    if (!paper.Find(mPrintSetup->paper_name))
+    nsIPaperSizePS* paper;
+    rv = nsPaperFactoryPS::CreatePaper
+      (fullPrinterName, printerName, paper);
+    if (NS_FAILED(rv))
+      return rv;
+
+    if (!paper->Find(mPrintSetup->paper_name))
       return NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED;
 
     aSpec->GetLandscape( landscape );
-    mPrintSetup->width = NS_MILLIMETERS_TO_TWIPS(paper.Width_mm());
-    mPrintSetup->height = NS_MILLIMETERS_TO_TWIPS(paper.Height_mm());
+    mPrintSetup->width = NS_MILLIMETERS_TO_TWIPS(paper->Width_mm());
+    mPrintSetup->height = NS_MILLIMETERS_TO_TWIPS(paper->Height_mm());
 
     if (landscape) {
       nscoord temp = mPrintSetup->width;
       mPrintSetup->width = mPrintSetup->height;
       mPrintSetup->height = temp;
     }
 
 #ifdef DEBUG
     printf("\nPaper Width = %d twips (%gmm) Height = %d twips (%gmm)\n",
-        mPrintSetup->width, paper.Width_mm(),
-        mPrintSetup->height, paper.Height_mm());
+        mPrintSetup->width, paper->Width_mm(),
+        mPrintSetup->height, paper->Height_mm());
 #endif
+    delete (paper);
     mPrintSetup->header = "header";
     mPrintSetup->footer = "footer";
     mPrintSetup->sizes = nsnull;
 
     mPrintSetup->landscape = (landscape) ? PR_TRUE : PR_FALSE; // Rotated output 
     //mPrintSetup->landscape = PR_FALSE;
 
     mPrintSetup->underline = PR_TRUE;             // underline links 
Index: gfx/src/ps/nsPrintJobPS.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.cpp,v
retrieving revision 1.7
diff -u -8 -p -r1.7 nsPrintJobPS.cpp
--- gfx/src/ps/nsPrintJobPS.cpp	21 May 2005 15:33:09 -0000	1.7
+++ gfx/src/ps/nsPrintJobPS.cpp	15 Nov 2006 11:02:46 -0000
@@ -359,16 +359,20 @@ nsPrintJobCUPS::Init(nsIDeviceContextSpe
     /* Printer name */
     const char *printerName = nsnull;
     aSpec->GetPrinterName(&printerName);
     NS_ENSURE_TRUE(printerName, NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND);
 
     const char *slash = strchr(printerName, '/');
     mPrinterName = slash ? slash + 1 : printerName;
     mJobTitle.SetIsVoid(PR_TRUE);
+    /* Paper name */
+    const char* paperName = nsnull;
+    aSpec->GetPaperName(&paperName);
+    mPaperName = paperName;
     return NS_OK;
 }
 
 nsresult
 nsPrintJobCUPS::SetNumCopies(int aNumCopies)
 {
     mNumCopies.Truncate();
     if (aNumCopies > 1)
@@ -440,16 +444,21 @@ nsPrintJobCUPS::FinishSubmission()
     // Setting result just to get rid of compilation warning
     int result=0;
     if (dest != NULL) {
         if (!mNumCopies.IsEmpty())
             dest->num_options = (mCups.mCupsAddOption)("copies",
                                                        mNumCopies.get(),
                                                        dest->num_options,
                                                        &dest->options);
+        if (!mPaperName.IsEmpty())
+            dest->num_options = (mCups.mCupsAddOption)("media",
+                                                       mPaperName.get(),
+                                                       dest->num_options,
+                                                       &dest->options);
         const char *title = mJobTitle.IsVoid() ?
             "Untitled Document" : mJobTitle.get();
         result = (mCups.mCupsPrintFile)(printer.CStringAt(0)->get(),
                                             GetDestination().get(), title, 
                                             dest->num_options, dest->options);
     }
     (mCups.mCupsFreeDests)(num_dests, dests);
     unlink(GetDestination().get());
Index: gfx/src/ps/nsPrintJobPS.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/ps/nsPrintJobPS.h,v
retrieving revision 1.5
diff -u -8 -p -r1.5 nsPrintJobPS.h
--- gfx/src/ps/nsPrintJobPS.h	21 May 2005 15:33:09 -0000	1.5
+++ gfx/src/ps/nsPrintJobPS.h	15 Nov 2006 11:02:46 -0000
@@ -174,13 +174,14 @@ class nsPrintJobCUPS : public nsPrintJob
 
     protected:
         nsresult Init(nsIDeviceContextSpecPS *);
 
     private:
         nsCUPSShim mCups;
         nsCString mPrinterName;
         nsCString mNumCopies;
+        nsCString mPaperName;
         nsCString mJobTitle;        // IsVoid() if no title
 };
 #endif  /* VMS */
 
 #endif /* nsPrintJobPS_h__ */
Index: gfx/src/psshared/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/Makefile.in,v
retrieving revision 1.4
diff -u -8 -p -r1.4 Makefile.in
--- gfx/src/psshared/Makefile.in	15 Dec 2004 05:52:36 -0000	1.4
+++ gfx/src/psshared/Makefile.in	15 Nov 2006 11:02:46 -0000
@@ -52,23 +52,26 @@ REQUIRES	= pref \
 		  xpcom \
 		  $(NULL)
 LIBXUL_LIBRARY = 1
 
 PACKAGE_FILE	= psshared.pkg
 
 EXPORTS		= nsCUPSShim.h \
 		  nsPaperPS.h \
+		  nsIPaperPS.h \
 		  nsPSPrinters.h\
 		  psSharedCore.h \
+		  nsPaperFactoryPS.h \
 		  $(NULL)
 
 CPPSRCS		= nsCUPSShim.cpp \
 		  nsPaperPS.cpp \
 		  nsPSPrinters.cpp \
+		  nsPaperFactoryPS.cpp \
 		  $(NULL)
 
 EXTRA_DSO_LDOPTS = \
 		  $(MOZ_COMPONENT_LIBS) \
 		  $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
Index: gfx/src/psshared/nsCUPSShim.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsCUPSShim.cpp,v
retrieving revision 1.3
diff -u -8 -p -r1.3 nsCUPSShim.cpp
--- gfx/src/psshared/nsCUPSShim.cpp	8 May 2005 15:01:20 -0000	1.3
+++ gfx/src/psshared/nsCUPSShim.cpp	15 Nov 2006 11:02:46 -0000
@@ -40,23 +40,30 @@
 #include "nsString.h"
 #include "nsCUPSShim.h"
 #include "prlink.h"
 
 
 // List of symbols to find in libcups. Must match symAddr[] defined in Init().
 // Making this an array of arrays instead of pointers allows storing the
 // whole thing in read-only memory.
-static const char gSymName[][sizeof("cupsPrintFile")] = {
+static const char gSymName[][sizeof("ppdMarkDefaults")] = {
     { "cupsAddOption" },
     { "cupsFreeDests" },
     { "cupsGetDest" },
     { "cupsGetDests" },
     { "cupsPrintFile" },
     { "cupsTempFd" },
+    { "cupsGetPPD" },
+    { "ppdOpenFile" },
+    { "ppdClose" },
+    { "ppdMarkDefaults" },
+    { "ppdIsMarked" },
+    { "ppdFindOption" },
+    { "ppdFindChoice" },
 };
 static const int gSymNameCt = sizeof(gSymName) / sizeof(gSymName[0]);
 
 
 PRBool
 nsCUPSShim::Init()
 {
     mCupsLib = PR_LoadLibrary("libcups.so.2");
@@ -66,16 +73,23 @@ nsCUPSShim::Init()
     // List of symbol pointers. Must match gSymName[] defined above.
     void **symAddr[] = {
         (void **)&mCupsAddOption,
         (void **)&mCupsFreeDests,
         (void **)&mCupsGetDest,
         (void **)&mCupsGetDests,
         (void **)&mCupsPrintFile,
         (void **)&mCupsTempFd,
+        (void **)&mCupsGetPPD,
+        (void **)&mPpdOpenFile,
+        (void **)&mPpdClose,
+        (void **)&mPpdMarkDefaults,
+        (void **)&mPpdIsMarked,
+        (void **)&mPpdFindOption,
+        (void **)&mPpdFindChoice,
     };
 
     for (int i = gSymNameCt; i--; ) {
         *(symAddr[i]) = PR_FindSymbol(mCupsLib, gSymName[i]);
         if (! *(symAddr[i])) {
 #ifdef DEBUG
             nsCAutoString msg(gSymName[i]);
             msg.Append(" not found in CUPS library");
Index: gfx/src/psshared/nsCUPSShim.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsCUPSShim.h,v
retrieving revision 1.4
diff -u -8 -p -r1.4 nsCUPSShim.h
--- gfx/src/psshared/nsCUPSShim.h	8 May 2005 15:01:20 -0000	1.4
+++ gfx/src/psshared/nsCUPSShim.h	15 Nov 2006 11:02:46 -0000
@@ -57,16 +57,138 @@ typedef struct               /**** Desti
 {
     char          *name,       /* Printer or class name */
                   *instance;   /* Local instance name or NULL */
     int           is_default;  /* Is this printer the default? */
     int           num_options; /* Number of options */
     cups_option_t *options;    /* Options */
 } cups_dest_t;
 
+typedef enum                /**** Colorspaces ****/
+{
+    PPD_CS_CMYK = -4,       /* CMYK colorspace */
+    PPD_CS_CMY,             /* CMY colorspace */
+    PPD_CS_GRAY = 1,        /* Grayscale colorspace */
+    PPD_CS_RGB = 3,         /* RGB colorspace */
+    PPD_CS_RGBK,            /* RGBK (K = gray) colorspace */
+    PPD_CS_N                /* DeviceN colorspace */
+} ppd_cs_t;
+
+typedef enum ppd_ui_e       /**** UI Types ****/
+{
+    PPD_UI_BOOLEAN,         /* True or False option */
+    PPD_UI_PICKONE,         /* Pick one from a list */
+    PPD_UI_PICKMANY         /* Pick zero or more from a list */
+} ppd_ui_t;
+
+typedef enum ppd_section_e  /**** Order dependency sections ****/
+{
+    PPD_ORDER_ANY,          /* Option code can be anywhere in the file */
+    PPD_ORDER_DOCUMENT,     /* ... must be in the DocumentSetup section */
+    PPD_ORDER_EXIT,         /* ... must be sent prior to the document */
+    PPD_ORDER_JCL,          /* ... must be sent as a JCL command */
+    PPD_ORDER_PAGE,         /* ... must be in the PageSetup section */
+    PPD_ORDER_PROLOG        /* ... must be in the Prolog section */
+} ppd_section_t;
+
+typedef struct ppd_option_s ppd_option_t;
+
+typedef struct ppd_choice_s     /**** Option choices ****/
+{
+    char        marked;     /* 0 if not selected, 1 otherwise */
+    char        choice[41]; /* Computer-readable option name */
+    char        text[81];     /* Human-readable option name */
+    char        *code;      /* Code to send for this option */
+    ppd_option_t*option;    /* Pointer to parent option structure */
+} ppd_choice_t;
+
+struct ppd_option_s         /**** Options ****/
+{
+    char        conflicted; /* 0 if no conflicts exist, 1 otherwise */
+    char        keyword[41];/* Option keyword name ("PageSize", etc.) */
+    char        defchoice[41];/* Default option choice */
+    char        text[81];   /* Human-readable text */
+    ppd_ui_t    ui;         /* Type of UI option */
+    ppd_section_t section;  /* Section for command */
+    float       order;      /* Order number */
+    int         num_choices;/* Number of option choices */
+    ppd_choice_t*choices;   /* Option choices */
+};
+
+typedef struct          /**** Page Sizes ****/
+{
+    int         marked;     /* Page size selected? */
+    char        name[41];
+    /* Media size option */
+    float       width,      /* Width of media in points */
+                length,     /* Length of media in points */
+                left,       /* Left printable margin in points */
+                bottom,     /* Bottom printable margin in points */
+                right,      /* Right printable margin in points */
+                top;        /* Top printable margin in points */
+} ppd_size_t;
+
+typedef struct			/**** Files ****/
+{
+    int         language_level;   /* Language level of device */
+    int         color_device;     /* 1 = color device, 0 = grayscale */
+    int         variable_sizes;   /* 1 = supports variable sizes, 0 = doesn't */
+    int         accurate_screens; /* 1 = supports accurate screens, 0 = not */
+    int         contone_only;     /* 1 = continuous tone only, 0 = not */
+    int         landscape;         /* -90 or 90 */
+    int         model_number;      /* Device-specific model number */
+    int         manual_copies;    /* 1 = Copies done manually, 0 = hardware */
+    int         throughput;       /* Pages per minute */
+    ppd_cs_t    colorspace;       /* Default colorspace */
+    char        *patches;         /* Patch commands to be sent to printer */
+    int         num_emulations;   /* Number of emulations supported */
+    void        *emulations;      /* Emulations and the code to invoke them */
+    char        *jcl_begin;       /* Start JCL commands */
+    char        *jcl_ps;          /* Enter PostScript interpreter */
+    char        *jcl_end;         /* End JCL commands */
+    char        *lang_encoding;   /* Language encoding */
+    char        *lang_version;    /* Language version (English, Spanish, etc.) */
+    char        *modelname;       /* Model name (general) */
+    char        *ttrasterizer;    /* Truetype rasterizer */
+    char        *manufacturer;    /* Manufacturer name */
+    char        *product;         /* Product name (from PS RIP/interpreter) */
+    char        *nickname;        /* Nickname (specific) */
+    char        *shortnickname;   /* Short version of nickname */
+    int         num_groups;       /* Number of UI groups */
+    void        *groups;          /* UI groups */
+    int         num_sizes;        /* Number of page sizes */
+    ppd_size_t  *sizes;           /* Page sizes */
+    float       custom_min[2];    /* Minimum variable page size */
+    float       custom_max[2];    /* Maximum variable page size */
+    float       custom_margins[4];/* Margins around page */
+    int         num_consts;       /* Number of UI/Non-UI constraints */
+    void        *consts;          /* UI/Non-UI constraints */
+    int         num_fonts;        /* Number of pre-loaded fonts */
+    char        **fonts;          /* Pre-loaded fonts */
+    int         num_profiles;     /* Number of sRGB color profiles */
+    void        *profiles;    /* sRGB color profiles */
+    int         num_filters;      /* Number of filters */
+    char        **filters;        /* Filter strings... */
+
+    /**** New in CUPS 1.1 ****/
+    int         flip_duplex;      /* 1 = Flip page for back sides */
+    
+    /**** New in CUPS 1.1.19 ****/
+    char        *protocols;       /* Protocols (BCP, TBCP) string */
+    char        *pcfilename;      /* PCFileName string */
+    int         num_attrs;        /* Number of attributes */
+    int         cur_attr;         /* Current attribute */
+    void        **attrs;          /* Attributes */
+
+    /**** New in CUPS 1.2 ****/
+    void        *sorted_attrs;    /* Attribute lookup array */
+    void        *options;	      /* Option lookup array */
+    void        *coptions;	      /* Custom options array */
+} ppd_file_t;
+
 typedef cups_dest_t* (PR_CALLBACK *CupsGetDestType)(const char *printer,
                                                     const char *instance,
                                                     int num_dests, 
                                                     cups_dest_t *dests);
 typedef int (PR_CALLBACK *CupsGetDestsType)(cups_dest_t **dests);
 typedef int (PR_CALLBACK *CupsFreeDestsType)(int         num_dests,
                                              cups_dest_t *dests);
 typedef int (PR_CALLBACK *CupsPrintFileType)(const char    *printer,
@@ -75,16 +197,27 @@ typedef int (PR_CALLBACK *CupsPrintFileT
                                              int           num_options,
                                              cups_option_t *options);
 typedef int (PR_CALLBACK *CupsTempFdType)(char *filename,
                                           int   length);
 typedef int (PR_CALLBACK *CupsAddOptionType)(const char    *name,
                                              const char    *value,
                                              int           num_options,
                                              cups_option_t **options);
+typedef const char* (PR_CALLBACK *CupsGetPPDType) (const char* name);
+typedef ppd_file_t* (PR_CALLBACK *PPDOpenFileType) (const char* filename);
+typedef void (PR_CALLBACK *PPDCloseType) (ppd_file_t* ppd);
+typedef void (PR_CALLBACK *PPDMarkDefaultsType) (ppd_file_t* ppd);
+typedef int (PR_CALLBACK *PPDIsMarkedType) (ppd_file_t* ppd,
+                                            const char* keyword,
+                                            const char* choice);
+typedef ppd_option_t* (PR_CALLBACK *PPDFindOption) (ppd_file_t* ppd,
+                                                    const char* option);
+typedef ppd_choice_t* (PR_CALLBACK *PPDFindChoice) (ppd_option_t* o,
+                                                    const char* choice);
 
 struct PRLibrary;
 
 class NS_PSSHARED nsCUPSShim {
     public:
         nsCUPSShim() : mCupsLib(nsnull) { }
         ~nsCUPSShim();
 
@@ -108,16 +241,22 @@ class NS_PSSHARED nsCUPSShim {
          * valid after successful initialization.
          */
         CupsAddOptionType   mCupsAddOption;
         CupsFreeDestsType   mCupsFreeDests;
         CupsGetDestType     mCupsGetDest;
         CupsGetDestsType    mCupsGetDests;
         CupsPrintFileType   mCupsPrintFile;
         CupsTempFdType      mCupsTempFd;
-
+        CupsGetPPDType      mCupsGetPPD;
+        PPDOpenFileType     mPpdOpenFile;
+        PPDCloseType        mPpdClose;
+        PPDMarkDefaultsType mPpdMarkDefaults;
+        PPDIsMarkedType     mPpdIsMarked;
+        PPDFindOption       mPpdFindOption;
+        PPDFindChoice       mPpdFindChoice;
     private:
         PRLibrary *mCupsLib;
 };
 
 
 
 #endif /* nsCUPSShim_h___ */
Index: gfx/src/psshared/nsIPaperPS.h
===================================================================
RCS file: gfx/src/psshared/nsIPaperPS.h
diff -N gfx/src/psshared/nsIPaperPS.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gfx/src/psshared/nsIPaperPS.h	15 Nov 2006 11:02:46 -0000
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ *   Arne John Glenstrup <panic@itu.dk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ 
+#ifndef _NSIPAPERPS_H_
+#define _NSIPAPERPS_H_
+
+#include "prtypes.h"
+#include "psSharedCore.h"
+
+class nsIPaperSizePS {
+    public:
+        /** ---------------------------------------------------
+         * Virtual destructor.
+         */
+    virtual ~nsIPaperSizePS() { };
+        /* Allow the paper factory to create instances */
+        friend class nsPaperFactoryPS;
+        /** ---------------------------------------------------
+         * @return PR_TRUE if the cursor points past the last item.
+         */
+        virtual PRBool AtEnd() = 0;
+
+        /** ---------------------------------------------------
+         * Position the cursor at the beginning of the paper size list.
+         * @return VOID
+         */
+        virtual void First() = 0;
+
+        /** ---------------------------------------------------
+         * Advance the cursor to the next item.
+         * @return VOID
+         */
+        virtual void Next() = 0;
+
+        /** ---------------------------------------------------
+         * Point the cursor to the entry with the given paper name.
+         * @return PR_TRUE if pointing to a valid entry.
+         */
+        virtual PRBool Find(const char *aName) = 0;
+
+        /** ---------------------------------------------------
+         * Point the cursor to the entry with the default paper
+         * name on the running system.
+         */
+        virtual PRBool SystemDefault() = 0;
+
+        /** ---------------------------------------------------
+         * @return a pointer to the name of the current paper size
+         */
+        virtual const char *Name() = 0;
+
+        /** ---------------------------------------------------
+         * @return the width of the page in millimeters
+         */
+        virtual float Width_mm() = 0;
+
+        /** ---------------------------------------------------
+         * @return the height of the page in millimeters
+         */
+        virtual float Height_mm() = 0;
+
+        /** ---------------------------------------------------
+         * @return PR_TRUE if the paper should be presented to
+         *                 the user in metric units.
+         */
+        virtual PRBool IsMetric() { return PR_TRUE; };
+};
+
+#endif /* _NSIPAPERPS_H_ */
Index: gfx/src/psshared/nsPSPrinters.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsPSPrinters.h,v
retrieving revision 1.3
diff -u -8 -p -r1.3 nsPSPrinters.h
--- gfx/src/psshared/nsPSPrinters.h	15 Dec 2004 05:52:36 -0000	1.3
+++ gfx/src/psshared/nsPSPrinters.h	15 Nov 2006 11:02:46 -0000
@@ -39,16 +39,17 @@
 #ifndef nsPSPrinters_h___
 #define nsPSPrinters_h___
 
 #include "nsString.h"
 #include "nsVoidArray.h"
 #include "prtypes.h"
 #include "nsCUPSShim.h"
 #include "psSharedCore.h"
+#include "nsCOMPtr.h"
 
 class nsIPrefService;
 class nsIPrefBranch;
 class nsCUPSShim;
 
 class NS_PSSHARED nsPSPrinterList {
     public:
         /**
Index: gfx/src/psshared/nsPaperFactoryPS.cpp
===================================================================
RCS file: gfx/src/psshared/nsPaperFactoryPS.cpp
diff -N gfx/src/psshared/nsPaperFactoryPS.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gfx/src/psshared/nsPaperFactoryPS.cpp	15 Nov 2006 11:02:46 -0000
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Kenneth Herron <kherron@fastmail.us>.
+ * Portions created by the Initial Developer are Copyright (C) 2004
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsDebug.h"
+#include "nsPaperFactoryPS.h"
+#include "nsIPaperPS.h"
+#include "nsPaperPS.h"
+#include "nsPSPrinters.h"
+
+/**
+ * Construct a paper size object for the given device context spec.
+ *
+ * @param fullPrinterName  Fully qualified name, e.g., "CUPS/myprinter"
+ * @param printerName      Stripped name, e.g., "myprinter"
+ * @param aPaper           If NS_OK is returned, this will be filled
+ *                         in with a pointer to a paper size object.
+ * @return NS_OK or a suitable error value.
+ */
+nsresult
+nsPaperFactoryPS::CreatePaper(const char* fullPrinterName,
+                              const char* printerName,
+                              nsIPaperSizePS* &aPaper)
+{
+    nsIPaperSizePS *newPZ;
+
+    if (nsPSPrinterList::kTypeCUPS == nsPSPrinterList::GetPrinterType
+        (nsDependentCString(fullPrinterName)))
+        newPZ = new nsPaperSizeCUPS(fullPrinterName, printerName);
+    else
+        newPZ = new nsPaperSizePS();
+    if (!newPZ)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+    aPaper = newPZ;
+    return NS_OK;
+}
Index: gfx/src/psshared/nsPaperFactoryPS.h
===================================================================
RCS file: gfx/src/psshared/nsPaperFactoryPS.h
diff -N gfx/src/psshared/nsPaperFactoryPS.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gfx/src/psshared/nsPaperFactoryPS.h	15 Nov 2006 11:02:46 -0000
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Contributor(s):
+ *   Arne John Glenstrup <panic@itu.dk>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsPaperFactoryPS_h__
+#define nsPaperFactoryPS_h__
+
+#include "nscore.h"
+#include "nsIPaperPS.h"
+
+/* Factory class for the paper sizes. This class determines
+ * which paper size class should handle a request, and constructs
+ * an object of the appropriate class.
+ */
+
+
+class NS_PSSHARED nsPaperFactoryPS
+{
+public:
+    /**
+     * Construct a paper size object for the given device context spec.
+     * On success, the paper size object is owned by the caller and should
+     * be destroyed when no longer needed.
+     *
+     * @param fullPrinterName  Fully qualified name, e.g., "CUPS/myprinter"
+     * @param printerName      Stripped name, e.g., "myprinter"
+     * @param aPaper           If NS_OK is returned, this will be filled
+     *                         in with a pointer to a paper size object.
+     * @return NS_OK or a suitable error value.
+     */
+    static nsresult CreatePaper(const char* fullPrinterName,
+				const char* printerName,
+				nsIPaperSizePS* &aPaper);
+};
+
+
+#endif /* nsPaperFactoryPS_h__ */
Index: gfx/src/psshared/nsPaperPS.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsPaperPS.cpp,v
retrieving revision 1.1
diff -u -8 -p -r1.1 nsPaperPS.cpp
--- gfx/src/psshared/nsPaperPS.cpp	7 Sep 2004 17:51:50 -0000	1.1
+++ gfx/src/psshared/nsPaperPS.cpp	15 Nov 2006 11:02:46 -0000
@@ -32,19 +32,35 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
- 
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG 1 /* Allow logging in the release build */
+#endif /* MOZ_LOGGING */
+#include "prlog.h"
+
 #include "nsPaperPS.h"
 #include "plstr.h"
+#include "nsPSPrinters.h"
+#include <math.h> 
+
+#ifdef PR_LOGGING 
+static PRLogModuleInfo *PaperSizePSLM = PR_NewLogModule("PaperSizePS");
+#endif /* PR_LOGGING */
+/* Macro to make lines shorter */
+#define DO_PR_DEBUG_LOG(x) PR_LOG(PaperSizePSLM, PR_LOG_DEBUG, x)
+
+#define MM_PER_PT (25.4 / 72.0)
+#define HALF_INCH_PT 36.0
+#define EPSILON 0.125
 
 #define COUNTOF(x) (sizeof(x) / sizeof((x)[0]))
 
 const nsPaperSizePS_ nsPaperSizePS::mList[] =
 {
 #define SIZE_MM(x)      (x)
 #define SIZE_INCH(x)    ((x) * 25.4)
     { "A5",             SIZE_MM(148),   SIZE_MM(210),   PR_TRUE },
@@ -52,21 +68,186 @@ const nsPaperSizePS_ nsPaperSizePS::mLis
     { "Letter",         SIZE_INCH(8.5), SIZE_INCH(11),  PR_FALSE },
     { "Legal",          SIZE_INCH(8.5), SIZE_INCH(14),  PR_FALSE },
     { "Tabloid",        SIZE_INCH(11),  SIZE_INCH(17),  PR_FALSE },
     { "Executive",      SIZE_INCH(7.5), SIZE_INCH(10),  PR_FALSE },
 #undef SIZE_INCH
 #undef SIZE_MM
 };
 
-const unsigned int nsPaperSizePS::mCount = COUNTOF(mList);
+nsCUPSShim nsPaperSizeCUPS::mCups;
+
+/* ~nsIPaperSizePS() is virtual, so must implement a destructor. */
+//nsIPaperSizePS::~nsIPaperSizePS () { }
+
+nsPaperSizePS::nsPaperSizePS() {
+    mCount = COUNTOF(mList);
+    mCurrent = 0;
+}
 
 PRBool
-nsPaperSizePS::Find(const char *aName)
-{
+nsPaperSizePS::Find(const char *aName) {
     for (int i = mCount; i--; ) {
         if (!PL_strcasecmp(aName, mList[i].name)) {
             mCurrent = i;
             return PR_TRUE;
         }
     }
     return PR_FALSE;
 }
+
+PRBool
+nsPaperSizePS::SystemDefault() {
+    DO_PR_DEBUG_LOG(("nsPaperSizePS::SystemDefault () "));
+    mCurrent = 0;
+    if (mCount <= 0) return PR_FALSE; else return PR_TRUE;
+}
+
+nsPaperSizeCUPS::nsPaperSizeCUPS(const char* fullPrinterName,
+                                 const char* printerName) {
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS('%s', '%s')\n",
+                     fullPrinterName, printerName));
+    /* Don't use CUPS before we are sure we have access to the PPD */
+    mUsingCups = false;
+    mCount = COUNTOF(mList);
+    mCurrent = 0;
+    mPPD = NULL;
+    mPageSizeText = NULL;
+    if (!fullPrinterName || !printerName ||
+        nsPSPrinterList::kTypeCUPS !=
+        nsPSPrinterList::GetPrinterType(nsDependentCString(fullPrinterName))) 
+        return;
+    if (!mCups.IsInitialized()) { mCups.Init(); }
+    if (!mCups.IsInitialized()) {
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: CUPS unavailable\n"));
+        return;
+    }
+    const char* ppdFileName = mCups.mCupsGetPPD (printerName);
+    if (!ppdFileName) {
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
+                         "cannot get PPD file name for printer '%s'\n",
+                         printerName));
+        return;
+    }
+    mPPD = mCups.mPpdOpenFile (ppdFileName);
+    if (!mPPD)  {
+        DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::nsPaperSizeCUPS: "
+                         "cannot open PPD file '%s'\n",
+                         ppdFileName));
+        return;
+    }
+    mPageSizeOption = mCups.mPpdFindOption (mPPD, "PageSize");
+    mCount = mPPD->num_sizes;
+    mCups.mPpdMarkDefaults (mPPD);
+    mPageSizeText = new const char* [mCount];
+    if (mPageSizeText) 
+        for (int i = mCount; i--; ) mPageSizeText [i] = NULL;
+    mUsingCups = true;
+}
+
+nsPaperSizeCUPS::~nsPaperSizeCUPS() {
+    if (mPPD) mCups.mPpdClose (mPPD);
+    if (mPageSizeText) delete (mPageSizeText);
+}
+
+void
+nsPaperSizeCUPS::SkipZeroSizes() {
+    if (!mUsingCups) return; 
+    while (mCurrent < mCount
+           && (mPPD->sizes [mCurrent].width == 0.0f || 
+               mPPD->sizes [mCurrent].length == 0.0f)) {
+        mCurrent++;
+    }
+}
+
+const char*
+nsPaperSizeCUPS::GetHumanReadableName (int i) {
+    const char* briefName = mPPD->sizes [i].name;
+    const char* name = NULL;
+    if (mPageSizeText) {
+        if (!mPageSizeText [i]) {
+            if (mPageSizeOption) {
+                ppd_choice_t* choice
+                    = mCups.mPpdFindChoice (mPageSizeOption, briefName);
+                if (choice) mPageSizeText [i] = choice->text;
+            }
+            if (!mPageSizeText [i] 
+                || PL_strcasecmp (mPageSizeText [i], "") == 0)
+                mPageSizeText [i] = briefName;
+        }
+        name = mPageSizeText [i];
+    } else {
+        name = briefName;
+    }
+    return name;
+}
+
+PRBool
+nsPaperSizeCUPS::Find(const char* aName) {
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::Find ('%s') ", aName));
+    if (!mUsingCups) return nsPaperSizePS::Find(aName);
+    for (int i = mCount; i--; ) {
+        const char* name = GetHumanReadableName (i);
+        if (!PL_strcasecmp(aName, name)) {
+            DO_PR_DEBUG_LOG
+                (("found paper '%s' (%gx%gmm)\n",
+                  aName,
+                  round(mPPD->sizes [i].width * MM_PER_PT),
+                  round(mPPD->sizes [i].length * MM_PER_PT)));
+            mCurrent = i;
+            return PR_TRUE;
+        }
+    }
+    DO_PR_DEBUG_LOG(("did not find paper '%s'\n", aName));
+    return PR_FALSE;
+}
+
+PRBool
+nsPaperSizeCUPS::SystemDefault() {
+    DO_PR_DEBUG_LOG(("nsPaperSizeCUPS::SystemDefault () "));
+    if (!mUsingCups) return nsPaperSizePS::SystemDefault();
+    First ();
+    for (int i = mCount; i--; )
+        if (mPPD->sizes [i].marked) {
+            mCurrent = i;
+            break;
+        }
+    if (mCurrent < mCount) {
+        DO_PR_DEBUG_LOG
+            (("selected system default paper '%s'\n",
+              GetHumanReadableName (mCurrent)));
+        return PR_TRUE; 
+    } else {
+        return PR_FALSE;
+    }
+}
+
+const char*
+nsPaperSizeCUPS::Name() {
+    if (!mUsingCups) return nsPaperSizePS::Name();
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
+    return GetHumanReadableName (mCurrent);
+}
+
+float
+nsPaperSizeCUPS::Width_mm() {
+    if (!mUsingCups) return nsPaperSizePS::Width_mm();
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
+    return round(mPPD->sizes [mCurrent].width * MM_PER_PT);
+}
+
+float
+nsPaperSizeCUPS::Height_mm() {
+    if (!mUsingCups) return nsPaperSizePS::Height_mm();
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
+    return round(mPPD->sizes [mCurrent].length * MM_PER_PT);
+}
+
+PRBool 
+nsPaperSizeCUPS::IsMetric() {
+    if (!mUsingCups) return nsPaperSizePS::IsMetric();
+    NS_PRECONDITION(!AtEnd(), "Invalid current item");
+    /* Educated guess: unless sizes are integral number    */
+    /* of half inches, present them to the user in metric. */
+    return
+        fabs(fmod(mPPD->sizes [mCurrent].width, HALF_INCH_PT)) > EPSILON ||
+        fabs(fmod(mPPD->sizes [mCurrent].length, HALF_INCH_PT)) > EPSILON;
+}
Index: gfx/src/psshared/nsPaperPS.h
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/psshared/nsPaperPS.h,v
retrieving revision 1.2
diff -u -8 -p -r1.2 nsPaperPS.h
--- gfx/src/psshared/nsPaperPS.h	15 Dec 2004 05:52:36 -0000	1.2
+++ gfx/src/psshared/nsPaperPS.h	15 Nov 2006 11:02:46 -0000
@@ -35,34 +35,33 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
  
 #ifndef _PAPERPS_H_
 #define _PAPERPS_H_
 
-#include "prtypes.h"
+#include "nsIPaperPS.h"
 #include "nsDebug.h"
-#include "psSharedCore.h"
+#include "nsCUPSShim.h"
 
 struct nsPaperSizePS_ {
     const char *name;
     float width_mm;
     float height_mm;
     PRBool isMetric;        // Present to the user in metric, if possible
 };
 
-class NS_PSSHARED nsPaperSizePS {
+class NS_PSSHARED nsPaperSizePS : public nsIPaperSizePS {
     public:
         /** ---------------------------------------------------
-         * Constructor
+         * Constructor.
          */
-        nsPaperSizePS() { mCurrent = 0; }
-
+        nsPaperSizePS();
         /** ---------------------------------------------------
          * @return PR_TRUE if the cursor points past the last item.
          */
         PRBool AtEnd() { return mCurrent >= mCount; }
 
         /** ---------------------------------------------------
          * Position the cursor at the beginning of the paper size list.
          * @return VOID
@@ -80,16 +79,23 @@ class NS_PSSHARED nsPaperSizePS {
 
         /** ---------------------------------------------------
          * Point the cursor to the entry with the given paper name.
          * @return PR_TRUE if pointing to a valid entry.
          */
         PRBool Find(const char *aName);
 
         /** ---------------------------------------------------
+         * Point the cursor to the entry with the default paper
+         * name on the running system.
+         * @return PR_TRUE if pointing to a valid entry.
+         */
+        PRBool SystemDefault();
+
+        /** ---------------------------------------------------
          * @return a pointer to the name of the current paper size
          */
         const char *Name() {
             NS_PRECONDITION(!AtEnd(), "Invalid current item");
             return mList[mCurrent].name;
         }
 
         /** ---------------------------------------------------
@@ -112,17 +118,90 @@ class NS_PSSHARED nsPaperSizePS {
          * @return PR_TRUE if the paper should be presented to
          *                 the user in metric units.
          */
         PRBool IsMetric() {
             NS_PRECONDITION(!AtEnd(), "Invalid current item");
             return mList[mCurrent].isMetric;
         }
 
-    private:
+    protected:
         unsigned int mCurrent;
         // the class visibility should export these, but it doesn't
         static NS_PSSHARED_STATIC_MEMBER_(const nsPaperSizePS_) mList[];
-        static NS_PSSHARED_STATIC_MEMBER_(const unsigned int) mCount;
+        unsigned int mCount;
+};
+
+class NS_PSSHARED nsPaperSizeCUPS : public nsPaperSizePS {
+    public:
+        /** ---------------------------------------------------
+         * Constructor for a specific CUPS printer.
+         * @param fullPrinterName  Fully qualified name, e.g., "CUPS/myprinter"
+         * @param printerName      Stripped name, e.g., "myprinter"
+         */
+        nsPaperSizeCUPS(const char* fullPrinterName, const char* printerName);
+        /** ---------------------------------------------------
+         * Destructor.
+         */
+        ~nsPaperSizeCUPS();
+        /** ---------------------------------------------------
+         * Position the cursor at the beginning of the paper size list.
+         * @return VOID
+         */
+        void First() {
+            nsPaperSizePS::First();
+            SkipZeroSizes();
+        }
+
+        /** ---------------------------------------------------
+         * Advance the cursor to the next item.
+         * @return VOID
+         */
+        void Next() {
+            nsPaperSizePS::Next();
+            SkipZeroSizes();
+        }
+
+        /** ---------------------------------------------------
+         * Point the cursor to the entry with the given paper name.
+         * @return PR_TRUE if pointing to a valid entry.
+         */
+        PRBool Find(const char *aName);
+
+        /** ---------------------------------------------------
+         * Point the cursor to the entry with the default paper
+         * name on the running system.
+         * @return PR_TRUE if pointing to a valid entry.
+         */
+        PRBool SystemDefault();
+
+        /** ---------------------------------------------------
+         * @return a pointer to the name of the current paper size
+         */
+        const char *Name();
+
+        /** ---------------------------------------------------
+         * @return the width of the page in millimeters
+         */
+        float Width_mm();
+
+        /** ---------------------------------------------------
+         * @return the height of the page in millimeters
+         */
+        float Height_mm();
+
+        /** ---------------------------------------------------
+         * @return PR_TRUE if the paper should be presented to
+         *                 the user in metric units.
+         */
+        PRBool IsMetric();
+    private:
+        void SkipZeroSizes();
+        const char* GetHumanReadableName (int i);
+        PRBool mUsingCups;
+        static NS_PSSHARED_STATIC_MEMBER_(nsCUPSShim) mCups;
+        ppd_file_t* mPPD;
+        ppd_option_t* mPageSizeOption;
+        const char** mPageSizeText;
 };
 
 #endif
 
Index: gfx/src/xlib/nsDeviceContextSpecXlib.cpp
===================================================================
RCS file: /cvsroot/mozilla/gfx/src/xlib/nsDeviceContextSpecXlib.cpp,v
retrieving revision 1.48
diff -u -8 -p -r1.48 nsDeviceContextSpecXlib.cpp
--- gfx/src/xlib/nsDeviceContextSpecXlib.cpp	24 Oct 2004 18:34:38 -0000	1.48
+++ gfx/src/xlib/nsDeviceContextSpecXlib.cpp	15 Nov 2006 11:02:47 -0000
@@ -1207,17 +1207,21 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::I
     printerFeatures.SetNumColorspaceRecords(1);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */   
 
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
     printerFeatures.SetCanChangePaperSize(PR_TRUE);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
     nsXPIDLCString papername;
     if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
-      nsPaperSizePS paper;
+      nsIPaperSizePS* paper;
+      nsresult rv;
+      rv = nsPaperFactoryPS::CreatePaper
+        (fullPrinterName.get(), printerName.get(), paper);
+      if (NS_FAILED(rv)) return rv;
 
       if (paper.Find(papername)) {
         DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
               paper.Name(), paper.Width_mm(), paper.Height_mm()));
         aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
             (int)nsIPrintSettings::kPaperSizeMillimeters :
             (int)nsIPrintSettings::kPaperSizeInches);
         aPrintSettings->SetPaperWidth(paper.Width_mm());
@@ -1233,16 +1237,17 @@ NS_IMETHODIMP nsPrinterEnumeratorXlib::I
       while (!paper.AtEnd())
       {
         printerFeatures.SetPaperRecord(count++, paper.Name(),
             (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
         paper.Next();
       }
       printerFeatures.SetNumPaperSizeRecords(count);
 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
+      delete(paper);
     }
 
     PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
         nsPSPrinterList::GetPrinterType(fullPrinterName));
 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
     printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd);
     printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd);