@@ -0,0 +1,889 @@
+From: Wolfgang Rosenauer <stark@suse.de>, Arne John Glenstrup <panic@itu.dk>
+Subject: get paper sizes from CUPS
+References:
+https://bugzilla.novell.com/show_bug.cgi?id=65482
+https://bugzilla.mozilla.org/show_bug.cgi?id=324060
+
+
+================================================================================
+--- gfx/src/gtk/nsDeviceContextSpecG.cpp
++++ gfx/src/gtk/nsDeviceContextSpecG.cpp
+@@ -66,6 +66,7 @@
+ #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 */
+@@ -1210,34 +1211,38 @@
+ #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->FindDefault();
++
++ 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 ==
+--- gfx/src/ps/nsPrintJobPS.cpp
++++ gfx/src/ps/nsPrintJobPS.cpp
+@@ -364,6 +364,10 @@
+ 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;
+ }
+
+@@ -445,6 +449,11 @@
+ 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(),
+--- gfx/src/ps/nsPrintJobPS.h
++++ gfx/src/ps/nsPrintJobPS.h
+@@ -179,6 +179,7 @@
+ nsCUPSShim mCups;
+ nsCString mPrinterName;
+ nsCString mNumCopies;
++ nsCString mPaperName;
+ nsCString mJobTitle; // IsVoid() if no title
+ };
+ #endif /* VMS */
+--- gfx/src/psshared/Makefile.in
++++ gfx/src/psshared/Makefile.in
+@@ -57,13 +57,16 @@
+
+ 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 = \
+--- gfx/src/psshared/nsCUPSShim.cpp
++++ gfx/src/psshared/nsCUPSShim.cpp
+@@ -45,13 +45,18 @@
+ // 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" },
+ };
+ static const int gSymNameCt = sizeof(gSymName) / sizeof(gSymName[0]);
+
+@@ -71,6 +76,11 @@
+ (void **)&mCupsGetDests,
+ (void **)&mCupsPrintFile,
+ (void **)&mCupsTempFd,
++ (void **)&mCupsGetPPD,
++ (void **)&mPpdOpenFile,
++ (void **)&mPpdClose,
++ (void **)&mPpdMarkDefaults,
++ (void **)&mPpdIsMarked,
+ };
+
+ for (int i = gSymNameCt; i--; ) {
+--- gfx/src/psshared/nsCUPSShim.h
++++ gfx/src/psshared/nsCUPSShim.h
+@@ -62,6 +62,82 @@
+ 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 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 */
++ color_device, /* 1 = color device, 0 = grayscale */
|