/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsPrintSettingsWin.h" #include "mozilla/ArrayUtils.h" #include "nsCRT.h" // Using paper sizes from wingdi.h and the units given there, plus a little // extra research for the ones it doesn't give. Looks like the list hasn't // changed since Windows 2000, so should be fairly stable now. const short kPaperSizeUnits[] = { nsIPrintSettings::kPaperSizeMillimeters, // Not Used default to mm as DEVMODE // uses tenths of mm, just in case nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTERSMALL nsIPrintSettings::kPaperSizeInches, // DMPAPER_TABLOID nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEDGER nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEGAL nsIPrintSettings::kPaperSizeInches, // DMPAPER_STATEMENT nsIPrintSettings::kPaperSizeInches, // DMPAPER_EXECUTIVE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4SMALL nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5 nsIPrintSettings::kPaperSizeInches, // DMPAPER_FOLIO nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_QUARTO nsIPrintSettings::kPaperSizeInches, // DMPAPER_10X14 nsIPrintSettings::kPaperSizeInches, // DMPAPER_11X17 nsIPrintSettings::kPaperSizeInches, // DMPAPER_NOTE nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_9 nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_10 nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_11 nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_12 nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_14 nsIPrintSettings::kPaperSizeInches, // DMPAPER_CSHEET nsIPrintSettings::kPaperSizeInches, // DMPAPER_DSHEET nsIPrintSettings::kPaperSizeInches, // DMPAPER_ESHEET nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_DL nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C5 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C3 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C6 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_C65 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B5 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_B6 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_ITALY nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_MONARCH nsIPrintSettings::kPaperSizeInches, // DMPAPER_ENV_PERSONAL nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_US nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_STD_GERMAN nsIPrintSettings::kPaperSizeInches, // DMPAPER_FANFOLD_LGL_GERMAN nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ISO_B4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JAPANESE_POSTCARD nsIPrintSettings::kPaperSizeInches, // DMPAPER_9X11 nsIPrintSettings::kPaperSizeInches, // DMPAPER_10X11 nsIPrintSettings::kPaperSizeInches, // DMPAPER_15X11 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_ENV_INVITE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_RESERVED_48 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_RESERVED_49 nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_EXTRA nsIPrintSettings::kPaperSizeInches, // DMPAPER_LEGAL_EXTRA nsIPrintSettings::kPaperSizeInches, // DMPAPER_TABLOID_EXTRA nsIPrintSettings::kPaperSizeInches, // DMPAPER_A4_EXTRA nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_TRANSVERSE nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_EXTRA_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A_PLUS nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B_PLUS nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_PLUS nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_PLUS nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_EXTRA nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_EXTRA nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_EXTRA nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A2 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_EXTRA_TRANSVERSE nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_DBL_JAPANESE_POSTCARD nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A6 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU2 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU3 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU3 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU4 nsIPrintSettings::kPaperSizeInches, // DMPAPER_LETTER_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A3_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A4_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A5_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B4_JIS_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B5_JIS_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JAPANESE_POSTCARD_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_A6_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU2_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_KAKU3_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU3_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_CHOU4_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B6_JIS nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_B6_JIS_ROTATED nsIPrintSettings::kPaperSizeInches, // DMPAPER_12X11 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_YOU4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_JENV_YOU4_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P16K nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32K nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32KBIG nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_1 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_2 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_3 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_4 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_5 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_6 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_7 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_8 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_9 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_10 nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P16K_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32K_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_P32KBIG_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_1_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_2_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_3_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_4_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_5_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_6_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_7_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_8_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_9_ROTATED nsIPrintSettings::kPaperSizeMillimeters, // DMPAPER_PENV_10_ROTATED }; NS_IMPL_ISUPPORTS_INHERITED(nsPrintSettingsWin, nsPrintSettings, nsIPrintSettingsWin) /** --------------------------------------------------- * See documentation in nsPrintSettingsWin.h * @update */ nsPrintSettingsWin::nsPrintSettingsWin() : nsPrintSettings(), mDeviceName(nullptr), mDriverName(nullptr), mDevMode(nullptr) { } /** --------------------------------------------------- * See documentation in nsPrintSettingsWin.h * @update */ nsPrintSettingsWin::nsPrintSettingsWin(const nsPrintSettingsWin& aPS) : mDeviceName(nullptr), mDriverName(nullptr), mDevMode(nullptr) { *this = aPS; } /** --------------------------------------------------- * See documentation in nsPrintSettingsWin.h * @update */ nsPrintSettingsWin::~nsPrintSettingsWin() { if (mDeviceName) free(mDeviceName); if (mDriverName) free(mDriverName); if (mDevMode) ::HeapFree(::GetProcessHeap(), 0, mDevMode); } NS_IMETHODIMP nsPrintSettingsWin::SetDeviceName(const char16_t * aDeviceName) { if (mDeviceName) { free(mDeviceName); } mDeviceName = aDeviceName?wcsdup(char16ptr_t(aDeviceName)):nullptr; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::GetDeviceName(char16_t **aDeviceName) { NS_ENSURE_ARG_POINTER(aDeviceName); *aDeviceName = mDeviceName?reinterpret_cast(wcsdup(mDeviceName)):nullptr; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::SetDriverName(const char16_t * aDriverName) { if (mDriverName) { free(mDriverName); } mDriverName = aDriverName?wcsdup(char16ptr_t(aDriverName)):nullptr; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::GetDriverName(char16_t **aDriverName) { NS_ENSURE_ARG_POINTER(aDriverName); *aDriverName = mDriverName?reinterpret_cast(wcsdup(mDriverName)):nullptr; return NS_OK; } void nsPrintSettingsWin::CopyDevMode(DEVMODEW* aInDevMode, DEVMODEW *& aOutDevMode) { aOutDevMode = nullptr; size_t size = aInDevMode->dmSize + aInDevMode->dmDriverExtra; aOutDevMode = (LPDEVMODEW)::HeapAlloc (::GetProcessHeap(), HEAP_ZERO_MEMORY, size); if (aOutDevMode) { memcpy(aOutDevMode, aInDevMode, size); } } NS_IMETHODIMP nsPrintSettingsWin::GetDevMode(DEVMODEW * *aDevMode) { NS_ENSURE_ARG_POINTER(aDevMode); if (mDevMode) { CopyDevMode(mDevMode, *aDevMode); } else { *aDevMode = nullptr; } return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::SetDevMode(DEVMODEW * aDevMode) { if (mDevMode) { ::HeapFree(::GetProcessHeap(), 0, mDevMode); mDevMode = nullptr; } if (aDevMode) { CopyDevMode(aDevMode, mDevMode); } return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::GetPrintableWidthInInches(double* aPrintableWidthInInches) { MOZ_ASSERT(aPrintableWidthInInches); *aPrintableWidthInInches = mPrintableWidthInInches; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::SetPrintableWidthInInches(double aPrintableWidthInInches) { mPrintableWidthInInches = aPrintableWidthInInches; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::GetPrintableHeightInInches(double* aPrintableHeightInInches) { MOZ_ASSERT(aPrintableHeightInInches); *aPrintableHeightInInches = mPrintableHeightInInches; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::SetPrintableHeightInInches(double aPrintableHeightInInches) { mPrintableHeightInInches = aPrintableHeightInInches; return NS_OK; } NS_IMETHODIMP nsPrintSettingsWin::GetEffectivePageSize(double *aWidth, double *aHeight) { // If printable page size not set, fall back to nsPrintSettings. if (mPrintableWidthInInches == 0l || mPrintableHeightInInches == 0l) { return nsPrintSettings::GetEffectivePageSize(aWidth, aHeight); } if (mOrientation == kPortraitOrientation) { *aWidth = NS_INCHES_TO_TWIPS(mPrintableWidthInInches); *aHeight = NS_INCHES_TO_TWIPS(mPrintableHeightInInches); } else { *aHeight = NS_INCHES_TO_TWIPS(mPrintableWidthInInches); *aWidth = NS_INCHES_TO_TWIPS(mPrintableHeightInInches); } return NS_OK; } void nsPrintSettingsWin::CopyFromNative(HDC aHdc, DEVMODEW* aDevMode) { MOZ_ASSERT(aHdc); MOZ_ASSERT(aDevMode); mIsInitedFromPrinter = true; if (aDevMode->dmFields & DM_ORIENTATION) { mOrientation = int32_t(aDevMode->dmOrientation == DMORIENT_PORTRAIT ? kPortraitOrientation : kLandscapeOrientation); } if (aDevMode->dmFields & DM_COPIES) { mNumCopies = aDevMode->dmCopies; } // Since we do the scaling, grab their value and reset back to 100. if (aDevMode->dmFields & DM_SCALE) { double scale = double(aDevMode->dmScale) / 100.0f; if (mScaling == 1.0 || scale != 1.0) { mScaling = scale; } aDevMode->dmScale = 100; } if (aDevMode->dmFields & DM_PAPERSIZE) { mPaperData = aDevMode->dmPaperSize; // If not a paper size we know about, the unit will be the last one saved. if (mPaperData > 0 && mPaperData < int32_t(mozilla::ArrayLength(kPaperSizeUnits))) { mPaperSizeUnit = kPaperSizeUnits[mPaperData]; } } else { mPaperData = -1; } // The length and width in DEVMODE are always in tenths of a millimeter. double sizeUnitToTenthsOfAmm = 10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L); if (aDevMode->dmFields & DM_PAPERLENGTH) { mPaperHeight = aDevMode->dmPaperLength / sizeUnitToTenthsOfAmm; } else { mPaperHeight = -1l; } if (aDevMode->dmFields & DM_PAPERWIDTH) { mPaperWidth = aDevMode->dmPaperWidth / sizeUnitToTenthsOfAmm; } else { mPaperWidth = -1l; } // On Windows we currently create a surface using the printable area of the // page and don't set the unwriteable [sic] margins. Using the unwriteable // margins doesn't appear to work on Windows, but I am not sure if this is a // bug elsewhere in our code or a Windows quirk. // Note: we only scale the printing using the LOGPIXELSY, so we use that // when calculating the surface width as well as the height. int32_t printableWidthInDots = GetDeviceCaps(aHdc, HORZRES); int32_t printableHeightInDots = GetDeviceCaps(aHdc, VERTRES); int32_t heightDPI = GetDeviceCaps(aHdc, LOGPIXELSY); // Keep these values in portrait format, so we can reflect our own changes // to mOrientation. if (mOrientation == kPortraitOrientation) { mPrintableWidthInInches = double(printableWidthInDots) / heightDPI; mPrintableHeightInInches = double(printableHeightInDots) / heightDPI; } else { mPrintableHeightInInches = double(printableWidthInDots) / heightDPI; mPrintableWidthInInches = double(printableHeightInDots) / heightDPI; } // Using Y to match existing code for print scaling calculations. mResolution = heightDPI; } void nsPrintSettingsWin::CopyToNative(DEVMODEW* aDevMode) { MOZ_ASSERT(aDevMode); if (mPaperData >= 0) { aDevMode->dmPaperSize = mPaperData; aDevMode->dmFields |= DM_PAPERSIZE; } else { aDevMode->dmPaperSize = 0; aDevMode->dmFields &= ~DM_PAPERSIZE; } // The length and width in DEVMODE are always in tenths of a millimeter. double sizeUnitToTenthsOfAmm = 10L * (mPaperSizeUnit == kPaperSizeInches ? MM_PER_INCH_FLOAT : 1L); // Note: small page sizes can be required here for sticker, label and slide // printers etc. see bug 1271900. if (mPaperHeight > 0) { aDevMode->dmPaperLength = mPaperHeight * sizeUnitToTenthsOfAmm; aDevMode->dmFields |= DM_PAPERLENGTH; } else { aDevMode->dmPaperLength = 0; aDevMode->dmFields &= ~DM_PAPERLENGTH; } if (mPaperWidth > 0) { aDevMode->dmPaperWidth = mPaperWidth * sizeUnitToTenthsOfAmm; aDevMode->dmFields |= DM_PAPERWIDTH; } else { aDevMode->dmPaperWidth = 0; aDevMode->dmFields &= ~DM_PAPERWIDTH; } // Setup Orientation aDevMode->dmOrientation = mOrientation == kPortraitOrientation ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE; aDevMode->dmFields |= DM_ORIENTATION; // Setup Number of Copies aDevMode->dmCopies = mNumCopies; aDevMode->dmFields |= DM_COPIES; } //------------------------------------------- nsresult nsPrintSettingsWin::_Clone(nsIPrintSettings **_retval) { RefPtr printSettings = new nsPrintSettingsWin(*this); printSettings.forget(_retval); return NS_OK; } //------------------------------------------- nsPrintSettingsWin& nsPrintSettingsWin::operator=(const nsPrintSettingsWin& rhs) { if (this == &rhs) { return *this; } ((nsPrintSettings&) *this) = rhs; if (mDeviceName) { free(mDeviceName); } if (mDriverName) { free(mDriverName); } // Use free because we used the native malloc to create the memory if (mDevMode) { ::HeapFree(::GetProcessHeap(), 0, mDevMode); } mDeviceName = rhs.mDeviceName?wcsdup(rhs.mDeviceName):nullptr; mDriverName = rhs.mDriverName?wcsdup(rhs.mDriverName):nullptr; if (rhs.mDevMode) { CopyDevMode(rhs.mDevMode, mDevMode); } else { mDevMode = nullptr; } return *this; } //------------------------------------------- nsresult nsPrintSettingsWin::_Assign(nsIPrintSettings *aPS) { nsPrintSettingsWin *psWin = static_cast(aPS); *this = *psWin; return NS_OK; } //---------------------------------------------------------------------- // Testing of assign and clone // This define turns on the testing module below // so at start up it writes and reads the prefs. #ifdef DEBUG_rodsX #include "nsIPrintOptions.h" #include "nsIServiceManager.h" class Tester { public: Tester(); }; Tester::Tester() { nsCOMPtr ps; nsresult rv; nsCOMPtr printService = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv); if (NS_SUCCEEDED(rv)) { rv = printService->CreatePrintSettings(getter_AddRefs(ps)); } if (ps) { ps->SetPrintOptions(nsIPrintSettings::kPrintOddPages, true); ps->SetPrintOptions(nsIPrintSettings::kPrintEvenPages, false); ps->SetMarginTop(1.0); ps->SetMarginLeft(1.0); ps->SetMarginBottom(1.0); ps->SetMarginRight(1.0); ps->SetScaling(0.5); ps->SetPrintBGColors(true); ps->SetPrintBGImages(true); ps->SetPrintRange(15); ps->SetHeaderStrLeft(NS_ConvertUTF8toUTF16("Left").get()); ps->SetHeaderStrCenter(NS_ConvertUTF8toUTF16("Center").get()); ps->SetHeaderStrRight(NS_ConvertUTF8toUTF16("Right").get()); ps->SetFooterStrLeft(NS_ConvertUTF8toUTF16("Left").get()); ps->SetFooterStrCenter(NS_ConvertUTF8toUTF16("Center").get()); ps->SetFooterStrRight(NS_ConvertUTF8toUTF16("Right").get()); ps->SetPaperName(NS_ConvertUTF8toUTF16("Paper Name").get()); ps->SetPaperData(1); ps->SetPaperWidth(100.0); ps->SetPaperHeight(50.0); ps->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); ps->SetPrintReversed(true); ps->SetPrintInColor(true); ps->SetOrientation(nsIPrintSettings::kLandscapeOrientation); ps->SetPrintCommand(NS_ConvertUTF8toUTF16("Command").get()); ps->SetNumCopies(2); ps->SetPrinterName(NS_ConvertUTF8toUTF16("Printer Name").get()); ps->SetPrintToFile(true); ps->SetToFileName(NS_ConvertUTF8toUTF16("File Name").get()); ps->SetPrintPageDelay(1000); nsCOMPtr ps2; if (NS_SUCCEEDED(rv)) { rv = printService->CreatePrintSettings(getter_AddRefs(ps2)); } ps2->Assign(ps); nsCOMPtr psClone; ps2->Clone(getter_AddRefs(psClone)); } } Tester gTester; #endif