/****************************************************************************
**
** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwindowsprintdevice.h"

#include <qdebug.h>

#ifndef DC_COLLATE
#  define DC_COLLATE 22
#endif

QT_BEGIN_NAMESPACE

QT_WARNING_DISABLE_GCC("-Wsign-compare")
typedef QVector<QWindowsPrinterInfo> WindowsPrinterLookup;
Q_GLOBAL_STATIC(WindowsPrinterLookup, windowsDeviceLookup);

extern qreal qt_pointMultiplier(QPageLayout::Unit unit);

static inline uint qwcsnlen(const wchar_t *str, uint maxlen)
{
    uint length = 0;
    if (str) {
        while (length < maxlen && *str++)
            length++;
    }
    return length;
}

static QPrint::InputSlot paperBinToInputSlot(int windowsId, const QString &name)
{
    QPrint::InputSlot slot;
    slot.name = name;
    int i;
    for (i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) {
        if (inputSlotMap[i].windowsId == windowsId) {
            slot.key = inputSlotMap[i].key;
            slot.id = inputSlotMap[i].id;
            slot.windowsId = inputSlotMap[i].windowsId;
            return slot;
        }
    }
    slot.key = inputSlotMap[i].key;
    slot.id = inputSlotMap[i].id;
    slot.windowsId = windowsId;
    return slot;
}

static LPDEVMODE getDevmode(HANDLE hPrinter, const QString &printerId)
{
    LPWSTR printerIdUtf16 = const_cast<LPWSTR>(reinterpret_cast<LPCWSTR>(printerId.utf16()));
    // Allocate the required DEVMODE buffer
    LONG dmSize = DocumentProperties(NULL, hPrinter, printerIdUtf16, NULL, NULL, 0);
    if (dmSize <= 0)
        return nullptr;
    LPDEVMODE pDevMode = reinterpret_cast<LPDEVMODE>(malloc(dmSize));
     // Get the default DevMode
    LONG result = DocumentProperties(NULL, hPrinter, printerIdUtf16, pDevMode, NULL, DM_OUT_BUFFER);
    if (result != IDOK) {
        free(pDevMode);
        pDevMode = nullptr;
    }
    return pDevMode;
}

QWindowsPrintDevice::QWindowsPrintDevice()
    : QPlatformPrintDevice(),
      m_hPrinter(0)
{
}

QWindowsPrintDevice::QWindowsPrintDevice(const QString &id)
    : QPlatformPrintDevice(id),
      m_hPrinter(0)
{
    // First do a fast lookup to see if printer exists, if it does then open it
    if (!id.isEmpty() && QWindowsPrintDevice::availablePrintDeviceIds().contains(id)) {
        if (OpenPrinter(const_cast<LPWSTR>(wcharId()), &m_hPrinter, nullptr)) {
            DWORD needed = 0;
            GetPrinter(m_hPrinter, 2, 0, 0, &needed);
            QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
            if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) {
                PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data());
                m_name = QString::fromWCharArray(info->pPrinterName);
                m_location = QString::fromWCharArray(info->pLocation);
                m_makeAndModel = QString::fromWCharArray(info->pDriverName); // TODO Check is not available elsewhere
                m_isRemote = info->Attributes & PRINTER_ATTRIBUTE_NETWORK;
            }
            QWindowsPrinterInfo m_info;
            m_info.m_id = m_id;
            m_info.m_name = m_name;
            m_info.m_location = m_location;
            m_info.m_makeAndModel = m_makeAndModel;
            m_info.m_isRemote = m_isRemote;
            m_infoIndex = windowsDeviceLookup()->indexOf(m_info);
            if (m_infoIndex != -1) {
                m_info = windowsDeviceLookup()->at(m_infoIndex);
                m_havePageSizes = m_info.m_havePageSizes;
                m_pageSizes = m_info.m_pageSizes;
                m_haveResolutions = m_info.m_haveResolutions;
                m_resolutions = m_info.m_resolutions;
                m_haveCopies = m_info.m_haveCopies;
                m_supportsMultipleCopies = m_info.m_supportsMultipleCopies;
                m_supportsCollateCopies = m_info.m_supportsCollateCopies;
                m_haveMinMaxPageSizes = m_info.m_haveMinMaxPageSizes;
                m_minimumPhysicalPageSize = m_info.m_minimumPhysicalPageSize;
                m_maximumPhysicalPageSize = m_info.m_maximumPhysicalPageSize;
                m_supportsCustomPageSizes = m_info.m_supportsCustomPageSizes;
                m_haveInputSlots = m_info.m_haveInputSlots;
                m_inputSlots = m_info.m_inputSlots;
                m_haveOutputBins = m_info.m_haveOutputBins;
                m_outputBins = m_info.m_outputBins;
                m_haveDuplexModes = m_info.m_haveDuplexModes;
                m_duplexModes = m_info.m_duplexModes;
                m_haveColorModes = m_info.m_haveColorModes;
                m_colorModes = m_info.m_colorModes;
                m_infoIndex = windowsDeviceLookup()->indexOf(m_info);
            } else {
                windowsDeviceLookup()->append(m_info);
                m_infoIndex = windowsDeviceLookup()->count() - 1;
            }
        }
    }
}

QWindowsPrintDevice::~QWindowsPrintDevice()
{
    ClosePrinter(m_hPrinter);
}

bool QWindowsPrintDevice::isValid() const
{
    return m_hPrinter;
}

bool QWindowsPrintDevice::isDefault() const
{
    return m_id == defaultPrintDeviceId();
}

QPrint::DeviceState QWindowsPrintDevice::state() const
{
    DWORD needed = 0;
    GetPrinter(m_hPrinter, 6, 0, 0, &needed);
    QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);

    if (GetPrinter(m_hPrinter, 6, buffer.data(), needed, &needed)) {
        PPRINTER_INFO_6 info = reinterpret_cast<PPRINTER_INFO_6>(buffer.data());
        // TODO Check mapping
        if (info->dwStatus == 0
            || (info->dwStatus & PRINTER_STATUS_WAITING) == PRINTER_STATUS_WAITING
            || (info->dwStatus & PRINTER_STATUS_POWER_SAVE) == PRINTER_STATUS_POWER_SAVE) {
            return QPrint::Idle;
        } else if ((info->dwStatus & PRINTER_STATUS_PRINTING) == PRINTER_STATUS_PRINTING
                   || (info->dwStatus & PRINTER_STATUS_BUSY) == PRINTER_STATUS_BUSY
                   || (info->dwStatus & PRINTER_STATUS_INITIALIZING) == PRINTER_STATUS_INITIALIZING
                   || (info->dwStatus & PRINTER_STATUS_IO_ACTIVE) == PRINTER_STATUS_IO_ACTIVE
                   || (info->dwStatus & PRINTER_STATUS_PROCESSING) == PRINTER_STATUS_PROCESSING
                   || (info->dwStatus & PRINTER_STATUS_WARMING_UP) == PRINTER_STATUS_WARMING_UP) {
            return QPrint::Active;
        }
    }

    return QPrint::Error;
}

void QWindowsPrintDevice::loadPageSizes() const
{
    // Get the number of paper sizes and check all 3 attributes have same count
    DWORD paperCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERNAMES, NULL, NULL);
    if (int(paperCount) > 0
        && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERSIZE, NULL, NULL) == paperCount
        && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERS, NULL, NULL) == paperCount) {

        QScopedArrayPointer<wchar_t> paperNames(new wchar_t[paperCount*64]);
        QScopedArrayPointer<POINT> winSizes(new POINT[paperCount]);
        QScopedArrayPointer<wchar_t> papers(new wchar_t[paperCount]);

        // Get the details and match the default paper size
        if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERNAMES, paperNames.data(), NULL) == paperCount
            && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERSIZE, (wchar_t *)winSizes.data(), NULL) == paperCount
            && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERS, papers.data(), NULL) == paperCount) {

            // Returned size is in tenths of a millimeter
            const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter);
            for (int i = 0; i < int(paperCount); ++i) {
                QSize size = QSize(qRound((winSizes[i].x / 10.0) * multiplier), qRound((winSizes[i].y / 10.0) * multiplier));
                wchar_t *paper = paperNames.data() + (i * 64);
                QString name = QString::fromWCharArray(paper, qwcsnlen(paper, 64));
                m_pageSizes.append(createPageSize(papers[i], size, name));
            }

        }
    }

    m_havePageSizes = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_havePageSizes = true;
    info[m_infoIndex].m_pageSizes = m_pageSizes;
}

QPageSize QWindowsPrintDevice::defaultPageSize() const
{
    if (!m_havePageSizes)
        loadPageSizes();

    QPageSize pageSize;

    if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) {
        // Get the default paper size
        if (pDevMode->dmFields & DM_PAPERSIZE) {
            // Find the supported page size that matches, in theory default should be one of them
            foreach (const QPageSize &ps, m_pageSizes) {
                if (ps.windowsId() == pDevMode->dmPaperSize) {
                    pageSize = ps;
                    break;
                }
            }
        }
        // Clean-up
        free(pDevMode);
    }

    return pageSize;
}

QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize,
                                                QPageLayout::Orientation orientation,
                                                int resolution) const
{
    // TODO This is slow, need to cache values or find better way!
    // Modify the DevMode to get the DC printable margins in device pixels
    QMarginsF margins = QMarginsF(0, 0, 0, 0);
    DWORD needed = 0;
    GetPrinter(m_hPrinter, 2, 0, 0, &needed);
    QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
    if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) {
        PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data());
        LPDEVMODE devMode = info->pDevMode;
        bool separateDevMode = false;
        if (!devMode) {
            // GetPrinter() didn't include the DEVMODE. Get it a different way.
            devMode = getDevmode(m_hPrinter, m_id);
            if (!devMode)
                return margins;
            separateDevMode = true;
        }

        HDC pDC = CreateDC(NULL, (LPWSTR)m_id.utf16(), NULL, devMode);
        if (pageSize.id() == QPageSize::Custom || pageSize.windowsId() <= 0 || pageSize.windowsId() > DMPAPER_LAST) {
            devMode->dmPaperSize =  0;
            devMode->dmPaperWidth = pageSize.size(QPageSize::Millimeter).width() * 10.0;
            devMode->dmPaperLength = pageSize.size(QPageSize::Millimeter).height() * 10.0;
        } else {
            devMode->dmPaperSize =  pageSize.windowsId();
        }
        devMode->dmPrintQuality = resolution;
        devMode->dmOrientation = orientation == QPageLayout::Portrait ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
        ResetDC(pDC, devMode);
        const int dpiWidth = GetDeviceCaps(pDC, LOGPIXELSX);
        const int dpiHeight = GetDeviceCaps(pDC, LOGPIXELSY);
        const qreal wMult = 72.0 / dpiWidth;
        const qreal hMult = 72.0 / dpiHeight;
        const qreal physicalWidth = GetDeviceCaps(pDC, PHYSICALWIDTH) * wMult;
        const qreal physicalHeight = GetDeviceCaps(pDC, PHYSICALHEIGHT) * hMult;
        const qreal printableWidth = GetDeviceCaps(pDC, HORZRES) * wMult;
        const qreal printableHeight = GetDeviceCaps(pDC, VERTRES) * hMult;
        const qreal leftMargin = GetDeviceCaps(pDC, PHYSICALOFFSETX)* wMult;
        const qreal topMargin = GetDeviceCaps(pDC, PHYSICALOFFSETY) * hMult;
        const qreal rightMargin = physicalWidth - leftMargin - printableWidth;
        const qreal bottomMargin = physicalHeight - topMargin - printableHeight;
        margins = QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin);
        if (separateDevMode)
            free(devMode);
        DeleteDC(pDC);
    }
    return margins;
}

void QWindowsPrintDevice::loadResolutions() const
{
    DWORD resCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, NULL, NULL);
    if (int(resCount) > 0) {
        QScopedArrayPointer<LONG> resolutions(new LONG[resCount*2]);
        // Get the details and match the default paper size
        if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, (LPWSTR)resolutions.data(), NULL) == resCount) {
            for (int i = 0; i < int(resCount * 2); i += 2)
                m_resolutions.append(resolutions[i+1]);
        }
    }
    m_haveResolutions = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveResolutions = true;
    info[m_infoIndex].m_resolutions = m_resolutions;
}

int QWindowsPrintDevice::defaultResolution() const
{
    int resolution = 72;  // TODO Set a sensible default?

    if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) {
        // Get the default resolution
        if (pDevMode->dmFields & DM_YRESOLUTION) {
            if (pDevMode->dmPrintQuality > 0)
                resolution = pDevMode->dmPrintQuality;
            else
                resolution = pDevMode->dmYResolution;
        }
        // Clean-up
        free(pDevMode);
    }
    return resolution;
}

void QWindowsPrintDevice::loadInputSlots() const
{
    const auto printerId = wcharId();
    DWORD binCount = DeviceCapabilities(printerId, nullptr, DC_BINS, nullptr, nullptr);
    if (int(binCount) > 0
        && DeviceCapabilities(printerId, nullptr, DC_BINNAMES, nullptr, nullptr) == binCount) {

        QScopedArrayPointer<WORD> bins(new WORD[binCount]);
        QScopedArrayPointer<wchar_t> binNames(new wchar_t[binCount*24]);

        // Get the details and match the default paper size
        if (DeviceCapabilities(printerId, nullptr, DC_BINS,
                               reinterpret_cast<LPWSTR>(bins.data()), nullptr) == binCount
            && DeviceCapabilities(printerId, nullptr, DC_BINNAMES, binNames.data(),
                                  nullptr) == binCount) {

            for (int i = 0; i < int(binCount); ++i) {
                wchar_t *binName = binNames.data() + (i * 24);
                QString name = QString::fromWCharArray(binName, qwcsnlen(binName, 24));
                m_inputSlots.append(paperBinToInputSlot(bins[i], name));
            }

        }
    }

    m_haveInputSlots = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveInputSlots = true;
    info[m_infoIndex].m_inputSlots = m_inputSlots;
}

QPrint::InputSlot QWindowsPrintDevice::defaultInputSlot() const
{
    QPrint::InputSlot inputSlot = QPlatformPrintDevice::defaultInputSlot();;

    if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) {
        // Get the default input slot
        if (pDevMode->dmFields & DM_DEFAULTSOURCE) {
            QPrint::InputSlot tempSlot = paperBinToInputSlot(pDevMode->dmDefaultSource, QString());
            foreach (const QPrint::InputSlot &slot, supportedInputSlots()) {
                if (slot.key == tempSlot.key) {
                    inputSlot = slot;
                    break;
                }
            }
        }
        // Clean-up
        free(pDevMode);
    }
    return inputSlot;
}

void QWindowsPrintDevice::loadOutputBins() const
{
    m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
    m_haveOutputBins = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveOutputBins = true;
    info[m_infoIndex].m_outputBins = m_outputBins;
}

void QWindowsPrintDevice::loadDuplexModes() const
{
    m_duplexModes.append(QPrint::DuplexNone);
    DWORD duplex = DeviceCapabilities(wcharId(), nullptr, DC_DUPLEX, nullptr, nullptr);
    if (int(duplex) == 1) {
        // TODO Assume if duplex flag supports both modes
        m_duplexModes.append(QPrint::DuplexAuto);
        m_duplexModes.append(QPrint::DuplexLongSide);
        m_duplexModes.append(QPrint::DuplexShortSide);
    }
    m_haveDuplexModes = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveDuplexModes = true;
    info[m_infoIndex].m_duplexModes = m_duplexModes;
}

QPrint::DuplexMode QWindowsPrintDevice::defaultDuplexMode() const
{
    QPrint::DuplexMode duplexMode = QPrint::DuplexNone;

    if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) {
        // Get the default duplex mode
        if (pDevMode->dmFields & DM_DUPLEX) {
            if (pDevMode->dmDuplex == DMDUP_VERTICAL)
                duplexMode = QPrint::DuplexLongSide;
            else if (pDevMode->dmDuplex == DMDUP_HORIZONTAL)
                duplexMode = QPrint::DuplexShortSide;
        }
        // Clean-up
        free(pDevMode);
    }
    return duplexMode;
}

void QWindowsPrintDevice::loadColorModes() const
{
    m_colorModes.append(QPrint::GrayScale);
    DWORD color = DeviceCapabilities(wcharId(), nullptr, DC_COLORDEVICE, nullptr, nullptr);
    if (int(color) == 1)
        m_colorModes.append(QPrint::Color);
    m_haveColorModes = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveColorModes = true;
    info[m_infoIndex].m_colorModes = m_colorModes;
}

QPrint::ColorMode QWindowsPrintDevice::defaultColorMode() const
{
    if (!m_haveColorModes)
        loadColorModes();
    if (!m_colorModes.contains(QPrint::Color))
        return QPrint::GrayScale;

    QPrint::ColorMode colorMode = QPrint::GrayScale;

    if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) {
        // Get the default color mode
        if (pDevMode->dmFields & DM_COLOR && pDevMode->dmColor == DMCOLOR_COLOR)
            colorMode = QPrint::Color;
        // Clean-up
        free(pDevMode);
    }
    return colorMode;
}

QStringList QWindowsPrintDevice::availablePrintDeviceIds()
{
    QStringList list;
    DWORD needed = 0;
    DWORD returned = 0;
    if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        || !needed) {
        return list;
    }
    QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
    if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned))
        return list;
    PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data());
    for (uint i = 0; i < returned; ++i)
        list.append(QString::fromWCharArray(infoList[i].pPrinterName));
    return list;
}

QString QWindowsPrintDevice::defaultPrintDeviceId()
{
    DWORD size = 0;
    if (GetDefaultPrinter(NULL, &size) == ERROR_FILE_NOT_FOUND)
       return QString();

    QScopedArrayPointer<wchar_t> name(new wchar_t[size]);
    GetDefaultPrinter(name.data(), &size);
    return QString::fromWCharArray(name.data());
}

void QWindowsPrintDevice::loadCopiesSupport() const
{
    auto printerId = wcharId();
    m_supportsMultipleCopies = (DeviceCapabilities(printerId, NULL, DC_COPIES, NULL, NULL) > 1);
    m_supportsCollateCopies = DeviceCapabilities(printerId, NULL, DC_COLLATE, NULL, NULL);
    m_haveCopies = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveCopies = true;
    info[m_infoIndex].m_supportsMultipleCopies = m_supportsMultipleCopies;
    info[m_infoIndex].m_supportsCollateCopies = m_supportsCollateCopies;
}

bool QWindowsPrintDevice::supportsCollateCopies() const
{
    if (!m_haveCopies)
        loadCopiesSupport();
    return m_supportsCollateCopies;
}

bool QWindowsPrintDevice::supportsMultipleCopies() const
{
    if (!m_haveCopies)
        loadCopiesSupport();
    return m_supportsMultipleCopies;
}

bool QWindowsPrintDevice::supportsCustomPageSizes() const
{
    if (!m_haveMinMaxPageSizes)
        loadMinMaxPageSizes();
    return m_supportsCustomPageSizes;
}

QSize QWindowsPrintDevice::minimumPhysicalPageSize() const
{
    if (!m_haveMinMaxPageSizes)
        loadMinMaxPageSizes();
    return m_minimumPhysicalPageSize;
}

QSize QWindowsPrintDevice::maximumPhysicalPageSize() const
{
    if (!m_haveMinMaxPageSizes)
        loadMinMaxPageSizes();
    return m_maximumPhysicalPageSize;
}

void QWindowsPrintDevice::loadMinMaxPageSizes() const
{
    // Min/Max custom size is in tenths of a millimeter
    const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter);
    auto printerId = wcharId();
    DWORD min = DeviceCapabilities(printerId, NULL, DC_MINEXTENT, NULL, NULL);
    m_minimumPhysicalPageSize = QSize((LOWORD(min) / 10.0) * multiplier, (HIWORD(min) / 10.0) * multiplier);
    DWORD max = DeviceCapabilities(printerId, NULL, DC_MAXEXTENT, NULL, NULL);
    m_maximumPhysicalPageSize = QSize((LOWORD(max) / 10.0) * multiplier, (HIWORD(max) / 10.0) * multiplier);
    m_supportsCustomPageSizes = (m_maximumPhysicalPageSize.width() > 0 && m_maximumPhysicalPageSize.height() > 0);
    m_haveMinMaxPageSizes = true;
    QWindowsPrinterInfo *info = windowsDeviceLookup()->data();
    info[m_infoIndex].m_haveCopies = true;
    info[m_infoIndex].m_supportsMultipleCopies = m_supportsMultipleCopies;
    info[m_infoIndex].m_supportsCollateCopies = m_supportsCollateCopies;
}

QT_END_NAMESPACE
