/*
 * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "awt_Component.h"
#include "awt_PrintControl.h"
#include "awt.h"
#include "awt_PrintDialog.h"
#include <winspool.h>
#include <float.h>
#include <math.h>

#define ROUNDTOINT(x) ((int)((x)+0.5))
static const int DEFAULT_RES = 72;
static const double TENTHS_MM_TO_POINTS = 3.527777778;
static const double LOMETRIC_TO_POINTS = (72.0 / 254.0);


/* Values must match those defined in WPrinterJob.java */
static const DWORD SET_COLOR = 0x00000200;
static const DWORD SET_ORIENTATION = 0x00004000;
static const DWORD SET_DUP_VERTICAL = 0x00000010;
static const DWORD SET_DUP_HORIZONTAL = 0x00000020;
static const DWORD SET_RES_HIGH = 0x00000040;
static const DWORD SET_RES_LOW = 0x00000080;


/* These methods and fields are on sun.awt.windows.WPrinterJob */
jfieldID  AwtPrintControl::dialogOwnerPeerID;
jmethodID AwtPrintControl::getPrintDCID;
jmethodID AwtPrintControl::setPrintDCID;
jmethodID AwtPrintControl::getDevmodeID;
jmethodID AwtPrintControl::setDevmodeID;
jmethodID AwtPrintControl::getDevnamesID;
jmethodID AwtPrintControl::setDevnamesID;
jfieldID  AwtPrintControl::driverDoesMultipleCopiesID;
jfieldID  AwtPrintControl::driverDoesCollationID;
jmethodID AwtPrintControl::getWin32MediaID;
jmethodID AwtPrintControl::setWin32MediaID;
jmethodID AwtPrintControl::getWin32MediaTrayID;
jmethodID AwtPrintControl::setWin32MediaTrayID;
jmethodID AwtPrintControl::getColorID;
jmethodID AwtPrintControl::getCopiesID;
jmethodID AwtPrintControl::getSelectID;
jmethodID AwtPrintControl::getDestID;
jmethodID AwtPrintControl::getDialogID;
jmethodID AwtPrintControl::getFromPageID;
jmethodID AwtPrintControl::getMaxPageID;
jmethodID AwtPrintControl::getMinPageID;
jmethodID AwtPrintControl::getCollateID;
jmethodID AwtPrintControl::getOrientID;
jmethodID AwtPrintControl::getQualityID;
jmethodID AwtPrintControl::getPrintToFileEnabledID;
jmethodID AwtPrintControl::getPrinterID;
jmethodID AwtPrintControl::setPrinterID;
jmethodID AwtPrintControl::getResID;
jmethodID AwtPrintControl::getSidesID;
jmethodID AwtPrintControl::getToPageID;
jmethodID AwtPrintControl::setToPageID;
jmethodID AwtPrintControl::setNativeAttID;
jmethodID AwtPrintControl::setRangeCopiesID;
jmethodID AwtPrintControl::setResID;
jmethodID AwtPrintControl::setJobAttributesID;


BOOL AwtPrintControl::IsSupportedLevel(HANDLE hPrinter, DWORD dwLevel) {
    BOOL isSupported = FALSE;
    DWORD cbBuf = 0;
    LPBYTE pPrinter = NULL;

    DASSERT(hPrinter != NULL);

    VERIFY(::GetPrinter(hPrinter, dwLevel, NULL, 0, &cbBuf) == 0);
    if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        pPrinter = new BYTE[cbBuf];
        if (::GetPrinter(hPrinter, dwLevel, pPrinter, cbBuf, &cbBuf)) {
            isSupported = TRUE;
        }
        delete[] pPrinter;
    }

    return isSupported;
}

