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/backend/printing_info_win.h"
14 #include "printing/printing_test.h"
15 #include "printing/printing_context.h"
16 #include "printing/printing_context_win.h"
17 #include "printing/print_settings.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 // This test is automatically disabled if no printer is available.
21 class PrintingContextTest
: public PrintingTest
<testing::Test
> {
23 void PrintSettingsCallback(printing::PrintingContext::Result result
) {
28 printing::PrintingContext::Result
result() const { return result_
; }
31 printing::PrintingContext::Result result_
;
34 // This is a fake PrintDlgEx implementation that sets the right fields in
35 // |lppd| to trigger a bug in older revisions of PrintingContext.
36 HRESULT WINAPI
PrintDlgExMock(LPPRINTDLGEX lppd
) {
37 // The interesting bits:
38 // Pretend the user hit print
39 lppd
->dwResultAction
= PD_RESULT_PRINT
;
41 // Pretend the page range is 1-5, but since lppd->Flags does not have
42 // PD_SELECTION set, this really shouldn't matter.
43 lppd
->nPageRanges
= 1;
44 lppd
->lpPageRanges
[0].nFromPage
= 1;
45 lppd
->lpPageRanges
[0].nToPage
= 5;
48 std::wstring printer_name
= PrintingContextTest::GetDefaultPrinter();
50 if (!OpenPrinter(const_cast<wchar_t*>(printer_name
.c_str()), &printer
, NULL
))
53 scoped_ptr
<uint8
[]> buffer
;
54 const DEVMODE
* dev_mode
= NULL
;
55 HRESULT result
= S_OK
;
57 lppd
->hDevMode
= NULL
;
58 lppd
->hDevNames
= NULL
;
60 printing::PrinterInfo2 info_2
;
61 if (info_2
.Init(printer
)) {
62 dev_mode
= info_2
.get()->pDevMode
;
69 if (!printing::PrintingContextWin::AllocateContext(printer_name
, dev_mode
,
75 size_t dev_mode_size
= dev_mode
->dmSize
+ dev_mode
->dmDriverExtra
;
76 lppd
->hDevMode
= GlobalAlloc(GMEM_MOVEABLE
, dev_mode_size
);
77 if (!lppd
->hDevMode
) {
81 void* dev_mode_ptr
= GlobalLock(lppd
->hDevMode
);
86 memcpy(dev_mode_ptr
, dev_mode
, dev_mode_size
);
87 GlobalUnlock(lppd
->hDevMode
);
90 size_t driver_size
= 2 + sizeof(wchar_t) * lstrlen(info_2
.get()->pDriverName
);
91 size_t printer_size
= 2 + sizeof(wchar_t) *
92 lstrlen(info_2
.get()->pPrinterName
);
93 size_t port_size
= 2 + sizeof(wchar_t) * lstrlen(info_2
.get()->pPortName
);
94 size_t dev_names_size
= sizeof(DEVNAMES
) + driver_size
+ printer_size
+
96 lppd
->hDevNames
= GlobalAlloc(GHND
, dev_names_size
);
97 if (!lppd
->hDevNames
) {
101 void* dev_names_ptr
= GlobalLock(lppd
->hDevNames
);
102 if (!dev_names_ptr
) {
106 DEVNAMES
* dev_names
= reinterpret_cast<DEVNAMES
*>(dev_names_ptr
);
107 dev_names
->wDefault
= 1;
108 dev_names
->wDriverOffset
= sizeof(DEVNAMES
);
109 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wDriverOffset
,
110 info_2
.get()->pDriverName
, driver_size
);
111 dev_names
->wDeviceOffset
= dev_names
->wDriverOffset
+ driver_size
;
112 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wDeviceOffset
,
113 info_2
.get()->pPrinterName
, printer_size
);
114 dev_names
->wOutputOffset
= dev_names
->wDeviceOffset
+ printer_size
;
115 memcpy(reinterpret_cast<uint8
*>(dev_names_ptr
) + dev_names
->wOutputOffset
,
116 info_2
.get()->pPortName
, port_size
);
117 GlobalUnlock(lppd
->hDevNames
);
118 dev_names_ptr
= NULL
;
121 // Note: This section does proper deallocation/free of DC/global handles. We
122 // did not use ScopedHGlobal or ScopedHandle because they did not
123 // perform what we need. Goto's are used based on Windows programming
124 // idiom, to avoid deeply nested if's, and try-catch-finally is not
125 // allowed in Chromium.
126 if (FAILED(result
)) {
130 if (lppd
->hDevMode
) {
131 GlobalFree(lppd
->hDevMode
);
133 if (lppd
->hDevNames
) {
134 GlobalFree(lppd
->hDevNames
);
137 ClosePrinter(printer
);
141 TEST_F(PrintingContextTest
, Base
) {
142 // Sometimes ::GetDefaultPrinter() fails? bug 61509.
143 if (IsTestCaseDisabled())
146 printing::PrintSettings settings
;
147 settings
.set_device_name(GetDefaultPrinter());
149 scoped_ptr
<printing::PrintingContext
> context(
150 printing::PrintingContext::Create(std::string()));
151 EXPECT_EQ(printing::PrintingContext::OK
, context
->InitWithSettings(settings
));
153 // The print may lie to use and may not support world transformation.
155 XFORM random_matrix
= { 1, 0.1f
, 0, 1.5f
, 0, 1 };
156 EXPECT_TRUE(SetWorldTransform(context
->context(), &random_matrix
));
157 EXPECT_TRUE(ModifyWorldTransform(context
->context(), NULL
, MWT_IDENTITY
));
160 TEST_F(PrintingContextTest
, PrintAll
) {
161 // Sometimes ::GetDefaultPrinter() fails? bug 61509.
162 if (IsTestCaseDisabled())
165 std::string dummy_locale
;
166 printing::PrintingContextWin
context(dummy_locale
);
167 context
.SetPrintDialog(&PrintDlgExMock
);
168 context
.AskUserForSettings(
169 NULL
, 123, false, base::Bind(&PrintingContextTest::PrintSettingsCallback
,
170 base::Unretained(this)));
171 EXPECT_EQ(printing::PrintingContext::OK
, result());
172 printing::PrintSettings settings
= context
.settings();
173 EXPECT_EQ(settings
.ranges
.size(), 0);