Index: printing/backend/print_backend_win.cc |
=================================================================== |
--- printing/backend/print_backend_win.cc (revision 153539) |
+++ printing/backend/print_backend_win.cc (working copy) |
@@ -18,6 +18,29 @@ |
namespace { |
+// This class is designed to work with PRINTER_INFO_X structures |
+// and calls GetPrinter internally with correctly allocated buffer. |
+template <typename T> |
+class PrinterInfo { |
+ public: |
+ bool GetPrinterInfo(HANDLE printer, int level) { |
+ DWORD buf_size = 0; |
+ GetPrinter(printer, level, NULL, 0, &buf_size); |
+ if (buf_size == 0) |
+ return false; |
+ buffer_.reset(new uint8[buf_size]); |
+ memset(buffer_.get(), 0, buf_size); |
+ return !!GetPrinter(printer, level, buffer_.get(), buf_size, &buf_size); |
+ } |
+ |
+ const T* get() const { |
+ return reinterpret_cast<T*>(buffer_.get()); |
+ } |
+ |
+ private: |
+ scoped_array<uint8> buffer_; |
+}; |
+ |
HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { |
DCHECK(stream); |
DCHECK(out); |
@@ -42,6 +65,9 @@ |
// PrintBackend implementation. |
virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; |
virtual std::string GetDefaultPrinterName() OVERRIDE; |
+ virtual bool GetPrinterSemanticCapsAndDefaults( |
+ const std::string& printer_name, |
+ PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE; |
virtual bool GetPrinterCapsAndDefaults( |
const std::string& printer_name, |
PrinterCapsAndDefaults* printer_info) OVERRIDE; |
@@ -93,6 +119,76 @@ |
return WideToUTF8(default_printer_name); |
} |
+bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( |
+ const std::string& printer_name, |
+ PrinterSemanticCapsAndDefaults* printer_info) { |
+ ScopedPrinterHandle printer_handle; |
+ OpenPrinter(const_cast<LPTSTR>(UTF8ToWide(printer_name).c_str()), |
+ printer_handle.Receive(), NULL); |
+ DCHECK(printer_handle); |
+ if (!printer_handle.IsValid()) |
+ return false; |
+ |
+ PrinterInfo<PRINTER_INFO_5> info_5; |
+ if (!info_5.GetPrinterInfo(printer_handle, 5)) |
+ return false; |
+ |
+ // Get printer capabilities. For more info see here: |
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).aspx |
+ bool color_supported = (DeviceCapabilities(info_5.get()->pPrinterName, |
+ info_5.get()->pPortName, |
+ DC_COLORDEVICE, |
+ NULL, |
+ NULL) == 1); |
+ |
+ bool duplex_supported = (DeviceCapabilities(info_5.get()->pPrinterName, |
+ info_5.get()->pPortName, |
+ DC_DUPLEX, |
+ NULL, |
+ NULL) == 1); |
+ |
+ // PRINTER_INFO_9 retrieves current user settings. |
+ PrinterInfo<PRINTER_INFO_9> info_9; |
+ if (!info_9.GetPrinterInfo(printer_handle, 9)) |
+ return false; |
+ DEVMODE* devmode = info_9.get()->pDevMode; |
+ |
+ // Sometimes user settings are not available (have not been setted up yet). |
+ // Use printer default settings (PRINTER_INFO_8) in this case. |
+ PrinterInfo<PRINTER_INFO_8> info_8; |
+ if (!devmode) { |
+ if (info_8.GetPrinterInfo(printer_handle, 8)) |
+ devmode = info_8.get()->pDevMode; |
+ } |
+ if (!devmode) |
+ return false; |
+ |
+ PrinterSemanticCapsAndDefaults caps; |
+ caps.color_capable = color_supported; |
+ if ((devmode->dmFields & DM_COLOR) == DM_COLOR) |
+ caps.color_default = (devmode->dmColor == DMCOLOR_COLOR); |
+ |
+ caps.duplex_capable = duplex_supported; |
+ if ((devmode->dmFields & DM_DUPLEX) == DM_DUPLEX) { |
+ switch (devmode->dmDuplex) { |
+ case DMDUP_SIMPLEX: |
+ caps.duplex_default = SIMPLEX; |
+ break; |
+ case DMDUP_VERTICAL: |
+ caps.duplex_default = LONG_EDGE; |
+ break; |
+ case DMDUP_HORIZONTAL: |
+ caps.duplex_default = SHORT_EDGE; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ } |
+ |
+ *printer_info = caps; |
+ return true; |
+} |
+ |
bool PrintBackendWin::GetPrinterCapsAndDefaults( |
const std::string& printer_name, |
PrinterCapsAndDefaults* printer_info) { |