BOOL AwtPrintControl::FindPrinter(jstring printerName, LPBYTE pPrinterEnum,
                                  LPDWORD pcbBuf, LPTSTR * foundPrinter,
                                  LPTSTR * foundPort)
{
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);

    DWORD cReturned = 0;

    if (pPrinterEnum == NULL) {
        // Compute size of buffer
        DWORD cbNeeded = 0;
        ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
                           NULL, 2, NULL, 0, &cbNeeded, &cReturned);
        ::EnumPrinters(PRINTER_ENUM_LOCAL,
                       NULL, 5, NULL, 0, pcbBuf, &cReturned);
        if (cbNeeded > (*pcbBuf)) {
            *pcbBuf = cbNeeded;
        }
        return TRUE;
    }

    DASSERT(printerName != NULL);

    DWORD cbBuf = *pcbBuf, dummyWord = 0;

    JavaStringBuffer printerNameBuf(env, printerName);
    LPTSTR lpcPrinterName = (LPTSTR)printerNameBuf;
    DASSERT(lpcPrinterName != NULL);

    // For NT, first do a quick check of all remote and local printers.
    // This only allows us to search by name, though. PRINTER_INFO_4
    // doesn't support port searches. So, if the user has specified the
    // printer name as "LPT1:" (even though this is actually a port
    // name), we won't find the printer here.
    if (!::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
                        NULL, 4, pPrinterEnum, cbBuf, &dummyWord, &cReturned)) {
        return FALSE;
    }

    for (DWORD i = 0; i < cReturned; i++) {
        PRINTER_INFO_4 *info4 = (PRINTER_INFO_4 *)
            (pPrinterEnum + i * sizeof(PRINTER_INFO_4));
        if (info4->pPrinterName != NULL &&
            _tcsicmp(lpcPrinterName, info4->pPrinterName) == 0) {

            // Fix for BugTraq Id 4281380.
            // Get the port name since some drivers may require
            // this name to be passed to ::DeviceCapabilities().
            HANDLE hPrinter = NULL;
            if (::OpenPrinter(info4->pPrinterName, &hPrinter, NULL)) {
                // Fix for BugTraq Id 4286812.
                // Some drivers don't support PRINTER_INFO_5.
                // In this case we try PRINTER_INFO_2, and if that
                // isn't supported as well return NULL port name.
                try {
                    if (AwtPrintControl::IsSupportedLevel(hPrinter, 5)) {
                        VERIFY(::GetPrinter(hPrinter, 5, pPrinterEnum, cbBuf,
                                            &dummyWord));
                        PRINTER_INFO_5 *info5 = (PRINTER_INFO_5 *)pPrinterEnum;
                        *foundPrinter = info5->pPrinterName;
                        // pPortName may specify multiple ports. We only want one.
                        *foundPort = (info5->pPortName != NULL)
                            ? _tcstok(info5->pPortName, TEXT(",")) : NULL;
                    } else if (AwtPrintControl::IsSupportedLevel(hPrinter, 2)) {
                        VERIFY(::GetPrinter(hPrinter, 2, pPrinterEnum, cbBuf,
                                            &dummyWord));
                        PRINTER_INFO_2 *info2 = (PRINTER_INFO_2 *)pPrinterEnum;
                        *foundPrinter = info2->pPrinterName;
                        // pPortName may specify multiple ports. We only want one.
                        *foundPort = (info2->pPortName != NULL)
                            ? _tcstok(info2->pPortName, TEXT(",")) : NULL;
                    } else {
                        *foundPrinter = info4->pPrinterName;
                        // We failed to determine port name for the found printer.
                        *foundPort = NULL;
                    }
                } catch (std::bad_alloc&) {
                    VERIFY(::ClosePrinter(hPrinter));
                    throw;
                }

                VERIFY(::ClosePrinter(hPrinter));

                return TRUE;
            }

            return FALSE;
        }
    }

    // We still haven't found the printer, /* or we're using 95/98. */
    // PRINTER_INFO_5 supports both printer name and port name, so
    // we'll test both. On NT, PRINTER_ENUM_LOCAL means just local
    // printers. This is what we want, because we already tested all
    // remote printer names above (and remote printer port names are
    // the same as remote printer names). On 95/98, PRINTER_ENUM_LOCAL
    // means both remote and local printers. This is also what we want
    // because we haven't tested any printers yet.
    if (!::EnumPrinters(PRINTER_ENUM_LOCAL,
                        NULL, 5, pPrinterEnum, cbBuf, &dummyWord, &cReturned)) {
        return FALSE;
    }

    for (DWORD i = 0; i < cReturned; i++) {
        PRINTER_INFO_5 *info5 = (PRINTER_INFO_5 *)
            (pPrinterEnum + i * sizeof(PRINTER_INFO_5));
        // pPortName can specify multiple ports. Test them one at
        // a time.
        if (info5->pPortName != NULL) {
            LPTSTR port = _tcstok(info5->pPortName, TEXT(","));
            while (port != NULL) {
                if (_tcsicmp(lpcPrinterName, port) == 0) {
                    *foundPrinter = info5->pPrinterName;
                    *foundPort = port;
                    return TRUE;
                }
                port = _tcstok(NULL, TEXT(","));
            }
        }
    }

    return FALSE;
}


