зеркало из https://github.com/mozilla/gecko-dev.git
printing on linux bug 323928. r=vlad
This commit is contained in:
Родитель
30aa38725d
Коммит
f0eb225e80
|
@ -557,6 +557,10 @@ nsThebesDeviceContext::GetDeviceContextFor(nsIDeviceContextSpec *aDevice,
|
||||||
|
|
||||||
NS_ADDREF(aDevice);
|
NS_ADDREF(aDevice);
|
||||||
|
|
||||||
|
#ifdef MOZ_ENABLE_GTK2
|
||||||
|
newDevCon->mDeviceContextSpec = aDevice;
|
||||||
|
#endif
|
||||||
|
|
||||||
newDevCon->mPrinter = PR_TRUE;
|
newDevCon->mPrinter = PR_TRUE;
|
||||||
|
|
||||||
aDevice->GetSurfaceForPrinter(getter_AddRefs(newDevCon->mPrintingSurface));
|
aDevice->GetSurfaceForPrinter(getter_AddRefs(newDevCon->mPrintingSurface));
|
||||||
|
@ -605,6 +609,11 @@ nsThebesDeviceContext::EndDocument(void)
|
||||||
{
|
{
|
||||||
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
|
nsRefPtr<gfxContext> thebes = new gfxContext(mPrintingSurface);
|
||||||
thebes->EndPrinting();
|
thebes->EndPrinting();
|
||||||
|
|
||||||
|
cairo_surface_finish(mPrintingSurface->CairoSurface());
|
||||||
|
|
||||||
|
if (mDeviceContextSpec)
|
||||||
|
mDeviceContextSpec->EndDocument();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,6 +146,7 @@ private:
|
||||||
nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache;
|
nsRefPtrHashtable<nsISupportsHashKey, gfxASurface> mWidgetSurfaceCache;
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> mPrintingSurface;
|
nsRefPtr<gfxASurface> mPrintingSurface;
|
||||||
|
nsIDeviceContextSpec * mDeviceContextSpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _NS_CAIRODEVICECONTEXT_H_ */
|
#endif /* _NS_CAIRODEVICECONTEXT_H_ */
|
||||||
|
|
|
@ -38,10 +38,14 @@
|
||||||
#ifndef GFX_PSSURFACE_H
|
#ifndef GFX_PSSURFACE_H
|
||||||
#define GFX_PSSURFACE_H
|
#define GFX_PSSURFACE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include "gfxASurface.h"
|
#include "gfxASurface.h"
|
||||||
|
|
||||||
class THEBES_API gfxPSSurface : public gfxASurface {
|
class THEBES_API gfxPSSurface : public gfxASurface {
|
||||||
public:
|
public:
|
||||||
|
#ifdef UNTESTED_CODE
|
||||||
|
gfxPSSurface(FILE *file, gfxSize aSizeInPonits); /* does not close the file */
|
||||||
|
#endif
|
||||||
gfxPSSurface(const char *filename, gfxSize aSizeInPonits);
|
gfxPSSurface(const char *filename, gfxSize aSizeInPonits);
|
||||||
virtual ~gfxPSSurface();
|
virtual ~gfxPSSurface();
|
||||||
|
|
||||||
|
|
|
@ -39,12 +39,30 @@
|
||||||
|
|
||||||
#include <cairo-ps.h>
|
#include <cairo-ps.h>
|
||||||
|
|
||||||
|
#ifdef UNTESTED_CODE
|
||||||
|
static cairo_status_t
|
||||||
|
write_func(void *closure,
|
||||||
|
const unsigned char *data,
|
||||||
|
unsigned int length)
|
||||||
|
{
|
||||||
|
fwrite(data, 1, length, (FILE*)closure);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gfxPSSurface::gfxPSSurface(const char *filename, gfxSize aSizeInPoints)
|
gfxPSSurface::gfxPSSurface(const char *filename, gfxSize aSizeInPoints)
|
||||||
: mXDPI(-1), mYDPI(-1), mSize(aSizeInPoints)
|
: mXDPI(-1), mYDPI(-1), mSize(aSizeInPoints)
|
||||||
{
|
{
|
||||||
Init(cairo_ps_surface_create(filename, mSize.width, mSize.height));
|
Init(cairo_ps_surface_create(filename, mSize.width, mSize.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNTESTED_CODE
|
||||||
|
gfxPSSurface::gfxPSSurface(FILE *file, gfxSize aSizeInPoints)
|
||||||
|
: mXDPI(-1), mYDPI(-1), mSize(aSizeInPoints)
|
||||||
|
{
|
||||||
|
Init(cairo_ps_surface_create_for_stream(write_func, file, mSize.width, mSize.height));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gfxPSSurface::~gfxPSSurface()
|
gfxPSSurface::~gfxPSSurface()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
|
@ -55,6 +55,13 @@ public:
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
#ifdef MOZ_CAIRO_GFX
|
||||||
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **nativeSurface) = 0;
|
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **nativeSurface) = 0;
|
||||||
|
|
||||||
|
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
|
||||||
|
PRUnichar* aPrintToFileName,
|
||||||
|
PRInt32 aStartPage,
|
||||||
|
PRInt32 aEndPage) = 0;
|
||||||
|
|
||||||
|
NS_IMETHOD EndDocument() = 0;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@ CPPSRCS = \
|
||||||
nsPrintOptionsGTK.cpp \
|
nsPrintOptionsGTK.cpp \
|
||||||
nsImageToPixbuf.cpp \
|
nsImageToPixbuf.cpp \
|
||||||
nsAccessibilityHelper.cpp \
|
nsAccessibilityHelper.cpp \
|
||||||
|
nsPrintJobFactoryGTK.cpp \
|
||||||
|
nsPrintJobGTK.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# build our subdirs, too
|
# build our subdirs, too
|
||||||
|
|
|
@ -69,6 +69,8 @@
|
||||||
#include "nsPaperPS.h" /* Paper size list */
|
#include "nsPaperPS.h" /* Paper size list */
|
||||||
#endif /* USE_POSTSCRIPT */
|
#endif /* USE_POSTSCRIPT */
|
||||||
|
|
||||||
|
#include "nsPrintJobFactoryGTK.h"
|
||||||
|
|
||||||
/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
|
/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
|
||||||
#define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
|
#define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
|
||||||
|
|
||||||
|
@ -379,11 +381,13 @@ nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
|
||||||
nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
|
nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
|
||||||
{
|
{
|
||||||
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
|
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
|
||||||
|
mPrintJob = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
|
nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
|
||||||
{
|
{
|
||||||
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
|
DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
|
||||||
|
delete mPrintJob;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use both PostScript and Xprint module */
|
/* Use both PostScript and Xprint module */
|
||||||
|
@ -417,7 +421,7 @@ NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK,
|
||||||
#include "nsUnitConversion.h"
|
#include "nsUnitConversion.h"
|
||||||
NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface)
|
NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface)
|
||||||
{
|
{
|
||||||
const char *path = nsnull;
|
const char *path;
|
||||||
GetPath(&path);
|
GetPath(&path);
|
||||||
|
|
||||||
PRInt32 width, height;
|
PRInt32 width, height;
|
||||||
|
@ -427,14 +431,15 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurfac
|
||||||
w = width/20;
|
w = width/20;
|
||||||
h = height/20;
|
h = height/20;
|
||||||
|
|
||||||
printf("%s, %d, %d\n", path, width, height);
|
printf("\"%s\", %d, %d\n", path, width, height);
|
||||||
|
|
||||||
|
nsPrintJobFactoryGTK::CreatePrintJob((this), mPrintJob);
|
||||||
#ifdef USE_PDF
|
#ifdef USE_PDF
|
||||||
gfxPDFSurface *surface = new gfxPDFSurface(path, gfxSize(w, h));
|
gfxPDFSurface *surface = new gfxPDFSurface(path, gfxSize(w, h));
|
||||||
#else
|
#else
|
||||||
gfxPSSurface *surface = new gfxPSSurface(path, gfxSize(w, h));
|
gfxPSSurface *surface = new gfxPSSurface(path, gfxSize(w, h));
|
||||||
#endif
|
#endif
|
||||||
surface->SetDPI(600, 600);
|
// surface->SetDPI(600, 600);
|
||||||
|
|
||||||
*aSurface = surface;
|
*aSurface = surface;
|
||||||
NS_ADDREF(*aSurface);
|
NS_ADDREF(*aSurface);
|
||||||
|
@ -713,6 +718,30 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::ClosePrintManager()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#include <errno.h>
|
||||||
|
NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument()
|
||||||
|
{
|
||||||
|
if (mToPrinter) {
|
||||||
|
const char *path;
|
||||||
|
GetPath(&path);
|
||||||
|
FILE *src = fopen(path, "r");
|
||||||
|
FILE *dst;
|
||||||
|
mPrintJob->StartSubmission(&dst);
|
||||||
|
while(!feof(src)) {
|
||||||
|
char data[255] = {0};
|
||||||
|
size_t s = fread(data, 1, sizeof(data), src);
|
||||||
|
fwrite(data, 1, s, dst);
|
||||||
|
}
|
||||||
|
fclose(src);
|
||||||
|
mPrintJob->FinishSubmission();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* Get prefs for printer
|
/* Get prefs for printer
|
||||||
* Search order:
|
* Search order:
|
||||||
* - Get prefs per printer name and module name
|
* - Get prefs per printer name and module name
|
||||||
|
|
|
@ -52,6 +52,8 @@
|
||||||
#endif /* USE_XPRINT */
|
#endif /* USE_XPRINT */
|
||||||
#include "nsCRT.h" /* should be <limits.h>? */
|
#include "nsCRT.h" /* should be <limits.h>? */
|
||||||
|
|
||||||
|
#include "nsIPrintJobGTK.h"
|
||||||
|
|
||||||
#define NS_PORTRAIT 0
|
#define NS_PORTRAIT 0
|
||||||
#define NS_LANDSCAPE 1
|
#define NS_LANDSCAPE 1
|
||||||
|
|
||||||
|
@ -81,6 +83,8 @@ public:
|
||||||
|
|
||||||
NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aIsPrintPreview);
|
NS_IMETHOD Init(nsIPrintSettings* aPS, PRBool aIsPrintPreview);
|
||||||
NS_IMETHOD ClosePrintManager();
|
NS_IMETHOD ClosePrintManager();
|
||||||
|
NS_IMETHOD BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName, PRInt32 aStartPage, PRInt32 aEndPage);
|
||||||
|
NS_IMETHOD EndDocument();
|
||||||
|
|
||||||
NS_IMETHOD GetToPrinter(PRBool &aToPrinter);
|
NS_IMETHOD GetToPrinter(PRBool &aToPrinter);
|
||||||
NS_IMETHOD GetIsPrintPreview(PRBool &aIsPPreview);
|
NS_IMETHOD GetIsPrintPreview(PRBool &aIsPPreview);
|
||||||
|
@ -127,6 +131,7 @@ protected:
|
||||||
float mRight; /* right margin */
|
float mRight; /* right margin */
|
||||||
float mTop; /* top margin */
|
float mTop; /* top margin */
|
||||||
float mBottom; /* bottom margin */
|
float mBottom; /* bottom margin */
|
||||||
|
nsIPrintJobGTK * mPrintJob;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/* -*- 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 "nsPrintJobFactoryGTK.h"
|
||||||
|
#include "nsIDeviceContextSpec.h"
|
||||||
|
#include "nsDeviceContextSpecG.h"
|
||||||
|
#include "nsPrintJobGTK.h"
|
||||||
|
#include "nsPSPrinters.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a print job object for the given device context spec.
|
||||||
|
*
|
||||||
|
* @param aSpec An nsDeviceContextSpecGTK object for the print
|
||||||
|
* job in question.
|
||||||
|
* @param aPrintJob A pointer to a print job object which will
|
||||||
|
* handle the print job.
|
||||||
|
* @return NS_OK if all is well, or a suitable error value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobFactoryGTK::CreatePrintJob(nsDeviceContextSpecGTK *aSpec,
|
||||||
|
nsIPrintJobGTK* &aPrintJob)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(nsnull != aSpec, "aSpec is NULL");
|
||||||
|
|
||||||
|
nsIPrintJobGTK *newPJ;
|
||||||
|
|
||||||
|
PRBool setting;
|
||||||
|
aSpec->GetIsPrintPreview(setting);
|
||||||
|
if (setting)
|
||||||
|
newPJ = new nsPrintJobPreviewGTK();
|
||||||
|
else {
|
||||||
|
aSpec->GetToPrinter(setting);
|
||||||
|
if (!setting)
|
||||||
|
newPJ = new nsPrintJobFileGTK();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char *printerName;
|
||||||
|
aSpec->GetPrinterName(&printerName);
|
||||||
|
if (nsPSPrinterList::kTypeCUPS == nsPSPrinterList::GetPrinterType(
|
||||||
|
nsDependentCString(printerName)))
|
||||||
|
newPJ = new nsPrintJobCUPS();
|
||||||
|
else
|
||||||
|
newPJ = new nsPrintJobPipeGTK();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!newPJ)
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
nsresult rv = newPJ->Init(aSpec);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
delete newPJ;
|
||||||
|
else
|
||||||
|
aPrintJob = newPJ;
|
||||||
|
return rv;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
/* -*- 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 ***** */
|
||||||
|
|
||||||
|
#ifndef nsPrintJobFactoryGTK_h__
|
||||||
|
#define nsPrintJobFactoryGTK_h__
|
||||||
|
|
||||||
|
#include "nscore.h"
|
||||||
|
#include "nsIPrintJobGTK.h"
|
||||||
|
#include "nsDeviceContextSpecG.h"
|
||||||
|
|
||||||
|
/* Factory class for the print job subsystem. This class determines
|
||||||
|
* which print job class should handle a print job, and constructs
|
||||||
|
* an object of the appropriate class.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class nsPrintJobFactoryGTK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Construct a print job object for the given device context spec.
|
||||||
|
* On success, the print job object is owned by the caller and should
|
||||||
|
* be destroyed when no longer needed.
|
||||||
|
*
|
||||||
|
* @param aSpec An nsIDeviceContextSpecGTK object for the print
|
||||||
|
* job in question.
|
||||||
|
* @param aPrintJob If NS_OK is returned, this will be filled in with
|
||||||
|
* a pointer to a print job object.
|
||||||
|
* @return NS_OK or a suitable error value.
|
||||||
|
*/
|
||||||
|
static nsresult CreatePrintJob(nsDeviceContextSpecGTK *aSpec,
|
||||||
|
nsIPrintJobGTK* &aPrintJob);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* nsPrintJobFactoryGTK_h__ */
|
|
@ -0,0 +1,554 @@
|
||||||
|
/* -*- 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
|
||||||
|
* Ken 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 "nscore.h"
|
||||||
|
#include "nsIDeviceContext.h" // NS_ERROR_GFX_*
|
||||||
|
#include "nsIDeviceContextPS.h" // NS_POSTSCRIPT_DRIVER_NAME_LEN
|
||||||
|
#include "nsIDeviceContextSpec.h"
|
||||||
|
#include "nsDeviceContextSpecG.h"
|
||||||
|
|
||||||
|
#include "nsPrintJobGTK.h"
|
||||||
|
#include "nsPSPrinters.h"
|
||||||
|
#include "nsReadableUtils.h"
|
||||||
|
|
||||||
|
#include "prenv.h"
|
||||||
|
#include "prinit.h"
|
||||||
|
#include "prlock.h"
|
||||||
|
#include "prprf.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Routines to set environment variables. These are defined toward
|
||||||
|
* the end of this file.
|
||||||
|
*/
|
||||||
|
static PRStatus EnvLock();
|
||||||
|
static PRStatus EnvSetPrinter(nsCString&);
|
||||||
|
static void EnvClear();
|
||||||
|
|
||||||
|
|
||||||
|
/* ~nsIPrintJobGTK() is virtual, so must implement a destructor. */
|
||||||
|
nsIPrintJobGTK::~nsIPrintJobGTK() {}
|
||||||
|
|
||||||
|
//#ifdef OLD_GFX_PRINTING
|
||||||
|
/**** nsPrintJobPreviewGTK - Stub class for print preview ****/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobPreviewGTK::Init(nsDeviceContextSpecGTK *aSpec)
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**** nsPrintJobFileGTK - Print-to-file support ****/
|
||||||
|
|
||||||
|
/* Print-to-file constructor */
|
||||||
|
nsPrintJobFileGTK::nsPrintJobFileGTK() : mDestHandle(nsnull) { }
|
||||||
|
|
||||||
|
/* Print-to-file destructor */
|
||||||
|
nsPrintJobFileGTK::~nsPrintJobFileGTK()
|
||||||
|
{
|
||||||
|
if (mDestHandle)
|
||||||
|
fclose(mDestHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the print-to-file object from the printing spec.
|
||||||
|
* See nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobFileGTK::Init(nsDeviceContextSpecGTK *aSpec)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aSpec, "aSpec must not be NULL");
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool toPrinter;
|
||||||
|
aSpec->GetToPrinter(toPrinter);
|
||||||
|
NS_PRECONDITION(!toPrinter, "This print job is to a printer");
|
||||||
|
#endif
|
||||||
|
const char *path;
|
||||||
|
aSpec->GetPath(&path);
|
||||||
|
mDestination = path;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the final output file and copy the temporary files there.
|
||||||
|
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobFileGTK::StartSubmission(FILE **aHandle)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aHandle, "aHandle is NULL");
|
||||||
|
NS_PRECONDITION(!mDestination.IsEmpty(), "No destination");
|
||||||
|
NS_PRECONDITION(!mDestHandle, "Already have a destination handle");
|
||||||
|
|
||||||
|
nsCOMPtr<nsILocalFile> destFile;
|
||||||
|
nsresult rv = NS_NewNativeLocalFile(GetDestination(),
|
||||||
|
PR_FALSE, getter_AddRefs(destFile));
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = destFile->OpenANSIFileDesc("w", &mDestHandle);
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE);
|
||||||
|
NS_POSTCONDITION(mDestHandle,
|
||||||
|
"OpenANSIFileDesc succeeded but no file handle");
|
||||||
|
*aHandle = mDestHandle;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish a print job. See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobFileGTK::FinishSubmission()
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(mDestHandle, "No destination file handle");
|
||||||
|
|
||||||
|
fclose(mDestHandle);
|
||||||
|
mDestHandle = nsnull;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#endif /* OLD_GFX_PRINTING */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
|
||||||
|
/**** Print-to-command on VMS. ****/
|
||||||
|
|
||||||
|
/* This implementation writes the print job to a temporary file, then runs
|
||||||
|
* the print command with the name of that file appended.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a VMS print-to-command object from the printing spec.
|
||||||
|
* See nsIPrintJobGTK.h and nsPrintJobGTK.h.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobVMSCmdGTK::Init(nsIDeviceContextSpec *aSpec)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aSpec, "argument must not be NULL");
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool toPrinter;
|
||||||
|
aSpec->GetToPrinter(toPrinter);
|
||||||
|
NS_PRECONDITION(toPrinter, "This print job is not to a printer");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Print command. This is stored as the destination string. */
|
||||||
|
const char *command;
|
||||||
|
aSpec->GetCommand(&command);
|
||||||
|
SetDestination(command);
|
||||||
|
|
||||||
|
/* Printer name */
|
||||||
|
const char *printerName;
|
||||||
|
aSpec->GetPrinterName(&printerName);
|
||||||
|
if (printerName) {
|
||||||
|
const char *slash = strchr(printerName, '/');
|
||||||
|
if (slash)
|
||||||
|
printerName = slash + 1;
|
||||||
|
if (0 != strcmp(printerName, "default"))
|
||||||
|
mPrinterName = printerName;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the temporary file for the print job and return a file handle
|
||||||
|
* to the caller.
|
||||||
|
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobVMSCmdGTK::StartSubmission(FILE **aHandle)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aHandle, "aHandle is NULL");
|
||||||
|
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
|
||||||
|
NS_PRECONDITION(!GetDestHandle(), "Already have a destination handle");
|
||||||
|
|
||||||
|
/* Create the final output file */
|
||||||
|
FILE *printHandle = nsnull;
|
||||||
|
nsresult rv = mTempFactory.CreateTempFile(
|
||||||
|
getter_AddRefs(mTempFile), &printHandle, "w+");
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
SetDestHandle(printHandle);
|
||||||
|
*aHandle = printHandle;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobVMSCmdGTK::FinishSubmission()
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(GetDestHandle(), "No destination file handle");
|
||||||
|
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
|
||||||
|
|
||||||
|
/* Close the temporary file handle */
|
||||||
|
fclose(GetDestHandle());
|
||||||
|
SetDestHandle(nsnull);
|
||||||
|
|
||||||
|
/* construct the print command */
|
||||||
|
nsCAutoString printFileName;
|
||||||
|
nsresult rv = mTempFile->GetNativePath(printFileName);
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
nsCAutoString cmd(GetDestination());
|
||||||
|
cmd += " "; cmd += printFileName; cmd += ".";
|
||||||
|
|
||||||
|
/* Set up the environment. */
|
||||||
|
if (PR_SUCCESS != EnvLock())
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
if (!mPrinterName.IsEmpty())
|
||||||
|
EnvSetPrinter(mPrinterName);
|
||||||
|
|
||||||
|
/* Run the print command */
|
||||||
|
int presult = system(cmd.get());
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
EnvClear();
|
||||||
|
mTempFile->Remove(PR_FALSE);
|
||||||
|
|
||||||
|
rv = (!WIFEXITED(presult) || (EXIT_SUCCESS != WEXITSTATUS(presult)))
|
||||||
|
? NS_ERROR_GFX_PRINTER_CMD_FAILURE : NS_OK;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#else /* NOT VMS */
|
||||||
|
|
||||||
|
/**** Print-to-Pipe for unix and unix-like systems ****/
|
||||||
|
|
||||||
|
/* This launches a command using popen(); the print job is then written
|
||||||
|
* to the pipe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Destructor. We must override the print-to-file destructor in order
|
||||||
|
* to pclose() any open file handle.
|
||||||
|
*/
|
||||||
|
nsPrintJobPipeGTK::~nsPrintJobPipeGTK()
|
||||||
|
{
|
||||||
|
if (GetDestHandle()) {
|
||||||
|
pclose(GetDestHandle());
|
||||||
|
SetDestHandle(nsnull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a print-to-pipe object.
|
||||||
|
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobPipeGTK::Init(nsDeviceContextSpecGTK *aSpec)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aSpec, "argument must not be NULL");
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool toPrinter;
|
||||||
|
aSpec->GetToPrinter(toPrinter);
|
||||||
|
NS_PRECONDITION(toPrinter, "Wrong class for this print job");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Print command. This is stored as the destination string. */
|
||||||
|
const char *command;
|
||||||
|
aSpec->GetCommand(&command);
|
||||||
|
SetDestination(command);
|
||||||
|
|
||||||
|
/* Printer name */
|
||||||
|
const char *printerName;
|
||||||
|
aSpec->GetPrinterName(&printerName);
|
||||||
|
if (printerName) {
|
||||||
|
const char *slash = strchr(printerName, '/');
|
||||||
|
if (slash)
|
||||||
|
printerName = slash + 1;
|
||||||
|
if (0 != strcmp(printerName, "default"))
|
||||||
|
mPrinterName = printerName;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch the print command using popen(), then copy the print job data
|
||||||
|
* to the pipe. See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobPipeGTK::StartSubmission(FILE **aHandle)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aHandle, "aHandle is NULL");
|
||||||
|
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
|
||||||
|
NS_PRECONDITION(!GetDestHandle(), "Already have a destination handle");
|
||||||
|
|
||||||
|
if (PR_SUCCESS != EnvLock())
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY; // Couldn't allocate the object?
|
||||||
|
if (!mPrinterName.IsEmpty())
|
||||||
|
EnvSetPrinter(mPrinterName);
|
||||||
|
|
||||||
|
FILE *destPipe = popen(GetDestination().get(), "w");
|
||||||
|
EnvClear();
|
||||||
|
if (!destPipe)
|
||||||
|
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
|
||||||
|
SetDestHandle(destPipe);
|
||||||
|
*aHandle = destPipe;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobPipeGTK::FinishSubmission()
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(GetDestHandle(), "No destination file handle");
|
||||||
|
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
|
||||||
|
|
||||||
|
int presult = pclose(GetDestHandle());
|
||||||
|
SetDestHandle(nsnull);
|
||||||
|
if (!WIFEXITED(presult) || (EXIT_SUCCESS != WEXITSTATUS(presult)))
|
||||||
|
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**** Print via CUPS ****/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a print-to-CUPS object.
|
||||||
|
* See nsIPrintJobGTK.h and nsPrintJobGTK.h for details.
|
||||||
|
*/
|
||||||
|
nsresult
|
||||||
|
nsPrintJobCUPS::Init(nsDeviceContextSpecGTK *aSpec)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aSpec, "argument must not be NULL");
|
||||||
|
#ifdef DEBUG
|
||||||
|
PRBool toPrinter;
|
||||||
|
aSpec->GetToPrinter(toPrinter);
|
||||||
|
NS_PRECONDITION(toPrinter, "Wrong class for this print job");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NS_ENSURE_TRUE(mCups.Init(), NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobCUPS::SetNumCopies(int aNumCopies)
|
||||||
|
{
|
||||||
|
mNumCopies.Truncate();
|
||||||
|
if (aNumCopies > 1)
|
||||||
|
mNumCopies.AppendInt(aNumCopies);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* According to the cups.development forum, only plain ASCII may be
|
||||||
|
* reliably used for CUPS print job titles. See
|
||||||
|
* <http://www.cups.org/newsgroups.php?s523+gcups.development+v530+T0>.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nsPrintJobCUPS::SetJobTitle(const PRUnichar *aTitle)
|
||||||
|
{
|
||||||
|
if (aTitle) {
|
||||||
|
LossyCopyUTF16toASCII(aTitle, mJobTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobCUPS::StartSubmission(FILE **aHandle)
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mCups.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
char buf[FILENAME_MAX];
|
||||||
|
|
||||||
|
fd = (mCups.mCupsTempFd)(buf, sizeof buf);
|
||||||
|
// The CUPS manual doesn't describe what cupsTempFd() returns to
|
||||||
|
// indicate failure. -1 is a likely value.
|
||||||
|
NS_ENSURE_TRUE(fd > 0, NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE);
|
||||||
|
|
||||||
|
SetDestHandle(fdopen(fd, "r+"));
|
||||||
|
if (!GetDestHandle()) {
|
||||||
|
close(fd);
|
||||||
|
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
|
||||||
|
}
|
||||||
|
SetDestination(buf);
|
||||||
|
*aHandle = GetDestHandle();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsPrintJobCUPS::FinishSubmission()
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(mCups.IsInitialized(), NS_ERROR_NOT_INITIALIZED);
|
||||||
|
NS_PRECONDITION(GetDestHandle(), "No destination file handle");
|
||||||
|
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
|
||||||
|
|
||||||
|
fclose(GetDestHandle());
|
||||||
|
SetDestHandle(nsnull);
|
||||||
|
|
||||||
|
nsCStringArray printer(3);
|
||||||
|
printer.ParseString(mPrinterName.get(),"/");
|
||||||
|
|
||||||
|
cups_dest_t *dests, *dest;
|
||||||
|
int num_dests = (mCups.mCupsGetDests)(&dests);
|
||||||
|
|
||||||
|
if (printer.Count() == 1) {
|
||||||
|
dest = (mCups.mCupsGetDest)(printer.CStringAt(0)->get(), NULL, num_dests, dests);
|
||||||
|
} else {
|
||||||
|
dest = (mCups.mCupsGetDest)(printer.CStringAt(0)->get(),
|
||||||
|
printer.CStringAt(1)->get(), num_dests, dests);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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());
|
||||||
|
|
||||||
|
// cupsPrintFile() result codes below 0x0300 indicate success.
|
||||||
|
// Individual success codes are defined in the cups headers, but
|
||||||
|
// we're not including those.
|
||||||
|
if (dest == NULL)
|
||||||
|
return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
|
||||||
|
else
|
||||||
|
return (result < 0x0300) ? NS_OK : NS_ERROR_GFX_PRINTER_CMD_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VMS */
|
||||||
|
|
||||||
|
|
||||||
|
/* Routines to set the MOZ_PRINTER_NAME environment variable and to
|
||||||
|
* single-thread print jobs while the variable is set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static PRLock *EnvLockObj;
|
||||||
|
static PRCallOnceType EnvLockOnce;
|
||||||
|
|
||||||
|
/* EnvLock callback function */
|
||||||
|
static PRStatus
|
||||||
|
EnvLockInit()
|
||||||
|
{
|
||||||
|
EnvLockObj = PR_NewLock();
|
||||||
|
return EnvLockObj ? PR_SUCCESS : PR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the lock for setting printing-related environment variables and
|
||||||
|
* running print commands.
|
||||||
|
* @return PR_SUCCESS on success
|
||||||
|
* PR_FAILURE if the lock object could not be initialized.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static PRStatus
|
||||||
|
EnvLock()
|
||||||
|
{
|
||||||
|
if (PR_FAILURE == PR_CallOnce(&EnvLockOnce, EnvLockInit))
|
||||||
|
return PR_FAILURE;
|
||||||
|
PR_Lock(EnvLockObj);
|
||||||
|
return PR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *EnvPrinterString;
|
||||||
|
static const char EnvPrinterName[] = { "MOZ_PRINTER_NAME" };
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set MOZ_PRINTER_NAME to the specified string.
|
||||||
|
* @param aPrinter The value for MOZ_PRINTER_NAME. May be an empty string.
|
||||||
|
* @return PR_SUCCESS on success.
|
||||||
|
* PR_FAILURE if memory could not be allocated.
|
||||||
|
*/
|
||||||
|
static PRStatus
|
||||||
|
EnvSetPrinter(nsCString& aPrinter)
|
||||||
|
{
|
||||||
|
/* Construct the new environment string */
|
||||||
|
char *newVar = PR_smprintf("%s=%s", EnvPrinterName, aPrinter.get());
|
||||||
|
if (!newVar)
|
||||||
|
return PR_FAILURE;
|
||||||
|
|
||||||
|
/* Add it to the environment and dispose of any old string */
|
||||||
|
PR_SetEnv(newVar);
|
||||||
|
if (EnvPrinterString)
|
||||||
|
PR_smprintf_free(EnvPrinterString);
|
||||||
|
EnvPrinterString = newVar;
|
||||||
|
|
||||||
|
return PR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the printer environment variable and release the environment lock.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
EnvClear()
|
||||||
|
{
|
||||||
|
if (EnvPrinterString) {
|
||||||
|
/* On some systems, setenv("FOO") will remove FOO
|
||||||
|
* from the environment.
|
||||||
|
*/
|
||||||
|
PR_SetEnv(EnvPrinterName);
|
||||||
|
if (!PR_GetEnv(EnvPrinterName)) {
|
||||||
|
/* It must have worked */
|
||||||
|
PR_smprintf_free(EnvPrinterString);
|
||||||
|
EnvPrinterString = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PR_Unlock(EnvLockObj);
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* -*- 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
|
||||||
|
* Ken 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 ***** */
|
||||||
|
|
||||||
|
#ifndef nsPrintJobGTK_h__
|
||||||
|
#define nsPrintJobGTK_h__
|
||||||
|
|
||||||
|
#include "nsCUPSShim.h"
|
||||||
|
#include "nsDebug.h"
|
||||||
|
#include "nsIDeviceContext.h" // for NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
#include "nsIPrintJobGTK.h"
|
||||||
|
#include "nsString.h"
|
||||||
|
#include "nsTempfilePS.h"
|
||||||
|
#include "nsDeviceContextSpecG.h"
|
||||||
|
|
||||||
|
/* Print job class for print preview operations. */
|
||||||
|
|
||||||
|
class nsPrintJobPreviewGTK : public nsIPrintJobGTK {
|
||||||
|
public:
|
||||||
|
/* see nsIPrintJobGTK.h. Print preview doesn't actually
|
||||||
|
* implement printing.
|
||||||
|
*/
|
||||||
|
nsresult StartSubmission(FILE **aHandle)
|
||||||
|
{ return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
|
nsresult FinishSubmission()
|
||||||
|
{ return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
|
nsresult SetNumCopies(int aNumCopies)
|
||||||
|
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* See nsIPrintJobGTK.h. */
|
||||||
|
nsresult Init(nsDeviceContextSpecGTK *);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Print job class for print-to-file. */
|
||||||
|
class nsPrintJobFileGTK : public nsIPrintJobGTK {
|
||||||
|
public:
|
||||||
|
nsPrintJobFileGTK();
|
||||||
|
~nsPrintJobFileGTK();
|
||||||
|
|
||||||
|
/* see nsIPrintJobGTK.h */
|
||||||
|
nsresult StartSubmission(FILE **aHandle);
|
||||||
|
nsresult FinishSubmission();
|
||||||
|
|
||||||
|
nsresult SetNumCopies(int aNumCopies)
|
||||||
|
{ return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* see nsIPrintJobGTK.h */
|
||||||
|
nsresult Init(nsDeviceContextSpecGTK *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the destination file handle.
|
||||||
|
* @param aHandle New value for the handle.
|
||||||
|
*/
|
||||||
|
void SetDestHandle(FILE *aHandle) { mDestHandle = aHandle; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current value for the destination file handle.
|
||||||
|
* @return the current value for the destination file handle.
|
||||||
|
*/
|
||||||
|
FILE *GetDestHandle() { return mDestHandle; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a string representing the destination. For print-to-file
|
||||||
|
* this is the name of the destination file. Subclasses could
|
||||||
|
* store something else here.
|
||||||
|
* @param aDest Destination filename.
|
||||||
|
*/
|
||||||
|
void SetDestination(const char *aDest) { mDestination = aDest; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string representing the destination.
|
||||||
|
* @return The current value of the destination string.
|
||||||
|
*/
|
||||||
|
nsCString& GetDestination() { return mDestination; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *mDestHandle; // Destination file handle
|
||||||
|
nsCString mDestination;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the class for printing to a pipe. The destination for
|
||||||
|
* GetDestination() and SetDestination() is a command to be executed,
|
||||||
|
* rather than a filename.
|
||||||
|
*/
|
||||||
|
class nsPrintJobPipeGTK : public nsPrintJobFileGTK {
|
||||||
|
public:
|
||||||
|
/* see nsIPrintJobGTK.h */
|
||||||
|
~nsPrintJobPipeGTK();
|
||||||
|
nsresult StartSubmission(FILE **aHandle);
|
||||||
|
nsresult FinishSubmission();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult Init(nsDeviceContextSpecGTK *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCString mPrinterName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* This class submits print jobs through CUPS. mDestHandle and
|
||||||
|
* mDestination point to a temporary file used to assemble the
|
||||||
|
* final print job.
|
||||||
|
*/
|
||||||
|
class nsPrintJobCUPS : public nsPrintJobFileGTK {
|
||||||
|
public:
|
||||||
|
nsresult StartSubmission(FILE **aHandle);
|
||||||
|
nsresult FinishSubmission();
|
||||||
|
nsresult SetNumCopies(int aNumCopies);
|
||||||
|
void SetJobTitle(const PRUnichar *aTitle);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsresult Init(nsDeviceContextSpecGTK *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
nsCUPSShim mCups;
|
||||||
|
nsCString mPrinterName;
|
||||||
|
nsCString mNumCopies;
|
||||||
|
nsCString mJobTitle; // IsVoid() if no title
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* nsPrintJobPS_h__ */
|
|
@ -57,6 +57,11 @@ public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
#ifdef MOZ_CAIRO_GFX
|
#ifdef MOZ_CAIRO_GFX
|
||||||
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface);
|
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface);
|
||||||
|
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
|
||||||
|
PRUnichar* aPrintToFileName,
|
||||||
|
PRInt32 aStartPage,
|
||||||
|
PRInt32 aEndPage) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
NS_IMETHOD EndDocument() { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -58,6 +58,11 @@ public:
|
||||||
|
|
||||||
#ifdef MOZ_CAIRO_GFX
|
#ifdef MOZ_CAIRO_GFX
|
||||||
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface);
|
NS_IMETHOD GetSurfaceForPrinter(gfxASurface **surface);
|
||||||
|
NS_IMETHOD BeginDocument(PRUnichar* aTitle,
|
||||||
|
PRUnichar* aPrintToFileName,
|
||||||
|
PRInt32 aStartPage,
|
||||||
|
PRInt32 aEndPage) { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
|
NS_IMETHOD EndDocument() { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||||
#else
|
#else
|
||||||
// kill these when we move to CAIRO_GFX
|
// kill these when we move to CAIRO_GFX
|
||||||
NS_IMETHOD GetType(PRUint16 *aType) { *aType = nsISupportsPrimitive::TYPE_VOID; return NS_OK; }
|
NS_IMETHOD GetType(PRUint16 *aType) { *aType = nsISupportsPrimitive::TYPE_VOID; return NS_OK; }
|
||||||
|
|
Загрузка…
Ссылка в новой задаче