1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "printing/printing_test.h"
14 #include "printing/printing_context.h"
15 #include "printing/printing_context_win.h"
16 #include "printing/print_settings.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 // This test is automatically disabled if no printer is available.
20 class PrintingContextTest
: public PrintingTest
<testing::Test
> {
22 void PrintSettingsCallback(printing::PrintingContext::Result result
) {
27 printing::PrintingContext::Result
result() const { return result_
; }
30 printing::PrintingContext::Result result_
;
33 // This is a fake PrintDlgEx implementation that sets the right fields in
34 // |lppd| to trigger a bug in older revisions of PrintingContext.
35 HRESULT WINAPI
PrintDlgExMock(LPPRINTDLGEX lppd
) {
36 // The interesting bits:
37 // Pretend the user hit print
38 lppd
->dwResultAction
= PD_RESULT_PRINT
;
40 // Pretend the page range is 1-5, but since lppd->Flags does not have
41 // PD_SELECTION set, this really shouldn't matter.
42 lppd
->nPageRanges
= 1;
43 lppd
->lpPageRanges
[0].nFromPage
= 1;
44 lppd
->lpPageRanges
[0].nToPage
= 5;
47 std::wstring printer_name
= PrintingContextTest::GetDefaultPrinter();
49 if (!OpenPrinter(const_cast<wchar_t*>(printer_name
.c_str()), &printer
, NULL
))
52 scoped_array
<uint8
> buffer
;
53 DEVMODE
* dev_mode
= NULL
;
54 PRINTER_INFO_2
* info_2
= NULL
;
55 HRESULT result
= S_OK
;
57 lppd
->hDevMode
= NULL
;
58 lppd
->hDevNames
= NULL
;
60 printing::PrintingContextWin::GetPrinterHelper(printer
, 2, &buffer
);
62 info_2
= reinterpret_cast<PRINTER_INFO_2
*>(buffer
.get());
63 if (info_2
->pDevMode
!= NULL
)
64 dev_mode
= info_2
->pDevMode
;
71 if (!printing::PrintingContextWin::AllocateContext(printer_name
, dev_mode
,
77 size_t dev_mode_size
= dev_mode
->dmSize
+ dev_mode
->dmDriverExtra
;
78 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, dev_mode_size
);
79 if (!lppd
->hDevMode
) {
83 void* dev_mode_ptr
= GlobalLock(lppd
->hDevMode
);
88 memcpy(dev_mode_ptr
, dev_mode
, dev_mode_size
);
89 GlobalUnlock(lppd
->hDevMode
);
92 size_t driver_size
= 2 + sizeof(wchar_t) * lstrlen(info_2
->pDriverName
);
93 size_t printer_size
= 2 + sizeof(wchar_t) * lstrlen(info_2
->pPrinterName
);
94 size_t port_size
= 2 + sizeof(wchar_t) * lstrlen(info_2
->pPortName
);
95 size_t dev_names_size
= sizeof(DEVNAMES
) + driver_size
+ printer_size
+
97 lppd
->hDevNames
= GlobalAlloc(GHND
, dev_names_size
);
98 if (!lppd
->hDevNames
) {
102 void* dev_names_ptr
= GlobalLock(lppd
->hDevNames
);
103 if (!dev_names_ptr
) {
107 DEVNAMES
* dev_names
= reinterpret_cast<DEVNAMES
*>(dev_names_ptr
);
108 dev_names
->wDefault
= 1;
109 dev_names
->wDriverOffset
= sizeof(DEVNAMES
);
110 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wDriverOffset
,
111 info_2
->pDriverName
, driver_size
);
112 dev_names
->wDeviceOffset
= dev_names
->wDriverOffset
+ driver_size
;
113 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wDeviceOffset
,
114 info_2
->pPrinterName
, printer_size
);
115 dev_names
->wOutputOffset
= dev_names
->wDeviceOffset
+ printer_size
;
116 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wOutputOffset
,
117 info_2
->pPortName
, port_size
);
118 GlobalUnlock(lppd
->hDevNames
);
119 dev_names_ptr
= NULL
;
122 // Note: This section does proper deallocation/free of DC/global handles. We
123 // did not use ScopedHGlobal or ScopedHandle because they did not
124 // perform what we need. Goto's are used based on Windows programming
125 // idiom, to avoid deeply nested if's, and try-catch-finally is not
126 // allowed in Chromium.
127 if (FAILED(result
)) {
131 if (lppd
->hDevMode
) {
132 GlobalFree(lppd
->hDevMode
);
134 if (lppd
->hDevNames
) {
135 GlobalFree(lppd
->hDevNames
);
138 ClosePrinter(printer
);
142 TEST_F(PrintingContextTest
, Base
) {
143 // Sometimes ::GetDefaultPrinter() fails? bug 61509.
144 if (IsTestCaseDisabled())
147 printing::PrintSettings settings
;
148 settings
.set_device_name(GetDefaultPrinter());
150 scoped_ptr
<printing::PrintingContext
> context(
151 printing::PrintingContext::Create(std::string()));
152 EXPECT_EQ(printing::PrintingContext::OK
, context
->InitWithSettings(settings
));
154 // The print may lie to use and may not support world transformation.
156 XFORM random_matrix
= { 1, 0.1f
, 0, 1.5f
, 0, 1 };
157 EXPECT_TRUE(SetWorldTransform(context
->context(), &random_matrix
));
158 EXPECT_TRUE(ModifyWorldTransform(context
->context(), NULL
, MWT_IDENTITY
));
161 TEST_F(PrintingContextTest
, PrintAll
) {
162 // Sometimes ::GetDefaultPrinter() fails? bug 61509.
163 if (IsTestCaseDisabled())
166 std::string dummy_locale
;
167 printing::PrintingContextWin
context(dummy_locale
);
168 context
.SetPrintDialog(&PrintDlgExMock
);
169 context
.AskUserForSettings(
170 NULL
, 123, false, base::Bind(&PrintingContextTest::PrintSettingsCallback
,
171 base::Unretained(this)));
172 EXPECT_EQ(printing::PrintingContext::OK
, result());
173 printing::PrintSettings settings
= context
.settings();
174 EXPECT_EQ(settings
.ranges
.size(), 0);