void AwtPrintControl::initIDs(JNIEnv *env, jclass cls)
{
    TRY;

    jclass cls = env->FindClass("sun/awt/windows/WPrinterJob");
    CHECK_NULL(cls);

    AwtPrintControl::dialogOwnerPeerID =
      env->GetFieldID(cls, "dialogOwnerPeer", "Ljava/awt/peer/ComponentPeer;");
    DASSERT(AwtPrintControl::dialogOwnerPeerID != NULL);
    CHECK_NULL(AwtPrintControl::dialogOwnerPeerID);

    AwtPrintControl::getPrintDCID = env->GetMethodID(cls, "getPrintDC", "()J");
    DASSERT(AwtPrintControl::getPrintDCID != NULL);
    CHECK_NULL(AwtPrintControl::getPrintDCID);

    AwtPrintControl::setPrintDCID =
        env->GetMethodID(cls, "setPrintDC", "(J)V");
    DASSERT(AwtPrintControl::setPrintDCID != NULL);
    CHECK_NULL(AwtPrintControl::setPrintDCID);

    AwtPrintControl::getDevmodeID = env->GetMethodID(cls, "getDevMode", "()J");
    DASSERT(AwtPrintControl::getDevmodeID != NULL);
    CHECK_NULL(AwtPrintControl::getDevmodeID);

    AwtPrintControl::setDevmodeID =
        env->GetMethodID(cls, "setDevMode", "(J)V");
    DASSERT(AwtPrintControl::setDevmodeID != NULL);
    CHECK_NULL(AwtPrintControl::setDevmodeID);

    AwtPrintControl::getDevnamesID =
        env->GetMethodID(cls, "getDevNames", "()J");
    DASSERT(AwtPrintControl::getDevnamesID != NULL);
    CHECK_NULL(AwtPrintControl::getDevnamesID);

    AwtPrintControl::setDevnamesID =
        env->GetMethodID(cls, "setDevNames", "(J)V");
    DASSERT(AwtPrintControl::setDevnamesID != NULL);
    CHECK_NULL(AwtPrintControl::setDevnamesID);

    AwtPrintControl::driverDoesMultipleCopiesID =
      env->GetFieldID(cls, "driverDoesMultipleCopies", "Z");
    DASSERT(AwtPrintControl::driverDoesMultipleCopiesID != NULL);
    CHECK_NULL(AwtPrintControl::driverDoesMultipleCopiesID);

    AwtPrintControl::driverDoesCollationID =
      env->GetFieldID(cls, "driverDoesCollation", "Z");
    DASSERT(AwtPrintControl::driverDoesCollationID != NULL);
    CHECK_NULL(AwtPrintControl::driverDoesCollationID);

    AwtPrintControl::getCopiesID =
      env->GetMethodID(cls, "getCopiesAttrib", "()I");
    DASSERT(AwtPrintControl::getCopiesID != NULL);
    CHECK_NULL(AwtPrintControl::getCopiesID);

    AwtPrintControl::getCollateID =
      env->GetMethodID(cls, "getCollateAttrib","()I");
    DASSERT(AwtPrintControl::getCollateID != NULL);
    CHECK_NULL(AwtPrintControl::getCollateID);

    AwtPrintControl::getOrientID =
      env->GetMethodID(cls, "getOrientAttrib", "()I");
    DASSERT(AwtPrintControl::getOrientID != NULL);
    CHECK_NULL(AwtPrintControl::getOrientID);

    AwtPrintControl::getFromPageID =
      env->GetMethodID(cls, "getFromPageAttrib", "()I");
    DASSERT(AwtPrintControl::getFromPageID != NULL);
    CHECK_NULL(AwtPrintControl::getFromPageID);

    AwtPrintControl::getToPageID =
      env->GetMethodID(cls, "getToPageAttrib", "()I");
    DASSERT(AwtPrintControl::getToPageID != NULL);
    CHECK_NULL(AwtPrintControl::getToPageID);

    AwtPrintControl::getMinPageID =
      env->GetMethodID(cls, "getMinPageAttrib", "()I");
    DASSERT(AwtPrintControl::getMinPageID != NULL);
    CHECK_NULL(AwtPrintControl::getMinPageID);

    AwtPrintControl::getMaxPageID =
      env->GetMethodID(cls, "getMaxPageAttrib", "()I");
    DASSERT(AwtPrintControl::getMaxPageID != NULL);
    CHECK_NULL(AwtPrintControl::getMaxPageID);

    AwtPrintControl::getDestID =
      env->GetMethodID(cls, "getDestAttrib", "()Z");
    DASSERT(AwtPrintControl::getDestID != NULL);
    CHECK_NULL(AwtPrintControl::getDestID);

    AwtPrintControl::getQualityID =
      env->GetMethodID(cls, "getQualityAttrib", "()I");
    DASSERT(AwtPrintControl::getQualityID != NULL);
    CHECK_NULL(AwtPrintControl::getQualityID);

    AwtPrintControl::getColorID =
      env->GetMethodID(cls, "getColorAttrib", "()I");
    DASSERT(AwtPrintControl::getColorID != NULL);
    CHECK_NULL(AwtPrintControl::getColorID);

    AwtPrintControl::getSidesID =
      env->GetMethodID(cls, "getSidesAttrib", "()I");
    DASSERT(AwtPrintControl::getSidesID != NULL);
    CHECK_NULL(AwtPrintControl::getSidesID);

    AwtPrintControl::getPrinterID =
      env->GetMethodID(cls, "getPrinterAttrib", "()Ljava/lang/String;");
    DASSERT(AwtPrintControl::getPrinterID != NULL);
    CHECK_NULL(AwtPrintControl::getPrinterID);

    AwtPrintControl::getWin32MediaID =
        env->GetMethodID(cls, "getWin32MediaAttrib", "()[I");
    DASSERT(AwtPrintControl::getWin32MediaID != NULL);
    CHECK_NULL(AwtPrintControl::getWin32MediaID);

    AwtPrintControl::setWin32MediaID =
      env->GetMethodID(cls, "setWin32MediaAttrib", "(III)V");
    DASSERT(AwtPrintControl::setWin32MediaID != NULL);
    CHECK_NULL(AwtPrintControl::setWin32MediaID);

    AwtPrintControl::getWin32MediaTrayID =
        env->GetMethodID(cls, "getMediaTrayAttrib", "()I");
    DASSERT(AwtPrintControl::getWin32MediaTrayID != NULL);
    CHECK_NULL(AwtPrintControl::getWin32MediaTrayID);

    AwtPrintControl::setWin32MediaTrayID =
      env->GetMethodID(cls, "setMediaTrayAttrib", "(I)V");
    DASSERT(AwtPrintControl::setWin32MediaTrayID != NULL);
    CHECK_NULL(AwtPrintControl::setWin32MediaTrayID);

    AwtPrintControl::getSelectID =
      env->GetMethodID(cls, "getSelectAttrib", "()I");
    DASSERT(AwtPrintControl::getSelectID != NULL);
    CHECK_NULL(AwtPrintControl::getSelectID);

    AwtPrintControl::getPrintToFileEnabledID =
      env->GetMethodID(cls, "getPrintToFileEnabled", "()Z");
    DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL);
    CHECK_NULL(AwtPrintControl::getPrintToFileEnabledID);

    AwtPrintControl::setNativeAttID =
      env->GetMethodID(cls, "setNativeAttributes", "(III)V");
    DASSERT(AwtPrintControl::setNativeAttID != NULL);
    CHECK_NULL(AwtPrintControl::setNativeAttID);

    AwtPrintControl::setRangeCopiesID =
      env->GetMethodID(cls, "setRangeCopiesAttribute", "(IIZI)V");
    DASSERT(AwtPrintControl::setRangeCopiesID != NULL);
    CHECK_NULL(AwtPrintControl::setRangeCopiesID);

    AwtPrintControl::setResID =
      env->GetMethodID(cls, "setResolutionDPI", "(II)V");
    DASSERT(AwtPrintControl::setResID != NULL);
    CHECK_NULL(AwtPrintControl::setResID);

    AwtPrintControl::setPrinterID =
      env->GetMethodID(cls, "setPrinterNameAttrib", "(Ljava/lang/String;)V");
    DASSERT(AwtPrintControl::setPrinterID != NULL);
    CHECK_NULL(AwtPrintControl::setPrinterID);

    AwtPrintControl::setJobAttributesID =
        env->GetMethodID(cls, "setJobAttributes",
        "(Ljavax/print/attribute/PrintRequestAttributeSet;IISSSSSSS)V");
    DASSERT(AwtPrintControl::setJobAttributesID != NULL);
    CHECK_NULL(AwtPrintControl::setJobAttributesID);

    CATCH_BAD_ALLOC;
}

