Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8480)

Unified Diff: chrome/service/cloud_print/print_system_win.cc

Issue 6523040: Added support to the Windows cloud print proxy to print XPS documents directl... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Code review changes Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/service/cloud_print/print_system_cups.cc ('k') | chrome/service/cloud_print/printer_job_handler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/service/cloud_print/print_system_win.cc
===================================================================
--- chrome/service/cloud_print/print_system_win.cc (revision 74874)
+++ chrome/service/cloud_print/print_system_win.cc (working copy)
@@ -6,8 +6,14 @@
#include <objidl.h>
#include <winspool.h>
+#if defined(_WIN32_WINNT)
+#undef _WIN32_WINNT
+#endif // defined(_WIN32_WINNT)
+#define _WIN32_WINNT _WIN32_WINNT_WIN7
+#include <xpsprint.h>
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "base/win/object_watcher.h"
@@ -366,10 +372,15 @@
private:
// We use a Core class because we want a separate RefCountedThreadSafe
// implementation for ServiceUtilityProcessHost::Client.
- class Core : public ServiceUtilityProcessHost::Client {
+ class Core : public ServiceUtilityProcessHost::Client,
+ public base::win::ObjectWatcher::Delegate {
public:
Core()
- : last_page_printed_(-1), job_id_(-1), delegate_(NULL), saved_dc_(0) {
+ : last_page_printed_(-1),
+ job_id_(-1),
+ delegate_(NULL),
+ saved_dc_(0),
+ should_couninit_(false) {
}
~Core() {
}
@@ -385,47 +396,54 @@
return false;
}
last_page_printed_ = -1;
- // We only support PDFs for now.
- if (print_data_mime_type != "application/pdf") {
- NOTREACHED();
- return false;
- }
+ // We only support PDF and XPS documents for now.
+ if (print_data_mime_type == "application/pdf") {
+ DevMode pt_dev_mode;
+ HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket,
+ &pt_dev_mode);
+ if (FAILED(hr)) {
+ NOTREACHED();
+ return false;
+ }
- DevMode pt_dev_mode;
- HRESULT hr = PrintTicketToDevMode(printer_name, print_ticket,
- &pt_dev_mode);
- if (FAILED(hr)) {
- NOTREACHED();
- return false;
- }
+ HDC dc = CreateDC(L"WINSPOOL", UTF8ToWide(printer_name).c_str(),
+ NULL, pt_dev_mode.dm_);
+ if (!dc) {
+ NOTREACHED();
+ return false;
+ }
+ hr = E_FAIL;
+ DOCINFO di = {0};
+ di.cbSize = sizeof(DOCINFO);
+ std::wstring doc_name = UTF8ToWide(job_title);
+ di.lpszDocName = doc_name.c_str();
+ job_id_ = StartDoc(dc, &di);
+ if (job_id_ <= 0)
+ return false;
- HDC dc = CreateDC(L"WINSPOOL", UTF8ToWide(printer_name).c_str(),
- NULL, pt_dev_mode.dm_);
- if (!dc) {
+ printer_dc_.Set(dc);
+ int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
+ saved_dc_ = SaveDC(printer_dc_.Get());
+ SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED);
+ XFORM xform = {0};
+ xform.eM11 = xform.eM22 = static_cast<float>(printer_dpi) /
+ static_cast<float>(GetDeviceCaps(GetDC(NULL), LOGPIXELSX));
+ ModifyWorldTransform(printer_dc_.Get(), &xform, MWT_LEFTMULTIPLY);
+ print_data_file_path_ = print_data_file_path;
+ delegate_ = delegate;
+ RenderNextPDFPages();
+ } else if (print_data_mime_type == "application/vnd.ms-xpsdocument") {
+ bool ret = PrintXPSDocument(printer_name,
+ job_title,
+ print_data_file_path,
+ print_ticket);
+ if (ret)
+ delegate_ = delegate;
+ return ret;
+ } else {
NOTREACHED();
return false;
}
- hr = E_FAIL;
- DOCINFO di = {0};
- di.cbSize = sizeof(DOCINFO);
- std::wstring doc_name = UTF8ToWide(job_title);
- di.lpszDocName = doc_name.c_str();
- job_id_ = StartDoc(dc, &di);
- if (job_id_ <= 0)
- return false;
-
- printer_dc_.Set(dc);
-
- int printer_dpi = ::GetDeviceCaps(printer_dc_.Get(), LOGPIXELSX);
- saved_dc_ = SaveDC(printer_dc_.Get());
- SetGraphicsMode(printer_dc_.Get(), GM_ADVANCED);
- XFORM xform = {0};
- xform.eM11 = xform.eM22 = static_cast<float>(printer_dpi) /
- static_cast<float>(GetDeviceCaps(GetDC(NULL), LOGPIXELSX));
- ModifyWorldTransform(printer_dc_.Get(), &xform, MWT_LEFTMULTIPLY);
- print_data_file_path_ = print_data_file_path;
- delegate_ = delegate;
- RenderNextPDFPages();
return true;
}
@@ -442,6 +460,33 @@
else
RenderNextPDFPages();
}
+
+ // base::win::ObjectWatcher::Delegate inplementation.
+ virtual void OnObjectSignaled(HANDLE object) {
+ DCHECK(xps_print_job_);
+ if (!delegate_)
+ return;
+ XPS_JOB_STATUS job_status = {0};
+ xps_print_job_->GetJobStatus(&job_status);
+ bool done = false;
+ if ((job_status.completion == XPS_JOB_CANCELLED) ||
+ (job_status.completion == XPS_JOB_FAILED)) {
+ delegate_->OnJobSpoolFailed();
+ done = true;
+ } else if (job_status.jobId) {
+ delegate_->OnJobSpoolSucceeded(job_status.jobId);
+ done = true;
+ } else {
+ ResetEvent(job_progress_event_.Get());
+ job_progress_watcher_.StopWatching();
+ job_progress_watcher_.StartWatching(job_progress_event_.Get(), this);
+ }
+ if (done && should_couninit_) {
+ CoUninitialize();
+ should_couninit_ = false;
+ }
+ }
+
virtual void OnRenderPDFPagesToMetafileFailed() {
PrintJobDone();
}
@@ -503,6 +548,67 @@
utility_host.release();
}
}
+ bool PrintXPSDocument(const std::string& printer_name,
+ const std::string& job_title,
+ const FilePath& print_data_file_path,
+ const std::string& print_ticket) {
+ if (!printing::XPSPrintModule::Init())
+ return false;
+ job_progress_event_.Set(CreateEvent(NULL, TRUE, FALSE, NULL));
+ if (!job_progress_event_.Get())
+ return false;
+ should_couninit_ = SUCCEEDED(CoInitializeEx(NULL,
+ COINIT_MULTITHREADED));
+ ScopedComPtr<IXpsPrintJobStream> doc_stream;
+ ScopedComPtr<IXpsPrintJobStream> print_ticket_stream;
+ bool ret = false;
+ // Use nested SUCCEEDED checks because we want a common return point.
+ if (SUCCEEDED(printing::XPSPrintModule::StartXpsPrintJob(
+ UTF8ToWide(printer_name).c_str(),
+ UTF8ToWide(job_title).c_str(),
+ NULL,
+ job_progress_event_.Get(),
+ NULL,
+ NULL,
+ NULL,
+ xps_print_job_.Receive(),
+ doc_stream.Receive(),
+ print_ticket_stream.Receive()))) {
+ ULONG bytes_written = 0;
+ if (SUCCEEDED(print_ticket_stream->Write(print_ticket.c_str(),
+ print_ticket.length(),
+ &bytes_written))) {
+ DCHECK(bytes_written == print_ticket.length());
+ if (SUCCEEDED(print_ticket_stream->Close())) {
+ std::string document_data;
+ file_util::ReadFileToString(print_data_file_path, &document_data);
+ bytes_written = 0;
+ if (SUCCEEDED(doc_stream->Write(document_data.c_str(),
+ document_data.length(),
+ &bytes_written))) {
+ DCHECK(bytes_written == document_data.length());
+ if (SUCCEEDED(doc_stream->Close())) {
+ job_progress_watcher_.StartWatching(job_progress_event_.Get(),
+ this);
+ ret = true;
+ }
+ }
+ }
+ }
+ }
+ if (!ret) {
+ if (xps_print_job_) {
+ xps_print_job_->Cancel();
+ xps_print_job_.Release();
+ }
+ if (should_couninit_) {
+ CoUninitialize();
+ should_couninit_ = false;
+ }
+ }
+ return ret;
+ }
+
// Some Cairo-generated PDFs from Chrome OS result in huge metafiles.
// So the PageCountPerBatch is set to 1 for now.
// TODO(sanjeevr): Figure out a smarter way to determine the pages per
@@ -515,6 +621,10 @@
int saved_dc_;
base::win::ScopedHDC printer_dc_;
FilePath print_data_file_path_;
+ base::win::ScopedHandle job_progress_event_;
+ base::win::ObjectWatcher job_progress_watcher_;
+ ScopedComPtr<IXpsPrintJob> xps_print_job_;
+ bool should_couninit_;
DISALLOW_COPY_AND_ASSIGN(JobSpoolerWin::Core);
};
scoped_refptr<Core> core_;
@@ -588,7 +698,9 @@
virtual PrintSystem::PrinterWatcher* CreatePrinterWatcher(
const std::string& printer_name);
virtual PrintSystem::JobSpooler* CreateJobSpooler();
+ virtual std::string GetSupportedMimeTypes();
+
private:
scoped_refptr<printing::PrintBackend> print_backend_;
};
@@ -728,6 +840,13 @@
return new JobSpoolerWin();
}
+std::string PrintSystemWin::GetSupportedMimeTypes() {
+ if (printing::XPSPrintModule::Init())
+ return "application/vnd.ms-xpsdocument,application/pdf";
+ return "application/pdf";
+}
+
+
std::string PrintSystem::GenerateProxyId() {
GUID proxy_id = {0};
HRESULT hr = UuidCreate(&proxy_id);
« no previous file with comments | « chrome/service/cloud_print/print_system_cups.cc ('k') | chrome/service/cloud_print/printer_job_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698