From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/prntvpt/ticket.c | 157 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 144 insertions(+), 13 deletions(-)
diff --git a/dlls/prntvpt/ticket.c b/dlls/prntvpt/ticket.c index 3dd4e18e9d7..d4239689a54 100644 --- a/dlls/prntvpt/ticket.c +++ b/dlls/prntvpt/ticket.c @@ -85,7 +85,14 @@ static const struct int paper; } psk_media[] = { + { L"psk:NorthAmericaLetter", DMPAPER_LETTER }, + { L"psk:NorthAmericaLegal", DMPAPER_LEGAL }, + { L"psk:NorthAmericaExecutive", DMPAPER_EXECUTIVE }, + { L"psk:ISOA3", DMPAPER_A3 }, { L"psk:ISOA4", DMPAPER_A4 }, + { L"psk:ISOA5", DMPAPER_A5 }, + { L"psk:JISB4", DMPAPER_B4 }, + { L"psk:JISB5", DMPAPER_B5 }, };
static int media_to_paper(const WCHAR *name) @@ -109,7 +116,7 @@ static const WCHAR *paper_to_media(int paper) return psk_media[i].name;
FIXME("%d\n", paper); - return psk_media[0].name; + return NULL; }
static BOOL is_valid_node_name(const WCHAR *name) @@ -816,12 +823,52 @@ static HRESULT write_int_value(IXMLDOMElement *root, int value) if (hr != S_OK) return hr;
hr = add_attribute(child, L"xsi:type", L"xsd:integer"); + if (hr == S_OK) + { + V_VT(&var) = VT_I4; + V_I4(&var) = value; + hr = IXMLDOMElement_put_nodeTypedValue(child, var); + } + IXMLDOMElement_Release(child); + return hr; +} + +static HRESULT write_string_value(IXMLDOMElement *root, const WCHAR *value) +{ + HRESULT hr; + IXMLDOMElement *child; + VARIANT var; + + hr = create_element(root, L"psf:Value", &child); if (hr != S_OK) return hr;
- V_VT(&var) = VT_I4; - V_I4(&var) = value; - hr = IXMLDOMElement_put_nodeTypedValue(child, var); + hr = add_attribute(child, L"xsi:type", L"xsd:string"); + if (hr == S_OK) + { + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = (BSTR)value; + hr = IXMLDOMElement_put_nodeTypedValue(child, var); + } + IXMLDOMElement_Release(child); + return hr; +} + +static HRESULT write_qname_value(IXMLDOMElement *root, const WCHAR *value) +{ + HRESULT hr; + IXMLDOMElement *child; + VARIANT var; + + hr = create_element(root, L"psf:Value", &child); + if (hr != S_OK) return hr;
+ hr = add_attribute(child, L"xsi:type", L"xsd:QName"); + if (hr == S_OK) + { + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = (BSTR)value; + hr = IXMLDOMElement_put_nodeTypedValue(child, var); + } IXMLDOMElement_Release(child); return hr; } @@ -889,15 +936,29 @@ static HRESULT create_ScoredProperty(IXMLDOMElement *root, const WCHAR *name, IX return add_attribute(*child, L"name", name); }
+static HRESULT create_Property(IXMLDOMElement *root, const WCHAR *name, IXMLDOMElement **child) +{ + HRESULT hr; + + hr = create_element(root, L"psf:Property", child); + if (hr != S_OK) return hr; + + return add_attribute(*child, L"name", name); +} + static HRESULT write_PageMediaSize(IXMLDOMElement *root, const struct ticket *ticket) { IXMLDOMElement *feature, *option = NULL, *property; + const WCHAR *media; HRESULT hr;
+ media = paper_to_media(ticket->page.media.paper); + if (!media) return E_FAIL; + hr = create_Feature(root, L"psk:PageMediaSize", &feature); if (hr != S_OK) return hr;
- hr = create_Option(feature, paper_to_media(ticket->page.media.paper), &option); + hr = create_Option(feature, media, &option); if (hr != S_OK) goto fail;
hr = create_ScoredProperty(option, L"psk:MediaSizeWidth", &property); @@ -1333,36 +1394,106 @@ HRESULT WINAPI PTMergeAndValidatePrintTicket(HPTPROVIDER provider, IStream *base
static HRESULT write_PageMediaSize_caps(const WCHAR *device, IXMLDOMElement *root) { - HRESULT hr = S_OK; + HRESULT hr; int count, i; POINT *pt; - IXMLDOMElement *feature = NULL; - - FIXME("stub\n"); + WORD *papers = NULL; + WCHAR *paper_names = NULL; + IXMLDOMElement *feature = NULL, *property;
count = DeviceCapabilitiesW(device, NULL, DC_PAPERSIZE, NULL, NULL); if (count <= 0) return HRESULT_FROM_WIN32(GetLastError());
+ if (DeviceCapabilitiesW(device, NULL, DC_PAPERS, NULL, NULL) != count) + { + FIXME("Count of DC_PAPERS doesn't match count of DC_PAPERSIZE\n"); + return E_FAIL; + } + + if (DeviceCapabilitiesW(device, NULL, DC_PAPERNAMES, NULL, NULL) != count) + { + FIXME("Count of DC_PAPERNAMES doesn't match count of DC_PAPERSIZE\n"); + return E_FAIL; + } + + hr = E_OUTOFMEMORY; pt = calloc(count, sizeof(*pt)); - if (!pt) return E_OUTOFMEMORY; + if (!pt) goto fail; + papers = calloc(count, sizeof(*papers)); + if (!papers) goto fail; + paper_names = calloc(count, sizeof(WCHAR) * 64); + if (!paper_names) goto fail;
- count = DeviceCapabilitiesW(device, NULL, DC_PAPERSIZE, (LPWSTR)pt, NULL); - if (count <= 0) + if (DeviceCapabilitiesW(device, NULL, DC_PAPERSIZE, (LPWSTR)pt, NULL) != count) { - hr = HRESULT_FROM_WIN32(GetLastError()); + hr = E_FAIL; + goto fail; + } + if (DeviceCapabilitiesW(device, NULL, DC_PAPERS, (LPWSTR)papers, NULL) != count) + { + hr = E_FAIL; + goto fail; + } + if (DeviceCapabilitiesW(device, NULL, DC_PAPERNAMES, (LPWSTR)paper_names, NULL) != count) + { + hr = E_FAIL; goto fail; }
hr = create_Feature(root, L"psk:PageMediaSize", &feature); if (hr != S_OK) goto fail;
+ hr = create_Property(feature, L"psk:SelectionType", &property); + if (hr != S_OK) goto fail; + hr = write_qname_value(property, L"psk:PickOne"); + IXMLDOMElement_Release(property); + if (hr != S_OK) goto fail; + + hr = create_Property(feature, L"psk:DisplayName", &property); + if (hr != S_OK) goto fail; + hr = write_string_value(property, L"PageSize"); + IXMLDOMElement_Release(property); + if (hr != S_OK) goto fail; + for (i = 0; i < count; i++) { + const WCHAR *media; + IXMLDOMElement *option; + + media = paper_to_media(papers[i]); + if (!media) continue; + + hr = create_Option(feature, media, &option); + if (hr != S_OK) goto fail; + + hr = create_Property(option, L"psk:DisplayName", &property); + if (hr == S_OK) + { + write_string_value(property, paper_names + i * 64); + IXMLDOMElement_Release(property); + } + + hr = create_ScoredProperty(option, L"psk:MediaSizeWidth", &property); + if (hr == S_OK) + { + write_int_value(property, pt[i].x * 100); + IXMLDOMElement_Release(property); + } + hr = create_ScoredProperty(option, L"psk:MediaSizeHeight", &property); + if (hr == S_OK) + { + write_int_value(property, pt[i].y * 100); + IXMLDOMElement_Release(property); + } + + IXMLDOMElement_Release(option); }
fail: if (feature) IXMLDOMElement_Release(feature); + free(paper_names); + free(papers); free(pt); return hr; }
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/prntvpt/Makefile.in | 2 +- dlls/prntvpt/ticket.c | 69 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/dlls/prntvpt/Makefile.in b/dlls/prntvpt/Makefile.in index 051dba89775..9ab750026c2 100644 --- a/dlls/prntvpt/Makefile.in +++ b/dlls/prntvpt/Makefile.in @@ -1,6 +1,6 @@ MODULE = prntvpt.dll IMPORTLIB = prntvpt -IMPORTS = winspool ole32 oleaut32 +IMPORTS = gdi32 winspool ole32 oleaut32
SOURCES = \ main.c \ diff --git a/dlls/prntvpt/ticket.c b/dlls/prntvpt/ticket.c index d4239689a54..0004722410d 100644 --- a/dlls/prntvpt/ticket.c +++ b/dlls/prntvpt/ticket.c @@ -1498,6 +1498,73 @@ fail: return hr; }
+static inline int pixels_to_mm_x1000(int pixels, int dpi) +{ + return MulDiv(pixels, 25400, dpi); +} + +static HRESULT write_PageImageableSize_caps(const WCHAR *device, IXMLDOMElement *root) +{ + HRESULT hr; + HDC hdc; + int res_x, res_y, phys_width, phys_height, width, height, offset_x, offset_y; + IXMLDOMElement *page, *area, *property; + + hdc = CreateDCW(NULL, device, NULL, NULL); + if (!hdc) HRESULT_FROM_WIN32(GetLastError()); + + res_x = GetDeviceCaps(hdc, LOGPIXELSX); + res_y = GetDeviceCaps(hdc, LOGPIXELSY); + + phys_width = pixels_to_mm_x1000(GetDeviceCaps(hdc, PHYSICALWIDTH), res_x); + phys_height = pixels_to_mm_x1000(GetDeviceCaps(hdc, PHYSICALHEIGHT), res_y); + width = pixels_to_mm_x1000(GetDeviceCaps(hdc, HORZRES), res_x); + height = pixels_to_mm_x1000(GetDeviceCaps(hdc, VERTRES), res_y); + + offset_x = pixels_to_mm_x1000(GetDeviceCaps(hdc, PHYSICALOFFSETX), res_x); + offset_y = pixels_to_mm_x1000(GetDeviceCaps(hdc, PHYSICALOFFSETY), res_y); + DeleteDC(hdc); + + hr = create_Property(root, L"psk:PageImageableSize", &page); + if (hr != S_OK) return hr; + + hr = create_Property(page, L"psk:ImageableSizeWidth", &property); + if (hr != S_OK) goto fail; + write_int_value(property, phys_width); + IXMLDOMElement_Release(property); + hr = create_Property(page, L"psk:ImageableSizeHeight", &property); + if (hr != S_OK) goto fail; + write_int_value(property, phys_height); + IXMLDOMElement_Release(property); + + hr = create_Property(page, L"psk:ImageableArea", &area); + if (hr != S_OK) goto fail; + + hr = create_Property(area, L"psk:OriginWidth", &property); + if (hr != S_OK) goto fail; + write_int_value(property, offset_x); + IXMLDOMElement_Release(property); + hr = create_Property(area, L"psk:OriginHeight", &property); + if (hr != S_OK) goto fail; + write_int_value(property, offset_y); + IXMLDOMElement_Release(property); + + hr = create_Property(area, L"psk:ExtentWidth", &property); + if (hr != S_OK) goto fail; + write_int_value(property, width); + IXMLDOMElement_Release(property); + hr = create_Property(area, L"psk:ExtentHeight", &property); + if (hr != S_OK) goto fail; + write_int_value(property, height); + IXMLDOMElement_Release(property); + + IXMLDOMElement_Release(area); + +fail: + IXMLDOMElement_Release(page); + return hr; +} + static HRESULT write_PageOutputColor_caps(const WCHAR *device, IXMLDOMElement *root) { HRESULT hr = S_OK; @@ -1688,6 +1755,8 @@ static HRESULT write_print_capabilities(const WCHAR *device, IStream *stream)
hr = write_PageMediaSize_caps(device, root); if (hr != S_OK) goto fail; + hr = write_PageImageableSize_caps(device, root); + if (hr != S_OK) goto fail; hr = write_PageOutputColor_caps(device, root); if (hr != S_OK) goto fail; hr = write_PageScaling_caps(device, root);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=151034
Your paranoid android.
=== debian11b (64 bit WoW report) ===
user32: input.c:4306: Test succeeded inside todo block: button_down_hwnd_todo 1: got MSG_TEST_WIN hwnd 0000000003A700E2, msg WM_LBUTTONDOWN, wparam 0x1, lparam 0x320032
If you only need writing functionality, there is no reason to use msxml. The xmllite fits better.