BOOL CALLBACK PrintDlgHook(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
    TRY;

    if (iMsg == WM_INITDIALOG) {
        SetForegroundWindow(hDlg);
        return FALSE;
    }
    return FALSE;

    CATCH_BAD_ALLOC_RET(TRUE);
}

BOOL AwtPrintControl::CreateDevModeAndDevNames(PRINTDLG *ppd,
                                               LPTSTR pPrinterName,
                                               LPTSTR pPortName)
{
    DWORD cbNeeded = 0;
    LPBYTE pPrinter = NULL;
    BOOL retval = FALSE;
    HANDLE hPrinter;

    try {
        if (!::OpenPrinter(pPrinterName, &hPrinter, NULL)) {
            goto done;
        }
        VERIFY(::GetPrinter(hPrinter, 2, NULL, 0, &cbNeeded) == 0);
        if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
            goto done;
        }
        pPrinter = new BYTE[cbNeeded];
        if (!::GetPrinter(hPrinter, 2, pPrinter, cbNeeded, &cbNeeded)) {
            goto done;
        }
        PRINTER_INFO_2 *info2 = (PRINTER_INFO_2 *)pPrinter;

        // Create DEVMODE, if it exists.
        if (info2->pDevMode != NULL) {
            size_t devmodeSize =
                sizeof(DEVMODE) + info2->pDevMode->dmDriverExtra;
            ppd->hDevMode = ::GlobalAlloc(GHND, devmodeSize);
            if (ppd->hDevMode == NULL) {
                throw std::bad_alloc();
            }
            DEVMODE *devmode = (DEVMODE *)::GlobalLock(ppd->hDevMode);
            DASSERT(!::IsBadWritePtr(devmode, devmodeSize));
            memcpy(devmode, info2->pDevMode, devmodeSize);
            VERIFY(::GlobalUnlock(ppd->hDevMode) == 0);
            DASSERT(::GetLastError() == NO_ERROR);
        }

        // Create DEVNAMES.
        if (pPortName != NULL) {
            info2->pPortName = pPortName;
        } else if (info2->pPortName != NULL) {
            // pPortName may specify multiple ports. We only want one.
            info2->pPortName = _tcstok(info2->pPortName, TEXT(","));
        }

        size_t lenDriverName = ((info2->pDriverName != NULL)
                                    ? _tcslen(info2->pDriverName)
                                    : 0) + 1;
        size_t lenPrinterName = ((pPrinterName != NULL)
                                     ? _tcslen(pPrinterName)
                                     : 0) + 1;
        size_t lenOutputName = ((info2->pPortName != NULL)
                                    ? _tcslen(info2->pPortName)
                                    : 0) + 1;
        size_t devnameSize= sizeof(DEVNAMES) +
                        lenDriverName*sizeof(TCHAR) +
                        lenPrinterName*sizeof(TCHAR) +
                        lenOutputName*sizeof(TCHAR);

        ppd->hDevNames = ::GlobalAlloc(GHND, devnameSize);
        if (ppd->hDevNames == NULL) {
            throw std::bad_alloc();
        }

        DEVNAMES *devnames =
            (DEVNAMES *)::GlobalLock(ppd->hDevNames);
        DASSERT(!IsBadWritePtr(devnames, devnameSize));
        LPTSTR lpcDevnames = (LPTSTR)devnames;

        // note: all sizes are in characters, not in bytes
        devnames->wDriverOffset = sizeof(DEVNAMES)/sizeof(TCHAR);
        devnames->wDeviceOffset =
            static_cast<WORD>(sizeof(DEVNAMES)/sizeof(TCHAR) + lenDriverName);
        devnames->wOutputOffset =
            static_cast<WORD>(sizeof(DEVNAMES)/sizeof(TCHAR) + lenDriverName + lenPrinterName);
        if (info2->pDriverName != NULL) {
            _tcscpy_s(lpcDevnames + devnames->wDriverOffset, devnameSize - devnames->wDriverOffset, info2->pDriverName);
        } else {
            *(lpcDevnames + devnames->wDriverOffset) = _T('\0');
        }
        if (pPrinterName != NULL) {
            _tcscpy_s(lpcDevnames + devnames->wDeviceOffset, devnameSize - devnames->wDeviceOffset, pPrinterName);
        } else {
            *(lpcDevnames + devnames->wDeviceOffset) = _T('\0');
        }
        if (info2->pPortName != NULL) {
            _tcscpy_s(lpcDevnames + devnames->wOutputOffset, devnameSize - devnames->wOutputOffset, info2->pPortName);
        } else {
            *(lpcDevnames + devnames->wOutputOffset) = _T('\0');
        }
        VERIFY(::GlobalUnlock(ppd->hDevNames) == 0);
        DASSERT(::GetLastError() == NO_ERROR);
    } catch (std::bad_alloc&) {
        if (ppd->hDevNames != NULL) {
            VERIFY(::GlobalFree(ppd->hDevNames) == NULL);
            ppd->hDevNames = NULL;
        }
        if (ppd->hDevMode != NULL) {
            VERIFY(::GlobalFree(ppd->hDevMode) == NULL);
            ppd->hDevMode = NULL;
        }
        delete [] pPrinter;
        VERIFY(::ClosePrinter(hPrinter));
        hPrinter = NULL;
        throw;
    }

    retval = TRUE;

