summaryrefslogtreecommitdiffstats
path: root/src/printsupport
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-23 12:58:08 +0200
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2020-09-24 10:36:38 +0200
commitfb18fe0316540d93f1bc2d4faf8eb1822e1481cb (patch)
treefe51c30b0aa36a71150af9ec117e89892e240ab8 /src/printsupport
parentab428e30004448dcff3c65163a8eb6533dd81542 (diff)
Windows: Build print support plugin directly into QtPrintSupport
Task-number: QTBUG-83259 Change-Id: I23042e1eb89d407692a96bfb2d6c4efdddbfb50f Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/printsupport')
-rw-r--r--src/printsupport/CMakeLists.txt21
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_win.cpp2
-rw-r--r--src/printsupport/dialogs/qprintdialog_win.cpp2
-rw-r--r--src/printsupport/kernel/kernel.pri9
-rw-r--r--src/printsupport/platform/windows/qprintengine_win.cpp (renamed from src/printsupport/kernel/qprintengine_win.cpp)4
-rw-r--r--src/printsupport/platform/windows/qprintengine_win_p.h (renamed from src/printsupport/kernel/qprintengine_win_p.h)8
-rw-r--r--src/printsupport/platform/windows/qwindowsprintdevice.cpp572
-rw-r--r--src/printsupport/platform/windows/qwindowsprintdevice_p.h154
-rw-r--r--src/printsupport/platform/windows/qwindowsprinterinfo.cpp120
-rw-r--r--src/printsupport/platform/windows/qwindowsprintersupport.cpp112
-rw-r--r--src/printsupport/platform/windows/qwindowsprintersupport_p.h79
-rw-r--r--src/printsupport/platform/windows/windows.json3
-rw-r--r--src/printsupport/platform/windows/windows.pri16
-rw-r--r--src/printsupport/printsupport.pro1
14 files changed, 1078 insertions, 25 deletions
diff --git a/src/printsupport/CMakeLists.txt b/src/printsupport/CMakeLists.txt
index 6372030148..1967f3d29a 100644
--- a/src/printsupport/CMakeLists.txt
+++ b/src/printsupport/CMakeLists.txt
@@ -57,20 +57,25 @@ qt_internal_extend_target(PrintSupport CONDITION MACOS
"platform/macos/qcocoaprintersupport.mm"
)
-qt_internal_extend_target(PrintSupport CONDITION QT_FEATURE_printpreviewwidget
- SOURCES
- kernel/qpaintengine_preview.cpp kernel/qpaintengine_preview_p.h
- widgets/qprintpreviewwidget.cpp widgets/qprintpreviewwidget.h
-)
-
qt_internal_extend_target(PrintSupport CONDITION WIN32
SOURCES
- kernel/qprintengine_win.cpp kernel/qprintengine_win_p.h
+ platform/windows/qprintengine_win.cpp platform/windows/qprintengine_win_p.h
+ platform/windows/qwindowsprintdevice.cpp platform/windows/qwindowsprintdevice_p.h
+ platform/windows/qwindowsprintersupport.cpp platform/windows/qwindowsprintersupport_p.h
LIBRARIES
- comdlg32
gdi32
user32
+ PUBLIC_LIBRARIES
+ comdlg32
winspool
+ NO_PCH_SOURCES
+ "platform/windows/qwindowsprintersupport.cpp"
+)
+
+qt_internal_extend_target(PrintSupport CONDITION QT_FEATURE_printpreviewwidget
+ SOURCES
+ kernel/qpaintengine_preview.cpp kernel/qpaintengine_preview_p.h
+ widgets/qprintpreviewwidget.cpp widgets/qprintpreviewwidget.h
)
qt_internal_extend_target(PrintSupport CONDITION QT_FEATURE_cups AND UNIX AND NOT APPLE
diff --git a/src/printsupport/dialogs/qpagesetupdialog_win.cpp b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
index 464381bbe4..2e2b41b372 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_win.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
@@ -41,7 +41,7 @@
#include <qapplication.h>
-#include "../kernel/qprintengine_win_p.h"
+#include <private/qprintengine_win_p.h>
#include "qpagesetupdialog_p.h"
#include "qprinter.h"
#include <qpa/qplatformnativeinterface.h>
diff --git a/src/printsupport/dialogs/qprintdialog_win.cpp b/src/printsupport/dialogs/qprintdialog_win.cpp
index c103bd911d..4f2ee83f62 100644
--- a/src/printsupport/dialogs/qprintdialog_win.cpp
+++ b/src/printsupport/dialogs/qprintdialog_win.cpp
@@ -47,7 +47,7 @@
#include <private/qapplication_p.h>
#include "qabstractprintdialog_p.h"
-#include "../kernel/qprintengine_win_p.h"
+#include <private/qprintengine_win_p.h>
#include "../kernel/qprinter_p.h"
#if !defined(PD_NOCURRENTPAGE)
diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri
index 5c0feaf7a9..c47ea9c87c 100644
--- a/src/printsupport/kernel/kernel.pri
+++ b/src/printsupport/kernel/kernel.pri
@@ -28,15 +28,6 @@ qtConfig(printpreviewwidget) {
SOURCES += $$PWD/qpaintengine_preview.cpp
}
-win32 {
- HEADERS += \
- $$PWD/qprintengine_win_p.h
- SOURCES += \
- $$PWD/qprintengine_win.cpp
- LIBS_PRIVATE += -lwinspool -lcomdlg32
- QMAKE_USE_PRIVATE += user32 gdi32
-}
-
unix:!darwin:qtConfig(cups) {
SOURCES += $$PWD/qcups.cpp
HEADERS += $$PWD/qcups_p.h
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/platform/windows/qprintengine_win.cpp
index e8bbbcfb1e..3d00f2683c 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/platform/windows/qprintengine_win.cpp
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtPrintSupport module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/platform/windows/qprintengine_win_p.h
index 878de9a7ac..eb8609e511 100644
--- a/src/printsupport/kernel/qprintengine_win_p.h
+++ b/src/printsupport/platform/windows/qprintengine_win_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the QtPrintSupport module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -44,8 +44,8 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
diff --git a/src/printsupport/platform/windows/qwindowsprintdevice.cpp b/src/printsupport/platform/windows/qwindowsprintdevice.cpp
new file mode 100644
index 0000000000..5ccc12fe9f
--- /dev/null
+++ b/src/printsupport/platform/windows/qwindowsprintdevice.cpp
@@ -0,0 +1,572 @@
+/****************************************************************************
+**
+** 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 QtPrintSupport module 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_p.h"
+
+#include <QtCore/qdebug.h>
+
+#ifndef DC_COLLATE
+# define DC_COLLATE 22
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QT_WARNING_DISABLE_GCC("-Wsign-compare")
+typedef QList<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
+ for (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());
+ const auto inputSlots = supportedInputSlots();
+ for (const QPrint::InputSlot &slot : inputSlots) {
+ 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
diff --git a/src/printsupport/platform/windows/qwindowsprintdevice_p.h b/src/printsupport/platform/windows/qwindowsprintdevice_p.h
new file mode 100644
index 0000000000..bbae4971b7
--- /dev/null
+++ b/src/printsupport/platform/windows/qwindowsprintdevice_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtPrintSupport module 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$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSPRINTDEVICE_H
+#define QWINDOWSPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformprintdevice.h>
+
+#include <QtPrintSupport/qtprintsupportglobal.h>
+#include <QtCore/qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_PRINTSUPPORT_EXPORT QWindowsPrinterInfo
+{
+public:
+ bool operator==(const QWindowsPrinterInfo &other) const
+ {
+ // We only need to check if these are the same for matching up
+ return m_id == other.m_id && m_name == other.m_name &&
+ m_location == other.m_location &&
+ m_makeAndModel == other.m_makeAndModel &&
+ m_isRemote == other.m_isRemote;
+ }
+ QString m_id;
+ QString m_name;
+ QString m_location;
+ QString m_makeAndModel;
+ QList<QPageSize> m_pageSizes;
+ QList<int> m_resolutions;
+ QList<QPrint::InputSlot> m_inputSlots;
+ QList<QPrint::OutputBin> m_outputBins;
+ QList<QPrint::DuplexMode> m_duplexModes;
+ QList<QPrint::ColorMode> m_colorModes;
+ QSize m_minimumPhysicalPageSize;
+ QSize m_maximumPhysicalPageSize;
+ bool m_isRemote = false;
+ bool m_havePageSizes = false;
+ bool m_haveResolutions = false;
+ bool m_haveCopies = false;
+ bool m_supportsMultipleCopies = false;
+ bool m_supportsCollateCopies = false;
+ bool m_haveMinMaxPageSizes = false;
+ bool m_supportsCustomPageSizes = false;
+ bool m_haveInputSlots = false;
+ bool m_haveOutputBins = false;
+ bool m_haveDuplexModes = false;
+ bool m_haveColorModes = false;
+};
+
+class Q_PRINTSUPPORT_EXPORT QWindowsPrintDevice : public QPlatformPrintDevice
+{
+public:
+ QWindowsPrintDevice();
+ explicit QWindowsPrintDevice(const QString &id);
+ virtual ~QWindowsPrintDevice();
+
+ bool isValid() const override;
+ bool isDefault() const override;
+
+ QPrint::DeviceState state() const override;
+
+ QPageSize defaultPageSize() const override;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const override;
+
+ int defaultResolution() const override;
+
+ QPrint::InputSlot defaultInputSlot() const override;
+
+ QPrint::DuplexMode defaultDuplexMode() const override;
+
+ QPrint::ColorMode defaultColorMode() const override;
+
+ static QStringList availablePrintDeviceIds();
+ static QString defaultPrintDeviceId();
+
+ bool supportsCollateCopies() const override;
+ bool supportsMultipleCopies() const override;
+ bool supportsCustomPageSizes() const override;
+ QSize minimumPhysicalPageSize() const override;
+ QSize maximumPhysicalPageSize() const override;
+
+protected:
+ void loadPageSizes() const override;
+ void loadResolutions() const override;
+ void loadInputSlots() const override;
+ void loadOutputBins() const override;
+ void loadDuplexModes() const override;
+ void loadColorModes() const override;
+ void loadCopiesSupport() const;
+ void loadMinMaxPageSizes() const;
+
+private:
+ LPCWSTR wcharId() const { return reinterpret_cast<LPCWSTR>(m_id.utf16()); }
+
+ HANDLE m_hPrinter;
+ mutable bool m_haveCopies;
+ mutable bool m_haveMinMaxPageSizes;
+ int m_infoIndex;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWINDOWSPRINTDEVICE_H
diff --git a/src/printsupport/platform/windows/qwindowsprinterinfo.cpp b/src/printsupport/platform/windows/qwindowsprinterinfo.cpp
new file mode 100644
index 0000000000..e416dd7a21
--- /dev/null
+++ b/src/printsupport/platform/windows/qwindowsprinterinfo.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module 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 "qprinterinfo.h"
+#include "qprinterinfo_p.h"
+
+#include <qstringlist.h>
+
+#include <qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+extern QPrinter::PaperSize mapDevmodePaperSize(int s);
+
+//QList<QPrinterInfo> QPrinterInfo::availablePrinters()
+//{
+// QList<QPrinterInfo> printers;
+
+// DWORD needed = 0;
+// DWORD returned = 0;
+// if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned)) {
+// LPBYTE buffer = new BYTE[needed];
+// if (EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer, needed, &needed, &returned)) {
+// PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer);
+// QPrinterInfo defPrn = defaultPrinter();
+// for (uint i = 0; i < returned; ++i) {
+// QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
+
+// QPrinterInfo printerInfo(printerName);
+// if (printerInfo.printerName() == defPrn.printerName())
+// printerInfo.d_ptr->isDefault = true;
+// printers.append(printerInfo);
+// }
+// }
+// delete [] buffer;
+// }
+
+// return printers;
+//}
+
+//QPrinterInfo QPrinterInfo::defaultPrinter()
+//{
+// QString noPrinters(QLatin1String("qt_no_printers"));
+// wchar_t buffer[256];
+// GetProfileString(L"windows", L"device", (wchar_t*)noPrinters.utf16(), buffer, 256);
+// QString output = QString::fromWCharArray(buffer);
+// if (output != noPrinters) {
+// // Filter out the name of the printer, which should be everything before a comma.
+// QString printerName = output.split(QLatin1Char(',')).value(0);
+// QPrinterInfo printerInfo(printerName);
+// printerInfo.d_ptr->isDefault = true;
+// return printerInfo;
+// }
+
+// return QPrinterInfo();
+//}
+
+//QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
+//{
+// const Q_D(QPrinterInfo);
+
+// QList<QPrinter::PaperSize> paperSizes;
+// if (isNull())
+// return paperSizes;
+
+// DWORD size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
+// NULL, DC_PAPERS, NULL, NULL);
+// if ((int)size != -1) {
+// wchar_t *papers = new wchar_t[size];
+// size = DeviceCapabilities(reinterpret_cast<const wchar_t*>(d->name.utf16()),
+// NULL, DC_PAPERS, papers, NULL);
+// for (int c = 0; c < (int)size; ++c)
+// paperSizes.append(mapDevmodePaperSize(papers[c]));
+// delete [] papers;
+// }
+
+// return paperSizes;
+//}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/platform/windows/qwindowsprintersupport.cpp b/src/printsupport/platform/windows/qwindowsprintersupport.cpp
new file mode 100644
index 0000000000..6fd5aef47f
--- /dev/null
+++ b/src/printsupport/platform/windows/qwindowsprintersupport.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtPrintSupport module 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 "qwindowsprintersupport_p.h"
+
+#ifndef QT_NO_PRINTER
+
+#include "qwindowsprintdevice_p.h"
+
+#include <QtCore/QStringList>
+#include <private/qprintengine_win_p.h>
+#include <private/qprintdevice_p.h>
+
+#define QT_STATICPLUGIN
+#include <qpa/qplatformprintplugin.h>
+
+QT_BEGIN_NAMESPACE
+
+QWindowsPrinterSupport::QWindowsPrinterSupport()
+ : QPlatformPrinterSupport()
+{
+}
+
+QWindowsPrinterSupport::~QWindowsPrinterSupport()
+{
+}
+
+QPrintEngine *QWindowsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId)
+{
+ return new QWin32PrintEngine(printerMode, deviceId);
+}
+
+QPaintEngine *QWindowsPrinterSupport::createPaintEngine(QPrintEngine *engine, QPrinter::PrinterMode printerMode)
+{
+ Q_UNUSED(printerMode);
+ return static_cast<QWin32PrintEngine *>(engine);
+}
+
+QPrintDevice QWindowsPrinterSupport::createPrintDevice(const QString &id)
+{
+ return QPlatformPrinterSupport::createPrintDevice(new QWindowsPrintDevice(id));
+}
+
+QStringList QWindowsPrinterSupport::availablePrintDeviceIds() const
+{
+ return QWindowsPrintDevice::availablePrintDeviceIds();
+}
+
+QString QWindowsPrinterSupport::defaultPrintDeviceId() const
+{
+ return QWindowsPrintDevice::defaultPrintDeviceId();
+}
+
+class QWindowsPrinterSupportPlugin : public QPlatformPrinterSupportPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QPlatformPrinterSupportFactoryInterface_iid FILE "windows.json")
+
+public:
+ QPlatformPrinterSupport *create(const QString &);
+};
+
+QPlatformPrinterSupport *QWindowsPrinterSupportPlugin::create(const QString &key)
+{
+ if (key.compare(key, QLatin1String("windowsprintsupport"), Qt::CaseInsensitive) == 0)
+ return new QWindowsPrinterSupport;
+ return nullptr;
+}
+
+Q_IMPORT_PLUGIN(QWindowsPrinterSupportPlugin)
+
+#include "qwindowsprintersupport.moc"
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/printsupport/platform/windows/qwindowsprintersupport_p.h b/src/printsupport/platform/windows/qwindowsprintersupport_p.h
new file mode 100644
index 0000000000..a43fdb8d0a
--- /dev/null
+++ b/src/printsupport/platform/windows/qwindowsprintersupport_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtPrintSupport module 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$
+**
+****************************************************************************/
+
+#ifndef WINDOWSPRINTERSUPPORT_H
+#define WINDOWSPRINTERSUPPORT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtPrintSupport/qtprintsupportglobal.h>
+
+#include <qpa/qplatformprintersupport.h>
+#ifndef QT_NO_PRINTER
+
+QT_BEGIN_NAMESPACE
+
+class Q_PRINTSUPPORT_EXPORT QWindowsPrinterSupport : public QPlatformPrinterSupport
+{
+ Q_DISABLE_COPY_MOVE(QWindowsPrinterSupport)
+public:
+ QWindowsPrinterSupport();
+ ~QWindowsPrinterSupport() override;
+
+ QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode, const QString &deviceId = QString()) override;
+ QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) override;
+
+ QPrintDevice createPrintDevice(const QString &id) override;
+ QStringList availablePrintDeviceIds() const override;
+ QString defaultPrintDeviceId() const override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+#endif // WINDOWSPRINTERSUPPORT_H
diff --git a/src/printsupport/platform/windows/windows.json b/src/printsupport/platform/windows/windows.json
new file mode 100644
index 0000000000..803052854e
--- /dev/null
+++ b/src/printsupport/platform/windows/windows.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "windowsprintsupport" ]
+}
diff --git a/src/printsupport/platform/windows/windows.pri b/src/printsupport/platform/windows/windows.pri
new file mode 100644
index 0000000000..89d765dc28
--- /dev/null
+++ b/src/printsupport/platform/windows/windows.pri
@@ -0,0 +1,16 @@
+SOURCES += \
+ $$PWD/qprintengine_win.cpp \
+ $$PWD/qwindowsprintdevice.cpp
+
+# Disable PCH to allow selectively enabling QT_STATICPLUGIN
+NO_PCH_SOURCES += $$PWD/qwindowsprintersupport.cpp
+
+HEADERS += \
+ $$PWD/qprintengine_win_p.h \
+ $$PWD/qwindowsprintersupport_p.h \
+ $$PWD/qwindowsprintdevice_p.h
+
+OTHER_FILES += $$PWD/windows.json
+
+LIBS += -lwinspool -lcomdlg32
+QMAKE_USE_PRIVATE += user32 gdi32
diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro
index e64fbb634c..53bdccb3a3 100644
--- a/src/printsupport/printsupport.pro
+++ b/src/printsupport/printsupport.pro
@@ -12,6 +12,7 @@ include(widgets/widgets.pri)
include(dialogs/dialogs.pri)
macos: include(platform/macos/macos.pri)
+win32: include(platform/windows/windows.pri)
MODULE_PLUGIN_TYPES = \
printsupport