зеркало из https://github.com/mozilla/pjs.git
Bug 72087 - major xprint revamp
patch by Roland.Mainz@informatik.med.uni-giessen.de r=blizzard, sr=shaver, a=asa NOT PART OF DEFAULT BUILD
This commit is contained in:
Родитель
c88f0571f4
Коммит
2e000089ba
|
@ -356,11 +356,11 @@ NS_IMETHODIMP nsDeviceContextSpecGTK :: GetPrintMethod(int &aMethod )
|
|||
nsresult rv;
|
||||
nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && pPrefs) {
|
||||
PRInt32 method = 0;
|
||||
PRInt32 method = NS_DEFAULT_PRINT_METHOD;
|
||||
(void) pPrefs->GetIntPref("print.print_method", &method);
|
||||
aMethod = method;
|
||||
} else {
|
||||
aMethod = 0;
|
||||
aMethod = NS_DEFAULT_PRINT_METHOD;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -275,11 +275,11 @@ NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrintMethod(int &aMethod)
|
|||
nsresult rv;
|
||||
nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && pPrefs) {
|
||||
PRInt32 method = 0;
|
||||
PRInt32 method = NS_DEFAULT_PRINT_METHOD;
|
||||
(void) pPrefs->GetIntPref("print.print_method", &method);
|
||||
aMethod = method;
|
||||
} else {
|
||||
aMethod = 0;
|
||||
aMethod = NS_DEFAULT_PRINT_METHOD;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -17,6 +17,7 @@
|
|||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
|
@ -30,9 +31,11 @@ MODULE = layout
|
|||
LIBRARY_NAME = gfxxprt
|
||||
IS_COMPONENT = 1
|
||||
EXTRA_DSO_LIBS = gkgfx
|
||||
REQUIRES = xpcom string widget view img util dom pref locale uconv unicharutil gfx2
|
||||
REQUIRES = xpcom string widget view img util dom pref locale uconv unicharutil gfx2 necko
|
||||
|
||||
CSRCS = ../xlibrgb/xlibrgb.c \
|
||||
xprintutil.c \
|
||||
xprintutil_printtofile.c \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
|
|
@ -18,9 +18,11 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
||||
* Bradley Baetz <bbaetz@cs.mcgill.ca>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream.h>
|
||||
#include <unistd.h>
|
||||
#include "nsDeviceContextXP.h"
|
||||
#include "nsRenderingContextXP.h"
|
||||
|
@ -29,10 +31,10 @@
|
|||
#include "nsIDeviceContextSpecXPrint.h"
|
||||
#include "il_util.h"
|
||||
#include "nspr.h"
|
||||
#include "nsXPrintContext.h"
|
||||
|
||||
static PRLogModuleInfo *nsDeviceContextXPLM = PR_NewLogModule("nsDeviceContextXP");
|
||||
|
||||
/*
|
||||
static NS_DEFINE_IID(kDeviceContextIID, NS_IDEVICE_CONTEXT_IID);
|
||||
*/
|
||||
static NS_DEFINE_IID(kIDeviceContextSpecXPIID, NS_IDEVICE_CONTEXT_SPEC_XP_IID);
|
||||
|
||||
/** ---------------------------------------------------
|
||||
|
@ -40,9 +42,7 @@ static NS_DEFINE_IID(kIDeviceContextSpecXPIID, NS_IDEVICE_CONTEXT_SPEC_XP_IID);
|
|||
*/
|
||||
nsDeviceContextXP :: nsDeviceContextXP()
|
||||
{
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
mSpec = nsnull;
|
||||
/* Inherited from xlib device context code */
|
||||
mTwipsToPixels = 1.0;
|
||||
mPixelsToTwips = 1.0;
|
||||
|
@ -53,46 +53,35 @@ nsDeviceContextXP :: nsDeviceContextXP()
|
|||
mNumCells = 0;
|
||||
mPrintContext = nsnull;
|
||||
|
||||
mWidthFloat = 0.0f;
|
||||
mWidthFloat = 0.0f;
|
||||
mHeightFloat = 0.0f;
|
||||
mWidth = -1;
|
||||
mWidth = -1;
|
||||
mHeight = -1;
|
||||
|
||||
NS_NewISupportsArray(getter_AddRefs(mFontMetrics));
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsIDeviceContext.h
|
||||
* @update 12/21/98 dwc
|
||||
* @update 12/21/98 dwc
|
||||
*/
|
||||
nsDeviceContextXP :: ~nsDeviceContextXP()
|
||||
{
|
||||
PRInt32 i, n;
|
||||
nsDeviceContextXP :: ~nsDeviceContextXP() { }
|
||||
|
||||
// get rid of the fonts in our mFontMetrics cache
|
||||
n= mFontMetrics.Count();
|
||||
for (i = 0; i < n; i++){
|
||||
nsIFontMetrics* fm = (nsIFontMetrics*) mFontMetrics.ElementAt(i);
|
||||
fm->Destroy();
|
||||
NS_RELEASE(fm);
|
||||
}
|
||||
mFontMetrics.Clear();
|
||||
NS_IF_RELEASE(mSpec);
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDeviceContextXP :: SetSpec(nsIDeviceContextSpec* aSpec)
|
||||
{
|
||||
nsIDeviceContextSpecXP *psSpec;
|
||||
nsresult res;
|
||||
PR_LOG(nsDeviceContextXPLM, PR_LOG_DEBUG, ("nsDeviceContextXP::SetSpec()\n"));
|
||||
|
||||
nsCOMPtr<nsIDeviceContextSpecXP> xpSpec;
|
||||
|
||||
mSpec = aSpec;
|
||||
NS_ADDREF(aSpec);
|
||||
if (mPrintContext == nsnull) {
|
||||
|
||||
if (!mPrintContext) {
|
||||
mPrintContext = new nsXPrintContext();
|
||||
res = mSpec->QueryInterface(kIDeviceContextSpecXPIID, (void **) &psSpec);
|
||||
if (res == NS_OK) {
|
||||
mPrintContext->Init(psSpec);
|
||||
xpSpec = do_QueryInterface(mSpec);
|
||||
if (xpSpec) {
|
||||
mPrintContext->Init(xpSpec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,10 +115,6 @@ nsDeviceContextXP::InitDeviceContextXP(nsIDeviceContext *aCreatingDeviceContext,
|
|||
mAppUnitsToDevUnits = (a2d / t2d) * mTwipsToPixels;
|
||||
mDevUnitsToAppUnits = 1.0f / mAppUnitsToDevUnits;
|
||||
|
||||
#ifdef XPRINT_ON_SCREEN
|
||||
mAppUnitsToDevUnits = 1.0;
|
||||
mDevUnitsToAppUnits = 1.0;
|
||||
#endif
|
||||
mScreen = mPrintContext->GetScreen();
|
||||
mDisplay = mPrintContext->GetDisplay();
|
||||
|
||||
|
@ -146,16 +131,18 @@ NS_IMETHODIMP nsDeviceContextXP :: CreateRenderingContext(nsIRenderingContext *&
|
|||
{
|
||||
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
aContext = new nsRenderingContextXP();
|
||||
if (nsnull != aContext){
|
||||
NS_ADDREF(aContext);
|
||||
rv = ((nsRenderingContextXP*) aContext)->Init(this);
|
||||
nsCOMPtr<nsRenderingContextXP> xpContext;
|
||||
|
||||
xpContext = new nsRenderingContextXP();
|
||||
if (xpContext){
|
||||
rv = xpContext->Init(this);
|
||||
}
|
||||
|
||||
if (NS_OK != rv){
|
||||
NS_IF_RELEASE(aContext);
|
||||
}
|
||||
return rv;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aContext = xpContext;
|
||||
NS_ADDREF(aContext);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
|
@ -171,10 +158,10 @@ NS_IMETHODIMP nsDeviceContextXP :: SupportsNativeWidgets(PRBool &aSupportsWidget
|
|||
* See documentation in nsIDeviceContext.h
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP :: GetScrollBarDimensions(float &aWidth,
|
||||
float &aHeight) const
|
||||
float &aHeight) const
|
||||
{
|
||||
// XXX Oh, yeah. These are hard coded.
|
||||
aWidth = 15 * mPixelsToTwips;
|
||||
aWidth = 15 * mPixelsToTwips;
|
||||
aHeight = 15 * mPixelsToTwips;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -210,16 +197,16 @@ NS_IMETHODIMP nsDeviceContextXP::GetILColorSpace(IL_ColorSpace*& aColorSpace)
|
|||
IL_AddRefToColorSpace(aColorSpace);
|
||||
#endif
|
||||
|
||||
if(nsnull==mColorSpace) {
|
||||
if(!mColorSpace) {
|
||||
IL_RGBBits colorRGBBits;
|
||||
|
||||
// Create a 24-bit color space
|
||||
colorRGBBits.red_shift = 16;
|
||||
colorRGBBits.red_bits = 8;
|
||||
colorRGBBits.green_shift = 8;
|
||||
colorRGBBits.green_bits = 8;
|
||||
colorRGBBits.blue_shift = 0;
|
||||
colorRGBBits.blue_bits = 8;
|
||||
colorRGBBits.red_shift = 16;
|
||||
colorRGBBits.red_bits = 8;
|
||||
colorRGBBits.green_shift = 8;
|
||||
colorRGBBits.green_bits = 8;
|
||||
colorRGBBits.blue_shift = 0;
|
||||
colorRGBBits.blue_bits = 8;
|
||||
|
||||
mColorSpace = IL_CreateTrueColorSpace(&colorRGBBits, 24);
|
||||
|
||||
|
@ -239,10 +226,21 @@ NS_IMETHODIMP nsDeviceContextXP::GetILColorSpace(IL_ColorSpace*& aColorSpace)
|
|||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsIDeviceContext.h
|
||||
* @update 12/21/98 dwc
|
||||
* @update 12/21/98 dwc
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP :: CheckFontExistence(const nsString& aFontName)
|
||||
{
|
||||
PR_LOG(nsDeviceContextXPLM, PR_LOG_DEBUG, ("nsDeviceContextXP::CheckFontExistence()\n"));
|
||||
/* BUG: this does - unfortunately - not work due missing DISPLAY ptr
|
||||
* Additionally this is the _wrong_ time to make any assumtions
|
||||
* about fonts - this info+the correct information is _only_
|
||||
* available _after_ XpSetContext() - therefore any assumtions
|
||||
* made here are _wrong_ until we have a vaoid XPContext
|
||||
* (X11 print context)
|
||||
*/
|
||||
#if 0
|
||||
return nsFontMetricsXP::FamilyExists(aFontName);
|
||||
#else
|
||||
char **fnames = nsnull;
|
||||
PRInt32 namelen = aFontName.Length() + 1;
|
||||
char *wildstring = (char *)PR_Malloc(namelen + 200);
|
||||
|
@ -253,22 +251,27 @@ NS_IMETHODIMP nsDeviceContextXP :: CheckFontExistence(const nsString& aFontName)
|
|||
XFontStruct *fonts;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (nsnull == wildstring)
|
||||
if (!wildstring)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (abs(dpi - 75) < abs(dpi - 100))
|
||||
#if 0 /* gisburn: this cannot work - Xprint usually operates at >= 300dpi */
|
||||
if (abs(dpi - 75) < abs(dpi - 100))
|
||||
dpi = 75;
|
||||
else
|
||||
dpi = 100;
|
||||
#endif
|
||||
|
||||
char* fontName = aFontName.ToNewCString();
|
||||
PR_snprintf(wildstring, namelen + 200,
|
||||
" -*-%s-*-*-normal-*-*-*-%d-%d-*-*-*-*",
|
||||
fontName, dpi, dpi);
|
||||
delete [] fontName;
|
||||
aFontName.get(), dpi, dpi);
|
||||
|
||||
/* applications must not make any assumptions about fonts _before_ XpSetContext() !!! */
|
||||
NS_ASSERTION((XpGetContext(mDisplay) != None), "Obtaining font information (XListFontsWithInfo()) _before_ XpSetContext()");
|
||||
fnames = ::XListFontsWithInfo(mDisplay, wildstring, 1, &numnames, &fonts);
|
||||
|
||||
PR_LOG(nsDeviceContextXPLM, PR_LOG_DEBUG,
|
||||
("nsDeviceContextXP::CheckFontExistence: XListFontsWithInfo '%s'=%d\n", wildstring, numnames));
|
||||
|
||||
if (numnames > 0)
|
||||
{
|
||||
::XFreeFontInfo(fnames, fonts, numnames);
|
||||
|
@ -277,10 +280,11 @@ NS_IMETHODIMP nsDeviceContextXP :: CheckFontExistence(const nsString& aFontName)
|
|||
|
||||
PR_Free(wildstring);
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextXP :: GetSystemAttribute(nsSystemAttrID anID,
|
||||
SystemAttrStruct * aInfo) const
|
||||
SystemAttrStruct * aInfo) const
|
||||
{
|
||||
switch (anID) {
|
||||
case 0:
|
||||
|
@ -295,7 +299,7 @@ NS_IMETHODIMP nsDeviceContextXP :: GetSystemAttribute(nsSystemAttrID anID,
|
|||
* See documentation in nsIDeviceContext.h
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP::GetDeviceSurfaceDimensions(PRInt32 &aWidth,
|
||||
PRInt32 &aHeight)
|
||||
PRInt32 &aHeight)
|
||||
{
|
||||
float width, height;
|
||||
width = (float) mPrintContext->GetWidth();
|
||||
|
@ -304,10 +308,6 @@ NS_IMETHODIMP nsDeviceContextXP::GetDeviceSurfaceDimensions(PRInt32 &aWidth,
|
|||
// height = height - 200;
|
||||
aWidth = NSToIntRound(width * mDevUnitsToAppUnits);
|
||||
aHeight = NSToIntRound(height * mDevUnitsToAppUnits);
|
||||
#ifdef XPRINT_ON_SCREEN
|
||||
aWidth = width;
|
||||
aHeight = height;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -347,7 +347,7 @@ NS_IMETHODIMP nsDeviceContextXP::BeginDocument(PRUnichar * aTitle)
|
|||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mPrintContext != nsnull) {
|
||||
rv = mPrintContext->BeginDocument();
|
||||
rv = mPrintContext->BeginDocument(aTitle);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -360,7 +360,16 @@ NS_IMETHODIMP nsDeviceContextXP::EndDocument(void)
|
|||
nsresult rv = NS_OK;
|
||||
if (mPrintContext != nsnull) {
|
||||
rv = mPrintContext->EndDocument();
|
||||
|
||||
// gisburn: mPrintContext cannot be reused between to print
|
||||
// tasks as the destination print server may be a different one
|
||||
// or the printer used on the same print server has other
|
||||
// properties (build-in fonts for example ) than the printer
|
||||
// previously used
|
||||
delete mPrintContext;
|
||||
mPrintContext = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -378,7 +387,7 @@ NS_IMETHODIMP nsDeviceContextXP::BeginPage(void)
|
|||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsIDeviceContext.h
|
||||
* @update 12/21/98 dwc
|
||||
* @update 12/21/98 dwc
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP::EndPage(void)
|
||||
{
|
||||
|
@ -391,10 +400,10 @@ NS_IMETHODIMP nsDeviceContextXP::EndPage(void)
|
|||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsIDeviceContext.h
|
||||
* @update 12/21/98 dwc
|
||||
* @update 12/21/98 dwc
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP :: ConvertPixel(nscolor aColor,
|
||||
PRUint32 & aPixel)
|
||||
PRUint32 & aPixel)
|
||||
{
|
||||
aPixel = aColor;
|
||||
return NS_OK;
|
||||
|
@ -424,34 +433,41 @@ NS_IMETHODIMP nsDeviceContextXP::GetDepth(PRUint32& aDepth)
|
|||
* See documentation in nsIDeviceContext.h
|
||||
*/
|
||||
NS_IMETHODIMP nsDeviceContextXP::GetMetricsFor(const nsFont& aFont,
|
||||
nsIAtom* aLangGroup, nsIFontMetrics *&aMetrics)
|
||||
nsIAtom* aLangGroup, nsIFontMetrics *&aMetrics)
|
||||
{
|
||||
return GetMetricsFor(aFont, aMetrics);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDeviceContextXP::GetMetricsFor(const nsFont& aFont,
|
||||
nsIFontMetrics *&aMetrics)
|
||||
nsIFontMetrics *&aMetrics)
|
||||
{
|
||||
PRInt32 n,cnt;
|
||||
PRUint32 n,cnt;
|
||||
nsresult rv;
|
||||
|
||||
// First check our cache
|
||||
n = mFontMetrics.Count();
|
||||
rv = mFontMetrics->Count(&n);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIFontMetrics> m;
|
||||
|
||||
for (cnt = 0; cnt < n; cnt++){
|
||||
aMetrics = (nsIFontMetrics*) mFontMetrics.ElementAt(cnt);
|
||||
|
||||
const nsFont *font;
|
||||
aMetrics->GetFont(font);
|
||||
if (aFont.Equals(*font)){
|
||||
NS_ADDREF(aMetrics);
|
||||
return NS_OK;
|
||||
for (cnt = 0; cnt < n; cnt++) {
|
||||
if (NS_SUCCEEDED(mFontMetrics->QueryElementAt(cnt,
|
||||
NS_GET_IID(nsIFontMetrics),
|
||||
getter_AddRefs(m)))) {
|
||||
const nsFont* font;
|
||||
m->GetFont(font);
|
||||
if (aFont.Equals(*font)) {
|
||||
aMetrics = m;
|
||||
NS_ADDREF(aMetrics);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It's not in the cache. Get font metrics and then cache them.
|
||||
nsIFontMetrics* fm = new nsFontMetricsXP();
|
||||
if (nsnull == fm) {
|
||||
nsCOMPtr<nsIFontMetrics> fm = new nsFontMetricsXP();
|
||||
if (!fm) {
|
||||
aMetrics = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -459,24 +475,21 @@ NS_IMETHODIMP nsDeviceContextXP::GetMetricsFor(const nsFont& aFont,
|
|||
// XXX need to pass real lang group
|
||||
rv = fm->Init(aFont, nsnull, this);
|
||||
|
||||
if (NS_OK != rv) {
|
||||
if (NS_FAILED(rv)) {
|
||||
aMetrics = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mFontMetrics.AppendElement(fm);
|
||||
NS_ADDREF(fm); // this is for the cache
|
||||
mFontMetrics->AppendElement(fm);
|
||||
|
||||
|
||||
for (cnt = 0; cnt < n; cnt++){
|
||||
aMetrics = (nsIFontMetrics*) mFontMetrics.ElementAt(cnt);
|
||||
const nsFont *font;
|
||||
aMetrics->GetFont(font);
|
||||
}
|
||||
|
||||
NS_ADDREF(fm); // this is for the routine that needs this font
|
||||
aMetrics = fm;
|
||||
NS_ADDREF(aMetrics);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDeviceContextXP::GetPrintContext(nsXPrintContext*& aContext) {
|
||||
aContext = mPrintContext;
|
||||
//NS_ADDREF(aContext);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -31,16 +31,16 @@
|
|||
#include "nsIRenderingContext.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsIDeviceContextXPrint.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
class nsXPrintContext;
|
||||
|
||||
class nsDeviceContextXP : public DeviceContextImpl,
|
||||
public nsIDeviceContextXP
|
||||
class nsDeviceContextXP : public nsIDeviceContextXP
|
||||
{
|
||||
public:
|
||||
nsDeviceContextXP();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
/**
|
||||
* This method does nothing since a postscript devicecontext will never be created
|
||||
|
@ -57,47 +57,47 @@ public:
|
|||
|
||||
NS_IMETHOD GetScrollBarDimensions(float &aWidth, float &aHeight) const;
|
||||
|
||||
void SetDrawingSurface(nsDrawingSurface aSurface) { mSurface = aSurface; }
|
||||
NS_IMETHOD GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface);
|
||||
void SetDrawingSurface(nsDrawingSurface aSurface) { mSurface = aSurface; }
|
||||
NS_IMETHOD GetDrawingSurface(nsIRenderingContext &aContext, nsDrawingSurface &aSurface);
|
||||
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFontName);
|
||||
NS_IMETHODIMP GetILColorSpace(IL_ColorSpace*& aColorSpace);
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
NS_IMETHOD ConvertPixel(nscolor aColor, PRUint32 & aPixel);
|
||||
NS_IMETHOD CheckFontExistence(const nsString& aFontName);
|
||||
NS_IMETHODIMP GetILColorSpace(IL_ColorSpace*& aColorSpace);
|
||||
NS_IMETHOD GetDepth(PRUint32& aDepth);
|
||||
NS_IMETHOD ConvertPixel(nscolor aColor, PRUint32 & aPixel);
|
||||
|
||||
NS_IMETHOD GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD GetRect(nsRect &aRect);
|
||||
NS_IMETHOD GetClientRect(nsRect &aRect);
|
||||
NS_IMETHOD GetDeviceSurfaceDimensions(PRInt32 &aWidth, PRInt32 &aHeight);
|
||||
NS_IMETHOD GetRect(nsRect &aRect);
|
||||
NS_IMETHOD GetClientRect(nsRect &aRect);
|
||||
|
||||
NS_IMETHOD GetDeviceContextFor(nsIDeviceContextSpec *aDevice,nsIDeviceContext *&aContext);
|
||||
NS_IMETHOD GetSystemAttribute(nsSystemAttrID anID, SystemAttrStruct * aInfo) const;
|
||||
NS_IMETHOD BeginDocument(PRUnichar * aTitle);
|
||||
NS_IMETHOD EndDocument(void);
|
||||
NS_IMETHOD BeginPage(void);
|
||||
NS_IMETHOD EndPage(void);
|
||||
NS_IMETHOD GetDeviceContextFor(nsIDeviceContextSpec *aDevice,nsIDeviceContext *&aContext);
|
||||
NS_IMETHOD GetSystemAttribute(nsSystemAttrID anID, SystemAttrStruct * aInfo) const;
|
||||
NS_IMETHOD BeginDocument(PRUnichar * aTitle);
|
||||
NS_IMETHOD EndDocument(void);
|
||||
NS_IMETHOD BeginPage(void);
|
||||
NS_IMETHOD EndPage(void);
|
||||
|
||||
NS_IMETHOD SetSpec(nsIDeviceContextSpec *aSpec);
|
||||
|
||||
Display * GetDisplay();
|
||||
nsXPrintContext *GetPrintContext() { return mPrintContext; }
|
||||
Display * GetDisplay();
|
||||
NS_IMETHOD GetPrintContext(nsXPrintContext*& aContext);
|
||||
|
||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics);
|
||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup, nsIFontMetrics*& aMetrics);
|
||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||
nsIFontMetrics*& aMetrics);
|
||||
|
||||
protected:
|
||||
virtual ~nsDeviceContextXP();
|
||||
virtual ~nsDeviceContextXP();
|
||||
|
||||
nsDrawingSurface mSurface ;
|
||||
nsXPrintContext *mPrintContext;
|
||||
Display *mDisplay;
|
||||
Screen *mScreen;
|
||||
PRUint32 mDepth;
|
||||
nsIDeviceContextSpec *mSpec;
|
||||
nsDrawingSurface mSurface;
|
||||
nsXPrintContext *mPrintContext;
|
||||
Display *mDisplay;
|
||||
Screen *mScreen;
|
||||
PRUint32 mDepth;
|
||||
nsCOMPtr<nsIDeviceContextSpec> mSpec;
|
||||
float mPixelScale;
|
||||
nsVoidArray mFontMetrics; // we are not using the normal font cache, this is special for PostScript.
|
||||
nsCOMPtr<nsISupportsArray> mFontMetrics; // we are not using the normal font cache
|
||||
|
||||
private:
|
||||
void CommonInit(void);
|
||||
nsPaletteInfo mPaletteInfo;
|
||||
PRBool mWriteable;
|
||||
PRUint32 mNumCells;
|
||||
|
@ -109,4 +109,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
#endif /* nsDeviceContextPS_h___ */
|
||||
#endif /* !nsDeviceContextPS_h___ */
|
||||
|
|
|
@ -203,7 +203,7 @@ NS_IMETHODIMP nsFontMetricsXP::Init(const nsFont& aFont, nsIAtom* aLangGroup,
|
|||
nsAutoString loc(str);
|
||||
loc.Truncate(2);
|
||||
loc.ToLowerCase();
|
||||
if ((loc.Equals(NS_ConvertASCIItoUCS2("ja"))) ||
|
||||
if ((loc.Equals(NS_ConvertASCIItoUCS2("ja"))) ||
|
||||
(loc.Equals(NS_ConvertASCIItoUCS2("ko"))) ||
|
||||
(loc.Equals(NS_ConvertASCIItoUCS2("zh")))) {
|
||||
// In CJK environments, we want the minimum request to be 16px,
|
||||
|
@ -1140,7 +1140,7 @@ static nsFontCharSetMap gCharSetMap[] =
|
|||
{ "johabs-1", &X11Johab },
|
||||
{ "johabsh-1", &X11Johab },
|
||||
{ "ksc5601.1987-0", &KSC5601 },
|
||||
{ "microsoft-cp1251", &CP1251 },
|
||||
{ "microsoft-cp1251", &CP1251 },
|
||||
{ "misc-fontspecific", &Ignore },
|
||||
{ "sgi-fontspecific", &Ignore },
|
||||
{ "sun-fontspecific", &Ignore },
|
||||
|
@ -1315,7 +1315,11 @@ GetMapFor10646Font(XFontStruct* aFont)
|
|||
void
|
||||
nsFontXP::LoadFont(nsFontCharSet* aCharSet, nsFontMetricsXP* aMetrics)
|
||||
{
|
||||
// XXX this is slow as dirt.
|
||||
PR_LOG(FontMetricsXPLM, PR_LOG_DEBUG, ("nsFontXP::LoadFont: loading font '%s'\n", mName));
|
||||
|
||||
/* applications must not make any assumptions about fonts _before_ XpSetContext() !!! */
|
||||
NS_ASSERTION((XpGetContext(aMetrics->mDisplay) != None), "Obtaining font information (XLoadQueryFont()) _before_ XpSetContext()");
|
||||
// XXX this is slow as dirt
|
||||
XFontStruct *xlibFont = XLoadQueryFont(aMetrics->mDisplay, mName);
|
||||
if (xlibFont) {
|
||||
if (aCharSet->mInfo->mCharSet) {
|
||||
|
@ -1324,7 +1328,7 @@ nsFontXP::LoadFont(nsFontCharSet* aCharSet, nsFontMetricsXP* aMetrics)
|
|||
else {
|
||||
mMap = GetMapFor10646Font(xlibFont);
|
||||
if (!mMap) {
|
||||
XFreeFont(aMetrics->mDisplay, xlibFont);
|
||||
XFreeFont(aMetrics->mDisplay, xlibFont);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1389,7 +1393,7 @@ nsFontXPNormal::GetWidth(const PRUnichar* aString, PRUint32 aLength)
|
|||
XChar2b buf[512];
|
||||
int ret;
|
||||
int len = mCharSetInfo->Convert(mCharSetInfo, aString, aLength,
|
||||
(char*) buf, sizeof(buf));
|
||||
(char*) buf, sizeof(buf));
|
||||
// XXX this is slow as dirt.
|
||||
XFontStruct *font_struct = mFont;
|
||||
if ((font_struct->min_byte1 == 0) && (font_struct->max_byte1 == 0))
|
||||
|
@ -1406,7 +1410,7 @@ nsFontXPNormal::DrawString(nsXPrintContext* aPrintContext,
|
|||
{
|
||||
XChar2b buf[512];
|
||||
int len = mCharSetInfo->Convert(mCharSetInfo, aString, aLength,
|
||||
(char*) buf, sizeof(buf));
|
||||
(char*) buf, sizeof(buf));
|
||||
XFontStruct *font_struct = mFont;
|
||||
nsFontMetricsXP::SetFont(aPrintContext, font_struct->fid);
|
||||
if ((font_struct->min_byte1 == 0) && (font_struct->max_byte1 == 0))
|
||||
|
@ -1468,18 +1472,18 @@ public:
|
|||
|
||||
virtual int GetWidth(const PRUnichar* aString, PRUint32 aLength);
|
||||
virtual int DrawString(nsXPrintContext* aContext,
|
||||
nscoord aX,
|
||||
nscoord aX,
|
||||
nscoord aY, const PRUnichar* aString,
|
||||
PRUint32 aLength);
|
||||
#ifdef MOZ_MATHML
|
||||
virtual nsresult GetBoundingMetrics(const PRUnichar* aString,
|
||||
PRUint32 aLength,
|
||||
nsBoundingMetrics& aBoundingMetrics);
|
||||
#endif
|
||||
#endif /* MOZ_MATHML */
|
||||
virtual PRUint32 Convert(const PRUnichar* aSrc, PRUint32 aSrcLen,
|
||||
PRUnichar* aDest, PRUint32 aDestLen);
|
||||
|
||||
nsFontXP* mSubstituteFont;
|
||||
nsFontXP *mSubstituteFont;
|
||||
|
||||
static int gCount;
|
||||
static nsISaveAsCharset* gConverter;
|
||||
|
@ -2209,6 +2213,8 @@ GetFontNames(char* aPattern)
|
|||
nsFontFamily* family = nsnull;
|
||||
|
||||
int count = 0;
|
||||
/* applications must not make any assumptions about fonts _before_ XpSetContext() !!! */
|
||||
NS_ASSERTION((XpGetContext(gDisplay) != None), "Obtaining font information (XListFonts()) _before_ XpSetContext()");
|
||||
char** list = ::XListFonts(gDisplay, aPattern, INT_MAX, &count);
|
||||
if ((!list) || (count < 1)) {
|
||||
return nsnull;
|
||||
|
|
|
@ -147,32 +147,32 @@ public:
|
|||
friend void TryFamily(nsFontSearch* aSearch, nsFontFamily* aFamily);
|
||||
friend struct nsFontXP;
|
||||
|
||||
nsFontXP **mLoadedFonts;
|
||||
PRUint16 mLoadedFontsAlloc;
|
||||
PRUint16 mLoadedFontsCount;
|
||||
nsFontXP **mLoadedFonts;
|
||||
PRUint16 mLoadedFontsAlloc;
|
||||
PRUint16 mLoadedFontsCount;
|
||||
|
||||
int mInFindSubstituteFont;
|
||||
nsFontXP *mSubstituteFont;
|
||||
int mInFindSubstituteFont;
|
||||
nsFontXP *mSubstituteFont;
|
||||
|
||||
nsString *mFonts;
|
||||
PRUint16 mFontsAlloc;
|
||||
PRUint16 mFontsCount;
|
||||
PRUint16 mFontsIndex;
|
||||
nsString *mFonts;
|
||||
PRUint16 mFontsAlloc;
|
||||
PRUint16 mFontsCount;
|
||||
PRUint16 mFontsIndex;
|
||||
|
||||
nsString *mGeneric;
|
||||
int mTriedAllGenerics;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
nsString *mGeneric;
|
||||
int mTriedAllGenerics;
|
||||
nsCOMPtr<nsIAtom> mLangGroup;
|
||||
|
||||
protected:
|
||||
char *PickAppropriateSize(char **names, XFontStruct *fonts, int cnt, nscoord desired);
|
||||
void RealizeFont();
|
||||
|
||||
Display *mDisplay;
|
||||
nsIDeviceContext *mDeviceContext;
|
||||
nsFont *mFont;
|
||||
XFontStruct *mFontHandle;
|
||||
XFontStruct *mFontStruct;
|
||||
nsFontXP *mWesternFont;
|
||||
Display *mDisplay;
|
||||
nsIDeviceContext *mDeviceContext;
|
||||
nsFont *mFont;
|
||||
XFontStruct *mFontHandle;
|
||||
XFontStruct *mFontStruct;
|
||||
nsFontXP *mWesternFont;
|
||||
nscoord mHeight;
|
||||
nscoord mLeading;
|
||||
nscoord mEmHeight;
|
||||
|
@ -200,7 +200,7 @@ protected:
|
|||
#endif /* FONT_SWITCHING */
|
||||
|
||||
private:
|
||||
static Font mLastSetFont;
|
||||
static Font mLastSetFont;
|
||||
};
|
||||
|
||||
class nsFontEnumeratorXP : public nsIFontEnumerator
|
||||
|
@ -211,4 +211,4 @@ public:
|
|||
NS_DECL_NSIFONTENUMERATOR
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* !nsFontMetricsXP_h__ */
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Contributor(s):
|
||||
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsIDeviceContextSpecXP_h___
|
||||
|
@ -25,12 +27,24 @@
|
|||
|
||||
#include "nsISupports.h"
|
||||
|
||||
/* make Xprint the default print system if user/admin has set the XPSERVERLIST"
|
||||
* env var. See Xprt config README (/usr/openwin/server/etc/XpConfig/README)
|
||||
* for details.
|
||||
*/
|
||||
#ifdef DEBUG_gisburn
|
||||
#define NS_DEFAULT_PRINT_METHOD ((PR_GetEnv("XPSERVERLIST")!=nsnull)?(puts("** using printing=Xprint"),1):(puts("** using printing=PostScript"),0))
|
||||
#else
|
||||
#define NS_DEFAULT_PRINT_METHOD ((PR_GetEnv("XPSERVERLIST")!=nsnull)?(1):(0))
|
||||
#endif /* DEBUG_gisburn */
|
||||
|
||||
#define NS_IDEVICE_CONTEXT_SPEC_XP_IID { 0xa4ef8910, 0xdd65, 0x11d2, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 } }
|
||||
|
||||
class nsIDeviceContextSpecXP : public nsISupports
|
||||
{
|
||||
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDEVICE_CONTEXT_SPEC_XP_IID);
|
||||
|
||||
/*
|
||||
* If PR_TRUE, print to printer
|
||||
* @update
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIDeviceContext.h"
|
||||
|
||||
#ifndef __nsIDeviceContextXP_h
|
||||
#define __nsIDeviceContextXP_h
|
||||
|
@ -30,7 +31,9 @@
|
|||
{0x35efd8b6, 0x13cc, 0x11d3, \
|
||||
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}}
|
||||
|
||||
class nsIDeviceContextXP : public nsISupports
|
||||
class nsXPrintContext;
|
||||
|
||||
class nsIDeviceContextXP : public DeviceContextImpl
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDEVICECONTEXTXP_IID);
|
||||
|
@ -39,6 +42,12 @@ public:
|
|||
|
||||
NS_IMETHOD InitDeviceContextXP(nsIDeviceContext *aCreatingDeviceContext,
|
||||
nsIDeviceContext *aPrinterContext) = 0;
|
||||
|
||||
NS_IMETHOD GetPrintContext(nsXPrintContext*& aContext) = 0;
|
||||
|
||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIFontMetrics*& aMetrics) = 0;
|
||||
NS_IMETHOD GetMetricsFor(const nsFont& aFont, nsIAtom* aLangGroup,
|
||||
nsIFontMetrics*& aMetrics) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,20 +18,33 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
#include "xlibrgb.h"
|
||||
#include "nsXPrintContext.h"
|
||||
#include "xprintutil.h"
|
||||
|
||||
#undef XPRINT_ON_SCREEN
|
||||
/* DEBUG: use
|
||||
* % export NSPR_LOG_MODULES=nsXPrintContext:5
|
||||
* to see these debug messages...
|
||||
*/
|
||||
static PRLogModuleInfo *nsXPrintContextLM = PR_NewLogModule("nsXPrintContext");
|
||||
|
||||
Display * nsXPrintContext::mDisplay = (Display *)0;
|
||||
|
||||
static int xerror_handler(Display *display, XErrorEvent *ev) {
|
||||
#ifdef __SUNPRO_C
|
||||
extern "C" /* Make Sun Workshop and other conformant compilers happy... :-) */
|
||||
#endif
|
||||
static
|
||||
int xerror_handler(Display *display, XErrorEvent *ev)
|
||||
{
|
||||
/* this should _never_ be happen... but if this happens - debug mode or not - scream !!! */
|
||||
char errmsg[80];
|
||||
XGetErrorText(display, ev->error_code, errmsg, 80);
|
||||
XGetErrorText(display, ev->error_code, errmsg, sizeof(errmsg));
|
||||
fprintf(stderr, "lib_xprint: Warning (X Error) - %s\n", errmsg);
|
||||
return 0;
|
||||
}
|
||||
|
@ -41,16 +54,17 @@ static int xerror_handler(Display *display, XErrorEvent *ev) {
|
|||
*/
|
||||
nsXPrintContext::nsXPrintContext()
|
||||
{
|
||||
mPContext = (XPContext )0;
|
||||
mPrintServerName = (char *)0;
|
||||
mPrinterName = (char *)0;
|
||||
mScreen = (Screen *)0;
|
||||
mVisual = (Visual *)0;
|
||||
mGC = (GC )0;
|
||||
mDrawable = (Drawable )0;
|
||||
mDepth = 0;
|
||||
mAlphaPixmap = 0;
|
||||
mImagePixmap = 0;
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::nsXPrintContext()\n"));
|
||||
|
||||
mPDisplay = (Display *)nsnull;
|
||||
mPContext = (XPContext)None;
|
||||
mScreen = (Screen *)nsnull;
|
||||
mVisual = (Visual *)nsnull;
|
||||
mGC = (GC)None;
|
||||
mDrawable = (Drawable)None;
|
||||
mDepth = 0;
|
||||
mAlphaPixmap = (Pixmap)None;
|
||||
mImagePixmap = (Pixmap)None;
|
||||
}
|
||||
|
||||
/** ---------------------------------------------------
|
||||
|
@ -58,61 +72,78 @@ nsXPrintContext::nsXPrintContext()
|
|||
*/
|
||||
nsXPrintContext::~nsXPrintContext()
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::~nsXPrintContext()\n"));
|
||||
|
||||
// end the document
|
||||
EndDocument();
|
||||
// Cleanup things allocated along the way
|
||||
XpDestroyContext(mDisplay, mPContext);
|
||||
XCloseDisplay(mDisplay);
|
||||
if( mPDisplay != nsnull )
|
||||
EndDocument();
|
||||
}
|
||||
|
||||
#ifdef HACK_PRINTONSCREEN
|
||||
// debug: "print" on display server for quick debugging
|
||||
// see sleep() in nsXPrintContext::EndDocument()
|
||||
#define XPRINTONSCREEN (!strcmp("xprint_preview",(aSpec->GetCommand(&buf),buf)))
|
||||
#endif /* HACK_PRINTONSCREEN */
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::Init(nsIDeviceContextSpecXP *aSpec)
|
||||
{
|
||||
int prefDepth = 8;
|
||||
#ifdef XPRINT_ON_SCREEN
|
||||
if (nsnull == mDisplay)
|
||||
mDisplay = (Display *)XOpenDisplay(NULL);
|
||||
mScreen = XDefaultScreenOfDisplay(mDisplay);
|
||||
xlib_rgb_init_with_depth(mDisplay, mScreen, prefDepth);
|
||||
mScreenNumber = XDefaultScreen(mDisplay);
|
||||
SetupWindow(0, 0, 1000, 1100);
|
||||
mPrintResolution = 300;
|
||||
mTextZoom = 1.0f;
|
||||
XMapWindow(mDisplay, mDrawable);
|
||||
#else
|
||||
char *printservername = (char *)0;
|
||||
if (!(printservername = getenv("XPDISPLAY"))) {
|
||||
printservername = strdup("localhost:1");
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::Init()\n"));
|
||||
|
||||
int prefDepth = 24; /* 24 or 8 */
|
||||
char *buf;
|
||||
|
||||
/* print on screen(="normal" Xserver) is "DEBUG" for now...
|
||||
* maybe usefull for preview, too...
|
||||
*/
|
||||
#ifdef HACK_PRINTONSCREEN
|
||||
if( XPRINTONSCREEN )
|
||||
{
|
||||
mPDisplay = (Display *)XOpenDisplay(nsnull);
|
||||
mScreen = XDefaultScreenOfDisplay(mPDisplay);
|
||||
xlib_rgb_init_with_depth(mPDisplay, mScreen, prefDepth);
|
||||
mScreenNumber = XDefaultScreen(mPDisplay);
|
||||
SetupWindow(0, 0, 1200, 1200);
|
||||
mPrintResolution = 300;
|
||||
mTextZoom = 1.0f;
|
||||
XMapWindow(mPDisplay, mDrawable);
|
||||
}
|
||||
if (nsnull == mDisplay) {
|
||||
if (!(mDisplay = XOpenDisplay(printservername))) {
|
||||
fprintf(stderr,"failed to open display '%s'\n", printservername);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
else
|
||||
#endif /* HACK_PRINTONSCREEN */
|
||||
{
|
||||
unsigned short width, height;
|
||||
XRectangle rect;
|
||||
|
||||
if( NS_FAILED( XPU_TRACE(SetupPrintContext(aSpec)) ) )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mScreen = XpGetScreenOfContext(mPDisplay, mPContext);
|
||||
mScreenNumber = XScreenNumberOfScreen(mScreen);
|
||||
xlib_rgb_init_with_depth(mPDisplay, mScreen, prefDepth);
|
||||
|
||||
XpGetPageDimensions(mPDisplay, mPContext, &width, &height, &rect);
|
||||
SetupWindow(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
mTextZoom = 2.4f; // should this be printer_DPI / display_DPI ?
|
||||
XMapWindow(mPDisplay, mDrawable);
|
||||
}
|
||||
unsigned short width, height;
|
||||
XRectangle rect;
|
||||
|
||||
SetupPrintContext(aSpec);
|
||||
mScreen = XpGetScreenOfContext(mDisplay, mPContext);
|
||||
mScreenNumber = XScreenNumberOfScreen(mScreen);
|
||||
xlib_rgb_init_with_depth(mDisplay, mScreen, prefDepth);
|
||||
|
||||
XpGetPageDimensions(mDisplay, mPContext, &width, &height, &rect);
|
||||
SetupWindow(rect.x, rect.y, rect.width, rect.height);
|
||||
|
||||
// mGC = XDefaultGCOfScreen(mScreen);
|
||||
mTextZoom = 2.0f;
|
||||
#endif
|
||||
mPDisplay = mDisplay;
|
||||
|
||||
/* Set error handler and sync
|
||||
* ToDo: unset handler after all is done - what about handler "stacking" ?
|
||||
*/
|
||||
(void)XSetErrorHandler(xerror_handler);
|
||||
XSynchronize(mDisplay, True);
|
||||
XSynchronize(mPDisplay, True);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::SetupWindow(int x, int y, int width, int height)
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG,
|
||||
("nsXPrintContext::SetupWindow: x=%d y=%d width=%d height=%d\n",
|
||||
x, y, width, height));
|
||||
|
||||
XSetWindowAttributes xattributes;
|
||||
long xattributes_mask;
|
||||
Window parent_win;
|
||||
|
@ -124,154 +155,245 @@ nsXPrintContext::SetupWindow(int x, int y, int width, int height)
|
|||
mHeight = height;
|
||||
visual_info = xlib_rgb_get_visual_info();
|
||||
|
||||
parent_win = RootWindow(mDisplay, mScreenNumber);
|
||||
xattributes.background_pixel = WhitePixel (mDisplay, mScreenNumber);
|
||||
xattributes.border_pixel = BlackPixel (mDisplay, mScreenNumber);
|
||||
parent_win = RootWindow(mPDisplay, mScreenNumber);
|
||||
xattributes.background_pixel = WhitePixel (mPDisplay, mScreenNumber);
|
||||
xattributes.border_pixel = BlackPixel (mPDisplay, mScreenNumber);
|
||||
xattributes_mask |= CWBorderPixel | CWBackPixel;
|
||||
|
||||
#ifdef _USE_PRIMITIVE_CALL_
|
||||
mVisual = visual_info->visual;
|
||||
mDepth = visual_info->depth;
|
||||
|
||||
mDrawable = (Drawable) XCreateWindow(mDisplay, parent_win, x, y, width,
|
||||
height, 2,
|
||||
mDepth, InputOutput, mVisual, xattributes_mask,
|
||||
&xattributes );
|
||||
#else
|
||||
mDrawable = (Drawable)XCreateSimpleWindow(mDisplay,
|
||||
mDrawable = (Drawable)XCreateSimpleWindow(mPDisplay,
|
||||
parent_win,
|
||||
x, y,
|
||||
width, height,
|
||||
0, BlackPixel(mDisplay, mScreenNumber),
|
||||
WhitePixel(mDisplay, mScreenNumber));
|
||||
mDepth = XDefaultDepth(mDisplay, mScreenNumber);
|
||||
mVisual = XDefaultVisual(mDisplay, mScreenNumber);
|
||||
#endif
|
||||
0, BlackPixel(mPDisplay, mScreenNumber),
|
||||
WhitePixel(mPDisplay, mScreenNumber));
|
||||
mDepth = XDefaultDepth(mPDisplay, mScreenNumber);
|
||||
mVisual = XDefaultVisual(mPDisplay, mScreenNumber);
|
||||
|
||||
gcmask = GCBackground | GCForeground | GCFunction ;
|
||||
gcvalues.background = WhitePixel(mDisplay, mScreenNumber);
|
||||
gcvalues.foreground = BlackPixel(mDisplay, mScreenNumber);
|
||||
gcvalues.background = WhitePixel(mPDisplay, mScreenNumber);
|
||||
gcvalues.foreground = BlackPixel(mPDisplay, mScreenNumber);
|
||||
gcvalues.function = GXcopy;
|
||||
mGC = XCreateGC(mDisplay, mDrawable, gcmask, &gcvalues);
|
||||
return NS_OK;
|
||||
mGC = XCreateGC(mPDisplay, mDrawable, gcmask, &gcvalues); /* ToDo: Check for error */
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::SetupPrintContext(nsIDeviceContextSpecXP *aSpec)
|
||||
{
|
||||
XPPrinterList plist;
|
||||
int plistcnt;
|
||||
PRBool isAPrinter;
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::SetupPrintContext()\n"));
|
||||
|
||||
int printSize;
|
||||
float top, bottom, left, right;
|
||||
char *buf;
|
||||
char cbuf[128];
|
||||
const int loglength = 128;
|
||||
char logname[loglength];
|
||||
|
||||
// Get the Attributes
|
||||
aSpec->GetToPrinter( isAPrinter );
|
||||
aSpec->GetSize( printSize );
|
||||
aSpec->GetTopMargin( top );
|
||||
aSpec->GetBottomMargin( bottom );
|
||||
aSpec->GetLeftMargin( left );
|
||||
aSpec->GetRightMargin( right );
|
||||
aSpec->GetToPrinter(mIsAPrinter);
|
||||
aSpec->GetSize(printSize);
|
||||
aSpec->GetTopMargin(top);
|
||||
aSpec->GetBottomMargin(bottom);
|
||||
aSpec->GetLeftMargin(left);
|
||||
aSpec->GetRightMargin(right);
|
||||
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG,
|
||||
("nsXPrintContext::SetupPrintContext: borders top=%f, bottom=%f, left=%f, right=%f\n",
|
||||
top, bottom, left, right));
|
||||
|
||||
/* get destination printer (we need this when printing to file as
|
||||
* the printer DDX in Xprt generates the data...)
|
||||
*/
|
||||
aSpec->GetCommand(&buf);
|
||||
|
||||
// Check the output type
|
||||
if (isAPrinter == PR_TRUE) {
|
||||
aSpec->GetCommand( &buf );
|
||||
} else {
|
||||
aSpec->GetPath( &buf );
|
||||
/* Are we "printing" to a file instead to the print queue ? */
|
||||
if (!mIsAPrinter)
|
||||
{
|
||||
/* ToDo: Guess a matching file extension of user did not set one - Xprint
|
||||
* currrently may use %s.ps, %s.pcl, %s.xwd, %s.pdf etc.
|
||||
* Best idea would be to ask a "datatyping" service (like CDE's datatyping
|
||||
* functions) what to-do...
|
||||
*/
|
||||
aSpec->GetPath(&mPrintFile);
|
||||
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("print to file '%s'\n", XPU_NULLXSTR(mPrintFile)));
|
||||
|
||||
if( (mPrintFile == nsnull) || (strlen(mPrintFile) == 0) )
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
plist = XpGetPrinterList(mDisplay, buf, &plistcnt);
|
||||
mPContext = XpCreateContext(mDisplay, plist[0].name );
|
||||
XpFreePrinterList(plist);
|
||||
XpSetContext(mDisplay, mPContext);
|
||||
/* get printer, either by "name" (foobar) or "name@display" (foobar@gaja:5)
|
||||
* ToDo: report error to user (dialog)
|
||||
*/
|
||||
if( XpuGetPrinter(buf, &mPDisplay, &mPContext) != 1 )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Set the Job attribute
|
||||
if (!getlogin_r(logname, loglength)) {
|
||||
sprintf(logname, "Mozilla-User");
|
||||
}
|
||||
sprintf(cbuf,"*job-owner: %s", logname);
|
||||
XpSetAttributes(mDisplay, mPContext,
|
||||
XPJobAttr,(char *)cbuf,XPAttrMerge);
|
||||
/* set printer context
|
||||
* WARNING: after this point it is no longer allows to change job attributes
|
||||
* only after the XpSetContext() call the alllication is allowed to make
|
||||
* assumptions about available fonts - otherwise you may get the wrong
|
||||
* ones !!
|
||||
*/
|
||||
XPU_TRACE(XpSetContext(mPDisplay, mPContext));
|
||||
|
||||
/* get default printer reolution
|
||||
* (note: if's AFAIK a Xprt configuration error when "default-printer-resolution"
|
||||
* cannot be obtained - return with an error to avoid the case that we#re working
|
||||
* with a faulty printer config...
|
||||
* ToDo: Report error to user (dialog)
|
||||
*/
|
||||
if( XpuGetOneLongAttribute(mPDisplay, mPContext, XPDocAttr, "default-printer-resolution", &mPrintResolution) != 1 )
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("print resolution %ld\n", (long)mPrintResolution));
|
||||
|
||||
/* We want to get events when Xp(Start|End)(Job|Page) requests are processed... */
|
||||
XpSelectInput(mPDisplay, mPContext, XPPrintMask);
|
||||
|
||||
// Set the Document Attributes
|
||||
// XpSetAttributes(mDisplay,mPContext, XPDocAttr,(char *)"*content-orientation: landscape",XPAttrMerge);
|
||||
// XpSetAttributes(mPDisplay,mPContext, XPDocAttr,(char *)"*content-orientation: landscape",XPAttrMerge);
|
||||
|
||||
mPrintResolution = 300;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
char *print_resolution = XpGetOneAttribute(mDisplay, mPContext, XPDocAttr,
|
||||
(char *)"default-printer-resolution");
|
||||
if (print_resolution) {
|
||||
char *tmp_str = strrchr(print_resolution, ':');
|
||||
if (tmp_str) {
|
||||
tmp_str++;
|
||||
mPrintResolution = atoi(tmp_str);
|
||||
}
|
||||
XFree(print_resolution);
|
||||
}
|
||||
/* MyConvertUCS2ToLocalEncoding:
|
||||
* Note that this function is _only_ a _hack_ until RFE 73446
|
||||
* (http://bugzilla.mozilla.org/show_bug.cgi?id=73446 - "RFE:
|
||||
* Need NS_ConvertUCS2ToLocalEncoding() and
|
||||
* NS_ConvertLocalEncodingToUCS2()") gets implemented...
|
||||
* Below we need COMPOUNT_TEXT which usually is the same as the Xserver's
|
||||
* local encoding - this hack should at least work for C/POSIX
|
||||
* and *.UTF-8 locales...
|
||||
*/
|
||||
static
|
||||
const char *MyConvertUCS2ToLocalEncoding( PRUnichar *str )
|
||||
{
|
||||
/* Use strdup() to avoid any silly effects...
|
||||
*/
|
||||
return PL_strdup(NS_ConvertUCS2toUTF8(str).get());
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::BeginDocument( PRUnichar *aTitle )
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::BeginDocument()\n"));
|
||||
|
||||
char *s = nsnull,
|
||||
*job_title;
|
||||
|
||||
if( aTitle != nsnull )
|
||||
job_title = s = (char *)MyConvertUCS2ToLocalEncoding(aTitle);
|
||||
else
|
||||
job_title = "Mozilla document without title";
|
||||
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::BeginDocument: document title: '%s'\n", XPU_NULLXSTR(job_title)));
|
||||
|
||||
/* Set the Job Attributes */
|
||||
XpuSetJobTitle(mPDisplay, mPContext, job_title);
|
||||
|
||||
if( s != nsnull )
|
||||
PL_strfree(s);
|
||||
|
||||
// Check the output type
|
||||
if (isAPrinter == PR_TRUE) {
|
||||
XpStartJob(mDisplay, XPSpool );
|
||||
} else {
|
||||
XpStartJob(mDisplay, XPGetData );
|
||||
if(mIsAPrinter)
|
||||
{
|
||||
XPU_TRACE(XpStartJob(mPDisplay, XPSpool));
|
||||
XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartJobNotify));
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_TRACE(XpStartJob(mPDisplay, XPGetData));
|
||||
|
||||
if( XPU_TRACE(mXpuPrintToFileHandle = XpuPrintToFile(mPDisplay, mPContext, mPrintFile)) == nsnull )
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG,
|
||||
("nsXPrintContext::BeginDocument(): XpuPrintToFile failure %s/(%d)\n",
|
||||
strerror(errno), errno));
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartJobNotify));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::BeginDocument()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::BeginPage()
|
||||
{
|
||||
XpStartPage(mDisplay, mDrawable);
|
||||
// Move the print window according to the given margin
|
||||
// XMoveWindow(mDisplay, mDrawable, 100, 100);
|
||||
// XMoveWindow(mPDisplay, mDrawable, 100, 100);
|
||||
|
||||
XPU_TRACE(XpStartPage(mPDisplay, mDrawable));
|
||||
XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPStartPageNotify));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::EndPage()
|
||||
{
|
||||
XpEndPage(mDisplay);
|
||||
XPU_TRACE(XpEndPage(mPDisplay));
|
||||
XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPEndPageNotify));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::EndDocument()
|
||||
{
|
||||
XFlush(mDisplay);
|
||||
XpEndJob(mDisplay);
|
||||
XPU_TRACE(XpEndJob(mPDisplay));
|
||||
XPU_TRACE(XpuWaitForPrintNotify(mPDisplay, XPEndJobNotify));
|
||||
|
||||
/* Are we printing to a file ? */
|
||||
if( !mIsAPrinter )
|
||||
{
|
||||
NS_ASSERTION(nsnull != mXpuPrintToFileHandle, "mXpuPrintToFileHandle is null.");
|
||||
|
||||
if( XPU_TRACE(XpuWaitForPrintFileChild(mXpuPrintToFileHandle)) == XPGetDocFinished )
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("XpuWaitForPrintFileChild returned success.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HACK_PRINTONSCREEN
|
||||
/* HACK: sleep 15secs if we're displaying to an "display" server
|
||||
* see nsXPrintContext::Init and XprintOnScreen macro above - this is only used if
|
||||
* we are printing to a normal Xserver and not to a Xprint server (e.g. in rare
|
||||
* rare cases...)
|
||||
*/
|
||||
if( XpuCheckExtension(mPDisplay) != 1 )
|
||||
{
|
||||
sleep(15);
|
||||
}
|
||||
#endif /* HACK_PRINTONSCREEN */
|
||||
|
||||
// Cleanup things allocated along the way
|
||||
XpDestroyContext(mDisplay, mPContext);
|
||||
// XCloseDisplay(mDisplay);
|
||||
XpDestroyContext(mPDisplay, mPContext);
|
||||
mPContext = nsnull;
|
||||
XCloseDisplay(mPDisplay);
|
||||
mPDisplay = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::DrawImage(nsIImage *aImage,
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
|
||||
PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
|
||||
{
|
||||
PRUint8 *image_bits = aImage->GetBits();
|
||||
PRInt32 row_bytes = aImage->GetLineStride();
|
||||
PRUint8 *image_bits = aImage->GetBits();
|
||||
PRInt32 row_bytes = aImage->GetLineStride();
|
||||
|
||||
// XpSetImageResolution(mDisplay, mPContext, new_res, &prev_res);
|
||||
xlib_draw_gray_image(mDrawable,
|
||||
mGC,
|
||||
aDX, aDY, aDWidth, aDHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
image_bits + row_bytes * aSY + 3 * aDX,
|
||||
row_bytes);
|
||||
// XpSetImageResolution(mPDisplay, mPContext, new_res, &prev_res);
|
||||
xlib_draw_gray_image(mDrawable,
|
||||
mGC,
|
||||
aDX, aDY, aDWidth, aDHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
image_bits + row_bytes * aSY + 3 * aDX,
|
||||
row_bytes);
|
||||
|
||||
// XpSetImageResolution(mDisplay, mPContext, prev_res, &new_res);
|
||||
// XpSetImageResolution(mPDisplay, mPContext, prev_res, &new_res);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -279,47 +401,48 @@ nsXPrintContext::DrawImage(nsIImage *aImage,
|
|||
// Draw the bitmap, this draw just has destination coordinates
|
||||
NS_IMETHODIMP
|
||||
nsXPrintContext::DrawImage(nsIImage *aImage,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
PRInt32 width = aImage->GetWidth();
|
||||
PRInt32 height = aImage->GetHeight();
|
||||
PRUint8 *alphaBits = aImage->GetAlphaBits();
|
||||
PRInt32 width = aImage->GetWidth();
|
||||
PRInt32 height = aImage->GetHeight();
|
||||
PRUint8 *alphaBits = aImage->GetAlphaBits();
|
||||
PRInt32 alphaRowBytes = aImage->GetAlphaLineStride();
|
||||
PRUint8 *image_bits = aImage->GetBits();
|
||||
PRInt32 row_bytes = aImage->GetLineStride();
|
||||
PRUint8 *image_bits = aImage->GetBits();
|
||||
PRInt32 row_bytes = aImage->GetLineStride();
|
||||
|
||||
// XXX kipp: this is temporary code until we eliminate the
|
||||
// width/height arguments from the draw method.
|
||||
if ((aWidth != width) || (aHeight != height)) {
|
||||
if ((aWidth != width) || (aHeight != height))
|
||||
{
|
||||
aWidth = width;
|
||||
aHeight = height;
|
||||
}
|
||||
|
||||
XImage *x_image = nsnull;
|
||||
GC gc;
|
||||
XGCValues gcv;
|
||||
XImage *x_image = nsnull;
|
||||
GC gc;
|
||||
XGCValues gcv;
|
||||
|
||||
// Create gc clip-mask on demand
|
||||
if ((alphaBits != nsnull) && (mAlphaPixmap == 0)) {
|
||||
if (!mAlphaPixmap) {
|
||||
mAlphaPixmap = XCreatePixmap(mDisplay,
|
||||
RootWindow(mDisplay, mScreenNumber),
|
||||
aWidth, aHeight, 1);
|
||||
if ((alphaBits != nsnull) && (mAlphaPixmap == None)) {
|
||||
if (mAlphaPixmap==None) {
|
||||
mAlphaPixmap = XCreatePixmap(mPDisplay,
|
||||
RootWindow(mPDisplay, mScreenNumber),
|
||||
aWidth, aHeight, 1); /* ToDo: Check for error */
|
||||
}
|
||||
|
||||
// Make an image out of the alpha-bits created by the image library
|
||||
x_image = XCreateImage(mDisplay, mVisual,
|
||||
1, /* visual depth...1 for bitmaps */
|
||||
/* Make an image out of the alpha-bits created by the image library (ToDo: check for error) */
|
||||
x_image = XCreateImage(mPDisplay, mVisual,
|
||||
1, /* visual depth...1 for bitmaps */
|
||||
XYPixmap,
|
||||
0, /* x offset, XXX fix this */
|
||||
(char *)alphaBits, /* cast away our sign. */
|
||||
0, /* x offset, XXX fix this */
|
||||
(char *)alphaBits, /* cast away our sign. */
|
||||
aWidth,
|
||||
aHeight,
|
||||
32,/* bitmap pad */
|
||||
alphaRowBytes); /* bytes per line */
|
||||
32, /* bitmap pad */
|
||||
alphaRowBytes); /* bytes per line */
|
||||
|
||||
x_image->bits_per_pixel=1;
|
||||
x_image->bits_per_pixel = 1;
|
||||
|
||||
/* Image library always places pixels left-to-right MSB to LSB */
|
||||
x_image->bitmap_bit_order = MSBFirst;
|
||||
|
@ -341,73 +464,67 @@ nsXPrintContext::DrawImage(nsIImage *aImage,
|
|||
// the image we just created.
|
||||
memset(&gcv, 0, sizeof(XGCValues));
|
||||
gcv.function = GXcopy;
|
||||
gc = XCreateGC(mDisplay, mAlphaPixmap, GCFunction, &gcv);
|
||||
gc = XCreateGC(mPDisplay, mAlphaPixmap, GCFunction, &gcv);
|
||||
|
||||
XPutImage(mDisplay, mAlphaPixmap, gc, x_image, 0, 0, 0, 0,
|
||||
XPutImage(mPDisplay, mAlphaPixmap, gc, x_image, 0, 0, 0, 0,
|
||||
aWidth, aHeight);
|
||||
XFreeGC(mDisplay, gc);
|
||||
XFreeGC(mPDisplay, gc);
|
||||
|
||||
// Now we are done with the temporary image
|
||||
x_image->data = 0; /* Don't free the IL_Pixmap's bits. */
|
||||
XDestroyImage(x_image);
|
||||
}
|
||||
|
||||
if (nsnull == mImagePixmap) {
|
||||
if (mImagePixmap == None) {
|
||||
// Create an off screen pixmap to hold the image bits.
|
||||
mImagePixmap = XCreatePixmap(mDisplay,
|
||||
RootWindow(mDisplay, mScreenNumber),
|
||||
aWidth, aHeight,
|
||||
mDepth);
|
||||
XSetClipOrigin(mDisplay, mGC, 0, 0);
|
||||
XSetClipMask(mDisplay, mGC, None);
|
||||
mImagePixmap = XCreatePixmap(mPDisplay,
|
||||
RootWindow(mPDisplay, mScreenNumber),
|
||||
aWidth, aHeight,
|
||||
mDepth);
|
||||
XSetClipOrigin(mPDisplay, mGC, 0, 0);
|
||||
XSetClipMask(mPDisplay, mGC, None);
|
||||
GC gc;
|
||||
XGCValues xvalues;
|
||||
unsigned long xvalues_mask;
|
||||
|
||||
xvalues.function = GXcopy;
|
||||
xvalues.fill_style = FillSolid;
|
||||
xvalues.arc_mode = ArcPieSlice;
|
||||
xvalues.subwindow_mode = ClipByChildren;
|
||||
xvalues.function = GXcopy;
|
||||
xvalues.fill_style = FillSolid;
|
||||
xvalues.arc_mode = ArcPieSlice;
|
||||
xvalues.subwindow_mode = ClipByChildren;
|
||||
xvalues.graphics_exposures = True;
|
||||
xvalues_mask = GCFunction | GCFillStyle | GCArcMode | GCSubwindowMode | GCGraphicsExposures;
|
||||
|
||||
gc = XCreateGC(mDisplay, mImagePixmap, xvalues_mask, &xvalues);
|
||||
// XpSetImageResolution(mDisplay, mPContext, new_res, &prev_res);
|
||||
#ifdef _USE_PRIMITIVE_CALL_
|
||||
xlib_draw_gray_image(mImagePixmap,
|
||||
gc,
|
||||
0, 0, aWidth, aHeight,
|
||||
XLIB_RGB_DITHER_MAX,
|
||||
image_bits,
|
||||
row_bytes);
|
||||
#else
|
||||
xlib_draw_rgb_image (mImagePixmap,
|
||||
gc,
|
||||
0, 0, aWidth, aHeight,
|
||||
XLIB_RGB_DITHER_NONE,
|
||||
image_bits, row_bytes);
|
||||
#endif
|
||||
// XpSetImageResolution(mDisplay, mPContext, prev_res, &new_res);
|
||||
gc = XCreateGC(mPDisplay, mImagePixmap, xvalues_mask, &xvalues);
|
||||
|
||||
// XpSetImageResolution(mPDisplay, mPContext, new_res, &prev_res);
|
||||
xlib_draw_rgb_image(mImagePixmap,
|
||||
gc,
|
||||
0, 0, aWidth, aHeight,
|
||||
XLIB_RGB_DITHER_NONE,
|
||||
image_bits, row_bytes);
|
||||
// XpSetImageResolution(mPDisplay, mPContext, prev_res, &new_res);
|
||||
}
|
||||
if (nsnull != mAlphaPixmap)
|
||||
|
||||
if (mAlphaPixmap != None)
|
||||
{
|
||||
// set up the gc to use the alpha pixmap for clipping
|
||||
XSetClipOrigin(mDisplay, mGC, aX, aY);
|
||||
XSetClipMask(mDisplay, mGC, mAlphaPixmap);
|
||||
XSetClipOrigin(mPDisplay, mGC, aX, aY);
|
||||
XSetClipMask(mPDisplay, mGC, mAlphaPixmap);
|
||||
}
|
||||
|
||||
// copy our off screen pixmap onto the window.
|
||||
XCopyArea(mDisplay, // display
|
||||
XCopyArea(mPDisplay, // display
|
||||
mImagePixmap, // source
|
||||
mDrawable, // dest
|
||||
mGC, // GC
|
||||
0, 0, // xsrc, ysrc
|
||||
mDrawable, // dest
|
||||
mGC, // GC
|
||||
0, 0, // xsrc, ysrc
|
||||
aWidth, aHeight, // width, height
|
||||
aX, aY); // xdest, ydest
|
||||
aX, aY); // xdest, ydest
|
||||
|
||||
if (mAlphaPixmap != nsnull) {
|
||||
XSetClipOrigin(mDisplay, mGC, 0, 0);
|
||||
XSetClipMask(mDisplay, mGC, None);
|
||||
if (mAlphaPixmap != None)
|
||||
{
|
||||
XSetClipOrigin(mPDisplay, mGC, 0, 0);
|
||||
XSetClipMask(mPDisplay, mGC, None);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -415,14 +532,16 @@ nsXPrintContext::DrawImage(nsIImage *aImage,
|
|||
|
||||
NS_IMETHODIMP nsXPrintContext::GetPrintResolution(int &aPrintResolution) const
|
||||
{
|
||||
PR_LOG(nsXPrintContextLM, PR_LOG_DEBUG, ("nsXPrintContext::GetPrintResolution()\n"));
|
||||
|
||||
aPrintResolution = mPrintResolution;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXPrintContext::SetForegroundColor(nscolor aColor)
|
||||
{
|
||||
|
||||
xlib_rgb_gc_set_foreground(mGC,
|
||||
NS_RGB(NS_GET_B(aColor), NS_GET_G(aColor), NS_GET_R(aColor)));
|
||||
NS_RGB(NS_GET_B(aColor), NS_GET_G(aColor), NS_GET_R(aColor)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
@ -44,7 +46,7 @@ public:
|
|||
NS_IMETHOD Init(nsIDeviceContextSpecXP *aSpec);
|
||||
NS_IMETHOD BeginPage();
|
||||
NS_IMETHOD EndPage();
|
||||
NS_IMETHOD BeginDocument();
|
||||
NS_IMETHOD BeginDocument(PRUnichar * aTitle);
|
||||
NS_IMETHOD EndDocument();
|
||||
|
||||
GC GetGC(void) { return mGC; }
|
||||
|
@ -52,8 +54,8 @@ public:
|
|||
Screen * GetScreen() { return mScreen; }
|
||||
Visual * GetVisual() { return mVisual; }
|
||||
int GetDepth() { return mDepth; }
|
||||
int GetHeight() { return mHeight; }
|
||||
int GetWidth() { return mWidth; }
|
||||
int GetHeight() { return mHeight; }
|
||||
int GetWidth() { return mWidth; }
|
||||
int GetScreenNumber() { return XScreenNumberOfScreen(mScreen); }
|
||||
|
||||
Display * GetDisplay() { return mPDisplay; }
|
||||
|
@ -72,30 +74,28 @@ public:
|
|||
NS_IMETHOD SetForegroundColor(nscolor aColor);
|
||||
|
||||
private:
|
||||
static Display * mDisplay;
|
||||
Display * mPDisplay;
|
||||
Screen * mScreen;
|
||||
Visual * mVisual;
|
||||
Display *mPDisplay;
|
||||
Screen *mScreen;
|
||||
Visual *mVisual;
|
||||
GC mGC;
|
||||
Drawable mDrawable;
|
||||
XImage * mImage;
|
||||
int mDepth;
|
||||
int mScreenNumber;
|
||||
XImage *mImage;
|
||||
int mDepth;
|
||||
int mScreenNumber;
|
||||
Pixmap mAlphaPixmap;
|
||||
Pixmap mImagePixmap;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
XPContext mPContext;
|
||||
int mPrintResolution;
|
||||
float mTextZoom;
|
||||
|
||||
char *mPrintServerName;
|
||||
char *mPrinterName;
|
||||
char *mAttrPool;
|
||||
PRBool mIsAPrinter;
|
||||
char *mPrintFile; /* file to "print" to */
|
||||
void *mXpuPrintToFileHandle; /* handle for XpuPrintToFile/XpuWaitForPrintFileChild when printing to file */
|
||||
long mPrintResolution;
|
||||
float mTextZoom;
|
||||
|
||||
NS_IMETHOD SetupWindow(int x, int y, int width, int height);
|
||||
NS_IMETHOD SetupPrintContext(nsIDeviceContextSpecXP *aSpec);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* !_XPCONTEXT_H_ */
|
||||
|
|
|
@ -0,0 +1,445 @@
|
|||
|
||||
/*
|
||||
* 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 the X11 print system utilities library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Roland Mainz
|
||||
* <roland.mainz@informatik.med.uni-giessen.de>.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define NeedFunctionPrototypes (1) /* is this legal from within an app. !? */
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/Print.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#include "xprintutil.h"
|
||||
|
||||
/*
|
||||
** XprintUtil functions start with Xpu
|
||||
**
|
||||
*/
|
||||
|
||||
int XpuCheckExtension( Display *pdpy )
|
||||
{
|
||||
char *display = DisplayString(pdpy);
|
||||
short major = 0,
|
||||
minor = 0;
|
||||
|
||||
if( XpQueryVersion(pdpy, &major, &minor) != 0 )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuCheckExtension: XpQueryVersion '%s' %d %d\n", XPU_NULLXSTR(display), (int)major, (int)minor));
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuCheckExtension: XpQueryVersion '%s' returned 0(=Xprint not supported)\n", XPU_NULLXSTR(display)));
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
char *XpuGetXpServerList( void )
|
||||
{
|
||||
/* BUG/TODO: XpServerList resource needs to be sourced first, then append
|
||||
* contents of XPSERVERLIST, then remove duplicates...
|
||||
*/
|
||||
return(getenv("XPSERVERLIST"));
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int XpuGetPrinter2( char *printer, char *display, Display **pdpyptr, XPContext *pcontextptr )
|
||||
{
|
||||
Display *pdpy;
|
||||
XPContext pcontext;
|
||||
|
||||
XPU_DEBUG_ONLY(printf("XpuGetPrinter2: probing display '%s' for '%s'\n", XPU_NULLXSTR(display), XPU_NULLXSTR(printer)));
|
||||
|
||||
if( (pdpy = XOpenDisplay(display)) != NULL )
|
||||
{
|
||||
if( XpuCheckExtension(pdpy) )
|
||||
{
|
||||
XPPrinterList list;
|
||||
int list_count;
|
||||
|
||||
/* get list of available printers... */
|
||||
list = XpGetPrinterList(pdpy, printer, &list_count);
|
||||
if( list != NULL ) XpFreePrinterList(list);
|
||||
|
||||
/* ...and check if printer exists... */
|
||||
if( (list != NULL) && (list_count > 0) )
|
||||
{
|
||||
if( (pcontext = XpCreateContext(pdpy, printer)) != NULL )
|
||||
{
|
||||
*pdpyptr = pdpy;
|
||||
*pcontextptr = pcontext;
|
||||
return(1);
|
||||
}
|
||||
|
||||
XPU_DEBUG_ONLY(printf("XpuGetPrinter2: could not create print context for '%s'\n", XPU_NULLXSTR(printer)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("display '%s' does not support the Xprint extension\n", XPU_NULLXSTR(display)));
|
||||
}
|
||||
|
||||
XCloseDisplay(pdpy);
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("could not open display '%s'\n", XPU_NULLXSTR(display)));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* acceps "printer" or "printer@display" */
|
||||
int XpuGetPrinter( char *printername, Display **pdpyptr, XPContext *pcontextptr )
|
||||
{
|
||||
Display *pdpy;
|
||||
XPContext pcontext;
|
||||
char *s;
|
||||
char *tok_lasts;
|
||||
|
||||
*pdpyptr = NULL;
|
||||
*pcontextptr = NULL;
|
||||
|
||||
XPU_DEBUG_ONLY(printf("XpuGetPrinter: looking for '%s'\n", XPU_NULLXSTR(printername)));
|
||||
|
||||
/* strtok_r will modify string - duplicate it first... */
|
||||
printername = (char *)strdup(printername);
|
||||
|
||||
if( (s = (char *)strtok_r(printername, "@", &tok_lasts)) != NULL )
|
||||
{
|
||||
char *name = s;
|
||||
char *display = (char *)strtok_r(NULL, "@", &tok_lasts);
|
||||
|
||||
/* if we have a display - open it and grab printer */
|
||||
if( display != NULL )
|
||||
{
|
||||
if( XpuGetPrinter2(name, display, pdpyptr, pcontextptr) )
|
||||
{
|
||||
free(printername);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
/* if we did not get a display, travel througth all displays */
|
||||
else
|
||||
{
|
||||
char *sl = XpuGetXpServerList();
|
||||
|
||||
if( sl != NULL )
|
||||
{
|
||||
for( display = (char *)strtok_r(sl, " ", &tok_lasts) ;
|
||||
display != NULL ;
|
||||
display = (char *)strtok_r(NULL, " ", &tok_lasts) )
|
||||
{
|
||||
if( XpuGetPrinter2(name, display, pdpyptr, pcontextptr) )
|
||||
{
|
||||
free(printername);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(printername);
|
||||
XPU_DEBUG_ONLY(printf("XpuGetPrinter: failure\n"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void XpuSetOneAttribute( Display *pdpy, XPContext pcontext,
|
||||
XPAttributes type, char *attribute_name, char *value, XPAttrReplacement replacement_rule )
|
||||
{
|
||||
char *buffer =
|
||||
#ifdef XPU_USE_NSPR
|
||||
PR_Malloc((PRUint32)
|
||||
#else
|
||||
Xmalloc(
|
||||
#endif
|
||||
strlen(attribute_name)+strlen(value)+8);
|
||||
|
||||
if( buffer != NULL )
|
||||
{
|
||||
sprintf(buffer, "%s: %s", attribute_name, value);
|
||||
XpSetAttributes(pdpy, pcontext, type, buffer, replacement_rule);
|
||||
#ifdef XPU_USE_NSPR
|
||||
PR_Free
|
||||
#else
|
||||
XFree
|
||||
#endif
|
||||
(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* enumerate attribute values - work in porgress */
|
||||
char *XpuEmumerateXpAttributeValue( char *value, void **context )
|
||||
{
|
||||
/* BUG: This does not work for quoted attribute values
|
||||
* A good example is the enumeration of supported paper sizes:
|
||||
* "{'' {na-letter False {6.3500 209.5500 6.3500 273.0500}} {executive False {6.3500 177.7500 6.3500 260.3500}} {na-legal False {6.3500 209.5500 6.3500 349.2500}} {iso-a4 False {6.3500 203.6500 6.3500 290.6500}} {iso-designated-long False {6.3500 103.6500 6.3500 213.6500}} {na-number-10-envelope False {6.3500 98.4500 6.3500 234.9500}} }"
|
||||
{''
|
||||
{
|
||||
na-letter
|
||||
False
|
||||
{6.3500 209.5500 6.3500 273.0500}
|
||||
}
|
||||
{
|
||||
executive
|
||||
False
|
||||
{6.3500 177.7500 6.3500 260.3500}
|
||||
}
|
||||
{
|
||||
na-legal
|
||||
False
|
||||
{6.3500 209.5500 6.3500 349.2500}
|
||||
}
|
||||
{
|
||||
iso-a4
|
||||
False
|
||||
{6.3500 203.6500 6.3500 290.6500}
|
||||
}
|
||||
{
|
||||
iso-designated-long
|
||||
False
|
||||
{6.3500 103.6500 6.3500 213.6500}
|
||||
}
|
||||
{
|
||||
na-number-10-envelope
|
||||
False
|
||||
{6.3500 98.4500 6.3500 234.9500}
|
||||
}
|
||||
}
|
||||
|
||||
* ToDo:
|
||||
* 1. Write a parser which grabs the 1st level of bracket pairs and
|
||||
* enumerate these items (six items in this example).
|
||||
* 2. Write enumeration functions for single attribute types with
|
||||
* complex content.
|
||||
*/
|
||||
return( (char *)strtok_r(value, " ", (char **)context) );
|
||||
}
|
||||
|
||||
|
||||
/* check if attribute value is supported or not */
|
||||
int XpuCheckSupported( Display *pdpy, XPContext pcontext, XPAttributes type, char *attribute_name, char *query )
|
||||
{
|
||||
char *value,
|
||||
*s;
|
||||
void *tok_lasts;
|
||||
|
||||
value = XpGetOneAttribute(pdpy, pcontext, type, attribute_name);
|
||||
|
||||
XPU_DEBUG_ONLY(printf("XpuCheckSupported: XpGetOneAttribute(%s) returned '%s'\n", XPU_NULLXSTR(attribute_name), XPU_NULLXSTR(value)));
|
||||
|
||||
if( value != NULL )
|
||||
{
|
||||
for( s = XpuEmumerateXpAttributeValue(value, &tok_lasts) ; s != NULL ; s = XpuEmumerateXpAttributeValue(NULL, &tok_lasts) )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuCheckSupported: probing '%s'=='%s'\n", XPU_NULLXSTR(s), XPU_NULLXSTR(query)));
|
||||
if( !strcmp(s, query) )
|
||||
{
|
||||
XFree(value);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
XFree(value);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int XpuSetJobTitle( Display *pdpy, XPContext pcontext, char *title )
|
||||
{
|
||||
if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "job-attributes-supported", "job-name") )
|
||||
{
|
||||
XpuSetOneAttribute(pdpy, pcontext, XPJobAttr, "*job-name", title, XPAttrMerge);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuSetJobTitle: XpuCheckSupported failed for '%s'\n", XPU_NULLXSTR(title)));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int XpuSetContentOrientation( Display *pdpy, XPContext pcontext, XPAttributes type, char *orientation )
|
||||
{
|
||||
if( XpuCheckSupported(pdpy, pcontext, XPPrinterAttr, "content-orientations-supported", orientation) )
|
||||
{
|
||||
XpuSetOneAttribute(pdpy, pcontext, type, "*content-orientation", orientation, XPAttrMerge);
|
||||
}
|
||||
else
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuSetContentOrientation: XpuCheckSupported failed for '%s'\n", XPU_NULLXSTR(orientation)));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, char *attribute_name, long *result )
|
||||
{
|
||||
char *s = XpGetOneAttribute(pdpy, pcontext, type, attribute_name);
|
||||
|
||||
if( (s != NULL) && (strlen(s) > 0) )
|
||||
{
|
||||
long tmp;
|
||||
|
||||
XPU_DEBUG_ONLY(printf("XpuGetOneLongAttribute: '%s' got '%s'\n", XPU_NULLXSTR(attribute_name), XPU_NULLXSTR(s)));
|
||||
|
||||
tmp = strtol(s, (char **)NULL, 10);
|
||||
|
||||
if( !(((tmp == 0L) || (tmp == LONG_MIN) || (tmp == LONG_MAX)) &&
|
||||
((errno == ERANGE) || (errno == EINVAL))) )
|
||||
{
|
||||
*result = tmp;
|
||||
XFree(s);
|
||||
XPU_DEBUG_ONLY(printf("XpuGetOneLongAttribute: result %ld\n", *result));
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
if( s != NULL ) XFree(s);
|
||||
|
||||
puts("XpuGetOneLongAttribute failed\n");
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
double XpuGetXDPI( Screen *pscreen )
|
||||
{
|
||||
double xres;
|
||||
|
||||
/* from X11R6.5.1/xc/programs/xdpyinfo/xdpyinfo.c:
|
||||
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
|
||||
*
|
||||
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
|
||||
* = N pixels / (M inch / 25.4)
|
||||
* = N * 25.4 pixels / M inch
|
||||
*/
|
||||
|
||||
xres = ((((double) WidthOfScreen(pscreen)) * 25.4) /
|
||||
((double) WidthMMOfScreen(pscreen)));
|
||||
|
||||
return(xres);
|
||||
}
|
||||
|
||||
|
||||
double XpuGetYDPI( Screen *pscreen )
|
||||
{
|
||||
double yres;
|
||||
|
||||
/* from X11R6.5.1/xc/programs/xdpyinfo/xdpyinfo.c:
|
||||
* there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
|
||||
*
|
||||
* dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
|
||||
* = N pixels / (M inch / 25.4)
|
||||
* = N * 25.4 pixels / M inch
|
||||
*/
|
||||
|
||||
yres = ((((double) HeightOfScreen(pscreen)) * 25.4) /
|
||||
((double) HeightMMOfScreen(pscreen)));
|
||||
|
||||
return(yres);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/* debug only */
|
||||
void dumpXpAttributes( Display *pdpy, XPContext pcontext )
|
||||
{
|
||||
/* BUG: values from XpuGet*Attributes should be passed to XFree() after use... :-) */
|
||||
printf("------------------------------------------------\n");
|
||||
printf("--> Job\n%s\n", XpuGetJobAttributes(pdpy, pcontext));
|
||||
printf("--> Doc\n%s\n", XpuGetDocAttributes(pdpy, pcontext));
|
||||
printf("--> Page\n%s\n", XpuGetPageAttributes(pdpy, pcontext));
|
||||
printf("--> Printer\n%s\n", XpuGetPrinterAttributes(pdpy, pcontext));
|
||||
printf("--> Server\n%s\n", XpuGetServerAttributes(pdpy, pcontext));
|
||||
printf("image resolution %d\n", (int)XpGetImageResolution(pdpy, pcontext));
|
||||
printf("------------------------------------------------\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/* BUG: Is it really neccesary that this function eats-up all other events ? */
|
||||
void XpuWaitForPrintNotify( Display *pdpy, int detail )
|
||||
{
|
||||
static int event_base_return = -1,
|
||||
error_base_return = -1;
|
||||
XEvent ev;
|
||||
|
||||
/* get extension event_base if we did not get it yet (and if Xserver does not
|
||||
* support extension do not wait for events which will never be send... :-)
|
||||
*/
|
||||
if( (event_base_return == -1) && (error_base_return == -1) )
|
||||
{
|
||||
int myevent_base_return, myerror_base_return;
|
||||
|
||||
if( XpQueryExtension(pdpy, &myevent_base_return, &myerror_base_return) == False )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuWaitForPrintNotify: XpQueryExtension failed\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* be sure we don't get in trouble if two threads try the same thing :-)
|
||||
* Bug/issue: Is it gurantteed that two different Xprt server's return the same values here ??
|
||||
*/
|
||||
event_base_return = myevent_base_return;
|
||||
error_base_return = myerror_base_return;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
XNextEvent(pdpy, &ev);
|
||||
if( ev.type != (event_base_return+XPPrintNotify) )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpuWaitForPrintNotify: Killing non-PrintNotify event %d/%d while waiting for %d/%d\n",
|
||||
(int)ev.type, (int)((XPPrintEvent *)(&ev))->detail,
|
||||
(int)(event_base_return+XPPrintNotify), detail));
|
||||
}
|
||||
} while( !((ev.type == (event_base_return+XPPrintNotify)) && (((XPPrintEvent *)(&ev))->detail == detail)) );
|
||||
}
|
||||
|
||||
|
||||
/* EOF. */
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
/*
|
||||
* 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 the X11 print system utilities library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Roland Mainz
|
||||
* <roland.mainz@informatik.med.uni-giessen.de>.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
|
||||
/* I don't know how to make this "better" yet... ;-( */
|
||||
#ifdef USE_MOZILLA_TYPES
|
||||
#include <prmem.h>
|
||||
#include <prthread.h>
|
||||
#define XPU_USE_NSPR 1
|
||||
#define XPU_USE_THREADS 1
|
||||
#endif /* USE_MOZILLA_TYPES */
|
||||
|
||||
#ifdef DEBUG
|
||||
/* trace function calls */
|
||||
#define XPU_TRACE(EX) (puts(#EX),EX)
|
||||
/* trace function calls in child */
|
||||
#define XPU_TRACE_CHILD(EX) (puts("child: " #EX),EX)
|
||||
/* execute function EX only in debug mode */
|
||||
#define XPU_DEBUG_ONLY(EX) (EX)
|
||||
#else
|
||||
#define XPU_TRACE(EX) (EX)
|
||||
#define XPU_TRACE_CHILD(EX) (EX)
|
||||
#define XPU_DEBUG_ONLY(EX)
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* debug: replace NULLptrs with "<NULL>" string */
|
||||
#define XPU_NULLXSTR(s) (((s)!=NULL)?(s):("<NULL>"))
|
||||
|
||||
/* prototypes */
|
||||
_XFUNCPROTOBEGIN
|
||||
|
||||
int XpuCheckExtension( Display *pdpy );
|
||||
char *XpuGetXpServerList( void );
|
||||
int XpuGetPrinter( char *printername, Display **pdpyptr, XPContext *pcontextptr );
|
||||
void XpuSetOneAttribute( Display *pdpy, XPContext pcontext,
|
||||
XPAttributes type, char *attribute_name, char *value, XPAttrReplacement replacement_rule );
|
||||
char *XpuEmumerateXpAttributeValue( char *value, void **context );
|
||||
int XpuCheckSupported( Display *pdpy, XPContext pcontext, XPAttributes type, char *attribute_name, char *query );
|
||||
int XpuSetJobTitle( Display *pdpy, XPContext pcontext, char *title );
|
||||
int XpuSetContentOrientation( Display *pdpy, XPContext pcontext, XPAttributes type, char *orientation );
|
||||
int XpuGetOneLongAttribute( Display *pdpy, XPContext pcontext, XPAttributes type, char *attribute_name, long *result );
|
||||
double XpuGetXDPI( Screen *pscreen );
|
||||
double XpuGetYDPI( Screen *pscreen );
|
||||
void dumpXpAttributes( Display *pdpy, XPContext pcontext );
|
||||
void XpuSetContext( Display *pdpy, XPContext pcontext );
|
||||
void XpuWaitForPrintNotify( Display *pdpy, int detail );
|
||||
|
||||
#define XpuGetJobAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPJobAttr )
|
||||
#define XpuGetDocAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPDocAttr )
|
||||
#define XpuGetPageAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPPageAttr )
|
||||
#define XpuGetPrinterAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPPrinterAttr )
|
||||
#define XpuGetServerAttributes( pdpy, pcontext ) XpGetAttributes( (pdpy), (pcontext), XPServerAttr )
|
||||
|
||||
void *XpuPrintToFile( Display *pdpy, XPContext pcontext, char *filename );
|
||||
XPGetDocStatus XpuWaitForPrintFileChild( void *handle );
|
||||
|
||||
_XFUNCPROTOEND
|
||||
|
||||
/* EOF. */
|
|
@ -0,0 +1,466 @@
|
|||
|
||||
/*
|
||||
* 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 the X11 print system utilities library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Roland Mainz
|
||||
* <roland.mainz@informatik.med.uni-giessen.de>.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#ifdef XPU_USE_THREADS
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#else
|
||||
#include <wait.h>
|
||||
#endif /* XPU_USE_THREADS */
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define NeedFunctionPrototypes (1) /* is this legal from within an app. !? */
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/Print.h>
|
||||
#include <X11/Intrinsic.h>
|
||||
|
||||
#include "xprintutil.h"
|
||||
|
||||
/* local prototypes */
|
||||
#ifdef DEBUG
|
||||
static void PrintXPGetDocStatus( XPGetDocStatus status );
|
||||
#endif
|
||||
static Bool XNextEventTimeout( Display *display, XEvent *event_return, struct timeval *timeout );
|
||||
static void MyPrintToFileProc( Display *pdpy, XPContext pcontext, unsigned char *data, unsigned int data_len, XPointer client_data );
|
||||
static void MyFinishProc( Display *pdpy, XPContext pcontext, XPGetDocStatus status, XPointer client_data );
|
||||
#ifdef XPU_USE_NSPR
|
||||
static void PrintToFile_Consumer( void *handle );
|
||||
#else
|
||||
static void *PrintToFile_Consumer( void *handle );
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
/* DEBUG: Print XPGetDocStatus */
|
||||
static
|
||||
void PrintXPGetDocStatus( XPGetDocStatus status )
|
||||
{
|
||||
switch(status)
|
||||
{
|
||||
case XPGetDocFinished: puts("PrintXPGetDocStatus: XPGetDocFinished"); break;
|
||||
case XPGetDocSecondConsumer: puts("PrintXPGetDocStatus: XPGetDocSecondConsumer"); break;
|
||||
case XPGetDocError: puts("PrintXPGetDocStatus: XPGetDocError"); break;
|
||||
default: puts("PrintXPGetDocStatus: <unknown value"); break;
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/* XNextEvent() with timeout */
|
||||
static
|
||||
Bool XNextEventTimeout( Display *display, XEvent *event_return, struct timeval *timeout )
|
||||
{
|
||||
int res;
|
||||
fd_set readfds;
|
||||
int display_fd = ConnectionNumber(display);
|
||||
|
||||
/* small shortcut... */
|
||||
if( timeout == NULL )
|
||||
{
|
||||
XNextEvent(display, event_return);
|
||||
return(True);
|
||||
}
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(display_fd, &readfds);
|
||||
|
||||
/* Note/bug: In the case of internal X events (like used to trigger callbacks
|
||||
* registered by XpGetDocumentData()&co.) select() will return with "new info"
|
||||
* - but XNextEvent() below processes these _internal_ events silently - and
|
||||
* will block if there are no other non-internal events.
|
||||
* The workaround here is to check with XEventsQueued() if there are non-internal
|
||||
* events queued - if not select() will be called again - unfortunately we use
|
||||
* the old timeout here instead of the "remaining" time... (this only would hurt
|
||||
* if the timeout would be really long - but for current use with values below
|
||||
* 1/2 secs it does not hurt... =:-)
|
||||
*/
|
||||
while( XEventsQueued(display, QueuedAfterFlush) == 0 )
|
||||
{
|
||||
res = select(display_fd+1, &readfds, NULL, NULL, timeout);
|
||||
|
||||
switch(res)
|
||||
{
|
||||
case -1: /* select() error - should not happen */
|
||||
perror("XNextEventTimeout: select() failure");
|
||||
return(False);
|
||||
case 0: /* timeout */
|
||||
return(False);
|
||||
}
|
||||
}
|
||||
|
||||
XNextEvent(display, event_return);
|
||||
return(True);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XPU_USE_THREADS
|
||||
/**
|
||||
** XpuPrintToFile() - threaded version
|
||||
** Create consumer thread which creates it's own display connection to print server
|
||||
** (a 2nd display connection/thread is required to avoid deadlocks within Xlib),
|
||||
** registers (Xlib-internal) consumer callback (via XpGetDocumentData(3Xp)) and
|
||||
** processes/eats all incoming events via MyPrintToFileProc(). A final call to
|
||||
** MyPrintToFileProc() cleans-up all stuff and sets the "done" flag.
|
||||
** Note that these callbacks are called directly by Xlib while waiting for events in
|
||||
** XNextEvent() because XpGetDocumentData() registeres them as "internal" callbacks,
|
||||
** e.g. XNextEvent() does _not_ return before/after processing these events !!
|
||||
**
|
||||
** Usage:
|
||||
** XpStartJob(pdpy, XPGetData);
|
||||
** handle = XpuPrintToFile(pdpy, pcontext, "myfile");
|
||||
** // render something
|
||||
** XpEndJob(); // or XpCancelJob()
|
||||
** status = XpuWaitForPrintFileChild(handle);
|
||||
**
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#ifdef XPU_USE_NSPR
|
||||
PRThread *prthread;
|
||||
#else
|
||||
pthread_t tid;
|
||||
#endif
|
||||
char *displayname;
|
||||
Display *pdpy;
|
||||
XPContext pcontext;
|
||||
char *file_name;
|
||||
FILE *file;
|
||||
XPGetDocStatus status;
|
||||
Bool done;
|
||||
} MyPrintFileData;
|
||||
|
||||
|
||||
void *XpuPrintToFile( Display *pdpy, XPContext pcontext, char *filename )
|
||||
{
|
||||
MyPrintFileData *mpfd; /* warning: shared between threads !! */
|
||||
|
||||
if( (mpfd = malloc(sizeof(MyPrintFileData))) == NULL )
|
||||
return(NULL);
|
||||
|
||||
mpfd->displayname = DisplayString(pdpy);
|
||||
mpfd->pdpy = NULL;
|
||||
mpfd->pcontext = pcontext;
|
||||
mpfd->file_name = filename;
|
||||
mpfd->file = NULL;
|
||||
mpfd->status = XPGetDocError;
|
||||
|
||||
/* make sure we can open the file for writing */
|
||||
if( (mpfd->file = fopen(mpfd->file_name, "w")) == NULL )
|
||||
{
|
||||
/* fopen() error */
|
||||
free(mpfd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* its important to flush before we start the consumer thread,
|
||||
* to make sure that the XpStartJob gets through first in the parent
|
||||
*/
|
||||
XFlush(pdpy);
|
||||
#ifdef XPU_USE_NSPR
|
||||
if( (mpfd->prthread = PR_CreateThread(PR_SYSTEM_THREAD, PrintToFile_Consumer, mpfd, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0)) == NULL )
|
||||
#else
|
||||
if( pthread_create(&(mpfd->tid), NULL, PrintToFile_Consumer, mpfd) != 0 )
|
||||
#endif
|
||||
{
|
||||
/* pthread_create() error */
|
||||
fclose(mpfd->file);
|
||||
free(mpfd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* we're still in the parent */
|
||||
XPU_DEBUG_ONLY(printf("### parent started consumer thread.\n" ));
|
||||
return(mpfd);
|
||||
}
|
||||
|
||||
|
||||
XPGetDocStatus XpuWaitForPrintFileChild( void *handle )
|
||||
{
|
||||
MyPrintFileData *mpfd = (MyPrintFileData *)handle;
|
||||
void *res;
|
||||
XPGetDocStatus status;
|
||||
|
||||
#ifdef XPU_USE_NSPR
|
||||
if( PR_JoinThread(mpfd->prthread) != PR_SUCCESS )
|
||||
perror("XpuWaitForPrintFileChild: PR_JoinThread() failure"); /* fixme(later): use NSPR error handling calls... */
|
||||
#else
|
||||
if( XPU_TRACE(pthread_join(mpfd->tid, &res)) != 0 )
|
||||
perror("XpuWaitForPrintFileChild: pthread_join() failure");
|
||||
#endif
|
||||
|
||||
status = mpfd->status;
|
||||
free(handle);
|
||||
|
||||
XPU_DEBUG_ONLY(PrintXPGetDocStatus(status));
|
||||
return(status);
|
||||
}
|
||||
|
||||
#else /* XPU_USE_THREADS */
|
||||
/**
|
||||
** XpuPrintToFile() - fork() version
|
||||
** Create consumer thread which creates it's own display connection to print server
|
||||
** (a 2nd display connection/process is required to avoid deadlocks within Xlib),
|
||||
** registers (Xlib-internal) consumer callback (via XpGetDocumentData(3Xp)) and
|
||||
** processes/eats all incoming events via MyPrintToFileProc(). A final call to
|
||||
** MyPrintToFileProc() cleans-up all stuff and sets the "done" flag.
|
||||
** Note that these callbacks are called directly by Xlib while waiting for events in
|
||||
** XNextEvent() because XpGetDocumentData() registeres them as "internal" callbacks,
|
||||
** e.g. XNextEvent() does _not_ return before/after processing these events !!
|
||||
**
|
||||
** Usage:
|
||||
** XpStartJob(pdpy, XPGetData);
|
||||
** handle = XpuPrintToFile(pdpy, pcontext, "myfile");
|
||||
** // render something
|
||||
** XpEndJob(); // or XpCancelJob()
|
||||
** status = XpuWaitForPrintFileChild(handle);
|
||||
**
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
pid_t pid;
|
||||
int pipe[2]; /* child-->parent communication pipe */
|
||||
char *displayname;
|
||||
Display *pdpy;
|
||||
XPContext pcontext;
|
||||
char *file_name;
|
||||
FILE *file;
|
||||
XPGetDocStatus status;
|
||||
Bool done;
|
||||
} MyPrintFileData;
|
||||
|
||||
|
||||
void *XpuPrintToFile( Display *pdpy, XPContext pcontext, char *filename )
|
||||
{
|
||||
MyPrintFileData *mpfd;
|
||||
|
||||
if( (mpfd = malloc(sizeof(MyPrintFileData))) == NULL )
|
||||
return(NULL);
|
||||
|
||||
/* create pipe */
|
||||
if( pipe(mpfd->pipe) == -1 )
|
||||
{
|
||||
/* this should never happen, but... */
|
||||
perror("XpuPrintToFile: cannot create pipe");
|
||||
free(mpfd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
mpfd->displayname = DisplayString(pdpy);
|
||||
mpfd->pcontext = pcontext;
|
||||
mpfd->file_name = filename;
|
||||
mpfd->file = NULL;
|
||||
mpfd->status = XPGetDocError;
|
||||
|
||||
/* make sure we can open the file for writing */
|
||||
if( (mpfd->file = fopen(mpfd->file_name, "w")) == NULL )
|
||||
{
|
||||
/* fopen() error */
|
||||
close(mpfd->pipe[1]);
|
||||
close(mpfd->pipe[0]);
|
||||
free(mpfd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* its important to flush before we fork, to make sure that the
|
||||
* XpStartJob gets through first in the parent
|
||||
*/
|
||||
XFlush(pdpy);
|
||||
|
||||
mpfd->pid = fork();
|
||||
|
||||
if( mpfd->pid == 0 )
|
||||
{
|
||||
/* we're now in the fork()'ed child */
|
||||
PrintToFile_Consumer(mpfd);
|
||||
}
|
||||
else if( mpfd->pid < 0 )
|
||||
{
|
||||
/* fork() error */
|
||||
close(mpfd->pipe[1]);
|
||||
close(mpfd->pipe[0]);
|
||||
fclose(mpfd->file);
|
||||
free(mpfd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* we're still in the parent */
|
||||
XPU_DEBUG_ONLY(printf("### parent fork()'ed consumer child.\n"));
|
||||
|
||||
/* child will write into file - we don't need it anymore here... :-) */
|
||||
fclose(mpfd->file);
|
||||
close(mpfd->pipe[1]);
|
||||
return(mpfd);
|
||||
}
|
||||
|
||||
|
||||
XPGetDocStatus XpuWaitForPrintFileChild( void *handle )
|
||||
{
|
||||
MyPrintFileData *mpfd = (MyPrintFileData *)handle;
|
||||
siginfo_t res;
|
||||
XPGetDocStatus status = XPGetDocError; /* used when read() from pipe fails */
|
||||
|
||||
if( XPU_TRACE(waitid(P_PID, mpfd->pid, &res, WEXITED)) == -1 )
|
||||
perror("XpuWaitForPrintFileChild: waitid failure");
|
||||
|
||||
/* read the status from the child */
|
||||
if( read(mpfd->pipe[0], &status, sizeof(XPGetDocStatus)) != sizeof(XPGetDocStatus) )
|
||||
{
|
||||
perror("XpuWaitForPrintFileChild: can't read XPGetDocStatus");
|
||||
}
|
||||
close(mpfd->pipe[0]);
|
||||
|
||||
free(handle);
|
||||
|
||||
XPU_DEBUG_ONLY(PrintXPGetDocStatus(status));
|
||||
return(status);
|
||||
}
|
||||
#endif /* XPU_USE_THREADS */
|
||||
|
||||
|
||||
static
|
||||
void MyPrintToFileProc( Display *pdpy,
|
||||
XPContext pcontext,
|
||||
unsigned char *data,
|
||||
unsigned int data_len,
|
||||
XPointer client_data )
|
||||
{
|
||||
MyPrintFileData *mpfd = (MyPrintFileData *)client_data;
|
||||
|
||||
/* write to the file */
|
||||
XPU_TRACE_CHILD((void)fwrite(data, data_len, 1, mpfd->file)); /* what about error handling ? */
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void MyFinishProc( Display *pdpy,
|
||||
XPContext pcontext,
|
||||
XPGetDocStatus status,
|
||||
XPointer client_data )
|
||||
{
|
||||
MyPrintFileData *mpfd = (MyPrintFileData *)client_data;
|
||||
|
||||
/* remove the file if not successfull */
|
||||
if( status != XPGetDocFinished )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("MyFinishProc: error %d\n", (int)status));
|
||||
XPU_TRACE_CHILD(remove(mpfd->file_name));
|
||||
}
|
||||
|
||||
XPU_TRACE_CHILD((void)fclose(mpfd->file)); /* what about error handling ? */
|
||||
|
||||
mpfd->status = status;
|
||||
mpfd->done = True;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
#ifdef XPU_USE_NSPR
|
||||
void PrintToFile_Consumer( void *handle )
|
||||
#else
|
||||
void *PrintToFile_Consumer( void *handle )
|
||||
#endif
|
||||
{
|
||||
MyPrintFileData *mpfd = (MyPrintFileData *)handle;
|
||||
XEvent dummy;
|
||||
struct timeval timeout;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000; /* 1/10 s */
|
||||
|
||||
XPU_DEBUG_ONLY(printf("### child running, getting data from '%s'.\n", mpfd->displayname));
|
||||
|
||||
/* we cannot reuse fork()'ed display handles - our child needs his own one */
|
||||
if( (mpfd->pdpy = XPU_TRACE_CHILD(XOpenDisplay(mpfd->displayname))) == NULL )
|
||||
{
|
||||
perror("child cannot open display");
|
||||
#ifdef XPU_USE_NSPR
|
||||
return;
|
||||
#else
|
||||
return(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
mpfd->done = False;
|
||||
|
||||
/* register "consumer" callbacks */
|
||||
if( XPU_TRACE_CHILD(XpGetDocumentData(mpfd->pdpy, mpfd->pcontext,
|
||||
MyPrintToFileProc, MyFinishProc,
|
||||
(XPointer)mpfd)) == 0 )
|
||||
{
|
||||
XPU_DEBUG_ONLY(printf("XpGetDocumentData cannot register callbacks\n"));
|
||||
#ifdef XPU_USE_NSPR
|
||||
return;
|
||||
#else
|
||||
return(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* loop forever - libXp has registered hidden event callbacks for the consumer
|
||||
* callbacks - the finishCB will call set the "done" boolean after all...
|
||||
*/
|
||||
while( mpfd->done != True )
|
||||
{
|
||||
XNextEventTimeout(mpfd->pdpy, &dummy, &timeout);
|
||||
}
|
||||
|
||||
XCloseDisplay(mpfd->pdpy);
|
||||
|
||||
#ifdef XPU_USE_THREADS
|
||||
#ifdef XPU_USE_NSPR
|
||||
return;
|
||||
#else
|
||||
return(NULL);
|
||||
#endif
|
||||
#else
|
||||
/* write the status to the parent */
|
||||
if( XPU_TRACE_CHILD(write(mpfd->pipe[1], &mpfd->status, sizeof(XPGetDocStatus))) != sizeof(XPGetDocStatus) )
|
||||
{
|
||||
perror("PrintToFile_Consumer: can't write XPGetDocStatus");
|
||||
}
|
||||
|
||||
/* we don't do any free's or close's, as we are just
|
||||
* going to exit, in fact, get out without calling any C++
|
||||
* destructors, etc., as we don't want anything funny to happen
|
||||
* to the parent
|
||||
*/
|
||||
XPU_TRACE_CHILD(_exit(EXIT_SUCCESS));
|
||||
#endif /* XPU_USE_THREADS */
|
||||
}
|
||||
|
||||
/* EOF. */
|
Загрузка…
Ссылка в новой задаче