done:
    delete [] pPrinter;
    if (hPrinter) {
        VERIFY(::ClosePrinter(hPrinter));
        hPrinter = NULL;
    }

    return retval;
}


WORD AwtPrintControl::getNearestMatchingPaper(LPTSTR printer, LPTSTR port,
                                      double origWid, double origHgt,
                                      double* newWid, double *newHgt) {
    const double epsilon = 0.50;
    const double tolerance = (1.0 * 72.0);  // # inches * 72
    int numPaperSizes = 0;
    WORD *papers = NULL;
    POINT *paperSizes = NULL;

    if ((printer== NULL) || (port == NULL)) {
        return 0;
    }

    SAVE_CONTROLWORD
    numPaperSizes = (int)DeviceCapabilities(printer, port, DC_PAPERSIZE,
                                              NULL, NULL);

    if (numPaperSizes > 0) {
        papers = (WORD*)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(WORD), numPaperSizes);
        paperSizes = (POINT *)SAFE_SIZE_ARRAY_ALLOC(safe_Malloc, sizeof(*paperSizes),
                                          numPaperSizes);

        DWORD result1 = DeviceCapabilities(printer, port,
                                       DC_PAPERS, (LPTSTR) papers, NULL);

        DWORD result2 = DeviceCapabilities(printer, port,
                                       DC_PAPERSIZE, (LPTSTR) paperSizes,
                                       NULL);

        // REMIND: cache in papers and paperSizes
        if (result1 == -1 || result2 == -1 ) {
            free((LPTSTR) papers);
            papers = NULL;
            free((LPTSTR) paperSizes);
            paperSizes = NULL;
        }
    }
    RESTORE_CONTROLWORD

    double closestWid = 0.0;
    double closestHgt = 0.0;
    WORD   closestMatch = 0;

    if (paperSizes != NULL) {

      /* Paper sizes are in 0.1mm units. Convert to 1/72"
       * For each paper size, compute the difference from the paper size
       * passed in. Use a least-squares difference, so paper much different
       * in x or y should score poorly
       */
        double diffw = origWid;
        double diffh = origHgt;
        double least_square = diffw * diffw + diffh * diffh;
        double tmp_ls;
        double widpts, hgtpts;

        for (int i=0;i<numPaperSizes;i++) {
            widpts = paperSizes[i].x * LOMETRIC_TO_POINTS;
            hgtpts = paperSizes[i].y * LOMETRIC_TO_POINTS;

            if ((fabs(origWid - widpts) < epsilon) &&
                (fabs(origHgt - hgtpts) < epsilon)) {
                closestWid = origWid;
                closestHgt = origHgt;
                closestMatch = papers[i];
                break;
            }

            diffw = fabs(widpts - origWid);
            diffh = fabs(hgtpts - origHgt);
            tmp_ls = diffw * diffw + diffh * diffh;
            if ((diffw < tolerance) && (diffh < tolerance) &&
                (tmp_ls < least_square)) {
                least_square = tmp_ls;
                closestWid = widpts;
                closestHgt = hgtpts;
                closestMatch = papers[i];
            }
        }
    }

    if (closestWid > 0) {
        *newWid = closestWid;
    }
    if (closestHgt > 0) {
        *newHgt = closestHgt;
    }

    if (papers != NULL) {
        free((LPTSTR)papers);
    }

    if (paperSizes != NULL) {
        free((LPTSTR)paperSizes);
    }

    return closestMatch;
}

/*
 * Copy settings into a print dialog & any devmode
 */
BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env,
                                      jobject printCtrl, PRINTDLG &pd) {
    HWND hwndOwner = NULL;
    jobject dialogOwner =
        env->GetObjectField(printCtrl, AwtPrintControl::dialogOwnerPeerID);
    if (dialogOwner != NULL) {
        AwtComponent *dialogOwnerComp =
          (AwtComponent *)JNI_GET_PDATA(dialogOwner);

        hwndOwner = dialogOwnerComp->GetHWnd();
        env->DeleteLocalRef(dialogOwner);
        dialogOwner = NULL;
    }
    jobject mdh = NULL;
    jobject dest = NULL;
    jobject select = NULL;
    jobject dialog = NULL;
    LPTSTR printName = NULL;
    LPTSTR portName = NULL;

    // If the user didn't specify a printer, then this call returns the
    // name of the default printer.
    jstring printerName = (jstring)
      env->CallObjectMethod(printCtrl, AwtPrintControl::getPrinterID);

    if (printerName != NULL) {

        pd.hDevMode = AwtPrintControl::getPrintHDMode(env, printCtrl);
        pd.hDevNames = AwtPrintControl::getPrintHDName(env, printCtrl);

        LPTSTR getName = (LPTSTR)JNU_GetStringPlatformChars(env,
                                                      printerName, NULL);
        if (getName == NULL) {
            env->DeleteLocalRef(printerName);
            throw std::bad_alloc();
        }

        BOOL samePrinter = FALSE;

        // check if given printername is same as the currently saved printer
        if (pd.hDevNames != NULL ) {

            DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(pd.hDevNames);
            if (devnames != NULL) {
                LPTSTR lpdevnames = (LPTSTR)devnames;
                printName = lpdevnames+devnames->wDeviceOffset;

                if (!_tcscmp(printName, getName)) {

                    samePrinter = TRUE;
                    printName = _tcsdup(lpdevnames+devnames->wDeviceOffset);
                    portName = _tcsdup(lpdevnames+devnames->wOutputOffset);

                }
            }
            ::GlobalUnlock(pd.hDevNames);
        }

        if (!samePrinter) {
            LPTSTR foundPrinter = NULL;
            LPTSTR foundPort = NULL;
            DWORD cbBuf = 0;
            VERIFY(AwtPrintControl::FindPrinter(NULL, NULL, &cbBuf,
                                                NULL, NULL));
            LPBYTE buffer = new BYTE[cbBuf];

            if (AwtPrintControl::FindPrinter(printerName, buffer, &cbBuf,
                                             &foundPrinter, &foundPort) &&
                (foundPrinter != NULL) && (foundPort != NULL)) {

                printName = _tcsdup(foundPrinter);
                portName = _tcsdup(foundPort);

                if (!AwtPrintControl::CreateDevModeAndDevNames(&pd,
                                                   foundPrinter, foundPort)) {
                    delete [] buffer;
                    if (printName != NULL) {
                      free(printName);
                    }
                    if (portName != NULL) {
                      free(portName);
                    }
                    env->DeleteLocalRef(printerName);
                    return FALSE;
                }

                DASSERT(pd.hDevNames != NULL);
            } else {
                delete [] buffer;
                if (printName != NULL) {
                  free(printName);
                }
                if (portName != NULL) {
                  free(portName);
                }
                env->DeleteLocalRef(printerName);
                return FALSE;
            }

            delete [] buffer;
        }
        env->DeleteLocalRef(printerName);
        // PrintDlg may change the values of hDevMode and hDevNames so we
        // re-initialize our saved handles.
        AwtPrintControl::setPrintHDMode(env, printCtrl, NULL);
        AwtPrintControl::setPrintHDName(env, printCtrl, NULL);
    } else {

        // There is no default printer. This means that there are no
        // printers installed at all.

        if (printName != NULL) {
          free(printName);
        }
        if (portName != NULL) {
          free(portName);
        }
        // Returning TRUE means try to display the native print dialog
        // which will either display an error message or prompt the
        // user to install a printer.
        return TRUE;
    }

    // Now, set-up the struct for the real calls to ::PrintDlg and ::CreateDC

    pd.hwndOwner = hwndOwner;
    pd.Flags = PD_ENABLEPRINTHOOK | PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
    pd.lpfnPrintHook = (LPPRINTHOOKPROC)PrintDlgHook;

    pd.nFromPage = (WORD)env->CallIntMethod(printCtrl,
                                            AwtPrintControl::getFromPageID);
    pd.nToPage = (WORD)env->CallIntMethod(printCtrl,
                                          AwtPrintControl::getToPageID);
    pd.nMinPage = (WORD)env->CallIntMethod(printCtrl,
                                           AwtPrintControl::getMinPageID);
    jint maxPage = env->CallIntMethod(printCtrl,
                                      AwtPrintControl::getMaxPageID);
    pd.nMaxPage = (maxPage <= (jint)((WORD)-1)) ? (WORD)maxPage : (WORD)-1;

    if (env->CallBooleanMethod(printCtrl,
                               AwtPrintControl::getDestID)) {
      pd.Flags |= PD_PRINTTOFILE;
    }

    jint selectType = env->CallIntMethod(printCtrl,
                                         AwtPrintControl::getSelectID);

    // selectType identifies whether No selection (2D) or
    // SunPageSelection (AWT)
    if (selectType != 0) {
      pd.Flags |= selectType;
    }

    if (!env->CallBooleanMethod(printCtrl,
                                AwtPrintControl::getPrintToFileEnabledID)) {
      pd.Flags |= PD_DISABLEPRINTTOFILE;
    }

    if (pd.hDevMode != NULL) {
      DEVMODE *devmode = (DEVMODE *)::GlobalLock(pd.hDevMode);
      DASSERT(!IsBadWritePtr(devmode, sizeof(DEVMODE)));

      WORD copies = (WORD)env->CallIntMethod(printCtrl,
                                             AwtPrintControl::getCopiesID);
      if (copies > 0) {
          devmode->dmFields |= DM_COPIES;
          devmode->dmCopies = copies;
      }

      jint orient = env->CallIntMethod(printCtrl,
                                       AwtPrintControl::getOrientID);
      if (orient == 0) {  // PageFormat.LANDSCAPE == 0
        devmode->dmFields |= DM_ORIENTATION;
        devmode->dmOrientation = DMORIENT_LANDSCAPE;
      } else if (orient == 1) { // PageFormat.PORTRAIT == 1
        devmode->dmFields |= DM_ORIENTATION;
        devmode->dmOrientation = DMORIENT_PORTRAIT;
      }

      // -1 means unset, so we'll accept the printer default.
      int collate = env->CallIntMethod(printCtrl,
                                       AwtPrintControl::getCollateID);
      if (collate == 1) {
        devmode->dmFields |= DM_COLLATE;
        devmode->dmCollate = DMCOLLATE_TRUE;
      } else if (collate == 0) {
        devmode->dmFields |= DM_COLLATE;
        devmode->dmCollate = DMCOLLATE_FALSE;
      }

      int quality = env->CallIntMethod(printCtrl,
                                       AwtPrintControl::getQualityID);
      if (quality) {
        devmode->dmFields |= DM_PRINTQUALITY;
        devmode->dmPrintQuality = quality;
      }

      int color = env->CallIntMethod(printCtrl,
                                     AwtPrintControl::getColorID);
      if (color) {
        devmode->dmFields |= DM_COLOR;
        devmode->dmColor = color;
      }

      int sides = env->CallIntMethod(printCtrl,
                                     AwtPrintControl::getSidesID);
      if (sides) {
        devmode->dmFields |= DM_DUPLEX;
        devmode->dmDuplex = (int)sides;
      }

      jintArray obj = (jintArray)env->CallObjectMethod(printCtrl,
                                       AwtPrintControl::getWin32MediaID);
      jboolean isCopy;
      jint *wid_ht = env->GetIntArrayElements(obj,
                                              &isCopy);

      double newWid = 0.0, newHt = 0.0;
      if (wid_ht != NULL && wid_ht[0] != 0 && wid_ht[1] != 0) {
        devmode->dmFields |= DM_PAPERSIZE;
        devmode->dmPaperSize = AwtPrintControl::getNearestMatchingPaper(
                                             printName,
                                             portName,
                                             (double)wid_ht[0],
                                             (double)wid_ht[1],
                                             &newWid, &newHt);

      }
      env->ReleaseIntArrayElements(obj, wid_ht, 0);
      ::GlobalUnlock(pd.hDevMode);
      devmode = NULL;
    }

    if (printName != NULL) {
      free(printName);
    }
    if (portName != NULL) {
      free(portName);
    }

    return TRUE;
}


/*
 * Copy settings from print dialog & any devmode back into attributes
 * or properties.
 */
extern "C" {
extern void setCapabilities(JNIEnv *env, jobject WPrinterJob, HDC hdc);
}
BOOL AwtPrintControl::UpdateAttributes(JNIEnv *env,
                                       jobject printCtrl, PRINTDLG &pd) {

    DEVNAMES *devnames = NULL;
    DEVMODE *devmode = NULL;
    unsigned int copies = 1;
    DWORD pdFlags = pd.Flags;
    DWORD dmFields = 0, dmValues = 0;
    bool newDC = false;

    // This call ensures that default PrintService gets updated for the
    // case where initially, there weren't any printers.
    env->CallObjectMethod(printCtrl, AwtPrintControl::getPrinterID);

    if (pd.hDevMode != NULL) {
        devmode = (DEVMODE *)::GlobalLock(pd.hDevMode);
        DASSERT(!IsBadReadPtr(devmode, sizeof(DEVMODE)));
    }

    if (devmode != NULL) {
        /* Query the settings we understand and are interested in.
         * For the flags that are set in dmFields, where the values
         * are a simple enumeration, set the same bits in a clean dmFields
         * variable, and set bits in a dmValues variable to indicate the
         * selected value. These can all be passed up to Java in one
         * call to sync up the Java view of this.
         */

        if (devmode->dmFields & DM_COPIES) {
            dmFields |= DM_COPIES;
            copies = devmode->dmCopies;
            if (pd.nCopies == 1) {
                env->SetBooleanField(printCtrl,
                                     driverDoesMultipleCopiesID,
                                     JNI_TRUE);
            } else {
              copies = pd.nCopies;
            }
        }

        if (devmode->dmFields & DM_PAPERSIZE) {
            env->CallVoidMethod(printCtrl, AwtPrintControl::setWin32MediaID,
                                devmode->dmPaperSize, devmode->dmPaperWidth,
                                devmode->dmPaperLength);

        }

        if (devmode->dmFields & DM_DEFAULTSOURCE) {
            env->CallVoidMethod(printCtrl,
                                AwtPrintControl::setWin32MediaTrayID,
                                devmode->dmDefaultSource);
        }

        if (devmode->dmFields & DM_COLOR) {
            dmFields |= DM_COLOR;
            if (devmode->dmColor == DMCOLOR_COLOR) {
                dmValues |= SET_COLOR;
            }
        }

        if (devmode->dmFields & DM_ORIENTATION) {
            dmFields |= DM_ORIENTATION;
            if (devmode->dmOrientation == DMORIENT_LANDSCAPE) {
                dmValues |= SET_ORIENTATION;
            }
        }

        if (devmode->dmFields & DM_COLLATE) {
            dmFields |= DM_COLLATE;
            if (devmode->dmCollate == DMCOLLATE_TRUE) {
                pdFlags |= PD_COLLATE;
                env->SetBooleanField(printCtrl,
                                     driverDoesCollationID,
                                     JNI_TRUE);
            } else {
                pdFlags &= ~PD_COLLATE;
            }
        }

        if (devmode->dmFields & DM_PRINTQUALITY) {
            /* value < 0 indicates quality setting.
             * value > 0 indicates X resolution. In that case
             * hopefully we will also find y-resolution specified.
             * If its not, assume its the same as x-res.
             * Maybe Java code should try to reconcile this against
             * the printers claimed set of supported resolutions.
             */
            if (devmode->dmPrintQuality < 0) {
                if (dmFields |= DM_PRINTQUALITY) {
                    if (devmode->dmPrintQuality == DMRES_HIGH) {
                        dmValues |= SET_RES_HIGH;
                    } else if ((devmode->dmPrintQuality == DMRES_LOW) ||
                               (devmode->dmPrintQuality == DMRES_DRAFT)) {
                        dmValues |= SET_RES_LOW;
                    } else if (devmode->dmPrintQuality == DMRES_MEDIUM) {
                        /* default */
                    }
                }
            } else {
                int xRes = devmode->dmPrintQuality;
                int yRes = (devmode->dmFields & DM_YRESOLUTION) ?
                  devmode->dmYResolution : devmode->dmPrintQuality;
                env->CallVoidMethod(printCtrl, AwtPrintControl::setResID,
                                    xRes, yRes);
            }
        }

        if (devmode->dmFields & DM_DUPLEX) {
            dmFields |= DM_DUPLEX;
            if (devmode->dmDuplex == DMDUP_HORIZONTAL) {
              dmValues |= SET_DUP_HORIZONTAL;
            } else if (devmode->dmDuplex == DMDUP_VERTICAL) {
                dmValues |= SET_DUP_VERTICAL;
            }
        }


        ::GlobalUnlock(pd.hDevMode);
        devmode = NULL;
    } else {
        copies = pd.nCopies;
    }

    if (pd.hDevNames != NULL) {
        DEVNAMES *devnames = (DEVNAMES*)::GlobalLock(pd.hDevNames);
        DASSERT(!IsBadReadPtr(devnames, sizeof(DEVNAMES)));
        LPTSTR lpcNames = (LPTSTR)devnames;
        LPTSTR pbuf = (_tcslen(lpcNames + devnames->wDeviceOffset) == 0 ?
                      TEXT("") : lpcNames + devnames->wDeviceOffset);
        if (pbuf != NULL) {
            jstring jstr = JNU_NewStringPlatform(env, pbuf);
            env->CallVoidMethod(printCtrl,
                                AwtPrintControl::setPrinterID,
                                jstr);
            env->DeleteLocalRef(jstr);
        }
        pbuf = (_tcslen(lpcNames + devnames->wOutputOffset) == 0 ?
                      TEXT("") : lpcNames + devnames->wOutputOffset);
        if (pbuf != NULL) {
            if (wcscmp(pbuf, L"FILE:") == 0) {
                pdFlags |= PD_PRINTTOFILE;
            }
        }
        ::GlobalUnlock(pd.hDevNames);
        devnames = NULL;
    }


    env->CallVoidMethod(printCtrl, AwtPrintControl::setNativeAttID,
                        pdFlags,  dmFields, dmValues);


    // copies  & range are always set so no need to check for any flags
    env->CallVoidMethod(printCtrl, AwtPrintControl::setRangeCopiesID,
                        pd.nFromPage, pd.nToPage, (pdFlags & PD_PAGENUMS),
                        copies);

    // repeated calls to printDialog should not leak handles
    HDC oldDC = AwtPrintControl::getPrintDC(env, printCtrl);
    if (pd.hDC != oldDC) {
        if (oldDC != NULL) {
            ::DeleteDC(oldDC);
        }
        AwtPrintControl::setPrintDC(env, printCtrl, pd.hDC);
        newDC = true;
    }
    // Need to update WPrinterJob with device resolution settings for
    // new or changed DC.
    setCapabilities(env, printCtrl, pd.hDC);

    HGLOBAL oldG = AwtPrintControl::getPrintHDMode(env, printCtrl);
    if (pd.hDevMode != oldG) {
        AwtPrintControl::setPrintHDMode(env, printCtrl, pd.hDevMode);
    }

    oldG = AwtPrintControl::getPrintHDName(env, printCtrl);
    if (pd.hDevNames != oldG) {
        AwtPrintControl::setPrintHDName(env, printCtrl, pd.hDevNames);
    }

    return newDC;
}


BOOL AwtPrintControl::getDevmode( HANDLE hPrinter,
                                 LPTSTR printerName,
                                 LPDEVMODE *pDevMode) {

    if (hPrinter == NULL || printerName == NULL || pDevMode == NULL) {
      return FALSE;
    }

    SAVE_CONTROLWORD

    DWORD dwNeeded = ::DocumentProperties(NULL, hPrinter, printerName,
                                        NULL, NULL, 0);

    RESTORE_CONTROLWORD

    if (dwNeeded <= 0) {
        *pDevMode = NULL;
        return FALSE;
    }

    *pDevMode = (LPDEVMODE)GlobalAlloc(GPTR, dwNeeded);

    if (*pDevMode == NULL) {
        return FALSE;
    }

    DWORD dwRet = ::DocumentProperties(NULL,
                                       hPrinter,
                                       printerName,
                                       *pDevMode,
                                       NULL,
                                       DM_OUT_BUFFER);

    RESTORE_CONTROLWORD

    if (dwRet != IDOK)  {
        /* if failure, cleanup and return failure */
        GlobalFree(pDevMode);
        *pDevMode = NULL;
        return FALSE;
    }

    return TRUE;
}
